@elasticias/screens 1.0.49 → 1.0.50

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elasticias/screens",
3
- "version": "1.0.49",
3
+ "version": "1.0.50",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^21.0.0",
6
6
  "@angular/core": "^21.0.0",
@@ -185,6 +185,24 @@ declare abstract class ScreenConfig {
185
185
  * to opt out. Must match the backend IAuditable.AuditEntityType (e.g. 'Client').
186
186
  */
187
187
  AUDIT_ENTITY_TYPE?: string;
188
+ /**
189
+ * Detail screens: business-rule codes (422 `ruleCode`) meaning "the record
190
+ * changed since you loaded it", e.g. ERP `['BR_SO_0123']`. A failed update
191
+ * with one of them offers a "reload" confirm; accepting
192
+ * reloads the record and drops the unsaved edits. The app must define the
193
+ * i18n keys `ef_stale_reload` (button), `ef_stale_reload_confirm` (message,
194
+ * say that unsaved edits are lost) and `ef_stale_reload_header`.
195
+ */
196
+ STALE_RULE_CODES?: string[];
197
+ /**
198
+ * Detail screens: after a successful in-place update (not a create or
199
+ * duplicate) refresh the record, so server-owned fields such as a
200
+ * concurrency revision are current for the next save. Uses the update
201
+ * response when it is the saved record (an object whose `id` is the
202
+ * screen's entity id), otherwise one `get(id)`. Change history reloads
203
+ * either way. Default false: the record is left as edited.
204
+ */
205
+ RELOAD_AFTER_SAVE?: boolean;
188
206
  /**
189
207
  * Report screens (AbstractReportScreenV2): starting period preset for the
190
208
  * screen's ef-datepicker-advanced. Unset → 'last_30_days'.
@@ -904,6 +922,13 @@ declare abstract class AbstractSearchScreenV2<TItem = any> extends AbstractScree
904
922
  * criteria to cache on success so revisits can restore.
905
923
  */
906
924
  search(): void;
925
+ /**
926
+ * Hook for a screen whose search returns more than a page of rows (counts,
927
+ * facets, a summary): called with the raw response after `items` and
928
+ * `totalCount` are set, for the latest issued search only. A stale or
929
+ * failed search never reaches it.
930
+ */
931
+ protected afterSearch(_result: unknown): void;
907
932
  setSearchText(text: string): void;
908
933
  setPage(pageNumber: number, pageSize?: number): void;
909
934
  setSort(field: string, direction?: string): void;
@@ -1058,6 +1083,14 @@ interface EfDetailToolbarAction {
1058
1083
  * context with no write state (no `canWrite`) leaves the action shown.
1059
1084
  */
1060
1085
  requiresWrite?: boolean;
1086
+ /**
1087
+ * On a phone, when the actions overflow into the menu, this one stays
1088
+ * inline beside Save (a screen's next step, which should never be one
1089
+ * tap deeper). Filtering by `visible`, `permission` and `requiresWrite`
1090
+ * still applies first. Ignored on tablet and desktop, which never
1091
+ * overflow. Keep it to one action: each one kept takes row width.
1092
+ */
1093
+ keepInView?: boolean;
1061
1094
  /** Click handler. */
1062
1095
  command?: () => void;
1063
1096
  }
@@ -1208,6 +1241,8 @@ declare abstract class AbstractDetailScreenV2<TItem extends object = any> extend
1208
1241
  patchEntity(patch: Partial<TItem>): void;
1209
1242
  /** Fetch the entity from the backend and populate `entity`. */
1210
1243
  loadData(): void;
1244
+ /** Install a fetched (or save-returned) record as the current entity. */
1245
+ private applyLoaded;
1211
1246
  /**
1212
1247
  * Persist the entity. Routes to `service.create()` when in new
1213
1248
  * or duplicate mode, `service.update(id, entity)` when editing.
@@ -1218,6 +1253,23 @@ declare abstract class AbstractDetailScreenV2<TItem extends object = any> extend
1218
1253
  * anyway.
1219
1254
  */
1220
1255
  save(): void;
1256
+ /**
1257
+ * True when a failed save means the record changed since it was loaded:
1258
+ * a refusal whose `ruleCode` is in the config's `STALE_RULE_CODES`. A bare
1259
+ * 409 is a duplicate (e.g. a slug already taken), not a stale record, so
1260
+ * it never offers a reload. Only a refusal
1261
+ * the app's interceptor already toasted counts, so the user is never
1262
+ * told twice.
1263
+ */
1264
+ protected isStaleSave(error: unknown): boolean;
1265
+ /**
1266
+ * Asks, in an accessible confirm dialog (focus trapped, Escape cancels),
1267
+ * whether to reload the record. Accepting discards the unsaved edits,
1268
+ * and the message says so. The refusal itself was already toasted.
1269
+ * App keys: `ef_stale_reload` (button), `ef_stale_reload_confirm`
1270
+ * (message) and optionally `ef_stale_reload_header`.
1271
+ */
1272
+ protected offerStaleReload(): void;
1221
1273
  /**
1222
1274
  * Soft-delete-then-navigate-back. Confirms with the user first.
1223
1275
  */