@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,258 @@
|
|
|
1
|
+
import type { ResourceSchema } from '../models/schema.model';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Colección con pestañas — base.md §11, api.md §3.2–§3.5.
|
|
5
|
+
* Imágenes, specs y FAQ viven en hojas hijas; la API los ensambla.
|
|
6
|
+
*/
|
|
7
|
+
export const productsSchema: ResourceSchema = {
|
|
8
|
+
id: 'products',
|
|
9
|
+
label: 'Producto',
|
|
10
|
+
labelPlural: 'Productos',
|
|
11
|
+
kind: 'collection',
|
|
12
|
+
uiViews: {
|
|
13
|
+
list: { type: 'list' },
|
|
14
|
+
create: { type: 'form', path: 'new' },
|
|
15
|
+
edit: { type: 'form', path: ':key/edit' },
|
|
16
|
+
},
|
|
17
|
+
endpoint: {
|
|
18
|
+
list: '/admin/products',
|
|
19
|
+
get: '/admin/products/{key}',
|
|
20
|
+
create: '/admin/products',
|
|
21
|
+
update: '/admin/products/{key}',
|
|
22
|
+
remove: '/admin/products/{key}',
|
|
23
|
+
},
|
|
24
|
+
keyField: 'slug',
|
|
25
|
+
titleField: 'name',
|
|
26
|
+
search: ['name', 'sku'],
|
|
27
|
+
filters: [
|
|
28
|
+
{
|
|
29
|
+
key: 'availability',
|
|
30
|
+
label: 'Disponibilidad',
|
|
31
|
+
type: 'select',
|
|
32
|
+
options: [
|
|
33
|
+
{ value: 'InStock', label: 'En stock' },
|
|
34
|
+
{ value: 'PreOrder', label: 'Preventa' },
|
|
35
|
+
{ value: 'OutOfStock', label: 'Agotado' },
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
{ key: 'active', label: 'Activo', type: 'boolean' },
|
|
39
|
+
],
|
|
40
|
+
listColumns: [
|
|
41
|
+
{ key: 'images', label: 'Imagen', format: 'thumbnail' },
|
|
42
|
+
{ key: 'name', label: 'Nombre' },
|
|
43
|
+
{ key: 'category_slug', label: 'Categoría' },
|
|
44
|
+
{ key: 'price', label: 'Precio', format: 'currency' },
|
|
45
|
+
{ key: 'availability', label: 'Disponibilidad' },
|
|
46
|
+
{ key: 'registro_sanitario', label: 'Sanitario', format: 'badge' },
|
|
47
|
+
{ key: 'active', label: 'Activo', format: 'boolean' },
|
|
48
|
+
],
|
|
49
|
+
layout: {
|
|
50
|
+
mode: 'tabs',
|
|
51
|
+
sections: [
|
|
52
|
+
{ id: 'general', label: 'General' },
|
|
53
|
+
{ id: 'contenido', label: 'Contenido' },
|
|
54
|
+
{ id: 'imagenes', label: 'Imágenes' },
|
|
55
|
+
{ id: 'sanitario', label: 'Sanitario' },
|
|
56
|
+
{ id: 'ficha', label: 'Ficha técnica' },
|
|
57
|
+
{ id: 'faq', label: 'FAQ' },
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
fields: [
|
|
61
|
+
// ── General ──
|
|
62
|
+
{
|
|
63
|
+
type: 'text',
|
|
64
|
+
key: 'name',
|
|
65
|
+
label: 'Nombre',
|
|
66
|
+
required: true,
|
|
67
|
+
section: 'general',
|
|
68
|
+
width: 6,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: 'slug',
|
|
72
|
+
key: 'slug',
|
|
73
|
+
label: 'Slug',
|
|
74
|
+
from: 'name',
|
|
75
|
+
lockAfterCreate: true,
|
|
76
|
+
required: true,
|
|
77
|
+
validators: { unique: true },
|
|
78
|
+
help: 'Inmutable tras publicar.',
|
|
79
|
+
section: 'general',
|
|
80
|
+
width: 6,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
type: 'relation',
|
|
84
|
+
key: 'category_slug',
|
|
85
|
+
label: 'Categoría',
|
|
86
|
+
required: true,
|
|
87
|
+
// F8 · R6.5 (D62): UN objeto `source` para todas las fuentes.
|
|
88
|
+
source: { resource: 'categories', valueField: 'slug', labelField: 'name' },
|
|
89
|
+
onlyActive: true,
|
|
90
|
+
section: 'general',
|
|
91
|
+
width: 6,
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
type: 'text',
|
|
95
|
+
key: 'sku',
|
|
96
|
+
label: 'SKU',
|
|
97
|
+
required: true,
|
|
98
|
+
validators: { unique: true },
|
|
99
|
+
section: 'general',
|
|
100
|
+
width: 6,
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
type: 'text',
|
|
104
|
+
key: 'brand',
|
|
105
|
+
label: 'Marca',
|
|
106
|
+
section: 'general',
|
|
107
|
+
width: 6,
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
type: 'currency',
|
|
111
|
+
key: 'price',
|
|
112
|
+
label: 'Precio',
|
|
113
|
+
required: true,
|
|
114
|
+
section: 'general',
|
|
115
|
+
width: 6,
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
type: 'select',
|
|
119
|
+
key: 'availability',
|
|
120
|
+
label: 'Disponibilidad',
|
|
121
|
+
required: true,
|
|
122
|
+
options: [
|
|
123
|
+
{ value: 'InStock', label: 'En stock' },
|
|
124
|
+
{ value: 'PreOrder', label: 'Preventa' },
|
|
125
|
+
{ value: 'OutOfStock', label: 'Agotado' },
|
|
126
|
+
],
|
|
127
|
+
section: 'general',
|
|
128
|
+
width: 6,
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
type: 'boolean',
|
|
132
|
+
key: 'featured',
|
|
133
|
+
label: 'Destacado',
|
|
134
|
+
required: true,
|
|
135
|
+
default: false,
|
|
136
|
+
trueLabel: 'Sí',
|
|
137
|
+
falseLabel: 'No',
|
|
138
|
+
section: 'general',
|
|
139
|
+
width: 6,
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
type: 'boolean',
|
|
143
|
+
key: 'active',
|
|
144
|
+
label: 'Activo',
|
|
145
|
+
required: true,
|
|
146
|
+
default: true,
|
|
147
|
+
trueLabel: 'Activo',
|
|
148
|
+
falseLabel: 'Inactivo',
|
|
149
|
+
section: 'general',
|
|
150
|
+
width: 6,
|
|
151
|
+
},
|
|
152
|
+
// ── Contenido ──
|
|
153
|
+
{
|
|
154
|
+
type: 'textarea',
|
|
155
|
+
key: 'description',
|
|
156
|
+
label: 'Descripción',
|
|
157
|
+
required: true,
|
|
158
|
+
rows: 8,
|
|
159
|
+
help: 'Entre 100 y 2000 caracteres.',
|
|
160
|
+
validators: { minLength: 100, maxLength: 2000 },
|
|
161
|
+
section: 'contenido',
|
|
162
|
+
width: 12,
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
type: 'text',
|
|
166
|
+
key: 'seo_title',
|
|
167
|
+
label: 'Título SEO',
|
|
168
|
+
section: 'contenido',
|
|
169
|
+
width: 12,
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
type: 'textarea',
|
|
173
|
+
key: 'seo_description',
|
|
174
|
+
label: 'Descripción SEO',
|
|
175
|
+
required: true,
|
|
176
|
+
rows: 3,
|
|
177
|
+
section: 'contenido',
|
|
178
|
+
width: 12,
|
|
179
|
+
},
|
|
180
|
+
// ── Imágenes (mín 1; la primera es la principal) ──
|
|
181
|
+
{
|
|
182
|
+
type: 'list',
|
|
183
|
+
key: 'images',
|
|
184
|
+
label: 'Imágenes',
|
|
185
|
+
required: true,
|
|
186
|
+
min: 1,
|
|
187
|
+
primaryFirst: true,
|
|
188
|
+
positionField: 'position',
|
|
189
|
+
addLabel: 'Agregar imagen',
|
|
190
|
+
emptyText: 'Sin imágenes. La primera será la imagen principal.',
|
|
191
|
+
itemDisplay: 'card',
|
|
192
|
+
itemTitle: 'image_alt',
|
|
193
|
+
itemFields: [
|
|
194
|
+
{ type: 'image', key: 'image_url', label: 'Imagen', required: true },
|
|
195
|
+
{ type: 'text', key: 'image_alt', label: 'Texto alternativo', required: true },
|
|
196
|
+
],
|
|
197
|
+
section: 'imagenes',
|
|
198
|
+
width: 12,
|
|
199
|
+
},
|
|
200
|
+
// ── Sanitario ──
|
|
201
|
+
{
|
|
202
|
+
type: 'text',
|
|
203
|
+
key: 'registro_sanitario',
|
|
204
|
+
label: 'Registro sanitario',
|
|
205
|
+
help: 'Sin esto el producto no se publica.',
|
|
206
|
+
section: 'sanitario',
|
|
207
|
+
width: 4,
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
type: 'select',
|
|
211
|
+
key: 'clase_riesgo',
|
|
212
|
+
label: 'Clase de riesgo',
|
|
213
|
+
options: [
|
|
214
|
+
{ value: 'I', label: 'I' },
|
|
215
|
+
{ value: 'IIa', label: 'IIa' },
|
|
216
|
+
{ value: 'IIb', label: 'IIb' },
|
|
217
|
+
{ value: 'III', label: 'III' },
|
|
218
|
+
],
|
|
219
|
+
section: 'sanitario',
|
|
220
|
+
width: 4,
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
type: 'text',
|
|
224
|
+
key: 'titular_registro',
|
|
225
|
+
label: 'Titular del registro',
|
|
226
|
+
section: 'sanitario',
|
|
227
|
+
width: 4,
|
|
228
|
+
},
|
|
229
|
+
// ── Ficha técnica ──
|
|
230
|
+
{
|
|
231
|
+
type: 'key-value',
|
|
232
|
+
key: 'specs',
|
|
233
|
+
label: 'Especificaciones',
|
|
234
|
+
positionField: 'position',
|
|
235
|
+
addLabel: 'Agregar especificación',
|
|
236
|
+
emptyText: 'Sin especificaciones.',
|
|
237
|
+
section: 'ficha',
|
|
238
|
+
width: 12,
|
|
239
|
+
},
|
|
240
|
+
// ── FAQ ──
|
|
241
|
+
{
|
|
242
|
+
type: 'list',
|
|
243
|
+
key: 'faq',
|
|
244
|
+
label: 'Preguntas frecuentes',
|
|
245
|
+
positionField: 'position',
|
|
246
|
+
addLabel: 'Agregar pregunta',
|
|
247
|
+
emptyText: 'Sin preguntas frecuentes.',
|
|
248
|
+
itemDisplay: 'card',
|
|
249
|
+
itemTitle: 'question',
|
|
250
|
+
itemFields: [
|
|
251
|
+
{ type: 'text', key: 'question', label: 'Pregunta', required: true },
|
|
252
|
+
{ type: 'textarea', key: 'answer', label: 'Respuesta', required: true, rows: 4 },
|
|
253
|
+
],
|
|
254
|
+
section: 'faq',
|
|
255
|
+
width: 12,
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
};
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import type { ResourceSchema } from '../models/schema.model';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Singleton de configuración del sitio — base.md §11, api.md §3.6–§3.8.
|
|
5
|
+
* La API aplana `address_street` etc. a objetos anidados al responder.
|
|
6
|
+
*/
|
|
7
|
+
export const siteSchema: ResourceSchema = {
|
|
8
|
+
id: 'site',
|
|
9
|
+
label: 'Sitio',
|
|
10
|
+
labelPlural: 'Sitio',
|
|
11
|
+
kind: 'singleton',
|
|
12
|
+
uiViews: {
|
|
13
|
+
settings: { type: 'form' },
|
|
14
|
+
},
|
|
15
|
+
endpoint: {
|
|
16
|
+
get: '/admin/site',
|
|
17
|
+
update: '/admin/site',
|
|
18
|
+
},
|
|
19
|
+
// Los singleton no tienen clave de registro; `get`/`update` no la usan.
|
|
20
|
+
keyField: 'key',
|
|
21
|
+
titleField: 'name',
|
|
22
|
+
// Sin listado: `listColumns` queda vacío por tipo.
|
|
23
|
+
listColumns: [],
|
|
24
|
+
layout: {
|
|
25
|
+
mode: 'sections',
|
|
26
|
+
sections: [
|
|
27
|
+
{ id: 'negocio', label: 'Negocio' },
|
|
28
|
+
{ id: 'contacto', label: 'Contacto' },
|
|
29
|
+
{ id: 'direccion', label: 'Dirección' },
|
|
30
|
+
{ id: 'horarios', label: 'Horarios' },
|
|
31
|
+
{ id: 'redes', label: 'Redes' },
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
fields: [
|
|
35
|
+
// ── Negocio ──
|
|
36
|
+
{
|
|
37
|
+
type: 'text',
|
|
38
|
+
key: 'name',
|
|
39
|
+
label: 'Nombre del negocio',
|
|
40
|
+
required: true,
|
|
41
|
+
section: 'negocio',
|
|
42
|
+
width: 6,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
type: 'url',
|
|
46
|
+
key: 'url',
|
|
47
|
+
label: 'Sitio web',
|
|
48
|
+
required: true,
|
|
49
|
+
section: 'negocio',
|
|
50
|
+
width: 6,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
type: 'textarea',
|
|
54
|
+
key: 'description',
|
|
55
|
+
label: 'Descripción',
|
|
56
|
+
required: true,
|
|
57
|
+
rows: 4,
|
|
58
|
+
section: 'negocio',
|
|
59
|
+
width: 12,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
type: 'text',
|
|
63
|
+
key: 'currency',
|
|
64
|
+
label: 'Moneda',
|
|
65
|
+
required: true,
|
|
66
|
+
default: 'PEN',
|
|
67
|
+
help: 'Código ISO 4217 (ej. PEN).',
|
|
68
|
+
validators: { pattern: '^[A-Z]{3}$' },
|
|
69
|
+
section: 'negocio',
|
|
70
|
+
width: 6,
|
|
71
|
+
},
|
|
72
|
+
// ── Contacto ──
|
|
73
|
+
{
|
|
74
|
+
type: 'phone',
|
|
75
|
+
key: 'phone',
|
|
76
|
+
label: 'Teléfono',
|
|
77
|
+
required: true,
|
|
78
|
+
format: 'e164',
|
|
79
|
+
section: 'contacto',
|
|
80
|
+
width: 6,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
type: 'phone',
|
|
84
|
+
key: 'whatsapp',
|
|
85
|
+
label: 'WhatsApp',
|
|
86
|
+
required: true,
|
|
87
|
+
format: 'digits',
|
|
88
|
+
help: 'Solo dígitos, sin +.',
|
|
89
|
+
section: 'contacto',
|
|
90
|
+
width: 6,
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
type: 'email',
|
|
94
|
+
key: 'email',
|
|
95
|
+
label: 'Correo',
|
|
96
|
+
required: true,
|
|
97
|
+
section: 'contacto',
|
|
98
|
+
width: 6,
|
|
99
|
+
},
|
|
100
|
+
// ── Dirección (grupos address y geo) ──
|
|
101
|
+
{
|
|
102
|
+
type: 'group',
|
|
103
|
+
key: 'address',
|
|
104
|
+
label: 'Dirección',
|
|
105
|
+
required: true,
|
|
106
|
+
display: 'card',
|
|
107
|
+
section: 'direccion',
|
|
108
|
+
width: 12,
|
|
109
|
+
fields: [
|
|
110
|
+
{ type: 'text', key: 'street', label: 'Calle', required: true },
|
|
111
|
+
{ type: 'text', key: 'city', label: 'Ciudad', required: true },
|
|
112
|
+
{ type: 'text', key: 'region', label: 'Región', required: true },
|
|
113
|
+
{ type: 'text', key: 'postal_code', label: 'Código postal', required: true },
|
|
114
|
+
{
|
|
115
|
+
type: 'text',
|
|
116
|
+
key: 'country',
|
|
117
|
+
label: 'País',
|
|
118
|
+
required: true,
|
|
119
|
+
help: 'ISO alpha-2 (ej. PE).',
|
|
120
|
+
validators: { pattern: '^[A-Z]{2}$' },
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
type: 'group',
|
|
126
|
+
key: 'geo',
|
|
127
|
+
label: 'Coordenadas',
|
|
128
|
+
required: true,
|
|
129
|
+
display: 'card',
|
|
130
|
+
section: 'direccion',
|
|
131
|
+
width: 12,
|
|
132
|
+
fields: [
|
|
133
|
+
{
|
|
134
|
+
type: 'number',
|
|
135
|
+
key: 'lat',
|
|
136
|
+
label: 'Latitud',
|
|
137
|
+
required: true,
|
|
138
|
+
min: -90,
|
|
139
|
+
max: 90,
|
|
140
|
+
decimals: 6,
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
type: 'number',
|
|
144
|
+
key: 'lng',
|
|
145
|
+
label: 'Longitud',
|
|
146
|
+
required: true,
|
|
147
|
+
min: -180,
|
|
148
|
+
max: 180,
|
|
149
|
+
decimals: 6,
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
},
|
|
153
|
+
// ── Horarios ──
|
|
154
|
+
{
|
|
155
|
+
type: 'list',
|
|
156
|
+
key: 'hours',
|
|
157
|
+
label: 'Horarios',
|
|
158
|
+
positionField: 'position',
|
|
159
|
+
addLabel: 'Agregar tramo',
|
|
160
|
+
emptyText: 'Sin horarios definidos.',
|
|
161
|
+
itemFields: [
|
|
162
|
+
{
|
|
163
|
+
type: 'multiselect',
|
|
164
|
+
key: 'days',
|
|
165
|
+
label: 'Días',
|
|
166
|
+
required: true,
|
|
167
|
+
options: [
|
|
168
|
+
{ value: 'mon', label: 'Lunes' },
|
|
169
|
+
{ value: 'tue', label: 'Martes' },
|
|
170
|
+
{ value: 'wed', label: 'Miércoles' },
|
|
171
|
+
{ value: 'thu', label: 'Jueves' },
|
|
172
|
+
{ value: 'fri', label: 'Viernes' },
|
|
173
|
+
{ value: 'sat', label: 'Sábado' },
|
|
174
|
+
{ value: 'sun', label: 'Domingo' },
|
|
175
|
+
],
|
|
176
|
+
},
|
|
177
|
+
{ type: 'time', key: 'opens', label: 'Abre', required: true },
|
|
178
|
+
{ type: 'time', key: 'closes', label: 'Cierra', required: true },
|
|
179
|
+
],
|
|
180
|
+
section: 'horarios',
|
|
181
|
+
width: 12,
|
|
182
|
+
},
|
|
183
|
+
// ── Redes ──
|
|
184
|
+
{
|
|
185
|
+
type: 'string-list',
|
|
186
|
+
key: 'social',
|
|
187
|
+
label: 'Redes sociales',
|
|
188
|
+
itemType: 'url',
|
|
189
|
+
addLabel: 'Agregar red',
|
|
190
|
+
emptyText: 'Sin redes sociales.',
|
|
191
|
+
section: 'redes',
|
|
192
|
+
width: 12,
|
|
193
|
+
},
|
|
194
|
+
],
|
|
195
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ResourceSchema } from '../models/schema.model';
|
|
2
|
+
|
|
3
|
+
import { categoriesSchema } from './categories.schema';
|
|
4
|
+
import { ordersSchema } from './orders.schema';
|
|
5
|
+
import { productsSchema } from './products.schema';
|
|
6
|
+
import { siteSchema } from './site.schema';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Catálogo de pruebas de la librería: copia CONGELADA de los schemas
|
|
10
|
+
* reales de `admin-schema` (orders, categories, products), del mismo modo
|
|
11
|
+
* que el motor backend congela fixtures de endpoints en sus tests. Los
|
|
12
|
+
* specs del motor prueban comportamiento (navegación, params, caché,
|
|
13
|
+
* composición) contra declaraciones con esa forma; los specs contra los
|
|
14
|
+
* schemas VIVOS del consumidor viven en el repo del consumidor.
|
|
15
|
+
*/
|
|
16
|
+
export const testCatalog: readonly ResourceSchema[] = [
|
|
17
|
+
ordersSchema,
|
|
18
|
+
categoriesSchema,
|
|
19
|
+
productsSchema,
|
|
20
|
+
siteSchema,
|
|
21
|
+
];
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { InjectionToken } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
import type { ResponseUnwrap } from './models/schema.model';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* URL base de la API (baseapi §2.3): es la URL directa del Web App de Apps
|
|
7
|
+
* Script; ahí se hace el `POST` del envelope `{ token, method, path, payload }`.
|
|
8
|
+
* OBLIGATORIO proporcionarlo en `app.config.ts`:
|
|
9
|
+
* `{ provide: API_URL, useValue: 'https://…' }` (Fase 3). Vacío = mismo origen.
|
|
10
|
+
*/
|
|
11
|
+
export const API_URL = new InjectionToken<string>('API_URL');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Superficie mínima que `gas-admin-ui` usa de Firebase Auth.
|
|
15
|
+
* Implementada por la aplicación consumidora; inyectada vía `FIREBASE_AUTH_ADAPTER`.
|
|
16
|
+
* Mantener la interfaz fina evita acoplar la librería a una versión específica de Firebase.
|
|
17
|
+
*/
|
|
18
|
+
export interface FirebaseAuthAdapter {
|
|
19
|
+
/**
|
|
20
|
+
* Abre un popup de Google sign-in y resuelve al ID token de Firebase.
|
|
21
|
+
* Rechaza si el usuario cancela o hay error.
|
|
22
|
+
*/
|
|
23
|
+
signInWithGoogle(): Promise<string>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Inicia sesión con email y contraseña vía Firebase y resuelve al ID token.
|
|
27
|
+
* Se usa cuando provider === 'password' Y firebase está configurado (Firebase email auth).
|
|
28
|
+
*/
|
|
29
|
+
signInWithEmailAndPassword(email: string, password: string): Promise<string>;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Cierra sesión en Firebase (llamado junto al clear de la sesión de la app).
|
|
33
|
+
*/
|
|
34
|
+
signOut(): Promise<void>;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Obtiene un ID token de Firebase FRESCO para usarlo en la cabecera
|
|
38
|
+
* `Authorization: Bearer <token>` de las peticiones REST.
|
|
39
|
+
*
|
|
40
|
+
* OPCIONAL: si el adaptador no lo implementa, `gas-admin-ui` envía el token
|
|
41
|
+
* de sesión almacenado tal cual (comportamiento actual). Implementarlo
|
|
42
|
+
* permite refrescar el ID token antes de cada petición REST, evitando
|
|
43
|
+
* errores "ID token inválido" tras la expiración de Firebase (1 hora).
|
|
44
|
+
*
|
|
45
|
+
* El adaptador decide cuándo refrescar (p. ej. `getIdToken(true)` de Firebase
|
|
46
|
+
* SDK fuerza la renovación; sin argumento devuelve el cacheado si aún es válido).
|
|
47
|
+
*/
|
|
48
|
+
getIdToken?(): Promise<string>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Token DI opcional para el adaptador de Firebase Auth.
|
|
53
|
+
* Proporcionado por la aplicación consumidora cuando usa proveedores federados o Firebase Auth.
|
|
54
|
+
*/
|
|
55
|
+
export const FIREBASE_AUTH_ADAPTER = new InjectionToken<FirebaseAuthAdapter>(
|
|
56
|
+
'gas.admin.firebaseAuthAdapter',
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Driver de transporte HTTP del motor.
|
|
61
|
+
*
|
|
62
|
+
* Vive acá (capa de infraestructura) y NO en `ResourceSchema` (capa de dominio)
|
|
63
|
+
* porque es una decisión de red, no de modelo de datos. Cambiar el driver
|
|
64
|
+
* no debería requerir tocar ningún schema de recursos.
|
|
65
|
+
*
|
|
66
|
+
* - `'gas'` (default): tunnel `POST text/plain` con envelope
|
|
67
|
+
* `{ token, method, path, payload }` — contrato de Google Apps Script.
|
|
68
|
+
* - `'rest'`: verbos HTTP reales (`GET`, `POST`, `PUT`, `DELETE`) con
|
|
69
|
+
* `Authorization: Bearer <token>` en cabeceras y params en la URL (GET/DELETE)
|
|
70
|
+
* o en el body JSON (POST/PUT/PATCH).
|
|
71
|
+
*
|
|
72
|
+
* Se fija en `provideGasAdmin({ driver })`. Sin declaración explícita el
|
|
73
|
+
* motor usa `'gas'` — cero impacto para consumidores existentes.
|
|
74
|
+
*/
|
|
75
|
+
export const API_DRIVER = new InjectionToken<'gas' | 'rest'>('gas.admin.driver');
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Registro de FUENTES DE CONTEXTO para marcadores en paths de endpoints.
|
|
79
|
+
*
|
|
80
|
+
* Cada clave es el nombre de una fuente — `{ <fuente> }` o
|
|
81
|
+
* `{ <fuente>.<ruta.anidada> }` dentro de un path declarado en
|
|
82
|
+
* `ResourceEndpoints` — y cada valor es un getter sin argumentos que devuelve
|
|
83
|
+
* el dato ACTUAL en el momento de la petición (no al registrar).
|
|
84
|
+
*
|
|
85
|
+
* El motor ya aporta dos fuentes construidas y éstas NO se declaran acá:
|
|
86
|
+
*
|
|
87
|
+
* - `auth` → la sesión que dueña `AuthService` (usuario y token).
|
|
88
|
+
* - `config` → el mapa global que puebla `ConfigService` desde los singletons.
|
|
89
|
+
*
|
|
90
|
+
* Este registro es sólo para fuentes que aporta el consumidor, para que el
|
|
91
|
+
* motor no conozca nombres de dominio: qué campo se lee lo decide el schema,
|
|
92
|
+
* no el engine.
|
|
93
|
+
*
|
|
94
|
+
* Un marcador que apunte a una fuente no registrada, o a un valor ausente,
|
|
95
|
+
* revienta con un error que nombra el path y el marcador — jamás se manda un
|
|
96
|
+
* segmento vacío al backend.
|
|
97
|
+
*/
|
|
98
|
+
export type ValueSources = Readonly<Record<string, () => unknown>>;
|
|
99
|
+
|
|
100
|
+
export const VALUE_SOURCES = new InjectionToken<ValueSources>('gas.admin.valueSources');
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Unwrap de respuesta global por defecto (`GasAdminConfig.defaultResponseUnwrap`).
|
|
104
|
+
*
|
|
105
|
+
* Se fusiona con la declaración `endpoint.responseUnwrap` de cada recurso:
|
|
106
|
+
* la del recurso tiene prioridad en las claves que declara. Sin token, sólo
|
|
107
|
+
* aplica lo declarado por recurso — cero impacto en schemas existentes.
|
|
108
|
+
*/
|
|
109
|
+
export const DEFAULT_RESPONSE_UNWRAP = new InjectionToken<ResponseUnwrap>(
|
|
110
|
+
'gas.admin.defaultResponseUnwrap',
|
|
111
|
+
);
|
|
112
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { buildShareMessage } from './clipboard';
|
|
4
|
+
|
|
5
|
+
const URL = 'https://ejemplo.test/p/abc123';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* `buildShareMessage` es el único sitio que decide QUÉ se copia. Aquí vive el
|
|
9
|
+
* bug que motivó la función: `copy()` y la acción del listado escribían sólo
|
|
10
|
+
* `url`, dejando afuera el `shareTextTemplate` formateado (saludo, ref, PIN y
|
|
11
|
+
* el propio enlace) que sí viajaban por WhatsApp.
|
|
12
|
+
*/
|
|
13
|
+
describe('buildShareMessage', () => {
|
|
14
|
+
it('sin shareText devuelve sólo la URL', () => {
|
|
15
|
+
expect(buildShareMessage(URL)).toBe(URL);
|
|
16
|
+
expect(buildShareMessage(URL, '')).toBe(URL);
|
|
17
|
+
expect(buildShareMessage(URL, ' ')).toBe(URL);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('con shareText que YA trae la URL no duplica el enlace', () => {
|
|
21
|
+
// Este es el caso de `orders.shareTextTemplate`: el mensaje ya incluye
|
|
22
|
+
// el link escrito dentro. Un `join` a ciegas lo pegaba DOS veces.
|
|
23
|
+
const template = `Hola Ana, puede retirar su pedido A-100 aquí: ${URL}`;
|
|
24
|
+
expect(buildShareMessage(URL, template)).toBe(template);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('con shareText SIN la URL completa el enlace al final', () => {
|
|
28
|
+
const text = 'Hola Ana, su pedido A-100 está listo';
|
|
29
|
+
expect(buildShareMessage(URL, text)).toBe(`${text} ${URL}`);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('un mensaje que sólo menciona la base del sitio NO recibe el enlace', () => {
|
|
33
|
+
// Caso real reportado: la plantilla interpola `{public_base_url}` (la
|
|
34
|
+
// base, sin `/p/{ref}`) y el motor le pegaba la URL con código al final
|
|
35
|
+
// aunque el mensaje YA apuntaba al sitio. El criterio es el origin,
|
|
36
|
+
// no la URL exacta.
|
|
37
|
+
const text = '🔗 Consulta tu pedido en https://ejemplo.test';
|
|
38
|
+
expect(buildShareMessage(URL, text)).toBe(text);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('un mensaje que apunta a OTRO sitio sí recibe el enlace', () => {
|
|
42
|
+
const text = 'Sigue el pedido en https://otro-sitio.test/pedidos';
|
|
43
|
+
expect(buildShareMessage(URL, text)).toBe(`${text} ${URL}`);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('con URL relativa sólo casa la coincidencia exacta', () => {
|
|
47
|
+
expect(buildShareMessage('/p/abc123', 'Ver en /p/abc123')).toBe('Ver en /p/abc123');
|
|
48
|
+
expect(buildShareMessage('/p/abc123', 'Ver tu pedido')).toBe('Ver tu pedido /p/abc123');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('recorta el shareText pero nunca la URL', () => {
|
|
52
|
+
expect(buildShareMessage(URL, ' Hola Ana ')).toBe(`Hola Ana ${URL}`);
|
|
53
|
+
expect(buildShareMessage('', 'Hola Ana')).toBe('Hola Ana');
|
|
54
|
+
});
|
|
55
|
+
});
|