# Change log


## 0.1.7

- enh: Menu: Allow dynamic insertion, using a new config options (see 'CORE_CONFIG_OPTIONS.MENU_ITEMS')
  * Example:
  ```js
    const options = [
      // Insert before'MENU.HOME'
      {title: "Item #1", path: "/settings", icon: "people", before: "MENU.HOME"},
  
      // Insert after 'MENU.HOME'
      {title: "Item #2", path: "/settings", icon: "people", after: "MENU.HOME"}
    ];
    config.properties[CORE_CONFIG_OPTIONS.MENU_ITEMS.key] = JSON.stringify(items); 
  ```
  Values of 'after' and 'before' will be compared with `title` of existing items.

## 0.3.3

- enh: CSS `.filter-panel` should be used with `.filter-panel-floating` to enable floating position

## 0.3.4

- fix: Users table: use floating filter panel

## 0.3.5

- enh: Add new pipe `arrayFilter` to be able to filter an array, in HTML templates

## 0.4.0

- enh: CSS: change style of error row (use warning color)
- enh: CSS: new class '.visible-dirty' (e.g. `<ion-icon name="star" class="visible-dirty"></ion-icon>` in the `actions` column)
- enh: ValidatorService: add function getI18nErrors(control)
- enh: AppTable: add outputs 'onDirty', 'onError'
- enh: AppTable:

## 0.4.1

- enh: Add new component 'app-actions-columns'

## 0.4.2

- enh: LoadResult class: Add a `fetchMore()` function
- enh: Autocomplete field: Add infinite scroll, using `LoadResult.fetchMore()`

## 0.4.3

- enh: AppTable: add `options` (with property `interactive`) in `deleteRow()` and `deleteRows()`
  Used to avoid user confirmation, when deletion has been confirmed elsewhere

## 0.4.4

- enh: Rename `<form-buttons-bar>` into `<app-form-buttons-bar>`
- enh: Export more CSS variables: `--app-paginator-height`, `app-form-buttons-bar-height`

## 0.5.0

- enh: Table: allow keyboard navigation, using `<app-actions-column>` and function `table.confirmAndBackward()` and `table.confirmAndForward()`

## 0.7.10

- enh: Table: no more border-left, on dirty rows (because of sticky columns nightmare !)

## 0.9.0

- enh: Autocomplete field: add config option `suggestLengthThreshold` to suggest after typing more than x characters
- enh: Autocomplete field: add config option `debounceTime`

## 0.10.0

- enh: Add EntityClasses class: use it to get an entity class by name (need to use @EntityClass decorator on the class)

## 0.11.4

- fix: Autocomplete field: when focus out, move caret to start (fix firefox bug, when `input[type=text]` content is too long)

## 0.11.5

- enh: Decorator @Entity now generate the static class function `asObject(source: any, opts?: any): any`

## 0.15.0

- enh: Add IAppForm.loading (optional)
- enh: Add AppForm.waitIdle()
- enh: IAppForm, AppForm, AppTabEditor: Add markAsLoading() and markAsLoaded()

## 0.18.0

- enh: Add AppTable.updateView(): Promise
- enh: Add AppTableDatasource: rename $busy into loadingSubject
- fix: Fix InMemoryTable setValue
- fix: AppTable: after save, refactor code to select previously edited row

## 0.19.0

- fix: refactor AppFormUtils.copyEntityToForm() for multiple values (split on the character '|' )
- fix: remove AppFormUtils.copyForm2Entity() - same a form.value

## 0.20.0

- fix: remove functions `isArray()` (please use `Array.isArray()` instead)
- enh: Add `AccountService.onChange: Subject` to listen account settings changes
- fix: Account model: use minify option to serialize as a POD object
- fix: AccountService: change some internal function's visibility, to protected
- fix: InMemoryService: fix equals() default implementation (avoid infinite loop)
- fix: SCSS: Set mat-select-column to width: 50px, to make it compatible with sticky <mat-table>
- enh: Add ComponentDirtyGuard to public API

## 0.20.0

- fix: AppEntityEditor: remove confirmation before backClick (use ComponentDirtyGuard instead)
- fix: AppEntityEditor: cancel() will not ask a confirmation, because called by dirty guard).

## 0.23.0

- fix: MatAutocompleteField: when escape event, close the panel and stop event's propagation
- fix: AppFormButtonsBar: when escape event, make sure preventDefault!=false before emit a back event

## 0.24.0

- fix: AppInstallUpgradeCard: use Cordova Downloader plugin, to download APK file correctly

## 0.25.0

- enh: Add FormErrorAdapter service, configurable using an injection token APP_FORM_ERROR_I18N_KEYS
- enh: Add pipe 'translateFormError' to translate form error in HTML template

## 0.26.0

- enh: Rename FormErrorAdapter into FormErrorTranslator
- enh: Add FormErrorTranslator to AppForm
- enh: Add directives [matBadgeIcon] and [ionBadgeIcon] to use icon within a matBadge

## 0.27.0

- enh: Split `AppTabEditor` into `AppEditor` and `AppTabEditor`
- enh: Add `markAsReady()` to base components (`IAppForm`, `AppForm`, `AppTable`, `AppEditor`)
- enh: Add `ready() => Promise` to base components (`IAppForm`, `AppForm`, `AppTable`, `AppEditor`)
- enh: `AppEntityEditor`: wait components is ready, before calling `setValue()`
- enh: `waitFor()` now return a `Promise<void>` (instead of a `Promise<any>`)

## 1.0.0

- enh: Store local settings remotely
- fix: Fix suggestFromArray when items is null
- fix: Fix parsing error, in GraphQL service (e.g error from Oracle database)

## 1.2.5

- fix: Install/Upgrade component: can now download file, on Android devices

## 1.5.1

- enh: MatAutocompleteField: set header position has sticky, in CSS
- enh: MatAutocompleteField: if mobile, set autocomplete panel's position to 'above' (instead of 'auto') because keyboard should open at the bottom
- fix: AppForm: add method 'unregisterSubscription()'
- fix: Account: disable form when offline

# 1.5.6

- enh: Add observables.waitForTrue() function
- enh: Editor: apply ready() opts (timeout, dueTime)
- fix: suggestFromArray: fix sorting

# 1.5.8

fix: When deleting rows selection, make sure to confirm edited row first

# 1.6.4

enh: EntitiesTableDateSource: Add 'fetchMore()' function (usable when dataService fill LoadResult.fetchMore)
fix: Auth modal: show error (e.g. when bad credentials)
fix: MatChipsField: rename 'compareWith' in 'equals'
enh: MatChipsField: Allow setup chips color
fix: MatSwipeField: rename 'compareWith' in 'equals'

# 1.6.5

fix: MatChipsField: Fix 'focusOut' then 'focusIn' behavior
fix: MatAutocompleteField: Fix 'focusOut' then 'focusIn' behavior

# 1.6.18

fix: MatDateTimeField: Fix when no Keyboard plugin

# 1.7.0

enh: Add directive `*ngVar` - see https://stackoverflow.com/questions/38582293/how-to-declare-a-variable-in-a-template-in-angular

# 1.8.1

enh: IEntityService: add new function `canUserWrite()`
enh: AppEntityEditor: add a default implementation of `canUserWrite()`

# 1.9.5

enh: AppTable: Add injector in constructor
fix: Platform: detect window touchscreen as NOT mobile
fix: AppEntityEditor: make sure to unsubscribe listen remote changes, when destroy
fix: Home: fix layout, of card close button, in history items
fix: Make sure to use LocalSettingsServicesettings.mobile instead of PlatformService.mobile
enh: Account: auto start listen changes on pod, during the user session

# 1.10.1

fix: AppTable: Fix table row deletion, when editedRow is invalid and not saved yet - fix issue IMAGINE-669

# 1.10.9

fix: AppTable: Fix table when calling save with options : `keepEditing=false`

# 1.11.0

enh: Add component UploadFilePopover
enh: Add component TextPopover
enh: Upgrade to @apollo/client 3.5.10

# 1.12.1

fix: searchTextFilter: escape special characters to avoid RegExp parse exception
enh: Autocomplete: Move result count in footer

# 1.12.4

fix: AppTable: Avoid deleting a row twice, when deleting an invalid row BUT not editing

# 1.12.13

enh: Add pipes formGet, formGetControl and formGetArray, to get a form controls
enh: Add pipe strIncludes

# 1.13.0

enh: Add utility class SharedAsyncValidators
enh: Add SharedAsyncValidators.registerAsyncValidator() to add long during validation job
fix: BaseEntityService: listenChanges() now return an empty observable, when not implemented, instead of error
fix: InstallUpgradeCard: do not show install link, on Windows touch screen

# 1.14.0

enh: Platform: auto reload web browser's page, if a new version is detected at startup

# 1.14.2

enh: Add DateUtils.resetTime(date, tz?: string)

# 1.15.0

fix: MateDateField: make sure to display errors
fix: MateDateField: Allow to show matPrefix (e.g. icon)
fix: MateDateField: Better management of mat-error
fix: MateDateTimeField: Add error for dateIsBefore
enh: SharedValidators: add new validator 'dateIsBefore'

# 1.15.1

fix: MateDateField: Add a timezone to serialize/deserialize date value

# 1.15.4

enh: MateDateField: Add an input 'datePickerFiler' to filter dates in picker
enh: MateDateTimeField: Add an input 'datePickerFiler' to filter dates in picker

# 1.15.9

fix: Editor listenChanges() should not update the cache, but call reload() when changes detected.
This will allow fetching partial graph in subscriptions
enh: Editor: show a toast when remote changes are detected
fix: Cache: minor fix

# 1.15.13

fix: File upload component: fix file/event management
enh: Add new pipe 'formGetGroup:<name>'

# 1.16.0

enh: Refactor JobUtils functions: 'progression' is now optional, and hold by options

# 1.17.0

fix: GraphQL: set NetworkStatus.error on error object in order to throw corresponding exception

