diff --git a/README.md b/README.md index caccdc73..616276c9 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,38 @@ # hsadminNg Development + + + +**Table of Contents** _generated with [DocToc](https://github.com/thlorenz/doctoc)_ + +- [Setting up the Development Environment](#setting-up-the-development-environment) +- [Frequent Tasks](#frequent-tasks) + - [Building the Application with Test Execution](#building-the-application-with-test-execution) + - [Starting the Application](#starting-the-application) + - [Running JUnit tests with branch coverage](#running-junit-tests-with-branch-coverage) +- [HOWTO Commits](#howto-commits) + - [Creating HOWTO Commits](#creating-howto-commits) +- [Special Build Tasks](#special-build-tasks) + - [Spotless Formatting](#spotless-formatting) + - [Mutation Testing PiTest](#mutation-testing-pitest) + - [Git Workflow for JHipster Generator](#git-workflow-for-jhipster-generator) + - [Generating the Table of Contents for Markdown](#generating-the-table-of-contents-for-markdown) + + + ## Setting up the Development Environment You'll often need to execute `./gradlew`, therefore we suggest to define this alias: alias gw='./gradlew' +TODO: Instructions for setting up the dev environment from scratch. + ## Frequent Tasks ### Building the Application with Test Execution -gw build + gw build ### Starting the Application @@ -31,45 +53,82 @@ see: https://confluence.jetbrains.com/display/IDEADEV/IDEA+Coverage+Runner Either apply it to specific test configurations or, better, delete the previous test configurations and amend the JUnit template. -## Git Workflow for JHipster Generator +## HOWTO Commits -The jhipster-generated git branch tracks the history of the JDL model file -and the generated source code. The project has to be resetted to a clean state -(without any generated entities) before changes to the JDL file can be imported. +There are git tags on some commits which show how to add certain features. -| WARNING: This is just a guideline. You should understand what you are doing! | -| ---------------------------------------------------------------------------- | +Find all of such tags with: + git tag | grep HOWTO - git checkout jhipster-generated - git pull - git tag REAL-HEAD - git reset --hard jdl-base - git clean -f -d - git cherry-pick -n spotless - git reset --soft REAL-HEAD - git checkout REAL-HEAD src/main/jdl/customer.jdl # AND OTHERS! - git tag -d REAL-HEAD +### Creating HOWTO Commits - # MANUAL STEP: Apply changes to the jdl file! +If you want to add such a commit, make sure that it contains no clutter +(no changes which are not necessary for whatever the commit is about to explain), +and is complete with all unit tests, code coverage, pitest and other checks. +Otherwise the next developer would run into the same problems again. - # (Re-) Importing - jhipster import-jdl src/main/jdl/customer.jdl - jhipster import-jdl src/main/jdl/accessrights.jdl - # AND OTHERS, if applicable! +One way to keep the commit clean, is to develop it on a local branch. +If any other changes (e.g. bugfixes, API extensions etc.) are necessary, +apply these only to the master or cherry-pick just these to the master, +then rebase your local branch. Do not forget to run all checks locally: + gw clean check pitest # might need over an hour + +(Check the PiTest section for speeding up mutation testing.) + +To create and push a new tag use: + + git tag HOWTO-... master + git push origin HOWTO-... + +After you've moved an existing the tag to another commit, you can use: + + git push --force origin HOWTO-... + +## Special Build Tasks + +Besides common build tasks like `build`, `test` or `bootRun` this projects has some not so common tasks which are explained in this section. + +### Spotless Formatting + +To make sure that no IDE auto-formatter destroys the git history of any file and +especially to avoid merge conflicts from JHipster generated files after these had been changed, +we are using a standard formatter enforced by _spotless_, which is based on the standard Eclipse formatter. + +The rules can be checked and applied with these commands: + + gw spotlessCheck gw spotlessApply - git add . - git commit -m"..." - # MANUAL STEP: - # - if you've renamed any identifiers, use refactoring to rename in master as well BEFORE MERGING! +The spotlessCheck task is included as an early step in our Jenkins build pipeline. +Therefore wrong formatting is automatically detected. - # Merge changeset into master branch - git checkout master - git merge jhipster-generated +Our configuration can be found under the directory `cfg/spotless`. +Currently we only have specific rules for _\*.java_-files and their import-order. -### Amending the spotless commit +#### Our Changes to the Standard Eclipse Formatter + +We amended the Standard Eclipse Formatter in these respects: + +- Lines of code are never joined, thus the developer has control about linebreaks, + which is important for readability in some implementations like toString(). +- Lines in comments are never joined either, because that often destroys readable stucture. +- Parts of files can be excluded from getting formatted, by using `@formatter:off` and `@formatter:on` in a comment. + See for example in class `SecurityConfiguration`. + +#### Pre-Commit Hook + +If you like, you could add this code to the _pre-commit or \_pre_push_ hook\_ in your `.git/hooks` directory: + + if ! ./gradlew spotlessCheck; then + exit 1 + fi + +#### The Tagged Spotless Commit + +The commit which introduces the spotless configuration is tagged. +Through this tag it can easily be cherry-picked in the JHipster workflow. If you need to amend the commit tagged 'spotless', e.g. to change the spotless configuration, it can be done with these steps: @@ -87,43 +146,6 @@ it can be done with these steps: git reset --hard REAL-HEAD git tag -d REAL-HEAD -## HOWTO do This and That - -There are git tags on some commits which show how to add certian features. - -Find all of such tags with: - - git tag | grep HOWTO - -### creating HOWTO commits - -If you want to add such a commit, make sure that it contains no clutter -(no changes which are not necessary for whatever the commit is about to explain), -and is complete with all unit tests, code coverage, pitest and other checks. -Otherwise the next developer would run into the same problems again. - -One way to keep the commit clean, is to develop it on a local branch. -If any other changes (e.g. bugfixes, API extensions etc.) are necessary, -apply these only to the master or cherry-pick just these to the master, -then rebase your local branch. Do not forget to run all checks locally: - - gw clean check pitest # might need over an hour - -(Check the pitest section for speeding up pitest.) - -To create and push a new tag use: - - git tag HOWTO-... master - git push origin HOWTO-... - -After you've moved an existing the tag to another commit, you can use: - - git push origin HOWTO-... --force - -## Special Build Tasks - -Besides common build tasks like `build`, `test` or `bootRun` this projects has some not so common tasks which are explained in this section. - ### Mutation Testing PiTest ./gradlew pitest @@ -168,3 +190,97 @@ If you want to spend more CPU threads on your local system, you can change that gw pitest -Doverride.pitest.threads=7 I suggest to leave one CPU thread for other tasks or your might lag extremely. + +### Git Workflow for JHipster Generator + +The following workflow steps make sure that + +- JHipster re-imports work properly, +- the git history of changes to the JDL-files, the generated code and the master is comprehensible, +- and merging newly generated code to the master branch is smooth. + +It uses a git branch `jhipster-generated` to track the history of the JDL model file and the generated source code. +Applying commits which contain non-generated changes to that branch breaks the normal git history for generated files. +Therefore, this documentation is also not available in that branch. +Thus: + +**MANUAL STEP before starting:** Copy this workflow documentation, because this file will be gone once you switched the branch. + +| WARNING: The following steps are just a guideline. You should understand what you are doing! | +| -------------------------------------------------------------------------------------------- | + + +#### 1. Preparing the `jhipster-generated` git Branch + +This step assumes that the latest `*.jdl` files are on the `HEAD` of the `jhipster-generated` git branch. +On a re-import of a JDL-file, JHipster does not remove any generated classes which belong to entities deleted from the JDL-file. +Therefore, the project has to be reset to a clean state before changes to the JDL file can be re-imported. +We have not yet finally tested a simplified workflow for just adding new entities or properties. + +A git tag `jdl-base` is assumed to sit on the base commit after the application was generated, but before any entities were imported. + + git checkout jhipster-generated + git pull + git tag REAL-HEAD + git reset --hard jdl-base + git clean -f -d + git cherry-pick -n spotless + git reset --soft REAL-HEAD + git checkout REAL-HEAD src/main/jdl/customer.jdl # AND OTHERS! + git tag -d REAL-HEAD + +#### 2. Amending and Re-Importing the JDL + +**MANUAL STEP:** First apply all necessary changes to the JDL files. +Then re-import like this: + + # (Re-) Importing + jhipster import-jdl src/main/jdl/customer.jdl + jhipster import-jdl src/main/jdl/accessrights.jdl + jhipster import-jdl src/main/jdl/... # once there are more + +For smoothly being able to merge, we need the same formatting in the generated code as on the master: + + gw spotlessApply + +#### 3. Committing our Changes + + git add . + git commit -m"..." + +#### 4. Merging our Changes to the `master` Branch + + git checkout master + git pull + +**MANUAL STEP:** If you've renamed any identifiers, use the refactoring feature of your IDE to rename in master as well. +To avoid oodles of merge-conflicts, you need to do that **BEFORE MERGING!** +Commit any of such changes, if any. + +Now we can finally merge our changes to master. + + git merge jhipster-generated + +It's a good idea doing this step in an IDE because it makes conflict resolving much easier. +Typical merge conflicts stem from: + +- Random numbers in test data of `*IntTest.java` files. +- Timestamps in Liquibase-xml-Files. + +Now, I suggest to run all tests locally: + + gw clean test + +Once everything works again, we can push our new version: + + git push + +### Generating the Table of Contents for Markdown + +This README file contains a table of contents generated by _doctoc_. +It's quite simple to use: + +npm install -g doctoc +doctoc --maxlevel 3 README.md + +Further information can be found [https://github.com/thlorenz/doctoc/blob/master/README.md](on the _doctoc_ github page). diff --git a/src/main/resources/config/liquibase/changelog/sample-data-Customer.xml b/src/main/resources/config/liquibase/changelog/sample-data-Customer.xml deleted file mode 100644 index c89e5ada..00000000 --- a/src/main/resources/config/liquibase/changelog/sample-data-Customer.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - UPDATE customer SET contractual_address = REPLACE(contractual_address, '|', STRINGDECODE('\n')); - - - - DELETE FROM customer; - - - - diff --git a/src/main/resources/config/liquibase/changelog/sample-data-Membership.xml b/src/main/resources/config/liquibase/changelog/sample-data-Membership.xml deleted file mode 100644 index 72cbe9de..00000000 --- a/src/main/resources/config/liquibase/changelog/sample-data-Membership.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/main/resources/config/liquibase/master.xml b/src/main/resources/config/liquibase/master.xml index b545c090..36848208 100644 --- a/src/main/resources/config/liquibase/master.xml +++ b/src/main/resources/config/liquibase/master.xml @@ -21,5 +21,9 @@ + + + + diff --git a/src/main/resources/config/liquibase/sample-data/assets.csv b/src/main/resources/config/liquibase/sample-data/assets.csv new file mode 100644 index 00000000..ac9d9efd --- /dev/null +++ b/src/main/resources/config/liquibase/sample-data/assets.csv @@ -0,0 +1,58 @@ +id;membership_id;document_date;value_date;action;amount;remark +210001;1;2001-05-10;2001-05-11;PAYMENT;64;some|multiline|1. instalment|just to produce some more rows for tests :-) +210002;1;2001-05-10;2001-05-12;PAYMENT;64;some|multiline|2. instalment +210003;1;2001-05-10;2001-05-13;PAYMENT;64;some|multiline|3. instalment +210004;1;2001-05-10;2001-05-14;PAYMENT;64;some|multiline|4. instalment +210005;1;2001-05-10;2001-05-15;PAYMENT;64;some|multiline|5. instalment +210006;1;2001-05-10;2001-05-16;PAYMENT;64;some|multiline|6. instalment +210007;1;2001-05-10;2001-05-17;PAYMENT;64;some|multiline|7. instalment +210008;1;2001-05-10;2001-05-18;PAYMENT;64;some|multiline|8. instalment +210009;1;2001-05-10;2001-05-19;PAYMENT;64;some|multiline|9. instalment +210010;1;2001-05-10;2001-05-20;PAYMENT;64;some|multiline|10. instalment +210011;1;2001-05-10;2001-05-21;PAYMENT;64;some|multiline|11. instalment +210012;1;2001-05-10;2001-05-22;PAYMENT;64;some|multiline|12. instalment +210013;1;2001-05-10;2001-05-23;PAYMENT;64;some|multiline|13. instalment +210014;1;2001-05-10;2001-05-24;PAYMENT;64;some|multiline|14. instalment +210015;1;2001-05-10;2001-05-25;PAYMENT;64;some|multiline|15. instalment +210016;1;2001-05-10;2001-05-26;PAYMENT;64;some|multiline|16. instalment +210017;1;2007-09-09;2008-07-10;PAYBACK;512;1. instalment +210018;1;2007-09-09;2009-07-10;PAYBACK;512;2. instalment +210019;2;2017-02-15;2017-02-15;PAYMENT;512;became a member again +210020;2;2017-02-15;2017-02-15;PAYMENT;64;just writing something +210021;3;2003-06-11;2003-06-11;PAYMENT;256;some comment +210022;3;2003-06-15;2004-07-03;PAYBACK;256;cancelled membership +210023;4;2017-06-15;2017-05-17;PAYMENT;1024; +210024;5;2011-09-18;2011-09-01;PAYMENT;640; +210101;5;2013-01-15;2013-01-01;PAYMENT;64;signed more shares|1. installment +210102;5;2013-01-15;2013-01-02;PAYMENT;64;signed more shares|2. installment +210103;5;2013-01-15;2013-01-03;PAYMENT;64;signed more shares|3. installment +210104;5;2013-01-15;2013-01-04;PAYMENT;64;signed more shares|4. installment +210105;5;2013-01-15;2013-01-05;PAYMENT;64;signed more shares|5. installment +210106;5;2013-01-15;2013-01-06;PAYMENT;64;signed more shares|6. installment +210107;5;2013-01-15;2013-01-07;PAYMENT;64;signed more shares|7. installment +210108;5;2013-01-15;2013-01-08;PAYMENT;64;signed more shares|8. installment +210109;5;2013-01-15;2013-01-09;PAYMENT;64;signed more shares|9. installment +210110;5;2013-01-15;2013-01-10;PAYMENT;64;signed more shares|10. installment +210111;5;2013-01-15;2013-01-11;PAYMENT;64;signed more shares|11. installment +210112;5;2013-01-15;2013-01-12;PAYMENT;64;signed more shares|12. installment +210123;5;2013-01-15;2013-01-13;PAYMENT;64;signed more shares|13. installment +210124;5;2013-01-15;2013-01-14;PAYMENT;64;signed more shares|14. installment +210125;5;2013-01-15;2013-01-15;PAYMENT;64;signed more shares|15. installment +210126;5;2013-01-15;2013-01-16;PAYMENT;64;signed more shares|16. installment +210127;5;2013-01-15;2013-01-17;PAYMENT;64;signed more shares|17. installment +210128;5;2013-01-15;2013-01-18;PAYMENT;64;signed more shares|18. installment +210129;5;2013-01-15;2013-01-19;PAYMENT;64;signed more shares|19. installment +210130;5;2013-01-15;2013-01-20;PAYMENT;64;signed more shares|20. installment +210230;5;2017-12-22;2018-07-01;PAYBACK;160;cancelled most of their shares|1. installment|just to produce more rows for tests :-) +210231;5;2017-12-22;2018-07-02;PAYBACK;160;cancelled most of their shares|2. installment|just to produce more rows for tests :-) +210232;5;2017-12-22;2018-08-03;PAYBACK;160;cancelled most of their shares|3. installment|just to produce more rows for tests :-) +210233;5;2017-12-22;2018-09-04;PAYBACK;160;cancelled most of their shares|4. installment|just to produce more rows for tests :-) +210234;5;2017-12-22;2018-10-05;PAYBACK;160;cancelled most of their shares|5. installment|just to produce more rows for tests :-) +210235;5;2017-12-22;2018-11-06;PAYBACK;160;cancelled most of their shares|6. installment|just to produce more rows for tests :-) +210236;5;2017-12-22;2018-12-07;PAYBACK;160;cancelled most of their shares|7. installment|just to produce more rows for tests :-) +210237;5;2017-12-22;2019-01-08;PAYBACK;160;cancelled most of their shares|8. installment|just to produce more rows for tests :-) +210238;5;2017-12-22;2019-02-09;PAYBACK;160;cancelled most of their shares|9. installment|just to produce more rows for tests :-) +210239;5;2017-12-22;2019-03-10;PAYBACK;160;cancelled most of their shares|10. installment|just to produce more rows for tests :-) + + + diff --git a/src/main/resources/config/liquibase/sample-data/assets.xml b/src/main/resources/config/liquibase/sample-data/assets.xml new file mode 100644 index 00000000..10d5828f --- /dev/null +++ b/src/main/resources/config/liquibase/sample-data/assets.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + UPDATE asset SET remark = replace(remark, '|', STRINGDECODE('\n')) + + + + DELETE FROM asset; + + + + diff --git a/src/main/resources/config/liquibase/sample-data/customers.xml b/src/main/resources/config/liquibase/sample-data/customers.xml index 730e9471..eb145b0d 100644 --- a/src/main/resources/config/liquibase/sample-data/customers.xml +++ b/src/main/resources/config/liquibase/sample-data/customers.xml @@ -19,7 +19,13 @@ - UPDATE customer SET contractual_address = replace(contractual_address, '|', '\n') + + UPDATE customer SET contractual_address = replace(contractual_address, '|', STRINGDECODE('\n')) + + + + DELETE FROM customer; + diff --git a/src/main/resources/config/liquibase/sample-data/memberships.csv b/src/main/resources/config/liquibase/sample-data/memberships.csv index 0408664f..14e43200 100644 --- a/src/main/resources/config/liquibase/sample-data/memberships.csv +++ b/src/main/resources/config/liquibase/sample-data/memberships.csv @@ -1,6 +1,7 @@ -id;customer_id;jhi_from;jhi_to -1;1;2001-04-10;2007-12-31 -2;1;2017-01-15;null -3;3;2003-05-15;2019-12-31 -4;4;2017-05-15;null -5;5;2011-08-18;null +id;customer_id;admission_document_date;cancellation_document_date;member_from_date;member_until_date;remark +1;1;2001-04-10;2007-08-09;2001-04-11;2007-12-31;is now client of another member|see XYZ +2;1;2017-01-15;null;2017-01-15;null;nothing to say here +3;3;2003-05-11;2018-11-30;2003-05-15;2018-12-31;business discontinued +4;4;2017-05-15;null;2017-05-15;null;whatever|is|to|say +5;5;2011-08-18;null;2011-08-18;null;foo bar etc. + diff --git a/src/main/resources/config/liquibase/sample-data/memberships.xml b/src/main/resources/config/liquibase/sample-data/memberships.xml new file mode 100644 index 00000000..97498a8f --- /dev/null +++ b/src/main/resources/config/liquibase/sample-data/memberships.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + UPDATE membership SET remark = replace(remark, '|', STRINGDECODE('\n')) + + + + DELETE FROM membership; + + + + diff --git a/src/main/resources/config/liquibase/sample-data/sepamandates.csv b/src/main/resources/config/liquibase/sample-data/sepamandates.csv new file mode 100644 index 00000000..2698cc95 --- /dev/null +++ b/src/main/resources/config/liquibase/sample-data/sepamandates.csv @@ -0,0 +1,6 @@ +id;customer_id;reference;iban;bic;granting_document_date;revokation_document_date;valid_from_date;valid_until_date;last_used_date;remark +1;1;DKXIDEHAC01;DE94500105172859877827;REF02039402;2018-01-15;null;2018-01-16;null;2019-04-09;a remark|over two lines +2;2;JKUIDEBIS00;DE56500105172321139153;REF2834823W;2017-06-03;2019-01-15;2017-06-04;2019-01-31;2019-01-10;for the old bank account +3;2;JUZTDEVER03;DE56500105172321139153;REF2834823W;2019-01-15;null;2019-02-01;null;2019-04-09;for the new bank account +4;3;CKIZDESiX98;DE24500105175933769123;REF23984928;2016-09-13;2018-11-20;2016-09-13;2018-12-31;2018-12-09;membership cancelled +5;5;ZUIJDEVOR12;DE92500105174781793571;REF23882384;2016-12-03;null;2016-12-03;null;2019-04-09;null diff --git a/src/main/resources/config/liquibase/sample-data/sepamandates.xml b/src/main/resources/config/liquibase/sample-data/sepamandates.xml new file mode 100644 index 00000000..1e75c9ea --- /dev/null +++ b/src/main/resources/config/liquibase/sample-data/sepamandates.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + UPDATE sepa_mandate SET remark = replace(remark, '|', STRINGDECODE('\n')) + + + + DELETE FROM sepa_mandate; + + + + diff --git a/src/main/resources/config/liquibase/sample-data/shares.csv b/src/main/resources/config/liquibase/sample-data/shares.csv new file mode 100644 index 00000000..b3cbe4e4 --- /dev/null +++ b/src/main/resources/config/liquibase/sample-data/shares.csv @@ -0,0 +1,13 @@ +id;membership_id;document_date;value_date;action;quantity;remark +1;1;2001-04-10;2001-04-11;SUBSCRIPTION;16;some|multiline|remark +2;1;2007-08-09;2007-12-31;CANCELLATION;16;another remark +3;2;2017-01-15;2017-01-17;SUBSCRIPTION;8;became a member again +4;2;2017-01-15;2017-01-17;SUBSCRIPTION;1;just writing something +5;3;2003-05-11;2003-05-18;SUBSCRIPTION;4;some comment +6;3;2003-05-15;2003-05-30;CANCELLATION;4;cancelled membership +7;4;2017-05-15;2017-05-17;SUBSCRIPTION;16; +8;5;2011-08-18;2011-09-01;SUBSCRIPTION;10; +9;5;2012-12-15;2013-01-01;SUBSCRIPTION;20;signed more shares +10;5;2017-11-22;2018-01-01;CANCELLATION;25;cancelled most of their shares + + diff --git a/src/main/resources/config/liquibase/sample-data/shares.xml b/src/main/resources/config/liquibase/sample-data/shares.xml new file mode 100644 index 00000000..f8fa136f --- /dev/null +++ b/src/main/resources/config/liquibase/sample-data/shares.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + UPDATE share SET remark = replace(remark, '|', STRINGDECODE('\n')) + + + + DELETE FROM share; + + + + diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index 2d182c88..e82256df 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -45,6 +45,10 @@ + diff --git a/src/main/webapp/app/entities/asset/asset-detail.component.html b/src/main/webapp/app/entities/asset/asset-detail.component.html index d092b737..f3dd73ed 100644 --- a/src/main/webapp/app/entities/asset/asset-detail.component.html +++ b/src/main/webapp/app/entities/asset/asset-detail.component.html @@ -7,11 +7,11 @@
Document Date
- {{asset.documentDate}} + {{asset.documentDate | date:'mediumDate'}}
Value Date
- {{asset.valueDate}} + {{asset.valueDate | date:'mediumDate'}}
Action
@@ -23,7 +23,7 @@
Remark
- {{asset.remark}} +
Membership
diff --git a/src/main/webapp/app/entities/asset/asset-update.component.html b/src/main/webapp/app/entities/asset/asset-update.component.html index 951db0b4..d9d36906 100644 --- a/src/main/webapp/app/entities/asset/asset-update.component.html +++ b/src/main/webapp/app/entities/asset/asset-update.component.html @@ -75,8 +75,8 @@
- +
diff --git a/src/main/webapp/app/entities/asset/asset.component.html b/src/main/webapp/app/entities/asset/asset.component.html index 8472107d..2545bb6f 100644 --- a/src/main/webapp/app/entities/asset/asset.component.html +++ b/src/main/webapp/app/entities/asset/asset.component.html @@ -14,14 +14,42 @@ - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/app/entities/asset/asset.component.ts b/src/main/webapp/app/entities/asset/asset.component.ts index 4a5c8445..19220504 100644 --- a/src/main/webapp/app/entities/asset/asset.component.ts +++ b/src/main/webapp/app/entities/asset/asset.component.ts @@ -9,6 +9,9 @@ import { AccountService } from 'app/core'; import { ITEMS_PER_PAGE } from 'app/shared'; import { AssetService } from './asset.service'; +import { IMembership } from 'app/shared/model/membership.model'; +import { MembershipService } from 'app/entities/membership'; +import { queryEquals, queryYearAsDateRange, TableFilter } from 'app/shared/util/tablefilter'; @Component({ selector: 'jhi-asset', @@ -24,9 +27,18 @@ export class AssetComponent implements OnInit, OnDestroy { predicate: any; reverse: any; totalItems: number; + memberships: IMembership[]; + filter: TableFilter<{ + documentDate?: string; + valueDate?: string; + action?: string; + amount?: string; + membershipId?: string; + }>; constructor( protected assetService: AssetService, + protected membershipService: MembershipService, protected jhiAlertService: JhiAlertService, protected eventManager: JhiEventManager, protected parseLinks: JhiParseLinks, @@ -40,11 +52,25 @@ export class AssetComponent implements OnInit, OnDestroy { }; this.predicate = 'id'; this.reverse = true; + this.filter = new TableFilter( + { + documentDate: queryYearAsDateRange, + valueDate: queryYearAsDateRange, + action: queryEquals, + amount: queryEquals, + membershipId: queryEquals + }, + 500, + () => { + this.reset(); + } + ); } loadAll() { this.assetService .query({ + ...this.filter.buildQueryCriteria(), page: this.page, size: this.itemsPerPage, sort: this.sort() @@ -71,6 +97,13 @@ export class AssetComponent implements OnInit, OnDestroy { this.accountService.identity().then(account => { this.currentAccount = account; }); + this.membershipService + .query() + .pipe( + filter((mayBeOk: HttpResponse) => mayBeOk.ok), + map((response: HttpResponse) => response.body) + ) + .subscribe((res: IMembership[]) => (this.memberships = res), (res: HttpErrorResponse) => this.onError(res.message)); this.registerChangeInAssets(); } @@ -78,7 +111,7 @@ export class AssetComponent implements OnInit, OnDestroy { this.eventManager.destroy(this.eventSubscriber); } - trackId(index: number, item: IAsset) { + trackId(index: number, item: { id: number }) { return item.id; } diff --git a/src/main/webapp/app/entities/customer/customer-detail.component.html b/src/main/webapp/app/entities/customer/customer-detail.component.html index 3a74ce9e..5e479fbb 100644 --- a/src/main/webapp/app/entities/customer/customer-detail.component.html +++ b/src/main/webapp/app/entities/customer/customer-detail.component.html @@ -51,7 +51,7 @@
Contractual Address
- {{customer.contractualAddress}} +
Billing Salutation
@@ -59,11 +59,11 @@
Billing Address
- {{customer.billingAddress}} +
Remark
- {{customer.remark}} +
diff --git a/src/main/webapp/app/entities/customer/customer-update.component.html b/src/main/webapp/app/entities/customer/customer-update.component.html index 0a498111..c59b92ac 100644 --- a/src/main/webapp/app/entities/customer/customer-update.component.html +++ b/src/main/webapp/app/entities/customer/customer-update.component.html @@ -159,9 +159,10 @@
- - + +
@@ -186,8 +187,8 @@
- +
@@ -197,8 +198,8 @@
- +
diff --git a/src/main/webapp/app/entities/customer/customer.component.html b/src/main/webapp/app/entities/customer/customer.component.html index c655cc04..f3183904 100644 --- a/src/main/webapp/app/entities/customer/customer.component.html +++ b/src/main/webapp/app/entities/customer/customer.component.html @@ -14,12 +14,26 @@
ID Document Date Value Date Action Amount Membership ID Document Date Value Date Action Amount Membership
+ + + +
- - - - - - + + + + + + + + + + + + + + diff --git a/src/main/webapp/app/entities/customer/customer.component.ts b/src/main/webapp/app/entities/customer/customer.component.ts index 3f95501d..94aa2e18 100644 --- a/src/main/webapp/app/entities/customer/customer.component.ts +++ b/src/main/webapp/app/entities/customer/customer.component.ts @@ -8,6 +8,7 @@ import { AccountService } from 'app/core'; import { ITEMS_PER_PAGE } from 'app/shared'; import { CustomerService } from './customer.service'; +import { TableFilter } from 'app/shared/util/tablefilter'; @Component({ selector: 'jhi-customer', @@ -23,6 +24,7 @@ export class CustomerComponent implements OnInit, OnDestroy { predicate: any; reverse: any; totalItems: number; + filter: TableFilter<{ reference?: string; prefix?: string; name?: string; kind?: string }>; constructor( protected customerService: CustomerService, @@ -39,11 +41,24 @@ export class CustomerComponent implements OnInit, OnDestroy { }; this.predicate = 'id'; this.reverse = true; + this.filter = new TableFilter( + { + reference: 'reference.equals', + prefix: 'prefix.contains', + name: 'name.contains', + kind: 'kind.equals' + }, + 500, + () => { + this.reset(); + } + ); } loadAll() { this.customerService .query({ + ...this.filter.buildQueryCriteria(), page: this.page, size: this.itemsPerPage, sort: this.sort() diff --git a/src/main/webapp/app/entities/membership/membership-detail.component.html b/src/main/webapp/app/entities/membership/membership-detail.component.html index 77601e66..dae64d50 100644 --- a/src/main/webapp/app/entities/membership/membership-detail.component.html +++ b/src/main/webapp/app/entities/membership/membership-detail.component.html @@ -7,23 +7,23 @@
Admission Document Date
- {{membership.admissionDocumentDate}} + {{membership.admissionDocumentDate | date:'mediumDate'}}
Cancellation Document Date
- {{membership.cancellationDocumentDate}} + {{membership.cancellationDocumentDate | date:'mediumDate'}}
Member From Date
- {{membership.memberFromDate}} + {{membership.memberFromDate | date:'mediumDate'}}
Member Until Date
- {{membership.memberUntilDate}} + {{membership.memberUntilDate | date:'mediumDate'}}
Remark
- {{membership.remark}} +
Customer
diff --git a/src/main/webapp/app/entities/membership/membership-update.component.html b/src/main/webapp/app/entities/membership/membership-update.component.html index 8a04c9e2..758ce53a 100644 --- a/src/main/webapp/app/entities/membership/membership-update.component.html +++ b/src/main/webapp/app/entities/membership/membership-update.component.html @@ -63,8 +63,8 @@
- +
diff --git a/src/main/webapp/app/entities/membership/membership.component.html b/src/main/webapp/app/entities/membership/membership.component.html index 8f141466..920fcc61 100644 --- a/src/main/webapp/app/entities/membership/membership.component.html +++ b/src/main/webapp/app/entities/membership/membership.component.html @@ -14,20 +14,38 @@
ID Reference Prefix Name Kind ID Reference Prefix Name Kind
+ +
- - - - - - + + + + + + + + + + + + + + + + + + + - +
ID Admission Document Date Cancellation Document Date Member From Date Member Until Date Customer ID Admission Document Date Cancellation Document Date Member From Date Member Until Date Customer
+ +
{{membership.id}} {{membership.admissionDocumentDate | date:'mediumDate'}}{{membership.cancellationDocumentDate | date:'mediumDsate'}}{{membership.cancellationDocumentDate | date:'mediumDate'}} {{membership.memberFromDate | date:'mediumDate'}} {{membership.memberUntilDate | date:'mediumDate'}} diff --git a/src/main/webapp/app/entities/membership/membership.component.ts b/src/main/webapp/app/entities/membership/membership.component.ts index 387df20d..5ca7c86a 100644 --- a/src/main/webapp/app/entities/membership/membership.component.ts +++ b/src/main/webapp/app/entities/membership/membership.component.ts @@ -9,6 +9,9 @@ import { AccountService } from 'app/core'; import { ITEMS_PER_PAGE } from 'app/shared'; import { MembershipService } from './membership.service'; +import { ICustomer } from 'app/shared/model/customer.model'; +import { CustomerService } from 'app/entities/customer'; +import { TableFilter, queryYearAsDateRange, queryEquals } from 'app/shared/util/tablefilter'; @Component({ selector: 'jhi-membership', @@ -24,9 +27,18 @@ export class MembershipComponent implements OnInit, OnDestroy { predicate: any; reverse: any; totalItems: number; + customers: ICustomer[]; + filter: TableFilter<{ + admissionDocumentDate?: string; + cancellationDocumentDate?: string; + memberFromDate?: string; + memberUntilDate?: string; + customerId?: string; + }>; constructor( protected membershipService: MembershipService, + protected customerService: CustomerService, protected jhiAlertService: JhiAlertService, protected eventManager: JhiEventManager, protected parseLinks: JhiParseLinks, @@ -40,11 +52,25 @@ export class MembershipComponent implements OnInit, OnDestroy { }; this.predicate = 'id'; this.reverse = true; + this.filter = new TableFilter( + { + admissionDocumentDate: queryYearAsDateRange, + cancellationDocumentDate: queryYearAsDateRange, + memberFromDate: queryYearAsDateRange, + memberUntilDate: queryYearAsDateRange, + customerId: queryEquals + }, + 500, + () => { + this.reset(); + } + ); } loadAll() { this.membershipService .query({ + ...this.filter.buildQueryCriteria(), page: this.page, size: this.itemsPerPage, sort: this.sort() @@ -72,13 +98,20 @@ export class MembershipComponent implements OnInit, OnDestroy { this.currentAccount = account; }); this.registerChangeInMemberships(); + this.customerService + .query() + .pipe( + filter((mayBeOk: HttpResponse) => mayBeOk.ok), + map((response: HttpResponse) => response.body) + ) + .subscribe((res: IMembership[]) => (this.customers = res), (res: HttpErrorResponse) => this.onError(res.message)); } ngOnDestroy() { this.eventManager.destroy(this.eventSubscriber); } - trackId(index: number, item: IMembership) { + trackId(index: number, item: { id: number }) { return item.id; } @@ -97,6 +130,7 @@ export class MembershipComponent implements OnInit, OnDestroy { protected paginateMemberships(data: IMembership[], headers: HttpHeaders) { this.links = this.parseLinks.parse(headers.get('link')); this.totalItems = parseInt(headers.get('X-Total-Count'), 10); + this.memberships = []; for (let i = 0; i < data.length; i++) { this.memberships.push(data[i]); } diff --git a/src/main/webapp/app/entities/sepa-mandate/sepa-mandate-detail.component.html b/src/main/webapp/app/entities/sepa-mandate/sepa-mandate-detail.component.html index 31330485..b12e9d33 100644 --- a/src/main/webapp/app/entities/sepa-mandate/sepa-mandate-detail.component.html +++ b/src/main/webapp/app/entities/sepa-mandate/sepa-mandate-detail.component.html @@ -19,28 +19,27 @@
Granting Document Date
- {{sepaMandate.grantingDocumentDate}} + {{sepaMandate.grantingDocumentDate | date:'mediumDate'}}
Revokation Document Date
- {{sepaMandate.revokationDocumentDate}} + {{sepaMandate.revokationDocumentDate | date:'mediumDate'}}
Valid From Date
- {{sepaMandate.validFromDate}} + {{sepaMandate.validFromDate | date:'mediumDate'}}
Valid Until Date
- {{sepaMandate.validUntilDate}} + {{sepaMandate.validUntilDate | date:'mediumDate'}}
Last Used Date
- {{sepaMandate.lastUsedDate}} -
+ {{sepaMandate.lastUsedDate | date:'mediumDate'}}
Remark
- {{sepaMandate.remark}} +
Customer
diff --git a/src/main/webapp/app/entities/sepa-mandate/sepa-mandate-update.component.html b/src/main/webapp/app/entities/sepa-mandate/sepa-mandate-update.component.html index 10a4d11e..50826fd8 100644 --- a/src/main/webapp/app/entities/sepa-mandate/sepa-mandate-update.component.html +++ b/src/main/webapp/app/entities/sepa-mandate/sepa-mandate-update.component.html @@ -110,8 +110,8 @@
- +
diff --git a/src/main/webapp/app/entities/sepa-mandate/sepa-mandate.component.html b/src/main/webapp/app/entities/sepa-mandate/sepa-mandate.component.html index a6c693d3..cc9c010f 100644 --- a/src/main/webapp/app/entities/sepa-mandate/sepa-mandate.component.html +++ b/src/main/webapp/app/entities/sepa-mandate/sepa-mandate.component.html @@ -14,19 +14,40 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -39,7 +60,6 @@ -
ID Reference Iban Bic Granting Document Date Revokation Document Date Valid From Date Valid Until Date Last Used Date Remark Customer ID Reference Iban Bic Granting Document Date Revokation Document Date Valid From Date Valid Until Date Last Used Date Customer
+ +
{{sepaMandate.validFromDate | date:'mediumDate'}} {{sepaMandate.validUntilDate | date:'mediumDate'}} {{sepaMandate.lastUsedDate | date:'mediumDate'}}{{sepaMandate.remark}}
{{sepaMandate.customerDisplayLabel}} diff --git a/src/main/webapp/app/entities/sepa-mandate/sepa-mandate.component.ts b/src/main/webapp/app/entities/sepa-mandate/sepa-mandate.component.ts index d7ef209a..d78686dd 100644 --- a/src/main/webapp/app/entities/sepa-mandate/sepa-mandate.component.ts +++ b/src/main/webapp/app/entities/sepa-mandate/sepa-mandate.component.ts @@ -9,6 +9,10 @@ import { AccountService } from 'app/core'; import { ITEMS_PER_PAGE } from 'app/shared'; import { SepaMandateService } from './sepa-mandate.service'; +import { ICustomer } from 'app/shared/model/customer.model'; +import { CustomerService } from 'app/entities/customer'; +import { TableFilter, queryYearAsDateRange, queryEquals, queryContains } from 'app/shared/util/tablefilter'; +import { IMembership } from 'app/shared/model/membership.model'; @Component({ selector: 'jhi-sepa-mandate', @@ -24,9 +28,22 @@ export class SepaMandateComponent implements OnInit, OnDestroy { predicate: any; reverse: any; totalItems: number; + customers: ICustomer[]; + filter: TableFilter<{ + reference?: string; + iban?: string; + bic?: string; + grantingDocumentDate?: string; + revokationDocumentDate?: string; + validFromDate?: string; + validUntilDate?: string; + lastUsedDate?: string; + customerId?: string; + }>; constructor( protected sepaMandateService: SepaMandateService, + protected customerService: CustomerService, protected jhiAlertService: JhiAlertService, protected eventManager: JhiEventManager, protected parseLinks: JhiParseLinks, @@ -40,11 +57,29 @@ export class SepaMandateComponent implements OnInit, OnDestroy { }; this.predicate = 'id'; this.reverse = true; + this.filter = new TableFilter( + { + reference: queryContains, + iban: queryContains, + bic: queryContains, + grantingDocumentDate: queryYearAsDateRange, + revokationDocumentDate: queryYearAsDateRange, + validFromDate: queryYearAsDateRange, + validUntilDate: queryYearAsDateRange, + lastUsedDate: queryYearAsDateRange, + customerId: queryEquals + }, + 500, + () => { + this.reset(); + } + ); } loadAll() { this.sepaMandateService .query({ + ...this.filter.buildQueryCriteria(), page: this.page, size: this.itemsPerPage, sort: this.sort() @@ -72,13 +107,20 @@ export class SepaMandateComponent implements OnInit, OnDestroy { this.currentAccount = account; }); this.registerChangeInSepaMandates(); + this.customerService + .query() + .pipe( + filter((mayBeOk: HttpResponse) => mayBeOk.ok), + map((response: HttpResponse) => response.body) + ) + .subscribe((res: IMembership[]) => (this.customers = res), (res: HttpErrorResponse) => this.onError(res.message)); } ngOnDestroy() { this.eventManager.destroy(this.eventSubscriber); } - trackId(index: number, item: ISepaMandate) { + trackId(index: number, item: { id: number }) { return item.id; } diff --git a/src/main/webapp/app/entities/share/share-detail.component.html b/src/main/webapp/app/entities/share/share-detail.component.html index bb1dfd9f..5dd34103 100644 --- a/src/main/webapp/app/entities/share/share-detail.component.html +++ b/src/main/webapp/app/entities/share/share-detail.component.html @@ -7,11 +7,11 @@
Document Date
- {{share.documentDate}} + {{share.documentDate | date:'mediumDate'}}
Value Date
- {{share.valueDate}} + {{share.valueDate | date:'mediumDate'}}
Action
@@ -23,7 +23,7 @@
Remark
- {{share.remark}} +
Membership
diff --git a/src/main/webapp/app/entities/share/share-update.component.html b/src/main/webapp/app/entities/share/share-update.component.html index faf87e8a..78a04f63 100644 --- a/src/main/webapp/app/entities/share/share-update.component.html +++ b/src/main/webapp/app/entities/share/share-update.component.html @@ -71,8 +71,8 @@
- +
diff --git a/src/main/webapp/app/entities/share/share-update.component.ts b/src/main/webapp/app/entities/share/share-update.component.ts index e7301309..b031a238 100644 --- a/src/main/webapp/app/entities/share/share-update.component.ts +++ b/src/main/webapp/app/entities/share/share-update.component.ts @@ -3,7 +3,6 @@ import { ActivatedRoute } from '@angular/router'; import { HttpResponse, HttpErrorResponse } from '@angular/common/http'; import { Observable } from 'rxjs'; import { filter, map } from 'rxjs/operators'; -import * as moment from 'moment'; import { JhiAlertService } from 'ng-jhipster'; import { IShare } from 'app/shared/model/share.model'; import { ShareService } from './share.service'; diff --git a/src/main/webapp/app/entities/share/share.component.html b/src/main/webapp/app/entities/share/share.component.html index 87d58b25..7ac7b10b 100644 --- a/src/main/webapp/app/entities/share/share.component.html +++ b/src/main/webapp/app/entities/share/share.component.html @@ -14,22 +14,46 @@ - - - - - - - + + + + + + + + + + + + + + + + + + + + - + - +
ID Document Date Value Date Action Quantity Membership ID Document Date Value Date Action Quantity Membership
+ + + +
{{share.id}}{{share.id}} {{share.documentDate | date:'mediumDate'}} {{share.valueDate | date:'mediumDate'}} {{share.action}}{{share.quantity}}{{share.quantity}}
{{share.membershipDisplayLabel}} diff --git a/src/main/webapp/app/entities/share/share.component.ts b/src/main/webapp/app/entities/share/share.component.ts index d636295f..831b30c6 100644 --- a/src/main/webapp/app/entities/share/share.component.ts +++ b/src/main/webapp/app/entities/share/share.component.ts @@ -9,6 +9,9 @@ import { AccountService } from 'app/core'; import { ITEMS_PER_PAGE } from 'app/shared'; import { ShareService } from './share.service'; +import { IMembership } from 'app/shared/model/membership.model'; +import { MembershipService } from 'app/entities/membership'; +import { TableFilter, queryYearAsDateRange, queryEquals } from 'app/shared/util/tablefilter'; @Component({ selector: 'jhi-share', @@ -24,9 +27,18 @@ export class ShareComponent implements OnInit, OnDestroy { predicate: any; reverse: any; totalItems: number; + memberships: IMembership[]; + filter: TableFilter<{ + documentDate?: string; + valueDate?: string; + action?: string; + quantity?: string; + membershipId?: string; + }>; constructor( protected shareService: ShareService, + protected membershipService: MembershipService, protected jhiAlertService: JhiAlertService, protected eventManager: JhiEventManager, protected parseLinks: JhiParseLinks, @@ -40,11 +52,25 @@ export class ShareComponent implements OnInit, OnDestroy { }; this.predicate = 'id'; this.reverse = true; + this.filter = new TableFilter( + { + documentDate: queryYearAsDateRange, + valueDate: queryYearAsDateRange, + action: queryEquals, + quantity: queryEquals, + membershipId: queryEquals + }, + 500, + () => { + this.reset(); + } + ); } loadAll() { this.shareService .query({ + ...this.filter.buildQueryCriteria(), page: this.page, size: this.itemsPerPage, sort: this.sort() @@ -71,6 +97,13 @@ export class ShareComponent implements OnInit, OnDestroy { this.accountService.identity().then(account => { this.currentAccount = account; }); + this.membershipService + .query() + .pipe( + filter((mayBeOk: HttpResponse) => mayBeOk.ok), + map((response: HttpResponse) => response.body) + ) + .subscribe((res: IMembership[]) => (this.memberships = res), (res: HttpErrorResponse) => this.onError(res.message)); this.registerChangeInShares(); } @@ -78,7 +111,7 @@ export class ShareComponent implements OnInit, OnDestroy { this.eventManager.destroy(this.eventSubscriber); } - trackId(index: number, item: IShare) { + trackId(index: number, item: { id: number }) { return item.id; } diff --git a/src/main/webapp/app/entities/user-role-assignment/user-role-assignment.component.html b/src/main/webapp/app/entities/user-role-assignment/user-role-assignment.component.html index 345fa10d..a08c8a10 100644 --- a/src/main/webapp/app/entities/user-role-assignment/user-role-assignment.component.html +++ b/src/main/webapp/app/entities/user-role-assignment/user-role-assignment.component.html @@ -14,13 +14,41 @@ - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/app/entities/user-role-assignment/user-role-assignment.component.ts b/src/main/webapp/app/entities/user-role-assignment/user-role-assignment.component.ts index 822109d8..38fde13c 100644 --- a/src/main/webapp/app/entities/user-role-assignment/user-role-assignment.component.ts +++ b/src/main/webapp/app/entities/user-role-assignment/user-role-assignment.component.ts @@ -9,6 +9,9 @@ import { AccountService } from 'app/core'; import { ITEMS_PER_PAGE } from 'app/shared'; import { UserRoleAssignmentService } from './user-role-assignment.service'; +import { IUser } from 'app/core/user/user.model'; +import { UserService } from 'app/core/user/user.service'; +import { TableFilter, queryEquals, queryContains } from 'app/shared/util/tablefilter'; @Component({ selector: 'jhi-user-role-assignment', @@ -24,9 +27,17 @@ export class UserRoleAssignmentComponent implements OnInit, OnDestroy { predicate: any; reverse: any; totalItems: number; + users: IUser[]; + filter: TableFilter<{ + entityTypeId?: string; + entityObjectId?: string; + assignedRole?: string; + userId?: string; + }>; constructor( protected userRoleAssignmentService: UserRoleAssignmentService, + protected userService: UserService, protected jhiAlertService: JhiAlertService, protected eventManager: JhiEventManager, protected parseLinks: JhiParseLinks, @@ -40,11 +51,24 @@ export class UserRoleAssignmentComponent implements OnInit, OnDestroy { }; this.predicate = 'id'; this.reverse = true; + this.filter = new TableFilter( + { + entityTypeId: queryContains, + entityObjectId: queryEquals, + assignedRole: queryEquals, + userId: queryEquals + }, + 500, + () => { + this.reset(); + } + ); } loadAll() { this.userRoleAssignmentService .query({ + ...this.filter.buildQueryCriteria(), page: this.page, size: this.itemsPerPage, sort: this.sort() @@ -71,6 +95,13 @@ export class UserRoleAssignmentComponent implements OnInit, OnDestroy { this.accountService.identity().then(account => { this.currentAccount = account; }); + this.userService + .query() + .pipe( + filter((mayBeOk: HttpResponse) => mayBeOk.ok), + map((response: HttpResponse) => response.body) + ) + .subscribe((res: IUser[]) => (this.users = res), (res: HttpErrorResponse) => this.onError(res.message)); this.registerChangeInUserRoleAssignments(); } @@ -78,7 +109,7 @@ export class UserRoleAssignmentComponent implements OnInit, OnDestroy { this.eventManager.destroy(this.eventSubscriber); } - trackId(index: number, item: IUserRoleAssignment) { + trackId(index: number, item: { id: number }) { return item.id; } diff --git a/src/main/webapp/app/shared/constants/pagination.constants.ts b/src/main/webapp/app/shared/constants/pagination.constants.ts index a148d457..1d1b27bb 100644 --- a/src/main/webapp/app/shared/constants/pagination.constants.ts +++ b/src/main/webapp/app/shared/constants/pagination.constants.ts @@ -1 +1,3 @@ -export const ITEMS_PER_PAGE = 20; +// For infinite scroll, it should be more than fits into a window height. +// Otherwise, the scrollbar might not be there at all, and further pages can't be reached. +export const ITEMS_PER_PAGE = 100; diff --git a/src/main/webapp/app/shared/util/tablefilter.ts b/src/main/webapp/app/shared/util/tablefilter.ts new file mode 100644 index 00000000..f6ac701f --- /dev/null +++ b/src/main/webapp/app/shared/util/tablefilter.ts @@ -0,0 +1,79 @@ +import { Subject, Subscription } from 'rxjs'; +import { debounceTime, distinctUntilChanged } from 'rxjs/operators'; + +export interface QueryDeclarations { + [key: string]: string; +} +export type DynamicQueryDefinition = (name: string, value: string) => QueryDefinitions; +export interface QueryDefinitions { + [key: string]: string | DynamicQueryDefinition; +} + +/** + * Handles filtering in data tables by converting the user input to query criteria of the JHipster REST API. + * + * It also does not reload during a given debounce period. + */ +export class TableFilter { + criteria: T; + + private criteriaChangedSubject = new Subject(); + private criteriaChangedDebouncer: Subscription; + + constructor(private query: QueryDefinitions, private debounceMillis: number, private reload: () => void) { + this.criteria = {} as any; + this.criteriaChangedDebouncer = this.criteriaChangedSubject.pipe(debounceTime(debounceMillis)).subscribe(() => this.reload()); + } + + trigger($event) { + this.debounce(); + } + + reset() { + this.criteria = {} as any; + this.debounce(); + } + + buildQueryCriteria(): QueryDeclarations { + let queryCriteria: any = {} as any; + Object.keys(this.criteria).forEach(name => { + const value = this.criteria[name]; + if (value === '--') { + queryCriteria[name + '.specified'] = false; + } else if (value === '++') { + queryCriteria[name + '.specified'] = true; + } else { + const queryDef = this.query[name]; + if (typeof queryDef !== 'function') { + queryCriteria[queryDef] = value; + } else { + const additionalQueryCriteria = queryDef(name, value); + queryCriteria = { ...queryCriteria, ...additionalQueryCriteria }; + } + } + }); + return queryCriteria; + } + + private debounce() { + this.criteriaChangedSubject.next(); + } +} + +export function queryYearAsDateRange(name: string, value: string) { + if (value.length === 'YYYY'.length) { + const queryCriteria: any = {} as any; + queryCriteria[name + '.greaterOrEqualThan'] = value + '-01-01'; + queryCriteria[name + '.lessOrEqualThan'] = value + '-12-31'; + return queryCriteria; + } + return null; +} + +export function queryEquals(name: string, value: string) { + return { [name + '.equals']: value }; +} + +export function queryContains(name: string, value: string) { + return { [name + '.contains']: value }; +} diff --git a/src/main/webapp/content/css/global.css b/src/main/webapp/content/css/global.css index f00b0323..9c162c66 100644 --- a/src/main/webapp/content/css/global.css +++ b/src/main/webapp/content/css/global.css @@ -225,3 +225,14 @@ ui bootstrap tweaks } /* jhipster-needle-css-add-main JHipster will add new css style */ + +/* ========================================================================== +ui tweaks by Hostsharing +========================================================================== */ +.jh-entity-details > dt { + color: lightslategray; +} + +.jh-entity-details > dd { + font-size: 140%; +} diff --git a/src/main/webapp/i18n/de/customerKind.json b/src/main/webapp/i18n/de/customerKind.json index f96e75e4..62f07a45 100644 --- a/src/main/webapp/i18n/de/customerKind.json +++ b/src/main/webapp/i18n/de/customerKind.json @@ -2,8 +2,8 @@ "hsadminNgApp": { "CustomerKind": { "null": "", - "NATURAL": "NATURAL", - "LEGAL": "LEGAL" + "NATURAL": "natürliche Person", + "LEGAL": "juristische Person" } } } diff --git a/src/test/javascript/spec/app/shared/util/tablefilter.spec.ts b/src/test/javascript/spec/app/shared/util/tablefilter.spec.ts new file mode 100644 index 00000000..8f523776 --- /dev/null +++ b/src/test/javascript/spec/app/shared/util/tablefilter.spec.ts @@ -0,0 +1,145 @@ +import { queryContains, queryEquals, queryYearAsDateRange, TableFilter } from 'app/shared/util/tablefilter'; + +/* To run these tests in IntelliJ IDEA, you need a run configuration with + Configuration File: + ~/Projekte/Hostsharing/hsadmin-ng/src/test/javascript/jest.conf.js + and a Node Interpreter, e.g. if installed with nvm, this could be: + ~/.nvm/versions/node/v10.15.3/bin/node + */ +describe('TableFilter Tests', () => { + describe('TableFilter', () => { + const TEST_DEBOUNCE_MILLIS = 100; + + let filter: TableFilter<{ name?: string; number?: string; date?: string }>; + let asynchronously: () => void; + + beforeEach(() => { + filter = new TableFilter( + { + name: queryContains, + number: queryEquals, + date: queryYearAsDateRange + }, + TEST_DEBOUNCE_MILLIS, + () => { + asynchronously(); + } + ); + }); + + it('trigger() asynchronously calls the reload-handler', done => { + // given + filter.criteria.name = 'Test Filter Value'; + + // when + filter.trigger({ target: { valid: true } }); + const triggerStartedAtMillis = Date.now(); + + // then + asynchronously = () => { + expect(Date.now()).toBeGreaterThan(triggerStartedAtMillis); + done(); + }; + }); + + it('if trigger() is called multiple times during debounce, debounce period ands after last trigger()', done => { + // given + filter.criteria.name = 'Test Filter Value'; + + // when + filter.trigger({ target: { valid: true } }); + let triggerStartedAtMillis = null; + setTimeout(() => { + filter.trigger({ target: { valid: true } }); + triggerStartedAtMillis = Date.now(); + }, 50); + + // then + asynchronously = () => { + expect(triggerStartedAtMillis).not.toBeNull(); + expect(Date.now()).toBeGreaterThan(triggerStartedAtMillis); + done(); + }; + }); + + it('when filter "name" is set, buildQueryCriteria() returns a name.contains query', () => { + // given + filter.criteria.name = 'test value'; + + // when + const actual = filter.buildQueryCriteria(); + + // then + expect(filter.buildQueryCriteria()).toEqual({ 'name.contains': 'test value' }); + }); + + it('when filter "name" is set to "--", buildQueryCriteria() returns a name.specified=false query', () => { + // given + filter.criteria.name = '--'; + + // when + const actual = filter.buildQueryCriteria(); + + // then + expect(filter.buildQueryCriteria()).toEqual({ 'name.specified': false }); + }); + + it('when filter "name" is set to "++", buildQueryCriteria() returns a name.specified=true query', () => { + // given + filter.criteria.name = '++'; + + // when + const actual = filter.buildQueryCriteria(); + + // then + expect(filter.buildQueryCriteria()).toEqual({ 'name.specified': true }); + }); + + it('when filter "number" is set, buildQueryCriteria() returns a number.equals query', () => { + // given + filter.criteria.number = '-42'; + + // when + const actual = filter.buildQueryCriteria(); + + // then + expect(filter.buildQueryCriteria()).toEqual({ 'number.equals': '-42' }); + }); + + it('when filter "date" is set to "2019", buildQueryCriteria() returns a date range query', () => { + // given + filter.criteria.date = '2019'; + + // when + const actual = filter.buildQueryCriteria(); + + // then + expect(filter.buildQueryCriteria()).toEqual({ 'date.greaterOrEqualThan': '2019-01-01', 'date.lessOrEqualThan': '2019-12-31' }); + }); + + it('queryYearAsDateRange() returns null if year is not 4-digit', () => { + expect(queryYearAsDateRange('date', '201')).toBeNull(); + expect(queryYearAsDateRange('date', '20191')).toBeNull(); + }); + + it('reset() clears criteria and calls reload-handler, considering debounce period', done => { + // given + filter.criteria.name = 'Test Filter Value'; + + // when + filter.trigger({ target: { valid: true } }); + let triggerStartedAtMillis = null; + setTimeout(() => { + filter.reset(); + triggerStartedAtMillis = Date.now(); + }, TEST_DEBOUNCE_MILLIS / 2); + + // then + asynchronously = () => { + expect(triggerStartedAtMillis).not.toBeNull(); + expect(Date.now()).toBeGreaterThan(triggerStartedAtMillis); + done(); + }; + }); + }); +});
ID Entity Type Id Entity Object Id Assigned Role User ID Entity Type Id Entity Object Id Assigned Role User
+ + + +