Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ node_modules
*/src/main/resources/public/css
*/src/main/resources/public/temp
*/src/main/resources/public/js
presences/src/main/resources/public/app
*/src/main/resources/public/template/entcore
*/src/main/resources/view/
*/rev-manifest.json
Expand All @@ -32,5 +33,6 @@ target
*/.flattened-pom.xml
yarn.lock
edifice
.pnpm-store

?
4 changes: 3 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Présences — bundle multi-modules (Maven + fronts AngularJS)

Module « vie scolaire » d'Edifice : gestion des absences et des appels, des présences, des incidents / punitions / sanctions, et publipostage. Backend **Java/Vert.x (ent-core)** ; fronts **AngularJS legacy** (webpack + gulp + yarn). Une application **React** de prise d'appel (epic Jira ORGA-493, spec `FS-01`) est en cours de création dans ce même dépôt : elle n'existe pas encore.
Module « vie scolaire » d'Edifice : gestion des absences et des appels, des présences, des incidents / punitions / sanctions, et publipostage. Backend **Java/Vert.x (ent-core)** ; fronts **AngularJS legacy** (webpack + gulp + yarn). Une application **React** de prise d'appel (epic Jira ORGA-493, spec `FS-01`) est en cours de création dans `frontend/` à la racine (Vite 8, React 18, **pnpm**, Node 24 ; voir son `README.md`). Ce front React est **centralisé** : il remplacera à terme les fronts AngularJS de tous les modules.

## Architecture

Expand All @@ -16,6 +16,7 @@ Maven multi-projet : `pom.xml` racine (parent `io.edifice:app-parent`, repo `OPE

- Java : `<module>/src/main/java/fr/openent/<module>/` (controller, service, model, cron, worker, event, security…). SQL dans `src/main/resources/sql`, i18n dans `src/main/resources/i18n`, vues dans `view` / `view-src`.
- Front AngularJS : `<module>/src/main/resources/public/ts/` (+ `sass/` pour `presences`). Alias TS : `@common`, `@presences`, `@incidents`, `@massmailing`, `@statistics`.
- Front React : `frontend/` à la racine, unique pour tout le bundle (pnpm, son propre `build.sh` + `docker-compose.yml` en `node:24-alpine-pnpm`). Build synchronisé par `./build.sh buildReact` : assets dans `presences/src/main/resources/public/app/`, `index.html` dans `view/`. Routes front sous `/presences/app/*` (préfixe dédié pour ne pas heurter l'API à plat sous `/presences/*`).
- `presences/specs/` : spécifications fonctionnelles (ex. `FS-ORGA-448-prise-appel-1d.md`).
- `build.sh` mélange des cibles Maven et des cibles Gradle historiques (`*:buildGradle`) ; la chaîne actuelle est **Maven** (cf. `pom.xml`).

Expand All @@ -31,6 +32,7 @@ Gestionnaire front : **yarn** (`yarn.lock`). Le build « officiel » passe par D
| Build d'un module (front + Maven) | `./build.sh presences` (idem `incidents`, `massmailing`, `statistics`) |
| Build Maven seul | `./build.sh buildMaven` ou `./build.sh presences:buildMaven` |
| Build front seul | `./build.sh buildGulp buildCss` |
| Build du front React seul (+ sync dans le module) | `./build.sh buildReact` ; dev : `cd frontend && pnpm dev` (http://localhost:4200) |
| Tests | `./build.sh test` (front + Maven) · `testNode` · `testMaven` |
| Install local | `./build.sh install` (Maven, `-DskipTests`) |

Expand Down
80 changes: 52 additions & 28 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,50 @@ MINGW*)
esac

clean () {
docker-compose run --rm maven mvn $MVN_OPT clean
docker compose run --rm maven mvn $MVN_OPT clean
}


buildNode() {
case $(uname -s) in
MINGW*)
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js build && yarn run build:sass"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js build && yarn run build:sass"
;;
*)
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install && node_modules/gulp/bin/gulp.js build && yarn run build:sass"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install && node_modules/gulp/bin/gulp.js build && yarn run build:sass"
;;
esac
esac || return 1
buildReact
}

# Build the centralized React front (frontend/, Node 24 / pnpm) and sync it into the
# presences module resources (the module that serves it), like entcore/actualites: assets under
# public/app/, HTML entrypoints moved to view/. Must run after gulp.
buildReact() {
local resources_dir=presences/src/main/resources

(cd frontend && ./build.sh clean init build) || return 1

rm -rf "$resources_dir/public/app"
cp -R frontend/dist/* "$resources_dir/" || return 1
mkdir -p "$resources_dir/view"
for html_file in "$resources_dir"/*.html; do
[ -f "$html_file" ] || continue
mv "$html_file" "$resources_dir/view/"
done

rm -rf frontend/dist
}

test() {
rm -rf coverage
rm -rf */build
case $(uname -s) in
MINGW*)
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js drop-cache && yarn test"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js drop-cache && yarn test"
;;
*)
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install && node_modules/gulp/bin/gulp.js drop-cache && yarn test"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install && node_modules/gulp/bin/gulp.js drop-cache && yarn test"
;;
esac
}
Expand All @@ -54,10 +74,10 @@ testNode () {
rm -rf */build
case `uname -s` in
MINGW*)
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js drop-cache && yarn test"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js drop-cache && yarn test"
;;
*)
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install && node_modules/gulp/bin/gulp.js drop-cache && yarn test"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install && node_modules/gulp/bin/gulp.js drop-cache && yarn test"
esac
}

