Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
d72bb0e
Svelte
rimi-itk Sep 17, 2025
5fff920
Cleaned up
rimi-itk Sep 17, 2025
9298e1a
Moved widgets
rimi-itk Sep 17, 2025
d4f1d7e
Added search widget
rimi-itk Sep 18, 2025
158eab7
Mocked API with Faker
rimi-itk Sep 23, 2025
47782c1
Updated UI
rimi-itk Sep 26, 2025
ac3e97d
SQLite
rimi-itk Sep 26, 2025
af479e8
Updated API mock
rimi-itk Sep 26, 2025
9238526
Updated overview
rimi-itk Sep 26, 2025
8f5d6c2
Updated translations
rimi-itk Sep 26, 2025
adf8813
Hmm …
rimi-itk Sep 26, 2025
3781f32
More fooling around …
rimi-itk Sep 28, 2025
78727d5
Updated Symfony UI
rimi-itk Sep 28, 2025
63bd961
More Python stuff
rimi-itk Sep 28, 2025
d80c5c8
Cleaned up
rimi-itk Sep 29, 2025
bf0cc71
Made fixtures create pending runs
rimi-itk Sep 29, 2025
e14b734
Fixed fixture
rimi-itk Sep 29, 2025
7f660c1
Add and use `rsync` inside docker service
rimi-itk Sep 29, 2025
1b716ae
Merge pull request #4 from itk-dev/feature/rsync
rimi-itk Sep 29, 2025
b80ac90
Cleaned up API
rimi-itk Sep 30, 2025
451e0a9
Refactored API wrapper
rimi-itk Sep 30, 2025
512edf1
Restored API to former glory
rimi-itk Sep 30, 2025
99dc58a
Handled default query
rimi-itk Sep 30, 2025
3a0114d
5615: setup tailwind-bundle
sinejespersen Oct 1, 2025
5192c8b
Update TODO.md
sinejespersen Oct 1, 2025
60053c6
Merge pull request #6 from itk-dev/feature/5615-install-tailwind
sinejespersen Oct 1, 2025
86eaaf2
Cleaned up
rimi-itk Oct 1, 2025
f5fb7fb
Merge pull request #7 from itk-dev/feature/cleanup
rimi-itk Oct 1, 2025
c981205
Added multi-step form hacks
rimi-itk Sep 30, 2025
2722e72
Fixed calculation of `collapsed`
rimi-itk Oct 1, 2025
a545e18
Cleaned up
rimi-itk Oct 1, 2025
94e84cd
Showed actual labels in accordion
rimi-itk Oct 1, 2025
1e990bd
Merge pull request #5 from itk-dev/feature/multi-step-form
rimi-itk Oct 1, 2025
5e6e930
Added user and made entities blameable and timestampable
rimi-itk Oct 1, 2025
0904a02
Added login form
rimi-itk Oct 1, 2025
2921ee1
Cleaned up login UI
rimi-itk Oct 1, 2025
07b633f
Added user management commands
rimi-itk Oct 1, 2025
d0aa3ef
Merge pull request #8 from itk-dev/feature/user-management
rimi-itk Oct 2, 2025
34bb8c6
5619: Tailwindify twig and svelte
sinejespersen Oct 2, 2025
67b5bb3
5619: add todos
sinejespersen Oct 2, 2025
5844f09
5619: add entry in changelog
sinejespersen Oct 2, 2025
4542e8b
5619: fix all black nav page
sinejespersen Oct 2, 2025
f47272e
5619: rename willTheNextFail to more correct isTheNextStepFailed
sinejespersen Oct 2, 2025
fbf82c2
5619: add localizable todo
sinejespersen Oct 2, 2025
b9c17de
Merge pull request #9 from itk-dev/feature/5619-tailwind-svelte-and-twig
sinejespersen Oct 3, 2025
d3345f9
Added OIDC login
rimi-itk Oct 2, 2025
2a2e2e9
Cleaned up user stuff
rimi-itk Oct 3, 2025
99c79c9
Merge pull request #10 from itk-dev/feature/oidc
rimi-itk Oct 3, 2025
d71c8a5
5633: copy localization tactics from tidyfeedback
sinejespersen Oct 3, 2025
594fbcf
5633: add changelog entry
sinejespersen Oct 3, 2025
bddc111
Merge pull request #11 from itk-dev/feature/5633-localization
sinejespersen Oct 3, 2025
d21be1c
Cleaned up
rimi-itk Oct 3, 2025
3e5a695
Merge pull request #13 from itk-dev/feature/user-cleanup
rimi-itk Oct 3, 2025
c4ae2d6
5634: light mode added
sinejespersen Oct 3, 2025
4203cc9
5634: changelog entry added
sinejespersen Oct 3, 2025
8696fa2
5634: update todos
sinejespersen Oct 3, 2025
f20749b
Merge pull request #14 from itk-dev/feature/5634-light-mode
sinejespersen Oct 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .docker/oidc-server-mock/cert/docker.pfx
Binary file not shown.
30 changes: 29 additions & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ APP_SECRET=
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4"
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4"
# DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8"
DATABASE_URL="mysql://db:db@mariadb:3306/db?serverVersion=10.11.14-MariaDB&charset=utf8"
# DATABASE_URL="mysql://db:db@mariadb:3306/db?serverVersion=10.11.14-MariaDB&charset=utf8"
DATABASE_URL="sqlite:///%kernel.project_dir%/var/app.db"
###< doctrine/doctrine-bundle ###

