├── .gitbook.yaml ├── .gitbook └── assets │ ├── image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png │ ├── image (1) (1) (1) (1) (1) (1) (1) (1) (1).png │ ├── image (1) (1) (1) (1) (1) (1) (1) (1).png │ ├── image (1) (1) (1) (1) (1) (1) (1).png │ ├── image (1) (1) (1) (1) (1) (1).png │ ├── image (1) (1) (1) (1) (1).png │ ├── image (1) (1) (1) (1).png │ ├── image (1) (1) (1).png │ ├── image (1) (1).png │ ├── image (1) (2).png │ ├── image (1).png │ ├── image (10).png │ ├── image (11).png │ ├── image (12).png │ ├── image (13).png │ ├── image (14).png │ ├── image (2) (1) (1) (1) (1) (1).png │ ├── image (2) (1) (1) (1) (1).png │ ├── image (2) (1) (1) (1).png │ ├── image (2) (1) (1).png │ ├── image (2) (1).png │ ├── image (2) (2).png │ ├── image (2).png │ ├── image (3) (1) (1).png │ ├── image (3) (1).png │ ├── image (3).png │ ├── image (4) (1).png │ ├── image (4).png │ ├── image (5) (1).png │ ├── image (5).png │ ├── image (6) (1) (1).png │ ├── image (6) (1).png │ ├── image (6).png │ ├── image (7) (1) (1).png │ ├── image (7) (1).png │ ├── image (7).png │ ├── image (8) (1).png │ ├── image (8).png │ ├── image (9) (1).png │ ├── image (9).png │ ├── image.png │ └── infite.mp4 ├── .gitignore ├── .run ├── Lab1Application.run.xml ├── Lab2Application.run.xml ├── Lab3Application.run.xml ├── Lab4Application.run.xml ├── Lab5Application.run.xml ├── Lab6Application.run.xml ├── Lab7Application.run.xml ├── Lab8Application.run.xml ├── Lab9Application.run.xml ├── LabCompletedApplication.run.xml └── Setup and build all.run.xml ├── README.md ├── SUMMARY.md ├── docs ├── .gitbook │ └── assets │ │ ├── image (1) (1) (1).png │ │ ├── image (1) (1).png │ │ ├── image (1).png │ │ ├── image (2) (1).png │ │ ├── image (2).png │ │ ├── image (3).png │ │ └── image.png ├── README.md ├── SUMMARY.md ├── lab-1-server-side-rendering-with-spring-boot-and-jte.md ├── lab-2-introducing-spring-viewcomponent.md ├── lab-3-inline-editing.md ├── lab-4-using-spring-beans-to-compose-the-ui.md ├── lab-5-lazy-loading.md ├── lab-6-full-text-search.md ├── lab-7-infinite-scroll.md ├── lab-8-exception-messages.md └── lab-9-server-sent-events.md ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── lab-1 ├── build.gradle.kts └── src │ ├── main │ ├── java │ │ └── de │ │ │ └── tschuehly │ │ │ └── easy │ │ │ └── spring │ │ │ └── auth │ │ │ ├── Lab1Application.java │ │ │ ├── group │ │ │ ├── EasyGroup.java │ │ │ ├── GroupController.java │ │ │ └── GroupService.java │ │ │ ├── htmx │ │ │ └── HtmxUtil.java │ │ │ └── user │ │ │ ├── EasyUser.java │ │ │ ├── UserController.java │ │ │ └── UserService.java │ ├── jte │ │ ├── .jteroot │ │ ├── CreateUserForm.jte │ │ ├── EditUserForm.jte │ │ ├── UserManagement.jte │ │ └── UserRow.jte │ └── resources │ │ ├── application.yaml │ │ └── static │ │ ├── css │ │ └── sakura.css │ │ ├── edit.svg │ │ ├── htmx_1.9.11.js │ │ ├── htmx_debug.js │ │ ├── plus.svg │ │ └── spinner.svg │ └── test │ └── java │ └── de │ └── tschuehly │ └── easy │ └── spring │ └── auth │ └── EasySpringAuthApplicationTests.java ├── lab-2 ├── build.gradle.kts └── src │ ├── main │ ├── java │ │ └── de │ │ │ └── tschuehly │ │ │ └── easy │ │ │ └── spring │ │ │ └── auth │ │ │ ├── Lab2Application.java │ │ │ ├── group │ │ │ ├── EasyGroup.java │ │ │ ├── GroupController.java │ │ │ └── GroupService.java │ │ │ ├── htmx │ │ │ └── HtmxUtil.java │ │ │ └── user │ │ │ ├── EasyUser.java │ │ │ ├── UserController.java │ │ │ ├── UserService.java │ │ │ └── management │ │ │ ├── .gitinclude │ │ │ ├── create │ │ │ └── .gitinclude │ │ │ ├── edit │ │ │ └── .gitinclude │ │ │ └── table │ │ │ ├── .gitinclude │ │ │ └── row │ │ │ └── .gitinclude │ ├── jte │ │ ├── CreateUserForm.jte │ │ ├── EditUserForm.jte │ │ ├── UserManagement.jte │ │ └── UserRow.jte │ └── resources │ │ ├── application.yaml │ │ └── static │ │ ├── css │ │ └── sakura.css │ │ ├── edit.svg │ │ ├── htmx_1.9.11.js │ │ ├── htmx_debug.js │ │ ├── plus.svg │ │ └── spinner.svg │ └── test │ └── java │ └── de │ └── tschuehly │ └── easy │ └── spring │ └── auth │ └── EasySpringAuthApplicationTests.java ├── lab-3 ├── build.gradle.kts └── src │ └── main │ ├── java │ └── de │ │ └── tschuehly │ │ └── easy │ │ └── spring │ │ └── auth │ │ ├── Lab3Application.java │ │ ├── group │ │ ├── EasyGroup.java │ │ ├── GroupController.java │ │ ├── GroupService.java │ │ └── management │ │ │ ├── .gitinclude │ │ │ └── table │ │ │ ├── .gitinclude │ │ │ └── user │ │ │ └── .gitinclude │ │ ├── htmx │ │ └── HtmxUtil.java │ │ └── user │ │ ├── EasyUser.java │ │ ├── UserController.java │ │ ├── UserService.java │ │ └── management │ │ ├── UserManagementComponent.java │ │ ├── UserManagementComponent.jte │ │ ├── create │ │ ├── CreateUserComponent.java │ │ └── CreateUserComponent.jte │ │ ├── edit │ │ ├── EditUserComponent.java │ │ └── EditUserComponent.jte │ │ └── table │ │ ├── UserTableComponent.java │ │ ├── UserTableComponent.jte │ │ └── row │ │ ├── UserRowComponent.java │ │ └── UserRowComponent.jte │ └── resources │ ├── application.yaml │ └── static │ ├── css │ └── sakura.css │ ├── edit.svg │ ├── htmx_1.9.11.js │ ├── htmx_debug.js │ ├── plus.svg │ └── spinner.svg ├── lab-4 ├── build.gradle.kts └── src │ └── main │ ├── java │ └── de │ │ └── tschuehly │ │ └── easy │ │ └── spring │ │ └── auth │ │ ├── Lab4Application.java │ │ ├── group │ │ ├── EasyGroup.java │ │ ├── GroupController.java │ │ ├── GroupService.java │ │ └── management │ │ │ ├── GroupManagementComponent.java │ │ │ ├── GroupManagementComponent.jte │ │ │ └── table │ │ │ ├── GroupTableComponent.java │ │ │ ├── GroupTableComponent.jte │ │ │ └── user │ │ │ ├── AddUserComponent.java │ │ │ └── AddUserComponent.jte │ │ ├── htmx │ │ └── HtmxUtil.java │ │ ├── user │ │ ├── EasyUser.java │ │ ├── UserController.java │ │ ├── UserService.java │ │ └── management │ │ │ ├── UserManagementComponent.java │ │ │ ├── UserManagementComponent.jte │ │ │ ├── create │ │ │ ├── CreateUserComponent.java │ │ │ └── CreateUserComponent.jte │ │ │ ├── edit │ │ │ ├── EditUserComponent.java │ │ │ └── EditUserComponent.jte │ │ │ └── table │ │ │ ├── UserTableComponent.java │ │ │ ├── UserTableComponent.jte │ │ │ └── row │ │ │ ├── UserRowComponent.java │ │ │ └── UserRowComponent.jte │ │ └── web │ │ ├── .gitinclude │ │ └── layout │ │ └── .gitinclude │ └── resources │ ├── application.yaml │ └── static │ ├── css │ └── sakura.css │ ├── edit.svg │ ├── htmx_1.9.11.js │ ├── htmx_debug.js │ ├── plus.svg │ └── spinner.svg ├── lab-5 ├── build.gradle.kts └── src │ └── main │ ├── java │ └── de │ │ └── tschuehly │ │ └── easy │ │ └── spring │ │ └── auth │ │ ├── Lab5Application.java │ │ ├── group │ │ ├── EasyGroup.java │ │ ├── GroupController.java │ │ ├── GroupService.java │ │ └── management │ │ │ ├── GroupManagementComponent.java │ │ │ └── table │ │ │ ├── GroupTableComponent.java │ │ │ ├── GroupTableComponent.jte │ │ │ └── user │ │ │ ├── AddUserComponent.java │ │ │ └── AddUserComponent.jte │ │ ├── htmx │ │ └── HtmxUtil.java │ │ ├── user │ │ ├── EasyUser.java │ │ ├── UserController.java │ │ ├── UserService.java │ │ └── management │ │ │ ├── UserManagementComponent.java │ │ │ ├── create │ │ │ ├── CreateUserComponent.java │ │ │ └── CreateUserComponent.jte │ │ │ ├── edit │ │ │ ├── EditUserComponent.java │ │ │ └── EditUserComponent.jte │ │ │ └── table │ │ │ ├── UserTableComponent.java │ │ │ ├── UserTableComponent.jte │ │ │ └── row │ │ │ ├── UserRowComponent.java │ │ │ └── UserRowComponent.jte │ │ └── web │ │ ├── Page.java │ │ └── layout │ │ ├── LayoutComponent.java │ │ └── LayoutComponent.jte │ └── resources │ ├── application.yaml │ └── static │ ├── css │ └── sakura.css │ ├── edit.svg │ ├── htmx_1.9.11.js │ ├── htmx_debug.js │ ├── plus.svg │ └── spinner.svg ├── lab-6 ├── build.gradle.kts └── src │ └── main │ ├── java │ └── de │ │ └── tschuehly │ │ └── easy │ │ └── spring │ │ └── auth │ │ ├── Lab6Application.java │ │ ├── group │ │ ├── EasyGroup.java │ │ ├── GroupController.java │ │ ├── GroupService.java │ │ └── management │ │ │ ├── GroupManagementComponent.java │ │ │ └── table │ │ │ ├── GroupTableComponent.java │ │ │ ├── GroupTableComponent.jte │ │ │ └── user │ │ │ ├── AddUserComponent.java │ │ │ └── AddUserComponent.jte │ │ ├── htmx │ │ └── HtmxUtil.java │ │ ├── user │ │ ├── EasyUser.java │ │ ├── UserController.java │ │ ├── UserService.java │ │ └── management │ │ │ ├── UserManagementComponent.java │ │ │ ├── UserManagementComponent.jte │ │ │ ├── create │ │ │ ├── CreateUserComponent.java │ │ │ └── CreateUserComponent.jte │ │ │ ├── edit │ │ │ ├── EditUserComponent.java │ │ │ └── EditUserComponent.jte │ │ │ └── table │ │ │ ├── UserTableComponent.java │ │ │ ├── UserTableComponent.jte │ │ │ └── row │ │ │ ├── UserRowComponent.java │ │ │ └── UserRowComponent.jte │ │ └── web │ │ ├── Page.java │ │ ├── layout │ │ ├── LayoutComponent.java │ │ └── LayoutComponent.jte │ │ └── list │ │ └── .gitinclude │ └── resources │ ├── application.yaml │ └── static │ ├── css │ └── sakura.css │ ├── edit.svg │ ├── htmx_1.9.11.js │ ├── htmx_debug.js │ ├── plus.svg │ └── spinner.svg ├── lab-7 ├── build.gradle.kts └── src │ └── main │ ├── java │ └── de │ │ └── tschuehly │ │ └── easy │ │ └── spring │ │ └── auth │ │ ├── Lab7Application.java │ │ ├── group │ │ ├── EasyGroup.java │ │ ├── GroupController.java │ │ ├── GroupService.java │ │ └── management │ │ │ ├── GroupManagementComponent.java │ │ │ └── table │ │ │ ├── GroupTableComponent.java │ │ │ ├── GroupTableComponent.jte │ │ │ └── user │ │ │ ├── AddUserComponent.java │ │ │ └── AddUserComponent.jte │ │ ├── htmx │ │ └── HtmxUtil.java │ │ ├── user │ │ ├── EasyUser.java │ │ ├── UserController.java │ │ ├── UserService.java │ │ └── management │ │ │ ├── UserManagementComponent.java │ │ │ ├── UserManagementComponent.jte │ │ │ ├── create │ │ │ ├── CreateUserComponent.java │ │ │ └── CreateUserComponent.jte │ │ │ ├── edit │ │ │ ├── EditUserComponent.java │ │ │ └── EditUserComponent.jte │ │ │ └── table │ │ │ ├── UserTableComponent.java │ │ │ ├── UserTableComponent.jte │ │ │ ├── infinite │ │ │ └── .gitinclude │ │ │ └── row │ │ │ ├── UserRowComponent.java │ │ │ └── UserRowComponent.jte │ │ └── web │ │ ├── Page.java │ │ ├── layout │ │ ├── LayoutComponent.java │ │ └── LayoutComponent.jte │ │ └── list │ │ ├── ListComponent.java │ │ └── ListComponent.jte │ └── resources │ ├── application.yaml │ └── static │ ├── css │ └── sakura.css │ ├── edit.svg │ ├── htmx_1.9.11.js │ ├── htmx_debug.js │ ├── plus.svg │ └── spinner.svg ├── lab-8 ├── build.gradle.kts └── src │ └── main │ ├── java │ └── de │ │ └── tschuehly │ │ └── easy │ │ └── spring │ │ └── auth │ │ ├── Lab8Application.java │ │ ├── group │ │ ├── EasyGroup.java │ │ ├── GroupController.java │ │ ├── GroupService.java │ │ └── management │ │ │ ├── GroupManagementComponent.java │ │ │ └── table │ │ │ ├── GroupTableComponent.java │ │ │ ├── GroupTableComponent.jte │ │ │ └── user │ │ │ ├── AddUserComponent.java │ │ │ └── AddUserComponent.jte │ │ ├── htmx │ │ └── HtmxUtil.java │ │ ├── user │ │ ├── EasyUser.java │ │ ├── UserController.java │ │ ├── UserService.java │ │ └── management │ │ │ ├── UserManagementComponent.java │ │ │ ├── UserManagementComponent.jte │ │ │ ├── create │ │ │ ├── CreateUserComponent.java │ │ │ └── CreateUserComponent.jte │ │ │ ├── edit │ │ │ ├── EditUserComponent.java │ │ │ └── EditUserComponent.jte │ │ │ └── table │ │ │ ├── UserTableComponent.java │ │ │ ├── UserTableComponent.jte │ │ │ ├── infinite │ │ │ ├── InfiniteLoadComponent.java │ │ │ └── InfiniteLoadComponent.jte │ │ │ └── row │ │ │ ├── UserRowComponent.java │ │ │ └── UserRowComponent.jte │ │ └── web │ │ ├── Page.java │ │ ├── layout │ │ ├── LayoutComponent.java │ │ └── LayoutComponent.jte │ │ └── list │ │ ├── ListComponent.java │ │ └── ListComponent.jte │ └── resources │ ├── application.yaml │ └── static │ ├── css │ └── sakura.css │ ├── edit.svg │ ├── htmx_1.9.11.js │ ├── htmx_debug.js │ ├── plus.svg │ └── spinner.svg ├── lab-9 ├── build.gradle.kts └── src │ └── main │ ├── java │ └── de │ │ └── tschuehly │ │ └── easy │ │ └── spring │ │ └── auth │ │ ├── Lab9Application.java │ │ ├── group │ │ ├── EasyGroup.java │ │ ├── GroupController.java │ │ ├── GroupService.java │ │ └── management │ │ │ ├── GroupManagementComponent.java │ │ │ └── table │ │ │ ├── GroupTableComponent.java │ │ │ ├── GroupTableComponent.jte │ │ │ └── user │ │ │ ├── AddUserComponent.java │ │ │ └── AddUserComponent.jte │ │ ├── htmx │ │ └── HtmxUtil.java │ │ ├── user │ │ ├── EasyUser.java │ │ ├── UserController.java │ │ ├── UserNotFoundException.java │ │ ├── UserService.java │ │ └── management │ │ │ ├── UserManagementComponent.java │ │ │ ├── UserManagementComponent.jte │ │ │ ├── create │ │ │ ├── CreateUserComponent.java │ │ │ └── CreateUserComponent.jte │ │ │ ├── edit │ │ │ ├── EditUserComponent.java │ │ │ └── EditUserComponent.jte │ │ │ └── table │ │ │ ├── UserTableComponent.java │ │ │ ├── UserTableComponent.jte │ │ │ ├── infinite │ │ │ ├── InfiniteLoadComponent.java │ │ │ └── InfiniteLoadComponent.jte │ │ │ └── row │ │ │ ├── UserRowComponent.java │ │ │ └── UserRowComponent.jte │ │ └── web │ │ ├── Page.java │ │ ├── advice │ │ └── ExceptionAdvice.java │ │ ├── exception │ │ └── InfoException.java │ │ ├── layout │ │ ├── LayoutComponent.java │ │ └── LayoutComponent.jte │ │ ├── list │ │ ├── ListComponent.java │ │ └── ListComponent.jte │ │ └── message │ │ ├── MessageComponent.java │ │ └── MessageComponent.jte │ └── resources │ ├── application.yaml │ └── static │ ├── css │ └── sakura.css │ ├── edit.svg │ ├── htmx_1.9.11.js │ ├── htmx_debug.js │ ├── plus.svg │ └── spinner.svg ├── lab-completed ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts ├── src │ └── main │ │ ├── java │ │ └── de │ │ │ └── tschuehly │ │ │ └── easy │ │ │ └── spring │ │ │ └── auth │ │ │ ├── LabCompletedApplication.java │ │ │ ├── group │ │ │ ├── EasyGroup.java │ │ │ ├── GroupController.java │ │ │ ├── GroupService.java │ │ │ └── management │ │ │ │ ├── GroupManagementComponent.java │ │ │ │ └── table │ │ │ │ ├── GroupTableComponent.java │ │ │ │ ├── GroupTableComponent.jte │ │ │ │ └── user │ │ │ │ ├── AddUserComponent.java │ │ │ │ └── AddUserComponent.jte │ │ │ ├── htmx │ │ │ └── HtmxUtil.java │ │ │ ├── user │ │ │ ├── EasyUser.java │ │ │ ├── UserController.java │ │ │ ├── UserNotFoundException.java │ │ │ ├── UserService.java │ │ │ └── management │ │ │ │ ├── UserManagementComponent.java │ │ │ │ ├── UserManagementComponent.jte │ │ │ │ ├── create │ │ │ │ ├── CreateUserComponent.java │ │ │ │ └── CreateUserComponent.jte │ │ │ │ ├── edit │ │ │ │ ├── EditUserComponent.java │ │ │ │ └── EditUserComponent.jte │ │ │ │ └── table │ │ │ │ ├── UserTableComponent.java │ │ │ │ ├── UserTableComponent.jte │ │ │ │ ├── infinite │ │ │ │ ├── InfiniteLoadComponent.java │ │ │ │ └── InfiniteLoadComponent.jte │ │ │ │ └── row │ │ │ │ ├── UserRowComponent.java │ │ │ │ └── UserRowComponent.jte │ │ │ └── web │ │ │ ├── Page.java │ │ │ ├── advice │ │ │ └── ExceptionAdvice.java │ │ │ ├── exception │ │ │ └── InfoException.java │ │ │ ├── layout │ │ │ ├── LayoutComponent.java │ │ │ └── LayoutComponent.jte │ │ │ ├── list │ │ │ ├── ListComponent.java │ │ │ └── ListComponent.jte │ │ │ └── message │ │ │ ├── MessageComponent.java │ │ │ └── MessageComponent.jte │ │ └── resources │ │ ├── application-dev.yaml │ │ ├── application.yaml │ │ └── static │ │ ├── css │ │ └── sakura.css │ │ ├── edit.svg │ │ ├── htmx_1.9.11.js │ │ ├── htmx_debug.js │ │ ├── plus.svg │ │ └── spinner.svg └── system.properties ├── server-side-htmx-workshop-devoxx.pdf └── settings.gradle.kts /.gitbook.yaml: -------------------------------------------------------------------------------- 1 | root: ./docs/ -------------------------------------------------------------------------------- /.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (1) (1) (1) (1) (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (1) (1) (1) (1) (1) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (1) (1) (1) (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (1) (1) (1) (1) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (1) (1) (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (1) (1) (1) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (1) (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (1) (1) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (1) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (1) (2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (1) (2).png -------------------------------------------------------------------------------- /.gitbook/assets/image (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (10).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (10).png -------------------------------------------------------------------------------- /.gitbook/assets/image (11).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (11).png -------------------------------------------------------------------------------- /.gitbook/assets/image (12).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (12).png -------------------------------------------------------------------------------- /.gitbook/assets/image (13).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (13).png -------------------------------------------------------------------------------- /.gitbook/assets/image (14).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (14).png -------------------------------------------------------------------------------- /.gitbook/assets/image (2) (1) (1) (1) (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (2) (1) (1) (1) (1) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (2) (1) (1) (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (2) (1) (1) (1) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (2) (1) (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (2) (1) (1) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (2) (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (2) (1) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (2) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (2) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (2) (2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (2) (2).png -------------------------------------------------------------------------------- /.gitbook/assets/image (2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (2).png -------------------------------------------------------------------------------- /.gitbook/assets/image (3) (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (3) (1) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (3) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (3) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (3).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (3).png -------------------------------------------------------------------------------- /.gitbook/assets/image (4) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (4) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (4).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (4).png -------------------------------------------------------------------------------- /.gitbook/assets/image (5) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (5) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (5).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (5).png -------------------------------------------------------------------------------- /.gitbook/assets/image (6) (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (6) (1) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (6) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (6) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (6).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (6).png -------------------------------------------------------------------------------- /.gitbook/assets/image (7) (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (7) (1) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (7) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (7) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (7).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (7).png -------------------------------------------------------------------------------- /.gitbook/assets/image (8) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (8) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (8).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (8).png -------------------------------------------------------------------------------- /.gitbook/assets/image (9) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (9) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (9).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image (9).png -------------------------------------------------------------------------------- /.gitbook/assets/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/image.png -------------------------------------------------------------------------------- /.gitbook/assets/infite.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/.gitbook/assets/infite.mp4 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | /storage/ 39 | jte-classes -------------------------------------------------------------------------------- /.run/Lab1Application.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /.run/Lab2Application.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /.run/Lab3Application.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /.run/Lab4Application.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /.run/Lab5Application.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /.run/Lab6Application.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /.run/Lab7Application.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /.run/Lab8Application.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /.run/Lab9Application.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /.run/LabCompletedApplication.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HTMX + Spring Boot Workshop 2 | 3 | You can find the workshop documentation at: 4 | 5 | [tschuehly.gitbook.io/server-side-spring-htmx-workshop/building-server-side-web-applications-with-htmx](https://tschuehly.gitbook.io/server-side-spring-htmx-workshop/building-server-side-web-applications-with-htmx) 6 | 7 | ### Spring I/O 2024 (2h) 8 | 9 | [2024.springio.net/sessions/building-server-side-web-applications-with-htmx-workshop/](https://2024.springio.net/sessions/building-server-side-web-applications-with-htmx-workshop/) 10 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [HTMX + Spring Boot Workshop](README.md) 4 | * [Building server-side web applications with htmx](building-server-side-web-applications-with-htmx.md) 5 | * [Lab 1: Server-side rendering with Spring Boot and JTE](lab-1-server-side-rendering-with-spring-boot-and-jte.md) 6 | * [Lab 2: Introducing Spring ViewComponent](lab-2-introducing-spring-viewcomponent.md) 7 | * [Lab 3: Inline Editing](lab-3-inline-editing.md) 8 | * [Lab 4: Using Spring Beans to Compose the UI](lab-4-using-spring-beans-to-compose-the-ui.md) 9 | * [Lab 5: Lazy Loading](lab-5-lazy-loading.md) 10 | * [Lab 6: Full Text Search](lab-6-full-text-search.md) 11 | * [Lab 7: Infinite Scroll](lab-7-infinite-scroll.md) 12 | * [Lab 8: Exception Messages](lab-8-exception-messages.md) 13 | * [Lab 9: Server-Sent Events](lab-9-server-sent-events.md) 14 | -------------------------------------------------------------------------------- /docs/.gitbook/assets/image (1) (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/docs/.gitbook/assets/image (1) (1) (1).png -------------------------------------------------------------------------------- /docs/.gitbook/assets/image (1) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/docs/.gitbook/assets/image (1) (1).png -------------------------------------------------------------------------------- /docs/.gitbook/assets/image (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/docs/.gitbook/assets/image (1).png -------------------------------------------------------------------------------- /docs/.gitbook/assets/image (2) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/docs/.gitbook/assets/image (2) (1).png -------------------------------------------------------------------------------- /docs/.gitbook/assets/image (2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/docs/.gitbook/assets/image (2).png -------------------------------------------------------------------------------- /docs/.gitbook/assets/image (3).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/docs/.gitbook/assets/image (3).png -------------------------------------------------------------------------------- /docs/.gitbook/assets/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/docs/.gitbook/assets/image.png -------------------------------------------------------------------------------- /docs/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [Building server-side web applications with htmx](README.md) 4 | * [Lab 1: Server-side rendering with Spring Boot and JTE](lab-1-server-side-rendering-with-spring-boot-and-jte.md) 5 | * [Lab 2: Using Spring ViewComponent](lab-2-introducing-spring-viewcomponent.md) 6 | * [Lab 3: Inline Editing](lab-3-inline-editing.md) 7 | * [Lab 4: Using Spring Beans to Compose the UI](lab-4-using-spring-beans-to-compose-the-ui.md) 8 | * [Lab 5: Lazy Loading](lab-5-lazy-loading.md) 9 | * [Lab 6: Full Text Search](lab-6-full-text-search.md) 10 | * [Lab 7: Infinite Scroll](lab-7-infinite-scroll.md) 11 | * [Lab 8: Exception Messages](lab-8-exception-messages.md) 12 | * [Lab 9: Server-Sent Events](lab-9-server-sent-events.md) 13 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012-2024 the original author or authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | distributionBase=GRADLE_USER_HOME 17 | distributionPath=wrapper/dists 18 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip 19 | networkTimeout=10000 20 | validateDistributionUrl=true 21 | zipStoreBase=GRADLE_USER_HOME 22 | zipStorePath=wrapper/dists 23 | -------------------------------------------------------------------------------- /lab-1/src/main/java/de/tschuehly/easy/spring/auth/Lab1Application.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth; 2 | 3 | import de.tschuehly.easy.spring.auth.group.GroupService; 4 | import de.tschuehly.easy.spring.auth.user.EasyUser; 5 | import de.tschuehly.easy.spring.auth.user.UserService; 6 | import org.springframework.boot.ApplicationRunner; 7 | import org.springframework.boot.SpringApplication; 8 | import org.springframework.boot.autoconfigure.SpringBootApplication; 9 | import org.springframework.context.annotation.Bean; 10 | 11 | @SpringBootApplication 12 | public class Lab1Application { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(Lab1Application.class, args); 16 | } 17 | 18 | @Bean 19 | public ApplicationRunner initializeUsers(UserService userService, GroupService groupService) { 20 | return (args) -> { 21 | EasyUser thomas = userService.createUser( 22 | "Thomas", 23 | "This is a password" 24 | ); 25 | userService.createUser( 26 | "Cassandra", 27 | "Test1234" 28 | ); 29 | groupService.createGroup("USER_GROUP"); 30 | groupService.createGroup("ADMIN_GROUP"); 31 | groupService.addUserToGroup("USER_GROUP", thomas.uuid); 32 | }; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lab-1/src/main/java/de/tschuehly/easy/spring/auth/group/EasyGroup.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class EasyGroup { 8 | public final String groupName; 9 | public final List memberList = new ArrayList<>(); 10 | 11 | public EasyGroup(String groupName) { 12 | this.groupName = groupName; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /lab-1/src/main/java/de/tschuehly/easy/spring/auth/group/GroupController.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group; 2 | 3 | import org.springframework.stereotype.Controller; 4 | 5 | @Controller 6 | public class GroupController { 7 | private final GroupService groupService; 8 | 9 | public GroupController(GroupService groupService) { 10 | this.groupService = groupService; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lab-1/src/main/java/de/tschuehly/easy/spring/auth/group/GroupService.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.NoSuchElementException; 8 | import java.util.UUID; 9 | import org.springframework.stereotype.Service; 10 | 11 | @Service 12 | public class GroupService { 13 | private final UserService userService; 14 | public final static List easyGroupList = new ArrayList<>(); 15 | 16 | public GroupService(UserService userService) { 17 | this.userService = userService; 18 | } 19 | 20 | public List getAll(){ 21 | return easyGroupList; 22 | } 23 | 24 | public List addUserToGroup(String groupName, UUID userId){ 25 | EasyGroup easyGroup = easyGroupList.stream().filter(it -> it.groupName.equals(groupName)).findFirst() 26 | .orElseThrow( 27 | NoSuchElementException::new); 28 | EasyUser user = userService.findById(userId); 29 | easyGroup.memberList.add(user); 30 | return easyGroup.memberList; 31 | } 32 | 33 | public void createGroup(String groupName) { 34 | easyGroupList.add( 35 | new EasyGroup(groupName) 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lab-1/src/main/java/de/tschuehly/easy/spring/auth/user/EasyUser.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user; 2 | 3 | import java.util.UUID; 4 | 5 | public class EasyUser { 6 | 7 | public final UUID uuid; 8 | public final String password; 9 | public final String username; 10 | 11 | public EasyUser(String username, String password) { 12 | this.uuid = UUID.randomUUID(); 13 | this.password = password; 14 | this.username = username; 15 | } 16 | 17 | public EasyUser(UUID uuid, String username, String password) { 18 | this.uuid = uuid; 19 | this.username = username; 20 | this.password = password; 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /lab-1/src/main/java/de/tschuehly/easy/spring/auth/user/UserController.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user; 2 | 3 | import org.springframework.stereotype.Controller; 4 | 5 | @Controller 6 | public class UserController { 7 | 8 | private final UserService userService; 9 | 10 | public UserController(UserService userService) { 11 | this.userService = userService; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /lab-1/src/main/jte/.jteroot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/lab-1/src/main/jte/.jteroot -------------------------------------------------------------------------------- /lab-1/src/main/jte/CreateUserForm.jte: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
-------------------------------------------------------------------------------- /lab-1/src/main/jte/EditUserForm.jte: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
-------------------------------------------------------------------------------- /lab-1/src/main/jte/UserManagement.jte: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Easy Spring Auth 5 | 6 | 7 | 8 | 9 | 10 | 11 | 16 |
17 | 18 | 19 | 20 | 23 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
21 | uuid 22 | 24 | username 25 | 27 | password 28 |
36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /lab-1/src/main/jte/UserRow.jte: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /lab-1/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: easy-spring-auth 4 | # view-component: 5 | # local-development: true 6 | gg: 7 | jte: 8 | developmentMode: true 9 | templateLocation: lab-1/src/main/jte -------------------------------------------------------------------------------- /lab-1/src/main/resources/static/edit.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lab-1/src/main/resources/static/htmx_debug.js: -------------------------------------------------------------------------------- 1 | htmx.defineExtension('debug', { 2 | onEvent: function (name, evt) { 3 | if (console.debug) { 4 | console.debug(name, evt); 5 | } else if (console) { 6 | console.log("DEBUG:", name, evt); 7 | } else { 8 | throw "NO CONSOLE SUPPORTED" 9 | } 10 | } 11 | }); -------------------------------------------------------------------------------- /lab-1/src/main/resources/static/plus.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /lab-1/src/main/resources/static/spinner.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /lab-1/src/test/java/de/tschuehly/easy/spring/auth/EasySpringAuthApplicationTests.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class EasySpringAuthApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /lab-2/src/main/java/de/tschuehly/easy/spring/auth/Lab2Application.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth; 2 | 3 | import de.tschuehly.easy.spring.auth.group.GroupService; 4 | import de.tschuehly.easy.spring.auth.user.EasyUser; 5 | import de.tschuehly.easy.spring.auth.user.UserService; 6 | import org.springframework.boot.ApplicationRunner; 7 | import org.springframework.boot.SpringApplication; 8 | import org.springframework.boot.autoconfigure.SpringBootApplication; 9 | import org.springframework.context.annotation.Bean; 10 | 11 | @SpringBootApplication 12 | public class Lab2Application { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(Lab2Application.class, args); 16 | } 17 | @Bean 18 | public ApplicationRunner initializeUsers(UserService userService, GroupService groupService) { 19 | return (args) -> { 20 | EasyUser thomas = userService.createUser( 21 | "Thomas", 22 | "This is a password" 23 | ); 24 | userService.createUser( 25 | "Cassandra", 26 | "Test1234" 27 | ); 28 | groupService.createGroup("USER_GROUP"); 29 | groupService.createGroup("ADMIN_GROUP"); 30 | groupService.addUserToGroup("USER_GROUP", thomas.uuid); 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lab-2/src/main/java/de/tschuehly/easy/spring/auth/group/EasyGroup.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class EasyGroup { 8 | public final String groupName; 9 | public final List memberList = new ArrayList<>(); 10 | 11 | public EasyGroup(String groupName) { 12 | this.groupName = groupName; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /lab-2/src/main/java/de/tschuehly/easy/spring/auth/group/GroupController.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group; 2 | 3 | import org.springframework.stereotype.Controller; 4 | 5 | @Controller 6 | public class GroupController { 7 | private final GroupService groupService; 8 | 9 | public GroupController(GroupService groupService) { 10 | this.groupService = groupService; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lab-2/src/main/java/de/tschuehly/easy/spring/auth/group/GroupService.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.NoSuchElementException; 8 | import java.util.UUID; 9 | import org.springframework.stereotype.Service; 10 | 11 | @Service 12 | public class GroupService { 13 | private final UserService userService; 14 | public final static List easyGroupList = new ArrayList<>(); 15 | 16 | public GroupService(UserService userService) { 17 | this.userService = userService; 18 | } 19 | 20 | public List getAll(){ 21 | return easyGroupList; 22 | } 23 | 24 | public List addUserToGroup(String groupName, UUID userId){ 25 | EasyGroup easyGroup = easyGroupList.stream().filter(it -> it.groupName.equals(groupName)).findFirst() 26 | .orElseThrow( 27 | NoSuchElementException::new); 28 | EasyUser user = userService.findById(userId); 29 | easyGroup.memberList.add(user); 30 | return easyGroup.memberList; 31 | } 32 | 33 | public void createGroup(String groupName) { 34 | easyGroupList.add( 35 | new EasyGroup(groupName) 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lab-2/src/main/java/de/tschuehly/easy/spring/auth/user/EasyUser.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user; 2 | 3 | import java.util.UUID; 4 | 5 | public class EasyUser { 6 | 7 | public final UUID uuid; 8 | public final String password; 9 | public final String username; 10 | 11 | public EasyUser(String username, String password) { 12 | this.uuid = UUID.randomUUID(); 13 | this.password = password; 14 | this.username = username; 15 | } 16 | 17 | public EasyUser(UUID uuid, String username, String password) { 18 | this.uuid = uuid; 19 | this.username = username; 20 | this.password = password; 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /lab-2/src/main/java/de/tschuehly/easy/spring/auth/user/management/.gitinclude: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/lab-2/src/main/java/de/tschuehly/easy/spring/auth/user/management/.gitinclude -------------------------------------------------------------------------------- /lab-2/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/.gitinclude: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/lab-2/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/.gitinclude -------------------------------------------------------------------------------- /lab-2/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/.gitinclude: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/lab-2/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/.gitinclude -------------------------------------------------------------------------------- /lab-2/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/.gitinclude: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/lab-2/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/.gitinclude -------------------------------------------------------------------------------- /lab-2/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/row/.gitinclude: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/lab-2/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/row/.gitinclude -------------------------------------------------------------------------------- /lab-2/src/main/jte/CreateUserForm.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.UserController.POST_CREATE_USER 2 |
3 |
4 | 8 | 12 | 15 |
16 |
-------------------------------------------------------------------------------- /lab-2/src/main/jte/EditUserForm.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.UserController.POST_SAVE_USER 2 | @param de.tschuehly.easy.spring.auth.user.UserController.UserForm userForm 3 | 4 |
5 |
6 | 10 | 14 | 18 | 21 |
22 |
-------------------------------------------------------------------------------- /lab-2/src/main/jte/UserRow.jte: -------------------------------------------------------------------------------- 1 | @import de.tschuehly.easy.spring.auth.user.EasyUser 2 | @import static de.tschuehly.easy.spring.auth.htmx.HtmxUtil.* 3 | @import static de.tschuehly.easy.spring.auth.user.UserController.* 4 | 5 | @param EasyUser easyUser 6 | !{var uuid = easyUser.uuid.toString();} 7 | 8 | 9 | ${uuid} 10 | 11 | 12 | ${easyUser.username} 13 | 14 | 15 | ${easyUser.password} 16 | 17 | 18 | 22 | 23 | -------------------------------------------------------------------------------- /lab-2/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: easy-spring-auth 4 | # view-component: 5 | # local-development: true 6 | # viewComponentRoot: lab-2/src/main/java 7 | gg: 8 | jte: 9 | developmentMode: true 10 | templateLocation: lab-2/src/main/jte 11 | -------------------------------------------------------------------------------- /lab-2/src/main/resources/static/edit.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lab-2/src/main/resources/static/htmx_debug.js: -------------------------------------------------------------------------------- 1 | htmx.defineExtension('debug', { 2 | onEvent: function (name, evt) { 3 | if (console.debug) { 4 | console.debug(name, evt); 5 | } else if (console) { 6 | console.log("DEBUG:", name, evt); 7 | } else { 8 | throw "NO CONSOLE SUPPORTED" 9 | } 10 | } 11 | }); -------------------------------------------------------------------------------- /lab-2/src/main/resources/static/plus.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /lab-2/src/main/resources/static/spinner.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /lab-2/src/test/java/de/tschuehly/easy/spring/auth/EasySpringAuthApplicationTests.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class EasySpringAuthApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /lab-3/src/main/java/de/tschuehly/easy/spring/auth/Lab3Application.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth; 2 | 3 | import de.tschuehly.easy.spring.auth.group.GroupService; 4 | import de.tschuehly.easy.spring.auth.user.EasyUser; 5 | import de.tschuehly.easy.spring.auth.user.UserService; 6 | import org.springframework.boot.ApplicationRunner; 7 | import org.springframework.boot.SpringApplication; 8 | import org.springframework.boot.autoconfigure.SpringBootApplication; 9 | import org.springframework.context.annotation.Bean; 10 | 11 | @SpringBootApplication 12 | public class Lab3Application { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(Lab3Application.class, args); 16 | } 17 | @Bean 18 | public ApplicationRunner initializeUsers(UserService userService, GroupService groupService) { 19 | return (args) -> { 20 | EasyUser thomas = userService.createUser( 21 | "Thomas", 22 | "This is a password" 23 | ); 24 | userService.createUser( 25 | "Cassandra", 26 | "Test1234" 27 | ); 28 | groupService.createGroup("USER_GROUP"); 29 | groupService.createGroup("ADMIN_GROUP"); 30 | groupService.addUserToGroup("USER_GROUP", thomas.uuid); 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lab-3/src/main/java/de/tschuehly/easy/spring/auth/group/EasyGroup.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class EasyGroup { 8 | public final String groupName; 9 | public final List memberList = new ArrayList<>(); 10 | 11 | public EasyGroup(String groupName) { 12 | this.groupName = groupName; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /lab-3/src/main/java/de/tschuehly/easy/spring/auth/group/GroupController.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group; 2 | 3 | import org.springframework.stereotype.Controller; 4 | 5 | @Controller 6 | public class GroupController { 7 | private final GroupService groupService; 8 | 9 | public GroupController(GroupService groupService) { 10 | this.groupService = groupService; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lab-3/src/main/java/de/tschuehly/easy/spring/auth/group/GroupService.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.NoSuchElementException; 8 | import java.util.UUID; 9 | import org.springframework.stereotype.Service; 10 | 11 | @Service 12 | public class GroupService { 13 | private final UserService userService; 14 | public final static List easyGroupList = new ArrayList<>(); 15 | 16 | public GroupService(UserService userService) { 17 | this.userService = userService; 18 | } 19 | 20 | public List getAll(){ 21 | return easyGroupList; 22 | } 23 | 24 | public List addUserToGroup(String groupName, UUID userId){ 25 | EasyGroup easyGroup = easyGroupList.stream().filter(it -> it.groupName.equals(groupName)).findFirst() 26 | .orElseThrow( 27 | NoSuchElementException::new); 28 | EasyUser user = userService.findById(userId); 29 | easyGroup.memberList.add(user); 30 | return easyGroup.memberList; 31 | } 32 | 33 | public void createGroup(String groupName) { 34 | easyGroupList.add( 35 | new EasyGroup(groupName) 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lab-3/src/main/java/de/tschuehly/easy/spring/auth/group/management/.gitinclude: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/lab-3/src/main/java/de/tschuehly/easy/spring/auth/group/management/.gitinclude -------------------------------------------------------------------------------- /lab-3/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/.gitinclude: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/lab-3/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/.gitinclude -------------------------------------------------------------------------------- /lab-3/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/user/.gitinclude: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/lab-3/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/user/.gitinclude -------------------------------------------------------------------------------- /lab-3/src/main/java/de/tschuehly/easy/spring/auth/user/EasyUser.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user; 2 | 3 | import java.util.UUID; 4 | 5 | public class EasyUser { 6 | 7 | public final UUID uuid; 8 | public final String password; 9 | public final String username; 10 | 11 | public EasyUser(String username, String password) { 12 | this.uuid = UUID.randomUUID(); 13 | this.password = password; 14 | this.username = username; 15 | } 16 | 17 | public EasyUser(UUID uuid, String username, String password) { 18 | this.uuid = uuid; 19 | this.username = username; 20 | this.password = password; 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /lab-3/src/main/java/de/tschuehly/easy/spring/auth/user/management/UserManagementComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management; 2 | 3 | import de.tschuehly.easy.spring.auth.user.management.table.UserTableComponent; 4 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 5 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 6 | 7 | @ViewComponent 8 | public class UserManagementComponent { 9 | private final UserTableComponent userTableComponent; 10 | 11 | public static final String MODAL_CONTAINER_ID = "modalContainer"; 12 | public static final String CLOSE_MODAL_EVENT = "close-modal"; 13 | 14 | public UserManagementComponent(UserTableComponent userTableComponent) { 15 | this.userTableComponent = userTableComponent; 16 | } 17 | 18 | public record UserManagementContext(ViewContext userTable) implements ViewContext{} 19 | 20 | public ViewContext render(){ 21 | return new UserManagementContext(userTableComponent.render()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lab-3/src/main/java/de/tschuehly/easy/spring/auth/user/management/UserManagementComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.management.UserManagementComponent.* 2 | @import de.tschuehly.easy.spring.auth.user.management.UserManagementComponent.UserManagementContext 3 | @param UserManagementContext userManagementContext 4 | 5 | 6 | 7 | Easy Spring Auth 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 |
23 | ${userManagementContext.userTable()} 24 |
25 | 26 |
27 | 28 |
29 | 30 | -------------------------------------------------------------------------------- /lab-3/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/CreateUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.create; 2 | 3 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 4 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 5 | 6 | @ViewComponent 7 | public class CreateUserComponent { 8 | 9 | public record CreateUserContext() implements ViewContext{} 10 | 11 | public ViewContext render(){ 12 | return new CreateUserContext(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lab-3/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/CreateUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.UserController.POST_CREATE_USER 2 |
3 |
4 | 8 | 12 | 15 |
16 |
-------------------------------------------------------------------------------- /lab-3/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/EditUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.edit; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.UUID; 8 | 9 | @ViewComponent 10 | public class EditUserComponent { 11 | 12 | private final UserService userService; 13 | 14 | public EditUserComponent(UserService userService) { 15 | this.userService = userService; 16 | } 17 | 18 | public record EditUserContext(UUID uuid, String username, String password) implements ViewContext { 19 | 20 | } 21 | 22 | public ViewContext render(UUID uuid) { 23 | EasyUser user = userService.findById(uuid); 24 | return new EditUserContext(user.uuid, user.username, user.password); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lab-3/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/EditUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.UserController.POST_SAVE_USER 2 | @import de.tschuehly.easy.spring.auth.user.management.edit.EditUserComponent 3 | @param EditUserComponent.EditUserContext editUserContext 4 | 5 |
6 |
7 | 11 | 15 | 19 | 22 |
23 |
-------------------------------------------------------------------------------- /lab-3/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/UserTableComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.table; 2 | 3 | import de.tschuehly.easy.spring.auth.user.UserService; 4 | import de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class UserTableComponent { 11 | 12 | private final UserService userService; 13 | private final UserRowComponent userRowComponent; 14 | 15 | public UserTableComponent(UserService userService, UserRowComponent userRowComponent) { 16 | this.userService = userService; 17 | this.userRowComponent = userRowComponent; 18 | } 19 | 20 | public record UserTableContext(List userTableRowList) implements ViewContext { 21 | 22 | } 23 | 24 | public static final String USER_TABLE_BODY_ID = "userTableBody"; 25 | 26 | public ViewContext render() { 27 | List rowList = userService.findAll() 28 | .stream().map(userRowComponent::render).toList(); 29 | return new UserTableContext(rowList); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lab-3/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/UserTableComponent.jte: -------------------------------------------------------------------------------- 1 | @import de.tschuehly.easy.spring.auth.user.management.table.UserTableComponent.UserTableContext 2 | @import static de.tschuehly.easy.spring.auth.user.UserController.GET_CREATE_USER_MODAL 3 | @import static de.tschuehly.easy.spring.auth.user.management.UserManagementComponent.MODAL_CONTAINER_ID 4 | @import static de.tschuehly.easy.spring.auth.user.management.table.UserTableComponent.USER_TABLE_BODY_ID 5 | @param UserTableContext userTableContext 6 | 7 | 8 | 9 | 12 | 15 | 18 | 19 | 20 | 21 | @for(var row: userTableContext.userTableRowList()) 22 | ${row} 23 | @endfor 24 | 25 | 26 | 27 | 32 | 33 | 34 |
10 | uuid 11 | 13 | username 14 | 16 | password 17 |
28 | 31 |
-------------------------------------------------------------------------------- /lab-3/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/row/UserRowComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.htmx.HtmxUtil.URI 2 | @import static de.tschuehly.easy.spring.auth.user.UserController.* 3 | @import static de.tschuehly.easy.spring.auth.user.management.UserManagementComponent.MODAL_CONTAINER_ID 4 | @import de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent.UserRowContext 5 | @param UserRowContext userRowContext 6 | 7 | !{var uuid = userRowContext.easyUser().uuid;} 8 | 9 | 10 | ${uuid.toString()} 11 | 12 | 13 | ${userRowContext.easyUser().username} 14 | 15 | 16 | ${userRowContext.easyUser().password} 17 | 18 | 19 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /lab-3/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: easy-spring-auth 4 | view-component: 5 | local-development: true 6 | viewComponentRoot: lab-3/src/main/java 7 | gg: 8 | jte: 9 | developmentMode: true -------------------------------------------------------------------------------- /lab-3/src/main/resources/static/edit.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lab-3/src/main/resources/static/htmx_debug.js: -------------------------------------------------------------------------------- 1 | htmx.defineExtension('debug', { 2 | onEvent: function (name, evt) { 3 | if (console.debug) { 4 | console.debug(name, evt); 5 | } else if (console) { 6 | console.log("DEBUG:", name, evt); 7 | } else { 8 | throw "NO CONSOLE SUPPORTED" 9 | } 10 | } 11 | }); -------------------------------------------------------------------------------- /lab-3/src/main/resources/static/plus.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /lab-3/src/main/resources/static/spinner.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/Lab4Application.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth; 2 | 3 | import de.tschuehly.easy.spring.auth.group.GroupService; 4 | import de.tschuehly.easy.spring.auth.user.EasyUser; 5 | import de.tschuehly.easy.spring.auth.user.UserService; 6 | import org.springframework.boot.ApplicationRunner; 7 | import org.springframework.boot.SpringApplication; 8 | import org.springframework.boot.autoconfigure.SpringBootApplication; 9 | import org.springframework.context.annotation.Bean; 10 | 11 | @SpringBootApplication 12 | public class Lab4Application { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(Lab4Application.class, args); 16 | } 17 | @Bean 18 | public ApplicationRunner initializeUsers(UserService userService, GroupService groupService) { 19 | return (args) -> { 20 | EasyUser thomas = userService.createUser( 21 | "Thomas", 22 | "This is a password" 23 | ); 24 | userService.createUser( 25 | "Cassandra", 26 | "Test1234" 27 | ); 28 | groupService.createGroup("USER_GROUP"); 29 | groupService.createGroup("ADMIN_GROUP"); 30 | groupService.addUserToGroup("USER_GROUP", thomas.uuid); 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/group/EasyGroup.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class EasyGroup { 8 | public final String groupName; 9 | public final List memberList = new ArrayList<>(); 10 | 11 | public EasyGroup(String groupName) { 12 | this.groupName = groupName; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/group/GroupService.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.NoSuchElementException; 8 | import java.util.UUID; 9 | import org.springframework.stereotype.Service; 10 | 11 | @Service 12 | public class GroupService { 13 | private final UserService userService; 14 | public final static List easyGroupList = new ArrayList<>(); 15 | 16 | public GroupService(UserService userService) { 17 | this.userService = userService; 18 | } 19 | 20 | public List getAll(){ 21 | return easyGroupList; 22 | } 23 | 24 | public List addUserToGroup(String groupName, UUID userId){ 25 | EasyGroup easyGroup = easyGroupList.stream().filter(it -> it.groupName.equals(groupName)).findFirst() 26 | .orElseThrow( 27 | NoSuchElementException::new); 28 | EasyUser user = userService.findById(userId); 29 | easyGroup.memberList.add(user); 30 | return easyGroup.memberList; 31 | } 32 | 33 | public void createGroup(String groupName) { 34 | easyGroupList.add( 35 | new EasyGroup(groupName) 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/group/management/GroupManagementComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management; 2 | 3 | import de.tschuehly.easy.spring.auth.group.management.table.GroupTableComponent; 4 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 5 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 6 | 7 | @ViewComponent 8 | public class GroupManagementComponent { 9 | private final GroupTableComponent groupTableComponent; 10 | 11 | public static final String MODAL_CONTAINER_ID = "modalContainer"; 12 | public static final String CLOSE_MODAL_EVENT = "close-modal"; 13 | 14 | public GroupManagementComponent(GroupTableComponent groupTableComponent) { 15 | this.groupTableComponent = groupTableComponent; 16 | } 17 | 18 | public record GroupManagementContext(ViewContext viewContext) implements ViewContext{} 19 | 20 | public ViewContext render(){ 21 | return new GroupManagementContext(groupTableComponent.render()); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/group/management/GroupManagementComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.group.management.GroupManagementComponent.CLOSE_MODAL_EVENT 2 | @import static de.tschuehly.easy.spring.auth.group.management.GroupManagementComponent.MODAL_CONTAINER_ID 3 | @import de.tschuehly.easy.spring.auth.group.management.GroupManagementComponent.GroupManagementContext 4 | @param GroupManagementContext groupManagementContext 5 | 6 | 7 | 8 | Easy Spring Auth 9 | 10 | 11 | 12 | 13 | 14 | 15 | 23 |
24 | ${groupManagementContext.viewContext()} 25 |
26 | 27 |
28 | 29 |
30 | 31 | -------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/GroupTableComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management.table; 2 | 3 | import de.tschuehly.easy.spring.auth.group.EasyGroup; 4 | import de.tschuehly.easy.spring.auth.group.GroupService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class GroupTableComponent { 11 | private final GroupService groupService; 12 | 13 | public record GroupTableContext(List groupList) implements ViewContext{} 14 | 15 | public final static String GROUP_TABLE_ID = "groupTable"; 16 | public ViewContext render(){ 17 | List groupList = groupService.getAll(); 18 | return new GroupTableContext(groupList); 19 | } 20 | 21 | public GroupTableComponent(GroupService groupService) { 22 | this.groupService = groupService; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/user/AddUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management.table.user; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class AddUserComponent { 11 | private final UserService userService; 12 | 13 | public AddUserComponent(UserService userService) { 14 | this.userService = userService; 15 | } 16 | 17 | public record AddUserContext(String groupName, List easyUserList) implements ViewContext{} 18 | 19 | public ViewContext render(String groupName){ 20 | return new AddUserContext(groupName,userService.findAll()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/user/AddUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.group.GroupController.* 2 | @import de.tschuehly.easy.spring.auth.group.management.table.GroupTableComponent 3 | @import de.tschuehly.easy.spring.auth.htmx.HtmxUtil 4 | @param de.tschuehly.easy.spring.auth.group.management.table.user.AddUserComponent.AddUserContext addUserContext 5 |
8 | 13 | 14 |
-------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/user/EasyUser.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user; 2 | 3 | import java.util.UUID; 4 | 5 | public class EasyUser { 6 | 7 | public final UUID uuid; 8 | public final String password; 9 | public final String username; 10 | 11 | public EasyUser(String username, String password) { 12 | this.uuid = UUID.randomUUID(); 13 | this.password = password; 14 | this.username = username; 15 | } 16 | 17 | public EasyUser(UUID uuid, String username, String password) { 18 | this.uuid = uuid; 19 | this.username = username; 20 | this.password = password; 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/user/management/UserManagementComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management; 2 | 3 | import de.tschuehly.easy.spring.auth.user.management.table.UserTableComponent; 4 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 5 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 6 | 7 | @ViewComponent 8 | public class UserManagementComponent { 9 | private final UserTableComponent userTableComponent; 10 | 11 | public static final String MODAL_CONTAINER_ID = "modalContainer"; 12 | public static final String CLOSE_MODAL_EVENT = "close-modal"; 13 | 14 | public UserManagementComponent(UserTableComponent userTableComponent) { 15 | this.userTableComponent = userTableComponent; 16 | } 17 | 18 | public record UserManagementContext(ViewContext viewContext) implements ViewContext{} 19 | 20 | public ViewContext render(){ 21 | return new UserManagementContext(userTableComponent.render()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/user/management/UserManagementComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.management.UserManagementComponent.* 2 | @import de.tschuehly.easy.spring.auth.user.management.UserManagementComponent.UserManagementContext 3 | @param UserManagementContext userManagementContext 4 | 5 | 6 | 7 | Easy Spring Auth 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 |
23 | ${userManagementContext.viewContext()} 24 |
25 | 26 |
27 | 28 |
29 | 30 | -------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/CreateUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.create; 2 | 3 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 4 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 5 | 6 | @ViewComponent 7 | public class CreateUserComponent { 8 | 9 | public record CreateUserContext() implements ViewContext{} 10 | 11 | public ViewContext render(){ 12 | return new CreateUserContext(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/CreateUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import de.tschuehly.easy.spring.auth.user.UserController 2 |
3 |
4 | 8 | 12 | 15 |
16 |
-------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/EditUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.edit; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.UUID; 8 | 9 | @ViewComponent 10 | public class EditUserComponent { 11 | 12 | private final UserService userService; 13 | 14 | public EditUserComponent(UserService userService) { 15 | this.userService = userService; 16 | } 17 | 18 | public record EditUserContext(UUID uuid, String username, String password) implements ViewContext { 19 | 20 | } 21 | 22 | public ViewContext render(UUID uuid) { 23 | EasyUser user = userService.findById(uuid); 24 | return new EditUserContext(user.uuid, user.username, user.password); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/EditUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.management.edit.EditUserComponent.* 2 | @import de.tschuehly.easy.spring.auth.user.UserController 3 | @import de.tschuehly.easy.spring.auth.user.management.edit.EditUserComponent 4 | @param EditUserComponent.EditUserContext editUserContext 5 | 6 |
7 |
8 | 12 | 16 | 20 | 23 |
24 |
-------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/UserTableComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.table; 2 | 3 | import de.tschuehly.easy.spring.auth.user.UserService; 4 | import de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class UserTableComponent { 11 | private final UserService userService; 12 | private final UserRowComponent userRowComponent; 13 | 14 | public UserTableComponent(UserService userService, UserRowComponent userRowComponent) { 15 | this.userService = userService; 16 | this.userRowComponent = userRowComponent; 17 | } 18 | 19 | public record UserTableContext(List userTableRowList) implements ViewContext{ 20 | 21 | } 22 | public static final String USER_TABLE_BODY_ID = "userTableBody"; 23 | 24 | public ViewContext render(){ 25 | List rowList = userService.findAll().stream().map(userRowComponent::render).toList(); 26 | return new UserTableContext(rowList); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/UserTableComponent.jte: -------------------------------------------------------------------------------- 1 | @import de.tschuehly.easy.spring.auth.user.management.table.UserTableComponent.UserTableContext 2 | @import static de.tschuehly.easy.spring.auth.user.UserController.GET_CREATE_USER_MODAL 3 | @import static de.tschuehly.easy.spring.auth.user.management.UserManagementComponent.MODAL_CONTAINER_ID 4 | @import static de.tschuehly.easy.spring.auth.user.management.table.UserTableComponent.USER_TABLE_BODY_ID 5 | @param UserTableContext userTableContext 6 | 7 | 8 | 9 | 12 | 15 | 18 | 19 | 20 | 21 | @for(var row: userTableContext.userTableRowList()) 22 | ${row} 23 | @endfor 24 | 25 | 26 | 27 | 32 | 33 | 34 |
10 | uuid 11 | 13 | username 14 | 16 | password 17 |
28 | 31 |
-------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/row/UserRowComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.htmx.HtmxUtil.URI 2 | @import static de.tschuehly.easy.spring.auth.user.UserController.* 3 | @import static de.tschuehly.easy.spring.auth.user.management.UserManagementComponent.MODAL_CONTAINER_ID 4 | @import de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent.UserRowContext 5 | @param de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent.UserRowContext userRowContext 6 | 7 | !{var uuid = userRowContext.easyUser().uuid;} 8 | 9 | 10 | ${uuid.toString()} 11 | 12 | 13 | ${userRowContext.easyUser().username} 14 | 15 | 16 | ${userRowContext.easyUser().password} 17 | 18 | 19 | 23 | 24 | -------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/web/.gitinclude: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/lab-4/src/main/java/de/tschuehly/easy/spring/auth/web/.gitinclude -------------------------------------------------------------------------------- /lab-4/src/main/java/de/tschuehly/easy/spring/auth/web/layout/.gitinclude: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/lab-4/src/main/java/de/tschuehly/easy/spring/auth/web/layout/.gitinclude -------------------------------------------------------------------------------- /lab-4/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: easy-spring-auth 4 | view-component: 5 | local-development: true 6 | viewComponentRoot: lab-4/src/main/java 7 | gg: 8 | jte: 9 | developmentMode: true -------------------------------------------------------------------------------- /lab-4/src/main/resources/static/edit.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lab-4/src/main/resources/static/htmx_debug.js: -------------------------------------------------------------------------------- 1 | htmx.defineExtension('debug', { 2 | onEvent: function (name, evt) { 3 | if (console.debug) { 4 | console.debug(name, evt); 5 | } else if (console) { 6 | console.log("DEBUG:", name, evt); 7 | } else { 8 | throw "NO CONSOLE SUPPORTED" 9 | } 10 | } 11 | }); -------------------------------------------------------------------------------- /lab-4/src/main/resources/static/plus.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /lab-4/src/main/resources/static/spinner.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/Lab5Application.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth; 2 | 3 | import de.tschuehly.easy.spring.auth.group.GroupService; 4 | import de.tschuehly.easy.spring.auth.user.EasyUser; 5 | import de.tschuehly.easy.spring.auth.user.UserService; 6 | import org.springframework.boot.ApplicationRunner; 7 | import org.springframework.boot.SpringApplication; 8 | import org.springframework.boot.autoconfigure.SpringBootApplication; 9 | import org.springframework.context.annotation.Bean; 10 | 11 | @SpringBootApplication 12 | public class Lab5Application { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(Lab5Application.class, args); 16 | } 17 | @Bean 18 | public ApplicationRunner initializeUsers(UserService userService, GroupService groupService) { 19 | return (args) -> { 20 | EasyUser thomas = userService.createUser( 21 | "Thomas", 22 | "This is a password" 23 | ); 24 | userService.createUser( 25 | "Cassandra", 26 | "Test1234" 27 | ); 28 | groupService.createGroup("USER_GROUP"); 29 | groupService.createGroup("ADMIN_GROUP"); 30 | groupService.addUserToGroup("USER_GROUP", thomas.uuid); 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/group/EasyGroup.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class EasyGroup { 8 | public final String groupName; 9 | public final List memberList = new ArrayList<>(); 10 | 11 | public EasyGroup(String groupName) { 12 | this.groupName = groupName; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/group/management/GroupManagementComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management; 2 | 3 | import de.tschuehly.easy.spring.auth.group.GroupController; 4 | import de.tschuehly.easy.spring.auth.group.management.table.GroupTableComponent; 5 | import de.tschuehly.easy.spring.auth.web.Page; 6 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 7 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 8 | import org.springframework.core.annotation.Order; 9 | import org.springframework.stereotype.Component; 10 | 11 | @Component 12 | @Order(2) 13 | public class GroupManagementComponent implements Page { 14 | 15 | @Override 16 | public NavigationItem navigationItem() { 17 | return new NavigationItem("Group Management", GroupController.GROUP_MANAGEMENT); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/GroupTableComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management.table; 2 | 3 | import de.tschuehly.easy.spring.auth.group.EasyGroup; 4 | import de.tschuehly.easy.spring.auth.group.GroupService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class GroupTableComponent { 11 | private final GroupService groupService; 12 | 13 | public record GroupTableContext(List groupList) implements ViewContext{} 14 | 15 | public final static String GROUP_TABLE_ID = "groupTable"; 16 | public ViewContext render(){ 17 | List groupList = groupService.getAll(); 18 | return new GroupTableContext(groupList); 19 | } 20 | 21 | public GroupTableComponent(GroupService groupService) { 22 | this.groupService = groupService; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/user/AddUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management.table.user; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class AddUserComponent { 11 | private final UserService userService; 12 | 13 | public AddUserComponent(UserService userService) { 14 | this.userService = userService; 15 | } 16 | 17 | public record AddUserContext(String groupName, List easyUserList) implements ViewContext{} 18 | 19 | public ViewContext render(String groupName){ 20 | return new AddUserContext(groupName,userService.findAll()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/user/AddUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.group.GroupController.* 2 | @import de.tschuehly.easy.spring.auth.group.management.table.GroupTableComponent 3 | @import de.tschuehly.easy.spring.auth.htmx.HtmxUtil 4 | @param de.tschuehly.easy.spring.auth.group.management.table.user.AddUserComponent.AddUserContext addUserContext 5 |
8 | 13 | 14 |
-------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/user/EasyUser.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user; 2 | 3 | import java.util.UUID; 4 | 5 | public class EasyUser { 6 | 7 | public final UUID uuid; 8 | public final String password; 9 | public final String username; 10 | 11 | public EasyUser(String username, String password) { 12 | this.uuid = UUID.randomUUID(); 13 | this.password = password; 14 | this.username = username; 15 | } 16 | 17 | public EasyUser(UUID uuid, String username, String password) { 18 | this.uuid = uuid; 19 | this.username = username; 20 | this.password = password; 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/user/management/UserManagementComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management; 2 | 3 | import de.tschuehly.easy.spring.auth.user.UserController; 4 | import de.tschuehly.easy.spring.auth.web.Page; 5 | import org.springframework.core.annotation.Order; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Component 9 | @Order(1) 10 | public class UserManagementComponent implements Page { 11 | 12 | @Override 13 | public NavigationItem navigationItem() { 14 | return new NavigationItem("User Management", UserController.USER_MANAGEMENT_PATH); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/CreateUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.create; 2 | 3 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 4 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 5 | 6 | @ViewComponent 7 | public class CreateUserComponent { 8 | 9 | public record CreateUserContext() implements ViewContext{} 10 | 11 | public ViewContext render(){ 12 | return new CreateUserContext(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/CreateUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import de.tschuehly.easy.spring.auth.user.UserController 2 |
3 |
4 | 8 | 12 | 15 |
16 |
-------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/EditUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.edit; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.UUID; 8 | 9 | @ViewComponent 10 | public class EditUserComponent { 11 | 12 | private final UserService userService; 13 | 14 | public EditUserComponent(UserService userService) { 15 | this.userService = userService; 16 | } 17 | 18 | public record EditUserContext(UUID uuid, String username, String password) implements ViewContext { 19 | 20 | } 21 | 22 | public ViewContext render(UUID uuid) { 23 | EasyUser user = userService.findById(uuid); 24 | return new EditUserContext(user.uuid, user.username, user.password); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/EditUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.management.edit.EditUserComponent.* 2 | @import de.tschuehly.easy.spring.auth.user.UserController 3 | @import de.tschuehly.easy.spring.auth.user.management.edit.EditUserComponent 4 | @param EditUserComponent.EditUserContext editUserContext 5 | 6 |
7 |
8 | 12 | 16 | 20 | 23 |
24 |
-------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/UserTableComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.table; 2 | 3 | import de.tschuehly.easy.spring.auth.user.UserService; 4 | import de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class UserTableComponent { 11 | private final UserService userService; 12 | private final UserRowComponent userRowComponent; 13 | 14 | public UserTableComponent(UserService userService, UserRowComponent userRowComponent) { 15 | this.userService = userService; 16 | this.userRowComponent = userRowComponent; 17 | } 18 | 19 | public record UserTableContext(List userTableRowList) implements ViewContext{ 20 | 21 | } 22 | public static final String USER_TABLE_BODY_ID = "userTableBody"; 23 | 24 | public ViewContext render(){ 25 | List rowList = userService.findAll().stream().map(userRowComponent::render).toList(); 26 | return new UserTableContext(rowList); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/UserTableComponent.jte: -------------------------------------------------------------------------------- 1 | @import de.tschuehly.easy.spring.auth.user.management.table.UserTableComponent.UserTableContext 2 | @import static de.tschuehly.easy.spring.auth.user.UserController.GET_CREATE_USER_MODAL 3 | @import static de.tschuehly.easy.spring.auth.user.management.table.UserTableComponent.USER_TABLE_BODY_ID 4 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.MODAL_CONTAINER_ID 5 | @param UserTableContext userTableContext 6 | 7 | 8 | 9 | 12 | 15 | 18 | 19 | 20 | 21 | @for(var row: userTableContext.userTableRowList()) 22 | ${row} 23 | @endfor 24 | 25 | 26 | 27 | 32 | 33 | 34 |
10 | uuid 11 | 13 | username 14 | 16 | password 17 |
28 | 31 |
-------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/row/UserRowComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.htmx.HtmxUtil.URI 2 | @import static de.tschuehly.easy.spring.auth.user.UserController.* 3 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.MODAL_CONTAINER_ID 4 | @import de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent.UserRowContext 5 | @param de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent.UserRowContext userRowContext 6 | 7 | !{var uuid = userRowContext.easyUser().uuid;} 8 | 9 | 10 | ${uuid.toString()} 11 | 12 | 13 | ${userRowContext.easyUser().username} 14 | 15 | 16 | ${userRowContext.easyUser().password} 17 | 18 | 19 | 23 | 24 | -------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/web/Page.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web; 2 | 3 | public interface Page { 4 | record NavigationItem(String displayName, String URI){} 5 | 6 | NavigationItem navigationItem(); 7 | } 8 | -------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/web/layout/LayoutComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web.layout; 2 | 3 | import de.tschuehly.easy.spring.auth.web.Page; 4 | import de.tschuehly.easy.spring.auth.web.Page.NavigationItem; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class LayoutComponent { 11 | 12 | public static final String MODAL_CONTAINER_ID = "modalContainer"; 13 | public static final String CLOSE_MODAL_EVENT = "close-modal"; 14 | 15 | private final List pageList; 16 | 17 | public LayoutComponent(List pageList) { 18 | this.pageList = pageList; 19 | } 20 | 21 | public record LayoutContext(ViewContext content, List navigationItemList) implements ViewContext { 22 | 23 | } 24 | 25 | public ViewContext render(ViewContext content) { 26 | List navigationItemList = pageList.stream().map(it -> it.navigationItem()).toList(); 27 | return new LayoutContext(content, navigationItemList); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lab-5/src/main/java/de/tschuehly/easy/spring/auth/web/layout/LayoutComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.CLOSE_MODAL_EVENT 2 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.MODAL_CONTAINER_ID 3 | @import de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.LayoutContext 4 | @param LayoutContext layoutContext 5 | 6 | 7 | 8 | Easy Spring Auth 9 | 10 | 11 | 12 | 13 | 14 | 15 | 24 |
25 | ${layoutContext.content()} 26 |
27 | 28 |
29 | 30 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /lab-5/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: easy-spring-auth 4 | view-component: 5 | local-development: true 6 | viewComponentRoot: lab-5/src/main/java 7 | gg: 8 | jte: 9 | developmentMode: true -------------------------------------------------------------------------------- /lab-5/src/main/resources/static/edit.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lab-5/src/main/resources/static/htmx_debug.js: -------------------------------------------------------------------------------- 1 | htmx.defineExtension('debug', { 2 | onEvent: function (name, evt) { 3 | if (console.debug) { 4 | console.debug(name, evt); 5 | } else if (console) { 6 | console.log("DEBUG:", name, evt); 7 | } else { 8 | throw "NO CONSOLE SUPPORTED" 9 | } 10 | } 11 | }); -------------------------------------------------------------------------------- /lab-5/src/main/resources/static/plus.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /lab-5/src/main/resources/static/spinner.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/group/EasyGroup.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class EasyGroup { 8 | public final String groupName; 9 | public final List memberList = new ArrayList<>(); 10 | 11 | public EasyGroup(String groupName) { 12 | this.groupName = groupName; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/group/management/GroupManagementComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management; 2 | 3 | import de.tschuehly.easy.spring.auth.group.GroupController; 4 | import de.tschuehly.easy.spring.auth.group.management.table.GroupTableComponent; 5 | import de.tschuehly.easy.spring.auth.web.Page; 6 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 7 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 8 | import org.springframework.core.annotation.Order; 9 | import org.springframework.stereotype.Component; 10 | 11 | @Component 12 | @Order(2) 13 | public class GroupManagementComponent implements Page { 14 | 15 | @Override 16 | public NavigationItem navigationItem() { 17 | return new NavigationItem("Group Management", GroupController.GROUP_MANAGEMENT); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/GroupTableComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management.table; 2 | 3 | import de.tschuehly.easy.spring.auth.group.EasyGroup; 4 | import de.tschuehly.easy.spring.auth.group.GroupService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class GroupTableComponent { 11 | private final GroupService groupService; 12 | 13 | public record GroupTableContext(List groupList) implements ViewContext{} 14 | 15 | public final static String GROUP_TABLE_ID = "groupTable"; 16 | public ViewContext render(){ 17 | List groupList = groupService.getAll(); 18 | return new GroupTableContext(groupList); 19 | } 20 | 21 | public GroupTableComponent(GroupService groupService) { 22 | this.groupService = groupService; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/user/AddUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management.table.user; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class AddUserComponent { 11 | private final UserService userService; 12 | 13 | public AddUserComponent(UserService userService) { 14 | this.userService = userService; 15 | } 16 | 17 | public record AddUserContext(String groupName, List easyUserList) implements ViewContext{} 18 | 19 | public ViewContext render(String groupName){ 20 | return new AddUserContext(groupName,userService.findAll()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/user/AddUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.group.GroupController.* 2 | @import de.tschuehly.easy.spring.auth.group.management.table.GroupTableComponent 3 | @import de.tschuehly.easy.spring.auth.htmx.HtmxUtil 4 | @param de.tschuehly.easy.spring.auth.group.management.table.user.AddUserComponent.AddUserContext addUserContext 5 |
8 | 13 | 14 |
-------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/user/EasyUser.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user; 2 | 3 | import java.util.UUID; 4 | 5 | public class EasyUser { 6 | 7 | public final UUID uuid; 8 | public final String password; 9 | public final String username; 10 | 11 | public EasyUser(String username, String password) { 12 | this.uuid = UUID.randomUUID(); 13 | this.password = password; 14 | this.username = username; 15 | } 16 | 17 | public EasyUser(UUID uuid, String username, String password) { 18 | this.uuid = uuid; 19 | this.username = username; 20 | this.password = password; 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/user/management/UserManagementComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management; 2 | 3 | import de.tschuehly.easy.spring.auth.user.UserController; 4 | import de.tschuehly.easy.spring.auth.web.Page; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import org.springframework.core.annotation.Order; 8 | 9 | @ViewComponent 10 | @Order(1) 11 | public class UserManagementComponent implements Page { 12 | 13 | public ViewContext render() { 14 | return new UserManagementContext(); 15 | } 16 | 17 | public record UserManagementContext() implements ViewContext {} 18 | 19 | @Override 20 | public NavigationItem navigationItem() { 21 | return new NavigationItem("User Management", UserController.USER_MANAGEMENT_PATH); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/user/management/UserManagementComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.UserController.GET_USER_TABLE 2 |
3 | Result loading... 4 |
-------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/CreateUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.create; 2 | 3 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 4 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 5 | 6 | @ViewComponent 7 | public class CreateUserComponent { 8 | 9 | public record CreateUserContext() implements ViewContext{} 10 | 11 | public ViewContext render(){ 12 | return new CreateUserContext(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/CreateUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import de.tschuehly.easy.spring.auth.user.UserController 2 |
3 |
4 | 8 | 12 | 15 |
16 |
-------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/EditUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.edit; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.UUID; 8 | 9 | @ViewComponent 10 | public class EditUserComponent { 11 | 12 | private final UserService userService; 13 | 14 | public EditUserComponent(UserService userService) { 15 | this.userService = userService; 16 | } 17 | 18 | public record EditUserContext(UUID uuid, String username, String password) implements ViewContext { 19 | 20 | } 21 | 22 | public ViewContext render(UUID uuid) { 23 | EasyUser user = userService.findById(uuid); 24 | return new EditUserContext(user.uuid, user.username, user.password); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/EditUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.management.edit.EditUserComponent.* 2 | @import de.tschuehly.easy.spring.auth.user.UserController 3 | @import de.tschuehly.easy.spring.auth.user.management.edit.EditUserComponent 4 | @param EditUserComponent.EditUserContext editUserContext 5 | 6 |
7 |
8 | 12 | 16 | 20 | 23 |
24 |
-------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/UserTableComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.table; 2 | 3 | import de.tschuehly.easy.spring.auth.user.UserService; 4 | import de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class UserTableComponent { 11 | private final UserService userService; 12 | private final UserRowComponent userRowComponent; 13 | 14 | public UserTableComponent(UserService userService, UserRowComponent userRowComponent) { 15 | this.userService = userService; 16 | this.userRowComponent = userRowComponent; 17 | } 18 | 19 | public record UserTableContext(List userTableRowList) implements ViewContext{ 20 | 21 | } 22 | public static final String USER_TABLE_BODY_ID = "userTableBody"; 23 | 24 | public ViewContext render(){ 25 | List rowList = userService.findAll().stream().map(userRowComponent::render).toList(); 26 | return new UserTableContext(rowList); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/UserTableComponent.jte: -------------------------------------------------------------------------------- 1 | @import de.tschuehly.easy.spring.auth.user.management.table.UserTableComponent.UserTableContext 2 | @import static de.tschuehly.easy.spring.auth.user.UserController.GET_CREATE_USER_MODAL 3 | @import static de.tschuehly.easy.spring.auth.user.management.table.UserTableComponent.USER_TABLE_BODY_ID 4 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.MODAL_CONTAINER_ID 5 | @param UserTableContext userTableContext 6 | 7 | 8 | 9 | 12 | 15 | 18 | 19 | 20 | 21 | @for(var row: userTableContext.userTableRowList()) 22 | ${row} 23 | @endfor 24 | 25 | 26 | 27 | 32 | 33 | 34 |
10 | uuid 11 | 13 | username 14 | 16 | password 17 |
28 | 31 |
-------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/row/UserRowComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.htmx.HtmxUtil.URI 2 | @import static de.tschuehly.easy.spring.auth.user.UserController.* 3 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.MODAL_CONTAINER_ID 4 | @import de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent.UserRowContext 5 | @param de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent.UserRowContext userRowContext 6 | 7 | !{var uuid = userRowContext.easyUser().uuid;} 8 | 9 | 10 | ${uuid.toString()} 11 | 12 | 13 | ${userRowContext.easyUser().username} 14 | 15 | 16 | ${userRowContext.easyUser().password} 17 | 18 | 19 | 23 | 24 | -------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/web/Page.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web; 2 | 3 | public interface Page { 4 | record NavigationItem(String displayName, String URI){} 5 | 6 | NavigationItem navigationItem(); 7 | } 8 | -------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/web/layout/LayoutComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web.layout; 2 | 3 | import de.tschuehly.easy.spring.auth.web.Page; 4 | import de.tschuehly.easy.spring.auth.web.Page.NavigationItem; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class LayoutComponent { 11 | 12 | public static final String MODAL_CONTAINER_ID = "modalContainer"; 13 | public static final String CLOSE_MODAL_EVENT = "close-modal"; 14 | 15 | private final List pageList; 16 | 17 | public LayoutComponent(List pageList) { 18 | this.pageList = pageList; 19 | } 20 | 21 | public record LayoutContext(ViewContext content, List navigationItemList) implements ViewContext { 22 | 23 | } 24 | 25 | public ViewContext render(ViewContext content) { 26 | List navigationItemList = pageList.stream().map(it -> it.navigationItem()).toList(); 27 | return new LayoutContext(content, navigationItemList); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/web/layout/LayoutComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.CLOSE_MODAL_EVENT 2 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.MODAL_CONTAINER_ID 3 | @import de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.LayoutContext 4 | @param LayoutContext layoutContext 5 | 6 | 7 | 8 | Easy Spring Auth 9 | 10 | 11 | 12 | 13 | 14 | 15 | 24 |
25 | ${layoutContext.content()} 26 |
27 | 28 |
29 | 30 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /lab-6/src/main/java/de/tschuehly/easy/spring/auth/web/list/.gitinclude: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/lab-6/src/main/java/de/tschuehly/easy/spring/auth/web/list/.gitinclude -------------------------------------------------------------------------------- /lab-6/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: easy-spring-auth 4 | view-component: 5 | local-development: true 6 | viewComponentRoot: lab-6/src/main/java 7 | gg: 8 | jte: 9 | developmentMode: true -------------------------------------------------------------------------------- /lab-6/src/main/resources/static/edit.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lab-6/src/main/resources/static/htmx_debug.js: -------------------------------------------------------------------------------- 1 | htmx.defineExtension('debug', { 2 | onEvent: function (name, evt) { 3 | if (console.debug) { 4 | console.debug(name, evt); 5 | } else if (console) { 6 | console.log("DEBUG:", name, evt); 7 | } else { 8 | throw "NO CONSOLE SUPPORTED" 9 | } 10 | } 11 | }); -------------------------------------------------------------------------------- /lab-6/src/main/resources/static/plus.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /lab-6/src/main/resources/static/spinner.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/group/EasyGroup.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class EasyGroup { 8 | public final String groupName; 9 | public final List memberList = new ArrayList<>(); 10 | 11 | public EasyGroup(String groupName) { 12 | this.groupName = groupName; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/group/management/GroupManagementComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management; 2 | 3 | import de.tschuehly.easy.spring.auth.group.GroupController; 4 | import de.tschuehly.easy.spring.auth.group.management.table.GroupTableComponent; 5 | import de.tschuehly.easy.spring.auth.web.Page; 6 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 7 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 8 | import org.springframework.core.annotation.Order; 9 | import org.springframework.stereotype.Component; 10 | 11 | @Component 12 | @Order(2) 13 | public class GroupManagementComponent implements Page { 14 | 15 | @Override 16 | public NavigationItem navigationItem() { 17 | return new NavigationItem("Group Management", GroupController.GROUP_MANAGEMENT); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/GroupTableComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management.table; 2 | 3 | import de.tschuehly.easy.spring.auth.group.EasyGroup; 4 | import de.tschuehly.easy.spring.auth.group.GroupService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class GroupTableComponent { 11 | private final GroupService groupService; 12 | 13 | public record GroupTableContext(List groupList) implements ViewContext{} 14 | 15 | public final static String GROUP_TABLE_ID = "groupTable"; 16 | public ViewContext render(){ 17 | List groupList = groupService.getAll(); 18 | return new GroupTableContext(groupList); 19 | } 20 | 21 | public GroupTableComponent(GroupService groupService) { 22 | this.groupService = groupService; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/user/AddUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management.table.user; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class AddUserComponent { 11 | private final UserService userService; 12 | 13 | public AddUserComponent(UserService userService) { 14 | this.userService = userService; 15 | } 16 | 17 | public record AddUserContext(String groupName, List easyUserList) implements ViewContext{} 18 | 19 | public ViewContext render(String groupName){ 20 | return new AddUserContext(groupName,userService.findAll()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/user/AddUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.group.GroupController.* 2 | @import de.tschuehly.easy.spring.auth.group.management.table.GroupTableComponent 3 | @import de.tschuehly.easy.spring.auth.htmx.HtmxUtil 4 | @param de.tschuehly.easy.spring.auth.group.management.table.user.AddUserComponent.AddUserContext addUserContext 5 |
8 | 13 | 14 |
-------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/user/EasyUser.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user; 2 | 3 | import java.util.UUID; 4 | 5 | public class EasyUser { 6 | 7 | public final UUID uuid; 8 | public final String password; 9 | public final String username; 10 | 11 | public EasyUser(String username, String password) { 12 | this.uuid = UUID.randomUUID(); 13 | this.password = password; 14 | this.username = username; 15 | } 16 | 17 | public EasyUser(UUID uuid, String username, String password) { 18 | this.uuid = uuid; 19 | this.username = username; 20 | this.password = password; 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/user/management/UserManagementComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management; 2 | 3 | import de.tschuehly.easy.spring.auth.user.UserController; 4 | import de.tschuehly.easy.spring.auth.web.Page; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import org.springframework.core.annotation.Order; 8 | 9 | @ViewComponent 10 | @Order(1) 11 | public class UserManagementComponent implements Page { 12 | 13 | public ViewContext render() { 14 | return new UserManagementContext(); 15 | } 16 | 17 | public record UserManagementContext() implements ViewContext { 18 | 19 | } 20 | 21 | @Override 22 | public NavigationItem navigationItem() { 23 | return new NavigationItem("User Management", UserController.USER_MANAGEMENT_PATH); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/user/management/UserManagementComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.UserController.GET_USER_TABLE 2 |
3 | Result loading... 4 |
-------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/CreateUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.create; 2 | 3 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 4 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 5 | 6 | @ViewComponent 7 | public class CreateUserComponent { 8 | 9 | public record CreateUserContext() implements ViewContext{} 10 | 11 | public ViewContext render(){ 12 | return new CreateUserContext(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/CreateUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import de.tschuehly.easy.spring.auth.user.UserController 2 |
3 |
4 | 8 | 12 | 15 |
16 |
-------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/EditUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.edit; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.UUID; 8 | 9 | @ViewComponent 10 | public class EditUserComponent { 11 | 12 | private final UserService userService; 13 | 14 | public EditUserComponent(UserService userService) { 15 | this.userService = userService; 16 | } 17 | 18 | public record EditUserContext(UUID uuid, String username, String password) implements ViewContext { 19 | 20 | } 21 | 22 | public ViewContext render(UUID uuid) { 23 | EasyUser user = userService.findById(uuid); 24 | return new EditUserContext(user.uuid, user.username, user.password); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/EditUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.management.edit.EditUserComponent.* 2 | @import de.tschuehly.easy.spring.auth.user.UserController 3 | @import de.tschuehly.easy.spring.auth.user.management.edit.EditUserComponent 4 | @param EditUserComponent.EditUserContext editUserContext 5 | 6 |
7 |
8 | 12 | 16 | 20 | 23 |
24 |
-------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/infinite/.gitinclude: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/lab-7/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/infinite/.gitinclude -------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/row/UserRowComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.htmx.HtmxUtil.URI 2 | @import static de.tschuehly.easy.spring.auth.user.UserController.* 3 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.MODAL_CONTAINER_ID 4 | @import de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent.UserRowContext 5 | @param de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent.UserRowContext userRowContext 6 | 7 | !{var uuid = userRowContext.easyUser().uuid;} 8 | 9 | 10 | ${uuid.toString()} 11 | 12 | 13 | ${userRowContext.easyUser().username} 14 | 15 | 16 | ${userRowContext.easyUser().password} 17 | 18 | 19 | 23 | 24 | -------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/web/Page.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web; 2 | 3 | public interface Page { 4 | record NavigationItem(String displayName, String URI){} 5 | 6 | NavigationItem navigationItem(); 7 | } 8 | -------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/web/layout/LayoutComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web.layout; 2 | 3 | import de.tschuehly.easy.spring.auth.web.Page; 4 | import de.tschuehly.easy.spring.auth.web.Page.NavigationItem; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class LayoutComponent { 11 | 12 | public static final String MODAL_CONTAINER_ID = "modalContainer"; 13 | public static final String CLOSE_MODAL_EVENT = "close-modal"; 14 | 15 | private final List pageList; 16 | 17 | public LayoutComponent(List pageList) { 18 | this.pageList = pageList; 19 | } 20 | 21 | public record LayoutContext(ViewContext content, List navigationItemList) implements ViewContext { 22 | 23 | } 24 | 25 | public ViewContext render(ViewContext content) { 26 | List navigationItemList = pageList.stream().map(it -> it.navigationItem()).toList(); 27 | return new LayoutContext(content, navigationItemList); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/web/layout/LayoutComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.CLOSE_MODAL_EVENT 2 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.MODAL_CONTAINER_ID 3 | @import de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.LayoutContext 4 | @param LayoutContext layoutContext 5 | 6 | 7 | 8 | Easy Spring Auth 9 | 10 | 11 | 12 | 13 | 14 | 15 | 24 |
25 | ${layoutContext.content()} 26 |
27 | 28 |
29 | 30 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/web/list/ListComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web.list; 2 | 3 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 4 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 5 | import java.util.List; 6 | 7 | @ViewComponent 8 | public class ListComponent { 9 | 10 | public ViewContext render(List viewContextList){ 11 | return new ListContext(viewContextList); 12 | } 13 | 14 | public record ListContext(List viewContextList) implements ViewContext { 15 | 16 | } 17 | } -------------------------------------------------------------------------------- /lab-7/src/main/java/de/tschuehly/easy/spring/auth/web/list/ListComponent.jte: -------------------------------------------------------------------------------- 1 | @param de.tschuehly.easy.spring.auth.web.list.ListComponent.ListContext listContext 2 | 3 | @for(var context: listContext.viewContextList()) 4 | ${context} 5 | @endfor -------------------------------------------------------------------------------- /lab-7/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: easy-spring-auth 4 | view-component: 5 | local-development: true 6 | viewComponentRoot: lab-7/src/main/java 7 | gg: 8 | jte: 9 | developmentMode: true -------------------------------------------------------------------------------- /lab-7/src/main/resources/static/edit.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lab-7/src/main/resources/static/htmx_debug.js: -------------------------------------------------------------------------------- 1 | htmx.defineExtension('debug', { 2 | onEvent: function (name, evt) { 3 | if (console.debug) { 4 | console.debug(name, evt); 5 | } else if (console) { 6 | console.log("DEBUG:", name, evt); 7 | } else { 8 | throw "NO CONSOLE SUPPORTED" 9 | } 10 | } 11 | }); -------------------------------------------------------------------------------- /lab-7/src/main/resources/static/plus.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /lab-7/src/main/resources/static/spinner.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/group/EasyGroup.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class EasyGroup { 8 | public final String groupName; 9 | public final List memberList = new ArrayList<>(); 10 | 11 | public EasyGroup(String groupName) { 12 | this.groupName = groupName; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/group/management/GroupManagementComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management; 2 | 3 | import de.tschuehly.easy.spring.auth.group.GroupController; 4 | import de.tschuehly.easy.spring.auth.web.Page; 5 | import org.springframework.core.annotation.Order; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Component 9 | @Order(2) 10 | public class GroupManagementComponent implements Page { 11 | 12 | @Override 13 | public NavigationItem navigationItem() { 14 | return new NavigationItem("Group Management", GroupController.GROUP_MANAGEMENT); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/GroupTableComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management.table; 2 | 3 | import de.tschuehly.easy.spring.auth.group.EasyGroup; 4 | import de.tschuehly.easy.spring.auth.group.GroupService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class GroupTableComponent { 11 | private final GroupService groupService; 12 | 13 | public record GroupTableContext(List groupList) implements ViewContext{} 14 | 15 | public final static String GROUP_TABLE_ID = "groupTable"; 16 | public ViewContext render(){ 17 | List groupList = groupService.getAll(); 18 | return new GroupTableContext(groupList); 19 | } 20 | 21 | public GroupTableComponent(GroupService groupService) { 22 | this.groupService = groupService; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/user/AddUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management.table.user; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class AddUserComponent { 11 | private final UserService userService; 12 | 13 | public AddUserComponent(UserService userService) { 14 | this.userService = userService; 15 | } 16 | 17 | public record AddUserContext(String groupName, List easyUserList) implements ViewContext{} 18 | 19 | public ViewContext render(String groupName){ 20 | return new AddUserContext(groupName,userService.findAll()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/user/AddUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.group.GroupController.* 2 | @import de.tschuehly.easy.spring.auth.group.management.table.GroupTableComponent 3 | @import de.tschuehly.easy.spring.auth.htmx.HtmxUtil 4 | @param de.tschuehly.easy.spring.auth.group.management.table.user.AddUserComponent.AddUserContext addUserContext 5 |
8 | 13 | 14 |
-------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/user/EasyUser.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user; 2 | 3 | import java.util.UUID; 4 | 5 | public class EasyUser { 6 | 7 | public final UUID uuid; 8 | public final String password; 9 | public final String username; 10 | 11 | public EasyUser(String username, String password) { 12 | this.uuid = UUID.randomUUID(); 13 | this.password = password; 14 | this.username = username; 15 | } 16 | 17 | public EasyUser(UUID uuid, String username, String password) { 18 | this.uuid = uuid; 19 | this.username = username; 20 | this.password = password; 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/user/management/UserManagementComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management; 2 | 3 | import de.tschuehly.easy.spring.auth.user.UserController; 4 | import de.tschuehly.easy.spring.auth.web.Page; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import org.springframework.core.annotation.Order; 8 | 9 | @ViewComponent 10 | @Order(1) 11 | public class UserManagementComponent implements Page { 12 | 13 | public ViewContext render() { 14 | return new UserManagementContext(); 15 | } 16 | 17 | public record UserManagementContext() implements ViewContext { 18 | 19 | } 20 | 21 | @Override 22 | public NavigationItem navigationItem() { 23 | return new NavigationItem("User Management", UserController.USER_MANAGEMENT_PATH); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/user/management/UserManagementComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.UserController.* 2 | @import de.tschuehly.easy.spring.auth.htmx.HtmxUtil 3 | 4 |
5 | Result loading... 6 |
7 | 8 | -------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/CreateUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.create; 2 | 3 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 4 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 5 | 6 | @ViewComponent 7 | public class CreateUserComponent { 8 | 9 | public record CreateUserContext() implements ViewContext{} 10 | 11 | public ViewContext render(){ 12 | return new CreateUserContext(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/CreateUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import de.tschuehly.easy.spring.auth.user.UserController 2 |
3 |
4 | 8 | 12 | 15 |
16 |
-------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/EditUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.edit; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.UUID; 8 | 9 | @ViewComponent 10 | public class EditUserComponent { 11 | 12 | private final UserService userService; 13 | 14 | public EditUserComponent(UserService userService) { 15 | this.userService = userService; 16 | } 17 | 18 | public record EditUserContext(UUID uuid, String username, String password) implements ViewContext { 19 | 20 | } 21 | 22 | public ViewContext render(UUID uuid) { 23 | EasyUser user = userService.findById(uuid); 24 | return new EditUserContext(user.uuid, user.username, user.password); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/EditUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.management.edit.EditUserComponent.* 2 | @import de.tschuehly.easy.spring.auth.user.UserController 3 | @import de.tschuehly.easy.spring.auth.user.management.edit.EditUserComponent 4 | @param EditUserComponent.EditUserContext editUserContext 5 | 6 |
7 |
8 | 12 | 16 | 20 | 23 |
24 |
-------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/infinite/InfiniteLoadComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.table.infinite; 2 | 3 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 4 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 5 | 6 | @ViewComponent 7 | public class InfiniteLoadComponent { 8 | 9 | public ViewContext render(int nextPage){ 10 | return new InfiniteLoadContext(nextPage); 11 | } 12 | 13 | public record InfiniteLoadContext(int nextPage) implements ViewContext { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/infinite/InfiniteLoadComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.UserController.* 2 | @import de.tschuehly.easy.spring.auth.htmx.HtmxUtil 3 | @import de.tschuehly.easy.spring.auth.user.management.table.infinite.InfiniteLoadComponent.InfiniteLoadContext 4 | @param InfiniteLoadContext infiniteLoadContext 5 | 7 | 8 | -------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/row/UserRowComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.htmx.HtmxUtil.URI 2 | @import static de.tschuehly.easy.spring.auth.user.UserController.* 3 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.MODAL_CONTAINER_ID 4 | @import de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent.UserRowContext 5 | @param de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent.UserRowContext userRowContext 6 | 7 | !{var uuid = userRowContext.easyUser().uuid;} 8 | 9 | 10 | ${uuid.toString()} 11 | 12 | 13 | ${userRowContext.easyUser().username} 14 | 15 | 16 | ${userRowContext.easyUser().password} 17 | 18 | 19 | 23 | 24 | -------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/web/Page.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web; 2 | 3 | public interface Page { 4 | record NavigationItem(String displayName, String URI){} 5 | 6 | NavigationItem navigationItem(); 7 | } 8 | -------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/web/layout/LayoutComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web.layout; 2 | 3 | import de.tschuehly.easy.spring.auth.web.Page; 4 | import de.tschuehly.easy.spring.auth.web.Page.NavigationItem; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class LayoutComponent { 11 | 12 | public static final String MODAL_CONTAINER_ID = "modalContainer"; 13 | public static final String CLOSE_MODAL_EVENT = "close-modal"; 14 | 15 | private final List pageList; 16 | 17 | public LayoutComponent(List pageList) { 18 | this.pageList = pageList; 19 | } 20 | 21 | public record LayoutContext(ViewContext content, List navigationItemList) implements ViewContext { 22 | 23 | } 24 | 25 | public ViewContext render(ViewContext content) { 26 | List navigationItemList = pageList.stream().map(it -> it.navigationItem()).toList(); 27 | return new LayoutContext(content, navigationItemList); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/web/layout/LayoutComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.CLOSE_MODAL_EVENT 2 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.MODAL_CONTAINER_ID 3 | @import de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.LayoutContext 4 | @param LayoutContext layoutContext 5 | 6 | 7 | 8 | Easy Spring Auth 9 | 10 | 11 | 12 | 13 | 14 | 15 | 24 |
25 | ${layoutContext.content()} 26 |
27 | 28 |
29 | 30 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/web/list/ListComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web.list; 2 | 3 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 4 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class ListComponent { 11 | 12 | public ViewContext render(List viewContextList){ 13 | return new ListContext(viewContextList); 14 | } 15 | public ViewContext render(List viewContextList, ViewContext... viewContext){ 16 | ArrayList combinedList = new ArrayList<>(); 17 | combinedList.addAll(viewContextList); 18 | combinedList.addAll(List.of(viewContext)); 19 | return new ListContext(combinedList); 20 | } 21 | public ViewContext render( ViewContext... viewContext){ 22 | return new ListContext(Arrays.stream(viewContext).toList()); 23 | } 24 | 25 | public record ListContext(List viewContextList) implements ViewContext { 26 | 27 | } 28 | } -------------------------------------------------------------------------------- /lab-8/src/main/java/de/tschuehly/easy/spring/auth/web/list/ListComponent.jte: -------------------------------------------------------------------------------- 1 | @param de.tschuehly.easy.spring.auth.web.list.ListComponent.ListContext listContext 2 | 3 | @for(var context: listContext.viewContextList()) 4 | ${context} 5 | @endfor -------------------------------------------------------------------------------- /lab-8/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: easy-spring-auth 4 | view-component: 5 | local-development: true 6 | viewComponentRoot: lab-8/src/main/java 7 | gg: 8 | jte: 9 | developmentMode: true -------------------------------------------------------------------------------- /lab-8/src/main/resources/static/edit.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lab-8/src/main/resources/static/htmx_debug.js: -------------------------------------------------------------------------------- 1 | htmx.defineExtension('debug', { 2 | onEvent: function (name, evt) { 3 | if (console.debug) { 4 | console.debug(name, evt); 5 | } else if (console) { 6 | console.log("DEBUG:", name, evt); 7 | } else { 8 | throw "NO CONSOLE SUPPORTED" 9 | } 10 | } 11 | }); -------------------------------------------------------------------------------- /lab-8/src/main/resources/static/plus.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /lab-8/src/main/resources/static/spinner.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/group/EasyGroup.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class EasyGroup { 8 | public final String groupName; 9 | public final List memberList = new ArrayList<>(); 10 | 11 | public EasyGroup(String groupName) { 12 | this.groupName = groupName; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/group/management/GroupManagementComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management; 2 | 3 | import de.tschuehly.easy.spring.auth.group.GroupController; 4 | import de.tschuehly.easy.spring.auth.web.Page; 5 | import org.springframework.core.annotation.Order; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Component 9 | @Order(2) 10 | public class GroupManagementComponent implements Page { 11 | 12 | @Override 13 | public NavigationItem navigationItem() { 14 | return new NavigationItem("Group Management", GroupController.GROUP_MANAGEMENT); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/GroupTableComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management.table; 2 | 3 | import de.tschuehly.easy.spring.auth.group.EasyGroup; 4 | import de.tschuehly.easy.spring.auth.group.GroupService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class GroupTableComponent { 11 | private final GroupService groupService; 12 | 13 | public record GroupTableContext(List groupList) implements ViewContext{} 14 | 15 | public final static String GROUP_TABLE_ID = "groupTable"; 16 | public ViewContext render(){ 17 | List groupList = groupService.getAll(); 18 | return new GroupTableContext(groupList); 19 | } 20 | 21 | public GroupTableComponent(GroupService groupService) { 22 | this.groupService = groupService; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/user/AddUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management.table.user; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class AddUserComponent { 11 | private final UserService userService; 12 | 13 | public AddUserComponent(UserService userService) { 14 | this.userService = userService; 15 | } 16 | 17 | public record AddUserContext(String groupName, List easyUserList) implements ViewContext{} 18 | 19 | public ViewContext render(String groupName){ 20 | return new AddUserContext(groupName,userService.findAll()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/user/AddUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.group.GroupController.* 2 | @import de.tschuehly.easy.spring.auth.group.management.table.GroupTableComponent 3 | @import de.tschuehly.easy.spring.auth.htmx.HtmxUtil 4 | @param de.tschuehly.easy.spring.auth.group.management.table.user.AddUserComponent.AddUserContext addUserContext 5 |
8 | 13 | 14 |
-------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/user/EasyUser.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user; 2 | 3 | import java.util.UUID; 4 | 5 | public class EasyUser { 6 | 7 | public final UUID uuid; 8 | public final String password; 9 | public final String username; 10 | 11 | public EasyUser(String username, String password) { 12 | this.uuid = UUID.randomUUID(); 13 | this.password = password; 14 | this.username = username; 15 | } 16 | 17 | public EasyUser(UUID uuid, String username, String password) { 18 | this.uuid = uuid; 19 | this.username = username; 20 | this.password = password; 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/user/UserNotFoundException.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user; 2 | 3 | import de.tschuehly.easy.spring.auth.web.exception.InfoException; 4 | 5 | public class UserNotFoundException extends InfoException { 6 | 7 | public UserNotFoundException(String message) { 8 | super(message); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/user/management/UserManagementComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management; 2 | 3 | import de.tschuehly.easy.spring.auth.user.UserController; 4 | import de.tschuehly.easy.spring.auth.web.Page; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import org.springframework.core.annotation.Order; 8 | 9 | @ViewComponent 10 | @Order(1) 11 | public class UserManagementComponent implements Page { 12 | 13 | public ViewContext render() { 14 | return new UserManagementContext(); 15 | } 16 | 17 | public record UserManagementContext() implements ViewContext { 18 | 19 | } 20 | 21 | @Override 22 | public NavigationItem navigationItem() { 23 | return new NavigationItem("User Management", UserController.USER_MANAGEMENT_PATH); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/user/management/UserManagementComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.UserController.* 2 | @import de.tschuehly.easy.spring.auth.htmx.HtmxUtil 3 | 4 |
5 | Result loading... 6 |
7 | 8 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/CreateUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.create; 2 | 3 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 4 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 5 | 6 | @ViewComponent 7 | public class CreateUserComponent { 8 | 9 | public record CreateUserContext() implements ViewContext{} 10 | 11 | public ViewContext render(){ 12 | return new CreateUserContext(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/CreateUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import de.tschuehly.easy.spring.auth.user.UserController 2 |
3 |
4 | 8 | 12 | 15 |
16 |
-------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/EditUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.edit; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.UUID; 8 | 9 | @ViewComponent 10 | public class EditUserComponent { 11 | 12 | private final UserService userService; 13 | 14 | public EditUserComponent(UserService userService) { 15 | this.userService = userService; 16 | } 17 | 18 | public record EditUserContext(UUID uuid, String username, String password) implements ViewContext { 19 | 20 | } 21 | 22 | public ViewContext render(UUID uuid) { 23 | EasyUser user = userService.findById(uuid); 24 | return new EditUserContext(user.uuid, user.username, user.password); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/EditUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.management.edit.EditUserComponent.* 2 | @import de.tschuehly.easy.spring.auth.user.UserController 3 | @import de.tschuehly.easy.spring.auth.user.management.edit.EditUserComponent 4 | @param EditUserComponent.EditUserContext editUserContext 5 | 6 |
7 |
8 | 12 | 16 | 20 | 23 |
24 |
-------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/infinite/InfiniteLoadComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.table.infinite; 2 | 3 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 4 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 5 | 6 | @ViewComponent 7 | public class InfiniteLoadComponent { 8 | 9 | public ViewContext render(int nextPage){ 10 | return new InfiniteLoadContext(nextPage); 11 | } 12 | 13 | public record InfiniteLoadContext(int nextPage) implements ViewContext { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/infinite/InfiniteLoadComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.UserController.* 2 | @import de.tschuehly.easy.spring.auth.htmx.HtmxUtil 3 | @import de.tschuehly.easy.spring.auth.user.management.table.infinite.InfiniteLoadComponent.InfiniteLoadContext 4 | @param InfiniteLoadContext infiniteLoadContext 5 | 7 | 8 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/row/UserRowComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.htmx.HtmxUtil.URI 2 | @import static de.tschuehly.easy.spring.auth.user.UserController.* 3 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.MODAL_CONTAINER_ID 4 | @import de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent.UserRowContext 5 | @param de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent.UserRowContext userRowContext 6 | 7 | !{var uuid = userRowContext.easyUser().uuid;} 8 | 9 | 10 | ${uuid.toString()} 11 | 12 | 13 | ${userRowContext.easyUser().username} 14 | 15 | 16 | ${userRowContext.easyUser().password} 17 | 18 | 19 | 23 | 24 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/web/Page.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web; 2 | 3 | public interface Page { 4 | record NavigationItem(String displayName, String URI){} 5 | 6 | NavigationItem navigationItem(); 7 | } 8 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/web/advice/ExceptionAdvice.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web.advice; 2 | 3 | import de.tschuehly.easy.spring.auth.htmx.HtmxUtil; 4 | import de.tschuehly.easy.spring.auth.web.exception.InfoException; 5 | import de.tschuehly.easy.spring.auth.web.layout.LayoutComponent; 6 | import de.tschuehly.easy.spring.auth.web.message.MessageComponent; 7 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 8 | import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxSwapType; 9 | import org.springframework.web.bind.annotation.ControllerAdvice; 10 | import org.springframework.web.bind.annotation.ExceptionHandler; 11 | 12 | @ControllerAdvice 13 | public class ExceptionAdvice { 14 | 15 | private final MessageComponent messageComponent; 16 | 17 | public ExceptionAdvice(MessageComponent messageComponent) { 18 | this.messageComponent = messageComponent; 19 | } 20 | 21 | @ExceptionHandler(InfoException.class) 22 | public ViewContext handle(InfoException e) { 23 | HtmxUtil.retarget(HtmxUtil.idSelector(LayoutComponent.TOAST_CONTAINER_ID)); 24 | HtmxUtil.swap(HxSwapType.INNER_HTML); 25 | return messageComponent.renderInfoToast(e.getMessage()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/web/exception/InfoException.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web.exception; 2 | 3 | public class InfoException extends RuntimeException{ 4 | 5 | public InfoException(String message) { 6 | super(message); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/web/layout/LayoutComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web.layout; 2 | 3 | import de.tschuehly.easy.spring.auth.web.Page; 4 | import de.tschuehly.easy.spring.auth.web.Page.NavigationItem; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class LayoutComponent { 11 | 12 | public static final String MODAL_CONTAINER_ID = "modalContainer"; 13 | public static final String CLOSE_MODAL_EVENT = "close-modal"; 14 | public static final String TOAST_CONTAINER_ID = "toastContainer"; 15 | 16 | private final List pageList; 17 | 18 | public LayoutComponent(List pageList) { 19 | this.pageList = pageList; 20 | } 21 | 22 | public record LayoutContext(ViewContext content, List navigationItemList) implements ViewContext { 23 | 24 | } 25 | 26 | public ViewContext render(ViewContext content) { 27 | List navigationItemList = pageList.stream().map(Page::navigationItem).toList(); 28 | return new LayoutContext(content, navigationItemList); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/web/layout/LayoutComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.CLOSE_MODAL_EVENT 2 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.MODAL_CONTAINER_ID 3 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.TOAST_CONTAINER_ID 4 | @import de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.LayoutContext 5 | @param LayoutContext layoutContext 6 | 7 | 8 | 9 | Easy Spring Auth 10 | 11 | 12 | 13 | 14 | 15 | 16 | 25 |
26 | ${layoutContext.content()} 27 |
28 | 29 |
30 | 31 |
32 |
33 | 34 |
35 | 36 | 37 | -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/web/list/ListComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web.list; 2 | 3 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 4 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class ListComponent { 11 | 12 | public ViewContext render(List viewContextList){ 13 | return new ListContext(viewContextList); 14 | } 15 | public ViewContext render(List viewContextList, ViewContext... viewContext){ 16 | ArrayList combinedList = new ArrayList<>(); 17 | combinedList.addAll(viewContextList); 18 | combinedList.addAll(List.of(viewContext)); 19 | return new ListContext(combinedList); 20 | } 21 | public ViewContext render( ViewContext... viewContext){ 22 | return new ListContext(Arrays.stream(viewContext).toList()); 23 | } 24 | 25 | public record ListContext(List viewContextList) implements ViewContext { 26 | 27 | } 28 | } -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/web/list/ListComponent.jte: -------------------------------------------------------------------------------- 1 | @param de.tschuehly.easy.spring.auth.web.list.ListComponent.ListContext listContext 2 | 3 | @for(var context: listContext.viewContextList()) 4 | ${context} 5 | @endfor -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/web/message/MessageComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web.message; 2 | 3 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 4 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 5 | 6 | @ViewComponent 7 | public class MessageComponent { 8 | 9 | public ViewContext renderInfoToast(String message) { 10 | return new MessageContext(message, MessageType.INFO); 11 | } 12 | 13 | public ViewContext renderErrorToast(String message) { 14 | return new MessageContext(message, MessageType.TOAST_ERROR); 15 | } 16 | 17 | public record MessageContext(String message, MessageType type) implements 18 | ViewContext {} 19 | 20 | public enum MessageType { 21 | TOAST_ERROR, 22 | NONE, 23 | INFO; 24 | 25 | public String severity() { 26 | return switch (this) { 27 | case TOAST_ERROR -> "error"; 28 | case INFO -> "info"; 29 | default -> ""; 30 | }; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /lab-9/src/main/java/de/tschuehly/easy/spring/auth/web/message/MessageComponent.jte: -------------------------------------------------------------------------------- 1 | @import de.tschuehly.easy.spring.auth.web.message.MessageComponent.MessageContext 2 | @import java.util.Date 3 | @param MessageContext messageContext 4 | 5 | !{var id = String.valueOf(new Date().getTime());} 6 | 14 | -------------------------------------------------------------------------------- /lab-9/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: easy-spring-auth 4 | view-component: 5 | local-development: true 6 | viewComponentRoot: lab-9/src/main/java 7 | gg: 8 | jte: 9 | developmentMode: true -------------------------------------------------------------------------------- /lab-9/src/main/resources/static/edit.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lab-9/src/main/resources/static/htmx_debug.js: -------------------------------------------------------------------------------- 1 | htmx.defineExtension('debug', { 2 | onEvent: function (name, evt) { 3 | if (console.debug) { 4 | console.debug(name, evt); 5 | } else if (console) { 6 | console.log("DEBUG:", name, evt); 7 | } else { 8 | throw "NO CONSOLE SUPPORTED" 9 | } 10 | } 11 | }); -------------------------------------------------------------------------------- /lab-9/src/main/resources/static/plus.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /lab-9/src/main/resources/static/spinner.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /lab-completed/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/lab-completed/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /lab-completed/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /lab-completed/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "lab-completed" -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/group/EasyGroup.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class EasyGroup { 8 | public final String groupName; 9 | public final List memberList = new ArrayList<>(); 10 | 11 | public EasyGroup(String groupName) { 12 | this.groupName = groupName; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/group/management/GroupManagementComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management; 2 | 3 | import de.tschuehly.easy.spring.auth.group.GroupController; 4 | import de.tschuehly.easy.spring.auth.web.Page; 5 | import org.springframework.core.annotation.Order; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Component 9 | @Order(2) 10 | public class GroupManagementComponent implements Page { 11 | 12 | @Override 13 | public NavigationItem navigationItem() { 14 | return new NavigationItem("Group Management", GroupController.GROUP_MANAGEMENT); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/GroupTableComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management.table; 2 | 3 | import de.tschuehly.easy.spring.auth.group.EasyGroup; 4 | import de.tschuehly.easy.spring.auth.group.GroupService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class GroupTableComponent { 11 | private final GroupService groupService; 12 | 13 | public record GroupTableContext(List groupList) implements ViewContext{} 14 | 15 | public final static String GROUP_TABLE_ID = "groupTable"; 16 | public ViewContext render(){ 17 | List groupList = groupService.getAll(); 18 | return new GroupTableContext(groupList); 19 | } 20 | 21 | public GroupTableComponent(GroupService groupService) { 22 | this.groupService = groupService; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/user/AddUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.group.management.table.user; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class AddUserComponent { 11 | private final UserService userService; 12 | 13 | public AddUserComponent(UserService userService) { 14 | this.userService = userService; 15 | } 16 | 17 | public record AddUserContext(String groupName, List easyUserList) implements ViewContext{} 18 | 19 | public ViewContext render(String groupName){ 20 | return new AddUserContext(groupName,userService.findAll()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/group/management/table/user/AddUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.group.GroupController.* 2 | @import de.tschuehly.easy.spring.auth.group.management.table.GroupTableComponent 3 | @import de.tschuehly.easy.spring.auth.htmx.HtmxUtil 4 | @param de.tschuehly.easy.spring.auth.group.management.table.user.AddUserComponent.AddUserContext addUserContext 5 |
8 | 13 | 14 |
-------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/user/EasyUser.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user; 2 | 3 | import java.util.UUID; 4 | 5 | public class EasyUser { 6 | 7 | public final UUID uuid; 8 | public final String password; 9 | public final String username; 10 | 11 | public EasyUser(String username, String password) { 12 | this.uuid = UUID.randomUUID(); 13 | this.password = password; 14 | this.username = username; 15 | } 16 | 17 | public EasyUser(UUID uuid, String username, String password) { 18 | this.uuid = uuid; 19 | this.username = username; 20 | this.password = password; 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/user/UserNotFoundException.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user; 2 | 3 | import de.tschuehly.easy.spring.auth.web.exception.InfoException; 4 | 5 | public class UserNotFoundException extends InfoException { 6 | 7 | public UserNotFoundException(String message) { 8 | super(message); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/user/management/UserManagementComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management; 2 | 3 | import de.tschuehly.easy.spring.auth.user.UserController; 4 | import de.tschuehly.easy.spring.auth.web.Page; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import org.springframework.core.annotation.Order; 8 | 9 | @ViewComponent 10 | @Order(1) 11 | public class UserManagementComponent implements Page { 12 | 13 | public ViewContext render() { 14 | return new UserManagementContext(); 15 | } 16 | 17 | public record UserManagementContext() implements ViewContext { 18 | 19 | } 20 | 21 | @Override 22 | public NavigationItem navigationItem() { 23 | return new NavigationItem("User Management", UserController.USER_MANAGEMENT_PATH); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/user/management/UserManagementComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.UserController.* 2 | @import de.tschuehly.easy.spring.auth.htmx.HtmxUtil 3 | 4 |
5 | Result loading... 6 |
7 | 8 | -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/CreateUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.create; 2 | 3 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 4 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 5 | 6 | @ViewComponent 7 | public class CreateUserComponent { 8 | 9 | public record CreateUserContext() implements ViewContext{} 10 | 11 | public ViewContext render(){ 12 | return new CreateUserContext(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/user/management/create/CreateUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import de.tschuehly.easy.spring.auth.user.UserController 2 |
3 |
4 | 8 | 12 | 15 |
16 |
-------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/EditUserComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.edit; 2 | 3 | import de.tschuehly.easy.spring.auth.user.EasyUser; 4 | import de.tschuehly.easy.spring.auth.user.UserService; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.UUID; 8 | 9 | @ViewComponent 10 | public class EditUserComponent { 11 | 12 | private final UserService userService; 13 | 14 | public EditUserComponent(UserService userService) { 15 | this.userService = userService; 16 | } 17 | 18 | public record EditUserContext(UUID uuid, String username, String password) implements ViewContext { 19 | 20 | } 21 | 22 | public ViewContext render(UUID uuid) { 23 | EasyUser user = userService.findById(uuid); 24 | return new EditUserContext(user.uuid, user.username, user.password); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/user/management/edit/EditUserComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.management.edit.EditUserComponent.* 2 | @import de.tschuehly.easy.spring.auth.user.UserController 3 | @import de.tschuehly.easy.spring.auth.user.management.edit.EditUserComponent 4 | @param EditUserComponent.EditUserContext editUserContext 5 | 6 |
7 |
8 | 12 | 16 | 20 | 23 |
24 |
-------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/infinite/InfiniteLoadComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.user.management.table.infinite; 2 | 3 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 4 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 5 | 6 | @ViewComponent 7 | public class InfiniteLoadComponent { 8 | 9 | public ViewContext render(int nextPage){ 10 | return new InfiniteLoadContext(nextPage); 11 | } 12 | 13 | public record InfiniteLoadContext(int nextPage) implements ViewContext { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/infinite/InfiniteLoadComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.user.UserController.* 2 | @import de.tschuehly.easy.spring.auth.htmx.HtmxUtil 3 | @import de.tschuehly.easy.spring.auth.user.management.table.infinite.InfiniteLoadComponent.InfiniteLoadContext 4 | @param InfiniteLoadContext infiniteLoadContext 5 | 7 | 8 | -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/user/management/table/row/UserRowComponent.jte: -------------------------------------------------------------------------------- 1 | @import static de.tschuehly.easy.spring.auth.htmx.HtmxUtil.URI 2 | @import static de.tschuehly.easy.spring.auth.user.UserController.* 3 | @import static de.tschuehly.easy.spring.auth.web.layout.LayoutComponent.MODAL_CONTAINER_ID 4 | @import de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent.UserRowContext 5 | @param de.tschuehly.easy.spring.auth.user.management.table.row.UserRowComponent.UserRowContext userRowContext 6 | 7 | !{var uuid = userRowContext.easyUser().uuid;} 8 | 9 | 10 | ${uuid.toString()} 11 | 12 | 13 | ${userRowContext.easyUser().username} 14 | 15 | 16 | ${userRowContext.easyUser().password} 17 | 18 | 19 | 23 | 24 | -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/web/Page.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web; 2 | 3 | public interface Page { 4 | record NavigationItem(String displayName, String URI){} 5 | 6 | NavigationItem navigationItem(); 7 | } 8 | -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/web/advice/ExceptionAdvice.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web.advice; 2 | 3 | import de.tschuehly.easy.spring.auth.htmx.HtmxUtil; 4 | import de.tschuehly.easy.spring.auth.web.exception.InfoException; 5 | import de.tschuehly.easy.spring.auth.web.layout.LayoutComponent; 6 | import de.tschuehly.easy.spring.auth.web.message.MessageComponent; 7 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 8 | import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxSwapType; 9 | import org.springframework.web.bind.annotation.ControllerAdvice; 10 | import org.springframework.web.bind.annotation.ExceptionHandler; 11 | 12 | @ControllerAdvice 13 | public class ExceptionAdvice { 14 | 15 | private final MessageComponent messageComponent; 16 | 17 | public ExceptionAdvice(MessageComponent messageComponent) { 18 | this.messageComponent = messageComponent; 19 | } 20 | 21 | @ExceptionHandler(InfoException.class) 22 | public ViewContext handle(InfoException e) { 23 | HtmxUtil.retarget(HtmxUtil.idSelector(LayoutComponent.TOAST_CONTAINER_ID)); 24 | HtmxUtil.swap(HxSwapType.INNER_HTML); 25 | return messageComponent.renderInfoToast(e.getMessage()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/web/exception/InfoException.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web.exception; 2 | 3 | public class InfoException extends RuntimeException{ 4 | 5 | public InfoException(String message) { 6 | super(message); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/web/layout/LayoutComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web.layout; 2 | 3 | import de.tschuehly.easy.spring.auth.web.Page; 4 | import de.tschuehly.easy.spring.auth.web.Page.NavigationItem; 5 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 6 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class LayoutComponent { 11 | 12 | public static final String MODAL_CONTAINER_ID = "modalContainer"; 13 | public static final String CLOSE_MODAL_EVENT = "close-modal"; 14 | public static final String TOAST_CONTAINER_ID = "toastContainer"; 15 | 16 | private final List pageList; 17 | 18 | public LayoutComponent(List pageList) { 19 | this.pageList = pageList; 20 | } 21 | 22 | public record LayoutContext(ViewContext content, List navigationItemList) implements ViewContext { 23 | 24 | } 25 | 26 | public ViewContext render(ViewContext content) { 27 | List navigationItemList = pageList.stream().map(Page::navigationItem).toList(); 28 | return new LayoutContext(content, navigationItemList); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/web/list/ListComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web.list; 2 | 3 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 4 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | @ViewComponent 10 | public class ListComponent { 11 | 12 | public ViewContext render(List viewContextList){ 13 | return new ListContext(viewContextList); 14 | } 15 | public ViewContext render(List viewContextList, ViewContext... viewContext){ 16 | ArrayList combinedList = new ArrayList<>(); 17 | combinedList.addAll(viewContextList); 18 | combinedList.addAll(List.of(viewContext)); 19 | return new ListContext(combinedList); 20 | } 21 | public ViewContext render( ViewContext... viewContext){ 22 | return new ListContext(Arrays.stream(viewContext).toList()); 23 | } 24 | 25 | public record ListContext(List viewContextList) implements ViewContext { 26 | 27 | } 28 | } -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/web/list/ListComponent.jte: -------------------------------------------------------------------------------- 1 | @param de.tschuehly.easy.spring.auth.web.list.ListComponent.ListContext listContext 2 | 3 | @for(var context: listContext.viewContextList()) 4 | ${context} 5 | @endfor -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/web/message/MessageComponent.java: -------------------------------------------------------------------------------- 1 | package de.tschuehly.easy.spring.auth.web.message; 2 | 3 | import de.tschuehly.spring.viewcomponent.core.component.ViewComponent; 4 | import de.tschuehly.spring.viewcomponent.jte.ViewContext; 5 | 6 | @ViewComponent 7 | public class MessageComponent { 8 | 9 | public ViewContext renderInfoToast(String message) { 10 | return new MessageContext(message, MessageType.INFO); 11 | } 12 | 13 | public ViewContext renderErrorToast(String message) { 14 | return new MessageContext(message, MessageType.TOAST_ERROR); 15 | } 16 | 17 | public record MessageContext(String message, MessageType type) implements 18 | ViewContext {} 19 | 20 | public enum MessageType { 21 | TOAST_ERROR, 22 | NONE, 23 | INFO; 24 | 25 | public String severity() { 26 | return switch (this) { 27 | case TOAST_ERROR -> "error"; 28 | case INFO -> "info"; 29 | default -> ""; 30 | }; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /lab-completed/src/main/java/de/tschuehly/easy/spring/auth/web/message/MessageComponent.jte: -------------------------------------------------------------------------------- 1 | @import de.tschuehly.easy.spring.auth.web.message.MessageComponent.MessageContext 2 | @import java.util.Date 3 | @param MessageContext messageContext 4 | 5 | !{var id = String.valueOf(new Date().getTime());} 6 | 14 | -------------------------------------------------------------------------------- /lab-completed/src/main/resources/application-dev.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | view-component: 3 | local-development: true 4 | view-component-root: lab-completed/src/main/java -------------------------------------------------------------------------------- /lab-completed/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: easy-spring-auth 4 | -------------------------------------------------------------------------------- /lab-completed/src/main/resources/static/edit.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lab-completed/src/main/resources/static/htmx_debug.js: -------------------------------------------------------------------------------- 1 | htmx.defineExtension('debug', { 2 | onEvent: function (name, evt) { 3 | if (console.debug) { 4 | console.debug(name, evt); 5 | } else if (console) { 6 | console.log("DEBUG:", name, evt); 7 | } else { 8 | throw "NO CONSOLE SUPPORTED" 9 | } 10 | } 11 | }); -------------------------------------------------------------------------------- /lab-completed/src/main/resources/static/plus.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /lab-completed/src/main/resources/static/spinner.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /lab-completed/system.properties: -------------------------------------------------------------------------------- 1 | java.runtime.version=21 -------------------------------------------------------------------------------- /server-side-htmx-workshop-devoxx.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tschuehly/htmx-spring-workshop/2bd924ffbd960c44dc6e52c97269e95df5e752e5/server-side-htmx-workshop-devoxx.pdf -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "easy-spring-auth" 2 | includeBuild("lab-1") 3 | includeBuild("lab-2") 4 | includeBuild("lab-3") 5 | includeBuild("lab-4") 6 | includeBuild("lab-5") 7 | includeBuild("lab-6") 8 | includeBuild("lab-7") 9 | includeBuild("lab-8") 10 | includeBuild("lab-9") 11 | includeBuild("lab-completed") --------------------------------------------------------------------------------