@mintplayer/ng-spark 22.27.0 → 22.28.1

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.
Files changed (36) hide show
  1. package/fesm2022/mintplayer-ng-spark-grid.mjs +5 -9
  2. package/fesm2022/mintplayer-ng-spark-grid.mjs.map +1 -1
  3. package/fesm2022/mintplayer-ng-spark-history.mjs +1 -1
  4. package/fesm2022/mintplayer-ng-spark-history.mjs.map +1 -1
  5. package/fesm2022/mintplayer-ng-spark-models.mjs +3 -3
  6. package/fesm2022/mintplayer-ng-spark-models.mjs.map +1 -1
  7. package/fesm2022/mintplayer-ng-spark-moderation.mjs +1 -1
  8. package/fesm2022/mintplayer-ng-spark-moderation.mjs.map +1 -1
  9. package/fesm2022/mintplayer-ng-spark-pipes.mjs +5 -2
  10. package/fesm2022/mintplayer-ng-spark-pipes.mjs.map +1 -1
  11. package/fesm2022/mintplayer-ng-spark-po-create.mjs +13 -5
  12. package/fesm2022/mintplayer-ng-spark-po-create.mjs.map +1 -1
  13. package/fesm2022/mintplayer-ng-spark-po-detail.mjs +2 -1
  14. package/fesm2022/mintplayer-ng-spark-po-detail.mjs.map +1 -1
  15. package/fesm2022/mintplayer-ng-spark-po-edit.mjs +38 -13
  16. package/fesm2022/mintplayer-ng-spark-po-edit.mjs.map +1 -1
  17. package/fesm2022/mintplayer-ng-spark-po-form.mjs +3 -3
  18. package/fesm2022/mintplayer-ng-spark-po-form.mjs.map +1 -1
  19. package/fesm2022/mintplayer-ng-spark-query-list.mjs +28 -9
  20. package/fesm2022/mintplayer-ng-spark-query-list.mjs.map +1 -1
  21. package/fesm2022/mintplayer-ng-spark-renderers.mjs +2 -1
  22. package/fesm2022/mintplayer-ng-spark-renderers.mjs.map +1 -1
  23. package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs +0 -1
  24. package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs.map +1 -1
  25. package/fesm2022/mintplayer-ng-spark-services.mjs +3 -2
  26. package/fesm2022/mintplayer-ng-spark-services.mjs.map +1 -1
  27. package/package.json +1 -1
  28. package/types/mintplayer-ng-spark-grid.d.ts +3 -14
  29. package/types/mintplayer-ng-spark-models.d.ts +13 -13
  30. package/types/mintplayer-ng-spark-moderation.d.ts +8 -4
  31. package/types/mintplayer-ng-spark-pipes.d.ts +3 -0
  32. package/types/mintplayer-ng-spark-po-create.d.ts +4 -0
  33. package/types/mintplayer-ng-spark-po-detail.d.ts +4 -0
  34. package/types/mintplayer-ng-spark-po-edit.d.ts +16 -0
  35. package/types/mintplayer-ng-spark-po-form.d.ts +1 -0
  36. package/types/mintplayer-ng-spark-services.d.ts +5 -1
@@ -66,7 +66,7 @@ i0.ɵɵngDeclareClassMetadata({
66
66
  }]
67
67
  });
68
68
  function revisionAttributes(entityType) {
69
- return (entityType?.attributes ?? []).filter((a) => a.isVisible && hasShowedOnFlag(a.showedOn, ShowedOn.PersistentObject)).sort((a, b) => a.order - b.order);
69
+ return (entityType?.attributes ?? []).filter((a) => hasShowedOnFlag(a.showedOn, ShowedOn.PersistentObject)).sort((a, b) => a.order - b.order);
70
70
  }
