@tinya-code/gas-admin-ui 0.2.0-alpha.15 → 0.2.0-alpha.18
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/fesm2022/tinya-code-gas-admin-ui-badge-EeCA_l-o.mjs +84 -0
- package/fesm2022/tinya-code-gas-admin-ui-badge-EeCA_l-o.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-bar-chart-G7sEMSBY.mjs +140 -0
- package/fesm2022/tinya-code-gas-admin-ui-bar-chart-G7sEMSBY.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-boolean-B2ASKL0E.mjs +113 -0
- package/fesm2022/tinya-code-gas-admin-ui-boolean-B2ASKL0E.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-button-BQjNW8KB.mjs +163 -0
- package/fesm2022/tinya-code-gas-admin-ui-button-BQjNW8KB.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-calendar-view-DCY8bj2V.mjs +1027 -0
- package/fesm2022/tinya-code-gas-admin-ui-calendar-view-DCY8bj2V.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-chart-line-BjdlKHoH.mjs +278 -0
- package/fesm2022/tinya-code-gas-admin-ui-chart-line-BjdlKHoH.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-color-Dljh_By3.mjs +107 -0
- package/fesm2022/tinya-code-gas-admin-ui-color-Dljh_By3.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-condition-evaluator-DY2k1M3C.mjs +101 -0
- package/fesm2022/tinya-code-gas-admin-ui-condition-evaluator-DY2k1M3C.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-currency-BvuF3Z63.mjs +141 -0
- package/fesm2022/tinya-code-gas-admin-ui-currency-BvuF3Z63.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-data-source.service-96FSbN72.mjs +88 -0
- package/fesm2022/tinya-code-gas-admin-ui-data-source.service-96FSbN72.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-date-1SJGXZrd.mjs +107 -0
- package/fesm2022/tinya-code-gas-admin-ui-date-1SJGXZrd.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-badge-fwk6sDU7.mjs +140 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-badge-fwk6sDU7.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-date-D7zLiDiG.mjs +119 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-date-D7zLiDiG.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-file-BiIhqvQC.mjs +125 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-file-BiIhqvQC.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-image-C1dhnZi1.mjs +152 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-image-C1dhnZi1.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-list-DOEuUbGe.mjs +211 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-list-DOEuUbGe.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-number-DDMzr4Hn.mjs +116 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-number-DDMzr4Hn.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-text-B8CdVNpv.mjs +111 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-text-B8CdVNpv.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-dropdown-C3blvmE1.mjs +122 -0
- package/fesm2022/tinya-code-gas-admin-ui-dropdown-C3blvmE1.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-email-CT_O5ihA.mjs +107 -0
- package/fesm2022/tinya-code-gas-admin-ui-email-CT_O5ihA.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-empty-state-BMc0QtoT.mjs +109 -0
- package/fesm2022/tinya-code-gas-admin-ui-empty-state-BMc0QtoT.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-error-mapper.service-DY5y1FjE.mjs +45 -0
- package/fesm2022/tinya-code-gas-admin-ui-error-mapper.service-DY5y1FjE.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-field-aria-BD1Wiggc.mjs +50 -0
- package/fesm2022/tinya-code-gas-admin-ui-field-aria-BD1Wiggc.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-field-node-CIK6KNN_.mjs +24 -0
- package/fesm2022/tinya-code-gas-admin-ui-field-node-CIK6KNN_.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-field-path-B4-FTBGZ.mjs +27 -0
- package/fesm2022/tinya-code-gas-admin-ui-field-path-B4-FTBGZ.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-file-Dmxioog7.mjs +408 -0
- package/fesm2022/tinya-code-gas-admin-ui-file-Dmxioog7.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-form-view-CEe7aZ4m.mjs +4516 -0
- package/fesm2022/tinya-code-gas-admin-ui-form-view-CEe7aZ4m.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-badge-CK8ct5Wk.mjs +82 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-badge-CK8ct5Wk.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-boolean-ClzezZz-.mjs +105 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-boolean-ClzezZz-.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-currency-CVmniKml.mjs +65 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-currency-CVmniKml.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-date-Dr1YsDd_.mjs +65 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-date-Dr1YsDd_.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-number-CWCjpI4n.mjs +65 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-number-CWCjpI4n.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-text-DBOgJkH0.mjs +59 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-text-DBOgJkH0.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-thumbnail-PCRvxWKt.mjs +94 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-thumbnail-PCRvxWKt.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-gap-sorting-iTdy_DYG.mjs +72 -0
- package/fesm2022/tinya-code-gas-admin-ui-gap-sorting-iTdy_DYG.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-group-h7-O8tt4.mjs +238 -0
- package/fesm2022/tinya-code-gas-admin-ui-group-h7-O8tt4.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-image-7UhJ7nqI.mjs +416 -0
- package/fesm2022/tinya-code-gas-admin-ui-image-7UhJ7nqI.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-kanban-view-Dl0Ol5Kb.mjs +439 -0
- package/fesm2022/tinya-code-gas-admin-ui-kanban-view-Dl0Ol5Kb.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-key-value-nVdgg5at.mjs +513 -0
- package/fesm2022/tinya-code-gas-admin-ui-key-value-nVdgg5at.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-list-DTtCYS4d.mjs +637 -0
- package/fesm2022/tinya-code-gas-admin-ui-list-DTtCYS4d.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-metric-card-DnGMQL8l.mjs +127 -0
- package/fesm2022/tinya-code-gas-admin-ui-metric-card-DnGMQL8l.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-multiselect-PB28e-jl.mjs +251 -0
- package/fesm2022/tinya-code-gas-admin-ui-multiselect-PB28e-jl.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-notification.service-LjSULER6.mjs +66 -0
- package/fesm2022/tinya-code-gas-admin-ui-notification.service-LjSULER6.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-number-JNr7glc8.mjs +114 -0
- package/fesm2022/tinya-code-gas-admin-ui-number-JNr7glc8.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-phone-jR417hPf.mjs +116 -0
- package/fesm2022/tinya-code-gas-admin-ui-phone-jR417hPf.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-quick-actions-DCQ6emmF.mjs +235 -0
- package/fesm2022/tinya-code-gas-admin-ui-quick-actions-DCQ6emmF.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-radio-mode-DxvN07DY.mjs +8 -0
- package/fesm2022/tinya-code-gas-admin-ui-radio-mode-DxvN07DY.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-readonly-text-BL7-4qie.mjs +124 -0
- package/fesm2022/tinya-code-gas-admin-ui-readonly-text-BL7-4qie.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-record-list-BiZfnd_7.mjs +249 -0
- package/fesm2022/tinya-code-gas-admin-ui-record-list-BiZfnd_7.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-relation-drawer.service-B0kT8EiW.mjs +39 -0
- package/fesm2022/tinya-code-gas-admin-ui-relation-drawer.service-B0kT8EiW.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-relation-ykpJ3PYl.mjs +309 -0
- package/fesm2022/tinya-code-gas-admin-ui-relation-ykpJ3PYl.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-render-registry-B88Pme-y.mjs +576 -0
- package/fesm2022/tinya-code-gas-admin-ui-render-registry-B88Pme-y.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-rich-select-CIHaOrbU.mjs +161 -0
- package/fesm2022/tinya-code-gas-admin-ui-rich-select-CIHaOrbU.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-rolldown-runtime-DpJrqANO.mjs +11 -0
- package/fesm2022/tinya-code-gas-admin-ui-schema-catalog-D0Pk0wAN.mjs +685 -0
- package/fesm2022/tinya-code-gas-admin-ui-schema-catalog-D0Pk0wAN.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-seed-DkVZbxPP.mjs +80 -0
- package/fesm2022/tinya-code-gas-admin-ui-seed-DkVZbxPP.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-select-CDwX9yNO.mjs +296 -0
- package/fesm2022/tinya-code-gas-admin-ui-select-CDwX9yNO.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-skeleton-DnWK0tcZ.mjs +119 -0
- package/fesm2022/tinya-code-gas-admin-ui-skeleton-DnWK0tcZ.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-slug-DU58cbiY.mjs +158 -0
- package/fesm2022/tinya-code-gas-admin-ui-slug-DU58cbiY.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-source-options-B9R4mw8-.mjs +26 -0
- package/fesm2022/tinya-code-gas-admin-ui-source-options-B9R4mw8-.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-status-progress-DmeG8htE.mjs +205 -0
- package/fesm2022/tinya-code-gas-admin-ui-status-progress-DmeG8htE.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-string-list-gleasqzD.mjs +432 -0
- package/fesm2022/tinya-code-gas-admin-ui-string-list-gleasqzD.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-template-interpolator-ewv7CkNX.mjs +36 -0
- package/fesm2022/tinya-code-gas-admin-ui-template-interpolator-ewv7CkNX.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-text-CUPmL7W_.mjs +107 -0
- package/fesm2022/tinya-code-gas-admin-ui-text-CUPmL7W_.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-textarea-CGLSIW13.mjs +223 -0
- package/fesm2022/tinya-code-gas-admin-ui-textarea-CGLSIW13.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-time-BcHzsTWf.mjs +107 -0
- package/fesm2022/tinya-code-gas-admin-ui-time-BcHzsTWf.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-upload.service-CZPEPCeN.mjs +60 -0
- package/fesm2022/tinya-code-gas-admin-ui-upload.service-CZPEPCeN.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-url-GO4LZi__.mjs +141 -0
- package/fesm2022/tinya-code-gas-admin-ui-url-GO4LZi__.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui.mjs +4738 -0
- package/fesm2022/tinya-code-gas-admin-ui.mjs.map +1 -0
- package/package.json +15 -3
- package/types/tinya-code-gas-admin-ui.d.ts +3634 -0
- package/ng-package.json +0 -7
- package/src/lib/actions/action-registry.spec.ts +0 -52
- package/src/lib/actions/action-registry.ts +0 -126
- package/src/lib/actions/action-service.spec.ts +0 -215
- package/src/lib/actions/action-service.ts +0 -87
- package/src/lib/actions/descriptors.spec.ts +0 -155
- package/src/lib/actions/descriptors.ts +0 -154
- package/src/lib/columns/column-cell.ts +0 -33
- package/src/lib/columns/column-defaults.spec.ts +0 -99
- package/src/lib/columns/column-defaults.ts +0 -84
- package/src/lib/columns/column-format.spec.ts +0 -274
- package/src/lib/columns/descriptors.ts +0 -113
- package/src/lib/columns/format-badge.ts +0 -51
- package/src/lib/columns/format-boolean.ts +0 -58
- package/src/lib/columns/format-currency.ts +0 -30
- package/src/lib/columns/format-date.ts +0 -35
- package/src/lib/columns/format-number.ts +0 -32
- package/src/lib/columns/format-text.ts +0 -23
- package/src/lib/columns/format-thumbnail.ts +0 -63
- package/src/lib/core/adapters/firebase-auth.adapter.ts +0 -6
- package/src/lib/core/guards/auth.guard.spec.ts +0 -88
- package/src/lib/core/guards/auth.guard.ts +0 -48
- package/src/lib/core/guards/unsaved-changes.guard.ts +0 -16
- package/src/lib/core/interceptors/api-error.interceptor.spec.ts +0 -182
- package/src/lib/core/interceptors/api-error.interceptor.ts +0 -87
- package/src/lib/core/models/api.model.ts +0 -104
- package/src/lib/core/models/schema-descriptions.ts +0 -118
- package/src/lib/core/models/schema.model.ts +0 -1097
- package/src/lib/core/registry/composition-validator.spec.ts +0 -358
- package/src/lib/core/registry/composition-validator.ts +0 -270
- package/src/lib/core/registry/field-validators.spec.ts +0 -199
- package/src/lib/core/registry/field-validators.ts +0 -440
- package/src/lib/core/registry/render-host.spec.ts +0 -208
- package/src/lib/core/registry/render-host.ts +0 -646
- package/src/lib/core/registry/render-registry.spec.ts +0 -96
- package/src/lib/core/registry/render-registry.ts +0 -312
- package/src/lib/core/registry/schema-catalog.ts +0 -156
- package/src/lib/core/services/api.service.spec.ts +0 -1142
- package/src/lib/core/services/api.service.ts +0 -371
- package/src/lib/core/services/auth.service.spec.ts +0 -653
- package/src/lib/core/services/auth.service.ts +0 -503
- package/src/lib/core/services/config.service.spec.ts +0 -121
- package/src/lib/core/services/config.service.ts +0 -119
- package/src/lib/core/services/data-source.service.spec.ts +0 -179
- package/src/lib/core/services/data-source.service.ts +0 -142
- package/src/lib/core/services/error-mapper.service.spec.ts +0 -50
- package/src/lib/core/services/error-mapper.service.ts +0 -49
- package/src/lib/core/services/notification.service.ts +0 -73
- package/src/lib/core/services/relation-drawer.service.ts +0 -41
- package/src/lib/core/services/theme.service.spec.ts +0 -106
- package/src/lib/core/services/theme.service.ts +0 -86
- package/src/lib/core/services/transport.spec.ts +0 -198
- package/src/lib/core/services/transport.ts +0 -164
- package/src/lib/core/services/upload.service.ts +0 -81
- package/src/lib/core/testing/categories.schema.ts +0 -125
- package/src/lib/core/testing/orders.schema.ts +0 -372
- package/src/lib/core/testing/products.schema.ts +0 -258
- package/src/lib/core/testing/site.schema.ts +0 -195
- package/src/lib/core/testing/test-catalog.ts +0 -21
- package/src/lib/core/tokens.ts +0 -112
- package/src/lib/core/utils/clipboard.spec.ts +0 -55
- package/src/lib/core/utils/clipboard.ts +0 -90
- package/src/lib/core/utils/context-resolver.spec.ts +0 -95
- package/src/lib/core/utils/context-resolver.ts +0 -101
- package/src/lib/core/utils/response-unwrapper.spec.ts +0 -70
- package/src/lib/core/utils/response-unwrapper.ts +0 -103
- package/src/lib/core/utils/source-options.spec.ts +0 -96
- package/src/lib/core/utils/source-options.ts +0 -54
- package/src/lib/core/utils/template-interpolator.spec.ts +0 -59
- package/src/lib/core/utils/template-interpolator.ts +0 -56
- package/src/lib/core/view-navigation/view-navigation.service.spec.ts +0 -207
- package/src/lib/core/view-navigation/view-navigation.service.ts +0 -132
- package/src/lib/fields/boolean/boolean.descriptor.ts +0 -11
- package/src/lib/fields/boolean/boolean.ts +0 -40
- package/src/lib/fields/color/color.descriptor.ts +0 -12
- package/src/lib/fields/color/color.ts +0 -34
- package/src/lib/fields/currency/currency.descriptor.ts +0 -12
- package/src/lib/fields/currency/currency.ts +0 -67
- package/src/lib/fields/date/date.descriptor.ts +0 -12
- package/src/lib/fields/date/date.ts +0 -36
- package/src/lib/fields/descriptors.ts +0 -122
- package/src/lib/fields/display/display-badge.ts +0 -65
- package/src/lib/fields/display/display-date.ts +0 -39
- package/src/lib/fields/display/display-defaults.ts +0 -84
- package/src/lib/fields/display/display-file.ts +0 -41
- package/src/lib/fields/display/display-image.ts +0 -54
- package/src/lib/fields/display/display-list.ts +0 -107
- package/src/lib/fields/display/display-number.ts +0 -41
- package/src/lib/fields/display/display-text.ts +0 -42
- package/src/lib/fields/display/display.spec.ts +0 -242
- package/src/lib/fields/dropdown/dropdown.descriptor.ts +0 -12
- package/src/lib/fields/dropdown/dropdown.ts +0 -45
- package/src/lib/fields/email/email.descriptor.ts +0 -12
- package/src/lib/fields/email/email.ts +0 -28
- package/src/lib/fields/field-aria.ts +0 -60
- package/src/lib/fields/field-host/field-host.spec.ts +0 -118
- package/src/lib/fields/field-host/field-host.ts +0 -47
- package/src/lib/fields/field-node.ts +0 -88
- package/src/lib/fields/file/file.descriptor.ts +0 -14
- package/src/lib/fields/file/file.spec.ts +0 -134
- package/src/lib/fields/file/file.ts +0 -281
- package/src/lib/fields/group/group.descriptor.ts +0 -21
- package/src/lib/fields/group/group.ts +0 -110
- package/src/lib/fields/image/image.descriptor.ts +0 -12
- package/src/lib/fields/image/image.spec.ts +0 -117
- package/src/lib/fields/image/image.ts +0 -281
- package/src/lib/fields/key-value/key-value.descriptor.ts +0 -11
- package/src/lib/fields/key-value/key-value.ts +0 -283
- package/src/lib/fields/list/list.descriptor.ts +0 -21
- package/src/lib/fields/list/list.ts +0 -376
- package/src/lib/fields/multiselect/multiselect.descriptor.ts +0 -11
- package/src/lib/fields/multiselect/multiselect.spec.ts +0 -142
- package/src/lib/fields/multiselect/multiselect.ts +0 -152
- package/src/lib/fields/number/number.descriptor.ts +0 -12
- package/src/lib/fields/number/number.ts +0 -40
- package/src/lib/fields/phone/phone.descriptor.ts +0 -12
- package/src/lib/fields/phone/phone.ts +0 -46
- package/src/lib/fields/readonly-text/readonly-text.descriptor.ts +0 -12
- package/src/lib/fields/readonly-text/readonly-text.ts +0 -58
- package/src/lib/fields/relation/relation.descriptor.ts +0 -12
- package/src/lib/fields/relation/relation.spec.ts +0 -193
- package/src/lib/fields/relation/relation.ts +0 -224
- package/src/lib/fields/rich-select/rich-select.descriptor.ts +0 -12
- package/src/lib/fields/rich-select/rich-select.ts +0 -175
- package/src/lib/fields/select/radio-mode.ts +0 -25
- package/src/lib/fields/select/select.descriptor.ts +0 -12
- package/src/lib/fields/select/select.spec.ts +0 -162
- package/src/lib/fields/select/select.ts +0 -210
- package/src/lib/fields/slug/slug.descriptor.ts +0 -19
- package/src/lib/fields/slug/slug.ts +0 -67
- package/src/lib/fields/string-list/string-list.descriptor.ts +0 -11
- package/src/lib/fields/string-list/string-list.ts +0 -222
- package/src/lib/fields/text/text.descriptor.ts +0 -12
- package/src/lib/fields/text/text.ts +0 -35
- package/src/lib/fields/textarea/textarea.descriptor.ts +0 -12
- package/src/lib/fields/textarea/textarea.spec.ts +0 -117
- package/src/lib/fields/textarea/textarea.ts +0 -126
- package/src/lib/fields/time/time.descriptor.ts +0 -12
- package/src/lib/fields/time/time.ts +0 -28
- package/src/lib/fields/unknown-render/unknown-render.ts +0 -49
- package/src/lib/fields/url/url.descriptor.ts +0 -12
- package/src/lib/fields/url/url.ts +0 -53
- package/src/lib/gas-admin-ui.spec.ts +0 -21
- package/src/lib/gas-admin-ui.ts +0 -9
- package/src/lib/layouts/descriptors.ts +0 -9
- package/src/lib/pages/dashboard/dashboard.ts +0 -167
- package/src/lib/pages/detail-view/detail-view.spec.ts +0 -333
- package/src/lib/pages/detail-view/detail-view.ts +0 -570
- package/src/lib/pages/drawer-form/drawer-form.ts +0 -228
- package/src/lib/pages/form-view/form-model.ts +0 -88
- package/src/lib/pages/form-view/form-schema.ts +0 -255
- package/src/lib/pages/form-view/form-view.ts +0 -1622
- package/src/lib/pages/list-view/list-view.formats.spec.ts +0 -214
- package/src/lib/pages/list-view/list-view.ts +0 -882
- package/src/lib/pages/login/login.spec.ts +0 -109
- package/src/lib/pages/login/login.ts +0 -227
- package/src/lib/pages/resource-page/resource-page.ts +0 -234
- package/src/lib/shared/components/badge/badge.ts +0 -35
- package/src/lib/shared/components/button/button.ts +0 -65
- package/src/lib/shared/components/confirm-dialog/confirm-dialog.ts +0 -48
- package/src/lib/shared/components/copy-button/copy-button.ts +0 -56
- package/src/lib/shared/components/copy-share/copy-share.spec.ts +0 -122
- package/src/lib/shared/components/copy-share/copy-share.ts +0 -107
- package/src/lib/shared/components/drawer/drawer.spec.ts +0 -127
- package/src/lib/shared/components/drawer/drawer.ts +0 -172
- package/src/lib/shared/components/empty-state/empty-state.ts +0 -30
- package/src/lib/shared/components/modal/modal.spec.ts +0 -149
- package/src/lib/shared/components/modal/modal.ts +0 -145
- package/src/lib/shared/components/post-create-modal/post-create-modal.spec.ts +0 -165
- package/src/lib/shared/components/post-create-modal/post-create-modal.ts +0 -159
- package/src/lib/shared/components/skeleton/skeleton.ts +0 -31
- package/src/lib/shared/components/toast/toast.ts +0 -58
- package/src/lib/shared/utils/col-span.ts +0 -25
- package/src/lib/shared/utils/condition-evaluator.ts +0 -53
- package/src/lib/shared/utils/depends-on.ts +0 -48
- package/src/lib/shared/utils/dialog-focus.ts +0 -28
- package/src/lib/shared/utils/field-path.ts +0 -49
- package/src/lib/shared/utils/gap-sorting.ts +0 -144
- package/src/lib/shared/utils/seed.spec.ts +0 -64
- package/src/lib/shared/utils/seed.ts +0 -149
- package/src/lib/shared/utils/slugify.ts +0 -13
- package/src/lib/shared/utils/validators.ts +0 -41
- package/src/lib/shell/layout/layout.ts +0 -63
- package/src/lib/shell/shell.routes.spec.ts +0 -59
- package/src/lib/shell/shell.routes.ts +0 -122
- package/src/lib/shell/sidebar/sidebar.ts +0 -139
- package/src/lib/shell/theme-toggle/theme-toggle.ts +0 -74
- package/src/lib/views/calendar-view/calendar-model.ts +0 -426
- package/src/lib/views/calendar-view/calendar-view.spec.ts +0 -557
- package/src/lib/views/calendar-view/calendar-view.ts +0 -568
- package/src/lib/views/composer/composer-host.spec.ts +0 -301
- package/src/lib/views/composer/composer-host.ts +0 -248
- package/src/lib/views/composer/composer-imports.spec.ts +0 -54
- package/src/lib/views/composer/view-context.spec.ts +0 -117
- package/src/lib/views/composer/view-context.ts +0 -109
- package/src/lib/views/composer/view-slot.spec.ts +0 -130
- package/src/lib/views/composer/view-slot.ts +0 -178
- package/src/lib/views/descriptors.ts +0 -46
- package/src/lib/views/kanban-view/kanban-model.ts +0 -173
- package/src/lib/views/kanban-view/kanban-view.spec.ts +0 -540
- package/src/lib/views/kanban-view/kanban-view.ts +0 -327
- package/src/lib/widgets/bar-chart/bar-chart.descriptor.ts +0 -17
- package/src/lib/widgets/bar-chart/bar-chart.spec.ts +0 -66
- package/src/lib/widgets/bar-chart/bar-chart.ts +0 -76
- package/src/lib/widgets/chart-line/chart-line.descriptor.ts +0 -17
- package/src/lib/widgets/chart-line/chart-line.spec.ts +0 -113
- package/src/lib/widgets/chart-line/chart-line.ts +0 -219
- package/src/lib/widgets/descriptors.ts +0 -29
- package/src/lib/widgets/metric-card/metric-card.descriptor.ts +0 -41
- package/src/lib/widgets/metric-card/metric-card.spec.ts +0 -52
- package/src/lib/widgets/metric-card/metric-card.ts +0 -48
- package/src/lib/widgets/quick-actions/quick-actions.descriptor.ts +0 -13
- package/src/lib/widgets/quick-actions/quick-actions.spec.ts +0 -61
- package/src/lib/widgets/quick-actions/quick-actions.ts +0 -100
- package/src/lib/widgets/record-list/record-list.descriptor.ts +0 -16
- package/src/lib/widgets/record-list/record-list.spec.ts +0 -79
- package/src/lib/widgets/record-list/record-list.ts +0 -115
- package/src/lib/widgets/series.spec.ts +0 -42
- package/src/lib/widgets/series.ts +0 -56
- package/src/lib/widgets/status-progress/status-progress.descriptor.ts +0 -19
- package/src/lib/widgets/status-progress/status-progress.spec.ts +0 -63
- package/src/lib/widgets/status-progress/status-progress.ts +0 -104
- package/src/lib/widgets/widget-host/widget-host.spec.ts +0 -179
- package/src/lib/widgets/widget-host/widget-host.ts +0 -99
- package/src/public-api.ts +0 -104
- package/tinya-code-gas-admin-ui-0.2.0-alpha.15.tgz +0 -0
- package/tsconfig.lib.json +0 -13
- package/tsconfig.lib.prod.json +0 -11
- package/tsconfig.spec.json +0 -10
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
import { HttpClient, provideHttpClient, withInterceptors } from '@angular/common/http';
|
|
2
|
-
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
|
|
3
|
-
import { TestBed } from '@angular/core/testing';
|
|
4
|
-
import { provideRouter } from '@angular/router';
|
|
5
|
-
|
|
6
|
-
import { ApiError } from '../models/api.model';
|
|
7
|
-
import { API_URL } from '../tokens';
|
|
8
|
-
import { AuthService, SESSION_TOKEN_KEY, SESSION_USER_KEY } from '../services/auth.service';
|
|
9
|
-
import { apiErrorInterceptor } from './api-error.interceptor';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Emite `body` en el canal de éxito (el backend responde 200 con el error
|
|
13
|
-
* dentro) y devuelve el `ApiError` que el interceptor lanzó.
|
|
14
|
-
* A nivel de módulo: lo usan el describe de mensajes y el de R2.9.
|
|
15
|
-
*/
|
|
16
|
-
function errorFromBody(body: object): ApiError {
|
|
17
|
-
const http = TestBed.inject(HttpClient);
|
|
18
|
-
const mock = TestBed.inject(HttpTestingController);
|
|
19
|
-
let lanzado: unknown;
|
|
20
|
-
http.get('/recursos').subscribe({
|
|
21
|
-
error: (e: unknown) => {
|
|
22
|
-
lanzado = e;
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
mock.expectOne('/recursos').flush(body);
|
|
26
|
-
mock.verify();
|
|
27
|
-
return lanzado as ApiError;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Plan 7.3 — mensajes en lenguaje humano (guía §2).
|
|
32
|
-
*
|
|
33
|
-
* Dos canales distintos: el body del backend (que ya escribe en español) y
|
|
34
|
-
* el transporte (red caída, proxy, 5xx), que sin normalizar deja en pantalla
|
|
35
|
-
* el texto crudo de Angular: «Http failure response for http://…».
|
|
36
|
-
*
|
|
37
|
-
* **R2.9** — desde que el interceptor entrega los `AUTH_*` a
|
|
38
|
-
* `AuthService.applyAuthCode`, necesita poder inyectarlo: por eso acá hay
|
|
39
|
-
* router y `API_URL`, que son las dependencias de ese servicio.
|
|
40
|
-
*/
|
|
41
|
-
describe('apiErrorInterceptor — mensajes humanos', () => {
|
|
42
|
-
beforeEach(() => {
|
|
43
|
-
sessionStorage.clear();
|
|
44
|
-
TestBed.configureTestingModule({
|
|
45
|
-
providers: [
|
|
46
|
-
provideHttpClient(withInterceptors([apiErrorInterceptor])),
|
|
47
|
-
provideHttpClientTesting(),
|
|
48
|
-
provideRouter([]),
|
|
49
|
-
{ provide: API_URL, useValue: '/api' },
|
|
50
|
-
],
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
afterEach(() => sessionStorage.clear());
|
|
55
|
-
|
|
56
|
-
function failWith(status: number, body?: unknown): string {
|
|
57
|
-
const http = TestBed.inject(HttpClient);
|
|
58
|
-
const mock = TestBed.inject(HttpTestingController);
|
|
59
|
-
let message = '';
|
|
60
|
-
http.get('/recursos').subscribe({
|
|
61
|
-
error: (error: unknown) => {
|
|
62
|
-
message = error instanceof ApiError ? error.message : String(error);
|
|
63
|
-
},
|
|
64
|
-
});
|
|
65
|
-
const request = mock.expectOne('/recursos');
|
|
66
|
-
if (status === 0) {
|
|
67
|
-
// Red caída: el backend no llegó a responder.
|
|
68
|
-
request.error(new ErrorEvent('error'));
|
|
69
|
-
} else {
|
|
70
|
-
// `flush` con status fuera de 2xx materializa un `HttpErrorResponse`.
|
|
71
|
-
request.flush(body ?? '', { status, statusText: 'ERR' });
|
|
72
|
-
}
|
|
73
|
-
mock.verify();
|
|
74
|
-
return message;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
it('un 5xx se explica en español, no con el texto crudo de Angular', () => {
|
|
78
|
-
expect(failWith(500)).toBe(
|
|
79
|
-
'El servidor tuvo un problema. Vuelve a intentarlo en unos segundos.',
|
|
80
|
-
);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('la red caída (status 0) dice que no hubo conexión', () => {
|
|
84
|
-
expect(failWith(0)).toBe('No se pudo conectar con el servidor. Revisa tu conexión.');
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('un 403 habla de permisos', () => {
|
|
88
|
-
expect(failWith(403)).toBe('No tienes permisos para realizar esta acción.');
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('conserva el mensaje del backend cuando viene en el body (canal de éxito)', () => {
|
|
92
|
-
expect(
|
|
93
|
-
failWith(200, {
|
|
94
|
-
error: { status: 422, message: 'Ya existe un registro con este valor', path: 'name' },
|
|
95
|
-
}),
|
|
96
|
-
).toBe('Ya existe un registro con este valor');
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* D42 — el422 manda sus rutas en `error.errors[]`, NO en `path`: sin
|
|
101
|
-
* modelar esa lista el form veía «Errores de validación» y no pintaba
|
|
102
|
-
* ningún campo (base.md §5, guía §10).
|
|
103
|
-
*/
|
|
104
|
-
it('conserva errors[] completo (path, message, code) en el ApiError', () => {
|
|
105
|
-
const error = errorFromBody({
|
|
106
|
-
error: {
|
|
107
|
-
status: 422,
|
|
108
|
-
message: 'Errores de validación',
|
|
109
|
-
errors: [
|
|
110
|
-
{
|
|
111
|
-
path: 'sku',
|
|
112
|
-
message: 'Debe tener al menos 5 caracteres.',
|
|
113
|
-
code: 'VALIDATION_MIN_LENGTH',
|
|
114
|
-
},
|
|
115
|
-
{ path: 'faq[2].answer', message: 'Campo obligatorio.', code: 'VALIDATION_REQUIRED' },
|
|
116
|
-
],
|
|
117
|
-
},
|
|
118
|
-
});
|
|
119
|
-
expect(error.status).toBe(422);
|
|
120
|
-
expect(error.message).toBe('Errores de validación');
|
|
121
|
-
expect(error.issues).toEqual([
|
|
122
|
-
{ path: 'sku', message: 'Debe tener al menos 5 caracteres.', code: 'VALIDATION_MIN_LENGTH' },
|
|
123
|
-
{ path: 'faq[2].answer', message: 'Campo obligatorio.', code: 'VALIDATION_REQUIRED' },
|
|
124
|
-
]);
|
|
125
|
-
// Sin `path` en el sobre no hay fieldPath: las rutas vienen en los issues.
|
|
126
|
-
expect(error.fieldPath).toBeUndefined();
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* R2.9 — éste es el ÚNICO puente entre el sobre de error y la tabla de
|
|
132
|
-
* §4.5. Si el interceptor dejara de llamar a `applyAuthCode`, el front se
|
|
133
|
-
* quedaría en una pantalla caducada sin reloguear: por eso el puente se
|
|
134
|
-
* prueba acá y las cinco filas de la tabla, en `auth.service.spec.ts`.
|
|
135
|
-
*/
|
|
136
|
-
describe('apiErrorInterceptor — entrega de los códigos de sesión (R2.9)', () => {
|
|
137
|
-
beforeEach(() => {
|
|
138
|
-
sessionStorage.clear();
|
|
139
|
-
sessionStorage.setItem(SESSION_TOKEN_KEY, 'tok-vigente');
|
|
140
|
-
sessionStorage.setItem(SESSION_USER_KEY, JSON.stringify({ id: 'u_1', role: 'admin' }));
|
|
141
|
-
TestBed.configureTestingModule({
|
|
142
|
-
providers: [
|
|
143
|
-
provideHttpClient(withInterceptors([apiErrorInterceptor])),
|
|
144
|
-
provideHttpClientTesting(),
|
|
145
|
-
provideRouter([]),
|
|
146
|
-
{ provide: API_URL, useValue: '/api' },
|
|
147
|
-
],
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
afterEach(() => sessionStorage.clear());
|
|
152
|
-
|
|
153
|
-
it('conserva el `code` en el ApiError que recibe el llamador', () => {
|
|
154
|
-
const error = errorFromBody({
|
|
155
|
-
error: { status: 401, message: 'No autorizado', code: 'AUTH_EXPIRED' },
|
|
156
|
-
});
|
|
157
|
-
expect(error.code).toBe('AUTH_EXPIRED');
|
|
158
|
-
expect(error.status).toBe(401);
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
it('un error SIN código de sesión no toca la sesión', () => {
|
|
162
|
-
errorFromBody({ error: { status: 422, message: 'Datos no válidos', path: 'name' } });
|
|
163
|
-
expect(sessionStorage.getItem(SESSION_TOKEN_KEY)).toBe('tok-vigente');
|
|
164
|
-
expect(TestBed.inject(AuthService).isAuthenticated()).toBe(true);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it('FORBIDDEN deja al usuario DENTRO de la sesión (§4.5)', () => {
|
|
168
|
-
errorFromBody({ error: { status: 403, message: 'Prohibido', code: 'FORBIDDEN' } });
|
|
169
|
-
expect(sessionStorage.getItem(SESSION_TOKEN_KEY)).toBe('tok-vigente');
|
|
170
|
-
expect(TestBed.inject(AuthService).isAuthenticated()).toBe(true);
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
it('AUTH_INVALID borra token y usuario ANTES de nada más (§5.4)', () => {
|
|
174
|
-
errorFromBody({ error: { status: 401, message: 'No autorizado', code: 'AUTH_INVALID' } });
|
|
175
|
-
expect(sessionStorage.getItem(SESSION_TOKEN_KEY)).toBeNull();
|
|
176
|
-
expect(sessionStorage.getItem(SESSION_USER_KEY)).toBeNull();
|
|
177
|
-
const auth = TestBed.inject(AuthService);
|
|
178
|
-
expect(auth.token()).toBeNull();
|
|
179
|
-
expect(auth.user()).toBeNull();
|
|
180
|
-
expect(auth.isAuthenticated()).toBe(false);
|
|
181
|
-
});
|
|
182
|
-
});
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { HttpErrorResponse, HttpInterceptorFn, HttpResponse } from '@angular/common/http';
|
|
2
|
-
import { inject } from '@angular/core';
|
|
3
|
-
import { catchError, map, throwError } from 'rxjs';
|
|
4
|
-
|
|
5
|
-
import { ApiError } from '../models/api.model';
|
|
6
|
-
import type { ApiErrorBody } from '../models/api.model';
|
|
7
|
-
import { AuthService } from '../services/auth.service';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Mensaje humano para un error HTTP real (§2).
|
|
11
|
-
*
|
|
12
|
-
* El backend siempre responde 200 con el error dentro del body —eso ya
|
|
13
|
-
* viene en español—, así que esto sólo cubre lo que el transporte falla:
|
|
14
|
-
* red caída, proxy y 5xx. Sin esto el usuario ve el texto crudo de Angular
|
|
15
|
-
* («Http failure response for http://…»), que es inglés técnico.
|
|
16
|
-
*/
|
|
17
|
-
function httpMessage(status: number): string {
|
|
18
|
-
switch (status) {
|
|
19
|
-
case 0:
|
|
20
|
-
return 'No se pudo conectar con el servidor. Revisa tu conexión.';
|
|
21
|
-
case 401:
|
|
22
|
-
return 'Tu sesión ha expirado. Vuelve a iniciar sesión.';
|
|
23
|
-
case 403:
|
|
24
|
-
return 'No tienes permisos para realizar esta acción.';
|
|
25
|
-
case 404:
|
|
26
|
-
return 'No se encontró el recurso solicitado.';
|
|
27
|
-
case 409:
|
|
28
|
-
return 'El registro cambió o ya existe. Recarga la página y vuelve a intentarlo.';
|
|
29
|
-
case 413:
|
|
30
|
-
return 'El archivo es demasiado grande.';
|
|
31
|
-
case 422:
|
|
32
|
-
return 'Los datos enviados no son válidos.';
|
|
33
|
-
default:
|
|
34
|
-
if (status >= 500) {
|
|
35
|
-
return 'El servidor tuvo un problema. Vuelve a intentarlo en unos segundos.';
|
|
36
|
-
}
|
|
37
|
-
return status >= 400 ? 'No se pudo completar la operación.' : 'Error inesperado.';
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function isErrorBody(body: unknown): body is ApiErrorBody {
|
|
42
|
-
if (typeof body !== 'object' || body === null) {
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
const error = (body as ApiErrorBody).error;
|
|
46
|
-
return typeof error === 'object' && error !== null && typeof error.message === 'string';
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* El backend responde SIEMPRE HTTP 200 y pone los errores en el body
|
|
51
|
-
* (api.md §7), así que se detectan en el canal de **éxito** y se relanzan
|
|
52
|
-
* como `ApiError` (con `fieldPath` cuando el backend envía `path`).
|
|
53
|
-
* Los errores HTTP reales (red caída, proxy) también se normalizan.
|
|
54
|
-
*
|
|
55
|
-
* **R2.9 — paso dos de dos.** Éste archivo es el ÚNICO punto donde el
|
|
56
|
-
* sobre de error se abre; lo que decide qué ocurre con un `AUTH_*` es
|
|
57
|
-
* `AuthService.applyAuthCode` (la tabla de §4.5). Aquí sólo se le entrega
|
|
58
|
-
* el código y se propaga el `ApiError` con él — un segundo sitio que
|
|
59
|
-
* «interprete» el código sería una regla duplicada y, a la larga, una que
|
|
60
|
-
* se contradiga con la primera.
|
|
61
|
-
*/
|
|
62
|
-
export const apiErrorInterceptor: HttpInterceptorFn = (req, next) => {
|
|
63
|
-
const auth = inject(AuthService);
|
|
64
|
-
|
|
65
|
-
return next(req).pipe(
|
|
66
|
-
map((event) => {
|
|
67
|
-
if (event instanceof HttpResponse && isErrorBody(event.body)) {
|
|
68
|
-
const { status, message, path, code, errors } = event.body.error;
|
|
69
|
-
// R2.9: ésta es la ÚNICA llamada a la tabla de §4.5.
|
|
70
|
-
auth.applyAuthCode(code);
|
|
71
|
-
// `errors[]` es el422 con rutas (D42): va entero al ApiError para que
|
|
72
|
-
// `ErrorMapperService` lo convierta en `serverErrors[prefix + key]`.
|
|
73
|
-
throw new ApiError(status, message, path, code, errors ?? []);
|
|
74
|
-
}
|
|
75
|
-
return event;
|
|
76
|
-
}),
|
|
77
|
-
catchError((err: unknown) => {
|
|
78
|
-
if (err instanceof ApiError) {
|
|
79
|
-
return throwError(() => err);
|
|
80
|
-
}
|
|
81
|
-
if (err instanceof HttpErrorResponse) {
|
|
82
|
-
return throwError(() => new ApiError(err.status, httpMessage(err.status)));
|
|
83
|
-
}
|
|
84
|
-
return throwError(() => err);
|
|
85
|
-
}),
|
|
86
|
-
);
|
|
87
|
-
};
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Contrato HTTP con el backend (doc/baseapi.md §8 «Errores»).
|
|
3
|
-
*
|
|
4
|
-
* El backend responde SIEMPRE HTTP 200; los errores viajan en el body
|
|
5
|
-
* con `{ error: { status, message, errors?: [{ path, message }] } }`.
|
|
6
|
-
* El interceptor (Fase 3) los convierte en `ApiError`.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Un error con ruta del422 (auth.md §6): `path` para pintarlo en el campo y
|
|
11
|
-
* `code` MAYUS_SNAKE (`VALIDATION_MIN_LENGTH`) para mapearlo sin leer texto.
|
|
12
|
-
*/
|
|
13
|
-
export interface ApiIssue {
|
|
14
|
-
/** Ruta del campo afectado (`faq[2].answer`, `sku`). */
|
|
15
|
-
path: string;
|
|
16
|
-
/** Mensaje en español, listo para pintar. */
|
|
17
|
-
message: string;
|
|
18
|
-
/** Código estable del validador (B11); el mensaje puede cambiar, el código no. */
|
|
19
|
-
code?: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/** Shape del body de error (doc/baseapi.md §8 «Errores»). */
|
|
23
|
-
export interface ApiErrorBody {
|
|
24
|
-
error: {
|
|
25
|
-
status: number;
|
|
26
|
-
message: string;
|
|
27
|
-
/** Ruta del campo afectado cuando el backend la envía (base.md §10). */
|
|
28
|
-
path?: string;
|
|
29
|
-
/**
|
|
30
|
-
* Código de sesión de §4.5 (R2.9): `AUTH_REQUIRED` · `AUTH_INVALID` ·
|
|
31
|
-
* `AUTH_EXPIRED` · `FORBIDDEN` · `RATE_LIMITED`. Aparece SÓLO en esas
|
|
32
|
-
* cinco respuestas — el sobre de error es aditivo (O7 / D10-5).
|
|
33
|
-
*/
|
|
34
|
-
code?: string;
|
|
35
|
-
/**
|
|
36
|
-
* Errores de validación con ruta (base.md §5, guía §10): el 422 los manda
|
|
37
|
-
* ACÁ (`error.errors[]`), no en `path`. Sin modelarlos el form veía
|
|
38
|
-
* «Errores de validación» genérico y ningún campo se pintaba (D42).
|
|
39
|
-
*/
|
|
40
|
-
errors?: ApiIssue[];
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** Error de API estandarizado que lanza el interceptor de errores. */
|
|
45
|
-
export class ApiError extends Error {
|
|
46
|
-
readonly status: number;
|
|
47
|
-
/** Ruta del campo que provocó el error (ej. `faq[2].answer`), si existe. */
|
|
48
|
-
readonly fieldPath?: string;
|
|
49
|
-
/** Código de sesión de §4.5 si el backend lo envió; `undefined` en el resto. */
|
|
50
|
-
readonly code?: string;
|
|
51
|
-
/** Issues con ruta (422); vacío cuando el error no trae `errors[]`. */
|
|
52
|
-
readonly issues: readonly ApiIssue[];
|
|
53
|
-
|
|
54
|
-
constructor(
|
|
55
|
-
status: number,
|
|
56
|
-
message: string,
|
|
57
|
-
fieldPath?: string,
|
|
58
|
-
code?: string,
|
|
59
|
-
issues: readonly ApiIssue[] = [],
|
|
60
|
-
) {
|
|
61
|
-
super(message);
|
|
62
|
-
this.name = 'ApiError';
|
|
63
|
-
this.status = status;
|
|
64
|
-
this.fieldPath = fieldPath;
|
|
65
|
-
this.code = code;
|
|
66
|
-
this.issues = issues;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* `meta.renewedToken` (auth.md §3.2/§3.4): el back lo adjunta a la respuesta
|
|
72
|
-
* cuando la vida del token bajó del umbral de renovación. Es el ÚNICO modo
|
|
73
|
-
* de que el front se entere — el token nuevo no viaja en cabeceras ni en la
|
|
74
|
-
* URL. Devuelve `null` cuando no hay renovación (que es lo normal).
|
|
75
|
-
*
|
|
76
|
-
* Vive acá y no en el `ApiService` porque lo consumen DOS servicios
|
|
77
|
-
* (`ApiService` y `AuthService`) y éste modelo no importa a ninguno de los
|
|
78
|
-
* dos: sin este archivo no hay ciclo de imports.
|
|
79
|
-
*/
|
|
80
|
-
export function renewedTokenOf(body: unknown): string | null {
|
|
81
|
-
if (body === null || typeof body !== 'object') return null;
|
|
82
|
-
const meta = (body as { meta?: unknown }).meta;
|
|
83
|
-
if (meta === null || typeof meta !== 'object') return null;
|
|
84
|
-
const token = (meta as { renewedToken?: unknown }).renewedToken;
|
|
85
|
-
return typeof token === 'string' && token !== '' ? token : null;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Resultado de una página para `ApiService.listPage()`.
|
|
90
|
-
*
|
|
91
|
-
* El backend envía la metadata de paginación dentro del sobre (típicamente
|
|
92
|
-
* en `meta`); el motor la extrae según la declaración `responseUnwrap.pagination`
|
|
93
|
-
* y la entrega en este shape. `list()` NO usa este tipo: sigue devolviendo `T[]`.
|
|
94
|
-
*/
|
|
95
|
-
export interface PageResult<T> {
|
|
96
|
-
/** Registros de la página actual. */
|
|
97
|
-
items: T[];
|
|
98
|
-
/** Cursor para pedir la página siguiente; `null` cuando no hay más. */
|
|
99
|
-
nextCursor: string | null;
|
|
100
|
-
/** Total de registros del conjunto, si el backend lo informa; `0` si no. */
|
|
101
|
-
total: number;
|
|
102
|
-
/** `true` si hay al menos una página más. `false` sin cursor informativo. */
|
|
103
|
-
hasMore: boolean;
|
|
104
|
-
}
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Descripciones centralizadas del catálogo de campos del motor `@tinya-code/gas-admin-ui`.
|
|
3
|
-
*
|
|
4
|
-
* Este archivo es el único lugar donde se editan los textos descriptivos de
|
|
5
|
-
* cada propiedad del schema. Los JSDoc de `schema.model.ts` usan estos mismos
|
|
6
|
-
* textos para que el editor (VSCode) muestre tooltips al pasar el cursor
|
|
7
|
-
* sobre una propiedad del schema del consumidor.
|
|
8
|
-
*
|
|
9
|
-
* Estructura: clave de propiedad → descripción en español.
|
|
10
|
-
*
|
|
11
|
-
* Uso en el consumidor (loyalty-admin, etc.):
|
|
12
|
-
* import { schemaDescriptions } from '@tinya-code/gas-admin-ui';
|
|
13
|
-
* schemaDescriptions['docLink']; // 'URL de documentación externa para este campo.'
|
|
14
|
-
*
|
|
15
|
-
* Nota: este objeto no se renderiza en la UI; solo existe para documentación
|
|
16
|
-
* y tooltips del editor. Para renderizar tooltips en el formulario usa
|
|
17
|
-
* `description` en cada campo del schema del consumidor.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
export const schemaDescriptions = {
|
|
21
|
-
// ── Propiedades comunes a todo campo (FieldBase) ───────────────────────
|
|
22
|
-
key: 'Nombre de la propiedad en el JSON que envía/recibe el back.',
|
|
23
|
-
label: 'Rótulo visible para el usuario en el formulario y la ficha.',
|
|
24
|
-
help: 'Texto corto de ayuda que se muestra debajo del campo.',
|
|
25
|
-
placeholder: 'Texto sugerente que se muestra dentro del input cuando está vacío.',
|
|
26
|
-
required: 'Si es obligatorio. El back también lo valida (R7.4).',
|
|
27
|
-
default: 'Valor por defecto si el registro no trae este campo (ej. `default: "none"` en un `select`/`dropdown`).',
|
|
28
|
-
readonly: 'Si el campo es solo lectura (no editable en el formulario).',
|
|
29
|
-
readonlyOn: 'Bloquea el campo solo en creación, solo en edición o siempre.',
|
|
30
|
-
readonlyWhen: 'Condición bajo la cual el campo es solo lectura (expresión sobre otros campos).',
|
|
31
|
-
visibleWhen: 'Condición bajo la cual el campo se muestra u oculta.',
|
|
32
|
-
hiddenOn: 'Oculta el campo en creación, en edición o siempre.',
|
|
33
|
-
dependsOn: 'Selección dependiente (guía §1: país → ciudad). Clave del campo padre del mismo nivel.',
|
|
34
|
-
validators: 'Reglas de validación (mínimo, máximo, patrón, unicidad, etc.).',
|
|
35
|
-
width: 'Ancho en la grilla del formulario (1–12), igual que un widget del dashboard.',
|
|
36
|
-
section: 'Id de la sección/pestaña del layout a la que pertenece (base.md §4).',
|
|
37
|
-
read: 'Código de nivel de acceso requerido para leer el campo.',
|
|
38
|
-
write: 'Código de nivel de acceso requerido para escribir el campo.',
|
|
39
|
-
description: 'Descripción corta de para qué sirve este campo. Se muestra como tooltip al pasar el cursor sobre el rótulo.',
|
|
40
|
-
docLink: 'URL de documentación externa para este campo (se abre al hacer clic en el tooltip).',
|
|
41
|
-
|
|
42
|
-
// ── Opciones de select/dropdown ───────────────────────────────────────
|
|
43
|
-
value: 'Valor que se envía al back cuando se elige esta opción.',
|
|
44
|
-
labelOption: 'Texto visible de la opción.',
|
|
45
|
-
disabled: 'Si la opción está deshabilitada (no se puede elegir).',
|
|
46
|
-
|
|
47
|
-
// ── Campos específicos ─────────────────────────────────────────────────
|
|
48
|
-
type: 'Tipo de campo: `text`, `color`, `number`, `currency`, `boolean`, `select`, `dropdown`, `rich-select`, `multiselect`, `url`, `email`, `phone`, `date`, `time`, `readonly-text`, `slug`, `textarea`, `relation`, `image`, `file`, `group`, `list`, `string-list`, `key-value`.',
|
|
49
|
-
maxLength: 'Longitud máxima de caracteres permitida.',
|
|
50
|
-
pattern: 'Expresión regular que debe cumplir el valor.',
|
|
51
|
-
rows: 'Número de filas visibles del textarea.',
|
|
52
|
-
minWords: 'Cantidad mínima de palabras.',
|
|
53
|
-
maxWords: 'Cantidad máxima de palabras.',
|
|
54
|
-
tokens: 'Marcadores insertables como chips bajo el área (plantillas de mensaje).',
|
|
55
|
-
from: 'Campo del registro del que se autogenera el slug.',
|
|
56
|
-
lockAfterCreate: 'Bloquea el campo una vez creado el registro (por defecto: sí).',
|
|
57
|
-
min: 'Valor mínimo permitido.',
|
|
58
|
-
max: 'Valor máximo permitido.',
|
|
59
|
-
step: 'Incremento entre valores permitidos.',
|
|
60
|
-
decimals: 'Número de decimales mostrados.',
|
|
61
|
-
currencyFrom: 'Campo del registro del que se toma la moneda (ej. `currency`).',
|
|
62
|
-
trueLabel: 'Texto que se muestra cuando el valor es verdadero.',
|
|
63
|
-
falseLabel: 'Texto que se muestra cuando el valor es falso.',
|
|
64
|
-
source: 'De dónde salen las opciones: `{ resource, view?, params?, … }` (F8 · R6.5).',
|
|
65
|
-
resource: 'Recurso declarado (`resource.id`): su listado es el de las opciones.',
|
|
66
|
-
view: 'Vista declarada en `resource.views` (opcional): filtra en el back.',
|
|
67
|
-
params: 'Valores interpolados para la vista (`{campo}` ← contexto).',
|
|
68
|
-
labelField: 'Etiqueta por defecto de las filas (si no, `titleField` del recurso).',
|
|
69
|
-
valueField: 'Valor por defecto de las filas (si no, `keyField` del recurso).',
|
|
70
|
-
secondaryField: 'Segundo dato a mostrar junto a la etiqueta (ej. "Juan Pérez · DNI 123").',
|
|
71
|
-
onlyActive: 'Cargar solo registros activos (lo exige además la FK en el back).',
|
|
72
|
-
accept: 'Tipos aceptados (ej. `image/*`, `image/png,image/jpeg` o `pdf,docx`).',
|
|
73
|
-
maxSizeMB: 'Tamaño máximo del archivo en megabytes.',
|
|
74
|
-
aspectRatio: 'Relación de aspecto de la vista previa (ej. `16/9`).',
|
|
75
|
-
previewSize: 'Tamaño de la vista previa.',
|
|
76
|
-
formatCurrency: 'Campo del registro del que se toma la moneda (ej. `currency`).',
|
|
77
|
-
display: 'Presentación del grupo: `card`, `collapsible` o `inline`.',
|
|
78
|
-
fields: 'Campos de cada item (cualquier tipo, incluso `group` o `list`).',
|
|
79
|
-
minItems: 'Cantidad mínima de items.',
|
|
80
|
-
maxItems: 'Cantidad máxima de items.',
|
|
81
|
-
sortable: 'Si se puede reordenar (por defecto: sí).',
|
|
82
|
-
positionField: 'Campo donde se guarda el orden dentro de cada item (`position`).',
|
|
83
|
-
addLabel: 'Etiqueta del botón para agregar un item nuevo.',
|
|
84
|
-
emptyText: 'Texto que se muestra cuando no hay items.',
|
|
85
|
-
itemDisplay: 'Cómo se muestra cada item: `card`, `row` o `accordion`.',
|
|
86
|
-
itemFields: 'Campos de cada item (cualquier tipo, incluso `group` o `list`).',
|
|
87
|
-
itemTitle: 'Campo del item usado como título cuando está colapsado.',
|
|
88
|
-
primaryFirst: 'El primer item tiene significado especial (ej. imagen principal).',
|
|
89
|
-
itemType: 'Tipo permitido de cada item (base.md §9: solo `text`, `url` o `email`).',
|
|
90
|
-
sort: 'Si la lista se ordena alfabéticamente o por posición.',
|
|
91
|
-
filter: 'Si el listado permite filtrado por texto.',
|
|
92
|
-
search: 'Campos buscables en el listado.',
|
|
93
|
-
filters: 'Filtros declarados para el listado.',
|
|
94
|
-
listColumns: 'Columnas que se muestran en el listado.',
|
|
95
|
-
searchable: 'Si el campo es buscable.',
|
|
96
|
-
filterable: 'Si el campo es filtrable.',
|
|
97
|
-
sortableItems: 'Si los items de la lista se pueden reordenar.',
|
|
98
|
-
groupBy: 'Campo por el que agrupar los items.',
|
|
99
|
-
cardWidth: 'Ancho de cada tarjeta de opción en la grilla (1–12). Por defecto `4` (3 tarjetas por fila en escritorio).',
|
|
100
|
-
cardCols: 'Cuántas tarjetas mostrar por fila en el punto de ruptura `lg`. Sobrescribe el cálculo automático basado en `cardWidth`.',
|
|
101
|
-
hintMetric: 'Texto secundario bajo la cifra (estático, va en el schema).',
|
|
102
|
-
unitChart: 'Sufijo de las cifras del eje («unidades», «S/»).',
|
|
103
|
-
segments: 'Segmentos de la barra de distribución porcentual.',
|
|
104
|
-
actions: 'Acciones de navegación por fila.',
|
|
105
|
-
labelAction: 'Etiqueta de la acción.',
|
|
106
|
-
icon: 'Icono de la acción.',
|
|
107
|
-
navigateTo: 'Ruta de destino de la acción.',
|
|
108
|
-
variant: 'Variante visual: `primary`, `secondary` u `outline`.',
|
|
109
|
-
|
|
110
|
-
// ── Widgets de dashboard ──────────────────────────────────────────────
|
|
111
|
-
widgets: 'Widgets del panel. Se declara en `ResourceSchema.widgets` — no en `fields`, porque un KPI no es un campo.',
|
|
112
|
-
mobileWidth: 'Ancho en la grilla en mobile (1–12). Por defecto `12` (ancho completo, apilado).',
|
|
113
|
-
sourceWidget: 'De dónde saca sus datos: `DataSource` o `{ kind: "payload" }`.',
|
|
114
|
-
hintWidget: 'Texto secundario bajo la cifra (estático, va en el schema).',
|
|
115
|
-
unitWidget: 'Sufijo de las cifras del eje.',
|
|
116
|
-
} as const;
|
|
117
|
-
|
|
118
|
-
export type SchemaDescriptionKey = keyof typeof schemaDescriptions;
|