@tinya-code/gas-admin-ui 0.2.0-alpha.13 → 0.2.0-alpha.15
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/ng-package.json +7 -0
- package/package.json +3 -15
- package/src/lib/actions/action-registry.spec.ts +52 -0
- package/src/lib/actions/action-registry.ts +126 -0
- package/src/lib/actions/action-service.spec.ts +215 -0
- package/src/lib/actions/action-service.ts +87 -0
- package/src/lib/actions/descriptors.spec.ts +155 -0
- package/src/lib/actions/descriptors.ts +154 -0
- package/src/lib/columns/column-cell.ts +33 -0
- package/src/lib/columns/column-defaults.spec.ts +99 -0
- package/src/lib/columns/column-defaults.ts +84 -0
- package/src/lib/columns/column-format.spec.ts +274 -0
- package/src/lib/columns/descriptors.ts +113 -0
- package/src/lib/columns/format-badge.ts +51 -0
- package/src/lib/columns/format-boolean.ts +58 -0
- package/src/lib/columns/format-currency.ts +30 -0
- package/src/lib/columns/format-date.ts +35 -0
- package/src/lib/columns/format-number.ts +32 -0
- package/src/lib/columns/format-text.ts +23 -0
- package/src/lib/columns/format-thumbnail.ts +63 -0
- package/src/lib/core/adapters/firebase-auth.adapter.ts +6 -0
- package/src/lib/core/guards/auth.guard.spec.ts +88 -0
- package/src/lib/core/guards/auth.guard.ts +48 -0
- package/src/lib/core/guards/unsaved-changes.guard.ts +16 -0
- package/src/lib/core/interceptors/api-error.interceptor.spec.ts +182 -0
- package/src/lib/core/interceptors/api-error.interceptor.ts +87 -0
- package/src/lib/core/models/api.model.ts +104 -0
- package/src/lib/core/models/schema-descriptions.ts +118 -0
- package/src/lib/core/models/schema.model.ts +1097 -0
- package/src/lib/core/registry/composition-validator.spec.ts +358 -0
- package/src/lib/core/registry/composition-validator.ts +270 -0
- package/src/lib/core/registry/field-validators.spec.ts +199 -0
- package/src/lib/core/registry/field-validators.ts +440 -0
- package/src/lib/core/registry/render-host.spec.ts +208 -0
- package/src/lib/core/registry/render-host.ts +646 -0
- package/src/lib/core/registry/render-registry.spec.ts +96 -0
- package/src/lib/core/registry/render-registry.ts +312 -0
- package/src/lib/core/registry/schema-catalog.ts +156 -0
- package/src/lib/core/services/api.service.spec.ts +1142 -0
- package/src/lib/core/services/api.service.ts +371 -0
- package/src/lib/core/services/auth.service.spec.ts +653 -0
- package/src/lib/core/services/auth.service.ts +503 -0
- package/src/lib/core/services/config.service.spec.ts +121 -0
- package/src/lib/core/services/config.service.ts +119 -0
- package/src/lib/core/services/data-source.service.spec.ts +179 -0
- package/src/lib/core/services/data-source.service.ts +142 -0
- package/src/lib/core/services/error-mapper.service.spec.ts +50 -0
- package/src/lib/core/services/error-mapper.service.ts +49 -0
- package/src/lib/core/services/notification.service.ts +73 -0
- package/src/lib/core/services/relation-drawer.service.ts +41 -0
- package/src/lib/core/services/theme.service.spec.ts +106 -0
- package/src/lib/core/services/theme.service.ts +86 -0
- package/src/lib/core/services/transport.spec.ts +198 -0
- package/src/lib/core/services/transport.ts +164 -0
- package/src/lib/core/services/upload.service.ts +81 -0
- package/src/lib/core/testing/categories.schema.ts +125 -0
- package/src/lib/core/testing/orders.schema.ts +372 -0
- package/src/lib/core/testing/products.schema.ts +258 -0
- package/src/lib/core/testing/site.schema.ts +195 -0
- package/src/lib/core/testing/test-catalog.ts +21 -0
- package/src/lib/core/tokens.ts +112 -0
- package/src/lib/core/utils/clipboard.spec.ts +55 -0
- package/src/lib/core/utils/clipboard.ts +90 -0
- package/src/lib/core/utils/context-resolver.spec.ts +95 -0
- package/src/lib/core/utils/context-resolver.ts +101 -0
- package/src/lib/core/utils/response-unwrapper.spec.ts +70 -0
- package/src/lib/core/utils/response-unwrapper.ts +103 -0
- package/src/lib/core/utils/source-options.spec.ts +96 -0
- package/src/lib/core/utils/source-options.ts +54 -0
- package/src/lib/core/utils/template-interpolator.spec.ts +59 -0
- package/src/lib/core/utils/template-interpolator.ts +56 -0
- package/src/lib/core/view-navigation/view-navigation.service.spec.ts +207 -0
- package/src/lib/core/view-navigation/view-navigation.service.ts +132 -0
- package/src/lib/fields/boolean/boolean.descriptor.ts +11 -0
- package/src/lib/fields/boolean/boolean.ts +40 -0
- package/src/lib/fields/color/color.descriptor.ts +12 -0
- package/src/lib/fields/color/color.ts +34 -0
- package/src/lib/fields/currency/currency.descriptor.ts +12 -0
- package/src/lib/fields/currency/currency.ts +67 -0
- package/src/lib/fields/date/date.descriptor.ts +12 -0
- package/src/lib/fields/date/date.ts +36 -0
- package/src/lib/fields/descriptors.ts +122 -0
- package/src/lib/fields/display/display-badge.ts +65 -0
- package/src/lib/fields/display/display-date.ts +39 -0
- package/src/lib/fields/display/display-defaults.ts +84 -0
- package/src/lib/fields/display/display-file.ts +41 -0
- package/src/lib/fields/display/display-image.ts +54 -0
- package/src/lib/fields/display/display-list.ts +107 -0
- package/src/lib/fields/display/display-number.ts +41 -0
- package/src/lib/fields/display/display-text.ts +42 -0
- package/src/lib/fields/display/display.spec.ts +242 -0
- package/src/lib/fields/dropdown/dropdown.descriptor.ts +12 -0
- package/src/lib/fields/dropdown/dropdown.ts +45 -0
- package/src/lib/fields/email/email.descriptor.ts +12 -0
- package/src/lib/fields/email/email.ts +28 -0
- package/src/lib/fields/field-aria.ts +60 -0
- package/src/lib/fields/field-host/field-host.spec.ts +118 -0
- package/src/lib/fields/field-host/field-host.ts +47 -0
- package/src/lib/fields/field-node.ts +88 -0
- package/src/lib/fields/file/file.descriptor.ts +14 -0
- package/src/lib/fields/file/file.spec.ts +134 -0
- package/src/lib/fields/file/file.ts +281 -0
- package/src/lib/fields/group/group.descriptor.ts +21 -0
- package/src/lib/fields/group/group.ts +110 -0
- package/src/lib/fields/image/image.descriptor.ts +12 -0
- package/src/lib/fields/image/image.spec.ts +117 -0
- package/src/lib/fields/image/image.ts +281 -0
- package/src/lib/fields/key-value/key-value.descriptor.ts +11 -0
- package/src/lib/fields/key-value/key-value.ts +283 -0
- package/src/lib/fields/list/list.descriptor.ts +21 -0
- package/src/lib/fields/list/list.ts +376 -0
- package/src/lib/fields/multiselect/multiselect.descriptor.ts +11 -0
- package/src/lib/fields/multiselect/multiselect.spec.ts +142 -0
- package/src/lib/fields/multiselect/multiselect.ts +152 -0
- package/src/lib/fields/number/number.descriptor.ts +12 -0
- package/src/lib/fields/number/number.ts +40 -0
- package/src/lib/fields/phone/phone.descriptor.ts +12 -0
- package/src/lib/fields/phone/phone.ts +46 -0
- package/src/lib/fields/readonly-text/readonly-text.descriptor.ts +12 -0
- package/src/lib/fields/readonly-text/readonly-text.ts +58 -0
- package/src/lib/fields/relation/relation.descriptor.ts +12 -0
- package/src/lib/fields/relation/relation.spec.ts +193 -0
- package/src/lib/fields/relation/relation.ts +224 -0
- package/src/lib/fields/rich-select/rich-select.descriptor.ts +12 -0
- package/src/lib/fields/rich-select/rich-select.ts +175 -0
- package/src/lib/fields/select/radio-mode.ts +25 -0
- package/src/lib/fields/select/select.descriptor.ts +12 -0
- package/src/lib/fields/select/select.spec.ts +162 -0
- package/src/lib/fields/select/select.ts +210 -0
- package/src/lib/fields/slug/slug.descriptor.ts +19 -0
- package/src/lib/fields/slug/slug.ts +67 -0
- package/src/lib/fields/string-list/string-list.descriptor.ts +11 -0
- package/src/lib/fields/string-list/string-list.ts +222 -0
- package/src/lib/fields/text/text.descriptor.ts +12 -0
- package/src/lib/fields/text/text.ts +35 -0
- package/src/lib/fields/textarea/textarea.descriptor.ts +12 -0
- package/src/lib/fields/textarea/textarea.spec.ts +117 -0
- package/src/lib/fields/textarea/textarea.ts +126 -0
- package/src/lib/fields/time/time.descriptor.ts +12 -0
- package/src/lib/fields/time/time.ts +28 -0
- package/src/lib/fields/unknown-render/unknown-render.ts +49 -0
- package/src/lib/fields/url/url.descriptor.ts +12 -0
- package/src/lib/fields/url/url.ts +53 -0
- package/src/lib/gas-admin-ui.spec.ts +21 -0
- package/src/lib/gas-admin-ui.ts +9 -0
- package/src/lib/layouts/descriptors.ts +9 -0
- package/src/lib/pages/dashboard/dashboard.ts +167 -0
- package/src/lib/pages/detail-view/detail-view.spec.ts +333 -0
- package/src/lib/pages/detail-view/detail-view.ts +570 -0
- package/src/lib/pages/drawer-form/drawer-form.ts +228 -0
- package/src/lib/pages/form-view/form-model.ts +88 -0
- package/src/lib/pages/form-view/form-schema.ts +255 -0
- package/src/lib/pages/form-view/form-view.ts +1622 -0
- package/src/lib/pages/list-view/list-view.formats.spec.ts +214 -0
- package/src/lib/pages/list-view/list-view.ts +882 -0
- package/src/lib/pages/login/login.spec.ts +109 -0
- package/src/lib/pages/login/login.ts +227 -0
- package/src/lib/pages/resource-page/resource-page.ts +234 -0
- package/src/lib/shared/components/badge/badge.ts +35 -0
- package/src/lib/shared/components/button/button.ts +65 -0
- package/src/lib/shared/components/confirm-dialog/confirm-dialog.ts +48 -0
- package/src/lib/shared/components/copy-button/copy-button.ts +56 -0
- package/src/lib/shared/components/copy-share/copy-share.spec.ts +122 -0
- package/src/lib/shared/components/copy-share/copy-share.ts +107 -0
- package/src/lib/shared/components/drawer/drawer.spec.ts +127 -0
- package/src/lib/shared/components/drawer/drawer.ts +172 -0
- package/src/lib/shared/components/empty-state/empty-state.ts +30 -0
- package/src/lib/shared/components/modal/modal.spec.ts +149 -0
- package/src/lib/shared/components/modal/modal.ts +145 -0
- package/src/lib/shared/components/post-create-modal/post-create-modal.spec.ts +165 -0
- package/src/lib/shared/components/post-create-modal/post-create-modal.ts +159 -0
- package/src/lib/shared/components/skeleton/skeleton.ts +31 -0
- package/src/lib/shared/components/toast/toast.ts +58 -0
- package/src/lib/shared/utils/col-span.ts +25 -0
- package/src/lib/shared/utils/condition-evaluator.ts +53 -0
- package/src/lib/shared/utils/depends-on.ts +48 -0
- package/src/lib/shared/utils/dialog-focus.ts +28 -0
- package/src/lib/shared/utils/field-path.ts +49 -0
- package/src/lib/shared/utils/gap-sorting.ts +144 -0
- package/src/lib/shared/utils/seed.spec.ts +64 -0
- package/src/lib/shared/utils/seed.ts +149 -0
- package/src/lib/shared/utils/slugify.ts +13 -0
- package/src/lib/shared/utils/validators.ts +41 -0
- package/src/lib/shell/layout/layout.ts +63 -0
- package/src/lib/shell/shell.routes.spec.ts +59 -0
- package/src/lib/shell/shell.routes.ts +122 -0
- package/src/lib/shell/sidebar/sidebar.ts +139 -0
- package/src/lib/shell/theme-toggle/theme-toggle.ts +74 -0
- package/src/lib/views/calendar-view/calendar-model.ts +426 -0
- package/src/lib/views/calendar-view/calendar-view.spec.ts +557 -0
- package/src/lib/views/calendar-view/calendar-view.ts +568 -0
- package/src/lib/views/composer/composer-host.spec.ts +301 -0
- package/src/lib/views/composer/composer-host.ts +248 -0
- package/src/lib/views/composer/composer-imports.spec.ts +54 -0
- package/src/lib/views/composer/view-context.spec.ts +117 -0
- package/src/lib/views/composer/view-context.ts +109 -0
- package/src/lib/views/composer/view-slot.spec.ts +130 -0
- package/src/lib/views/composer/view-slot.ts +178 -0
- package/src/lib/views/descriptors.ts +46 -0
- package/src/lib/views/kanban-view/kanban-model.ts +173 -0
- package/src/lib/views/kanban-view/kanban-view.spec.ts +540 -0
- package/src/lib/views/kanban-view/kanban-view.ts +327 -0
- package/src/lib/widgets/bar-chart/bar-chart.descriptor.ts +17 -0
- package/src/lib/widgets/bar-chart/bar-chart.spec.ts +66 -0
- package/src/lib/widgets/bar-chart/bar-chart.ts +76 -0
- package/src/lib/widgets/chart-line/chart-line.descriptor.ts +17 -0
- package/src/lib/widgets/chart-line/chart-line.spec.ts +113 -0
- package/src/lib/widgets/chart-line/chart-line.ts +219 -0
- package/src/lib/widgets/descriptors.ts +29 -0
- package/src/lib/widgets/metric-card/metric-card.descriptor.ts +41 -0
- package/src/lib/widgets/metric-card/metric-card.spec.ts +52 -0
- package/src/lib/widgets/metric-card/metric-card.ts +48 -0
- package/src/lib/widgets/quick-actions/quick-actions.descriptor.ts +13 -0
- package/src/lib/widgets/quick-actions/quick-actions.spec.ts +61 -0
- package/src/lib/widgets/quick-actions/quick-actions.ts +100 -0
- package/src/lib/widgets/record-list/record-list.descriptor.ts +16 -0
- package/src/lib/widgets/record-list/record-list.spec.ts +79 -0
- package/src/lib/widgets/record-list/record-list.ts +115 -0
- package/src/lib/widgets/series.spec.ts +42 -0
- package/src/lib/widgets/series.ts +56 -0
- package/src/lib/widgets/status-progress/status-progress.descriptor.ts +19 -0
- package/src/lib/widgets/status-progress/status-progress.spec.ts +63 -0
- package/src/lib/widgets/status-progress/status-progress.ts +104 -0
- package/src/lib/widgets/widget-host/widget-host.spec.ts +179 -0
- package/src/lib/widgets/widget-host/widget-host.ts +99 -0
- package/src/public-api.ts +104 -0
- package/tinya-code-gas-admin-ui-0.2.0-alpha.15.tgz +0 -0
- package/tsconfig.lib.json +13 -0
- package/tsconfig.lib.prod.json +11 -0
- package/tsconfig.spec.json +10 -0
- package/fesm2022/tinya-code-gas-admin-ui-badge-EeCA_l-o.mjs +0 -84
- package/fesm2022/tinya-code-gas-admin-ui-badge-EeCA_l-o.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-bar-chart-G7sEMSBY.mjs +0 -140
- package/fesm2022/tinya-code-gas-admin-ui-bar-chart-G7sEMSBY.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-boolean-B2ASKL0E.mjs +0 -113
- package/fesm2022/tinya-code-gas-admin-ui-boolean-B2ASKL0E.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-button-BQjNW8KB.mjs +0 -163
- package/fesm2022/tinya-code-gas-admin-ui-button-BQjNW8KB.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-calendar-view-DCY8bj2V.mjs +0 -1027
- package/fesm2022/tinya-code-gas-admin-ui-calendar-view-DCY8bj2V.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-chart-line-BjdlKHoH.mjs +0 -278
- package/fesm2022/tinya-code-gas-admin-ui-chart-line-BjdlKHoH.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-color-Dljh_By3.mjs +0 -107
- package/fesm2022/tinya-code-gas-admin-ui-color-Dljh_By3.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-condition-evaluator-DY2k1M3C.mjs +0 -101
- package/fesm2022/tinya-code-gas-admin-ui-condition-evaluator-DY2k1M3C.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-currency-BvuF3Z63.mjs +0 -141
- package/fesm2022/tinya-code-gas-admin-ui-currency-BvuF3Z63.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-data-source.service-96FSbN72.mjs +0 -88
- package/fesm2022/tinya-code-gas-admin-ui-data-source.service-96FSbN72.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-date-1SJGXZrd.mjs +0 -107
- package/fesm2022/tinya-code-gas-admin-ui-date-1SJGXZrd.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-display-badge-fwk6sDU7.mjs +0 -140
- package/fesm2022/tinya-code-gas-admin-ui-display-badge-fwk6sDU7.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-display-date-D7zLiDiG.mjs +0 -119
- package/fesm2022/tinya-code-gas-admin-ui-display-date-D7zLiDiG.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-display-file-BiIhqvQC.mjs +0 -125
- package/fesm2022/tinya-code-gas-admin-ui-display-file-BiIhqvQC.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-display-image-C1dhnZi1.mjs +0 -152
- package/fesm2022/tinya-code-gas-admin-ui-display-image-C1dhnZi1.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-display-list-DOEuUbGe.mjs +0 -211
- package/fesm2022/tinya-code-gas-admin-ui-display-list-DOEuUbGe.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-display-number-DDMzr4Hn.mjs +0 -116
- package/fesm2022/tinya-code-gas-admin-ui-display-number-DDMzr4Hn.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-display-text-B8CdVNpv.mjs +0 -111
- package/fesm2022/tinya-code-gas-admin-ui-display-text-B8CdVNpv.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-dropdown-C3blvmE1.mjs +0 -122
- package/fesm2022/tinya-code-gas-admin-ui-dropdown-C3blvmE1.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-email-CT_O5ihA.mjs +0 -107
- package/fesm2022/tinya-code-gas-admin-ui-email-CT_O5ihA.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-empty-state-BMc0QtoT.mjs +0 -109
- package/fesm2022/tinya-code-gas-admin-ui-empty-state-BMc0QtoT.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-error-mapper.service-DY5y1FjE.mjs +0 -45
- package/fesm2022/tinya-code-gas-admin-ui-error-mapper.service-DY5y1FjE.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-field-aria-BD1Wiggc.mjs +0 -50
- package/fesm2022/tinya-code-gas-admin-ui-field-aria-BD1Wiggc.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-field-node-CIK6KNN_.mjs +0 -24
- package/fesm2022/tinya-code-gas-admin-ui-field-node-CIK6KNN_.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-field-path-B4-FTBGZ.mjs +0 -27
- package/fesm2022/tinya-code-gas-admin-ui-field-path-B4-FTBGZ.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-file-Dmxioog7.mjs +0 -408
- package/fesm2022/tinya-code-gas-admin-ui-file-Dmxioog7.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-form-view-C709rc57.mjs +0 -4516
- package/fesm2022/tinya-code-gas-admin-ui-form-view-C709rc57.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-format-badge-CK8ct5Wk.mjs +0 -82
- package/fesm2022/tinya-code-gas-admin-ui-format-badge-CK8ct5Wk.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-format-boolean-ClzezZz-.mjs +0 -105
- package/fesm2022/tinya-code-gas-admin-ui-format-boolean-ClzezZz-.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-format-currency-CVmniKml.mjs +0 -65
- package/fesm2022/tinya-code-gas-admin-ui-format-currency-CVmniKml.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-format-date-Dr1YsDd_.mjs +0 -65
- package/fesm2022/tinya-code-gas-admin-ui-format-date-Dr1YsDd_.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-format-number-CWCjpI4n.mjs +0 -65
- package/fesm2022/tinya-code-gas-admin-ui-format-number-CWCjpI4n.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-format-text-DBOgJkH0.mjs +0 -59
- package/fesm2022/tinya-code-gas-admin-ui-format-text-DBOgJkH0.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-format-thumbnail-PCRvxWKt.mjs +0 -94
- package/fesm2022/tinya-code-gas-admin-ui-format-thumbnail-PCRvxWKt.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-gap-sorting-iTdy_DYG.mjs +0 -72
- package/fesm2022/tinya-code-gas-admin-ui-gap-sorting-iTdy_DYG.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-group-h7-O8tt4.mjs +0 -238
- package/fesm2022/tinya-code-gas-admin-ui-group-h7-O8tt4.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-image-7UhJ7nqI.mjs +0 -416
- package/fesm2022/tinya-code-gas-admin-ui-image-7UhJ7nqI.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-kanban-view-Dl0Ol5Kb.mjs +0 -439
- package/fesm2022/tinya-code-gas-admin-ui-kanban-view-Dl0Ol5Kb.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-key-value-nVdgg5at.mjs +0 -513
- package/fesm2022/tinya-code-gas-admin-ui-key-value-nVdgg5at.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-list-C8ijJHAx.mjs +0 -637
- package/fesm2022/tinya-code-gas-admin-ui-list-C8ijJHAx.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-metric-card-DnGMQL8l.mjs +0 -127
- package/fesm2022/tinya-code-gas-admin-ui-metric-card-DnGMQL8l.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-multiselect-PB28e-jl.mjs +0 -251
- package/fesm2022/tinya-code-gas-admin-ui-multiselect-PB28e-jl.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-notification.service-LjSULER6.mjs +0 -66
- package/fesm2022/tinya-code-gas-admin-ui-notification.service-LjSULER6.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-number-JNr7glc8.mjs +0 -114
- package/fesm2022/tinya-code-gas-admin-ui-number-JNr7glc8.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-phone-jR417hPf.mjs +0 -116
- package/fesm2022/tinya-code-gas-admin-ui-phone-jR417hPf.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-quick-actions-DCQ6emmF.mjs +0 -235
- package/fesm2022/tinya-code-gas-admin-ui-quick-actions-DCQ6emmF.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-radio-mode-DxvN07DY.mjs +0 -8
- package/fesm2022/tinya-code-gas-admin-ui-radio-mode-DxvN07DY.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-readonly-text-BL7-4qie.mjs +0 -124
- package/fesm2022/tinya-code-gas-admin-ui-readonly-text-BL7-4qie.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-record-list-BiZfnd_7.mjs +0 -249
- package/fesm2022/tinya-code-gas-admin-ui-record-list-BiZfnd_7.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-relation-drawer.service-B0kT8EiW.mjs +0 -39
- package/fesm2022/tinya-code-gas-admin-ui-relation-drawer.service-B0kT8EiW.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-relation-ykpJ3PYl.mjs +0 -309
- package/fesm2022/tinya-code-gas-admin-ui-relation-ykpJ3PYl.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-render-registry-CULkxrSt.mjs +0 -576
- package/fesm2022/tinya-code-gas-admin-ui-render-registry-CULkxrSt.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-rich-select-CIHaOrbU.mjs +0 -161
- package/fesm2022/tinya-code-gas-admin-ui-rich-select-CIHaOrbU.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-rolldown-runtime-DpJrqANO.mjs +0 -11
- package/fesm2022/tinya-code-gas-admin-ui-schema-catalog-D0Pk0wAN.mjs +0 -685
- package/fesm2022/tinya-code-gas-admin-ui-schema-catalog-D0Pk0wAN.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-seed-CcCA3FdQ.mjs +0 -80
- package/fesm2022/tinya-code-gas-admin-ui-seed-CcCA3FdQ.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-select-CDwX9yNO.mjs +0 -296
- package/fesm2022/tinya-code-gas-admin-ui-select-CDwX9yNO.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-skeleton-DnWK0tcZ.mjs +0 -119
- package/fesm2022/tinya-code-gas-admin-ui-skeleton-DnWK0tcZ.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-slug-DU58cbiY.mjs +0 -158
- package/fesm2022/tinya-code-gas-admin-ui-slug-DU58cbiY.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-source-options-B9R4mw8-.mjs +0 -26
- package/fesm2022/tinya-code-gas-admin-ui-source-options-B9R4mw8-.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-status-progress-DmeG8htE.mjs +0 -205
- package/fesm2022/tinya-code-gas-admin-ui-status-progress-DmeG8htE.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-string-list-gleasqzD.mjs +0 -432
- package/fesm2022/tinya-code-gas-admin-ui-string-list-gleasqzD.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-template-interpolator-ewv7CkNX.mjs +0 -36
- package/fesm2022/tinya-code-gas-admin-ui-template-interpolator-ewv7CkNX.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-text-CUPmL7W_.mjs +0 -107
- package/fesm2022/tinya-code-gas-admin-ui-text-CUPmL7W_.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-textarea-CGLSIW13.mjs +0 -223
- package/fesm2022/tinya-code-gas-admin-ui-textarea-CGLSIW13.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-time-BcHzsTWf.mjs +0 -107
- package/fesm2022/tinya-code-gas-admin-ui-time-BcHzsTWf.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-upload.service-CZPEPCeN.mjs +0 -60
- package/fesm2022/tinya-code-gas-admin-ui-upload.service-CZPEPCeN.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-url-GO4LZi__.mjs +0 -141
- package/fesm2022/tinya-code-gas-admin-ui-url-GO4LZi__.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui.mjs +0 -4599
- package/fesm2022/tinya-code-gas-admin-ui.mjs.map +0 -1
- package/types/tinya-code-gas-admin-ui.d.ts +0 -3632
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { RenderDescriptor } from '../core/registry/render-registry';
|
|
2
|
+
import type { FieldType } from '../core/models/schema.model';
|
|
3
|
+
|
|
4
|
+
import { descriptor as booleanDescriptor } from './boolean/boolean.descriptor';
|
|
5
|
+
import { descriptor as colorDescriptor } from './color/color.descriptor';
|
|
6
|
+
import { descriptor as currencyDescriptor } from './currency/currency.descriptor';
|
|
7
|
+
import { descriptor as dateDescriptor } from './date/date.descriptor';
|
|
8
|
+
import { descriptor as emailDescriptor } from './email/email.descriptor';
|
|
9
|
+
import { descriptor as fileDescriptor } from './file/file.descriptor';
|
|
10
|
+
import { descriptor as groupDescriptor } from './group/group.descriptor';
|
|
11
|
+
import { descriptor as imageDescriptor } from './image/image.descriptor';
|
|
12
|
+
import { descriptor as keyValueDescriptor } from './key-value/key-value.descriptor';
|
|
13
|
+
import { descriptor as listDescriptor } from './list/list.descriptor';
|
|
14
|
+
import { descriptor as multiselectDescriptor } from './multiselect/multiselect.descriptor';
|
|
15
|
+
import { descriptor as numberDescriptor } from './number/number.descriptor';
|
|
16
|
+
import { descriptor as phoneDescriptor } from './phone/phone.descriptor';
|
|
17
|
+
import { descriptor as readonlyTextDescriptor } from './readonly-text/readonly-text.descriptor';
|
|
18
|
+
import { descriptor as relationDescriptor } from './relation/relation.descriptor';
|
|
19
|
+
import { descriptor as richSelectDescriptor } from './rich-select/rich-select.descriptor';
|
|
20
|
+
import { descriptor as selectDescriptor } from './select/select.descriptor';
|
|
21
|
+
import { descriptor as dropdownDescriptor } from './dropdown/dropdown.descriptor';
|
|
22
|
+
import { descriptor as slugDescriptor } from './slug/slug.descriptor';
|
|
23
|
+
import { descriptor as stringListDescriptor } from './string-list/string-list.descriptor';
|
|
24
|
+
import { descriptor as textDescriptor } from './text/text.descriptor';
|
|
25
|
+
import { descriptor as textareaDescriptor } from './textarea/textarea.descriptor';
|
|
26
|
+
import { descriptor as timeDescriptor } from './time/time.descriptor';
|
|
27
|
+
import { descriptor as urlDescriptor } from './url/url.descriptor';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Tripwire de compilación (R1.7 · D17): que la unión `FieldType` y los
|
|
31
|
+
* tipos que la UI sabe dibujar sigan diciendo lo mismo.
|
|
32
|
+
*
|
|
33
|
+
* · un valor que no esté en la unión `FieldSchema` ⇒ `satisfies` falla;
|
|
34
|
+
* · un tipo de la unión que falte acá ⇒ `FaltaEnLaUi` no es `never`.
|
|
35
|
+
*
|
|
36
|
+
* **No es una fuente de verdad en runtime.** El catálogo vive en
|
|
37
|
+
* `core/registry/render-registry.ts`, alimentado por los descriptores de
|
|
38
|
+
* abajo. Esta lista sólo existe para que `npm run build` y `npm test` vean
|
|
39
|
+
* la aserción por igual, sin depender de que un test la ejecute.
|
|
40
|
+
*
|
|
41
|
+
* **Exportada en R3.7** para que `core/registry/contract.spec.ts` pueda
|
|
42
|
+
* verificar además el sentido que este archivo no cubre — que cada nombre de
|
|
43
|
+
* la lista tenga **descriptor**: aquí sólo se comprueba que está en la unión,
|
|
44
|
+
* y un tipo declarado en la lista pero ausente del manifiesto se vería en el
|
|
45
|
+
* primer schema que lo use.
|
|
46
|
+
*
|
|
47
|
+
* **Mudado acá en R3.8.** Vivía en `field-host/field-host.ts`, y §0 es
|
|
48
|
+
* explícito: «si añadir un tipo obliga a editar `FieldHost`, el motor no
|
|
49
|
+
* está terminado». Estaba sin uso en runtime — sólo servía a este tripwire —
|
|
50
|
+
* así que trasladarlo acá no cambia comportamiento y deja el registro y su
|
|
51
|
+
* aserción en el **mismo archivo**: añadir un tipo toca una carpeta y una
|
|
52
|
+
* línea de este manifiesto, y el host no se entera.
|
|
53
|
+
*/
|
|
54
|
+
export const SUPPORTED_FIELD_TYPE_LIST = [
|
|
55
|
+
'text',
|
|
56
|
+
'textarea',
|
|
57
|
+
'slug',
|
|
58
|
+
'number',
|
|
59
|
+
'currency',
|
|
60
|
+
'boolean',
|
|
61
|
+
'select',
|
|
62
|
+
'multiselect',
|
|
63
|
+
'url',
|
|
64
|
+
'email',
|
|
65
|
+
'phone',
|
|
66
|
+
'date',
|
|
67
|
+
'time',
|
|
68
|
+
'readonly-text',
|
|
69
|
+
'group',
|
|
70
|
+
'list',
|
|
71
|
+
'string-list',
|
|
72
|
+
'key-value',
|
|
73
|
+
'relation',
|
|
74
|
+
'image',
|
|
75
|
+
'file',
|
|
76
|
+
'color',
|
|
77
|
+
'rich-select',
|
|
78
|
+
'dropdown',
|
|
79
|
+
] as const satisfies readonly FieldType[];
|
|
80
|
+
|
|
81
|
+
type FaltaEnLaUi = Exclude<FieldType, (typeof SUPPORTED_FIELD_TYPE_LIST)[number]>;
|
|
82
|
+
const _exhaustivo: FaltaEnLaUi extends never
|
|
83
|
+
? true
|
|
84
|
+
: ['Falta en SUPPORTED_FIELD_TYPE_LIST', FaltaEnLaUi] = true;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Manifiesto de descriptores de campo (R3.3 · registro único de render).
|
|
88
|
+
*
|
|
89
|
+
* Una línea por tipo: el registro los recoge al importar este módulo. Es la
|
|
90
|
+
* **única** lista manual del catálogo de campos — `import.meta.glob` no
|
|
91
|
+
* sobrevive a `ng build`, así que D9-1 se resuelve con «registro manual de
|
|
92
|
+
* una línea». Ver `core/registry/render-registry.ts`.
|
|
93
|
+
*
|
|
94
|
+
* Añadir un tipo de campo ⇒ crear la carpeta + su `.descriptor.ts` + una
|
|
95
|
+
* línea acá. **Ningún host se toca** (R3.8).
|
|
96
|
+
*/
|
|
97
|
+
export const fieldDescriptors: readonly RenderDescriptor[] = [
|
|
98
|
+
booleanDescriptor,
|
|
99
|
+
colorDescriptor,
|
|
100
|
+
currencyDescriptor,
|
|
101
|
+
dateDescriptor,
|
|
102
|
+
emailDescriptor,
|
|
103
|
+
fileDescriptor,
|
|
104
|
+
groupDescriptor,
|
|
105
|
+
imageDescriptor,
|
|
106
|
+
keyValueDescriptor,
|
|
107
|
+
listDescriptor,
|
|
108
|
+
multiselectDescriptor,
|
|
109
|
+
numberDescriptor,
|
|
110
|
+
phoneDescriptor,
|
|
111
|
+
readonlyTextDescriptor,
|
|
112
|
+
relationDescriptor,
|
|
113
|
+
selectDescriptor,
|
|
114
|
+
slugDescriptor,
|
|
115
|
+
stringListDescriptor,
|
|
116
|
+
textDescriptor,
|
|
117
|
+
textareaDescriptor,
|
|
118
|
+
timeDescriptor,
|
|
119
|
+
urlDescriptor,
|
|
120
|
+
richSelectDescriptor,
|
|
121
|
+
dropdownDescriptor,
|
|
122
|
+
];
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Component, computed, input } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
import { Badge, type BadgeKind } from '../../shared/components/badge/badge';
|
|
4
|
+
import type { FieldSchema, SelectField } from '../../core/models/schema.model';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Display por defecto de `boolean` y `select` (R4.1 · modo `display`).
|
|
8
|
+
*
|
|
9
|
+
* Absorbe `formatValue` + `resolveBadgeKind` de `detail-view` (R4.2): los
|
|
10
|
+
* estados siguen clasificándose con el mismo vocabulario —
|
|
11
|
+
* `PENDIENTE/WAITING/EN_PROCESO/PROCESSING` en `warning`,
|
|
12
|
+
* `ENTREGADO/DELIVERED/…` en `success`, `CANCELADO/REVOCADA/ERROR/…` en
|
|
13
|
+
* `danger` y el resto en `neutral` — porque es el criterio que el operador
|
|
14
|
+
* ya reconoce en la cabecera de la ficha.
|
|
15
|
+
*
|
|
16
|
+
* `boolean` pinta `Sí`/`No` con `success`/`neutral` (la paridad de R4.2);
|
|
17
|
+
* los `trueLabel`/`falseLabel` del schema siguen siendo cosa del control de
|
|
18
|
+
* **edición**, y de la columna de lista (R4.3), que sí los usa.
|
|
19
|
+
*/
|
|
20
|
+
@Component({
|
|
21
|
+
selector: 'app-field-display-badge',
|
|
22
|
+
imports: [Badge],
|
|
23
|
+
template: `<app-badge [label]="label()" [kind]="kind()" />`,
|
|
24
|
+
})
|
|
25
|
+
export class FieldDisplayBadge {
|
|
26
|
+
readonly field = input.required<FieldSchema>();
|
|
27
|
+
readonly value = input<unknown>(null);
|
|
28
|
+
/** El chip de la cabecera ya es este componente: se ignora. */
|
|
29
|
+
readonly chip = input(false);
|
|
30
|
+
|
|
31
|
+
protected readonly label = computed(() => {
|
|
32
|
+
if (this.field().type === 'boolean') {
|
|
33
|
+
return this.value() ? 'Sí' : 'No';
|
|
34
|
+
}
|
|
35
|
+
const opciones = (this.field() as SelectField).options ?? [];
|
|
36
|
+
const encontrada = opciones.find((o) => o.value === String(this.value()));
|
|
37
|
+
return encontrada ? encontrada.label : String(this.value());
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
protected readonly kind = computed<BadgeKind>(() => {
|
|
41
|
+
if (this.field().type === 'boolean') {
|
|
42
|
+
return this.value() ? 'success' : 'neutral';
|
|
43
|
+
}
|
|
44
|
+
return resolveBadgeKind(String(this.value()));
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Clasificación de estados, común al display de detalle (acá) y al
|
|
50
|
+
* timeline del historial (`display-list`). Exportada para que R4.3 pueda
|
|
51
|
+
* reusarla si la columna de lista decide alinearse con este criterio.
|
|
52
|
+
*/
|
|
53
|
+
export function resolveBadgeKind(valor: string): BadgeKind {
|
|
54
|
+
const upper = String(valor).toUpperCase();
|
|
55
|
+
if (['PENDIENTE', 'WAITING', 'EN_PROCESO', 'PROCESSING'].includes(upper)) return 'warning';
|
|
56
|
+
if (
|
|
57
|
+
['ENTREGADO', 'DELIVERED', 'ACTIVA', 'ACTIVE', 'COMPLETADO', 'SUCCESS', 'SI', 'SÍ'].includes(
|
|
58
|
+
upper,
|
|
59
|
+
)
|
|
60
|
+
)
|
|
61
|
+
return 'success';
|
|
62
|
+
if (['CANCELADO', 'CANCELLED', 'REVOCADA', 'REVOKED', 'ERROR', 'NO'].includes(upper))
|
|
63
|
+
return 'danger';
|
|
64
|
+
return 'neutral';
|
|
65
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Component, computed, input } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
import { Badge } from '../../shared/components/badge/badge';
|
|
4
|
+
import type { FieldSchema } from '../../core/models/schema.model';
|
|
5
|
+
|
|
6
|
+
const FORMATO_FECHA = new Intl.DateTimeFormat('es-PE', { dateStyle: 'medium', timeZone: 'UTC' });
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Display por defecto de `date` (R4.1 · modo `display`).
|
|
10
|
+
*
|
|
11
|
+
* Misma fórmula que `formatValue` de `detail-view` antes de R4.2: `es-PE`,
|
|
12
|
+
* `dateStyle: 'medium'`, **UTC** para que la fecha no se corra un día según
|
|
13
|
+
* el huso de quien abra la ficha, y texto crudo si no es parseable.
|
|
14
|
+
*/
|
|
15
|
+
@Component({
|
|
16
|
+
selector: 'app-field-display-date',
|
|
17
|
+
imports: [Badge],
|
|
18
|
+
template: `
|
|
19
|
+
@if (chip()) {
|
|
20
|
+
<app-badge [label]="texto()" />
|
|
21
|
+
} @else {
|
|
22
|
+
{{ texto() }}
|
|
23
|
+
}
|
|
24
|
+
`,
|
|
25
|
+
})
|
|
26
|
+
export class FieldDisplayDate {
|
|
27
|
+
readonly field = input.required<FieldSchema>();
|
|
28
|
+
readonly value = input<unknown>(null);
|
|
29
|
+
/** `true` en la cabecera: la fecha se pinta como chip compacto. */
|
|
30
|
+
readonly chip = input(false);
|
|
31
|
+
|
|
32
|
+
protected readonly texto = computed(() => {
|
|
33
|
+
const d = new Date(String(this.value()));
|
|
34
|
+
if (Number.isNaN(d.getTime())) {
|
|
35
|
+
return String(this.value());
|
|
36
|
+
}
|
|
37
|
+
return FORMATO_FECHA.format(d);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { Type } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
import type { FieldType } from '../../core/models/schema.model';
|
|
4
|
+
|
|
5
|
+
/** Carga perezosa del componente que pinta un valor en modo `display`. */
|
|
6
|
+
export type DisplayLoader = () => Promise<Type<any>>;
|
|
7
|
+
|
|
8
|
+
const TEXTO: DisplayLoader = () =>
|
|
9
|
+
import('./display-text').then((module) => module.FieldDisplayText);
|
|
10
|
+
const FECHA: DisplayLoader = () =>
|
|
11
|
+
import('./display-date').then((module) => module.FieldDisplayDate);
|
|
12
|
+
const NUMERO: DisplayLoader = () =>
|
|
13
|
+
import('./display-number').then((module) => module.FieldDisplayNumber);
|
|
14
|
+
const BADGE: DisplayLoader = () =>
|
|
15
|
+
import('./display-badge').then((module) => module.FieldDisplayBadge);
|
|
16
|
+
const IMAGEN: DisplayLoader = () =>
|
|
17
|
+
import('./display-image').then((module) => module.FieldDisplayImage);
|
|
18
|
+
const ARCHIVO: DisplayLoader = () =>
|
|
19
|
+
import('./display-file').then((module) => module.FieldDisplayFile);
|
|
20
|
+
const LISTA: DisplayLoader = () =>
|
|
21
|
+
import('./display-list').then((module) => module.FieldDisplayList);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* **Tabla de display por defecto según `field.type`** (F3 de
|
|
25
|
+
* `doc/refactormotor.md`, R4.1 del plan): «cada descriptor declara si sabe
|
|
26
|
+
* pintarse en `display`; si no, usa un `display` por defecto según tipo».
|
|
27
|
+
*
|
|
28
|
+
* La declaración vive en el descriptor (`surfaces: ['form', 'display']`) y
|
|
29
|
+
* el componente sale de acá: un solo sitio decide qué pinta cada tipo en la
|
|
30
|
+
* ficha de detalle. Es la misma familia de cambio que la tabla de formato
|
|
31
|
+
* de columna de R4.4 — «declarada, no implícita».
|
|
32
|
+
*
|
|
33
|
+
* `Record<FieldType, …>` es el **tripwire de exhaustividad en compilación**:
|
|
34
|
+
* un tipo nuevo obliga a elegir su display antes de que el build pase, y un
|
|
35
|
+
* tipo retirado obliga a limpiar la entrada. En runtime el acceso pasa por
|
|
36
|
+
* `displayLoader()`, que no lanza si el `type` viene de un schema mal
|
|
37
|
+
* escrito.
|
|
38
|
+
*
|
|
39
|
+
* Paridad con el `formatValue` que vivía en `detail-view` (R4.2):
|
|
40
|
+
* `text/textarea/slug/url/email/phone/readonly-text/relation/group/
|
|
41
|
+
* key-value/string-list/multiselect/time` → texto crudo · `date` → fecha ·
|
|
42
|
+
* `number/currency` → número · `boolean/select` → badge · `image` →
|
|
43
|
+
* miniatura · `list` → timeline.
|
|
44
|
+
*/
|
|
45
|
+
const DISPLAY_POR_DEFECTO: Record<FieldType, DisplayLoader> = {
|
|
46
|
+
text: TEXTO,
|
|
47
|
+
textarea: TEXTO,
|
|
48
|
+
slug: TEXTO,
|
|
49
|
+
url: TEXTO,
|
|
50
|
+
email: TEXTO,
|
|
51
|
+
phone: TEXTO,
|
|
52
|
+
'readonly-text': TEXTO,
|
|
53
|
+
relation: TEXTO,
|
|
54
|
+
group: TEXTO,
|
|
55
|
+
'key-value': TEXTO,
|
|
56
|
+
'string-list': TEXTO,
|
|
57
|
+
multiselect: TEXTO,
|
|
58
|
+
time: TEXTO,
|
|
59
|
+
date: FECHA,
|
|
60
|
+
number: NUMERO,
|
|
61
|
+
currency: NUMERO,
|
|
62
|
+
boolean: BADGE,
|
|
63
|
+
select: BADGE,
|
|
64
|
+
image: IMAGEN,
|
|
65
|
+
file: ARCHIVO,
|
|
66
|
+
list: LISTA,
|
|
67
|
+
color: TEXTO,
|
|
68
|
+
// Un rich-select se muestra con el label de la opción elegida.
|
|
69
|
+
'rich-select': TEXTO,
|
|
70
|
+
// Un dropdown se muestra con el label de la opción elegida.
|
|
71
|
+
dropdown: TEXTO,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Componente de display para un `type`, o `undefined` si no está en la
|
|
76
|
+
* tabla (tipo fuera de la unión — p. ej. un schema con un `type` mal
|
|
77
|
+
* escrito). Ese `undefined` es lo que el host traduce en la degradación
|
|
78
|
+
* controlada de R1.10: en dev se avisa, en producción se omite.
|
|
79
|
+
*/
|
|
80
|
+
export function displayLoader(type: string): DisplayLoader | undefined {
|
|
81
|
+
return Object.prototype.hasOwnProperty.call(DISPLAY_POR_DEFECTO, type)
|
|
82
|
+
? DISPLAY_POR_DEFECTO[type as FieldType]
|
|
83
|
+
: undefined;
|
|
84
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Component, computed, input } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
import { Badge } from '../../shared/components/badge/badge';
|
|
4
|
+
import type { FieldSchema } from '../../core/models/schema.model';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Display por defecto de `file` (R4.1 · modo `display` · R9.5.3).
|
|
8
|
+
*
|
|
9
|
+
* Un archivo no tiene miniatura: el valor es la URL pública, y lo honesto
|
|
10
|
+
* en la ficha de detalle es un enlace que lo abre (mismo lenguaje que el
|
|
11
|
+
* «Abrir» de `url`). En la cabecera (`chip`) va como badge con la URL, la
|
|
12
|
+
* paridad con el resto de los displays.
|
|
13
|
+
*/
|
|
14
|
+
@Component({
|
|
15
|
+
selector: 'app-field-display-file',
|
|
16
|
+
imports: [Badge],
|
|
17
|
+
template: `
|
|
18
|
+
@if (chip()) {
|
|
19
|
+
<app-badge [label]="url()" />
|
|
20
|
+
} @else {
|
|
21
|
+
<a
|
|
22
|
+
class="font-medium text-primary hover:underline"
|
|
23
|
+
[href]="url()"
|
|
24
|
+
target="_blank"
|
|
25
|
+
rel="noopener noreferrer"
|
|
26
|
+
>
|
|
27
|
+
Abrir archivo
|
|
28
|
+
</a>
|
|
29
|
+
}
|
|
30
|
+
`,
|
|
31
|
+
})
|
|
32
|
+
export class FieldDisplayFile {
|
|
33
|
+
/** Campo que se pinta. Lo usa el tipo; acá sólo tipa la forma común. */
|
|
34
|
+
readonly field = input.required<FieldSchema>();
|
|
35
|
+
/** Valor crudo del registro (la URL pública). El host ya filtró el vacío. */
|
|
36
|
+
readonly value = input<unknown>(null);
|
|
37
|
+
/** `true` en la cabecera: la URL se pinta como chip compacto. */
|
|
38
|
+
readonly chip = input(false);
|
|
39
|
+
|
|
40
|
+
protected readonly url = computed(() => String(this.value()));
|
|
41
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Component, computed, input } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
import { LucideExternalLink } from '@lucide/angular';
|
|
4
|
+
|
|
5
|
+
import { Badge } from '../../shared/components/badge/badge';
|
|
6
|
+
import type { FieldSchema } from '../../core/models/schema.model';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Display por defecto de `image` (R4.1 · modo `display`).
|
|
10
|
+
*
|
|
11
|
+
* Mismo maquetado que la rama `kind === 'image'` de `detail-view` antes de
|
|
12
|
+
* R4.2: miniatura de 7×7 con enlace a la imagen completa y overlay con el
|
|
13
|
+
* icono de «abrir». El `alt` sigue siendo la etiqueta del campo.
|
|
14
|
+
*
|
|
15
|
+
* El host ya se encarga del valor vacío (pinta `—`), así que acá la URL
|
|
16
|
+
* siempre existe.
|
|
17
|
+
*/
|
|
18
|
+
@Component({
|
|
19
|
+
selector: 'app-field-display-image',
|
|
20
|
+
imports: [Badge, LucideExternalLink],
|
|
21
|
+
template: `
|
|
22
|
+
@if (chip()) {
|
|
23
|
+
<!-- Paridad R4.2: la cabecera siempre mostró el valor formateado
|
|
24
|
+
como chip, y para una imagen ese valor era la URL. -->
|
|
25
|
+
<app-badge [label]="url()" />
|
|
26
|
+
} @else {
|
|
27
|
+
<a
|
|
28
|
+
[href]="url()"
|
|
29
|
+
target="_blank"
|
|
30
|
+
rel="noopener noreferrer"
|
|
31
|
+
class="group relative inline-block overflow-hidden rounded-xl border border-neutral/20 shadow-xs transition hover:border-primary"
|
|
32
|
+
>
|
|
33
|
+
<img
|
|
34
|
+
[src]="url()"
|
|
35
|
+
[alt]="field().label"
|
|
36
|
+
class="h-28 w-28 object-cover transition duration-300 group-hover:scale-105"
|
|
37
|
+
/>
|
|
38
|
+
<div
|
|
39
|
+
class="absolute inset-0 flex items-center justify-center bg-black/40 opacity-0 transition group-hover:opacity-100"
|
|
40
|
+
>
|
|
41
|
+
<svg lucideExternalLink size="18" class="text-white" />
|
|
42
|
+
</div>
|
|
43
|
+
</a>
|
|
44
|
+
}
|
|
45
|
+
`,
|
|
46
|
+
})
|
|
47
|
+
export class FieldDisplayImage {
|
|
48
|
+
readonly field = input.required<FieldSchema>();
|
|
49
|
+
readonly value = input<unknown>(null);
|
|
50
|
+
/** `true` en la cabecera: la URL se pinta como chip compacto. */
|
|
51
|
+
readonly chip = input(false);
|
|
52
|
+
|
|
53
|
+
protected readonly url = computed(() => String(this.value()));
|
|
54
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Component, computed, input } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
import { LucideClock } from '@lucide/angular';
|
|
4
|
+
|
|
5
|
+
import { Badge, type BadgeKind } from '../../shared/components/badge/badge';
|
|
6
|
+
import type { FieldSchema } from '../../core/models/schema.model';
|
|
7
|
+
import { resolveBadgeKind } from './display-badge';
|
|
8
|
+
|
|
9
|
+
const FORMATO_FECHA_HORA = new Intl.DateTimeFormat('es-PE', {
|
|
10
|
+
dateStyle: 'medium',
|
|
11
|
+
timeStyle: 'short',
|
|
12
|
+
timeZone: 'UTC',
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
type Item = Record<string, unknown>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Display por defecto de `list` (R4.1 · modo `display`).
|
|
19
|
+
*
|
|
20
|
+
* Es la línea de tiempo del historial: **toda la plantilla de `list` que
|
|
21
|
+
* vivía en `detail-view`** se muda acá, que es lo que R4.2 exige
|
|
22
|
+
* («`detail-view` no tiene plantilla propia de campo»). El agrupador sigue
|
|
23
|
+
* siendo `detail-view`: él decide que este campo va en su bloque con el
|
|
24
|
+
* `<h3>` y el ancho grande; acá sólo se pinta el valor.
|
|
25
|
+
*
|
|
26
|
+
* `itemFields` no participa: el timeline lee `action` / `at` / `detail`
|
|
27
|
+
* directamente, igual que antes.
|
|
28
|
+
*/
|
|
29
|
+
@Component({
|
|
30
|
+
selector: 'app-field-display-list',
|
|
31
|
+
imports: [Badge, LucideClock],
|
|
32
|
+
template: `
|
|
33
|
+
@if (chip()) {
|
|
34
|
+
<!-- Paridad R4.2: la cabecera siempre mostró el valor formateado
|
|
35
|
+
como chip, y para una lista ese valor era «N elementos». -->
|
|
36
|
+
<app-badge [label]="resumen()" />
|
|
37
|
+
} @else if (items().length > 0) {
|
|
38
|
+
<div
|
|
39
|
+
class="relative pl-6 space-y-4 before:absolute before:left-2 before:top-2 before:bottom-2 before:w-0.5 before:bg-neutral/20"
|
|
40
|
+
>
|
|
41
|
+
@for (item of items(); track $index) {
|
|
42
|
+
<div class="relative group">
|
|
43
|
+
<span
|
|
44
|
+
class="absolute -left-6 top-1 flex h-4 w-4 items-center justify-center rounded-full bg-primary/20 ring-4 ring-surface"
|
|
45
|
+
>
|
|
46
|
+
<span class="h-1.5 w-1.5 rounded-full bg-primary"></span>
|
|
47
|
+
</span>
|
|
48
|
+
<div
|
|
49
|
+
class="rounded-xl border border-neutral/10 bg-neutral/5 p-3.5 transition hover:border-neutral/20"
|
|
50
|
+
>
|
|
51
|
+
<div class="flex flex-wrap items-center justify-between gap-2 mb-1.5">
|
|
52
|
+
@if (item['action']) {
|
|
53
|
+
<app-badge
|
|
54
|
+
[label]="etiquetaAccion(item['action'])"
|
|
55
|
+
[kind]="kindAccion(item['action'])"
|
|
56
|
+
/>
|
|
57
|
+
}
|
|
58
|
+
@if (item['at']) {
|
|
59
|
+
<span class="text-xs text-neutral flex items-center gap-1">
|
|
60
|
+
<svg lucideClock size="12" />
|
|
61
|
+
{{ fechaHora(item['at']) }}
|
|
62
|
+
</span>
|
|
63
|
+
}
|
|
64
|
+
</div>
|
|
65
|
+
@if (item['detail']) {
|
|
66
|
+
<p class="text-sm text-neutral-light">{{ item['detail'] }}</p>
|
|
67
|
+
}
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
}
|
|
71
|
+
</div>
|
|
72
|
+
} @else {
|
|
73
|
+
<p class="text-xs italic text-neutral">No hay registros en el historial.</p>
|
|
74
|
+
}
|
|
75
|
+
`,
|
|
76
|
+
})
|
|
77
|
+
export class FieldDisplayList {
|
|
78
|
+
readonly field = input.required<FieldSchema>();
|
|
79
|
+
readonly value = input<unknown>(null);
|
|
80
|
+
/** `true` en la cabecera: el resumen «N elementos» va como chip. */
|
|
81
|
+
readonly chip = input(false);
|
|
82
|
+
|
|
83
|
+
/** El host entrega el valor crudo; sólo un array tiene timeline. */
|
|
84
|
+
protected readonly items = computed<Item[]>(() =>
|
|
85
|
+
Array.isArray(this.value()) ? (this.value() as Item[]) : [],
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
/** Mismo texto que daba el formateo de detalle previo a R4.2. */
|
|
89
|
+
protected resumen(): string {
|
|
90
|
+
return `${this.items().length} elementos`;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
protected fechaHora(valor: unknown): string {
|
|
94
|
+
if (!valor) return '—';
|
|
95
|
+
const d = new Date(String(valor));
|
|
96
|
+
return Number.isNaN(d.getTime()) ? String(valor) : FORMATO_FECHA_HORA.format(d);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
protected etiquetaAccion(valor: unknown): string {
|
|
100
|
+
if (!valor) return '';
|
|
101
|
+
return String(valor).replace(/_/g, ' ');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
protected kindAccion(valor: unknown): BadgeKind {
|
|
105
|
+
return resolveBadgeKind(String(valor));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Component, computed, input } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
import { Badge } from '../../shared/components/badge/badge';
|
|
4
|
+
import type { FieldSchema } from '../../core/models/schema.model';
|
|
5
|
+
|
|
6
|
+
const FORMATO_NUMERO = new Intl.NumberFormat('es-PE');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Display por defecto de `number` y `currency` (R4.1 · modo `display`).
|
|
10
|
+
*
|
|
11
|
+
* Los dos tipos compartían rama en `formatValue` y la comparten acá: miles
|
|
12
|
+
* con separador `es-PE` y sin decimales fijos (el schema controla los
|
|
13
|
+
* decimales con `decimals` en el form; en display manda el valor tal cual
|
|
14
|
+
* viene). Si no es número, se pinta el texto crudo — la degradación que ya
|
|
15
|
+
* hacía `detail-view`.
|
|
16
|
+
*/
|
|
17
|
+
@Component({
|
|
18
|
+
selector: 'app-field-display-number',
|
|
19
|
+
imports: [Badge],
|
|
20
|
+
template: `
|
|
21
|
+
@if (chip()) {
|
|
22
|
+
<app-badge [label]="texto()" />
|
|
23
|
+
} @else {
|
|
24
|
+
{{ texto() }}
|
|
25
|
+
}
|
|
26
|
+
`,
|
|
27
|
+
})
|
|
28
|
+
export class FieldDisplayNumber {
|
|
29
|
+
readonly field = input.required<FieldSchema>();
|
|
30
|
+
readonly value = input<unknown>(null);
|
|
31
|
+
/** `true` en la cabecera: el número se pinta como chip compacto. */
|
|
32
|
+
readonly chip = input(false);
|
|
33
|
+
|
|
34
|
+
protected readonly texto = computed(() => {
|
|
35
|
+
const n = Number(this.value());
|
|
36
|
+
if (!Number.isFinite(n)) {
|
|
37
|
+
return String(this.value());
|
|
38
|
+
}
|
|
39
|
+
return FORMATO_NUMERO.format(n);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Component, computed, input } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
import { Badge } from '../../shared/components/badge/badge';
|
|
4
|
+
import type { FieldSchema } from '../../core/models/schema.model';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Display por defecto de los tipos textuales (R4.1 · modo `display`).
|
|
8
|
+
*
|
|
9
|
+
* Toma el valor crudo del registro —no el árbol del formulario— y lo pinta
|
|
10
|
+
* como texto: el `default` de `formatValue` de `detail-view`, que era donde
|
|
11
|
+
* caían `text`, `textarea`, `slug`, `url`, `email`, `phone`, `readonly-text`,
|
|
12
|
+
* `relation`, `group`, `key-value`, `string-list`, `multiselect` y `time`.
|
|
13
|
+
*
|
|
14
|
+
* `String(raw)` conserva el comportamiento previo (un array sale `a,b`; un
|
|
15
|
+
* objeto sale `[object Object]`): R4.2 pide que «los 7 detalles rendericen
|
|
16
|
+
* igual», así que la paridad manda sobre la estética.
|
|
17
|
+
*
|
|
18
|
+
* Todos los display declaran `field`, `value` y `chip` aunque no los usen:
|
|
19
|
+
* el host les pasa la misma forma a los 6 y `ngComponentOutletInputs` no
|
|
20
|
+
* admite claves que el componente no declare.
|
|
21
|
+
*/
|
|
22
|
+
@Component({
|
|
23
|
+
selector: 'app-field-display-text',
|
|
24
|
+
imports: [Badge],
|
|
25
|
+
template: `
|
|
26
|
+
@if (chip()) {
|
|
27
|
+
<app-badge [label]="texto()" />
|
|
28
|
+
} @else {
|
|
29
|
+
{{ texto() }}
|
|
30
|
+
}
|
|
31
|
+
`,
|
|
32
|
+
})
|
|
33
|
+
export class FieldDisplayText {
|
|
34
|
+
/** Campo que se pinta. Lo usa el tipo; acá sólo tipa la forma común. */
|
|
35
|
+
readonly field = input.required<FieldSchema>();
|
|
36
|
+
/** Valor crudo del registro. El host ya filtró el vacío (`—`). */
|
|
37
|
+
readonly value = input<unknown>(null);
|
|
38
|
+
/** `true` en la cabecera: el texto se pinta como chip compacto. */
|
|
39
|
+
readonly chip = input(false);
|
|
40
|
+
|
|
41
|
+
protected readonly texto = computed(() => String(this.value()));
|
|
42
|
+
}
|