Website redesign
6
.gitignore
vendored
@ -7,10 +7,14 @@ elm-stuff
|
|||||||
result
|
result
|
||||||
_site/
|
_site/
|
||||||
*.qcow2
|
*.qcow2
|
||||||
/website/site/content/docs/changelog/
|
/website/site/content/docs/install/changelog.md
|
||||||
/website/site/public/
|
/website/site/public/
|
||||||
/website/site/static/openapi/
|
/website/site/static/openapi/
|
||||||
/website/site/static/js/bundle.js
|
/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/server.conf
|
||||||
/website/site/templates/shortcodes/sample-exim.conf
|
/website/site/templates/shortcodes/sample-exim.conf
|
||||||
/website/site/templates/shortcodes/joex.conf
|
/website/site/templates/shortcodes/joex.conf
|
||||||
|
@ -840,19 +840,17 @@ val website = project
|
|||||||
}.taskValue,
|
}.taskValue,
|
||||||
Compile / resourceGenerators += Def.task {
|
Compile / resourceGenerators += Def.task {
|
||||||
val changelog = (LocalRootProject / baseDirectory).value / "Changelog.md"
|
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)
|
IO.createDirectory(targetDir)
|
||||||
val target = targetDir / "_index.md"
|
val target = targetDir / "changelog.md"
|
||||||
|
|
||||||
IO.write(
|
IO.write(
|
||||||
target,
|
target,
|
||||||
"""|+++
|
"""|+++
|
||||||
|title = "Changelog"
|
|title = "Changelog"
|
||||||
|description = "See what changed between releases."
|
|description = "See what changed between releases."
|
||||||
|weight = 10
|
|weight = 10000
|
||||||
|insert_anchor_links = "right"
|
|insert_anchor_links = "right"
|
||||||
|[extra]
|
|
||||||
|maketoc = false
|
|
||||||
|+++
|
|+++
|
||||||
|""".stripMargin
|
|""".stripMargin
|
||||||
)
|
)
|
||||||
|
@ -15,6 +15,7 @@ object Cmd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def run(cmd: Seq[String], wd: File, logger: Logger): Unit = {
|
def run(cmd: Seq[String], wd: File, logger: Logger): Unit = {
|
||||||
|
logger.info(s"Running ${cmd.mkString(" ")}")
|
||||||
val res = Cmd.exec(cmd, Some(wd))
|
val res = Cmd.exec(cmd, Some(wd))
|
||||||
logger.info(res.out)
|
logger.info(res.out)
|
||||||
logger.error(res.err)
|
logger.error(res.err)
|
||||||
|
@ -2,6 +2,7 @@ package docspell.build
|
|||||||
|
|
||||||
import sbt._
|
import sbt._
|
||||||
import sbt.Keys._
|
import sbt.Keys._
|
||||||
|
import sbt.nio.file.FileTreeView
|
||||||
import scala.sys.process._
|
import scala.sys.process._
|
||||||
|
|
||||||
object ZolaPlugin extends AutoPlugin {
|
object ZolaPlugin extends AutoPlugin {
|
||||||
@ -74,10 +75,12 @@ object ZolaPlugin extends AutoPlugin {
|
|||||||
case Some(url) =>
|
case Some(url) =>
|
||||||
Seq("--base-url", url)
|
Seq("--base-url", url)
|
||||||
case None =>
|
case None =>
|
||||||
runYarnInstall("yarn", inDir.getParentFile, logger)
|
|
||||||
runElmCompile("elm", inDir.getParentFile, inDir, logger)
|
|
||||||
Seq.empty
|
Seq.empty
|
||||||
}
|
}
|
||||||
|
runYarnInstall("yarn", inDir.getParentFile, logger)
|
||||||
|
runElmCompile("elm", inDir.getParentFile, inDir, logger)
|
||||||
|
runTailwind("npx", inDir.getParentFile, inDir, logger)
|
||||||
|
|
||||||
Cmd.run(
|
Cmd.run(
|
||||||
Seq(zolaCmd, "build", "-o", outDir.absolutePath.toString) ++ baseUrl,
|
Seq(zolaCmd, "build", "-o", outDir.absolutePath.toString) ++ baseUrl,
|
||||||
inDir,
|
inDir,
|
||||||
@ -106,4 +109,39 @@ object ZolaPlugin extends AutoPlugin {
|
|||||||
logger
|
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
|
static site generator. The (very minimal) dynamic parts are written in
|
||||||
Elm.
|
Elm.
|
||||||
|
|
||||||
The `build.sh` script builds the site.
|
Sbt is used to build the site.
|
||||||
|
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
Install things by running `yarn install`.
|
Install things by running `yarn install`.
|
||||||
|
|
||||||
Open two terminals. In first run:
|
Open terminal for each script below:
|
||||||
|
|
||||||
``` shell
|
1. Starting the server
|
||||||
nix-shell --run ./run-elm.sh
|
``` shell
|
||||||
```
|
nix-shell --run "cd site && zola serve"
|
||||||
|
```
|
||||||
and in the second
|
2. Building the stylesheet
|
||||||
|
``` shell
|
||||||
``` shell
|
nix-shell --run ./scripts/run-styles.sh
|
||||||
nix-shell --run "cd site && zola serve"
|
```
|
||||||
```
|
3. Building some javascript files
|
||||||
|
``` shell
|
||||||
|
nix-shell --run ./scripts/run-elm.sh
|
||||||
|
```
|
||||||
|
|
||||||
Open browser at `localhost:1111`.
|
Open browser at `localhost:1111`.
|
||||||
|
|
||||||
|
|
||||||
## Publishing
|
## 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
|
``` shell
|
||||||
nix-shell website/shell.nix --run sbt
|
nix-shell website/shell.nix --run sbt
|
||||||
sbt> project website
|
sbt> project website
|
||||||
```
|
```
|
||||||
|
|
||||||
### Check Links
|
Build everything and check for dead links:
|
||||||
|
|
||||||
``` scala
|
``` scala
|
||||||
sbt> zolaBuild
|
sbt> zolaBuildTest
|
||||||
sbt> zolaCheck
|
sbt> zolaCheck
|
||||||
```
|
```
|
||||||
|
|
||||||
### Testing
|
### Testing
|
||||||
|
|
||||||
``` scala
|
``` scala
|
||||||
sbt> zolaBuildTest
|
|
||||||
sbt> ghpagesSynchLocal
|
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
|
``` shell
|
||||||
cd ~/.sbt/ghpages/<some-hash>/com.github.eikek/docspell-website
|
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.
|
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 : Demo -> Html msg
|
||||||
demo data =
|
demo data =
|
||||||
div [ class "columns is-vcentered box mb-5" ]
|
div [ class "px-4 py-4 mx-2 sm:mx-8 rounded border shadow-lg flex flex-col" ]
|
||||||
[ div [ class "column" ]
|
[ h2 [ class "text-3xl font-bold py-2 font-serif" ]
|
||||||
[ h2 [ class "title" ]
|
[ text data.title
|
||||||
[ text data.title
|
]
|
||||||
]
|
, if data.info == "" then
|
||||||
, if data.info == "" then
|
span [] []
|
||||||
span [] []
|
|
||||||
|
|
||||||
else
|
else
|
||||||
p []
|
Markdown.toHtml [ class "text-lg" ] data.info
|
||||||
[ Markdown.toHtml [] data.info
|
, div [ class "mt-6 self-center" ]
|
||||||
]
|
[ video
|
||||||
, div [ class "mt-5 columns is-centered" ]
|
[ src data.url
|
||||||
[ video
|
, controls True
|
||||||
[ src data.url
|
|
||||||
, controls True
|
|
||||||
]
|
|
||||||
[]
|
|
||||||
]
|
]
|
||||||
|
[]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -14,38 +14,66 @@ type alias Feature =
|
|||||||
|
|
||||||
featureBox : Int -> Feature -> Html msg
|
featureBox : Int -> Feature -> Html msg
|
||||||
featureBox index f =
|
featureBox index f =
|
||||||
case isOdd index of
|
let
|
||||||
False ->
|
titleCss =
|
||||||
div [ class "columns is-vcentered box mb-5" ]
|
"text-3xl font-bold font-serif mb-3"
|
||||||
[ div [ class "column is-three-quarter" ]
|
|
||||||
[ figure [ class "image is-2by1 feature-image" ]
|
|
||||||
[ img [ src f.image ] []
|
|
||||||
]
|
|
||||||
]
|
|
||||||
, div [ class "column" ]
|
|
||||||
[ h2 [ class "title" ]
|
|
||||||
[ text f.header
|
|
||||||
]
|
|
||||||
, Markdown.toHtml []
|
|
||||||
f.description
|
|
||||||
]
|
|
||||||
]
|
|
||||||
|
|
||||||
True ->
|
boxCss =
|
||||||
div [ class "columns is-vcentered box mb-5" ]
|
[ class "flex-col space-y-2"
|
||||||
[ div [ class "column is-three-quarter" ]
|
, class "sm:flex-row sm:space-y-0 sm-space-x-4"
|
||||||
[ h2 [ class "title" ]
|
, class "flex px-8 py-8 border rounded mb-5 shadow-lg mx-2 sm:mx-8"
|
||||||
[ text f.header
|
]
|
||||||
]
|
|
||||||
, Markdown.toHtml []
|
descrCss =
|
||||||
f.description
|
"flex flex-col text-xl "
|
||||||
]
|
in
|
||||||
, div [ class "column" ]
|
if isOdd index then
|
||||||
[ figure [ class "image is-2by1 feature-image" ]
|
div boxCss
|
||||||
[ img [ src f.image ] []
|
[ 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
|
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"
|
, { image = "img/notify-feature.png"
|
||||||
, header = "Notifications"
|
, header = "Notifications"
|
||||||
, description = """
|
, 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 exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Icons
|
|
||||||
import Markdown
|
import Markdown
|
||||||
|
|
||||||
|
|
||||||
getStarted : String -> List (Html msg)
|
getStarted : String -> Html msg
|
||||||
getStarted version =
|
getStarted _ =
|
||||||
[ div [ class "content container" ]
|
div [ class "container max-w-screen-lg mx-auto text-xl px-10 lg:px-0 leading-relaxed min-h-screen" ]
|
||||||
[ Markdown.toHtml []
|
[ Markdown.toHtml [ class "my-4 markdown-view" ]
|
||||||
"""Docspell consists of several components. The easiest way to get started is probably to use docker and
|
"""Docspell consists of several components. The easiest way to get started is probably to use docker and
|
||||||
[docker-compose](https://docs.docker.com/compose/)."""
|
[docker-compose](https://docs.docker.com/compose/)."""
|
||||||
, Markdown.toHtml []
|
, Markdown.toHtml [ class "my-4 markdown-view " ]
|
||||||
"""1. Clone the github repository
|
"""1. Clone the github repository
|
||||||
```bash
|
```bash
|
||||||
$ git clone https://github.com/eikek/docspell
|
$ git clone https://github.com/eikek/docspell
|
||||||
```
|
```
|
||||||
Alternatively, [download](https://github.com/eikek/docspell/archive/master.zip) the sources and extract the zip file.
|
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
|
```bash
|
||||||
$ cd docspell/docker/docker-compose
|
$ cd docspell/docker/docker-compose
|
||||||
```
|
```
|
||||||
3. Run `docker-compose up`:
|
3. Run `docker-compose up`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ docker-compose up -d
|
$ docker-compose up -d
|
||||||
```
|
```
|
||||||
4. Goto <http://localhost:7880>, signup and login. When signing up,
|
4. Goto <http://localhost:7880>, signup and login. When signing up,
|
||||||
choose the same name for collective and user. Then login
|
choose the same name for collective and user. Then login
|
||||||
with this name and the password.
|
with this name and the password.
|
||||||
|
|
||||||
5. (Optional) Create a folder `./docs/<collective-name>` (the name you
|
5. (Optional) Create a folder `./docs/<collective-name>` (the name you
|
||||||
chose for the collective at registration) and place files in there
|
chose for the collective at registration) and place files in there
|
||||||
for importing them.
|
for importing them.
|
||||||
@ -38,58 +35,51 @@ getStarted version =
|
|||||||
The `docker-compose.yml` file defines some environment variables to
|
The `docker-compose.yml` file defines some environment variables to
|
||||||
configure docspell. You can [modify](docs/configure) them as needed.
|
configure docspell. You can [modify](docs/configure) them as needed.
|
||||||
"""
|
"""
|
||||||
]
|
, div [ class "blue-message" ]
|
||||||
, div [ class "content container" ]
|
|
||||||
[ div [ class "notification is-info is-light" ]
|
|
||||||
[ text "If you don't use docker, there are other ways that are "
|
[ text "If you don't use docker, there are other ways that are "
|
||||||
, text "described in the relevant "
|
, text "described in the relevant "
|
||||||
, a [ href "/docs/install" ]
|
, a [ href "/docs/install", class "link" ]
|
||||||
[ text "documentation page"
|
[ text "documentation page"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
, div [ class "green-message mt-4 " ]
|
||||||
, div [ class "content container" ]
|
[ h3 [ class "text-4xl font-bold font-serif py-2 mb-2" ]
|
||||||
[ div [ class "notification is-success is-light" ]
|
[ text "Where to go from here?"
|
||||||
[ div [ class "content is-medium" ]
|
]
|
||||||
[ h3 [ class "title" ]
|
, ul [ class "list-disc list-inside " ]
|
||||||
[ text "Where to go from here?"
|
[ li []
|
||||||
|
[ text "Find out "
|
||||||
|
, a [ href "/docs/feed" ]
|
||||||
|
[ text "how files can get into Docspell."
|
||||||
|
]
|
||||||
]
|
]
|
||||||
, ul []
|
, li []
|
||||||
[ li []
|
[ text "The "
|
||||||
[ text "Find out "
|
, a [ href "/docs/intro" ]
|
||||||
, a [ href "/docs/feed" ]
|
[ text "introduction" ]
|
||||||
[ text "how files can get into Docspell."
|
, text " writes about the goals and basic idea."
|
||||||
]
|
]
|
||||||
|
, li []
|
||||||
|
[ text "There is a comprehensive "
|
||||||
|
, a [ href "/docs" ]
|
||||||
|
[ text "documentation"
|
||||||
]
|
]
|
||||||
, li []
|
, text " available."
|
||||||
[ text "The "
|
]
|
||||||
, a [ href "/docs/intro" ]
|
, li []
|
||||||
[ text "introduction" ]
|
[ text "The source code is hosted on "
|
||||||
, text " writes about the goals and basic idea."
|
, a [ href "https://github.com/eikek/docspell" ]
|
||||||
|
[ text "github"
|
||||||
]
|
]
|
||||||
, li []
|
, text "."
|
||||||
[ text "There is a comprehensive "
|
]
|
||||||
, a [ href "/docs" ]
|
, li []
|
||||||
[ text "documentation"
|
[ text "Chat on "
|
||||||
]
|
, a [ href "https://gitter.im/eikek/docspell" ]
|
||||||
, text " available."
|
[ text "Gitter"
|
||||||
]
|
|
||||||
, 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 " for questions and feedback."
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
|
||||||
|
@ -6,7 +6,7 @@ import Html.Attributes exposing (..)
|
|||||||
|
|
||||||
copyright : Html msg
|
copyright : Html msg
|
||||||
copyright =
|
copyright =
|
||||||
img [ src "icons/copyright-40.svg" ] []
|
i [ class "fa fa-copyright font-thin" ] []
|
||||||
|
|
||||||
|
|
||||||
infoSquared : Html msg
|
infoSquared : Html msg
|
||||||
@ -36,19 +36,24 @@ logoWidth w =
|
|||||||
|
|
||||||
home : Html msg
|
home : Html msg
|
||||||
home =
|
home =
|
||||||
img [ src "icons/home-40.svg" ] []
|
i [ class "fa fa-home" ] []
|
||||||
|
|
||||||
|
|
||||||
docs : Html msg
|
docs : Html msg
|
||||||
docs =
|
docs =
|
||||||
img [ src "icons/notes-40.svg" ] []
|
i [ class "fa fa-book" ] []
|
||||||
|
|
||||||
|
|
||||||
github : Html msg
|
github : Html msg
|
||||||
github =
|
github =
|
||||||
img [ src "/icons/github-40.svg" ] []
|
i [ class "fab fa-github-alt" ] []
|
||||||
|
|
||||||
|
|
||||||
githubGreen : Html msg
|
githubGreen : Html msg
|
||||||
githubGreen =
|
githubGreen =
|
||||||
img [ src "/icons/github-40-green.svg" ] []
|
img [ src "/icons/github-40-green.svg" ] []
|
||||||
|
|
||||||
|
|
||||||
|
blog : Html msg
|
||||||
|
blog =
|
||||||
|
i [ class "fa fa-blog" ] []
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
module Main exposing (..)
|
module Main exposing (..)
|
||||||
|
|
||||||
import Browser exposing (Document)
|
import Browser
|
||||||
import Browser.Navigation exposing (Key)
|
|
||||||
import Demo
|
import Demo
|
||||||
import ExtraAttr exposing (..)
|
import ExtraAttr exposing (..)
|
||||||
import Feature exposing (Feature)
|
import Feature exposing (Feature)
|
||||||
@ -109,34 +108,33 @@ subscriptions _ =
|
|||||||
view : Model -> Html Msg
|
view : Model -> Html Msg
|
||||||
view model =
|
view model =
|
||||||
node "body"
|
node "body"
|
||||||
[]
|
[ class "text-gray-700" ]
|
||||||
[ mainHero model
|
[ mainHero model
|
||||||
, demoHero
|
, demoHeader
|
||||||
, section [ class "section" ]
|
, section [ class "container max-w-screen-xl mx-auto mb-2" ]
|
||||||
[ div [ class "container" ]
|
[ div [ class "mt-3 flex flex-col space-y-4" ]
|
||||||
[ Demo.demo Demo.processDemo
|
[ Demo.demo Demo.processDemo
|
||||||
, Demo.demo Demo.navigateDemo
|
, Demo.demo Demo.navigateDemo
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, featureHero model
|
, featureHeader model
|
||||||
, section [ class "section" ]
|
, section [ class "mx-auto max-w-screen-xl mb-2 mt-4" ]
|
||||||
[ div [ class "container" ]
|
(List.indexedMap Feature.featureBox model.features
|
||||||
(List.indexedMap Feature.featureBox model.features
|
++ [ div
|
||||||
++ [ div [ class "columns box" ]
|
[ class "flex px-8 py-8 border rounded mb-5 shadow-lg text-2xl"
|
||||||
[ div [ class "column is-full" ]
|
, class "sm:flex-row sm:space-y-0 sm-space-x-4"
|
||||||
[ div [ class "content has-text-centered is-medium" ]
|
, class "mx-2 sm:mx-8"
|
||||||
[ text "A more complete list can be found in "
|
]
|
||||||
, a [ href "/docs/features" ] [ text "here" ]
|
[ div [ class "text-center w-full" ]
|
||||||
, text "."
|
[ text "A more complete list can be found in "
|
||||||
]
|
, a [ href "/docs/features", class "link" ] [ text "here" ]
|
||||||
]
|
, text "."
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
)
|
]
|
||||||
]
|
)
|
||||||
, getStartedHero model
|
, getStartedHeader model
|
||||||
, div [ class "section" ]
|
, GetStarted.getStarted model.flags.version
|
||||||
(GetStarted.getStarted model.flags.version)
|
|
||||||
, footHero model
|
, footHero model
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -147,7 +145,7 @@ footHero model =
|
|||||||
[ id "footer"
|
[ id "footer"
|
||||||
, class "footer"
|
, class "footer"
|
||||||
]
|
]
|
||||||
[ div [ class "has-text-centered" ]
|
[ div [ class "text-center" ]
|
||||||
[ span []
|
[ span []
|
||||||
[ text ("Docspell, " ++ model.flags.version)
|
[ text ("Docspell, " ++ model.flags.version)
|
||||||
]
|
]
|
||||||
@ -157,6 +155,7 @@ footHero model =
|
|||||||
, a
|
, a
|
||||||
[ href "https://spdx.org/licenses/AGPL-3.0-or-later.html"
|
[ href "https://spdx.org/licenses/AGPL-3.0-or-later.html"
|
||||||
, target "_blank"
|
, target "_blank"
|
||||||
|
, class "link"
|
||||||
]
|
]
|
||||||
[ text "AGPLv3+"
|
[ text "AGPLv3+"
|
||||||
]
|
]
|
||||||
@ -166,6 +165,7 @@ footHero model =
|
|||||||
, a
|
, a
|
||||||
[ href "https://github.com/eikek/docspell"
|
[ href "https://github.com/eikek/docspell"
|
||||||
, target "_blank"
|
, target "_blank"
|
||||||
|
, class "link"
|
||||||
]
|
]
|
||||||
[ text "Source Code"
|
[ text "Source Code"
|
||||||
]
|
]
|
||||||
@ -176,6 +176,7 @@ footHero model =
|
|||||||
[ a
|
[ a
|
||||||
[ href "https://gitter.im/eikek/docspell"
|
[ href "https://gitter.im/eikek/docspell"
|
||||||
, target "_blank"
|
, target "_blank"
|
||||||
|
, class "link"
|
||||||
]
|
]
|
||||||
[ text "Chat on Gitter"
|
[ text "Chat on Gitter"
|
||||||
]
|
]
|
||||||
@ -184,166 +185,142 @@ footHero model =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
getStartedHero : Model -> Html Msg
|
getStartedHeader : Model -> Html Msg
|
||||||
getStartedHero _ =
|
getStartedHeader _ =
|
||||||
section
|
section
|
||||||
[ id "get-started"
|
[ id "get-started"
|
||||||
, class "hero is-primary is-bold"
|
, class "hero-header"
|
||||||
]
|
]
|
||||||
[ div [ class "hero-body" ]
|
[ text "Get Started"
|
||||||
[ div [ class "container" ]
|
|
||||||
[ h2 [ class "title" ]
|
|
||||||
[ text "Get Started"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
demoHero : Html msg
|
demoHeader : Html msg
|
||||||
demoHero =
|
demoHeader =
|
||||||
section
|
h2
|
||||||
[ id "demos"
|
[ class "hero-header"
|
||||||
, class "hero is-info is-bold"
|
, id "demos"
|
||||||
]
|
]
|
||||||
[ div
|
[ text "Screencasts"
|
||||||
[ class "hero-body"
|
|
||||||
]
|
|
||||||
[ div [ class "container" ]
|
|
||||||
[ h2 [ class "title" ]
|
|
||||||
[ text "Screencasts"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
featureHero : Model -> Html Msg
|
featureHeader : Model -> Html Msg
|
||||||
featureHero model =
|
featureHeader _ =
|
||||||
section
|
h2
|
||||||
[ id "feature-selection"
|
[ id "feature-selection"
|
||||||
, class "hero is-info is-bold"
|
, class "hero-header"
|
||||||
]
|
]
|
||||||
[ div
|
[ text "Feature Selection"
|
||||||
[ class "hero-body"
|
]
|
||||||
|
|
||||||
|
|
||||||
|
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" ]
|
[ i [ class "fa fa-bars" ] []
|
||||||
[ h2 [ class "title" ]
|
]
|
||||||
[ text "Feature Selection"
|
, 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 -> Html Msg
|
||||||
mainHero model =
|
mainHero _ =
|
||||||
section
|
section
|
||||||
[ id "hero-main"
|
[ 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" ]
|
[ navBar " text-white"
|
||||||
[ nav [ class "navbar" ]
|
, div [ class "flex-grow flex flex-col items-center justify-center w-full" ]
|
||||||
[ div [ class "navbar-brand" ]
|
[ Icons.logoWidth 112
|
||||||
[ a
|
, h1 [ class "text-6xl font-semibold shadow font-serif" ]
|
||||||
[ class "navbar-item"
|
[ text "Docspell"
|
||||||
, href "/"
|
]
|
||||||
]
|
, h2 [ class "text-3xl font-madium tracking-wide mt-2 mb-4 " ]
|
||||||
[ span [ class "icon is-large" ]
|
[ text "Simple document organizer"
|
||||||
[ Icons.logo
|
]
|
||||||
]
|
, p [ class "px-2 text-center text-xl font-light shadow max-w-prose font-sans" ]
|
||||||
, text "Docspell"
|
[ text "Docspell assists in organizing your piles of "
|
||||||
]
|
, text "digital documents, resulting from scanners, e-mails "
|
||||||
, a
|
, text "and other sources with miminal effort."
|
||||||
[ role "button"
|
]
|
||||||
, onClick ToggleNavbarMenu
|
, div
|
||||||
, classList
|
[ class "mt-4 flex flex-col space-y-2 text-2xl"
|
||||||
[ ( "navbar-burger", True )
|
, class "sm:items-center sm:flex-row sm:space-y-0 sm:space-x-4"
|
||||||
, ( "is-active", model.navbarOpen )
|
]
|
||||||
]
|
[ a
|
||||||
, ariaLabel "menu"
|
[ class "button info"
|
||||||
, ariaExpanded False
|
, href "#demos"
|
||||||
]
|
|
||||||
[ span [ ariaHidden True ] []
|
|
||||||
, span [ ariaHidden True ] []
|
|
||||||
, span [ ariaHidden True ] []
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
, div
|
[ text "Screencasts"
|
||||||
[ classList
|
|
||||||
[ ( "navbar-menu", True )
|
|
||||||
, ( "is-active", model.navbarOpen )
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
[ div [ class "navbar-start" ]
|
, a
|
||||||
[ a
|
[ class "button info"
|
||||||
[ href "docs/"
|
, href "#feature-selection"
|
||||||
, class "navbar-item"
|
]
|
||||||
]
|
[ text "Features"
|
||||||
[ span [ class "icon" ]
|
]
|
||||||
[ Icons.docs
|
, a
|
||||||
]
|
[ class "button primary"
|
||||||
, span []
|
, href "#get-started"
|
||||||
[ text "Documentation"
|
]
|
||||||
]
|
[ text "Get Started"
|
||||||
]
|
|
||||||
, a
|
|
||||||
[ target "_blank"
|
|
||||||
, href "https://github.com/eikek/docspell"
|
|
||||||
, class "navbar-item"
|
|
||||||
]
|
|
||||||
[ span [ class "icon" ]
|
|
||||||
[ Icons.github
|
|
||||||
]
|
|
||||||
, span []
|
|
||||||
[ text "Github"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "hero-body" ]
|
, div [ class "text-right w-full" ]
|
||||||
[ div
|
[ span [ class "opacity-40 text-xs" ]
|
||||||
[ class "container has-text-centered"
|
[ i [ class "fab fa-unsplash mr-1" ] []
|
||||||
]
|
, text "Photo by "
|
||||||
[ 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 "
|
|
||||||
, a
|
, a
|
||||||
[ href "https://unsplash.com/@numericcitizen"
|
[ href "https://unsplash.com/@numericcitizen"
|
||||||
, target "_blank"
|
, target "_blank"
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
port module Search exposing (..)
|
port module Search exposing (..)
|
||||||
|
|
||||||
import Browser exposing (Document)
|
import Browser
|
||||||
import Browser.Navigation exposing (Key)
|
|
||||||
import Html as H exposing (..)
|
import Html as H exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick, onInput, onSubmit)
|
import Html.Events exposing (onClick, onInput, onSubmit)
|
||||||
import Json.Decode as D
|
|
||||||
import Markdown
|
import Markdown
|
||||||
|
|
||||||
|
|
||||||
@ -45,14 +43,21 @@ type alias SearchEntry =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type SearchState
|
||||||
|
= Initial
|
||||||
|
| Found (List SearchEntry)
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
type alias Model =
|
||||||
{ searchInput : String
|
{ searchInput : String
|
||||||
, results : List SearchEntry
|
, results : SearchState
|
||||||
|
, searchVisible : Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
type Msg
|
||||||
= SetSearch String
|
= SetSearch String
|
||||||
|
| ToggleBar
|
||||||
| SubmitSearch
|
| SubmitSearch
|
||||||
| GetSearchResults (List SearchEntry)
|
| GetSearchResults (List SearchEntry)
|
||||||
|
|
||||||
@ -64,7 +69,8 @@ type Msg
|
|||||||
init : Flags -> ( Model, Cmd Msg )
|
init : Flags -> ( Model, Cmd Msg )
|
||||||
init flags =
|
init flags =
|
||||||
( { searchInput = ""
|
( { searchInput = ""
|
||||||
, results = []
|
, results = Initial
|
||||||
|
, searchVisible = False
|
||||||
}
|
}
|
||||||
, Cmd.none
|
, Cmd.none
|
||||||
)
|
)
|
||||||
@ -77,6 +83,11 @@ init flags =
|
|||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||||
update msg model =
|
update msg model =
|
||||||
case msg of
|
case msg of
|
||||||
|
ToggleBar ->
|
||||||
|
( { model | searchVisible = not model.searchVisible }
|
||||||
|
, Cmd.none
|
||||||
|
)
|
||||||
|
|
||||||
SetSearch str ->
|
SetSearch str ->
|
||||||
( { model | searchInput = str }
|
( { model | searchInput = str }
|
||||||
, Cmd.none
|
, Cmd.none
|
||||||
@ -86,7 +97,7 @@ update msg model =
|
|||||||
( model, doSearch model.searchInput )
|
( model, doSearch model.searchInput )
|
||||||
|
|
||||||
GetSearchResults list ->
|
GetSearchResults list ->
|
||||||
( { model | results = List.take 8 list }, Cmd.none )
|
( { model | results = Found <| List.take 20 list }, Cmd.none )
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
subscriptions : Model -> Sub Msg
|
||||||
@ -100,56 +111,67 @@ subscriptions _ =
|
|||||||
|
|
||||||
view : Model -> Html Msg
|
view : Model -> Html Msg
|
||||||
view model =
|
view model =
|
||||||
H.form
|
div
|
||||||
[ class "form"
|
[ class " inline-flex px-4 items-center hover:bg-amber-600 hover:bg-opacity-10 dark:hover:bg-stone-800"
|
||||||
, onSubmit SubmitSearch
|
|
||||||
]
|
]
|
||||||
[ div [ class "dropdown field is-active is-fullwidth has-addons" ]
|
[ a
|
||||||
[ div [ class "control is-fullwidth" ]
|
[ 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
|
[ input
|
||||||
[ class "input"
|
[ type_ "text"
|
||||||
, type_ "text"
|
|
||||||
, placeholder "Search docs…"
|
|
||||||
, onInput SetSearch
|
|
||||||
, value model.searchInput
|
, 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 model.results
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewResults : List SearchEntry -> Html Msg
|
viewResults : SearchState -> Html Msg
|
||||||
viewResults entries =
|
viewResults state =
|
||||||
div
|
case state of
|
||||||
[ classList
|
Initial ->
|
||||||
[ ( "dropdown-menu", True )
|
span [ class "hidden" ] []
|
||||||
, ( "is-hidden", entries == [] )
|
|
||||||
]
|
Found [] ->
|
||||||
]
|
div
|
||||||
[ div [ class "dropdown-content" ]
|
[ class "bg-white dark:bg-stone-800 mt-2 w-full"
|
||||||
(List.intersperse
|
]
|
||||||
(div [ class "dropdown-divider" ] [])
|
[ div [ class "flex flex-row items-center h-14 justify-center text-xl" ]
|
||||||
(List.map viewResult entries)
|
[ 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 : SearchEntry -> Html Msg
|
||||||
viewResult result =
|
viewResult result =
|
||||||
div [ class "dropdown-item" ]
|
div [ class "py-2 content" ]
|
||||||
[ a
|
[ a
|
||||||
[ class "is-size-5"
|
[ class "text-lg font-semibold"
|
||||||
, href result.ref
|
, href result.ref
|
||||||
]
|
]
|
||||||
[ text result.doc.title
|
[ 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
|
--- Ports
|
||||||
|
|
||||||
|
@ -1,6 +1,17 @@
|
|||||||
{
|
{
|
||||||
"license": "GPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"dependencies": {
|
"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
|
set -e
|
||||||
|
|
||||||
yarn install
|
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
|
elm make --output site/static/js/bundle.js --optimize elm/Main.elm
|
||||||
cd site && zola build
|
cd site && zola build
|
||||||
cd ..
|
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
|
let
|
||||||
nixpkgs = builtins.fetchTarball {
|
nixpkgs = builtins.fetchTarball {
|
||||||
#url = "channel:nixos-21.05";
|
#url = "channel:nixos-21.11";
|
||||||
url = "https://github.com/NixOS/nixpkgs/archive/e6badb26fc0d238fda2432c45b7dd4e782eb8200.tar.gz";
|
#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 { };
|
pkgs = import nixpkgs { };
|
||||||
in
|
in
|
||||||
@ -11,6 +12,9 @@ with pkgs;
|
|||||||
buildInputs = [
|
buildInputs = [
|
||||||
zola
|
zola
|
||||||
yarn
|
yarn
|
||||||
|
sbt
|
||||||
|
elmPackages.elm
|
||||||
|
nodejs
|
||||||
inotifyTools
|
inotifyTools
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,13 @@ default_language = "en"
|
|||||||
|
|
||||||
[markdown]
|
[markdown]
|
||||||
highlight_code = true
|
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]
|
[link_checker]
|
||||||
skip_prefixes = [
|
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"
|
title = "Documentation"
|
||||||
template = "overview.html"
|
template = "docs.html"
|
||||||
|
page_template = "docs.html"
|
||||||
insert_anchor_links = "right"
|
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."
|
description = "Contains documentation about the REST API."
|
||||||
weight = 70
|
weight = 70
|
||||||
insert_anchor_links = "right"
|
insert_anchor_links = "right"
|
||||||
template = "pages.html"
|
template = "docs.html"
|
||||||
sort_by = "weight"
|
sort_by = "weight"
|
||||||
redirect_to = "docs/api/intro"
|
|
||||||
+++
|
+++
|
||||||
|
|
||||||
No Content
|
|
||||||
|
@ -3,10 +3,10 @@ title = "Api Introduction"
|
|||||||
description = "Api Basics"
|
description = "Api Basics"
|
||||||
weight = 10
|
weight = 10
|
||||||
insert_anchor_links = "right"
|
insert_anchor_links = "right"
|
||||||
[extra]
|
|
||||||
mktoc = true
|
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# Api
|
||||||
|
|
||||||
Docspell is designed as a REST server that uses JSON to exchange
|
Docspell is designed as a REST server that uses JSON to exchange
|
||||||
data. The REST api can be used to integrate docspell into your
|
data. The REST api can be used to integrate docspell into your
|
||||||
workflow.
|
workflow.
|
||||||
|
@ -3,10 +3,10 @@ title = "Upload Request"
|
|||||||
description = "Describes the upload request"
|
description = "Describes the upload request"
|
||||||
weight = 20
|
weight = 20
|
||||||
insert_anchor_links = "right"
|
insert_anchor_links = "right"
|
||||||
[extra]
|
|
||||||
mktoc = true
|
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# Upload Request
|
||||||
|
|
||||||
Uploads of files to docspell are always processed the same way, no
|
Uploads of files to docspell are always processed the same way, no
|
||||||
matter if coming from a source, the integration endpoint or from the
|
matter if coming from a source, the integration endpoint or from the
|
||||||
webapp.
|
webapp.
|
||||||
|
@ -3,10 +3,11 @@ title = "Configuration"
|
|||||||
insert_anchor_links = "right"
|
insert_anchor_links = "right"
|
||||||
description = "Describes the configuration file and shows all default settings."
|
description = "Describes the configuration file and shows all default settings."
|
||||||
weight = 40
|
weight = 40
|
||||||
[extra]
|
template = "docs.html"
|
||||||
mktoc = true
|
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
|
||||||
Docspell's executables (restserver and joex) can take one argument – a
|
Docspell's executables (restserver and joex) can take one argument – a
|
||||||
configuration file. If that is not given, the defaults are used,
|
configuration file. If that is not given, the defaults are used,
|
||||||
overriden by environment variables. A config file overrides default
|
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
|
weight = 300
|
||||||
sort_by = "weight"
|
sort_by = "weight"
|
||||||
insert_anchor_links = "right"
|
insert_anchor_links = "right"
|
||||||
template = "pages.html"
|
template = "docs.html"
|
||||||
|
page_template = "docs.html"
|
||||||
[extra]
|
[extra]
|
||||||
mktoc = true
|
page_list = true
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# ADR
|
||||||
|
|
||||||
This contains a list of ADRs, most of them are from very early. It
|
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
|
often just contains notes that could go nowhere else, but still should
|
||||||
be captured.
|
be captured.
|
||||||
|
@ -3,6 +3,7 @@ title = "Building Docspell"
|
|||||||
weight = 0
|
weight = 0
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# Building
|
||||||
|
|
||||||
You must install [sbt](https://scala-sbt.org),
|
You must install [sbt](https://scala-sbt.org),
|
||||||
[nodejs](https://www.npmjs.com/get-npm) (for the `npm` command) and
|
[nodejs](https://www.npmjs.com/get-npm) (for the `npm` command) and
|
||||||
|
@ -3,7 +3,9 @@ title = "Tips & Setup"
|
|||||||
weight = 20
|
weight = 20
|
||||||
+++
|
+++
|
||||||
|
|
||||||
# Starting Servers with `reStart`
|
# Setup / Tips
|
||||||
|
|
||||||
|
## Starting Servers with `reStart`
|
||||||
|
|
||||||
When developing, it's very convenient to use the [revolver sbt
|
When developing, it's very convenient to use the [revolver sbt
|
||||||
plugin](https://github.com/spray/sbt-revolver). Start the sbt console
|
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
|
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
|
`local` (at root of the source tree) is picked up as config file, if
|
||||||
|
@ -3,6 +3,7 @@ title = "Translating Web-UI"
|
|||||||
weight = 10
|
weight = 10
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# UI Translation
|
||||||
|
|
||||||
Help with translating the web-ui is greatly appreciated. I can only
|
Help with translating the web-ui is greatly appreciated. I can only
|
||||||
provide translations for English and German, and these may be wrong -
|
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.
|
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:
|
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.
|
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
|
If sbt is not started, start sbt from within the source root. Also
|
||||||
export the `DOCSPELL_ENV` variable *before* starting sbt:
|
export the `DOCSPELL_ENV` variable *before* starting sbt:
|
||||||
|
@ -3,8 +3,8 @@ title = "FAQ"
|
|||||||
weight = 100
|
weight = 100
|
||||||
description = "Frequently asked questions."
|
description = "Frequently asked questions."
|
||||||
insert_anchor_links = "right"
|
insert_anchor_links = "right"
|
||||||
|
template = "docs.html"
|
||||||
[extra]
|
[extra]
|
||||||
mktoc = true
|
|
||||||
+++
|
+++
|
||||||
|
|
||||||
# FAQ
|
# FAQ
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
+++
|
+++
|
||||||
title = "Features and Limitations"
|
title = "Features and Limitations"
|
||||||
weight = 10
|
weight = 9
|
||||||
insert_anchor_links = "right"
|
insert_anchor_links = "right"
|
||||||
description = "A list of features and limitations."
|
description = "A list of features and limitations."
|
||||||
|
template = "docs.html"
|
||||||
+++
|
+++
|
||||||
|
|
||||||
# Features
|
# Features
|
||||||
@ -20,7 +21,7 @@ description = "A list of features and limitations."
|
|||||||
- A powerful [query language](@/docs/query/_index.md) to find
|
- A powerful [query language](@/docs/query/_index.md) to find
|
||||||
documents
|
documents
|
||||||
- use [bookmarks](@/docs/webapp/bookmarks.md) to save more complex queries
|
- 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
|
- Non-destructive: all your uploaded files are never modified and can
|
||||||
always be downloaded untouched
|
always be downloaded untouched
|
||||||
- Organize files using tags, folders, [Custom
|
- Organize files using tags, folders, [Custom
|
||||||
@ -80,8 +81,6 @@ description = "A list of features and limitations."
|
|||||||
files, watch folders and many more!
|
files, watch folders and many more!
|
||||||
- [Android App](@/docs/tools/android.md) to quickly upload files
|
- [Android App](@/docs/tools/android.md) to quickly upload files
|
||||||
from your android devices
|
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
|
- [SMTP Gateway](@/docs/tools/smtpgateway.md): Setup a SMTP server
|
||||||
that delivers mails directly to docspell.
|
that delivers mails directly to docspell.
|
||||||
- License: AGPLv3
|
- License: AGPLv3
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
+++
|
+++
|
||||||
title = "Feed Data into Docspell"
|
title = "Feed Data into Docspell"
|
||||||
weight = 5
|
weight = 8
|
||||||
description = "Shows several ways for getting data into Docspell."
|
description = "Shows several ways for getting data into Docspell."
|
||||||
insert_anchor_links = "right"
|
insert_anchor_links = "right"
|
||||||
|
template = "docs.html"
|
||||||
[extra]
|
[extra]
|
||||||
mktoc = true
|
mktoc = true
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# Documents → Docspell
|
||||||
|
|
||||||
One of the main goals is to stow documents away quickly.
|
One of the main goals is to stow documents away quickly.
|
||||||
|
|
||||||
Docspell makes no assumptions about where your documents are. It
|
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:
|
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
|
This is the simplest way, but also the least flexible. You can just
|
||||||
login and go to the upload page to submit files.
|
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
|
This requires to login at the webapp. Since this is complicated from
|
||||||
other applications, you can create custom hard-to-guess endpoints to
|
other applications, you can create custom hard-to-guess endpoints to
|
||||||
use with the following options.
|
use with the following options.
|
||||||
|
|
||||||
# Scanners / Watch Directories
|
## Scanners / Watch Directories
|
||||||
|
|
||||||
If you have a (document) scanner (or think about getting one), it can
|
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
|
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
|
files from scanners with ADF, applying corrections and sending them to
|
||||||
docspell.
|
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
|
There is an [android
|
||||||
client](https://github.com/docspell/android-client) provided that lets
|
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
|
This is especially useful to quickly upload small things like shopping
|
||||||
receipts.
|
receipts.
|
||||||
|
|
||||||
<div class="columns is-centered">
|
<div class="grid grid-cols-2 gap-8 divide-x ">
|
||||||
<div class="column is-one-third">
|
<div class="flex items-center justify-center">
|
||||||
<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">
|
|
||||||
<a href="https://f-droid.org/packages/org.docspell.docspellshare">
|
<a href="https://f-droid.org/packages/org.docspell.docspellshare">
|
||||||
<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
|
<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>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="column is-one-third">
|
<div class="flex items-center justify-center text-xl">
|
||||||
Download the APK from <a href="https://github.com/docspell/android-client/releases/latest">here</a>
|
<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>
|
||||||
|
|
||||||
</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,
|
Your mailbox can be polled periodically to import mails. For example,
|
||||||
create a dedicated folder in your e-mail client and move mails in
|
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
|
there that you want to push to Docspell. You can then define a
|
||||||
recurring job, that looks into this folders and imports the mails.
|
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
|
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
|
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
|
There is a docker container prepared to get started. Click below to
|
||||||
read more.
|
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
|
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
|
for some tasks, for example uploading files. Below is a quick demo, it
|
||||||
supports many more options, see the link below for details.
|
supports many more options, see the link below for details.
|
||||||
|
|
||||||
<div class="columns is-centered is-full-width">
|
<figure>
|
||||||
<div class="column">
|
<script id="asciicast-427679" src="https://asciinema.org/a/427679.js" async></script>
|
||||||
<script id="asciicast-427679" src="https://asciinema.org/a/427679.js" async></script>
|
</figure>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{{ buttonright(classes="is-primary ", href="/docs/tools/cli", text="More") }}
|
{{ buttonright(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") }}
|
|
||||||
|
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."
|
description = "There are multiple ways to install Docspell. This section contains detailed instructions."
|
||||||
weight = 30
|
weight = 5
|
||||||
sort_by = "weight"
|
sort_by = "weight"
|
||||||
insert_anchor_links = "right"
|
insert_anchor_links = "right"
|
||||||
template = "pages.html"
|
template = "docs.html"
|
||||||
|
page_template = "docs.html"
|
||||||
redirect_to = "/docs/install/quickstart"
|
redirect_to = "/docs/install/quickstart"
|
||||||
+++
|
+++
|
||||||
|
@ -3,7 +3,7 @@ title = "Docker"
|
|||||||
weight = 20
|
weight = 20
|
||||||
+++
|
+++
|
||||||
|
|
||||||
## Docker Images
|
# Docker Images
|
||||||
|
|
||||||
The docker images are at
|
The docker images are at
|
||||||
[hub.docker.com](https://hub.docker.com/u/docspell). The `latest` tag
|
[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
|
is used to watch a directory for uploading files. This runs the `dsc
|
||||||
watch` command.
|
watch` command.
|
||||||
|
|
||||||
### Examples
|
## Examples
|
||||||
|
|
||||||
These examples use `docker run` to start the restserver and
|
These examples use `docker run` to start the restserver and
|
||||||
jobexecutor. Both must be connected to the same database. For this
|
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
|
appropriate tools, for example `docker-compose` which is explained
|
||||||
below.
|
below.
|
||||||
|
|
||||||
## Docker Compose
|
# Docker Compose
|
||||||
|
|
||||||
There is a [docker-compose](https://docs.docker.com/compose/) setup
|
There is a [docker-compose](https://docs.docker.com/compose/) setup
|
||||||
available in the `/docker/docker-compose` folder. This setup is
|
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
|
PostgreSQL database by using just one command. It's only a few steps
|
||||||
to get started.
|
to get started.
|
||||||
|
|
||||||
### Start Docspell
|
## Start Docspell
|
||||||
#### 1. Get the docker-compose files
|
### 1. Get the docker-compose files
|
||||||
|
|
||||||
There are two options. You can clone the whole repository:
|
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
|
make the rest of the guide work for both ways of obtaining the
|
||||||
docker-compose file.
|
docker-compose file.
|
||||||
|
|
||||||
#### 2. Run `docker-compose up`
|
### 2. Run `docker-compose up`
|
||||||
|
|
||||||
Change into the new `docker-compose` directory, for example:
|
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:`
|
to the service definition (or add it to an existing `command:`
|
||||||
section).
|
section).
|
||||||
|
|
||||||
### Override this setup
|
## Override this setup
|
||||||
|
|
||||||
If you want to change this setup, you can simply use your own compose
|
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
|
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,
|
Since [downgrading](@/docs/install/downgrading.md) is not supported,
|
||||||
it is recommended to backup your database before upgrading. Should
|
it is recommended to backup your database before upgrading. Should
|
||||||
@ -267,7 +267,7 @@ $ docker-compose pull
|
|||||||
$ docker-compose up --force-recreate --build -d
|
$ docker-compose up --force-recreate --build -d
|
||||||
```
|
```
|
||||||
|
|
||||||
### Backups
|
## Backups
|
||||||
|
|
||||||
When running the docker compose setup, you can use the following to
|
When running the docker compose setup, you can use the following to
|
||||||
backup the database.
|
backup the database.
|
||||||
|
@ -3,7 +3,9 @@ title = "Downgrading"
|
|||||||
weight = 37
|
weight = 37
|
||||||
+++
|
+++
|
||||||
|
|
||||||
{% infobubble(mode="info", title="⚠ Please note") %}
|
# Downgrading
|
||||||
|
|
||||||
|
{% warningbubble(title="Note") %}
|
||||||
Downgrading is currently not supported!
|
Downgrading is currently not supported!
|
||||||
|
|
||||||
It is not safe to install a previous version, because the database
|
It is not safe to install a previous version, because the database
|
||||||
|
@ -3,24 +3,23 @@ title = "Download & Run"
|
|||||||
weight = 22
|
weight = 22
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# Download and Run
|
||||||
|
|
||||||
You can install via zip or deb archives. Please see the
|
You can install via zip or deb archives. Please see the
|
||||||
[prerequisites](@/docs/install/prereq.md) first.
|
[prerequisites](@/docs/install/prereq.md) first.
|
||||||
|
|
||||||
## Using zip files
|
## Using zip files
|
||||||
|
|
||||||
You need to download the two 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>
|
||||||
- [docspell-restserver-{{version()}}.zip](https://github.com/eikek/docspell/releases/download/v{{version()}}/docspell-restserver-{{version()}}.zip)
|
- <a href="https://github.com/eikek/docspell/releases/download/v{{version()}}/docspell-joex-{{version()}}.zip">docspell-joex-{{version()}}.zip</a>
|
||||||
- [docspell-joex-{{version()}}.zip](https://github.com/eikek/docspell/releases/download/v{{version()}}/docspell-joex-{{version()}}.zip)
|
2. Unzip both files:
|
||||||
|
|
||||||
|
|
||||||
1. Unzip both files:
|
|
||||||
``` bash
|
``` bash
|
||||||
$ unzip docspell-*.zip
|
$ 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.
|
containing the zip files.
|
||||||
3. Start both components executing:
|
4. Start both components executing:
|
||||||
``` bash
|
``` bash
|
||||||
$ ./docspell-restserver*/bin/docspell-restserver
|
$ ./docspell-restserver*/bin/docspell-restserver
|
||||||
```
|
```
|
||||||
@ -29,8 +28,8 @@ You need to download the two files:
|
|||||||
$ ./docspell-joex*/bin/docspell-joex
|
$ ./docspell-joex*/bin/docspell-joex
|
||||||
```
|
```
|
||||||
in the other.
|
in the other.
|
||||||
4. Point your browser to: <http://localhost:7880/app>
|
5. Point your browser to: <http://localhost:7880/app>
|
||||||
5. Register a new account, sign in and try it.
|
6. Register a new account, sign in and try it.
|
||||||
|
|
||||||
Note, that this setup doesn't include watching a directory nor
|
Note, that this setup doesn't include watching a directory nor
|
||||||
fulltext search. Using zip/deb files requires to take care of the
|
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.
|
no deb files provided.
|
||||||
|
|
||||||
|
|
||||||
## Running
|
# Running
|
||||||
|
|
||||||
Run the start script (in the corresponding `bin/` directory when using
|
Run the start script (in the corresponding `bin/` directory when using
|
||||||
the zip files):
|
the zip files):
|
||||||
|
@ -3,6 +3,7 @@ title = "Nix / NixOS"
|
|||||||
weight = 24
|
weight = 24
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# Nix
|
||||||
|
|
||||||
## Install via Nix
|
## Install via Nix
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ back to the previous version.
|
|||||||
When using the provided nix setup, the `currentPkg` always points to
|
When using the provided nix setup, the `currentPkg` always points to
|
||||||
the latest release. Thus it is enough to run `nix-build`.
|
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
|
If you are running [NixOS](https://nixos.org), there is a module
|
||||||
definition for installing Docspell as a service using systemd.
|
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
|
Docspell. If you really need an older version, checkout the
|
||||||
appropriate commit.
|
appropriate commit.
|
||||||
|
|
||||||
### NixOS Example
|
## NixOS Example
|
||||||
|
|
||||||
This is a example system configuration that installs docspell with a
|
This is a example system configuration that installs docspell with a
|
||||||
postgres database. This snippet can be used to create a vm (using
|
postgres database. This snippet can be used to create a vm (using
|
||||||
|
@ -3,6 +3,8 @@ title = "Prerequisites"
|
|||||||
weight = 10
|
weight = 10
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# Prerequisites
|
||||||
|
|
||||||
The two components have one prerequisite in common: they both require
|
The two components have one prerequisite in common: they both require
|
||||||
Java to run. While this is the only requirement for the *REST server*,
|
Java to run. While this is the only requirement for the *REST server*,
|
||||||
the *Joex* components requires some more external programs.
|
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
|
The rest server and joex components are not required to "see" each
|
||||||
other, though it is recommended.
|
other, though it is recommended.
|
||||||
|
|
||||||
# Java
|
## Java
|
||||||
|
|
||||||
Very often, Java is already installed. You can check this by opening a
|
Very often, Java is already installed. You can check this by opening a
|
||||||
terminal and typing `java -version`. Otherwise install Java using your
|
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*
|
The next tools are only required on machines running the *Joex*
|
||||||
component.
|
component.
|
||||||
|
|
||||||
# External Programs for Joex
|
## External Programs for Joex
|
||||||
|
|
||||||
- [Ghostscript](http://pages.cs.wisc.edu/~ghost/) (the `gs` command)
|
- [Ghostscript](http://pages.cs.wisc.edu/~ghost/) (the `gs` command)
|
||||||
is used to extract/convert PDF files into images that are then fed
|
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
|
in a separate process. This runs a libreoffice/openoffice listener and
|
||||||
therefore avoids starting one each time `unoconv` is called.
|
therefore avoids starting one each time `unoconv` is called.
|
||||||
|
|
||||||
## Example Debian
|
### Example Debian
|
||||||
|
|
||||||
On Debian this should install all joex requirements:
|
On Debian this should install all joex requirements:
|
||||||
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
+++
|
+++
|
||||||
title = "Quickstart"
|
title = "Getting started"
|
||||||
weight = 0
|
weight = 0
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# Getting started
|
||||||
|
|
||||||
To get started, here are some quick links:
|
To get started, here are some quick links:
|
||||||
|
|
||||||
- Using [docker and docker-compose](@/docs/install/docker.md). This
|
- 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
|
thread](https://forums.unraid.net/topic/103425-docspell-hilfe/) in
|
||||||
the German Unraid forum. Thanks for providing these!
|
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.
|
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
|
Most of the time running all on one machine is sufficient and also for
|
||||||
simplicity, the docker-compose setup reflects this variant.
|
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
|
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.
|
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,
|
Please have a look at the [configuration page](/docs/configure/) page,
|
||||||
before making docspell publicly available. By default, everyone can
|
before making docspell publicly available. By default, everyone can
|
||||||
|
@ -3,6 +3,8 @@ title = "Reverse Proxy"
|
|||||||
weight = 50
|
weight = 50
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# Reverse Proxy
|
||||||
|
|
||||||
This contains examples for how to use docspell behind a reverse proxy.
|
This contains examples for how to use docspell behind a reverse proxy.
|
||||||
|
|
||||||
For the examples below, assume the following:
|
For the examples below, assume the following:
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
+++
|
+++
|
||||||
title = "Raspberry-Pi and Similiar"
|
title = "Raspberry-Pi"
|
||||||
weight = 40
|
weight = 40
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# Raspberry Pi
|
||||||
|
|
||||||
Both components can run next to each other on a raspberry pi or
|
Both components can run next to each other on a raspberry pi or
|
||||||
similiar device.
|
similiar device.
|
||||||
|
|
||||||
|
@ -3,149 +3,8 @@ title = "Introduction"
|
|||||||
weight = 0
|
weight = 0
|
||||||
description = "Gives a short introduction to the goals of docspell and an overview of the components involved."
|
description = "Gives a short introduction to the goals of docspell and an overview of the components involved."
|
||||||
insert_anchor_links = "right"
|
insert_anchor_links = "right"
|
||||||
|
redirect_to = "/docs/"
|
||||||
[extra]
|
[extra]
|
||||||
mktoc = true
|
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
|
mktoc = true
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# File Processing
|
||||||
|
|
||||||
When uploading a file, it is only saved to the database together with
|
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
|
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.
|
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
|
When this is changed, you must re-generate all preview images. Check
|
||||||
the api for this, there is an endpoint to regenerate all preview
|
the api for this, there is an endpoint to regenerate all preview
|
||||||
|
@ -7,7 +7,8 @@ insert_anchor_links = "right"
|
|||||||
mktoc = true
|
mktoc = true
|
||||||
+++
|
+++
|
||||||
|
|
||||||
# Introduction
|
# Joex
|
||||||
|
## Introduction
|
||||||
|
|
||||||
Joex is short for *Job Executor* and it is the component managing long
|
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
|
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
|
and no job is waiting in the queue, joex will sleep until notified
|
||||||
again. It will also periodically notify itself as a fallback.
|
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
|
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,
|
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.
|
while a task is just code.
|
||||||
|
|
||||||
|
|
||||||
# Scheduler and Queue
|
## Scheduler and Queue
|
||||||
|
|
||||||
The scheduler is the part that runs and monitors the long running
|
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
|
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.
|
logged in.
|
||||||
|
|
||||||
|
|
||||||
# Scheduler Config
|
## Scheduler Config
|
||||||
|
|
||||||
The relevant part of the config file regarding the scheduler is shown
|
The relevant part of the config file regarding the scheduler is shown
|
||||||
below with some explanations.
|
below with some explanations.
|
||||||
@ -130,7 +131,7 @@ reach a joex component. This periodic wakup is just to ensure that
|
|||||||
jobs are eventually run.
|
jobs are eventually run.
|
||||||
|
|
||||||
|
|
||||||
# Periodic Tasks
|
## Periodic Tasks
|
||||||
|
|
||||||
The job executor can execute tasks periodically. These tasks are
|
The job executor can execute tasks periodically. These tasks are
|
||||||
stored in the database such that they can be submitted into the job
|
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.
|
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
|
The job executor and rest server can be started multiple times. This
|
||||||
is especially useful for the job executor. For example, when
|
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.
|
executors.
|
||||||
|
|
||||||
|
|
||||||
# Shutting down
|
## Shutting down
|
||||||
|
|
||||||
If a job executor is sleeping and not executing any jobs, you can just
|
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
|
quit using SIGTERM or `Ctrl-C` when running in a terminal. But if
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
+++
|
+++
|
||||||
title = "JSON (mini) query"
|
title = "JSON (mini) query"
|
||||||
|
weight = 58
|
||||||
|
template = "docs.html"
|
||||||
|
page_template = "docs.html"
|
||||||
|
|
||||||
[extra]
|
[extra]
|
||||||
mktoc = true
|
|
||||||
hidden = true
|
hidden = true
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# JSON Miniquery
|
||||||
|
|
||||||
A "JSON mini query" is a simple expression that evaluates to `true` or
|
A "JSON mini query" is a simple expression that evaluates to `true` or
|
||||||
`false` for any given JSON value.
|
`false` for any given JSON value.
|
||||||
|
|
||||||
|
@ -3,15 +3,14 @@ title = "Query Language"
|
|||||||
weight = 55
|
weight = 55
|
||||||
description = "The query language is a powerful way to search for documents."
|
description = "The query language is a powerful way to search for documents."
|
||||||
insert_anchor_links = "right"
|
insert_anchor_links = "right"
|
||||||
[extra]
|
template = "docs.html"
|
||||||
mktoc = true
|
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# Query Language
|
||||||
|
|
||||||
Docspell uses a query language to provide a powerful way to search for
|
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
|
your documents. It currently needs to be enabled explicitely in your
|
||||||
enabled explicitely in your user settings to be used on the search
|
user settings to be used on the search page.
|
||||||
page.
|
|
||||||
|
|
||||||
<div class="colums">
|
<div class="colums">
|
||||||
|
|
||||||
|
@ -6,6 +6,4 @@ insert_anchor_links = "right"
|
|||||||
template = "pages.html"
|
template = "pages.html"
|
||||||
redirect_to = "docs/tools/cli/"
|
redirect_to = "docs/tools/cli/"
|
||||||
sort_by = "weight"
|
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
|
from your android devices. Combined with a scanner app, this allows to
|
||||||
very quickly scan single page documents like receipts.
|
very quickly scan single page documents like receipts.
|
||||||
|
|
||||||
<div class="columns is-vcentered is-centered">
|
<div class="grid grid-cols-2 gap-8 divide-x ">
|
||||||
<div class="column">
|
<div class="flex items-center justify-center">
|
||||||
<a href="https://f-droid.org/packages/org.docspell.docspellshare">
|
<a href="https://f-droid.org/packages/org.docspell.docspellshare">
|
||||||
<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
|
<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
|
||||||
alt="Get it on F-Droid"
|
alt="Get it on F-Droid"
|
||||||
style="height:120px;"/>
|
class="w-56"
|
||||||
|
/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="flex items-center justify-center text-xl">
|
||||||
Download the APK from <a href="https://github.com/docspell/android-client/releases/latest">here</a>
|
<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>
|
||||||
|
|
||||||
</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
|
- You can now either select an URL from the app, or the upload begins
|
||||||
immediatly if you set a default URL.
|
immediatly if you set a default URL.
|
||||||
|
|
||||||
<div class="columns">
|
<div class="grid grid-cols-3 gap-4 mx-6 my-4">
|
||||||
<div class="column">
|
<div class="shadow dark:shadow-stone-600">
|
||||||
{{ imgnormal(file="screenshot-create.jpg", width="") }}
|
{{ imgnormal(file="screenshot-create.jpg", width="") }}
|
||||||
<p class="has-text-centered subtitle"> (A) </p>
|
<p class="text-center font-mono"> (A) </p>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="box-shadow">
|
||||||
{{ imgnormal(file="screenshot-choose.jpg", width="") }}
|
{{ imgnormal(file="screenshot-choose.jpg", width="") }}
|
||||||
<p class="has-text-centered subtitle"> (B) </p>
|
<p class="text-center font-mono"> (B) </p>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="box-shadow">
|
||||||
{{ imgnormal(file="screenshot-options.jpg", width="") }}
|
{{ 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>
|
<div class="box-shadow">
|
||||||
<div class="columns">
|
|
||||||
<div class="column">
|
|
||||||
{{ imgnormal(file="screenshot-default.jpg", width="") }}
|
{{ imgnormal(file="screenshot-default.jpg", width="") }}
|
||||||
<p class="has-text-centered subtitle"> (D) </p>
|
<p class="text-center font-mono"> (D) </p>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="box-shadow">
|
||||||
{{ imgnormal(file="screenshot-share.jpg", width="") }}
|
{{ imgnormal(file="screenshot-share.jpg", width="") }}
|
||||||
<p class="has-text-centered subtitle"> (E) </p>
|
<p class="text-center font-mono"> (E) </p>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="box-shadow">
|
||||||
{{ imgnormal(file="screenshot-uploading.jpg", width="") }}
|
{{ imgnormal(file="screenshot-uploading.jpg", width="") }}
|
||||||
<p class="has-text-centered subtitle"> (F) </p>
|
<p class="text-center font-mono"> (F) </p>
|
||||||
</div>
|
</div>
|
||||||
</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
|
weight = 5
|
||||||
+++
|
+++
|
||||||
|
|
||||||
# Introduction
|
# Docspell CLI
|
||||||
|
## Introduction
|
||||||
|
|
||||||
The **d**oc**s**pell **c**lient, short
|
The **d**oc**s**pell **c**lient, short
|
||||||
[dsc](https://github.com/docspell/dsc), is a tool to use
|
[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
|
It is a work in progress; eventually most of the
|
||||||
[api](@/docs/api/_index.md) will be covered.
|
[api](@/docs/api/_index.md) will be covered.
|
||||||
|
|
||||||
# Usage
|
## Usage
|
||||||
|
|
||||||
Download the binary for your architecture from the [release
|
Download the binary for your architecture from the [release
|
||||||
page](https://github.com/docspell/dsc/releases/latest) and rename it
|
page](https://github.com/docspell/dsc/releases/latest) and rename it
|
||||||
@ -86,11 +87,9 @@ you need to `login` again.
|
|||||||
|
|
||||||
## Demo
|
## Demo
|
||||||
|
|
||||||
<div class="columns is-centered is-full-width">
|
<figure>
|
||||||
<div class="column">
|
<script id="asciicast-427679" src="https://asciinema.org/a/427679.js" async></script>
|
||||||
<script id="asciicast-427679" src="https://asciinema.org/a/427679.js" async></script>
|
</figure>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
# Use Cases / Examples
|
# Use Cases / Examples
|
||||||
|
@ -4,7 +4,9 @@ description = "Import your data from paperless."
|
|||||||
weight = 60
|
weight = 60
|
||||||
+++
|
+++
|
||||||
|
|
||||||
# Introduction
|
# Import from Paperless
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
Coming from
|
Coming from
|
||||||
[paperless](https://github.com/the-paperless-project/paperless/), the
|
[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.
|
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
|
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
|
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 %}
|
{% end %}
|
||||||
|
|
||||||
# Usage
|
## Usage
|
||||||
|
|
||||||
Copy the script to the machine where paperless is running. Run it with
|
Copy the script to the machine where paperless is running. Run it with
|
||||||
the following arguments:
|
the following arguments:
|
||||||
|
@ -4,6 +4,8 @@ description = "Start a SMTP server that forwards all mails to docspell."
|
|||||||
weight = 50
|
weight = 50
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# SMTP Gateway with Exim
|
||||||
|
|
||||||
One possible use case for the [integration
|
One possible use case for the [integration
|
||||||
endpoint](@/docs/api/upload.md#integration-endpoint) is a SMTP server
|
endpoint](@/docs/api/upload.md#integration-endpoint) is a SMTP server
|
||||||
that forwards all local mail to docspell. This way there is no
|
that forwards all local mail to docspell. This way there is no
|
||||||
|
@ -5,6 +5,7 @@ weight = 90
|
|||||||
mktoc = true
|
mktoc = true
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# Auto-Tagging
|
||||||
|
|
||||||
Auto-Tagging must be enabled in the collective profile. Docspell can
|
Auto-Tagging must be enabled in the collective profile. Docspell can
|
||||||
go through your items periodically and learn from your existing tags.
|
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
|
Docspell could learn relationships that are not correct and then tag
|
||||||
the next incoming items with `Done`.
|
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
|
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
|
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
|
mktoc = true
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# Bookmarks
|
||||||
|
|
||||||
Bookmarks allow you to save queries under a name and refer to it from the search menu.
|
Bookmarks allow you to save queries under a name and refer to it from the search menu.
|
||||||
|
|
||||||
## Creating bookmarks
|
## 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
|
Bookmarks can be created from the search view. Apply some criteria to
|
||||||
select items and then click on the top left menu.
|
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
|
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
|
adjust the query and enter the name. You can also decide whether this
|
||||||
bookmark is for all users or just for you.
|
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
|
The other way is to go to *Manage Data* where you can edit and delete
|
||||||
existing bookmarks and also create new ones.
|
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
|
"enables" it, meaning the query is used in conjunction with other
|
||||||
criteria.
|
criteria.
|
||||||
|
|
||||||
<div class="columns is-centered">
|
<div class="flex items-center justify-center">
|
||||||
{{ imgnormal(file="bookmarks-01.png", width="") }}
|
{{ imgnormal2(light="bookmarks-01.png", dark="bookmarks-01_dark.png", width="") }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
An active bookmark has a check icon next to its name.
|
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
|
The *Manage Data* page has a section for bookmarks. There you can
|
||||||
delete and edit bookmarks.
|
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
|
The personal bookmarks are only visible to you. The collective
|
||||||
bookmarks are visible to every user in the collective, which also
|
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
|
weight = 20
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# Curate items
|
||||||
|
|
||||||
Curating the items meta data helps finding them later. This page
|
Curating the items meta data helps finding them later. This page
|
||||||
describes how you can quickly go through those items and correct or
|
describes how you can quickly go through those items and correct or
|
||||||
amend with existing data.
|
amend with existing data.
|
||||||
|
|
||||||
# Select New items
|
## Select New items
|
||||||
|
|
||||||
After files have been uploaded and the job executor created the
|
After files have been uploaded and the job executor created the
|
||||||
corresponding items, they will show up on the main page. All items 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
|
option *Inbox* in the left search menu can be used to select only new
|
||||||
items:
|
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
|
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
|
on the first item to open the detail view. This shows the documents
|
||||||
and the meta data in the header.
|
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.
|
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
|
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
|
state *New* the left menu is fully expanded so you see all suggestions
|
||||||
immediatly.
|
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.
|
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
|
It is also possible to change tags and folders in the list view via
|
||||||
drag&drop.
|
drag&drop.
|
||||||
|
|
||||||
<div class="columns is-centered">
|
<div class="flex items-center justify-center">
|
||||||
<div class="column is-narrow">
|
{{ imgnormal2(light="drop-tag.png", dark="drop-tag_dark.png", width="500px") }}
|
||||||
{{ imgnormal(file="drop-tag.png", width="500px") }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
# Confirm
|
## Confirm
|
||||||
|
|
||||||
If everything looks good, click the *Confirm* button to confirm the
|
If everything looks good, click the *Confirm* button to confirm the
|
||||||
current data. The *New* status goes away and also the suggestions are
|
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.
|
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*
|
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
|
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
|
are on the last item, the view switches to the listing view when
|
||||||
clicking *Next*.
|
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
|
weight = 18
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# Custom Fields
|
||||||
|
|
||||||
Custom fields allow to attach user defined metadata to items. For
|
Custom fields allow to attach user defined metadata to items. For
|
||||||
example, you may want to track the amount of each receipt or the
|
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
|
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
|
Go to the _Manage Data_ page, that can be reached from the top right
|
||||||
menu. One entry at the left shows _Custom Fields_:
|
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
|
Fields are defined per collective. They can also be created in the
|
||||||
item edit menu (just like creating organizations). The `#Usage`
|
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:
|
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
|
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_:
|
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.
|
multiple fields. Only one value is allowed to set per item and field.
|
||||||
The example below shows a text field and a money 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
|
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
|
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
|
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.
|
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:
|
The item card also shows custom fields, in the same place as tags:
|
||||||
|
|
||||||
<div class="columns is-centered">
|
|
||||||
<div class="column is-one-quarter">
|
<div class="flex flex-row items-center justify-center">
|
||||||
{{ imgnormal(file="custom-fields-05.png", width=300) }}
|
{{ imgnormal2(light="custom-fields-05.png", dark="custom-fields-05_dark.png", width=300) }}
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Adding values for custom fields in
|
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.
|
The search menu shows the same dropdown for selecting a custom field.
|
||||||
Then you can set values that are matched against your items.
|
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
|
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
|
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:
|
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
|
For all numeric and money values, a little summary is displayed next
|
||||||
to the overall item count at the top of the page.
|
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
|
mktoc = true
|
||||||
+++
|
+++
|
||||||
|
|
||||||
|
# Dashboards
|
||||||
|
|
||||||
The main page shows a dashboard that can be configured to show some
|
The main page shows a dashboard that can be configured to show some
|
||||||
aspects of your documents. The following shows the default dashboard
|
aspects of your documents. The following shows the default dashboard
|
||||||
that is bundled in the application:
|
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
|
It shows a predefined set of information, which can be customized. You
|
||||||
can create multiple dashboards and switch between them, you can also
|
can create multiple dashboards and switch between them, you can also
|
||||||
define one as the "default" which is shown when the page loads.
|
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
|
The side menu contains a list of useful links. The first loads the
|
||||||
default dashboard. All others (and more) are available through 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.
|
_Manage_ section has links to metadata that can be managed separately.
|
||||||
These links are fixed and cannot be changed.
|
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 main component on this page is the "dashboard". A dashboard has
|
||||||
the following properties (all required):
|
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:
|
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
|
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.
|
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
|
satisfied, click _Submit_. In the example, the last two boxes are
|
||||||
removed and box decorations are enabled for the field overview box.
|
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
|
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
|
can change the dashboard and also delete it. You can also create a new
|
||||||
dashboard or copy the current one.
|
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
|
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
|
changed and it was set to the default dashboard. This is how it looks
|
||||||
now:
|
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
|
When there is more than one dashboard, the side menu shows all of
|
||||||
them. The little house icon indicates whether this is the default
|
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 |