###> symfony/mercure-bundle ###
Expand All @@ -28,4 +29,31 @@ MERCURE_PUBLIC_URL=https://example.com/.well-known/mercure
MERCURE_JWT_SECRET="!ChangeThisMercureHubJWTSecretKey!"
###< symfony/mercure-bundle ###

###> nelmio/cors-bundle ###
CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
###< nelmio/cors-bundle ###

# Set this to a non-empty value in .env.local to disable the OIDC service.
# DOCKER_OIDC_DISABLE=""

DEFAULT_LOCALE=en

SITE_TITLE="RPA Process Overview"
DEFAULT_URI=https://rpa-process-overview.local.itkdev.dk/

# https://github.com/itk-dev/openid-connect-bundle
# "admin" open id connect configuration variables (values provided by the OIDC IdP)
# For production, these must be overridden in .env.local.
ADMIN_OIDC_ALLOW_HTTP=true
ADMIN_OIDC_METADATA_URL=http://idp.rpa-process-overview.local.itkdev.dk/.well-known/openid-configuration
ADMIN_OIDC_CLIENT_ID=client-id
ADMIN_OIDC_CLIENT_SECRET=client-secret
ADMIN_OIDC_REDIRECT_URI=https://rpa-process-overview.local.itkdev.dk/
ADMIN_OIDC_LEEWAY=30
ADMIN_OIDC_ROLE_MAP='{
"overview-manager": ["ROLE_OVERVIEW_MANAGER"]
}'

# cli redirect url
OIDC_CLI_LOGIN_ROUTE=app_default
###< itk-dev/openid-connect-bundle ###
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@
/assets/vendor/
###< symfony/asset-mapper ###
*.local
.idea
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# The Svelte standalone widgets have a life of their own …
widgets/
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