# 1.17.1

fix: Hotkeys: Prevent global hotkeys when popover component exists

# 1.18.0

enh: Autocomplete field: Add search bar on mobile
fix: Autocomplete field: Fix style when multiple=true
fix: Autocomplete field: Fix default displayWith when multiple=true (manage array value)
fix: Exclude Windows from the platform mobile detection

# 1.18.4

fix: Autocomplete: fix search in mobile searchbar
enh: Material field components: allow to set 'required' as empty tag, and not only '[required]=true'

# 1.18.4

fix: Autocomplete: fix panel width, on small screens

# 1.18.7

fix: fix DateUtils.min() and DateUtils.max()

# 1.19.0

enh: Add a MessageModal, to compose message to users (internal or email messages)
fix: MatDateField: if not required, manually set a date will not apply the value to formControl

# 1.19.1

fix: Platform detection failed (infinite loop) on MacBook

# 1.19.2

fix: Platform detection cache

# 1.19.3

enh: AppForm now wait form not pending, before emitting onSubmit event

# 1.19.6

fix: Fix toolbar back button
fix: Autocomplete: Fix multiple values (displayValue was no shown)
fix: Autocomplete: avoid to many call to suggest, on mobile
fix: Autocomplete: use mat-option for searchbar, to have selected option is visible
fix: Install APK: make sure to have '.apk' at end of filename
fix: Auth modal: keep modal into loading, when waiting server response
enh: Create a specific card for offline mode update
fix: Entity storage: do NOT set skipIfPristine to false, when storage keep non local entities (e.g. OperationVO)
enh: Entity storage: persist() has a new option skipIfPristine, to be able to force all data to be stored, even if not dirty

# 1.19.7

enh: Add pipe 'formGetValue' that will listen value changes (from a form or a control)

# 1.19.16

fix: Date and Date Short field: optimize <mat-error> with a switch/case
fix: Lat/Long pipes: remove provider in root (not need on a pipe)
fix: SharedValidators: rename 'double' validator into 'decimal'. Now return an error 'decimal' when opts.maxDecimals is nil

# 1.19.18

