spiderly 19.11.1 → 19.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36,6 +36,8 @@ The generated service receives `EntityServiceDependencies` (bundles `IApplicatio
36
36
 
37
37
  Step 2 runs **before** step 3 — this means `OnBeforeSave` can set server-generated fields (e.g., `[UIDoNotGenerate]` + `[Required]` properties like hashes or computed values) before DTO validation runs.
38
38
 
39
+ This same pipeline also runs **per child** when children are saved inline through a parent's `[UIOrderedOneToMany]` list — the parent's step 7 delegates each kept child to the child's own MainUIForm save, so a child entity's hooks (including steps 2 and 8) fire regardless of which page saved it. The child save runs with authorization off (`authorizeUpdate`/`authorizeInsert` = false): the parent's save carries the authorization decision.
40
+
39
41
  On the **update path**, the entity load before step 5b goes through `GetInstanceAsync(id, dto.Version)` — it throws a localized `ConcurrencyException` (HTTP 409) when the client's `Version` is stale, and the whole flow runs in a transaction. Generated saves are therefore protected by optimistic concurrency out of the box; don't add manual race-condition guards to hooks for plain concurrent edits. Mechanism and limits: `entity-design` skill, *Base Classes* (`BusinessObject` `Version`).
40
42
 
41
43
  **Signatures:**
@@ -699,12 +699,6 @@ function ReflectProp(target, propertyKey) {
699
699
  const props = Reflect.getMetadata(PROPS_KEY, target) || [];
700
700
  Reflect.defineMetadata(PROPS_KEY, [...props, propertyKey], target);
701
701
  }
702
- const primitiveArrayTypes = [
703
- 'Namebook[]',
704
- 'number[]',
705
- 'Date[]',
706
- 'string[]',
707
- ];
708
702
  function getImageDimensions(file) {
709
703
  return new Promise((resolve) => {
710
704
  const img = new Image();
@@ -2339,11 +2333,12 @@ class BaseFormService {
2339
2333
  }
2340
2334
  }
2341
2335
  else {
2336
+ const isArrayValued = propSchema.type.endsWith('[]');
2342
2337
  // HACK: Because on the backend id type is not nullable on generated DTOs, we need to do this, it's ugly hack and we should make it better.
2343
2338
  if (formControlName === 'id' && !propInitialValue) {
2344
2339
  propInitialValue = 0;
2345
2340
  }
2346
- if (propSchema.type.endsWith('[]') && propInitialValue == null) {
2341
+ if (isArrayValued && propInitialValue == null) {
2347
2342
  propInitialValue = [];
2348
2343
  }
2349
2344
  if (existingControl instanceof SpiderlyFormControl) {
@@ -2351,10 +2346,16 @@ class BaseFormService {
2351
2346
  }
2352
2347
  else {
2353
2348
  let control;
2349
+ // Array-valued controls (multiselect/multiautocomplete selections) must
2350
+ // commit on change: their value mutates through overlay/chip interactions
2351
+ // that can end without the control ever having focus (PrimeNG's chip
2352
+ // remove stops propagation before the host focuses its hidden input), so
2353
+ // a blur-deferred commit leaves the deselect pending forever and the save
2354
+ // reads the OLD selection while the UI already shows the item removed.
2354
2355
  if (updateOnChangeControls?.includes(formControlName) ||
2355
2356
  (formControlName.endsWith('Id') && formControlName.length > 2) ||
2356
2357
  propSchema.type === 'Date' ||
2357
- propSchema.type === 'Namebook[]') {
2358
+ isArrayValued) {
2358
2359
  control = new SpiderlyFormControl(propInitialValue, {
2359
2360
  updateOn: 'change',
2360
2361
  });
@@ -5537,5 +5538,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImpo
5537
5538
  * Generated bundle index. Do not edit.
5538
5539
  */
5539
5540
 
5540
- export { Action, AllClickEvent, ApiErrorCodes, ApiSecurityService, AppSidebarComponent, AuthCardComponent, AuthGuard, AuthResult, AuthResultWithCookies, AuthServiceBase, BaseAutocompleteControl, BaseControl, BaseDropdownControl, BaseEntity, BaseFormComponent, BaseFormService, CardSkeletonComponent, Codebook, Column, ConfigServiceBase, DEFAULT_EXTERNAL_PROVIDER_ICONS, ExternalLoginComponent, ExternalProvider, ExternalProviderPublic, Filter, FilterRule, FilterSortMeta, FooterComponent, IndexCardComponent, InfoCardComponent, InitCompanyAuthDialogDetails, InitTopBarData, IsAuthorizedForSaveEvent, LastMenuIconIndexClicked, LayoutServiceBase, LazyLoadSelectedIdsResult, Login, LoginVerificationComponent, LoginVerificationToken, MatchModeCodes, MenuChangeEvent, MenuitemComponent, Namebook, NotAuthGuard, NotFoundComponent, PROPS_KEY, PaginatedResult, PanelBodyComponent, PanelFooterComponent, PanelHeaderComponent, PrimengOption, ProfileAvatarComponent, ReflectProp, RefreshTokenRequest, RequiredComponent, RowClickEvent, SecurityPermissionCodes, SendLoginVerificationEmailResult, SideMenuTopBarComponent, SidebarMenuComponent, SimpleSaveResult, SpiderlyAutocompleteComponent, SpiderlyButtonBaseComponent, SpiderlyButtonComponent, SpiderlyCalendarComponent, SpiderlyCardComponent, SpiderlyCheckboxComponent, SpiderlyColorPickerComponent, SpiderlyControlsModule, SpiderlyDataTableActionsDirective, SpiderlyDataTableComponent, SpiderlyDataViewComponent, SpiderlyDeleteConfirmationComponent, SpiderlyDropdownComponent, SpiderlyEditorComponent, SpiderlyErrorHandler, SpiderlyFileComponent, SpiderlyFileSelectEvent, SpiderlyFormArray, SpiderlyFormControl, SpiderlyFormGroup, SpiderlyLayoutComponent, SpiderlyLoginComponent, SpiderlyMarkdownComponent, SpiderlyMessageService, SpiderlyMultiAutocompleteComponent, SpiderlyMultiSelectComponent, SpiderlyNumberComponent, SpiderlyPanelComponent, SpiderlyPanelsModule, SpiderlyPasswordComponent, SpiderlyReturnButtonComponent, SpiderlySplitButtonComponent, SpiderlyTab, SpiderlyTemplateTypeDirective, SpiderlyTextareaComponent, SpiderlyTextboxComponent, SpiderlyTranslocoLoader, TopBarComponent, UserBase, UserRole, ValidatorAbstractService, VerificationTokenRequest, VerificationTypeCodes, VerificationWrapperComponent, adjustColor, authInitializer, capitalizeFirstChar, deleteAction, exportListToExcel, firstCharToUpper, getFileNameFromContentDisposition, getHtmlImgDisplayString64, getImageDimensions, getMimeTypeForFileName, getMonth, getParentUrl, getPrimengAutocompleteCodebookOptions, getPrimengAutocompleteNamebookOptions, getPrimengDropdownCodebookOptions, getPrimengDropdownNamebookOptions, getPrimengNamebookOptions, httpLoadingInterceptor, isExcelFileType, isFileImageType, isNullOrEmpty, jsonHttpInterceptor, jwtInterceptor, kebabToTitleCase, nameOf, nameof, parseDateOnlyLocal, primitiveArrayTypes, pushAction, saveResponseAsFile, selectedTab, singleOrDefault, splitPascalCase, toCommaSeparatedString, unauthorizedInterceptor, validatePrecisionScale };
5541
+ export { Action, AllClickEvent, ApiErrorCodes, ApiSecurityService, AppSidebarComponent, AuthCardComponent, AuthGuard, AuthResult, AuthResultWithCookies, AuthServiceBase, BaseAutocompleteControl, BaseControl, BaseDropdownControl, BaseEntity, BaseFormComponent, BaseFormService, CardSkeletonComponent, Codebook, Column, ConfigServiceBase, DEFAULT_EXTERNAL_PROVIDER_ICONS, ExternalLoginComponent, ExternalProvider, ExternalProviderPublic, Filter, FilterRule, FilterSortMeta, FooterComponent, IndexCardComponent, InfoCardComponent, InitCompanyAuthDialogDetails, InitTopBarData, IsAuthorizedForSaveEvent, LastMenuIconIndexClicked, LayoutServiceBase, LazyLoadSelectedIdsResult, Login, LoginVerificationComponent, LoginVerificationToken, MatchModeCodes, MenuChangeEvent, MenuitemComponent, Namebook, NotAuthGuard, NotFoundComponent, PROPS_KEY, PaginatedResult, PanelBodyComponent, PanelFooterComponent, PanelHeaderComponent, PrimengOption, ProfileAvatarComponent, ReflectProp, RefreshTokenRequest, RequiredComponent, RowClickEvent, SecurityPermissionCodes, SendLoginVerificationEmailResult, SideMenuTopBarComponent, SidebarMenuComponent, SimpleSaveResult, SpiderlyAutocompleteComponent, SpiderlyButtonBaseComponent, SpiderlyButtonComponent, SpiderlyCalendarComponent, SpiderlyCardComponent, SpiderlyCheckboxComponent, SpiderlyColorPickerComponent, SpiderlyControlsModule, SpiderlyDataTableActionsDirective, SpiderlyDataTableComponent, SpiderlyDataViewComponent, SpiderlyDeleteConfirmationComponent, SpiderlyDropdownComponent, SpiderlyEditorComponent, SpiderlyErrorHandler, SpiderlyFileComponent, SpiderlyFileSelectEvent, SpiderlyFormArray, SpiderlyFormControl, SpiderlyFormGroup, SpiderlyLayoutComponent, SpiderlyLoginComponent, SpiderlyMarkdownComponent, SpiderlyMessageService, SpiderlyMultiAutocompleteComponent, SpiderlyMultiSelectComponent, SpiderlyNumberComponent, SpiderlyPanelComponent, SpiderlyPanelsModule, SpiderlyPasswordComponent, SpiderlyReturnButtonComponent, SpiderlySplitButtonComponent, SpiderlyTab, SpiderlyTemplateTypeDirective, SpiderlyTextareaComponent, SpiderlyTextboxComponent, SpiderlyTranslocoLoader, TopBarComponent, UserBase, UserRole, ValidatorAbstractService, VerificationTokenRequest, VerificationTypeCodes, VerificationWrapperComponent, adjustColor, authInitializer, capitalizeFirstChar, deleteAction, exportListToExcel, firstCharToUpper, getFileNameFromContentDisposition, getHtmlImgDisplayString64, getImageDimensions, getMimeTypeForFileName, getMonth, getParentUrl, getPrimengAutocompleteCodebookOptions, getPrimengAutocompleteNamebookOptions, getPrimengDropdownCodebookOptions, getPrimengDropdownNamebookOptions, getPrimengNamebookOptions, httpLoadingInterceptor, isExcelFileType, isFileImageType, isNullOrEmpty, jsonHttpInterceptor, jwtInterceptor, kebabToTitleCase, nameOf, nameof, parseDateOnlyLocal, pushAction, saveResponseAsFile, selectedTab, singleOrDefault, splitPascalCase, toCommaSeparatedString, unauthorizedInterceptor, validatePrecisionScale };
5541
5542
  //# sourceMappingURL=spiderly.mjs.map