* [PR-14](https://github.com/itk-dev/rpa-process-overview/pull/14)
Light mode added
* [PR-13](https://github.com/itk-dev/rpa-process-overview/pull/13)
Cleaned up user stuff
* [PR-11](https://github.com/itk-dev/rpa-process-overview/pull/11)
Add localization
* [PR-10](https://github.com/itk-dev/rpa-process-overview/pull/10)
Added OIDC login
* [PR-9](https://github.com/itk-dev/rpa-process-overview/pull/9)
Tailwind classes in twig and svelte files
* [PR-8](https://github.com/itk-dev/rpa-process-overview/pull/8)
Added users and security and form based login
* [PR-5](https://github.com/itk-dev/rpa-process-overview/pull/5)
Added multi-step form hacks
* [PR-7](https://github.com/itk-dev/rpa-process-overview/pull/7)
Cleaned up
* [PR-6](https://github.com/itk-dev/rpa-process-overview/pull/6)
Setup tailwind
* [PR-4](https://github.com/itk-dev/rpa-process-overview/pull/4)
Added and used `rsync` inside docker service
* [PR-3](https://github.com/itk-dev/rpa-process-overview/pull/3)
Mocked API with FastAPI and friends.
* [PR-2](https://github.com/rimi-itk/rpa-process-overview/pull/2)
Svelte

[Unreleased]: https://github.com/rimi-itk/rpa-process-overview
96 changes: 89 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,109 @@ task help

## Production

First, add a little config to make our tasks use the right docker compose setup:

``` shell
# .env.local
TASK_DOCKER_COMPOSE='itkdev-docker-compose'
TASK_COMPOSER_INSTALL_ARGS='--no-dev'
```

## API Mock
Update the site by running:

``` shell
task site:update
```

## Development

Run

``` shell
docker compose up --build --detach --wait
task site:update
```

to get things started.

Load fixtures with

``` shell
task fixtures:load
```

## API Mock

We use a [FastAPI](https://fastapi.tiangolo.com) app to mock the RPA process overview API.

``` shell
curl "http://$(docker compose port api 8000)/openapi.json"
curl "http://$(docker compose port api 8000)/api/v1/process/"
curl "http://$(docker compose port api 8000)/api/v1/process/" --header 'x-api-key: a-not-so-secret-key'
curl "http://$(docker compose port api 8000)/api/v1/process"
curl "http://$(docker compose port api 8000)/api/v1/process" --header 'x-api-key: a-not-so-secret-key'
```

Create some data:
Create some fixture data for the API:

``` shell
docker compose exec api uv run python -m src.api.create-data
task api:fixtures:load
curl "http://$(docker compose port api 8000)/api/v1/process/" --header 'x-api-key: a-not-so-secret-key'
```

See [api/README.md](api/README.md) for some more details.
See [api/README.md](api/README.md) for some more details (and [`docker-compose.api.yml`](docker-compose.api.yml) for the
docker compose setup).

## CORS

We use [NelmioCorsBundle](https://symfony.com/bundles/NelmioCorsBundle/current/index.html) for widget development.

``` shell
curl "http://$(task --silent compose -- port nginx 8080)/group/1/overview/1/data"
```

``` shell name=cors-test-widget-dev
curl -H "Origin: http://127.0.0.1:3000/ProcessOverview?page=3" \
-H "Access-Control-Request-Method: GET" \
-X OPTIONS --verbose \
"http://$(task --silent compose -- port nginx 8080)/group/1/overview/1/data"
```

## User management

[Symfony supports OpenID Connect](https://symfony.com/doc/current/security/access_token.html#using-openid-connect-oidc),
but our IdP does not play well with that. Therefore, we use our own battle-tested [OpenId Connect
Bundle](https://github.com/itk-dev/openid-connect-bundle) for OIDC login.

The bundle is configured with some environment variables:

``` dotenv
# .env.local
ADMIN_OIDC_ALLOW_HTTP=false
# Get these from your IdP provider
ADMIN_OIDC_METADATA_URL=https://…/.well-known/openid-configuration
ADMIN_OIDC_CLIENT_ID=…
ADMIN_OIDC_CLIENT_SECRET=…

ADMIN_OIDC_REDIRECT_URI=https://rpa-process-overview.example.com/

ADMIN_OIDC_ROLE_MAP='{
"overview-manager": ["ROLE_OVERVIEW_MANAGER"]
}'
```

For local testing of OIDC login, we use [OpenId Connect Server Mock](https://github.com/Soluto/oidc-server-mock) (cf.
[`docker-compose.oidc.yml`](docker-compose.oidc.yml)) and the mock is running on
<https://idp.rpa-process-overview.local.itkdev.dk/>.

The mock provides these users (cf. [`docker-compose.oidc.yml`](docker-compose.oidc.yml)):

| Username | Password | Roles |
|------------------|------------------|------------------|
| admin | admin | administrator |
| overview-manager | overview-manager | overview-manager |
| user | user | user |

> [!TIP]
> Set `DOCKER_OIDC_DISABLE` to a non-empty value in `.env.local` to disable the OIDC service, e.g.
>
> ``` dotend
> # .env.local
> DOCKER_OIDC_DISABLE=true
8 changes: 8 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# RPA Process Overview

- [ ] Handle pagination
- [ ] Search for process when creating/editing overview
- [ ] Figure out [how to build tailwind](https://symfony.com/bundles/TailwindBundle/current/index.html#deploying) and set
it up
- [x] Add light mode
- [x] Localizable texts in svelte
66 changes: 55 additions & 11 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ dotenv: [".env.local", ".env"]

vars:
DOCKER_COMPOSE: '{{.TASK_DOCKER_COMPOSE | default "docker compose" }}'
COMPOSER_INSTALL_ARGS: '{{.TASK_DOCKER_COMPOSE | default "" }}'
COMPOSER_INSTALL_ARGS: '{{.TASK_COMPOSER_INSTALL_ARGS | default "" }}'

includes:
coding-standards: ./task/Taskfile.coding-standards.yml
widgets:
# https://taskfile.dev/usage/#directory-of-included-taskfile
taskfile: ./widgets/Taskfile.yml
dir: ./widgets

tasks:
default:
Expand All @@ -35,10 +39,7 @@ tasks:
TASK_ARGS: pull
- task: compose
vars:
TASK_ARGS: up --detach --wait
- task: composer
vars:
TASK_ARGS: install {{.COMPOSER_INSTALL_ARGS}}
TASK_ARGS: up --build --detach --wait

logs:
desc: Show live logs
Expand Down Expand Up @@ -72,9 +73,12 @@ tasks:
desc: Update site
deps: [start]
cmds:
- task: composer
vars:
TASK_ARGS: install {{.COMPOSER_INSTALL_ARGS}}
- task: console
vars:
TASK_ARGS: doctrine:migrations:migrate
TASK_ARGS: doctrine:migrations:migrate --no-interaction
- task: console
vars:
TASK_ARGS: cache:clear
Expand All @@ -87,11 +91,51 @@ tasks:
vars:
TASK_ARGS: hautelook:fixtures:load --no-interaction

api:fixtures:load:
desc: Load API fixtures
prompt: Continue?
cmds:
- task: compose
vars:
TASK_ARGS: exec api uv run python -m src.api.fixtures

translations:extract:
cmds:
# We need a translation from en to en (!) (without prefix) to be able to process placeholders in en.
- "DEFAULT_LOCALE=en task console -- translation:extract --clean --force en --prefix=''"
- "DEFAULT_LOCALE=en task console -- translation:extract --clean --force da"
# Mark default translations (prefixed with `__`) as “Needs work” in Danish translations
- gsed --in-place='' 's/<target>__/<target state=\"needs-l10n\">__/' translations/*.da.*xlf
- task: script
vars:
TASK_ARGS: "{{.TASK}}"
silent: true

script:
cmds:
- task: compose
vars:
TASK_ARGS: run --rm phpfpm task/scripts/{{.TASK_ARGS}}
internal: true

build:widgets:
desc: Build widgets for production and copy to public folder
cmds:
- task: widgets:build

# Build tailwind
- task: console
vars:
TASK_ARGS: tailwind:build

# Copy result into public folder
- task: compose
vars:
TASK_ARGS: exec phpfpm rm -fr {{.PUBLIC_DIR}}
- task: compose
vars:
# rsync is weird when it comes to including and excluding files …
# https://stackoverflow.com/a/11111793
TASK_ARGS: exec phpfpm rsync -azv {{.BUILD_DIR}} --include '*/' --include '**/*.css' --include '**/*.js' --exclude '*' --delete {{.PUBLIC_DIR}}
- task: compose
vars:
TASK_ARGS: exec phpfpm find {{.PUBLIC_DIR}} -type f

vars:
BUILD_DIR: widgets/static/dist/
PUBLIC_DIR: public/widgets
23 changes: 13 additions & 10 deletions api/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# API

> [!WARNING]
> Don't use this API mock for production!

## Database

``` mermaid
Expand Down Expand Up @@ -61,7 +64,14 @@ pip install
```

``` shell name=update-run-step
curl --silent --verbose --location 'http://127.0.0.1:8000/api/v1/process/1/run/3/step/2' --header 'content-type: application/json' --data '
curl --silent --verbose --location 'http://127.0.0.1:8000/api/v1/process/1/run/2/step/5' --header 'content-type: application/json' --data '
{
"status":"SUCCESS",
"started_at": "2025-09-25"
}
'

curl --silent --verbose --location 'http://127.0.0.1:8000/api/v1/process/1/run/2/step/6' --header 'content-type: application/json' --data '
{
"status":"FAILED",
"started_at": "2025-09-25",
Expand All @@ -71,13 +81,6 @@ curl --silent --verbose --location 'http://127.0.0.1:8000/api/v1/process/1/run/3
}
}
'

curl --silent --verbose --location 'http://127.0.0.1:8000/api/v1/process/1/run/3/step/0' --header 'content-type: application/json' --data '
{
"status":"SUCCESS",
"started_at": "2025-09-25"
}
'
```

## Security
Expand All @@ -87,7 +90,7 @@ Define API keys in `.env.local`, e.g.
``` dotenv
# .env.local
# Get a token from https://generate-random.org/api-token-generator or some such …
# Notice that the values must not be enclose in single quotes!
# Notice that the values must not be enclosed in single quotes and must not contain spaces!
API_KEYS_READ=["a-not-so-secret-key", "759568492f338454603821a04810eabf"]
API_KEYS_WRITE=["3825e7be2d1ca130063171d8362ad4996e3a0df1e9f6dd2a4dc6bebf38bfc205"]
```
Expand All @@ -97,7 +100,7 @@ Restart the API to load the updated config.
Use a key:

``` shell
curl http://127.0.0.1:8000/api/v1/process/ --header 'x-api-key: a-not-so-secret-key'
curl http://127.0.0.1:8000/api/v1/process --header 'x-api-key: a-not-so-secret-key'
```

> [!TIP]
Expand Down
9 changes: 7 additions & 2 deletions api/Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,15 @@ tasks:
fixtures:load:
prompt: Really reset data?
cmds:
- uv run python -m src.api.create-data
- uv run python -m src.api.fixtures

lint:
cmds:
- ruff format src
- ruff check --select ALL check src --fix
- ruff check --select ALL src --fix
# - ruff check --select ALL check src

sql:
desc: Talk to the database, e.g. `task {{.TASK}} -- "SELECT * FROM process LIMIT 10"`
cmds:
- sqlite3 -header -column database-api.db -- {{.CLI_ARGS}}
1 change: 1 addition & 0 deletions api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ docstring-code-format = true
[dependency-groups]
dev = [
"faker>=37.8.0",
"python-lsp-server[all]>=1.13.1",
"ruff>=0.13.1",
]
Loading