fix: Add a workaround to patch <html> class to 'plt-desktop', on Windows touch screen (fix sumaris-app issue #346)
enh: EntitiesStorage: detect platform pause, to force saving the storage

# 1.19.23

fix: Menu: avoid to many call of onLogin() function (add a distinctUntilChanged() filter)
fix: MateDateTime: set required validator using template, and no more by overriding formControl.validator (allow to change the required value)
fix: EntityEditor: wait end of saving, in waitIdle() function
fix: EntityEditor: add debug log when changing/updating route
fix: EntityEditor.load(): rename the unused options 'updateTabAndRoute' into 'updateRoute'
fix: EntityEditor.load(): allow to reset to the first tab (e.g. when load another entity into an existing editor)

# 1.19.23

fix: Editor: allow to skip page history (computePageHistory can return 'undefined')

# 1.19.25

fix: Home: translate 'Loading...' message

# 1.19.28

enh: Add function escapeRegExp() to escape all special regexp characters

# 1.19.30

enh: Add argument to pipe 'formGetValue' to listen status change (e.g. to force update, when emitEvent: false)

# 1.20.0

enh: Menu: allow to enable/disable menu
enh: Menu: rename MenuService.menuVisible$ into MenuService.splitPaneWhen

# 1.20.2

enh: Material fields: add @Input() appearance

# 1.20.3

enh: css-variables-to-root-mobile() will expose variables '--mat-tab-link-height' and '--mat-tab-bar-height'

# 1.20.4

enh: Add helper class CsvUtils
enh: Add pipe formatProperty
enh: Add directive [appAutoTitle] for <ion-label> or <mat-label>

# 1.20.5

enh: formatProperty pipe: when type is 'boolean', display a translated Yes/No

# 1.20.7

enh: add function FileUtils.writeTextToFile()

# 1.20.11

enh: add function FileUtils.downloadUri()

# 1.20.13

fix: fix SharedValidators.decimal() when maxDecimals = 3 (cached regexp was wrong)

# 1.20.14

fix: Menu: Force menu update when config changed

# 1.20.16

fix: MatChipsField: fix chip height

# 1.20.17

fix: Add module ResizableModule, for MatTable column resize

# 1.20.18

fix: PlatformService.download() now useFileUtils.download(), that create a temp download (not need browser permission to open popup)

# 1.20.19

enh: Add new abstract class AppEntityEditorModal, that can managed many forms and tables

# 1.20.20

fix: SCSS: remove `user-select: text !important` applied on body, because of modals ViewEncapsulation.None (e.g. physical gear modal) where Tab label were becomes focusable

# 1.20.21

fix: Fix mat latlong field: was broken since v1.19.13

# 1.20.21

fix: Fix MatDateField mat-error display (was too large)

# 1.20.24

fix: Revert change on LatLongField (SCSS file was removed ??)

# 1.20.25

fix: MatBooleanField: set indeterminate=true, when value is null

# 1.20.27

fix: Mat***Field: add `@Input() appearance`

# 1.20.30

fix: Add InMemoryDataService.hiddenCount

# 1.20.33

fix: MatAutocompleteField: reload items when cleaning text, and no suggestLengthThreshold

# 1.20.34

fix: AppTable: remove 'opts.skipIfLoading' on delete functions, to use only 'opts.interactive' to force deletion when table is busy.

# 1.21.0

enh: AppForm: use public behavior subjects: readySubject, loadingSubject, errorSubject

# 1.22.0

enh: Add social components: UserEventNotification and JobProgression

# 1.22.1

enh: Menu: add APP_MENU_OPTIONS token, to configure menu (e.g. show notification icon in the left menu header)

# 1.22.9

enh: Remove <app-user-events-table> (move to specific sub projects that use ngx-components)

# 1.22.11

enh: Rename <app-user-event-notification-component> into <app-user-event-notification-icon>

# 1.22.12

enh: Can mark a Moment without time, allowing empty time field in MatDateTime

# 1.23.6

fix: Many fix in table. Upgrade to ngx-material-table 0.12.0
enh: Table, Form and Editor: Add a destroySubject
enh: Observables functions first***Promise() : add more options (timeout or stop notifier)

# 1.23.10

enh: Autocomplete: add a 'title' property on each option, on desktop screen

# 1.23.11

fix: Memory Data service: now implement IStartableService
enh: StartableService: use a stopSubject, to stop waitFor promise
enh: remove unused class EntitiesService. Use IEntitiesService instead

# 1.23.26

enh: Add new pipe 'arrayJoin'
enh: 'arrayPluck' pipe: allow to use string[] for path
enh: getPropertyByPath() function now allow to use string[] as path

# 1.23.29

enh: FormArrayHelper: add setValue() to resize the FormArray, then set value

# 1.23.30

fix: InMemoryDataService: do NOT apply default sortReplacement id -> rankOrder

# 1.23.31

fix: InMemoryDataService: change 'dirtySubject' as public property

# 1.23.39

enh: Add FormArrayHelper.patchValue() : clear array, then push each value
fix: StartableService: avoid to log error when stopped

# 1.23.41

enh: AppEditor: Add 'loaded' getter

# 1.23.44

enh: Referential model: add a 'icon' property (IconRef)

# 1.23.46

enh: Add `ColorScale.getValueColor(): Color`  
enh: EntityEditorModal: rename input `isNewData` into `isNew`

# 1.23.51

Observables: function `waitFor()`, `waitForTrue()`, `watForFalse()`, `firstNotNilPromise()`

- fix: Make sure `takeUntil` is always the last operator (avoid memory leak)
- enh: Observables: Allow set option.stopError with custom error message
- enh: Observables: Create the Error outside the observable, to keep the original stack trace readable

# 1.23.61

- fix: Boolean field: fix button layout

# 1.23.65

- enh: Add pipes: isNotNil and isNotNilOrNaN

# 1.23.67

- fix: Rename DateFormatPipe into DateFormatService (DateFormatPipe is no more a provider)
- fix: Fix patterns in DateFormatPipe/Service : add a fallback when translate service is not started - fix issue sar-app #28

# 2.0.0

- enh: Migration to
  - Angular 14.2
  - Ionic 6.2
  - Angular Material Table 0.14.4 (allow to use async validator for rows)
  - Apollo 3, graph-ws 5
- enh: Add <app-debug> component

# 2.1.0

- enh: Add new class AppFormArray with all functions of FormArrayHelper

# 2.2.1

- fix: FormArrayHelper and AppFormArray: Apply the parent disabled state, in added controls, when calling resize() or patchValue()
- fix: FormArrayHelper.getOrCreateArray(): Apply the parent form disabled state, in added FormArray
- fix: MatChipsField: fix loading spinner freeze

# 2.2.3

- enh: Test Geolocation.getCurrentPosition() in the lat/long field test page

# 2.2.4

- fix: Fix DateUtils.isSame(), when first argument is nil, but the second not
- enh: AppTable: allow to call deleteSelection with opts (e.g `{interactive: false}`)

# 2.2.6

- fix: Refresh menu on any account changes (login changes - eg. when account updated)

# 2.2.8

- fix: Table actions column: add CSS variable to set column width, min-width and max-width

# 2.3.7

- fix: Mat form field: use inherit font size (do not force font-size, in the theme)
- fix: MatDateShort: fix behaviour for Angular 14

# 2.4.0

- Breaking change: ProgressBarService and HTTP_INTERCEPTORS no longer provided in SharedModule (see: AppModule)
- enh: Make ProgressBarService fully optional (InjectionToken: APP_PROGRESS_BAR_SERVICE)
- enh: Settings: the settings object is now stored in json format

# 2.4.1

- fix: AppFormArray: do not resize the array when patchValue() receive `undefined` value (e.g. useful when called by parent, recursively, without value)
- fix: AppAsyncTable: optimize markAsUntouched()

# 2.4.2

- enh: Graphql service: add new token `APP_GRAPHQL_FRAGMENTS` to register fragments, and avoid redeclaration in queries (
  see https://github.com/apollographql/apollo-client/pull/9764#issuecomment-1329857853)

# 2.4.3

- fix: AppFormArray: do not resize the array when patchValue() receive `null` or `undefined` value (same behavior as official `FormArray.patchValue()`)

# 2.4.4

- fix: Applying environment defaultLocale, when settings data has no locale (merge some code from lpecquot, that was in a branch)

# 2.4.9

- fix: Settings: allow to store settings as string (like < 2.4.0) using an injection token

# 2.4.10

- fix: When detecting a app update, stop the check timer to avoid to many toast to be displayed

# 2.4.14

- enh: add function `setPropertyByPath()`
- fix: Implement `EntityUtils.getPropertyByPath()` using generic shared function `getPropertyByPath()`

# 2.4.15

- fix: Fix pipes formGetControl, formGetValue, formGetGroup : when using a path, return nil if control not found, and NOT the form itself

# 2.4.16

- fix: `SharedModule.forRoot()`:  make environment optional, to be defined it in the `app.module.ts` (need by Quadrige App)

# 2.4.17

- fix: MatLatLongField: remove strict character regexp, in degrees part, to be able to set only one digit (e.g. `9°`)

# 2.4.18

- fix: MatDateShortField: fix control validation, in desktop mode

# 2.4.19

- fix: MatAutocompleteField: revert the cdk overlay position, when closing the mat-select panel

# 2.4.23

- enh: Add DateUtils.markTime(), to reset the 'no time' marker
- enh: Add DateUtilsEntityEditor: simplify updateTabAndRoute()
- enh: Add DateUtilsEntityEditor: updateRoute() now manage queryParams change, before /new to /:id transition
- enh: Toolbar: goBack() return a boolean

# 2.4.25

- enh: Environment: add a boolean option 'sameUrlPeer', to force network to start on peer at the same URL
- enh: EntityEditor: allow to listen changes on local entity
- enh: add functions collectByProperty() to split an array in a map of array

# 2.4.26

- fix: Rename pipe 'isNotOnField' by 'isOnDesk'

# 2.4.28

- enh: TranslateContext: allow to translate many keys (string[])
- fix: Force ngx-quicklink to 0.3.0

# 2.4.31

- enh: Add JsonUtils.parseFile()

# 2.4.33

- enh: Add AppPropertiesForm.length

# 2.4.48

- fix: Fix highlight pipe (used by autocomplete field)

# 2.4.50

- enh: Add type 'enums' for AppFormField

# 2.4.54

- enh: Use NavController by default, instead of Angular router. This will use the default animation style of the OS

# 2.4.55

- fix: Editor: Disable animation, when reloading same page after saving

# 2.4.58

- enh: Add storage explorer (with log preview)
- enh: Add debug service (to send debug data to server)
- enh: Add logging service

# 2.4.61

- enh: Add logger on network service

# 2.4.67

fix: Minor fix (add missing i18n)
fix: GeolocationUtils: add many useful functions, and detect Capacitor errors (from message)
fix: Fix some issues in storage explorer

# 2.4.74

enh: LocalSettingsService: save changes in local storage, when calling setProperty()

# 2.4.75

enh: SharedValidator: add a precision validator

# 2.4.79

fix: ImageGallery: fix add button icon (center alignement)

# 2.4.81

fix: AppToolbar: allow to use ion-segment in app-toolbar

# 2.4.82

enh: Migrate to Ionic 7
fix: Form field: show the clear button, when clearable=true, on types 'integer', 'double', 'string', 'date' and 'date-time'

# 2.4.82

enh: AppEntityEditor: add get/set for autoOpenNextTab

# 2.4.87

fix: AppEntityEditor: When reload the editor, force the fetch policy to 'network-only'

# 2.4.88

fix: AppInstallUpgradeCard: Installation APK link are not visible - fix issue [sumaris-app#445](https://gitlab.ifremer.fr/sih-public/sumaris/sumaris-app/-/issues/445)

# 2.4.88

enh: Add protected BaseEntityService.getLoadQueryNames()

# 2.4.89

fix: Fix Autocomplete searchbar value trigger, after ionic 7 update

# 2.4.90

fix: AppEntityEditor: when catch error in save(), set the selectedTabIndex=0 before calling setError()
This will allow subclasses to override the default selectedTabIndex after an error occur, inside the overridden setError()

# 2.4.91

enh: functions: allow to use sort(array) without the 'attribute' argument (e.g. allow to sort a string[])

# 2.4.95

fix: Platform: avoid error at startup, because of StatusBar in web mode
enh: MatBooleanField: display value when disabled, instead of 'empty'

# 2.4.112

enh: AppBadge: allow to set a text or number content

# 2.4.114

enh: Menu: allow to add sub menu item

# 2.4.158

enh: Environment: add useHash property to configure Angular router to use hash URL (need by web-ext)

# 2.5.0

- enh: Add token APP_USER_SETTINGS_OPTIONS of type UserSettingsOptions to add user properties table in AccountPage
- fix: MatBooleanField: in checkbox style, the placeholder can be shown as expected

# 2.6.0

- enh: Account: Add User tokens (table and modal)

# 2.6.23

- fix: Fix Configuration.getPropertyAsNumbers() when no value (avoid to get an array with an unique NaN value)

# 2.6.25

- enh: Upgrade to nodejs 18
- fix: Menu: hide spacer divider ion-label (hide the skeleton)

# 2.6.28

- fix: ImageGallery: Change image's title background color

# 2.6.31

- fix: ImageGallery: Add output event when after editing title

# 2.6.32

- fix: AppFormArray: Avoid an infinite loop, when calling resize(0) if options.allowEmptyArray=false
- fix: Table, Form, Editor: fix error when markAsLoaded() on closed BehaviorSubject
- fix: Table, Form, Editor: Make sure waitIdle() will stop, when component is destroyed (force default opts)

# 2.6.34

- enh: functions: add a static function `underscoreToChangeCase()`

# 2.6.35

- fix: Settings: Add type for property `OfflineFeature.filter`, then use it to in `LocalSettingsService.getOfflineFeatures()`

# 2.6.38

- fix: Fix mapGet pipe, when key is zero (0)

# 2.6.39

- enh: table: Add an input `style: 'table'|mat-table` into `<app-actions-column>`, to be usable inside a `<table mat-table>` (using `<td>`) or `<mat-table>` (using `<mat-cell>`)

# 2.8.0

- enh: `IAppForm<T>` : add a type `<T=any>`
- enh: `IAppForm` : add optional functions `setValue()`, `patchValue()`, `resetValue()` and `getValue()`
- fix: `AppForm` and `AppEditor`: Remove unused and deprecated properties `_loading`, `_$ready`, `_$loading`
- fix: `AppForm` : rename `_enable` as `enabled` to avoid confusion with `enable()`
- enh: Add abstract class `AppFormContainer` to manage many `IAppForm` - and use it as a super class of `AppEditor`
- enh: Add new pipes for SelectionModel :
  - `isSelected`: e.g. `selection | isSelected: row`,
  - `isEmptySelection`: e.g. `selection | isEmptySelection`
  - `isNotEmptySelection`: e.g. `selection | isNotEmptySelection`
  - `selectionLength`: e.g. `selection | selectionLength`,
  - `isMultipleSelection`: e.g. `selection | isMultipleSelection`,
- enh: Add new pipes for table :
  - `isAllSelected`: e.g. `table | isAllSelected`,
  - `isNotAllSelected`: e.g. `table | isNotAllSelected`

# 2.8.1

- enh: Add a pipe `badgeNumber` to limit badge content when > `99` (will display `99+`)
- enh: function setPropertyByPath() now return the input obj
- fix: Referential: fix `asObject()`
- enh: Add options:
  - `sumaris.defaultLatLongFormat.enabled` to show/hide default Lat/Lon setting in account page (default is true)
  - `sumaris.auth.api.token.scope.enabled` to show/hide scopes in API token table (default is false)
  - `sumaris.auth.api.token.scope.default` set the default scope for new API token, mandatory if `sumaris.auth.api.token.scope.enabled` if false (default is 'read_api')
- enh: Add AppRowField component: wrap an AppFormField into a table column
- enh: Add pipe `valueFormat` to format a value with a FormFieldDefinition (equivalent to pipe `propertyFormat`)
- fix: `UploadFileComponent` Refactored
- enh: Add new config options to override the form field background color (active, focus or disabled)
- enh: Add new pipe `booleanFormat`
- enh: Update pipe `propertyFormat` to use complex path (using `getPropertyByPath()`)
- enh: Add static functions `CsvUtils.getLocalizedEncoding()` and `CsvUtils.getLocalizedSeparator()`
- enh: Add static function `JsonUtils.getLocalizedEncoding()`

# 2.8.2

- enh: Function `getPropertyByPath` now handles the optional chaining operator `(?.)`
- enh: Add `AccountService.onWillLogout` emitter
- fix: Table: Call `emitRefresh()` instead of `onRefresh.emit()` to safely emit to an opened Observable

# 2.8.3

- enh: Add support of `<mat-hint>` in MatDateTime, MatDate, MatDateShort, MatAutocompleteField and MatLatLongField
- enh: Add `DateUtils.compare` to be able to sort dates (using Array `sort()`)
- enh: Add function `resizeArray(T[], size): T[]`
- fix: NamedFilter: Abort import if callback returns null or undefined
- fix: DataSource: Allow to refresh datasource (using `watchAll()`) when having dirty row

# 2.8.4

- enh: MatBooleanField: add `@Input() clearable` (default to `false`)
- fix: MatBooleanField: when resetting value, hide radio buttons

# 2.8.11

- fix: MatBooleanField: hide checkbox's placeholder when floatLabel=never

# 2.8.12

- enh: Pipe `referentialToString`: add new option `propertySeparator` to override the default ' - ' separator

# 2.8.13

- enh: AsyncTable: make `setFilter()` async

# 2.8.14

- enh: Upgrade to ngx-material-table 17.2.1 (add options to TableElement `delete()`, `cancelOrDelete()` and `confirmEditCreate()`)

# 2.9.0

- enh: Upgrade to Angular 17.3
- fix: Replace zone.js `setTimeout()`, by rx-angular zone-less
- fix: IFormControlPathTranslator : Rename interface IFormControlPathTranslator into IFormPathTranslator, and rename property `controlPathTranslator` into `pathTranslator`
- fix: Remove deprecated validator `SharedValidators.double` (was renamed into `SharedValidators.decimal`)
- fix: AppAsyncTable: re add `@Input() get filter`
- fix: AppTable: clear selection when opening a row (like AppAsyncTable)
- fix: MatAutocompleteField: Add `@Input() panelClass` (same as `class`)
- fix: MatAutocompleteField: Allow boolean inputs from string (using `@Input({transform: booleanAttribute})`)
- fix: MatAutocompleteField: add `panelWidth` and `panelClass` to `MatAutocompleteFieldConfig`

# 2.9.1

- fix: MatAutocompleteField: revert `applyImplicitValue` default value `true`
- fix: MatChipsField: fix usage of `suggestLengthThreshold`
- enh: MatChipsField: add `applyImplicitValue` (default: false)

# 2.9.2

- fix: Notification list: add an ion-text-wrap to the notification message

# 2.9.3

- fix: Home: Add a call to `markForCheck()` after removing a page history item

# 2.9.4

- fix: Form: reduce line height of row label (form-container > ion-row > ion-col > ion-label)

# 2.9.6

- fix: MatAutocompleteField: Remove animation in searchbar (bad icon position in iOS)

# 2.9.7

- fix: Form: fix field label position (form-container > ion-row > ion-col > ion-label)

# 2.9.8

- enh: Add AppFormUtils.filterErrorsByPrefix() and AppFormUtils.filterErrors()

# 2.9.13

- fix: Home: when removing a page history, force settings to update

# 2.9.17

- fix: MatSelectPanel: add `--min-width: fit-content` to class `mat-select-panel-fit-content`

# 2.9.20

- enh: NamedFilterSelector: add `filterCleared` event

# 2.9.22

- enh(deps): Minor update to Angular 17.3.12
- enh(theme): Dark theme: Move dark theme toggle into the settings form
- enh(theme): Dark theme: Fix toggle field style, in dark theme
- enh(settings): Add icons on each form fields
- fix(config): When saving the remote config, do not return to the editor config's inherited properties

# 2.9.23

- fix(boolean-field): fix click on radio button 'no', when field has no value

# 2.11.1

- enh(deps): Upgrade to apollo-angular 7.1.2 and apollo 3.11 (+ fix breaking changes in graphql.service.ts)
- fix(css): Dark theme: fix checkbox style, and autocomplete panel

# 2.11.2

- enh(app-text-form): Add new inputs `appearance` and `subscriptSizing`
- fix(css): Dark theme: fix style for outline field

# 2.11.3

- fix(app-text-form): Input `autoHeight` is now deprecated (use `autoSize` instead)
- enh(app-text-form): Add new inputs `autoSizeMinRows` and `autoSizeMaxRows`

# 2.11.7

- fix(css): Dark theme: fix style

# 2.11.8

- enh(form-error): Add options to `IFormPathTranslator.translateFormPath()`

# 2.12.0

- enh(form-error): Remove deprecated interface `IFormControlPathTranslator`

# 2.12.4

- fix(date): Update formControl (and datePicker) when textControl value changes, and clean text input by regexp
- fix(date-time): Keep control as invalid is time is empty
- enh(date-time): Add new `@Input() allowNoTime` to make time optional
- fix(lat-long): Fix deletion, when press delete key

# 2.12.7

- fix: addShortcut handler use `KeyboardEvent` instead of a simple 'EVent'

# 2.12.8

- enh: function `toNumber()` will now return the default value, when input is `NaN`

# 2.12.9

- fix(paginator): Fix paginator style on mobile screen (align to the left, and hide page size, like before the Angular 17 migration)

# 2.12.10

- fix(autocomplete): Compute the panel width if not set (in mobile) - workaround for an issue in mat-select panel

# 2.12.12

- fix(theme): add all dark colors from material theme
- fix(autocomplete): in mobile device, add a text-wrap and a max-height in mat-option

# 2.12.13

- fix(config): New option `sumaris.account.latLongFormat.enable` to replace the deprecated option `sumaris.defaultLatLongFormat.enabled` (key was not well named)

# 2.12.16

- fix(autocomplete): Reload items when `showAllOnFocus = true`
- fix(autocomplete): Use `??` operator, instead of `toBoolean()`, `toNumber()` etc.
- enh(autocomplete): Add option `applyImplicitValue` to config
- enh(pipe): add a `asBoolean` pipe, with an optional predicate function as option (e.g. to test any value)
- enh(account): Allow to change password, if auth token is `token` (will update the pubkey)
- fix(lat-long): Refactor component (remove maskito placeholder use)
- enh(table): Add new component `<nav-actions-column>`

# 2.12.19

- fix(nav-actions-column): Fix when inside a `AppAsyncTable`

# 2.12.26

- enh(app-async-table): declare property `readonly cd: ChangeDetectorRef`
- enh(app-async-table): implement `markForCheck()` and `detectCHanges()`
- enh(app-table): declare property `readonly cd: ChangeDetectorRef`
- fix(app-table): call `detectChanges()` inside `editRow()`, `addRowToTable()` and `toggleSelectRow()` - need by SUMARiS (e.g. samples tables)
- fix(app-table): `toggleSelectRow()` should not call `event.preventDefault()` otherwise checkbox will not be checked

# 2.12.27

- enh(app-table): implement `markForCheck()` and `detectChanges()`

# 2.12.29

- fix(new-token-modal): Add a full form and fix save issue

# 2.12.30

- enh(platform): Add copy to clipboard return state

# 2.12.29

- fix(new-token-modal): Add a full form and fix save issue

# 18.0.0

- enh(deps) Upgrade to Angular 18.2.8 and Ionic 8.3
- enh(deps) Remove zone.js (enable experimental zone-less config)
- enh(app-properties-form): Use an autocomplete field to select an option, instead of a simple mat-select
- enh(app-properties-form): Add `@Input() showHintKey: boolean` to show option key (has a hint)
- enh(network-service): Avoid to restart the service if peer has not changed
- enh(AppFormArray): allow to use AppFormArray on any type (and not only Entity has before)
- enh(AppFormUtils) add useful static functions to enable/disable control(s)
- enh(mat-autocomplete-field): add option `selectInputContentOnFocus` to option, to select the input content on focus in
- enh(app-named-filter-selector): Add `@Input() buttonsPosition: 'matSuffix'|'after'` to let user defined button position (inside the field, or after)
- fix(AppForm and AppFormContainer) log error using the child path (if defined using `addForm()`)
- fix(graphql) Fix pod error in JSON format, before parsing it (e.g. Oracle can return error on multiple lines)
- fix(nav-actions-column): Use `OnPush` changeDetection
- fix(app-form-field): Emit `(keyup.enter)` event, when field's type is `double`

# 18.0.5

- enh(mat-autocomplete-field):
  - Change type of `MatAutocompleteFieldConfig.suggestFn` to use SuggestFn<T, F> (allow to pass more options - e.g. used to resolve entity in AppPropertiesUtils)
  - Add `@Input() label`
  - Add `@Input() hideRequiredMarker`
- enh(app-form-field):
  - Add `@Input() hideRequiredMarker`
  - Fix the style when readonly and type `enum`
  - interface `FormFieldDefinition`: Add property `serializeAttribute?: string` (instead of using autocomplete.filer.joinAttribute)
  - add a static function `FormFieldDefinitionUtils.prepareDefinitions()` to resolve enum values, by `InjectionToken`
- enh(app-properties-form):
  - Entity/Entities are now resolved from helper class AppPropertiesUtils
  - Allow to change add button title
  - Resolve enum item, when using InjectionToken for values
- enh(shared) Add decorators `@RxStateRegister()` `@RxStateSelect()` and `@RxStateProperty()` to connect property to a `RxState`
- fix(properties-utils): Add `opts?: {keepOrphan?: boolean}` to `AppPropertiesUtils.arrayFromObject` to be able to remove property without definition (`keepOrphan` is `true` by default)
- fix(token-table): Fix error when no scopes defined (InjectToken `APP_USER_TOKEN_SCOPES` should be optional)

# 18.0.6

- fix(scss): set flex-wrap to nowrap
- enh(autocomplete-test): add test case with a button
- fix(logout) Logout should be done AFTER home redirection, because of cache clearing - see issue #5

# 18.0.7

- fix(hotkeys) Fix default platform control key ('meta' on iOS)

# 18.0.8

- fix(hotkeys) Avoid to open many help modal
- fix(hotkeys) Skip open help modal, if nothing to display
- fix(form-buttons-bar) Fix shortcuts for iOS
- fix(modal-toolbar) Fix shortcut for iOS

# 18.0.9

- fix(mat-latlong-field) Mark control as dirty, when text control changed
- fix(about) Fix missing markdown module, to display config description
- enh(about) Allow to override the "report an issue" link, using a config option `sumaris.reportIssue.url`

# 18.0.10

- enh(utils) Add static functions `isFirefox()`, `isSafari()` and `isEdge()` to test user agent
- enh(utils) Add static functions `EntityUtils.collectIds()` and `EntityUtils.splitById()`
- fix(utils) Mark function `EntityUtils.collectById()` as deprecated (in flavor of `EntityUtils.splitById()`)

# 18.1.0

- enh(deps) Upgrade to angular 18.2.11 and other deps
- fix(deps) move maildev library into dev dependencies

# 18.1.1

- enh(deps) Update angular-eslint to 18.4.0

# 18.1.2

- enh(deps) Revert to Ionic 7.8.6

# 18.1.3

- fix(settings) Add static function `isOnFieldMode()`
- fix(menu) Make unpinned menu works, when reload app (F5) with a pinned menu

# 18.1.4

- fix(tab) Keep default tab label style (e.g. min-width) when stretch tabs is enabled
- fix(tab) Reduce tab label padding, on small screen

# 18.1.7

- enh(AppFormArray) Add `clone()` function

# 18.2.0

- enh(base-entity-service) Allow opts.toEntity to be a function (e.g. to be able to transform each element, also when fetching more items)
- fix(graphql-service) Allow `opts.update` to use new Apollo type `MutationUpdaterFunction` (type `MutationUpdaterFn` is deprecated)

# 18.2.6

- fix(autocomplete-field) Fix arrow drop icon position, when mobile
- fix(autocomplete-field) Use desktop arrow drop icon, when multiple and desktop
- fix(BaseEntityService) simplify functions `fromObject()` and `fromObjects()` (move `toEntity` argument into `options`)
- enh(services) Allow `suggestFromArray()` to search using `?` as wildcard (=match one character) in the search text
- enh(HighlightPipe) Allow to use the character `?` as wildcard (=match one character) in the search text
- enh(functions) Allow `suggestFromStringArray()` to search using `?` as wildcard (=match one character) in the search text
- enh(shared) New helper class `RegExpUtils`

# 18.2.7

- enh(autocomplete-field) Add `@Input() selectInputContentOnFocusDelay` - workaround when input text selection is overridden by another event (e.g. see in SUMARiS, in the calendar component)

# 18.2.9

- enh(autocomplete-field): Add `@Input() reloadItemsOnFocus` : Reload items when focused, necessary if filtered items depends on an external source (e.g. see in SUMARiS, in the calendar component)

# 18.2.11

- enh(DateUtils): Add `DateUtils.diffAbs()` to compute duration between two dates

# 18.2.19

- enh(timepicker) MatDateTime : Migrate timepicker to new library Ngx Mat TimePicker (fix animation, cancel button, Angular 17 compatibility, etc.)

# 18.2.21

- enh(functions) Rename `selectInputContent` into `selectInputContentFromEvent`, and make `selectInputContent` that only use an `<input>` as argument
- enh(autocomplete-field) Add `@Input() clearInvalidValueOnBlur: boolean` to reset the field when typing invalid search text (no match or no many matches)
- fix(swipe-field) Fix swiper previous/next arrows

# 18.2.23

- enh(validators) add option skipIfNoTime to dateRange

# 18.2.24

- enh(pipe) add new pipe `isValidDate` with option `requiredTime` (to test date with noTime flag)

# 18.2.26

- enh(select-peer-modal) Allow to search on peers modal
- enh(select-peer-modal) Allow to select peer by features (aka programs) - should set `enableSelectPeerByFeature: true` in the environment token (disabled by default)

# 18.2.28

- fix(mat-boolean-field) Small refactoring + simplify blur detection, using standard Angular outputs
- enh(mat-latlong-field) Refactor the component, to use separate inputs (instead of using Maskito)
- fix(entity-store) setEntities() should mark all entities as dirty, when id mode is enabled (because an optimization in `persist()` that skip pristine entities)

# 18.2.29

- enh(validators) add opts to dateMaxDuration to skip date with NoTime
- fix(mat-boolean-field) Fix buttons layout (padding) to be same as sumaris QV pmfm buttons

# 18.2.30

- fix(forms) Fix error `TypeError: Cannot read properties of undefined (reading 'setControlEnabled')`

# 18.2.31

- fix(mat-latlong-field) Prevent NaN on component initialization

# 18.2.32

- fix(mat-latlong-field) Fix unit symbol font color

# 18.2.33

- enh(ReferentialUtils) add static function `ReferentialUtils.isNotDisabled()`

# 18.3.0

- fix(entity-editor) Fix page reload, when changing tab after the first save

# 18.3.9

- fix(image-gallery) add a padding at bottom, for ios
- enh(android) Upgrade compileSdkVersion to API 34 (required by the Google Play Store)
- enh(theme) Add css class 'visible-xxs'
- enh(dateDiffDuration) Add an option `opts.unit` to convert into a particular unit. If not defined, result will be like `x days HH:MM`

# 18.3.16

- fix(AppFormUtils) `disableControl()` now disable without reset value
- enh(AppFormUtils) Add `disableAndClearControl()` that can disable then clear the control

# 18.3.17

- fix(mat-chip-field) fix issue sumaris-app#844

# 18.3.18

- fix(mat-*-field) Avoid to display 'false' as input placeholder, when floatLabel="never"

# 18.3.19

- fix(mat-latlong-field) Fix height in theme.scss (Need to remove one extra pixel, because of the sign that use a mat-select)

# 18.3.20

- enh(directive) Add new directive to avoid prevent double click: Simply replace `(click)=...` by  `(throttledClick)=...`

# 18.3.21

- fix(table) Add a `@Input() openRowThrottleTime = 800` to prevent double click to open a row (see issue sumaris-app#864)

# 18.3.22

- fix(async-table) Add a `@Input() openRowThrottleTime = 800` to prevent double click to open a row

# 18.3.24

- fix(geolocation) Do not use Capacitor plugin, when using without capacitor

# 18.3.25

- fix(platform) Fix infinite loop on auto reload, when new version detected at startup (allow version using 'alpha', 'beta' or 'rc')

# 18.3.26

- fix(timepicker) Increase max-width for small screens

# 18.3.27

- fix(table) Use SortDirection type, for getter sortDirection
- fix(async-table) Use SortDirection type, for getter sortDirection

# 18.4.0

- enh(mat-latlong-field) Refactoring component, to use distinct `<input>`

# 18.4.4

- enh(settings) Add a button to access to the user account
- enh(menu) Change my account button color, when account page is open (add a 'selected' class, like for a selected menu item)

# 18.5.0

- enh(capacitor) Migrate to capacitor 6
- enh(deps) Migrate to Network plugin
- fix(properties-form) Selected option not visible, on mobile device - fix #16
- fix(settings) Refresh peerUrl control validation, when force offline
- fix(settings) Remove the help icon on small screen, on the 'My account' link
- enh(install-upgrade-card) Add installation links for electron (desktop)
- fix(account) Disabled all forms/tables, when page disabled (offline)
- enh(account) Display the offline card, when network is offline and the page disabled

# 18.5.1

- enh(account, settings) Avoid to quit or refresh the page, without saving (web browser)

# 18.5.4

- fix(entity-editor) Fix update route with tab params (URL was not updated sometimes)

# 18.5.5

- fix(audio) Avoid trying to use audio management, in iOS
- enh(install-upgrade-card) Add a debug Input, to debug install link url

# 18.5.6

- fix(platform) Avoid error on status bar, in iOS

# 18.5.7

- fix(platform) Hide splash screen on macOS
- enh(home) Add legal information by configuration
- enh(help-modal) Add error management from markdown

# 18.5.8

- enh(home) Add privacy policy links (using environment property or config option)

# 18.5.10

- fix(theme) Auto enable dark mode (if allow) until the user change it in the settings page

# 18.5.11

- fix(settings) Merge properties from account into properties from local storage - see sumaris-app#897

# 18.6.0

- enh(pipes) Add `replace` pipe
- enh(markdown) Rename `HelpModal` into `AppMarkdownModal`
- enh(markdown) Add new markdown components, that allow navigation with markdown relative links

# 18.6.9

- enh(public_api) Expert `NetworkUtils` and `VersionUtils`

# 18.6.12

- fix(markdown) Fix link click
- fix(theme) Set mat-expansion panel colors, to use ionic color

# 18.6.13

- enh(gallery): Allow to use textual button, instead of card button
- fix(gallery): Keep the given input mode (auto set only if empty)

# 18.6.14

- fix(markdown) Fix link click (avoid router resolution if target is a markdown file)

# 18.6.15

- fix(table) Avoid subscript part of a field, to be clicked, in table (event when row is disabled)

# 18.6.16

- enh(properties-form) Add `keyPanelClass` and `valuePanelClass`

# 18.6.19

- fix(autocomplete-field) Avoid too many blur events - see issue sumaris-app#837

# 18.6.22

- enh(styles) Avoid use selection of tab labels

# 18.6.23

- enh(PlatformService) Add `markAsBusy()` and `markAsNotBusy()` to display a backdrop (e.g. from the app.component.ts)

# 18.6.25

- enh(PlatformService) Make `showToast()` public (instead of protected)

# 18.6.26

- enh(PlatformService) Add `closeToast(id: number)`

# 18.6.27

- enh(pipes) Add pipe `arrayDistinct`

# 18.6.28

- enh(PrintService) Add `?print-id=` into created iframe URL
- enh(PrintService) Add function `getJobId(url?: string)` to retrieve the Job ID of the given URL

# 18.6.33

- enh(PrintService) Add function `isPrintingUrl(url?: string, queryParam: string = 'print-id')` to known if a URL is for printing

# 18.6.36

- enh(pipes) Add pipes `truncText` and `truncHtml`

# 18.6.37

- enh(SharedValidators) Add new validators `SharedValidators.validDateAllowNoTime` and `SharedValidators.validDateTime(requiredTime = true)`
- fix(SharedValidators) Make sure `SharedValidators.validDate` failed when no time set
- fix(mat-date-time) MatDateTime should have an error, when no time

# 18.6.39

- enh(pipes) Add some pipes for observables : `firstTrue`, `firstFalse`, `first`

# 18.6.42

- fix(theme) Redirect CSS variables `--mat-sidenav-*` to theme variables `--ion-*` (need for dark theme)

# 18.6.45

- enh(directive): Add a workaround for directive `cdkTextareaAutosize` to fix scroll behavior (see issue sumaris-app#950)

# 18.6.46

- fix(home) Hide the print icon when mobile, in the markdown modal (e.g. legacy info)

# 18.6.50

- fix(autocomplete-field) Avoid to display a suggest result, when a newer call is running

# 18.6.51

- fix(toast) Fix info/warning color, for dark theme
- fix(toast) Use text color for button color (can be override in app's custom theme)

# 18.6.56

- fix(menu) Refresh menu, when logout after a pod changed

# 18.6.57

- fix(rx-state) Merge annotations from sumaris-app shared annotation

# 18.6.58

- enh(EntityUtils) In functions `EntityUtils.isEmpty()` and `EntityUtils.isNotEmpty()`: the second argument `checkAttribute` is now 'id' by default
- enh(EntityUtils) Add `EntityUtils.hasNilId()`

# 18.6.59

- enh(EntityUtils) Add `EntityUtils.findById(items: E[], id: ID)`

# 18.6.60

- fix(toast) Add a default anchor to app-toolbar

# 18.6.61

- enh(DateUtils) add `durationToString()` and change duration pipe

# 18.6.62

- fix(toast) Add default icon when `options.type` is `warning` and `error`

# 18.6.63

- fix(autocomplete) Fix `class="min-width-medium"` option alignment - fix issue sumaris-app#943

# 18.6.65

- fix(theme) Fix timepicker modal color, for dark mode

# 18.6.66

- enh(home) Add a dark theme toggle button (is dark mode enable)

# 18.6.69

- enh(users) Add compact rows mode
- enh(users) Add columns updateDate and creationDate
- enh(users) Add a download to CSV button
- fix(deps) Replace deprecated @ionic-native by @awesome-cordova-plugins

# 18.6.71

- fix(latlong) Remove required validator on sub controls, required is false

# 18.7.0

- enh(account) Save account settings with only configured keys
- fix(mat-duration) Change the DEFAULT_MAX_DECIMALS to 7 and use DateUtils.durationToString() to get value

# 18.7.2

- fix(mat-duration) component emit dirty on writing

# 18.7.4

- enh(pipes) Add `RoundPipe`, Add parameter on `round` function
- fix(mat-duration) component emit valid and dirty
- enh(users) display label for organization in displayed columns
- enh(actions-column) Add input `cellTemplateStart`
- fix(mat-chips-field) Show the required marker, when required=true

# 18.7.5

- fix(AppFormContainer, AppEditor) Add `enabledSubject` observable

# 18.7.7

- enh(type) Add a new type `Observed<T>` to publish all properties

# 18.7.8

- enh(ComponentDirtyGuard, CanLeave) Add function `deactivate()`

# 18.7.9

- enh(ImageGallery) Add `@Input() cardTemplate` to override the default card template

# 18.7.10

- enh(table, async-table) Do not clear selection inside `clickRow()`, but only in `openRow()` before navigating to detail

# 18.7.11

- enh(table, async-table) Add `@Output() onClickRow`

# 18.7.12

- enh(animation) Add `expansionAnimation`

# 18.7.13

- fix(table, async-table) Don't threat undefined value emitted by `loadingSubject`

# 18.7.14

- enh(image-gallery) Open image URL using q query params (e.g. `?size=<large|medium|small>` - params name and values can be configured by inputs)

# 18.7.17

- fix(home) Inverse dark theme icon
- fix(pipes) Allow selection pipes for `AppTable` and `AppAsyncTable`

# 18.7.19

- enh(functions) Add function `interpolateString` to bind a message using given parameters

# 18.7.20

- enh(autocomplete-field) Allow to display favorites items in the dropdown panel, by using `@Input() favoriteItems: any[]`
- fix(functions) Fix runtime error in function `interpolateString`

# 18.7.20

- enh(autocomplete-field) Allow to toggle favorite

# 18.7.24

- fix(autocomplete-field) Avoid to display 'null' as field title (on mouse over)
- fix(autocomplete-field) Keep the favorite column visible, when favoriteItems is empty but `toggleFavorite` output is observed

# 18.7.25

- enh(autocomplete-field) Add `@Output() openedChange: EventEmitter<boolean>` to listen panel open/close state

# 18.7.27

- enh(mat-boolean-field) Add `@Input() autofocus`

# 18.7.29

- enh(pipes) Change pipe `asBoolean: <mapperFn>` to allow `mapperFn` to have more arguments (e.g. `| asBoolean: mapperFn: 'arg2'`)

# 18.8.0

- enh(auth-guard,home) Allow to define a custom `defaultRoute` in `Environment`

# 18.8.3

- enh(image-service) Add more options to the `add()` function (e.g. `source: 'PROMPT'|'CAMERA'|'GALLERY'`)

# 18.8.8

- fix(form) `AppForm.getFormError()` now uses the provided form or this.form
- fix(table.pipes) Fix error when table's datasource subscription, when table not found (e.g. on pipe `isAllSelected`)

# 18.8.10

- fix(autocomplete-field) Fix error in `reloadItems()` when mobile but matSelect is not used

# 18.8.11

- enh(types) Add type `OmitFunctions` to get only properties of a class, without functions (e.g. from an Entity class)

# 18.8.15

- enh(EntityUtils) Use more precise parametrized types in function `EntityUtils.cleanIdAndUpdateDate` 

# 18.8.16

- enh(EntityUtils) Add function `EntityUtils.fromObject(source, dataType)`

# 18.8.17

- enh(file.utils) In function `FileUtils.writeTextToFile` set attributes `lastModifiedDate` and `filename` in the generated Blob object

# 18.8.20

- fix(pipes) Fix `mapGet` pipe to return `undefined` (or `defaultValue`) instead of `null`, when no input value, or no key.
  This is important, to have same behavior as `propertyGet` pipe
- enh(functions) Add `numberOrNilAttribute` that allow `undefined|null` input (without convert into `NaN`)

# 18.8.21

- fix(functions) Fix `underscoreToChangeCase()`
  - e.g. `underscoreToChangeCase('my_property')` => `myProperty` instead of `my,Property`
  - Add unit test, to have same behavior as the Java implementation (SUMARiS Pod)

# 18.8.23

- fix(table, async-table) Fix duplicateRows() to allow `skipProperties` on complex paths
- fix(table, async-table) Fix duplicateRows() to use deep clone (using `row.cloneData()` instead of `{...row.currentData}`)

# 18.8.24

- fix(table, async-table) duplicateRows() - rename `options.skipProperties` into `options.excludedProperties`
- enh(table, async-table) duplicateRows() - add `options.includedProperties`
- enh(csv-utils) Add more options to CsvUtils.exportToCsv() (e.g. `options.includedProperties`, `options.excludedProperties`)

# 18.8.26

- enh(image-gallery) Add `@Input() showAddToolbarButton: boolean`

# 18.9.0

- enh(deps) Upgrade to `ngx-material-table@18.0.0` (build for Angular 18)
- enh(functions) Add `Beans.clone()` for deep cloning a JS object

# 18.9.1

- enh(EntitiesTableDataSource) Add more options in function `waitIdle(opts: number | ({ debounceTimeMs?: number } & FirstOptions))`
- enh(IEntitiesService) Add readonly property `defaultFetchPolicy: WatchQueryFetchPolicy` (need by `EntitiesTableDataSource.waitIdle()`)

# 18.9.2

- fix(EntitiesTableDataSource) Fix function `waitIdle()`
- fix(EntitiesTableDataSource) Remove some deprecated feature: `close()` and `serviceOptions`

# 18.9.3

- fix(AppTable, AppAsyncTable) Make sure to call table.markAsDirty() when the editing row is dirty

# 18.9.4

- fix(MatBooleanField) Fix alignment when floatLabel="never", on styles 'checkbox' and 'button'
- fix(MatBooleanField) Exclude more blur internal events (e.g. when the hidden input is the target)
- fix(AppFormField) Make sure to pass readonly input to all internal input/field (was ignored in style 'enums' and 'color')

# 18.9.5

- fix(functions) Fix `round()` when passing a string value, instead of a number (avoid to return `NaN`)

# 18.9.6

- enh(pipes) Add `MapPipe` to convert an object into another (e.g. `object | map: converToSomething` or `object$ | map: converToSomething | async`)

# 18.9.7

- fix(platform-service) Avoid toggling dark mode, when window's media match 'print'

# 18.10.0

- enh(deps) Upgrade to ngx-material-table@18.0.1 (allow to create new row with insertAt=0)

# 18.10.1

- fix(theme) Avoid a add the dark CSS class, when on screen media

# 18.10.2

- fix(PersonUtils) `PersonUtils.personToString()` should always display lastname then firstName (even when `opts.withDepartment=true`)

# 18.10.3

- fix(GraphqlService) Make sure cache data is an array, before trying to update it (to avoid console error when cache data has been corrupted)

# 18.10.4

- fix(GraphqlService) Fix addManyToQueryCache() when cacheable query result size exceed (cached data were corrupted when trying to update the cached total)

# 18.10.7

- fix(autocomplete-field) Add `@Input() colSizes = [undefined, 'auto']` to fix layout when using `matAfter`

# 18.10.8

- fix(chips-field) Add `@Input() colSizes = [undefined, 'auto']` to fix layout when using `matAfter`

# 18.10.11

- enh(array.pipe) Add `arrayFindByProperty` pipe

# 18.10.12

- enh(table) Add a setter for `sortActive` property

# 18.10.13

- enh(array.pipe) Add arraySort pipe

# 18.10.14

- enh(functions) Add function `formatNumber(value: number: opts): string`

# 18.10.22

- enh(SharedFormGroupValidators) Add more options to `requiredIf` (allow to set the `isEmpty` function)

# 18.10.23

- fix(mat-chips-field) Fix error color

# 18.10.25

- enh(arrays.pipe.ts) move SplitArrayInChunksPipe from sumaris to sumaris-ngx-component
- enh(function.ts) add utils function to split array in chunks

# 18.10.28

- enh(gallery) Allow to pass options to `gallery.add()` (e.g. `{multiple: true; autoHideDropArea: true}`)

# 18.11.0

- fix(inputs) `canHaveFocus()`: rename option `excludeEmptyInput` into `isEmpty` (confusing naming)
- enh(inputs) `canHaveFocus()`: add `isNotEmpty` option

# 18.12.2

- enh(MapPipe) Allow to pass arguments to the `map` pipe (e.g. `value | map: converToSomething: 'arg2'` will call `converToSomething(value, 'arg2'`)

# 18.12.3

- enh(AppTable, AppAsyncTable) FUnction `trackFn()` can now return `any` (instead of `number`) - like the official Angular `TrackByFunction`

# 18.12.4

- enh(deps) Fix version of webpack
- enh(deps) Upgrade ngx-material-table into 18.0.4

# 18.12.5

- enh(functions) Add function `UrlUtils.appendQueryParams()` to append q queryParams (as a map) to an url

# 18.12.6

- enh(functions) Allow `UrlUtils.appendQueryParams()` to get url as `string | any[]`

# 18.12.7

- enh(forms) Add `AppFormUtils.setFormErrors()` to apply errors into a form group and it children (inverse function as `getFormErrors()`))
- enh(forms) Allow `AppFormUtils.getControlFromPath()` to works with any control (FormGroup, FormArray or simple control)

# 18.12.8

- enh(tree-item-entity) Add `TreeItemEntityUtils.fromObjectArrayAsTrees()` to convert array of objects, into trees (return root items)

# 18.12.11

- enh(entities-table-datasource) When saving, do not call `markAsLoading()`

# 18.12.12

- fix(form-container) Avoid to add a child form twice (add a test before adding a child form)

# 18.12.13

- fix(AppTable, AppAsyncTable) When press 'escape' on an edited row will cancel row, if the row is still pristine, instead of trying to confirm the row (see `escapeEditingRow()`)

# 18.13.0

- enh(home) Allow to show notification icons, in the home page, using a new APP_HOME_CONFIG token
- enh(user-event) Add a modal to show notifications (e.g. for mobile)

# 18.14.15

- enh(network) Add fetch function to load JSON file
- enh(social) Add a feed component, to display news from a service (e.g. Json Feed or Discourse)

# 18.15.0

- enh(pipes) Add pipe `arrayMap` to transform each map's items with a function
- enh(pipes) Add pipe `mapTo` to transform any object with a function

# 18.15.3
- enh(mat-date-time) Add @Output focus and blur event emitter
- enh(mat-date-time) In desktop, attach the timepicker to the hour input
- fix(mat-date-time) In desktop, attach the date picker at the end of the day input

# 18.16.0

- enh(about) Add pod and angular build date to identify the exact version running

# 18.16.3

- enh(network) Add version in HTTP headers: GraphQL and HTTP requests now include X-App-Version and X-App-Name headers for better server-side identification

# 18.16.4

- enh(environment) Add `Environment.sendAppVersionHeaders` property to enable `X-App-*` headers (false by default)

# 18.16.5

- enh(forms, form-array) Ar optional argument `options?: {emitEvent?: boolean}` to `removeValueInArray()`, `AppFormArray.removeAt()` (and other functions like `clearAt()`)

# 18.16.6
- enh(shared) Add static function `truncateHtml(html, maxLength)`
- enh(shared) Add new pipe `trancateHtml`

# 18.16.7
- enh(graphql-service) Move connectionParams into the network service 
- enh(network-service) Add header `Authorization` when fetching resource on pod

# 18.16.8

- enh(feed) Allow to open feed details
- enh(feed) Display content_text as Markdown, when no html found in the feed item

# 18.17.0

- enh(feed) Allow to edit/delete feed item, if user is the author or an admin

# 18.17.4
- fix(table) Fix opening row details from the current route to ./{id} or ./new - see issue sumaris-app#1214

# 18.18.0
- fix(LocalSettingsService) Call `LocalSettingsService.onChange` when calling `savePageSettings()`
- enh(LocalSettingsService) Add a `LocalSettingsService.onStoredLocally` event emitter, when settings have been well stored locally
- enh(AppPropertiesForm) Add a toolbar (hidden by default) with an options menu to import/export properties from/to a CSV file

# 18.18.1
- enh(LocalSettingsService) Allow skipping onChange event on pages settings, with a new property `LocalSettingsOptions.skipEmitChangeKeys` (injection token)  

# 18.18.2
- fix(SCSS) Fix `.stack-modal` class

# 18.18.5
- fix(types) Rename `Function` into `SimpleFunction` to avoid confusion with Typescript standard type `Function`
  - Old custom type `Function` still exists, but mark as `deprecacted` 
- enh(RxState) Add new type `Statefull<T>` to allow type check, when using `@RxStateProperty()` or `@RxStateSelect()`
- fix(gallery) Add a call to `markForCheck()` when receiving new rows

# 18.18.6
- fix(person) Fix `personToString()` when lastName or firstName is nil

# 18.18.8
- Revert last 18.18.7 changes

# 18.18.9
- enh(pipe) Add new pipe `dateFrom` to display delta with another date.
  Example: `<date> | dateFrom: <anotherDate>: opts`

# 18.18.10
- enh(entity-service) Add typed options to `save()` and `delete()`

# 18.18.11
- enh(entity-editor) Pass typed options to `save()` and `delete()`

# 18.18.11
- fix(deps) Add the module `AppTextFormModule` into the `AppFormModule` (instead of the SharedModule)

# 18.18.14
- enh(pipes) Allow pipe `arrayDistinct` to work with a property path (.e.g `property.subProperty`), and not only a simple property.

# 18.18.15
- enh(pipes) Allow pipe `arraySort` to work with property paths (.e.g `property.subProperty` or `['propA', 'propB']`), and not only a compare function

# 18.18.16
- enh(pipes) Add pipe `arraySlice` to get sub array

# 18.18.17
- enh(form-field) Fix disabled when setting from `@Input` 

# 18.18.18
- enh(form-field) Allow to inject <mat-error> into a custom form field

# 18.18.23
- fix(form-field) Fix unexpected behavior when overriding Input disabled (revert changes done in 18.18.17) 

# 18.18.23-2
- fix(date) Emit change when the field is cleared (`mat-date-field` & `mat-date-time-field`) 

# 18.18.24
- fix(pipes) Fix `isSingleSelection`

# 18.18.26
- fix(mat-duration) Use input placeholder (instead of `COMMON.TIME`)
- fix(mat-latlong) Make sure the default sign is used when no value is set (fix sumaris-app#1305)

# 18.18.27 - beta
- enh(rx-state) Add new decorator `@RxStateOutput() property: Observable<R>` for output binding

# 18.18.38
- enh(type) Replace all `declare type` by `type`
- fix(rx-state) Fix `@RxStateOutput()` decorator

# 18.19.0
- enh(form) Add `AppForm.markAsNotReady()`
- enh(table) Add `AppTable.markAsNotReady()` and `AppAsyncTable.markAsNotReady()`

# 18.19.2
- enh(image-gallery) CSS: Added sticky toolbar on scroll

# 18.19.2
- enh(pipes) Add `referentialsToString(any[])`
 
# 18.19.4
- enh(network) Add an option `peerFiler` to `NetworkService.showSelectPeerModal()` (e.g. to exclude the current peer)

# 18.19.5
- fix(forms) When trying to resize an AppFormArray with allowEmptyArray=false, avoid infinite loop - closes [sumaris-app#1389](https://gitlab.ifremer.fr/sih-public/sumaris/sumaris-app/-/issues/1389)

# 18.19.7
- enh(app-toolbar) Add a slot=title
- enh(app-modal-toolbar) Add a slot=title 

# 18.20.0
- enh(menu) Allow badge on menu items
- enh(home) Allow badge on home buttons

# 18.21.0
- enh(BaseEntityService) Allow to refetch mutable watch queries, when deleting

# 18.21.3
- fix(validators) `SharedFormGroupValidators.requiredIf` will now throw an exception if the control not exists (instead of an undefined property exception) 

# 18.21.5
- fix(GeoLocationUtils) rename GeoLocationUtils.computeDistanceInMiles into GeoLocationUtils.computeDistanceInNauticalMiles

# 18.21.7
- fix(AccountService) Clean remote settings keys, before using it (fix issue sumaris-app#1458)
- fix(AppTable) add a `takeUntil()` on the `datasource.watchAll()` observable 

# 18.21.8
- fix(AppTable, AppAsyncTable) Remove unused function `AppTable.startsWithUpperCase` (already exists as a static function) 

# 18.21.10
- enh(AppFormUtils) Add `AppFormUtils.setControlRequired(control, required)`

# 18.21.12
- enh(types) Type `FilterFn<T>` now accept a second argument `index?: number` (useful when using inside a `array.filter()`)

# 18.21.13
- fix(menu) set display on ion-item when has specific rules applied (e.g hidden-xs...) 

# 18.21.14
- fix(menu) Hide menu footer (about) on mobile device

# 18.22.0
- enh(EntityFilter) Add logical combinators properties: `or`, `and` and `not`   

# 18.22.5
- enh(functions) Add utilities in `shared/functions.ts`:
  `compareValues`, `compareValuesDesc`, `propertyPathComparator`, `propertyComparator`, `propertiesPathComparator`, `multiPropertyComparator`

# 18.22.6
- enh(functions) Change the third (optional) argument of `propertyComparator(key: string, direction, nullsAtFirst?: boolean)`.
  (remove `defaultValue`) 
- enh(functions) Change the third (optional) argument of `propertyPathComparator(key: string, direction, nullsAtFirst?: boolean)`.
  (remove `defaultValue`)
- enh(functions) Change the third (optional) argument of `propertiesPathComparator(keys: string[], direction, nullsAtFirst?: boolean)`.
  (remove `defaultValues`)

# 18.22.7
- fix(rx-state-decorators) Change naming convention of @RxStateOutput , to allow the suffix `Change` and not only `Changes`

# 18.22.8
- enh(actions-column) Add `@Input() showPendingSPiner = true`

# 18.22.9
- enh(table, async-table) Add options `{focusColumn?: string}` to `AppTable.confirmAndForward()` and `AppTable.confirmAndBackward()` 

# 18.22.10
- enh(table, async-table) Add options `{focusColumn?: string}` to `AppTable.confirmAndAdd()` 

# 18.22.11
- enh(functions) Allow `AppFormUtils.getControlFromPath()` to return null without error (add a new argument `failIfMissing: boolean = false`)

# 18.22.12
- enh(types) Change type `SuggestFn<T, F, R>` (add the return type `R`)  

# 18.22.12
- enh(table, async-table) Add a getter: `get saving()` 

# 18.22.14
- enh(observables) Add utility function `firstPromise(Observable<T>): Promise<T>`
- enh(StartableService,StartableObservableService) Add optional argument `options` to ready functions: `ready(options?: FirstOptions)`

# 18.22.15
- enh(InMemoryDataService) Add `setOptions()` to allow to pass options after the constructor

# 18.22.16
- enh(InMemoryDataService) Add `get visibleCount()` (to replace deprecated `get count()`)

# 18.22.17
- enh(InMemoryDataService) Add `get totalCount()` ( = `visibleCount + hiddenCount`)

# 18.22.18
- fix(forms) Fix `adaptValueToControl` to works with type controls (and not only with `UntypedFormGroup`, `UntypedFormArray`, and `UntypedFormControl`) 

# 18.22.19
- enh(async-table) Add `confirmAndUp()` ro enable navigation using event like `<input (keyup.arrowUp)="confirmAndUp(event, row)">` 

# 18.22.21
- enh(functions) Add utility function `toLoadData()` to extract data from a `LoadResult<T> | T[]` (e.g. from a `suggestFn` result type)

# 18.22.22
- enh(table) Catch error on the dataSource.watchAll(), to be able to refresh the table after a graphql error
- enh(table) Add options to emitRefresh() and doRefresh()

# 18.22.23
- fix(form-error-adapter) Minor fix, when accessing to control error content

# 18.22.24
- merge branche v18.18.x (changes of 18.18.23-2)
- fix(date) Emit change when the field is cleared (`mat-date-field` & `mat-date-time-field`) 

# 18.22.25
- enh(dates) Add options to `fromDateISOString(value: any, options: {undefinedIfInvalid?: boolean; strict?: boolean; requiredTime?: boolean} = {undefinedIfInvalid: true, strict: false, requiredTime: false}`
- enh(validators) SharedValidators.validDateTime will now detect invalid Moment date (e.g. parsing input string '0/0/0') 

# 18.22.26
- fix(mat-autocomplete-field) Avoid template error, when an item is null (when accessing the property 'classList')

# 18.22.27
- fix(regexps) Revert changes in SPECIAL_CHARACTERS_REGEXP - reintroduce the last '/g' as string.replace(RegExp) is not stateful

# 18.22.28
- enh(android) Upgrade to SDK API 35
- fix(android) Fix StatusBar style, for Android 15

## 18.23.1

- enh: Migration vers Capacitor 7
  - Mise à jour des dépendances `@capacitor/*` en version `~7.0.0`.
  - Android: `minSdkVersion` relevé à 24 (Capacitor 7).
  - Android: mise à jour de l'Android Gradle Plugin à `8.5.2` et du Gradle Wrapper à `8.7`.
  - Aucun changement fonctionnel attendu, mais un resync des plateformes est requis: `npm i && npx cap sync`.
- enh(mobile) Fix edge-to-edge issue

# 18.23.3
- fix(ios) Not need to call Edge2Edge plugin in iOS devices

# 18.23.11
- fix(account) Manage additional field on type entities (e.g. a list of programs)

# 18.23.12
- enh(account) Add avatar edition (enable by a config option)

# 18.23.14
- enh(account-service) Add service options (new injection token), to be able to change graphql default queries 

# 18.23.16
- enh(entity-metadata-component) Fix avatar image background color

# 18.23.18
- enh(entity-metadata-component) Increase text size of the recorder department, when recorder person is empty

# 18.23.19
- fix(theme) Fix status style

# 18.23.20
- fix(account-page) Cannot change the avatar when the network is offline
- enh(account-page) Limit the avatar size to 200px (by default - can be changed by config option) 

# 18.23.21
- enh(platform-service) Add `PlatformService.addDeepLinkListener()` to manage App deep links (mobile app only)

# 18.23.26
- enh(inputs) `focusNextInput()` ignore readonly input 

# 18.23.27
- fix(mat-chips-field) Set default `colSizes` if undefined
- fix(mat-autocomplete-field) Set default `colSizes` if undefined
- fix(mat-autocomplete-field) Simplify detection of `required` default value, using `control.hasValidator()` 

# 18.23.28
- fix(menu) Fix footer show/hide, depending on screen resolution, and not if mobile

# 18.23.29
- fix(scss) Fix style in tables, for class `cdk-visssualy-hidden` on cell or footer-cell 

# 18.23.30
- enh(image-gallery) Add public function `setViewMode()`

# 18.23.31
- enh(image-service) Mobile web: open camera by default, when `style` is undefined or `auto` (the Capacitor Camera plugin is now compatible with web)  

# 18.23.33
- enh(table) Add getters for `totalRowCount` and `visibleRowCount` properties (subclasses can override. e.g. to exclude divider rows)
- enh(async-table) Add getters for `totalRowCount` and `visibleRowCount` properties (subclasses can override. e.g. to exclude divider rows)

# 18.23.34
- enh(Resizable) Better usability
- enh(cell-selection) Add cell selection service and directives

# 18.23.35
- enh(validators) Add static function `SharedValidators.copyError(sourceCOntrol, targetControl, errorCode)`

# 18.23.37
- enh(mat-chips-field) Add input `showChips` to allow hiding them

# 18.23.38
- enh(table, async-table) Add option `messageKey` to `deleteRows()` and `askDeleteConfirmation()` to allow customizing the confirmation message

# 18.23.39
- enh(table, async-table) Add option `messageKey` to `deleteSelection()` to allow customizing the confirmation message

# 18.23.41
- enh(functions) Add static function `mergeObjectsWithoutUndefined` to merge object without undefined

# 18.23.42
- fix(network-service) Fix error `Cannot read properties of null (reading 'url')` when watching peer$ when service if not ready yet

# 18.23.43
- enh(functions) Add `collectByPropertyPath()` to split an array into a map of array, group by property path

# 18.23.45
- fix(mat-autocomplete-field) Fix issue when control has been clear, but continue to show the old title
- enh(mat-autocomplete-field) Add new outputs `arrowUp`, `arrowDown` and `enter`
- enh(mat-date-time-field) Allow matSuffix into mat-date-time-field, and add inputs `hourMinWidth` and `hourMaxWidth` to set the width of the hour part
- enh(tree-item-entity.model) Add static function `TreeItemEntityUtils.findById()`

# 18.23.47
- enh(CanLeave) Add new argument `navigateForward` to function `CanLeave.deactivate(navigateForward: boolean)`. This allow to known if the navigation is forward or backward.

# 18.23.48
- enh(functions) Add static function `assignSkipUndefined` to assign objects without undefined properties

# 18.23.50
- enh(AutoTooltipDirective) Adding possibility to use MatTooltip with AutoTooltipDirective instead of title
- enh(material) Add MatTooltip possibility for all components using `SHOW_TOOLTIP` injection token

# 18.23.53
- enh(editor) add `opts.openTabIndex` to `saveIfDirtyAndConfirm()`

# 18.23.54
- fix(ResizableDirective) use cursor position by the event to resize column (Mantis#69006)

# 18.23.55
- enh(CellSelection) Refactoring service and directives. The CellIdentifierDirective can be used without a service.

# 18.23.56
- enh(MatLatLongFieldInput) the pattern input changes will dynamically update the component

# 18.23.57
- fix(ResizableDirective) Change width constraint

# 18.23.58
- fix(FormErrorTranslator) when calling `translateError('message', 'A already translated string')` will now return `A already translated string`

## 18.23.60

- enh(home): Allow injectable toolbar buttons via `APP_HOME_TOOLBAR_BUTTONS` token, with icon, title, color, and action support
- enh(home): Filter toolbar buttons using `MenuItems.checkIfVisible()`, same as central page buttons (profile, config, login state)

## 18.23.61
- enh(home): Support badge display on injectable toolbar buttons via `matBadge` directive, using `MenuItem.$badge` and `$badgeColor`
- enh(menu): Update `ifProperty` handling to support negation logic for configuration checks

## 18.23.64
- enh(shared): Add new pipe `changeCaseToUnderscore` to convert camelCase to underscore_case in templates

## 18.23.65
- enh(date-time-field): Fix datetime value emission on invalid datetime (closes sumaris-app#1863)

## 18.23.68
- enh(theme): add responsive `min-width` utility classes for select panel - Allow to use panelClass with :
  * mobile/desktop: `min-width-fit-content`, `min-width-medium`, `min-width-large`, `min-width-xlarge` , `min-width-80vw` : 
  * mobile only: `mat-select-panel-fit-content`|`mat-select-panel-medium-size`|`mat-select-panel-large-size`|`mat-select-panel-xlarge-size`|`mat-select-panel-80vw-size`

## 18.23.69
- enh(theme): MatAutocompleteField: add panelClass style `full-width`, as an alias of `full-size`

## 18.23.70
- enh(functions) Add static function `deepMergeSkipUndefined` (and deprecate `assignSkipUndefined`)
  * Prevents infinite loop (fix issue sumaris-app#1929)

## 18.23.72
- fix(functions) Fix logic in the static function `deepMergeSkipUndefined`

## 18.24.0
- enh(form-container) Allow to call `addForm()`, `addForms()` and `removeForm()` with a FormGroup argument (it will be wrapped into AppForm)

## 18.24.1
- enh(editor) Fix error in `saveDirtyChildren()` error, when having no children