71
71
  function diffRevision(entityType, revision, current) {
72
72
  if (!revision || !current) return [];
@@ -1 +1 @@
1
- {"version":3,"file":"mintplayer-ng-spark-history.mjs","names":[],"sources":["../../history/src/spark-history.service.ts","../../history/src/revision-diff.ts","../../history/src/spark-po-history.component.ts","../../history/src/spark-po-history.component.html","../../history/src/spark-history-panel.component.ts","../../history/src/provide-spark-history.ts"],"sourcesContent":["import { inject, Injectable } from '@angular/core';\nimport { PersistentObject, SparkDeletedFilter } from '@mintplayer/ng-spark/models';\nimport { SparkService } from '@mintplayer/ng-spark/services';\n\n/** One revision of a row, newest first (`MintPlayer.Spark.History.SparkRevision`). */\nexport interface SparkRevision {\n changeVector: string;\n /** When the revision was written (ISO 8601 with offset); null when the server does not know. */\n lastModified?: string | null;\n /** Who wrote it — an id (D8: audit fields hold ids only). */\n userId?: string | null;\n /** The id resolved to a name at read time, when the app registered an `IHistoryUserNameResolver`. */\n userName?: string | null;\n /** The revision RavenDB writes when the document is deleted (a purge-free hard delete). */\n isDeleteRevision?: boolean;\n /** The revision the document currently is. Reverting to it changes nothing. */\n isCurrent?: boolean;\n}\n\nexport interface SparkRevisionListOptions {\n skip?: number;\n /** Server default 50, at most 200. */\n take?: number;\n /** `include` / `only` to read the history of a soft-deleted row (`ViewDeleted` holders only). */\n deleted?: SparkDeletedFilter | null;\n}\n\n/**\n * Client for the History package's endpoints (`MintPlayer.Spark.History`, #460 T1). Every read is\n * gated on the CURRENT row (a row the caller can no longer see has no readable history) and on\n * `History/T`; old revisions come back redacted like the live object.\n */\n@Injectable({ providedIn: 'root' })\nexport class SparkHistoryService {\n private readonly spark = inject(SparkService);\n\n /** `POST /spark/po/revisions` → the row's revisions, newest first. */\n list(type: string, id: string, options?: SparkRevisionListOptions): Promise<SparkRevision[]> {\n return this.spark.postEnvelope<SparkRevision[]>('/po/revisions', {\n objectTypeId: type,\n id,\n ...(options?.skip ? { skip: options.skip } : {}),\n ...(options?.take ? { take: options.take } : {}),\n ...(options?.deleted && options.deleted !== 'exclude' ? { deleted: options.deleted } : {}),\n });\n }\n\n /** `POST /spark/po/revision` → the revision as a read-only, redacted persistent object. */\n get(type: string, id: string, changeVector: string, options?: { deleted?: SparkDeletedFilter | null }): Promise<PersistentObject> {\n return this.spark.postEnvelope<PersistentObject>('/po/revision', {\n objectTypeId: type,\n id,\n changeVector,\n ...(options?.deleted && options.deleted !== 'exclude' ? { deleted: options.deleted } : {}),\n });\n }\n\n /**\n * `POST /spark/po/revert` → the reverted row. Requires `History/T`, `Revert/T` and `Edit/T`; saved\n * through the normal pipeline. 403 = the revert is disabled for this row, 409 = the row changed\n * since it was loaded, 400 = an interceptor refused (e.g. the row is locked).\n */\n revert(type: string, id: string, changeVector: string): Promise<PersistentObject> {\n return this.spark.postEnvelope<PersistentObject>('/po/revert', { objectTypeId: type, id, changeVector });\n }\n}\n","import { EntityAttributeDefinition, EntityType, PersistentObject, PersistentObjectAttribute, ShowedOn, comparableValue, hasShowedOnFlag } from '@mintplayer/ng-spark/models';\n\n/** One attribute that differs between a revision and the current object. */\nexport interface SparkRevisionChange {\n attribute: EntityAttributeDefinition;\n /** Absent when the attribute did not exist on that side (added or removed since). */\n revision: PersistentObjectAttribute | undefined;\n current: PersistentObjectAttribute | undefined;\n}\n\n/**\n * The attributes a revision is compared on: the ones the detail page shows, in its order. Redacted\n * attributes are simply absent from what the server sends, so they never appear as a difference.\n */\nexport function revisionAttributes(entityType: EntityType | null | undefined): EntityAttributeDefinition[] {\n return (entityType?.attributes ?? [])\n .filter(a => a.isVisible && hasShowedOnFlag(a.showedOn, ShowedOn.PersistentObject))\n .sort((a, b) => a.order - b.order);\n}\n\n// The normalizer lives in models since po-edit's conflict merge needs the same answer; re-exported\n// here so History's public surface is unchanged.\nexport { comparableValue };\n\n/** The shown attributes whose content differs between `revision` and `current`, in display order. */\nexport function diffRevision(\n entityType: EntityType | null | undefined,\n revision: PersistentObject | null | undefined,\n current: PersistentObject | null | undefined,\n): SparkRevisionChange[] {\n if (!revision || !current) return [];\n const changes: SparkRevisionChange[] = [];\n for (const attribute of revisionAttributes(entityType)) {\n const r = revision.attributes.find(a => a.name === attribute.name);\n const c = current.attributes.find(a => a.name === attribute.name);\n if (comparableValue(r) !== comparableValue(c)) changes.push({ attribute, revision: r, current: c });\n }\n return changes;\n}\n","import { ChangeDetectionStrategy, Component, computed, effect, inject, input, output, signal, untracked } from '@angular/core';\nimport { DatePipe } from '@angular/common';\nimport { HttpErrorResponse } from '@angular/common/http';\nimport { Color } from '@mintplayer/ng-bootstrap';\nimport { BsAlertComponent } from '@mintplayer/ng-bootstrap/alert';\nimport { BsBadgeComponent } from '@mintplayer/ng-bootstrap/badge';\nimport { BsSpinnerComponent } from '@mintplayer/ng-bootstrap/spinner';\nimport { BsTableComponent } from '@mintplayer/ng-bootstrap/table';\nimport { SparkGridCellComponent, SparkGridRenderers } from '@mintplayer/ng-spark/grid';\nimport { QueryCellValuePipe, QueryReferenceChipsPipe, ReferenceChip, ResolveTranslationPipe, TranslateKeyPipe } from '@mintplayer/ng-spark/pipes';\nimport { cellValue } from '@mintplayer/ng-spark/renderers';\nimport { SparkLanguageService } from '@mintplayer/ng-spark/services';\nimport {\n EntityAttributeDefinition, EntityPermissions, EntityType, LookupReference, PersistentObject, QueryColumn, QueryResultItem,\n SparkDeletedFilter, valueFor,\n} from '@mintplayer/ng-spark/models';\nimport { SparkHistoryService, SparkRevision } from './spark-history.service';\nimport { diffRevision, revisionAttributes } from './revision-diff';\n\ntype HistoryView = 'view' | 'diff';\n\n/** One attribute of one object, ready for `<spark-grid-cell>`. */\ninterface HistoryCell {\n column: QueryColumn;\n display: unknown;\n rendererValue: unknown;\n chips: ReferenceChip[];\n}\n\nconst cellValuePipe = new QueryCellValuePipe();\nconst chipsPipe = new QueryReferenceChipsPipe();\n\n/**\n * A row's revision history (#460, History package): the revision list, a read-only view of one\n * revision, its field diff against the current object, and Revert.\n *\n * Standalone — bind it anywhere — and also what the History detail panel\n * (`provideSparkHistory()`) renders on every routed detail page.\n *\n * Rights come from `permissions`: nothing is listed without `canViewHistory`, and Revert is offered\n * only with `canRevert` (the server's `Revert/T` together with `Edit/T`), never for the current\n * revision, a delete revision, or a row opened from the recycle bin (Revert saves through the live\n * pipeline, which does not see a deleted row). The server enforces all of it again.\n */\n@Component({\n selector: 'spark-po-history',\n imports: [DatePipe, BsAlertComponent, BsBadgeComponent, BsSpinnerComponent, BsTableComponent, SparkGridCellComponent, ResolveTranslationPipe, TranslateKeyPipe],\n templateUrl: './spark-po-history.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SparkPoHistoryComponent {\n private readonly history = inject(SparkHistoryService);\n protected readonly lang = inject(SparkLanguageService);\n\n /** Entity type id or alias, as the endpoints take it. */\n type = input.required<string>();\n id = input.required<string>();\n entityType = input.required<EntityType>();\n /** The object as it is now — the right-hand side of every diff. */\n current = input<PersistentObject | null>(null);\n permissions = input<EntityPermissions | null>(null);\n /** The mode the row was opened with (`only` = from the recycle bin). */\n deleted = input<SparkDeletedFilter | null>(null);\n /** Rows per request (server default 50, at most 200). */\n pageSize = input(50);\n\n /** Emitted with the saved object after a successful Revert. */\n reverted = output<PersistentObject>();\n\n protected readonly colors = Color;\n protected readonly revisions = signal<SparkRevision[]>([]);\n protected readonly loading = signal(false);\n protected readonly hasMore = signal(false);\n protected readonly error = signal<string | null>(null);\n\n protected readonly selected = signal<SparkRevision | null>(null);\n protected readonly selectedObject = signal<PersistentObject | null>(null);\n protected readonly selectedLoading = signal(false);\n protected readonly view = signal<HistoryView>('diff');\n protected readonly reverting = signal(false);\n\n protected readonly canView = computed(() => this.permissions()?.canViewHistory === true);\n\n protected readonly attributes = computed(() => revisionAttributes(this.entityType()));\n protected readonly changes = computed(() => diffRevision(this.entityType(), this.selectedObject(), this.current()));\n\n private readonly gridRenderers = inject(SparkGridRenderers);\n /** Lookup-reference labels for the shown attributes, so a lookup value reads as its label. */\n private readonly lookupOptions = signal<Record<string, LookupReference>>({});\n\n /**\n * The read-only view: every shown attribute of the selected revision, rendered by the same\n * `<spark-grid-cell>` (and custom renderers) as a query grid — a reference as its label, a date in\n * the viewer's culture and zone, a boolean as a checkbox — instead of the raw wire value.\n */\n protected readonly viewCells = computed(() => {\n const revision = this.selectedObject();\n return revision ? this.attributes().map(a => ({ attribute: a, cell: this.cell(a, revision) })) : [];\n });\n\n /** The diff rows, both sides rendered like {@link viewCells}. */\n protected readonly changeCells = computed(() => {\n const revision = this.selectedObject();\n const current = this.current();\n return this.changes().map(change => ({\n change,\n old: this.cell(change.attribute, revision),\n now: this.cell(change.attribute, current),\n }));\n });\n\n protected readonly canRevertSelected = computed(() => {\n const revision = this.selected();\n return !!revision\n && this.permissions()?.canRevert === true\n && this.deleted() !== 'only'\n && !revision.isCurrent\n && !revision.isDeleteRevision\n && !!this.selectedObject();\n });\n\n constructor() {\n effect(() => {\n const attributes = this.attributes();\n untracked(() => {\n this.gridRenderers.loadLookupOptions(attributes).then(o => this.lookupOptions.set(o), () => this.lookupOptions.set({}));\n });\n });\n\n // (Re)load the list when the row, its mode or the rights change. A revert emits a new `current`\n // but keeps the id, so it is not in this effect; `refresh()` reloads explicitly.\n effect(() => {\n const type = this.type();\n const id = this.id();\n const deleted = this.deleted();\n const allowed = this.canView();\n untracked(() => {\n this.clearSelection();\n this.revisions.set([]);\n if (allowed && type && id) void this.loadPage(type, id, deleted, 0);\n });\n });\n }\n\n /** Reloads the list from the top, dropping the selection. */\n async refresh(): Promise<void> {\n this.clearSelection();\n this.revisions.set([]);\n await this.loadPage(this.type(), this.id(), this.deleted(), 0);\n }\n\n async loadMore(): Promise<void> {\n await this.loadPage(this.type(), this.id(), this.deleted(), this.revisions().length);\n }\n\n private async loadPage(type: string, id: string, deleted: SparkDeletedFilter | null, skip: number): Promise<void> {\n this.loading.set(true);\n this.error.set(null);\n try {\n const take = this.pageSize();\n const page = await this.history.list(type, id, { skip, take, deleted });\n // A response for a row the inputs have moved away from is dropped.\n if (type !== this.type() || id !== this.id()) return;\n this.revisions.update(existing => skip === 0 ? page : [...existing, ...page]);\n this.hasMore.set(page.length >= take);\n } catch (e) {\n this.error.set(this.describe(e as HttpErrorResponse));\n } finally {\n this.loading.set(false);\n }\n }\n\n async select(revision: SparkRevision): Promise<void> {\n if (this.selected()?.changeVector === revision.changeVector) {\n this.clearSelection();\n return;\n }\n this.selected.set(revision);\n this.selectedObject.set(null);\n this.error.set(null);\n this.selectedLoading.set(true);\n try {\n const po = await this.history.get(this.type(), this.id(), revision.changeVector, { deleted: this.deleted() });\n if (this.selected()?.changeVector === revision.changeVector) this.selectedObject.set(po);\n } catch (e) {\n this.error.set(this.describe(e as HttpErrorResponse));\n } finally {\n this.selectedLoading.set(false);\n }\n }\n\n clearSelection(): void {\n this.selected.set(null);\n this.selectedObject.set(null);\n }\n\n async revert(): Promise<void> {\n const revision = this.selected();\n if (!revision || !this.canRevertSelected() || this.reverting()) return;\n if (!confirm(this.lang.t('history.confirmRevert'))) return;\n\n this.reverting.set(true);\n this.error.set(null);\n try {\n const saved = await this.history.revert(this.type(), this.id(), revision.changeVector);\n this.reverted.emit(saved);\n await this.refresh();\n } catch (e) {\n this.error.set(this.describe(e as HttpErrorResponse));\n } finally {\n this.reverting.set(false);\n }\n }\n\n /**\n * One attribute of `po` for `<spark-grid-cell>`. A persistent object is a row the grid pipes read\n * (`valueFor` understands both shapes), so the value resolution is the grid's, not a copy of it.\n */\n private cell(attribute: EntityAttributeDefinition, po: PersistentObject | null): HistoryCell {\n const column = attribute as unknown as QueryColumn;\n const row = po as unknown as QueryResultItem | null;\n const display = cellValuePipe.transform(column, row, this.lookupOptions());\n return {\n column,\n // The detail page's placeholder for an empty value; a boolean keeps null (an indeterminate box).\n display: attribute.dataType !== 'boolean' && (display == null || display === '') ? '-' : display,\n rendererValue: cellValue(valueFor(row, attribute.name)),\n chips: chipsPipe.transform(column, row),\n };\n }\n\n protected who(revision: SparkRevision): string {\n return revision.userName || revision.userId || this.lang.t('history.unknownUser');\n }\n\n private describe(err: HttpErrorResponse): string {\n switch (err?.status) {\n case 404: return this.lang.t('history.unavailable');\n case 409: return this.lang.t('history.conflict');\n default: return err?.error?.error || err?.message || this.lang.t('common.actionFailed');\n }\n }\n}\n","@if (canView()) {\n <div class=\"spark-po-history\">\n @if (error(); as message) {\n <bs-alert [type]=\"colors.danger\" class=\"d-block mb-3\">{{ message }}</bs-alert>\n }\n\n @if (revisions().length === 0 && !loading()) {\n <p class=\"text-muted mb-0 spark-history-empty\">{{ 'history.noRevisions' | t }}</p>\n } @else {\n <bs-table [isResponsive]=\"true\">\n <thead>\n <tr>\n <th>{{ 'history.modifiedAt' | t }}</th>\n <th>{{ 'history.modifiedBy' | t }}</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @for (revision of revisions(); track revision.changeVector) {\n <tr class=\"spark-history-row\" [class.table-active]=\"selected()?.changeVector === revision.changeVector\">\n <td>\n <button type=\"button\" class=\"btn btn-link p-0 spark-history-select\" (click)=\"select(revision)\">\n {{ revision.lastModified ? (revision.lastModified | date:'medium') : '—' }}\n </button>\n </td>\n <td>{{ who(revision) }}</td>\n <td class=\"text-end\">\n @if (revision.isCurrent) {\n <bs-badge [type]=\"colors.primary\" class=\"spark-history-current\">{{ 'history.current' | t }}</bs-badge>\n }\n @if (revision.isDeleteRevision) {\n <bs-badge [type]=\"colors.secondary\" class=\"ms-1\">{{ 'history.deleteRevision' | t }}</bs-badge>\n }\n </td>\n </tr>\n }\n </tbody>\n </bs-table>\n }\n\n @if (loading()) {\n <div class=\"text-center p-2\"><bs-spinner /></div>\n } @else if (hasMore()) {\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm spark-history-more\" (click)=\"loadMore()\">\n {{ 'history.loadMore' | t }}\n </button>\n }\n\n @if (selected(); as revision) {\n <div class=\"mt-3 spark-history-selected\">\n <div class=\"d-flex flex-wrap gap-2 align-items-center mb-2\">\n <div class=\"btn-group\" role=\"group\">\n <button type=\"button\" class=\"btn btn-sm spark-history-diff-tab\"\n [class.btn-secondary]=\"view() === 'diff'\" [class.btn-outline-secondary]=\"view() !== 'diff'\"\n (click)=\"view.set('diff')\">{{ 'history.changes' | t }}</button>\n <button type=\"button\" class=\"btn btn-sm spark-history-view-tab\"\n [class.btn-secondary]=\"view() === 'view'\" [class.btn-outline-secondary]=\"view() !== 'view'\"\n (click)=\"view.set('view')\">{{ 'history.revision' | t }}</button>\n </div>\n @if (canRevertSelected()) {\n <button type=\"button\" class=\"btn btn-warning btn-sm spark-history-revert\" [disabled]=\"reverting()\" (click)=\"revert()\">\n {{ 'history.revert' | t }}\n </button>\n }\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm ms-auto\" (click)=\"clearSelection()\">\n {{ 'history.close' | t }}\n </button>\n </div>\n\n @if (selectedLoading()) {\n <div class=\"text-center p-2\"><bs-spinner /></div>\n } @else if (selectedObject()) {\n @if (view() === 'diff') {\n @if (changes().length === 0) {\n <p class=\"text-muted spark-history-nochanges\">{{ 'history.noChanges' | t }}</p>\n } @else {\n <bs-table [isResponsive]=\"true\">\n <thead>\n <tr>\n <th>{{ 'history.field' | t }}</th>\n <th>{{ 'history.revisionValue' | t }}</th>\n <th>{{ 'history.currentValue' | t }}</th>\n </tr>\n </thead>\n <tbody>\n @for (row of changeCells(); track row.change.attribute.name) {\n <tr class=\"spark-history-change\">\n <th scope=\"row\">{{ row.change.attribute.label | resolveTranslation:row.change.attribute.name }}</th>\n <td class=\"spark-history-old\">\n <spark-grid-cell [column]=\"row.old.column\" [display]=\"row.old.display\" [rendererValue]=\"row.old.rendererValue\"\n [item]=\"selectedObject()\" [chips]=\"row.old.chips\" />\n </td>\n <td class=\"spark-history-new\">\n <spark-grid-cell [column]=\"row.now.column\" [display]=\"row.now.display\" [rendererValue]=\"row.now.rendererValue\"\n [item]=\"current()\" [chips]=\"row.now.chips\" />\n </td>\n </tr>\n }\n </tbody>\n </bs-table>\n }\n } @else {\n <dl class=\"spark-history-view\">\n @for (entry of viewCells(); track entry.attribute.name) {\n <dt>{{ entry.attribute.label | resolveTranslation:entry.attribute.name }}</dt>\n <dd>\n <spark-grid-cell [column]=\"entry.cell.column\" [display]=\"entry.cell.display\" [rendererValue]=\"entry.cell.rendererValue\"\n [item]=\"selectedObject()\" [chips]=\"entry.cell.chips\" />\n </dd>\n }\n </dl>\n }\n }\n </div>\n }\n </div>\n}\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport { BsCardComponent, BsCardHeaderComponent } from '@mintplayer/ng-bootstrap/card';\nimport { TranslateKeyPipe } from '@mintplayer/ng-spark/pipes';\nimport { SparkDetailContext } from '@mintplayer/ng-spark/panels';\nimport { SparkPoHistoryComponent } from './spark-po-history.component';\n\n/**\n * The History card on the routed detail page (#460). Registered by {@link provideSparkHistory} as a\n * `SPARK_DETAIL_PANELS` entry; renders nothing for a caller without `History/T`.\n * After a Revert it asks the page to reload, so the attributes above show the reverted values.\n */\n@Component({\n selector: 'spark-history-panel',\n imports: [BsCardComponent, BsCardHeaderComponent, TranslateKeyPipe, SparkPoHistoryComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (visible()) {\n <bs-card class=\"d-block spark-history-panel\">\n <bs-card-header>{{ 'history.title' | t }}</bs-card-header>\n <div class=\"p-3\">\n <spark-po-history\n [type]=\"context().type\"\n [id]=\"context().id\"\n [entityType]=\"context().entityType\"\n [current]=\"context().item\"\n [permissions]=\"context().permissions\"\n [deleted]=\"context().deleted\"\n (reverted)=\"context().reload()\" />\n </div>\n </bs-card>\n }\n `,\n})\nexport class SparkHistoryPanelComponent {\n context = input.required<SparkDetailContext>();\n\n protected readonly visible = computed(() => this.context().permissions?.canViewHistory === true);\n}\n","import { Provider } from '@angular/core';\nimport { provideSparkDetailPanels } from '@mintplayer/ng-spark/panels';\nimport { SparkHistoryPanelComponent } from './spark-history-panel.component';\n\n/**\n * Adds a History card (`<spark-po-history>`: revision list, read-only view, diff, Revert) to every\n * detail page `sparkRoutes()` routes to, for holders of `History/T` (#460). Needs the server package\n * `MintPlayer.Spark.History` and revisions enabled for the type in its model.\n *\n * `providers: [provideSpark(...), provideSparkHistory()]`\n */\nexport function provideSparkHistory(options?: { order?: number }): Provider[] {\n return provideSparkDetailPanels({ id: 'spark-history', component: SparkHistoryPanelComponent, order: options?.order ?? 100 });\n}\n"],"mappings":";;;;;;;;;;;;;;;AAiCA,IAAa,sBAAb,MAAa,oBAAmB;CACb,QAAQ,OAAO,YAAY;CAG5C,KAAK,MAAc,IAAY,SAAkC;EAC/D,OAAO,KAAK,MAAM,aAA8B,iBAAiB;GAC/D,cAAc;GACd;GACA,GAAI,SAAS,OAAO,EAAE,MAAM,QAAQ,KAAI,IAAK,CAAA;GAC7C,GAAI,SAAS,OAAO,EAAE,MAAM,QAAQ,KAAI,IAAK,CAAA;GAC7C,GAAI,SAAS,WAAW,QAAQ,YAAY,YAAY,EAAE,SAAS,QAAQ,QAAO,IAAK,CAAA;EACxF,CAAA;CACH;CAGA,IAAI,MAAc,IAAY,cAAsB,SAAiD;EACnG,OAAO,KAAK,MAAM,aAA+B,gBAAgB;GAC/D,cAAc;GACd;GACA;GACA,GAAI,SAAS,WAAW,QAAQ,YAAY,YAAY,EAAE,SAAS,QAAQ,QAAO,IAAK,CAAA;EACxF,CAAA;CACH;CAOA,OAAO,MAAc,IAAY,cAAoB;EACnD,OAAO,KAAK,MAAM,aAA+B,cAAc;GAAE,cAAc;GAAM;GAAI;EAAY,CAAE;CACzG;CA/BW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAmB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAnB,OAAA,QAAA,GAAA,sBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAmB,YADN;CAAM,CAAA;;AACnB,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAmB,YAAA,CAAA;EAD/B,MAAA;EAAW,MAAA,CAAA,EAAE,YAAY,OAAM,CAAE;;;AClBlC,SAAgB,mBAAmB,YAAyC;CAC1E,QAAQ,YAAY,cAAc,CAAA,EAAA,CAC/B,QAAO,MAAK,EAAE,aAAa,gBAAgB,EAAE,UAAU,SAAS,gBAAgB,CAAC,CAAC,CAClF,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACrC;AAOA,SAAgB,aACd,YACA,UACA,SAA4C;CAE5C,IAAI,CAAC,YAAY,CAAC,SAAS,OAAO,CAAA;CAClC,MAAM,UAAiC,CAAA;CACvC,KAAK,MAAM,aAAa,mBAAmB,UAAU,GAAG;EACtD,MAAM,IAAI,SAAS,WAAW,MAAK,MAAK,EAAE,SAAS,UAAU,IAAI;EACjE,MAAM,IAAI,QAAQ,WAAW,MAAK,MAAK,EAAE,SAAS,UAAU,IAAI;EAChE,IAAI,gBAAgB,CAAC,MAAM,gBAAgB,CAAC,GAAG,QAAQ,KAAK;GAAE;GAAW,UAAU;GAAG,SAAS;EAAC,CAAE;CACpG;CACA,OAAO;AACT;ACTA,MAAM,gBAAgB,IAAI,mBAAkB;AAC5C,MAAM,YAAY,IAAI,wBAAuB;AAoB7C,IAAa,0BAAb,MAAa,wBAAuB;CACjB,UAAU,OAAO,mBAAmB;CAClC,OAAO,OAAO,oBAAoB;CAGrD,OAAO,MAAM,SAAkB,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAC/B,KAAK,MAAM,SAAkB,GAAA,YAAA,CAAA,EAAA,WAAA,KAAA,CAAA,+BAAA,CAAA,CAAA;CAC7B,aAAa,MAAM,SAAsB,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAEzC,UAAU,MAA+B,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAC9C,cAAc,MAAgC,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAEnD,UAAU,MAAiC,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAEhD,WAAW,MAAM,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAGpB,WAAW,OAAM;CAEE,SAAS;CACT,YAAY,OAAwB,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CACvC,UAAU,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CACvB,UAAU,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CACvB,QAAQ,OAAsB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAEnC,WAAW,OAA6B,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAC7C,iBAAiB,OAAgC,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CACtD,kBAAkB,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,kBAAA,CAAA,+BAAA,CAAA,CAAA;CAC/B,OAAO,OAAoB,QAAO,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAClC,YAAY,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAEzB,UAAU,eAAe,KAAK,YAAW,CAAE,EAAE,mBAAmB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAErE,aAAa,eAAe,mBAAmB,KAAK,WAAU,CAAE,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAClE,UAAU,eAAe,aAAa,KAAK,WAAU,GAAI,KAAK,eAAc,GAAI,KAAK,QAAO,CAAE,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAElG,gBAAgB,OAAO,kBAAkB;CAEzC,gBAAgB,OAAwC,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;CAOzD,YAAY,eAAc;EAC3C,MAAM,WAAW,KAAK,eAAc;EACpC,OAAO,WAAW,KAAK,WAAU,CAAE,CAAC,KAAI,OAAM;GAAE,WAAW;GAAG,MAAM,KAAK,KAAK,GAAG,QAAQ;EAAC,EAAG,IAAI,CAAA;CACnG,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAGiB,cAAc,eAAc;EAC7C,MAAM,WAAW,KAAK,eAAc;EACpC,MAAM,UAAU,KAAK,QAAO;EAC5B,OAAO,KAAK,QAAO,CAAE,CAAC,KAAI,YAAW;GACnC;GACA,KAAK,KAAK,KAAK,OAAO,WAAW,QAAQ;GACzC,KAAK,KAAK,KAAK,OAAO,WAAW,OAAO;EACzC,EAAC;CACJ,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAEiB,oBAAoB,eAAc;EACnD,MAAM,WAAW,KAAK,SAAQ;EAC9B,OAAO,CAAC,CAAC,YACJ,KAAK,YAAW,CAAE,EAAE,cAAc,QAClC,KAAK,QAAO,MAAO,UACnB,CAAC,SAAS,aACV,CAAC,SAAS,oBACV,CAAC,CAAC,KAAK,eAAc;CAC5B,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,oBAAA,CAAA,+BAAA,CAAA,CAAA;CAEF,cAAA;EACE,aAAY;GACV,MAAM,aAAa,KAAK,WAAU;GAClC,gBAAe;IACb,KAAK,cAAc,kBAAkB,UAAU,CAAC,CAAC,MAAK,MAAK,KAAK,cAAc,IAAI,CAAC,SAAS,KAAK,cAAc,IAAI,CAAA,CAAE,CAAC;GACxH,CAAC;EACH,CAAC;EAID,aAAY;GACV,MAAM,OAAO,KAAK,KAAI;GACtB,MAAM,KAAK,KAAK,GAAE;GAClB,MAAM,UAAU,KAAK,QAAO;GAC5B,MAAM,UAAU,KAAK,QAAO;GAC5B,gBAAe;IACb,KAAK,eAAc;IACnB,KAAK,UAAU,IAAI,CAAA,CAAE;IACrB,IAAI,WAAW,QAAQ,IAAI,AAAK,KAAK,SAAS,MAAM,IAAI,SAAS,CAAC;GACpE,CAAC;EACH,CAAC;CACH;CAGA,MAAM,UAAO;EACX,KAAK,eAAc;EACnB,KAAK,UAAU,IAAI,CAAA,CAAE;EACrB,MAAM,KAAK,SAAS,KAAK,KAAI,GAAI,KAAK,GAAE,GAAI,KAAK,QAAO,GAAI,CAAC;CAC/D;CAEA,MAAM,WAAQ;EACZ,MAAM,KAAK,SAAS,KAAK,KAAI,GAAI,KAAK,GAAE,GAAI,KAAK,QAAO,GAAI,KAAK,UAAS,CAAE,CAAC,MAAM;CACrF;CAEQ,MAAM,SAAS,MAAc,IAAY,SAAoC,MAAY;EAC/F,KAAK,QAAQ,IAAI,IAAI;EACrB,KAAK,MAAM,IAAI,IAAI;EACnB,IAAI;GACF,MAAM,OAAO,KAAK,SAAQ;GAC1B,MAAM,OAAO,MAAM,KAAK,QAAQ,KAAK,MAAM,IAAI;IAAE;IAAM;IAAM;GAAO,CAAE;GAEtE,IAAI,SAAS,KAAK,KAAI,KAAM,OAAO,KAAK,GAAE,GAAI;GAC9C,KAAK,UAAU,QAAO,aAAY,SAAS,IAAI,OAAO,CAAC,GAAG,UAAU,GAAG,IAAI,CAAC;GAC5E,KAAK,QAAQ,IAAI,KAAK,UAAU,IAAI;EACtC,SAAS,GAAG;GACV,KAAK,MAAM,IAAI,KAAK,SAAS,CAAsB,CAAC;EACtD,UAAU;GACR,KAAK,QAAQ,IAAI,KAAK;EACxB;CACF;CAEA,MAAM,OAAO,UAAuB;EAClC,IAAI,KAAK,SAAQ,CAAE,EAAE,iBAAiB,SAAS,cAAc;GAC3D,KAAK,eAAc;GACnB;EACF;EACA,KAAK,SAAS,IAAI,QAAQ;EAC1B,KAAK,eAAe,IAAI,IAAI;EAC5B,KAAK,MAAM,IAAI,IAAI;EACnB,KAAK,gBAAgB,IAAI,IAAI;EAC7B,IAAI;GACF,MAAM,KAAK,MAAM,KAAK,QAAQ,IAAI,KAAK,KAAI,GAAI,KAAK,GAAE,GAAI,SAAS,cAAc,EAAE,SAAS,KAAK,QAAO,EAAE,CAAE;GAC5G,IAAI,KAAK,SAAQ,CAAE,EAAE,iBAAiB,SAAS,cAAc,KAAK,eAAe,IAAI,EAAE;EACzF,SAAS,GAAG;GACV,KAAK,MAAM,IAAI,KAAK,SAAS,CAAsB,CAAC;EACtD,UAAU;GACR,KAAK,gBAAgB,IAAI,KAAK;EAChC;CACF;CAEA,iBAAc;EACZ,KAAK,SAAS,IAAI,IAAI;EACtB,KAAK,eAAe,IAAI,IAAI;CAC9B;CAEA,MAAM,SAAM;EACV,MAAM,WAAW,KAAK,SAAQ;EAC9B,IAAI,CAAC,YAAY,CAAC,KAAK,kBAAiB,KAAM,KAAK,UAAS,GAAI;EAChE,IAAI,CAAC,QAAQ,KAAK,KAAK,EAAE,uBAAuB,CAAC,GAAG;EAEpD,KAAK,UAAU,IAAI,IAAI;EACvB,KAAK,MAAM,IAAI,IAAI;EACnB,IAAI;GACF,MAAM,QAAQ,MAAM,KAAK,QAAQ,OAAO,KAAK,KAAI,GAAI,KAAK,GAAE,GAAI,SAAS,YAAY;GACrF,KAAK,SAAS,KAAK,KAAK;GACxB,MAAM,KAAK,QAAO;EACpB,SAAS,GAAG;GACV,KAAK,MAAM,IAAI,KAAK,SAAS,CAAsB,CAAC;EACtD,UAAU;GACR,KAAK,UAAU,IAAI,KAAK;EAC1B;CACF;CAMQ,KAAK,WAAsC,IAA2B;EAC5E,MAAM,SAAS;EACf,MAAM,MAAM;EACZ,MAAM,UAAU,cAAc,UAAU,QAAQ,KAAK,KAAK,cAAa,CAAE;EACzE,OAAO;GACL;GAEA,SAAS,UAAU,aAAa,cAAc,WAAW,QAAQ,YAAY,MAAM,MAAM;GACzF,eAAe,UAAU,SAAS,KAAK,UAAU,IAAI,CAAC;GACtD,OAAO,UAAU,UAAU,QAAQ,GAAG;EACvC;CACH;CAEU,IAAI,UAAuB;EACnC,OAAO,SAAS,YAAY,SAAS,UAAU,KAAK,KAAK,EAAE,qBAAqB;CAClF;CAEQ,SAAS,KAAsB;EACrC,QAAQ,KAAK,QAAb;GACE,KAAK,KAAK,OAAO,KAAK,KAAK,EAAE,qBAAqB;GAClD,KAAK,KAAK,OAAO,KAAK,KAAK,EAAE,kBAAkB;GAC/C,SAAS,OAAO,KAAK,OAAO,SAAS,KAAK,WAAW,KAAK,KAAK,EAAE,qBAAqB;EACxF;CACF;CA/LW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAuB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAvB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAuB,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,MAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,IAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,YAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,SAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,aAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,SAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,UAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,SAAA,EAAA,UAAA,WAAA;EAAA,UAAA;EAAA,UClDpC;EAqHA,cAAA;GAAA;IAAA,MAAA;IAAA,MDvEsB;IAAgB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA,CAAA,mBAAA,qBAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAgB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAkB,UAAA;IAAA,QAAA,CAAA,QAAA,OAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAgB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAsB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAA1G;IAAQ,MAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAoG;IAAsB,MAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAgB,MAAA;GAAA;EAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AAInJ,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAuB,YAAA,CAAA;EANnC,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAkB,SACnB;IAAC;IAAU;IAAkB;IAAkB;IAAoB;IAAkB;IAAwB;IAAwB;GAAgB;GAAC,iBAE9I,wBAAwB;GAAM,UAAA;EAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AEfjD,IAAa,6BAAb,MAAa,2BAA0B;CACrC,UAAU,MAAM,SAA8B,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAE3B,UAAU,eAAe,KAAK,QAAO,CAAE,CAAC,aAAa,mBAAmB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAHrF,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAA0B,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAA1B,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAA0B,cAAA;EAAA,UAAA;EAAA,QAAA,EAAA,SAAA;GAAA,mBAAA;GAAA,YAAA;GAAA,UAAA;GAAA,YAAA;GAAA,mBAAA;EAAA,EAAA;EAAA,UAAA;EAAA,UAlB3B;;;;;;;;;;;;;;;;;EAgBT,UAAA;EAAA,cAAA;GAAA;IAAA,MAAA;IAAA,MAlBS;IAAe,UAAA;IAAA,QAAA,CAAA,SAAA,SAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAqB,UAAA;IAAA,QAAA,CAAA,SAAA,UAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAoB;IAAuB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA,CAAA,UAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAzC;IAAgB,MAAA;GAAA;EAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AAoBvD,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAA0B,YAAA,CAAA;EAtBtC,MAAA;EAAU,MAAA,CAAA;GACT,UAAU;GACV,SAAS;IAAC;IAAiB;IAAuB;IAAkB;GAAuB;GAC3F,iBAAiB,wBAAwB;GACzC,UAAU;;;;;;;;;;;;;;;;;EAiBX,CAAA;;;;;;;;;;;ACrBD,SAAgB,oBAAoB,SAA4B;CAC9D,OAAO,yBAAyB;EAAE,IAAI;EAAiB,WAAW;EAA4B,OAAO,SAAS,SAAS;CAAG,CAAE;AAC9H"}
1
+ {"version":3,"file":"mintplayer-ng-spark-history.mjs","names":[],"sources":["../../history/src/spark-history.service.ts","../../history/src/revision-diff.ts","../../history/src/spark-po-history.component.ts","../../history/src/spark-po-history.component.html","../../history/src/spark-history-panel.component.ts","../../history/src/provide-spark-history.ts"],"sourcesContent":["import { inject, Injectable } from '@angular/core';\nimport { PersistentObject, SparkDeletedFilter } from '@mintplayer/ng-spark/models';\nimport { SparkService } from '@mintplayer/ng-spark/services';\n\n/** One revision of a row, newest first (`MintPlayer.Spark.History.SparkRevision`). */\nexport interface SparkRevision {\n changeVector: string;\n /** When the revision was written (ISO 8601 with offset); null when the server does not know. */\n lastModified?: string | null;\n /** Who wrote it — an id (D8: audit fields hold ids only). */\n userId?: string | null;\n /** The id resolved to a name at read time, when the app registered an `IHistoryUserNameResolver`. */\n userName?: string | null;\n /** The revision RavenDB writes when the document is deleted (a purge-free hard delete). */\n isDeleteRevision?: boolean;\n /** The revision the document currently is. Reverting to it changes nothing. */\n isCurrent?: boolean;\n}\n\nexport interface SparkRevisionListOptions {\n skip?: number;\n /** Server default 50, at most 200. */\n take?: number;\n /** `include` / `only` to read the history of a soft-deleted row (`ViewDeleted` holders only). */\n deleted?: SparkDeletedFilter | null;\n}\n\n/**\n * Client for the History package's endpoints (`MintPlayer.Spark.History`, #460 T1). Every read is\n * gated on the CURRENT row (a row the caller can no longer see has no readable history) and on\n * `History/T`; old revisions come back redacted like the live object.\n */\n@Injectable({ providedIn: 'root' })\nexport class SparkHistoryService {\n private readonly spark = inject(SparkService);\n\n /** `POST /spark/po/revisions` → the row's revisions, newest first. */\n list(type: string, id: string, options?: SparkRevisionListOptions): Promise<SparkRevision[]> {\n return this.spark.postEnvelope<SparkRevision[]>('/po/revisions', {\n objectTypeId: type,\n id,\n ...(options?.skip ? { skip: options.skip } : {}),\n ...(options?.take ? { take: options.take } : {}),\n ...(options?.deleted && options.deleted !== 'exclude' ? { deleted: options.deleted } : {}),\n });\n }\n\n /** `POST /spark/po/revision` → the revision as a read-only, redacted persistent object. */\n get(type: string, id: string, changeVector: string, options?: { deleted?: SparkDeletedFilter | null }): Promise<PersistentObject> {\n return this.spark.postEnvelope<PersistentObject>('/po/revision', {\n objectTypeId: type,\n id,\n changeVector,\n ...(options?.deleted && options.deleted !== 'exclude' ? { deleted: options.deleted } : {}),\n });\n }\n\n /**\n * `POST /spark/po/revert` → the reverted row. Requires `History/T`, `Revert/T` and `Edit/T`; saved\n * through the normal pipeline. 403 = the revert is disabled for this row, 409 = the row changed\n * since it was loaded, 400 = an interceptor refused (e.g. the row is locked).\n */\n revert(type: string, id: string, changeVector: string): Promise<PersistentObject> {\n return this.spark.postEnvelope<PersistentObject>('/po/revert', { objectTypeId: type, id, changeVector });\n }\n}\n","import { EntityAttributeDefinition, EntityType, PersistentObject, PersistentObjectAttribute, ShowedOn, comparableValue, hasShowedOnFlag } from '@mintplayer/ng-spark/models';\n\n/** One attribute that differs between a revision and the current object. */\nexport interface SparkRevisionChange {\n attribute: EntityAttributeDefinition;\n /** Absent when the attribute did not exist on that side (added or removed since). */\n revision: PersistentObjectAttribute | undefined;\n current: PersistentObjectAttribute | undefined;\n}\n\n/**\n * The attributes a revision is compared on: the ones the detail page shows, in its order. Redacted\n * attributes are simply absent from what the server sends, so they never appear as a difference.\n */\nexport function revisionAttributes(entityType: EntityType | null | undefined): EntityAttributeDefinition[] {\n return (entityType?.attributes ?? [])\n .filter(a => hasShowedOnFlag(a.showedOn, ShowedOn.PersistentObject))\n .sort((a, b) => a.order - b.order);\n}\n\n// The normalizer lives in models since po-edit's conflict merge needs the same answer; re-exported\n// here so History's public surface is unchanged.\nexport { comparableValue };\n\n/** The shown attributes whose content differs between `revision` and `current`, in display order. */\nexport function diffRevision(\n entityType: EntityType | null | undefined,\n revision: PersistentObject | null | undefined,\n current: PersistentObject | null | undefined,\n): SparkRevisionChange[] {\n if (!revision || !current) return [];\n const changes: SparkRevisionChange[] = [];\n for (const attribute of revisionAttributes(entityType)) {\n const r = revision.attributes.find(a => a.name === attribute.name);\n const c = current.attributes.find(a => a.name === attribute.name);\n if (comparableValue(r) !== comparableValue(c)) changes.push({ attribute, revision: r, current: c });\n }\n return changes;\n}\n","import { ChangeDetectionStrategy, Component, computed, effect, inject, input, output, signal, untracked } from '@angular/core';\nimport { DatePipe } from '@angular/common';\nimport { HttpErrorResponse } from '@angular/common/http';\nimport { Color } from '@mintplayer/ng-bootstrap';\nimport { BsAlertComponent } from '@mintplayer/ng-bootstrap/alert';\nimport { BsBadgeComponent } from '@mintplayer/ng-bootstrap/badge';\nimport { BsSpinnerComponent } from '@mintplayer/ng-bootstrap/spinner';\nimport { BsTableComponent } from '@mintplayer/ng-bootstrap/table';\nimport { SparkGridCellComponent, SparkGridRenderers } from '@mintplayer/ng-spark/grid';\nimport { QueryCellValuePipe, QueryReferenceChipsPipe, ReferenceChip, ResolveTranslationPipe, TranslateKeyPipe } from '@mintplayer/ng-spark/pipes';\nimport { cellValue } from '@mintplayer/ng-spark/renderers';\nimport { SparkLanguageService } from '@mintplayer/ng-spark/services';\nimport {\n EntityAttributeDefinition, EntityPermissions, EntityType, LookupReference, PersistentObject, QueryColumn, QueryResultItem,\n SparkDeletedFilter, valueFor,\n} from '@mintplayer/ng-spark/models';\nimport { SparkHistoryService, SparkRevision } from './spark-history.service';\nimport { diffRevision, revisionAttributes } from './revision-diff';\n\ntype HistoryView = 'view' | 'diff';\n\n/** One attribute of one object, ready for `<spark-grid-cell>`. */\ninterface HistoryCell {\n column: QueryColumn;\n display: unknown;\n rendererValue: unknown;\n chips: ReferenceChip[];\n}\n\nconst cellValuePipe = new QueryCellValuePipe();\nconst chipsPipe = new QueryReferenceChipsPipe();\n\n/**\n * A row's revision history (#460, History package): the revision list, a read-only view of one\n * revision, its field diff against the current object, and Revert.\n *\n * Standalone — bind it anywhere — and also what the History detail panel\n * (`provideSparkHistory()`) renders on every routed detail page.\n *\n * Rights come from `permissions`: nothing is listed without `canViewHistory`, and Revert is offered\n * only with `canRevert` (the server's `Revert/T` together with `Edit/T`), never for the current\n * revision, a delete revision, or a row opened from the recycle bin (Revert saves through the live\n * pipeline, which does not see a deleted row). The server enforces all of it again.\n */\n@Component({\n selector: 'spark-po-history',\n imports: [DatePipe, BsAlertComponent, BsBadgeComponent, BsSpinnerComponent, BsTableComponent, SparkGridCellComponent, ResolveTranslationPipe, TranslateKeyPipe],\n templateUrl: './spark-po-history.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SparkPoHistoryComponent {\n private readonly history = inject(SparkHistoryService);\n protected readonly lang = inject(SparkLanguageService);\n\n /** Entity type id or alias, as the endpoints take it. */\n type = input.required<string>();\n id = input.required<string>();\n entityType = input.required<EntityType>();\n /** The object as it is now — the right-hand side of every diff. */\n current = input<PersistentObject | null>(null);\n permissions = input<EntityPermissions | null>(null);\n /** The mode the row was opened with (`only` = from the recycle bin). */\n deleted = input<SparkDeletedFilter | null>(null);\n /** Rows per request (server default 50, at most 200). */\n pageSize = input(50);\n\n /** Emitted with the saved object after a successful Revert. */\n reverted = output<PersistentObject>();\n\n protected readonly colors = Color;\n protected readonly revisions = signal<SparkRevision[]>([]);\n protected readonly loading = signal(false);\n protected readonly hasMore = signal(false);\n protected readonly error = signal<string | null>(null);\n\n protected readonly selected = signal<SparkRevision | null>(null);\n protected readonly selectedObject = signal<PersistentObject | null>(null);\n protected readonly selectedLoading = signal(false);\n protected readonly view = signal<HistoryView>('diff');\n protected readonly reverting = signal(false);\n\n protected readonly canView = computed(() => this.permissions()?.canViewHistory === true);\n\n protected readonly attributes = computed(() => revisionAttributes(this.entityType()));\n protected readonly changes = computed(() => diffRevision(this.entityType(), this.selectedObject(), this.current()));\n\n private readonly gridRenderers = inject(SparkGridRenderers);\n /** Lookup-reference labels for the shown attributes, so a lookup value reads as its label. */\n private readonly lookupOptions = signal<Record<string, LookupReference>>({});\n\n /**\n * The read-only view: every shown attribute of the selected revision, rendered by the same\n * `<spark-grid-cell>` (and custom renderers) as a query grid — a reference as its label, a date in\n * the viewer's culture and zone, a boolean as a checkbox — instead of the raw wire value.\n */\n protected readonly viewCells = computed(() => {\n const revision = this.selectedObject();\n return revision ? this.attributes().map(a => ({ attribute: a, cell: this.cell(a, revision) })) : [];\n });\n\n /** The diff rows, both sides rendered like {@link viewCells}. */\n protected readonly changeCells = computed(() => {\n const revision = this.selectedObject();\n const current = this.current();\n return this.changes().map(change => ({\n change,\n old: this.cell(change.attribute, revision),\n now: this.cell(change.attribute, current),\n }));\n });\n\n protected readonly canRevertSelected = computed(() => {\n const revision = this.selected();\n return !!revision\n && this.permissions()?.canRevert === true\n && this.deleted() !== 'only'\n && !revision.isCurrent\n && !revision.isDeleteRevision\n && !!this.selectedObject();\n });\n\n constructor() {\n effect(() => {\n const attributes = this.attributes();\n untracked(() => {\n this.gridRenderers.loadLookupOptions(attributes).then(o => this.lookupOptions.set(o), () => this.lookupOptions.set({}));\n });\n });\n\n // (Re)load the list when the row, its mode or the rights change. A revert emits a new `current`\n // but keeps the id, so it is not in this effect; `refresh()` reloads explicitly.\n effect(() => {\n const type = this.type();\n const id = this.id();\n const deleted = this.deleted();\n const allowed = this.canView();\n untracked(() => {\n this.clearSelection();\n this.revisions.set([]);\n if (allowed && type && id) void this.loadPage(type, id, deleted, 0);\n });\n });\n }\n\n /** Reloads the list from the top, dropping the selection. */\n async refresh(): Promise<void> {\n this.clearSelection();\n this.revisions.set([]);\n await this.loadPage(this.type(), this.id(), this.deleted(), 0);\n }\n\n async loadMore(): Promise<void> {\n await this.loadPage(this.type(), this.id(), this.deleted(), this.revisions().length);\n }\n\n private async loadPage(type: string, id: string, deleted: SparkDeletedFilter | null, skip: number): Promise<void> {\n this.loading.set(true);\n this.error.set(null);\n try {\n const take = this.pageSize();\n const page = await this.history.list(type, id, { skip, take, deleted });\n // A response for a row the inputs have moved away from is dropped.\n if (type !== this.type() || id !== this.id()) return;\n this.revisions.update(existing => skip === 0 ? page : [...existing, ...page]);\n this.hasMore.set(page.length >= take);\n } catch (e) {\n this.error.set(this.describe(e as HttpErrorResponse));\n } finally {\n this.loading.set(false);\n }\n }\n\n async select(revision: SparkRevision): Promise<void> {\n if (this.selected()?.changeVector === revision.changeVector) {\n this.clearSelection();\n return;\n }\n this.selected.set(revision);\n this.selectedObject.set(null);\n this.error.set(null);\n this.selectedLoading.set(true);\n try {\n const po = await this.history.get(this.type(), this.id(), revision.changeVector, { deleted: this.deleted() });\n if (this.selected()?.changeVector === revision.changeVector) this.selectedObject.set(po);\n } catch (e) {\n this.error.set(this.describe(e as HttpErrorResponse));\n } finally {\n this.selectedLoading.set(false);\n }\n }\n\n clearSelection(): void {\n this.selected.set(null);\n this.selectedObject.set(null);\n }\n\n async revert(): Promise<void> {\n const revision = this.selected();\n if (!revision || !this.canRevertSelected() || this.reverting()) return;\n if (!confirm(this.lang.t('history.confirmRevert'))) return;\n\n this.reverting.set(true);\n this.error.set(null);\n try {\n const saved = await this.history.revert(this.type(), this.id(), revision.changeVector);\n this.reverted.emit(saved);\n await this.refresh();\n } catch (e) {\n this.error.set(this.describe(e as HttpErrorResponse));\n } finally {\n this.reverting.set(false);\n }\n }\n\n /**\n * One attribute of `po` for `<spark-grid-cell>`. A persistent object is a row the grid pipes read\n * (`valueFor` understands both shapes), so the value resolution is the grid's, not a copy of it.\n */\n private cell(attribute: EntityAttributeDefinition, po: PersistentObject | null): HistoryCell {\n const column = attribute as unknown as QueryColumn;\n const row = po as unknown as QueryResultItem | null;\n const display = cellValuePipe.transform(column, row, this.lookupOptions());\n return {\n column,\n // The detail page's placeholder for an empty value; a boolean keeps null (an indeterminate box).\n display: attribute.dataType !== 'boolean' && (display == null || display === '') ? '-' : display,\n rendererValue: cellValue(valueFor(row, attribute.name)),\n chips: chipsPipe.transform(column, row),\n };\n }\n\n protected who(revision: SparkRevision): string {\n return revision.userName || revision.userId || this.lang.t('history.unknownUser');\n }\n\n private describe(err: HttpErrorResponse): string {\n switch (err?.status) {\n case 404: return this.lang.t('history.unavailable');\n case 409: return this.lang.t('history.conflict');\n default: return err?.error?.error || err?.message || this.lang.t('common.actionFailed');\n }\n }\n}\n","@if (canView()) {\n <div class=\"spark-po-history\">\n @if (error(); as message) {\n <bs-alert [type]=\"colors.danger\" class=\"d-block mb-3\">{{ message }}</bs-alert>\n }\n\n @if (revisions().length === 0 && !loading()) {\n <p class=\"text-muted mb-0 spark-history-empty\">{{ 'history.noRevisions' | t }}</p>\n } @else {\n <bs-table [isResponsive]=\"true\">\n <thead>\n <tr>\n <th>{{ 'history.modifiedAt' | t }}</th>\n <th>{{ 'history.modifiedBy' | t }}</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @for (revision of revisions(); track revision.changeVector) {\n <tr class=\"spark-history-row\" [class.table-active]=\"selected()?.changeVector === revision.changeVector\">\n <td>\n <button type=\"button\" class=\"btn btn-link p-0 spark-history-select\" (click)=\"select(revision)\">\n {{ revision.lastModified ? (revision.lastModified | date:'medium') : '—' }}\n </button>\n </td>\n <td>{{ who(revision) }}</td>\n <td class=\"text-end\">\n @if (revision.isCurrent) {\n <bs-badge [type]=\"colors.primary\" class=\"spark-history-current\">{{ 'history.current' | t }}</bs-badge>\n }\n @if (revision.isDeleteRevision) {\n <bs-badge [type]=\"colors.secondary\" class=\"ms-1\">{{ 'history.deleteRevision' | t }}</bs-badge>\n }\n </td>\n </tr>\n }\n </tbody>\n </bs-table>\n }\n\n @if (loading()) {\n <div class=\"text-center p-2\"><bs-spinner /></div>\n } @else if (hasMore()) {\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm spark-history-more\" (click)=\"loadMore()\">\n {{ 'history.loadMore' | t }}\n </button>\n }\n\n @if (selected(); as revision) {\n <div class=\"mt-3 spark-history-selected\">\n <div class=\"d-flex flex-wrap gap-2 align-items-center mb-2\">\n <div class=\"btn-group\" role=\"group\">\n <button type=\"button\" class=\"btn btn-sm spark-history-diff-tab\"\n [class.btn-secondary]=\"view() === 'diff'\" [class.btn-outline-secondary]=\"view() !== 'diff'\"\n (click)=\"view.set('diff')\">{{ 'history.changes' | t }}</button>\n <button type=\"button\" class=\"btn btn-sm spark-history-view-tab\"\n [class.btn-secondary]=\"view() === 'view'\" [class.btn-outline-secondary]=\"view() !== 'view'\"\n (click)=\"view.set('view')\">{{ 'history.revision' | t }}</button>\n </div>\n @if (canRevertSelected()) {\n <button type=\"button\" class=\"btn btn-warning btn-sm spark-history-revert\" [disabled]=\"reverting()\" (click)=\"revert()\">\n {{ 'history.revert' | t }}\n </button>\n }\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm ms-auto\" (click)=\"clearSelection()\">\n {{ 'history.close' | t }}\n </button>\n </div>\n\n @if (selectedLoading()) {\n <div class=\"text-center p-2\"><bs-spinner /></div>\n } @else if (selectedObject()) {\n @if (view() === 'diff') {\n @if (changes().length === 0) {\n <p class=\"text-muted spark-history-nochanges\">{{ 'history.noChanges' | t }}</p>\n } @else {\n <bs-table [isResponsive]=\"true\">\n <thead>\n <tr>\n <th>{{ 'history.field' | t }}</th>\n <th>{{ 'history.revisionValue' | t }}</th>\n <th>{{ 'history.currentValue' | t }}</th>\n </tr>\n </thead>\n <tbody>\n @for (row of changeCells(); track row.change.attribute.name) {\n <tr class=\"spark-history-change\">\n <th scope=\"row\">{{ row.change.attribute.label | resolveTranslation:row.change.attribute.name }}</th>\n <td class=\"spark-history-old\">\n <spark-grid-cell [column]=\"row.old.column\" [display]=\"row.old.display\" [rendererValue]=\"row.old.rendererValue\"\n [item]=\"selectedObject()\" [chips]=\"row.old.chips\" />\n </td>\n <td class=\"spark-history-new\">\n <spark-grid-cell [column]=\"row.now.column\" [display]=\"row.now.display\" [rendererValue]=\"row.now.rendererValue\"\n [item]=\"current()\" [chips]=\"row.now.chips\" />\n </td>\n </tr>\n }\n </tbody>\n </bs-table>\n }\n } @else {\n <dl class=\"spark-history-view\">\n @for (entry of viewCells(); track entry.attribute.name) {\n <dt>{{ entry.attribute.label | resolveTranslation:entry.attribute.name }}</dt>\n <dd>\n <spark-grid-cell [column]=\"entry.cell.column\" [display]=\"entry.cell.display\" [rendererValue]=\"entry.cell.rendererValue\"\n [item]=\"selectedObject()\" [chips]=\"entry.cell.chips\" />\n </dd>\n }\n </dl>\n }\n }\n </div>\n }\n </div>\n}\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport { BsCardComponent, BsCardHeaderComponent } from '@mintplayer/ng-bootstrap/card';\nimport { TranslateKeyPipe } from '@mintplayer/ng-spark/pipes';\nimport { SparkDetailContext } from '@mintplayer/ng-spark/panels';\nimport { SparkPoHistoryComponent } from './spark-po-history.component';\n\n/**\n * The History card on the routed detail page (#460). Registered by {@link provideSparkHistory} as a\n * `SPARK_DETAIL_PANELS` entry; renders nothing for a caller without `History/T`.\n * After a Revert it asks the page to reload, so the attributes above show the reverted values.\n */\n@Component({\n selector: 'spark-history-panel',\n imports: [BsCardComponent, BsCardHeaderComponent, TranslateKeyPipe, SparkPoHistoryComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (visible()) {\n <bs-card class=\"d-block spark-history-panel\">\n <bs-card-header>{{ 'history.title' | t }}</bs-card-header>\n <div class=\"p-3\">\n <spark-po-history\n [type]=\"context().type\"\n [id]=\"context().id\"\n [entityType]=\"context().entityType\"\n [current]=\"context().item\"\n [permissions]=\"context().permissions\"\n [deleted]=\"context().deleted\"\n (reverted)=\"context().reload()\" />\n </div>\n </bs-card>\n }\n `,\n})\nexport class SparkHistoryPanelComponent {\n context = input.required<SparkDetailContext>();\n\n protected readonly visible = computed(() => this.context().permissions?.canViewHistory === true);\n}\n","import { Provider } from '@angular/core';\nimport { provideSparkDetailPanels } from '@mintplayer/ng-spark/panels';\nimport { SparkHistoryPanelComponent } from './spark-history-panel.component';\n\n/**\n * Adds a History card (`<spark-po-history>`: revision list, read-only view, diff, Revert) to every\n * detail page `sparkRoutes()` routes to, for holders of `History/T` (#460). Needs the server package\n * `MintPlayer.Spark.History` and revisions enabled for the type in its model.\n *\n * `providers: [provideSpark(...), provideSparkHistory()]`\n */\nexport function provideSparkHistory(options?: { order?: number }): Provider[] {\n return provideSparkDetailPanels({ id: 'spark-history', component: SparkHistoryPanelComponent, order: options?.order ?? 100 });\n}\n"],"mappings":"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"}
@@ -6,6 +6,7 @@ function resolveTranslation(ts, lang) {
6
6
  }
7
7
  var ShowedOn;
8
8
  (function(ShowedOn) {
9
+ ShowedOn[ShowedOn["None"] = 0] = "None";
9
10
  ShowedOn[ShowedOn["Query"] = 1] = "Query";
10
11
  ShowedOn[ShowedOn["PersistentObject"] = 2] = "PersistentObject";
11
12
  })(ShowedOn || (ShowedOn = {}));
@@ -162,7 +163,6 @@ function buildAttribute(attrDef, raw, resolve, originalDate) {
162
163
  dataType: attrDef.dataType,
163
164
  isArray: attrDef.isArray,
164
165
  isRequired: attrDef.isRequired,
165
- isVisible: attrDef.isVisible,
166
166
  isReadOnly: attrDef.isReadOnly,
167
167
  order: attrDef.order,
168
168
  rules: attrDef.rules ?? [],
@@ -356,7 +356,7 @@ function applyOverlay(attr, overlay) {
356
356
  ...attr,
357
357
  isRequired: overlay.isRequired ?? attr.isRequired,
358
358
  isReadOnly: overlay.isReadOnly ?? attr.isReadOnly,
359
- isVisible: overlay.isVisible ?? attr.isVisible,
359
+ showedOn: overlay.showedOn ?? attr.showedOn,
360
360
  rules: overlay.rules ?? attr.rules,
361
361
  query: overlay.query ?? attr.query
362
362
  };
@@ -366,7 +366,7 @@ function overlayFromResponse(response) {
366
366
  for (const attr of response.attributes ?? []) overlay[attr.name] = {
367
367
  isRequired: attr.isRequired,
368
368
  isReadOnly: attr.isReadOnly,
369
- isVisible: attr.isVisible,
369
+ showedOn: attr.showedOn,
370
370
  rules: attr.rules ?? [],
371
371
  query: attr.query,
372
372
  options: attr.options ?? void 0