@elasticias/screens 1.0.49 → 1.0.51

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.51",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^21.0.0",
6
6
  "@angular/core": "^21.0.0",
@@ -185,6 +185,34 @@ 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: translate raw values in the change-history box. Maps an
190
+ * audited field path to the static reference list holding its codes, e.g.
191
+ * `{ status: 'boutique_order_status' }` (key `status` also covers the
192
+ * from/to of status-change entries). The lists are loaded with the screen
193
+ * (no need to repeat them in DETAILS_STATIC_LISTS); bind
194
+ * `<ef-change-history [entries]="auditEntries()" [valueLists]="auditValueLists()" />`.
195
+ * Unset keeps raw values.
196
+ */
197
+ AUDIT_VALUE_LISTS?: Record<string, string>;
198
+ /**
199
+ * Detail screens: business-rule codes (422 `ruleCode`) meaning "the record
200
+ * changed since you loaded it", e.g. ERP `['BR_SO_0123']`. A failed update
201
+ * with one of them offers a "reload" confirm; accepting
202
+ * reloads the record and drops the unsaved edits. The app must define the
203
+ * i18n keys `ef_stale_reload` (button), `ef_stale_reload_confirm` (message,
204
+ * say that unsaved edits are lost) and `ef_stale_reload_header`.
205
+ */
206
+ STALE_RULE_CODES?: string[];
207
+ /**
208
+ * Detail screens: after a successful in-place update (not a create or
209
+ * duplicate) refresh the record, so server-owned fields such as a
210
+ * concurrency revision are current for the next save. Uses the update
211
+ * response when it is the saved record (an object whose `id` is the
212
+ * screen's entity id), otherwise one `get(id)`. Change history reloads
213
+ * either way. Default false: the record is left as edited.
214
+ */
215
+ RELOAD_AFTER_SAVE?: boolean;
188
216
  /**
189
217
  * Report screens (AbstractReportScreenV2): starting period preset for the
190
218
  * screen's ef-datepicker-advanced. Unset → 'last_30_days'.
@@ -904,6 +932,13 @@ declare abstract class AbstractSearchScreenV2<TItem = any> extends AbstractScree
904
932
  * criteria to cache on success so revisits can restore.
905
933
  */
906
934
  search(): void;
935
+ /**
936
+ * Hook for a screen whose search returns more than a page of rows (counts,
937
+ * facets, a summary): called with the raw response after `items` and
938
+ * `totalCount` are set, for the latest issued search only. A stale or
939
+ * failed search never reaches it.
940
+ */
941
+ protected afterSearch(_result: unknown): void;
907
942
  setSearchText(text: string): void;
908
943
  setPage(pageNumber: number, pageSize?: number): void;
909
944
  setSort(field: string, direction?: string): void;
@@ -1058,6 +1093,14 @@ interface EfDetailToolbarAction {
1058
1093
  * context with no write state (no `canWrite`) leaves the action shown.
1059
1094
  */
1060
1095
  requiresWrite?: boolean;
1096
+ /**
1097
+ * On a phone, when the actions overflow into the menu, this one stays
1098
+ * inline beside Save (a screen's next step, which should never be one
1099
+ * tap deeper). Filtering by `visible`, `permission` and `requiresWrite`
1100
+ * still applies first. Ignored on tablet and desktop, which never
1101
+ * overflow. Keep it to one action: each one kept takes row width.
1102
+ */
1103
+ keepInView?: boolean;
1061
1104
  /** Click handler. */
1062
1105
  command?: () => void;
1063
1106
  }
@@ -1130,6 +1173,12 @@ declare abstract class AbstractDetailScreenV2<TItem extends object = any> extend
1130
1173
  * `<ef-change-history [entries]="auditEntries()" />`.
1131
1174
  */
1132
1175
  readonly auditEntries: _angular_core.WritableSignal<any[]>;
1176
+ /**
1177
+ * Field path to reference items for `<ef-change-history [valueLists]>`,
1178
+ * built from `ScreenConfig.AUDIT_VALUE_LISTS` and the already-loaded static
1179
+ * lists. Empty (raw values) when the config does not declare any.
1180
+ */
1181
+ readonly auditValueLists: _angular_core.Signal<Record<string, any[]>>;
1133
1182
  /** Loaded entity. Empty object when on `/details` (create mode). */
1134
1183
  readonly entity: _angular_core.WritableSignal<TItem>;
1135
1184
  /** PK from the route param, or `null` on `/details` (new). */
@@ -1208,6 +1257,8 @@ declare abstract class AbstractDetailScreenV2<TItem extends object = any> extend
1208
1257
  patchEntity(patch: Partial<TItem>): void;
1209
1258
  /** Fetch the entity from the backend and populate `entity`. */
1210
1259
  loadData(): void;
1260
+ /** Install a fetched (or save-returned) record as the current entity. */
1261
+ private applyLoaded;
1211
1262
  /**
1212
1263
  * Persist the entity. Routes to `service.create()` when in new
1213
1264
  * or duplicate mode, `service.update(id, entity)` when editing.
@@ -1218,6 +1269,23 @@ declare abstract class AbstractDetailScreenV2<TItem extends object = any> extend
1218
1269
  * anyway.
1219
1270
  */
1220
1271
  save(): void;
1272
+ /**
1273
+ * True when a failed save means the record changed since it was loaded:
1274
+ * a refusal whose `ruleCode` is in the config's `STALE_RULE_CODES`. A bare
1275
+ * 409 is a duplicate (e.g. a slug already taken), not a stale record, so
1276
+ * it never offers a reload. Only a refusal
1277
+ * the app's interceptor already toasted counts, so the user is never
1278
+ * told twice.
1279
+ */
1280
+ protected isStaleSave(error: unknown): boolean;
1281
+ /**
1282
+ * Asks, in an accessible confirm dialog (focus trapped, Escape cancels),
1283
+ * whether to reload the record. Accepting discards the unsaved edits,
1284
+ * and the message says so. The refusal itself was already toasted.
1285
+ * App keys: `ef_stale_reload` (button), `ef_stale_reload_confirm`
1286
+ * (message) and optionally `ef_stale_reload_header`.
1287
+ */
1288
+ protected offerStaleReload(): void;
1221
1289
  /**
1222
1290
  * Soft-delete-then-navigate-back. Confirms with the user first.
1223
1291
  */