diff --git a/.github/workflows/codequality.yml b/.github/workflows/codequality.yml
new file mode 100644
index 00000000..6091ad33
--- /dev/null
+++ b/.github/workflows/codequality.yml
@@ -0,0 +1,26 @@
+name: Code Quality
+
+on:
+ pull_request:
+ branches: [master, development]
+ push:
+ branches: [master, development, java-8]
+
+jobs:
+ code_scan:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+ - name: Set up JDK 10
+ uses: actions/setup-java@v1
+ with:
+ java-version: 10
+ - name: Scan on SonarCloud.io
+ run: mvn verify sonar:sonar -Psonar --file superfields/pom.xml
+ env:
+ SONAR_TOKEN: ${{ secrets.SONARCLOUD_IO_LOGIN_KEY }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/makerelease.yml b/.github/workflows/makerelease.yml
new file mode 100644
index 00000000..a6beb2a8
--- /dev/null
+++ b/.github/workflows/makerelease.yml
@@ -0,0 +1,34 @@
+name: Make Release
+
+on:
+ push:
+ branches: [master]
+
+jobs:
+ create-release:
+ runs-on: ubuntu-latest
+ timeout-minutes: 30
+
+ steps:
+ - uses: actions/checkout@v2
+ - id: variables
+ run: |
+ echo "::set-output name=version::`head -1 superfields/release-notes.md | cut -d' ' -f2`"
+ echo "::set-output name=title::`head -1 superfields/release-notes.md | sed -n -e 's/^.* - //p'`"
+ export NOTES=`cat superfields/release-notes.md | sed -e '0,/^# /d;/^# /,$d'`
+ export NOTES="${NOTES//'%'/'%25'}"
+ export NOTES="${NOTES//$'\n'/'%0A'}"
+ export NOTES="${NOTES//$'\r'/'%0D'}"
+ echo "::set-output name=notes::$NOTES"
+ - name: Create Release
+ uses: fleskesvor/create-release@feature/support-target-commitish
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: "v${{ steps.variables.outputs.version }}"
+ commitish: "master"
+ release_name: "${{ steps.variables.outputs.version }} - ${{ steps.variables.outputs.title }}"
+ body: |
+ ${{ steps.variables.outputs.notes }}
+ draft: false
+ prerelease: false
\ No newline at end of file
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 08afac21..e0a87645 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -1,18 +1,19 @@
# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
-name: Java CI with Maven
+name: Build (Java 10)
on:
push:
- branches: [ master ]
+ branches: [ master, development ]
pull_request:
- branches: [ master ]
+ branches: [ master, development ]
jobs:
- build:
+ package:
runs-on: ubuntu-latest
+ timeout-minutes: 10
steps:
- uses: actions/checkout@v2
diff --git a/.github/workflows/mavenpublish.yml b/.github/workflows/mavenpublish.yml
index 2aadfd45..0f4b2017 100644
--- a/.github/workflows/mavenpublish.yml
+++ b/.github/workflows/mavenpublish.yml
@@ -8,9 +8,10 @@ on:
types: [created]
jobs:
- build:
+ publish:
runs-on: ubuntu-latest
+ timeout-minutes: 30
steps:
- uses: actions/checkout@v2
diff --git a/.github/workflows/releasebranch.yml b/.github/workflows/releasebranch.yml
new file mode 100644
index 00000000..fc67f869
--- /dev/null
+++ b/.github/workflows/releasebranch.yml
@@ -0,0 +1,22 @@
+name: Release branch on milestone close
+
+on:
+ milestone:
+ types: [closed]
+
+jobs:
+ make-branch:
+ runs-on: ubuntu-latest
+ if: ${{ startsWith(github.event.milestone.title, '0.') || startsWith(github.event.milestone.title, '1.') || startsWith(github.event.milestone.title, '2.') || startsWith(github.event.milestone.title, '3.') || startsWith(github.event.milestone.title, '4.') || startsWith(github.event.milestone.title, '5.') || startsWith(github.event.milestone.title, '6.') || startsWith(github.event.milestone.title, '7.') || startsWith(github.event.milestone.title, '8.') || startsWith(github.event.milestone.title, '9.') }}
+ steps:
+ - id: version
+ run: |
+ set -x
+ echo "::set-output name=version::`echo '${{ github.event.milestone.title }}' | cut -d' ' -f1`"
+ - name: Push release branch
+ uses: UnforgivenPL/push-branch@v2
+ with:
+ repository: ${{ github.repository }}
+ token: ${{ secrets.ACTIONS_PAT }}
+ source: development
+ target: release-${{ steps.version.outputs.version }}
diff --git a/.github/workflows/setversion.yml b/.github/workflows/setversion.yml
new file mode 100644
index 00000000..74525957
--- /dev/null
+++ b/.github/workflows/setversion.yml
@@ -0,0 +1,63 @@
+name: Version and Release Notes
+
+on: create
+
+jobs:
+ set-version:
+ if: ${{ (github.event.ref_type == 'branch') && startsWith(github.event.ref, 'release-') }}
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up JDK 10
+ uses: actions/setup-java@v1
+ with:
+ java-version: 10
+ server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
+ settings-path: ${{ github.workspace }} # location for the settings.xml file
+ - id: what-version
+ name: Determine version
+ run: |
+ set -x
+ export VERSION="`echo ${{ github.event.ref }} | sed -e s/release-//g`"
+ echo "::set-output name=version::$VERSION"
+ - name: Set version and update readme
+ run: |
+ set -x
+ export VERSION="${{ steps.what-version.outputs.version }}"
+ mvn versions:set -DnewVersion=$VERSION --file pom.xml
+ mvn versions:set -DnewVersion=$VERSION --file superfields/pom.xml
+ sed -i -e s/{VERSION}/$VERSION/g ./README.md
+ - name: Create milestone notes
+ uses: UnforgivenPL/milestone-notes@v1
+ with:
+ match-milestone: "^${{ steps.what-version.outputs.version }} "
+ repository: ${{ github.repository }}
+ labels: "enhancement, api, bug"
+ - name: Format milestone notes
+ run: |
+ sed -i -e "s/## enhancement/## New features and enhancements/g" milestone-notes.md
+ sed -i -e "s/## api/## Changes to API/g" milestone-notes.md
+ sed -i -e "s/## bug/## Bug fixes/g" milestone-notes.md
+ sed -i -e "s/^$/(nothing reported)/g" milestone-notes.md
+ - name: Update release notes
+ run: |
+ echo -e "\n" | cat milestone-notes.md - superfields/release-notes.md > superfields/release-notes.md.new
+ mv superfields/release-notes.md.new superfields/release-notes.md
+ - name: Remove milestone notes
+ run: rm milestone-notes.md
+ - name: Push changes
+ uses: stefanzweifel/git-auto-commit-action@v4.1.6
+ with:
+ commit_message: "(bot) version and release notes updated to ${{ steps.what-version.outputs.version }}"
+ branch: ${{ github.event.ref }}
+ - name: Create PR
+ uses: UnforgivenPL/pull-request@v1
+ with:
+ source: ${{ github.event.ref }}
+ target: master
+ repository: ${{ github.repository }}
+ token: ${{ secrets.ACTIONS_PAT }}
+ pr-title: Release ${{ steps.what-version.outputs.version }} ready
+ pr-body: Automatically created release ${{ steps.what-version.outputs.version }}.
+ pr-assignees: ${{ github.actor }}
diff --git a/README.md b/README.md
index b0b97532..c425aafc 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
# Welcome to SuperFields!
## Overview
+
This is a collection of hopefully useful Vaadin 14 components, grouped into several sub-projects:
* `superfields` are various input components;
* `demo-v14` contains an app for Vaadin 14 that shows all components - [see the demo online](https://superfields.herokuapp.com/) on Heroku
@@ -18,7 +19,7 @@ This is the relevant dependency:
org.vaadin.miki
superfields
- 0.6.0
+ 0.6.1
```
@@ -38,11 +39,13 @@ All releases are available:
### Java 8
-Some versions compatible with Java 8 may be released only to the Vaadin Directory. The repository has a branch `java-8`. The most recent version that supports Java 8 is `0.6.0.java8`.
+Some versions compatible with Java 8 are available in the Vaadin Directory. They are marked with `.java8` suffix in the version, e.g. `0.6.0.java8`. Their functionality is identical to the official release.
+
+This repository has a branch `java-8` which contains the most recent release compatible with Java 8.
## Contribution guidelines
-You are more than welcome to contribute. Feel free to make PRs, submit issues, etc.
+You are more than welcome to contribute. Feel free to make PRs, submit issues, ideas etc.
## Small print
diff --git a/demo-v14/pom.xml b/demo-v14/pom.xml
index e0d44b68..fc1877fa 100644
--- a/demo-v14/pom.xml
+++ b/demo-v14/pom.xml
@@ -4,11 +4,11 @@
superfields-parent
org.vaadin.miki
- 0.6.0
+ 0.6.1
superfields-demo-v14
- 0.6.0
+ 0.6.1
V14 demo app for SuperFields
Showcase application for V14 and SuperFields.
war
@@ -23,7 +23,7 @@
org.vaadin.miki
superfields
- 0.6.0
+ 0.6.1
javax.servlet
diff --git a/pom.xml b/pom.xml
index 914f8f10..d011eabb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
org.vaadin.miki
superfields-parent
- 0.6.0
+ 0.6.1
superfields
demo-v14
diff --git a/settings.xml b/settings.xml
new file mode 100644
index 00000000..ea5758a7
--- /dev/null
+++ b/settings.xml
@@ -0,0 +1,11 @@
+
+
+
+
+ github
+ ${env.GITHUB_ACTOR}
+ ${env.GITHUB_TOKEN}
+
+
+
+
\ No newline at end of file
diff --git a/superfields/pom.xml b/superfields/pom.xml
index 620fea3c..adaba0c4 100644
--- a/superfields/pom.xml
+++ b/superfields/pom.xml
@@ -8,7 +8,7 @@
superfields
SuperFields
Code for various V14+ fields and other components.
- 0.6.0
+ 0.6.1
10
@@ -204,6 +204,27 @@
+
+
+ sonar
+
+ vaadin-miki_super-fields
+ vaadin-miki
+ https://sonarcloud.io
+
+
+
+
+
+ org.sonarsource.scanner.maven
+ sonar-maven-plugin
+ 3.7.0.1746
+
+
+
+
+
+
directory
diff --git a/superfields/release-notes.md b/superfields/release-notes.md
new file mode 100644
index 00000000..55a763d9
--- /dev/null
+++ b/superfields/release-notes.md
@@ -0,0 +1,73 @@
+# 0.6.1 - Release process improvement
+## New features and enhancements
+* \#107 - [Generate release notes from a milestone](https://api.github.com/repos/vaadin-miki/super-fields/issues/107)
+## Changes to API
+(nothing reported)
+## Bug fixes
+* \#105 - [Removing date (time) picker and adding it back in the dom resets the display pattern](https://api.github.com/repos/vaadin-miki/super-fields/issues/105)
+
+# 0.6 - ComponentObserver and UnloadObserver
+## New features and enhancements
+* \#66 - [A field that changes value on becoming shown and hidden](https://api.github.com/repos/vaadin-miki/super-fields/issues/66)
+* \#69 - [ComponentObserver - reusing client-side IntersectionObserver as a server-side component](https://api.github.com/repos/vaadin-miki/super-fields/issues/69)
+* \#75 - [Component for encapsulating beforeunload events](https://api.github.com/repos/vaadin-miki/super-fields/issues/75)
+* \#80 - [Expand SuperTabs to work also with removing tab contents](https://api.github.com/repos/vaadin-miki/super-fields/issues/80)
+* \#82 - [Allow overriding default container in SuperTabs](https://api.github.com/repos/vaadin-miki/super-fields/issues/82)
+## Changes to API
+* \#76 - [Make Vaadin dependencies not transitive](https://api.github.com/repos/vaadin-miki/super-fields/issues/76)
+* \#85 - [Add WithItems also to ItemGrid](https://api.github.com/repos/vaadin-miki/super-fields/issues/85)
+* \#86 - [Create WithValue to allow chaining setValue calls](https://api.github.com/repos/vaadin-miki/super-fields/issues/86)
+* \#89 - [Expose DatePicker and TimePicker in SuperDateTimePicker](https://api.github.com/repos/vaadin-miki/super-fields/issues/89)
+* \#92 - [Add WithIdMixin to all components](https://api.github.com/repos/vaadin-miki/super-fields/issues/92)
+## Bug fixes
+* \#81 - [Setting date display pattern does not work out-of-the-box](https://api.github.com/repos/vaadin-miki/super-fields/issues/81)
+* \#83 - [SuperTabs should implement HasItems](https://api.github.com/repos/vaadin-miki/super-fields/issues/83)
+* \#90 - [SuperTabs should be using removing handler by default](https://api.github.com/repos/vaadin-miki/super-fields/issues/90)
+* \#93 - ["this.observer is undefined" after ObservedField is removed from dom and added again](https://api.github.com/repos/vaadin-miki/super-fields/issues/93)
+* \#98 - [Vaadin production mode not included](https://api.github.com/repos/vaadin-miki/super-fields/issues/98)
+# 0.5.1 - Fix maven dependencies
+## New features and enhancements
+(nothing reported)
+## Changes to API
+(nothing reported)
+## Bug fixes
+* \#70 - [Parent pom unavailable for Directory downloads](https://api.github.com/repos/vaadin-miki/super-fields/issues/70)
+# 0.5 - LazyLoad
+## New features and enhancements
+* \#50 - [Investigate lazy loading for ItemGrid](https://api.github.com/repos/vaadin-miki/super-fields/issues/50)
+* \#51 - [Custom date formatting for date components](https://api.github.com/repos/vaadin-miki/super-fields/issues/51)
+## Changes to API
+(nothing reported)
+## Bug fixes
+* \#56 - [Set width to full in number fields](https://api.github.com/repos/vaadin-miki/super-fields/issues/56)
+# 0.4 - ItemGrid
+## New features and enhancements
+* \#34 - [Basic version of `ItemGrid`](https://api.github.com/repos/vaadin-miki/super-fields/issues/34)
+## Changes to API
+(nothing reported)
+## Bug fixes
+(nothing reported)
+# 0.3 - SuperTabs
+## New features and enhancements
+* \#26 - [SuperTabs](https://api.github.com/repos/vaadin-miki/super-fields/issues/26)
+## Changes to API
+* \#30 - [Add .withXYZ methods to all fields](https://api.github.com/repos/vaadin-miki/super-fields/issues/30)
+## Bug fixes
+(nothing reported)
+# 0.2 - Date components
+## New features and enhancements
+* \#12 - [SuperDatePicker](https://api.github.com/repos/vaadin-miki/super-fields/issues/12)
+* \#20 - [SuperDateTimePicker](https://api.github.com/repos/vaadin-miki/super-fields/issues/20)
+## Changes to API
+(nothing reported)
+## Bug fixes
+(nothing reported)
+# 0.1 - Number fields
+## New features and enhancements
+* \#2 - [SuperDoubleField](https://api.github.com/repos/vaadin-miki/super-fields/issues/2)
+* \#4 - [SuperIntegerField and SuperLongField](https://api.github.com/repos/vaadin-miki/super-fields/issues/4)
+* \#5 - [SuperBigDecimalField](https://api.github.com/repos/vaadin-miki/super-fields/issues/5)
+## Changes to API
+(nothing reported)
+## Bug fixes
+* \#10 - [Max integer length does not work if it is a multiplication of grouping size](https://api.github.com/repos/vaadin-miki/super-fields/issues/10)
\ No newline at end of file
diff --git a/superfields/src/main/java/org/vaadin/miki/superfields/dates/DatePatternHelper.java b/superfields/src/main/java/org/vaadin/miki/superfields/dates/DatePatternHelper.java
index 82431830..556cd364 100644
--- a/superfields/src/main/java/org/vaadin/miki/superfields/dates/DatePatternHelper.java
+++ b/superfields/src/main/java/org/vaadin/miki/superfields/dates/DatePatternHelper.java
@@ -1,5 +1,6 @@
package org.vaadin.miki.superfields.dates;
+import com.vaadin.flow.component.AttachEvent;
import com.vaadin.flow.component.Component;
/**
@@ -9,7 +10,7 @@
* @author miki
* @since 2020-05-02
*/
-final class DatePatternHelper {
+final class DatePatternHelper {
/**
* Returns the pattern descriptor string expected by the client-side code.
@@ -52,20 +53,48 @@ private static String convertDatePatternToClientPattern(DatePattern pattern) {
}
}
+ private final C source;
+
/**
- * Does magic and sets the display pattern on the client side.
- * Requires the client-side connector to have a {@code setDisplayPattern} method.
- * @param source Source component.
- * @param pattern Pattern to set.
+ * Creates a helper for a given source object.
+ * The client-side representation should have mixed in methods from {@code date-pattern-mixin.js}.
+ * @param source Source to use.
+ */
+ DatePatternHelper(C source) {
+ this.source = source;
+ this.source.addAttachListener(this::onAttached);
+ }
+
+ /**
+ * Class client-side method {@code initPatternSetting()} that, well, inits pattern setting.
+ * In general, client-side code overrides a few methods to make sure pattern displaying and parsing works properly with custom patterns.
*/
- static void setClientSidePattern(Component source, DatePattern pattern) {
- source.getElement().getNode().runWhenAttached(ui -> ui.beforeClientResponse(source, context ->
- source.getElement().callJsFunction("setDisplayPattern", source.getElement(), convertDatePatternToClientPattern(pattern))
+ protected void initPatternSetting() {
+ this.source.getElement().getNode().runWhenAttached(ui -> ui.beforeClientResponse(this.source, context ->
+ this.source.getElement().callJsFunction("initPatternSetting", this.source)
));
}
- private DatePatternHelper() {
- // instances not allowed
+ /**
+ * Callback when onAttach() is called.
+ * @param event An {@link AttachEvent}.
+ */
+ protected void onAttached(AttachEvent event) {
+ this.initPatternSetting();
+ this.updateClientSidePattern();
+ }
+
+ /**
+ * Does magic and sets the display pattern on the client side.
+ * Requires the client-side connector to have a {@code setDisplayPattern} method.
+ */
+ protected void updateClientSidePattern() {
+ this.source.getElement().getNode().runWhenAttached(ui -> ui.beforeClientResponse(this.source, context ->
+ this.source.getElement().callJsFunction(
+ "setDisplayPattern",
+ this.source.getElement(), convertDatePatternToClientPattern(this.source.getDatePattern())
+ )
+ ));
}
}
diff --git a/superfields/src/main/java/org/vaadin/miki/superfields/dates/SuperDatePicker.java b/superfields/src/main/java/org/vaadin/miki/superfields/dates/SuperDatePicker.java
index 346b6b57..f8a8f264 100644
--- a/superfields/src/main/java/org/vaadin/miki/superfields/dates/SuperDatePicker.java
+++ b/superfields/src/main/java/org/vaadin/miki/superfields/dates/SuperDatePicker.java
@@ -30,6 +30,8 @@ public class SuperDatePicker extends DatePicker
WithValueMixin, LocalDate, SuperDatePicker>,
WithIdMixin {
+ private final DatePatternHelper delegate = new DatePatternHelper<>(this);
+
private DatePattern datePattern;
public SuperDatePicker() {
@@ -77,22 +79,25 @@ public SuperDatePicker(String label, LocalDate initialDate, ValueChangeListener<
}
public SuperDatePicker(LocalDate initialDate, Locale locale) {
- super(initialDate, locale);
+ super(initialDate);
+ this.setLocale(locale);
}
@Override
public final void setLocale(Locale locale) {
- this.getElement().getNode().runWhenAttached(ui -> ui.beforeClientResponse(this, context ->
- this.getElement().callJsFunction("initPatternSetting", this.getElement())
- ));
- SuperDatePickerI18nHelper.updateI18N(locale, this::getI18n, this::setI18n);
+ // there is a call for setting locale from the superclass' constructor
+ // and when that happens, the field is not yet initialised
+ if(this.delegate != null) {
+ this.delegate.initPatternSetting();
+ SuperDatePickerI18nHelper.updateI18N(locale, this::getI18n, this::setI18n);
+ }
super.setLocale(locale);
}
@Override
public void setDatePattern(DatePattern datePattern) {
this.datePattern = datePattern;
- DatePatternHelper.setClientSidePattern(this, datePattern);
+ this.delegate.updateClientSidePattern();
}
@Override
diff --git a/superfields/src/main/java/org/vaadin/miki/superfields/dates/SuperDateTimePicker.java b/superfields/src/main/java/org/vaadin/miki/superfields/dates/SuperDateTimePicker.java
index b724ba4c..dce504f9 100644
--- a/superfields/src/main/java/org/vaadin/miki/superfields/dates/SuperDateTimePicker.java
+++ b/superfields/src/main/java/org/vaadin/miki/superfields/dates/SuperDateTimePicker.java
@@ -36,6 +36,8 @@ public class SuperDateTimePicker extends DateTimePicker
private static final String INTERNAL_DATE_PICKER_FIELD_NAME = "datePicker";
private static final String INTERNAL_TIME_PICKER_FIELD_NAME = "timePicker";
+ private final DatePatternHelper delegate = new DatePatternHelper<>(this);
+
private DatePattern datePattern;
public SuperDateTimePicker() {
@@ -89,11 +91,12 @@ public SuperDateTimePicker(LocalDateTime initialDateTime, Locale locale) {
@Override
public void setLocale(Locale locale) {
- this.getElement().getNode().runWhenAttached(ui -> ui.beforeClientResponse(this, context ->
- this.getElement().callJsFunction("initPatternSetting", this)
- ))
- ;
- SuperDatePickerI18nHelper.updateI18N(locale, this::getDatePickerI18n, this::setDatePickerI18n);
+ // this method is called from the constructor of the superclass
+ // which means that first time it gets called, the delegate is not yet initialised
+ if(this.delegate != null) {
+ this.delegate.initPatternSetting();
+ SuperDatePickerI18nHelper.updateI18N(locale, this::getDatePickerI18n, this::setDatePickerI18n);
+ }
super.setLocale(locale);
}
@@ -101,7 +104,7 @@ public void setLocale(Locale locale) {
* Exposes an internal {@link DatePicker}, if it was successfully obtained through reflection.
* @return A {@link DatePicker} used by this component, if possible.
*/
- public Optional getDatePicker() {
+ public Optional getInternalDatePicker() {
return ReflectTools.getValueOfField(this, DatePicker.class, INTERNAL_DATE_PICKER_FIELD_NAME);
}
@@ -116,7 +119,7 @@ public Optional getInternalTimePicker() {
@Override
public void setDatePattern(DatePattern pattern) {
this.datePattern = pattern;
- DatePatternHelper.setClientSidePattern(this, pattern);
+ this.delegate.updateClientSidePattern();
}
@Override