Expand All @@ -66,10 +86,10 @@ testNodeDev () {
rm -rf */build
case `uname -s` in
MINGW*)
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js drop-cache && yarn run test:dev"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js drop-cache && yarn run test:dev"
;;
*)
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install && node_modules/gulp/bin/gulp.js drop-cache && yarn run test:dev"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install && node_modules/gulp/bin/gulp.js drop-cache && yarn run test:dev"
esac
}

Expand All @@ -83,11 +103,11 @@ install () {
}

buildGulp() {
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js build"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js build"
}

buildCss() {
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn run build:sass"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn run build:sass"
}

publish() {
Expand All @@ -103,66 +123,67 @@ publish() {
presences() {
case $(uname -s) in
MINGW*)
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js build --targetModule=presences && yarn run build:sass"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js build --targetModule=presences && yarn run build:sass"
;;
*)
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install && node_modules/gulp/bin/gulp.js build --targetModule=presences && yarn run build:sass"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install && node_modules/gulp/bin/gulp.js build --targetModule=presences && yarn run build:sass"
;;
esac
docker-compose run --rm maven mvn $MVN_OPTS -pl presences -am install -DskipTests
buildReact || return 1
docker compose run --rm maven mvn $MVN_OPTS -pl presences -am install -DskipTests

}

presences:buildMaven() {
docker-compose run --rm maven mvn $MVN_OPTS -pl presences -am install -DskipTests
docker compose run --rm maven mvn $MVN_OPTS -pl presences -am install -DskipTests
}

incidents() {
case $(uname -s) in
MINGW*)
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js build --targetModule=incidents && yarn run build:sass"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js build --targetModule=incidents && yarn run build:sass"
;;
*)
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install && node_modules/gulp/bin/gulp.js build --targetModule=incidents && yarn run build:sass"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install && node_modules/gulp/bin/gulp.js build --targetModule=incidents && yarn run build:sass"
;;
esac
docker-compose run --rm -u "$USER_UID:$GROUP_GID" gradle gradle :incidents:shadowJar :incidents:install :incidents:publishToMavenLocal
docker compose run --rm -u "$USER_UID:$GROUP_GID" gradle gradle :incidents:shadowJar :incidents:install :incidents:publishToMavenLocal
}

incidents:buildGradle() {
docker-compose run --rm -u "$USER_UID:$GROUP_GID" gradle gradle :incidents:shadowJar :incidents:install :incidents:publishToMavenLocal
docker compose run --rm -u "$USER_UID:$GROUP_GID" gradle gradle :incidents:shadowJar :incidents:install :incidents:publishToMavenLocal
}

massmailing() {
case $(uname -s) in
MINGW*)
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js build --targetModule=massmailing && yarn run build:sass"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js build --targetModule=massmailing && yarn run build:sass"
;;
*)
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install && node_modules/gulp/bin/gulp.js build --targetModule=massmailing && yarn run build:sass"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install && node_modules/gulp/bin/gulp.js build --targetModule=massmailing && yarn run build:sass"
;;
esac
docker-compose run --rm -u "$USER_UID:$GROUP_GID" gradle gradle :massmailing:shadowJar :massmailing:install :massmailing:publishToMavenLocal
docker compose run --rm -u "$USER_UID:$GROUP_GID" gradle gradle :massmailing:shadowJar :massmailing:install :massmailing:publishToMavenLocal
}

massmailing:buildGradle() {
docker-compose run --rm -u "$USER_UID:$GROUP_GID" gradle gradle :massmailing:shadowJar :massmailing:install :massmailing:publishToMavenLocal
docker compose run --rm -u "$USER_UID:$GROUP_GID" gradle gradle :massmailing:shadowJar :massmailing:install :massmailing:publishToMavenLocal
}

statistics() {
case $(uname -s) in
MINGW*)
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js build --targetModule=statistics-presences && yarn run build:sass"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links && node_modules/gulp/bin/gulp.js build --targetModule=statistics-presences && yarn run build:sass"
;;
*)
docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install && node_modules/gulp/bin/gulp.js build --targetModule=statistics-presences && yarn run build:sass"
docker compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install && node_modules/gulp/bin/gulp.js build --targetModule=statistics-presences && yarn run build:sass"
;;
esac
docker-compose run --rm -u "$USER_UID:$GROUP_GID" gradle gradle :statistics:shadowJar :statistics:install :statistics:publishToMavenLocal
docker compose run --rm -u "$USER_UID:$GROUP_GID" gradle gradle :statistics:shadowJar :statistics:install :statistics:publishToMavenLocal
}

statistics:buildGradle() {
docker-compose run --rm -u "$USER_UID:$GROUP_GID" gradle gradle :statistics:shadowJar :statistics:install :statistics:publishToMavenLocal
docker compose run --rm -u "$USER_UID:$GROUP_GID" gradle gradle :statistics:shadowJar :statistics:install :statistics:publishToMavenLocal
}

publishNexus() {
Expand Down Expand Up @@ -210,6 +231,9 @@ for param in "$@"; do
buildNode)
buildNode
;;
buildReact)
buildReact
;;
buildMaven)
install
;;
Expand Down
46 changes: 46 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.

# compiled output
dist
tmp
/out-tsc

# dependencies
node_modules

# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace

# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings

# System Files
.DS_Store
Thumbs.db

.nx/cache
.nx/workspace-data

.env*
*.tsbuildinfo
.pnpm-store
5 changes: 5 additions & 0 deletions frontend/.husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Lint & format only the staged files (fast), only when the React front changed.
# The git root is the repository root: AngularJS / Java commits skip this hook.
if git diff --cached --name-only | grep -q '^frontend/'; then
cd frontend && pnpm run pre-commit
fi
6 changes: 6 additions & 0 deletions frontend/.husky/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Run the full build before pushing, only when the pushed commits touch the React front.
# Without an upstream (first push of a branch), compare with origin/dev.
UPSTREAM=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null || echo origin/dev)
if git diff --name-only "$UPSTREAM"...HEAD | grep -q '^frontend/'; then
cd frontend && pnpm run pre-push
fi
1 change: 1 addition & 0 deletions frontend/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
auto-install-peers=true
5 changes: 5 additions & 0 deletions frontend/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Add files here to ignore them from prettier formatting
/dist
/coverage
/.nx/cache
/.nx/workspace-data
10 changes: 10 additions & 0 deletions frontend/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all",
"semi": true,
"printWidth": 80,
"useTabs": false,
"endOfLine": "auto",
"quoteProps": "consistent"
}
Loading
Loading