@nutin/cli 1.3.1 → 2.0.0
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/CHANGELOG.md +89 -9
- package/README.md +20 -35
- package/bin/add-feature.mjs +9 -0
- package/bin/cli.mjs +8 -0
- package/bin/create-app.mjs +5 -4
- package/bin/update-app.mjs +9 -0
- package/lib/index.mjs +76 -25
- package/lib/src/add-feature/feature-adder.mjs +83 -0
- package/lib/src/add-feature/feature-context-builder.mjs +25 -0
- package/lib/src/add-feature/nutin-config-updater.mjs +29 -0
- package/lib/src/add-feature/package-json-updater.mjs +49 -0
- package/lib/src/common/feature-registry.mjs +11 -0
- package/lib/src/common/file-generator.mjs +159 -0
- package/lib/src/common/meta-bootstrap-prompt.mjs +33 -0
- package/lib/src/common/package-data.mjs +10 -0
- package/lib/src/common/package-json-helper.mjs +103 -0
- package/lib/src/common/project-meta.mjs +54 -0
- package/lib/src/create-app/context-builder.mjs +21 -0
- package/lib/src/{git-manager.mjs → create-app/git-manager.mjs} +2 -2
- package/lib/src/create-app/json-manager.mjs +73 -0
- package/lib/src/{prompts.mjs → create-app/new-app-prompt.mjs} +6 -6
- package/lib/src/{project-generator.mjs → create-app/project-generator.mjs} +10 -8
- package/lib/src/create-app/success-message.mjs +14 -0
- package/lib/src/update-app/conflict-report-writer.mjs +31 -0
- package/lib/src/update-app/fetch-old-templates.mjs +61 -0
- package/lib/src/update-app/project-updater.mjs +136 -0
- package/lib/src/update-app/template-differ.mjs +124 -0
- package/lib/src/update-app/update-context-builder.mjs +25 -0
- package/lib/src/update-app/update-summary-printer.mjs +22 -0
- package/lib/src/update-app/version-compare.mjs +12 -0
- package/lib/src/utils/print.mjs +36 -0
- package/lib/src/utils/promise-exec-alias.mjs +4 -0
- package/package.json +17 -12
- package/templates/base/.gitignore.hbs +6 -1
- package/templates/base/AGENTS.md.hbs +169 -0
- package/templates/base/GETTING_STARTED.md.hbs +227 -0
- package/templates/base/README.md.hbs +8 -17
- package/templates/base/config/languages.json.hbs +6 -0
- package/templates/base/config/seo.json.hbs +12 -0
- package/templates/base/nutin.config.js.hbs +51 -0
- package/templates/base/src/app/components/index.ts.hbs +1 -2
- package/templates/base/src/app/globals.d.ts.hbs +3 -19
- package/templates/base/src/{libs/guards → app}/guards.ts.hbs +1 -5
- package/templates/base/src/app/main.ts.hbs +7 -26
- package/templates/base/src/app/services/index.ts.hbs +1 -1
- package/templates/base/src/app/views/home/home.view.html.hbs +7 -0
- package/templates/base/src/app/views/home/home.view.ts.hbs +1 -56
- package/templates/base/src/app/views/index.ts.hbs +1 -0
- package/templates/base/src/app/views/not-found/not-found.view.html.hbs +8 -0
- package/templates/base/src/app/views/not-found/not-found.view.ts.hbs +4 -37
- package/templates/base/src/core/base-classes/base-component/base-component.test.js.hbs +158 -0
- package/templates/base/src/core/base-classes/base-component/base-component.ts.hbs +68 -35
- package/templates/base/src/core/base-classes/base-component/helpers/catalog.helper.test.js.hbs +124 -0
- package/templates/base/src/core/base-classes/base-component/helpers/catalog.helper.ts.hbs +9 -8
- package/templates/base/src/core/base-classes/base-component/helpers/children.helper.test.js.hbs +74 -0
- package/templates/base/src/core/base-classes/base-component/helpers/children.helper.ts.hbs +1 -1
- package/templates/base/src/core/base-classes/base-component/helpers/dom.helper.test.js.hbs +145 -0
- package/templates/base/src/core/base-classes/base-component/helpers/dom.helper.ts.hbs +7 -1
- package/templates/base/src/core/base-classes/base-component/helpers/event.helper.test.js.hbs +88 -0
- package/templates/base/src/core/base-classes/base-component/helpers/event.helper.ts.hbs +2 -2
- package/templates/base/src/core/base-classes/base-component/helpers/i18n.helper.test.js.hbs +62 -0
- package/templates/base/src/core/base-classes/base-component/helpers/pipe.helper.test.js.hbs +82 -0
- package/templates/base/src/core/base-classes/base-component/helpers/security.helper.test.js.hbs +142 -0
- package/templates/base/src/core/base-classes/base-component/helpers/security.helper.ts.hbs +67 -22
- package/templates/base/src/core/base-classes/base-component/helpers/token.helper.test.js.hbs +183 -0
- package/templates/base/src/core/base-classes/component/component.test.js.hbs +85 -0
- package/templates/base/src/core/base-classes/component/component.ts.hbs +24 -33
- package/templates/base/src/core/base-classes/component/helpers/config.helper.test.js.hbs +58 -0
- package/templates/base/src/core/base-classes/component/helpers/data-binding.helper.test.js.hbs +75 -0
- package/templates/base/src/core/base-classes/service/service.test.js.hbs +150 -0
- package/templates/base/src/core/base-classes/service/service.ts.hbs +26 -20
- package/templates/base/src/core/base-classes/view/view.test.js.hbs +74 -0
- package/templates/base/src/core/base-classes/view/view.ts.hbs +17 -41
- package/templates/base/src/core/config.ts.hbs +7 -0
- package/templates/base/src/core/index.ts.hbs +0 -3
- package/templates/base/src/core/internals.d.ts.hbs +27 -0
- package/templates/base/src/core/nutin-config.d.ts.hbs +4 -0
- package/templates/base/src/core/services/event-bus/event-bus.test.js.hbs +67 -3
- package/templates/base/src/core/services/event-bus/event-bus.ts.hbs +9 -4
- package/templates/base/src/core/services/event-bus/index.ts.hbs +3 -0
- package/templates/base/src/core/services/event-bus/lifecycle.facade.test.js.hbs +123 -0
- package/templates/base/src/core/services/event-bus/lifecycle.facade.ts.hbs +61 -0
- package/templates/base/src/core/services/event-bus/navigation.facade.test.js.hbs +46 -0
- package/templates/base/src/core/services/event-bus/navigation.facade.ts.hbs +25 -0
- package/templates/base/src/core/services/globals/globals.test.js.hbs +149 -0
- package/templates/base/src/core/services/globals/globals.ts.hbs +95 -0
- package/templates/base/src/core/services/http-client/helpers/http-builder.helper.test.js.hbs +25 -0
- package/templates/base/src/core/services/http-client/helpers/http-manager.helper.test.js.hbs +20 -0
- package/templates/base/src/core/services/http-client/http-client.test.js.hbs +43 -0
- package/templates/base/src/core/services/i18n/i18n.test.js.hbs +270 -0
- package/templates/{features/i18n → base}/src/core/services/i18n/i18n.ts.hbs +22 -4
- package/templates/base/src/core/services/index.ts.hbs +5 -6
- package/templates/base/src/core/services/pipe-registry/pipe-registry.test.js.hbs +60 -1
- package/templates/base/src/core/services/pipe-registry/pipe-registry.ts.hbs +1 -1
- package/templates/base/src/core/services/pipe-registry/pipes.test.js.hbs +128 -0
- package/templates/base/src/{libs/pipes → core/services/pipe-registry}/pipes.ts.hbs +8 -5
- package/templates/base/src/core/services/router/helpers/navigation-manager.helper.test.js.hbs +149 -6
- package/templates/base/src/core/services/router/helpers/navigation-manager.helper.ts.hbs +40 -29
- package/templates/base/src/core/services/router/helpers/route-guard-manager.helper.test.js.hbs +27 -0
- package/templates/base/src/core/services/router/helpers/view-render-manager.helper.test.js.hbs +83 -17
- package/templates/base/src/core/services/router/helpers/view-render-manager.helper.ts.hbs +14 -38
- package/templates/base/src/core/services/router/router.test.js.hbs +226 -2
- package/templates/base/src/core/services/router/router.ts.hbs +40 -8
- package/templates/base/src/index.html.hbs +2 -6
- package/templates/base/src/styles/_styles.scss.hbs +102 -43
- package/templates/base/src/styles/base/_variables.scss.hbs +1 -86
- package/templates/base/src/styles/main.scss.hbs +1 -18
- package/templates/base/src/styles/tailwind.css.hbs +2 -0
- package/templates/base/tools/builder/builder.config.js.hbs +40 -0
- package/templates/base/tools/builder/builder.js.hbs +24 -26
- package/templates/base/tools/builder/core/app/binary-extensions.test.js.hbs +16 -0
- package/templates/base/tools/builder/core/app/compile-ts.js.hbs +16 -0
- package/templates/base/tools/builder/core/{copy-static.js.hbs → app/copy-static.js.hbs} +27 -34
- package/templates/base/tools/builder/core/app/validate-routes.js.hbs +77 -0
- package/templates/base/tools/builder/core/finalize-build.js.hbs +16 -7
- package/templates/base/tools/builder/core/{add-tags.js.hbs → html-index/add-tags.js.hbs} +2 -2
- package/templates/base/tools/builder/core/html-index/add-tags.test.js.hbs +56 -0
- package/templates/base/tools/builder/core/{validate-html.js.hbs → html-index/validate-html.js.hbs} +5 -11
- package/templates/base/tools/builder/core/html-templates/merge-templates.js.hbs +152 -0
- package/templates/base/tools/builder/core/html-templates/minify-html.js.hbs +15 -0
- package/templates/base/tools/builder/core/html-templates/process-html-templates.js.hbs +8 -0
- package/templates/{features/i18n/tools/builder/core → base/tools/builder/core/i18n}/build-i18n.js.hbs +6 -17
- package/templates/base/tools/builder/core/prod-bundle/compress-files.js.hbs +37 -0
- package/templates/base/tools/builder/core/prod-bundle/esbuild.js.hbs +30 -0
- package/templates/base/tools/builder/core/{hash-files.js.hbs → prod-bundle/hash-files.js.hbs} +14 -11
- package/templates/base/tools/builder/core/seo/generate-robots-txt.js.hbs +51 -0
- package/templates/base/tools/builder/core/seo/generate-seo-files.js.hbs +16 -0
- package/templates/base/tools/builder/core/seo/generate-seo-html.js.hbs +128 -0
- package/templates/base/tools/builder/core/seo/generate-sitemap-xml.js.hbs +43 -0
- package/templates/base/tools/builder/core/seo/html-substitutions.js.hbs +99 -0
- package/templates/base/tools/builder/core/seo/i18n-resolution.js.hbs +66 -0
- package/templates/base/tools/builder/core/seo/route-output.js.hbs +64 -0
- package/templates/base/tools/builder/core/seo/ssr/ssr-bundle.js.hbs +54 -0
- package/templates/base/tools/builder/core/seo/ssr/ssr-polyfills.js.hbs +132 -0
- package/templates/base/tools/builder/core/seo/ssr/ssr-render.js.hbs +95 -0
- package/templates/base/tools/builder/core/styles/sass.js.hbs +40 -0
- package/templates/base/tools/builder/core/styles/tailwind.js.hbs +84 -0
- package/templates/base/tools/dev/dev-serve.js.hbs +26 -18
- package/templates/base/tools/dev/serve.js.hbs +11 -1
- package/templates/base/tools/dev/watcher.js.hbs +14 -6
- package/templates/base/tools/generator/generator.js.hbs +64 -47
- package/templates/base/tools/generator/handle-file.js.hbs +17 -44
- package/templates/base/tools/generator/handle-file.test.js.hbs +72 -0
- package/templates/base/tools/generator/templates/{component.template.js.hbs → component/component.template.js.hbs} +3 -2
- package/templates/base/tools/generator/templates/component/component.template.test.js.hbs +23 -0
- package/templates/base/tools/generator/templates/html/html.template.js.hbs +2 -0
- package/templates/base/tools/generator/templates/html/html.template.test.js.hbs +7 -0
- package/templates/base/tools/generator/templates/index.js.hbs +7 -12
- package/templates/base/tools/generator/templates/locale/locale.template.js.hbs +4 -0
- package/templates/base/tools/generator/templates/locale/locale.template.test.js.hbs +7 -0
- package/templates/base/tools/generator/templates/scss/scss.template.js.hbs +1 -0
- package/templates/base/tools/generator/templates/scss/scss.template.test.js.hbs +7 -0
- package/templates/base/tools/generator/templates/service/service.template.js.hbs +17 -0
- package/templates/base/tools/generator/templates/service/service.template.test.js.hbs +22 -0
- package/templates/base/tools/generator/templates/test/test.template.js.hbs +10 -0
- package/templates/base/tools/generator/templates/test/test.template.test.js.hbs +27 -0
- package/templates/base/tools/generator/templates/{view.template.js.hbs → view/view.template.js.hbs} +3 -2
- package/templates/base/tools/generator/templates/view/view.template.test.js.hbs +24 -0
- package/templates/base/tools/testin-nutin/core/coverage/collect-coverage.js.hbs +39 -0
- package/templates/base/tools/testin-nutin/core/coverage/compute-coverage.js.hbs +115 -0
- package/templates/base/tools/testin-nutin/core/coverage/compute-coverage.test.js.hbs +74 -0
- package/templates/base/tools/testin-nutin/core/coverage/write-summary-report.js.hbs +54 -0
- package/templates/base/tools/testin-nutin/core/coverage/write-uncovered-report.js.hbs +44 -0
- package/templates/{features/testinNutin/testin-nutin/core/src → base/tools/testin-nutin/core}/globals/assertion-lib.js.hbs +62 -24
- package/templates/base/tools/testin-nutin/core/globals/clock.js.hbs +206 -0
- package/templates/{features/testinNutin/testin-nutin/core/src → base/tools/testin-nutin/core}/globals/jsdom-setup.js.hbs +19 -6
- package/templates/{features/testinNutin/testin-nutin/core/src → base/tools/testin-nutin/core}/globals/register-test-globals.js.hbs +13 -4
- package/templates/base/tools/testin-nutin/core/globals/silence-console.js.hbs +23 -0
- package/templates/{features/testinNutin/testin-nutin/core/src → base/tools/testin-nutin/core}/globals/spyon.js.hbs +2 -0
- package/templates/base/tools/testin-nutin/core/index.js.hbs +9 -0
- package/templates/base/tools/testin-nutin/core/printer.js.hbs +85 -0
- package/templates/base/tools/testin-nutin/core/queue/queue.test.js.hbs +46 -0
- package/templates/base/tools/testin-nutin/core/queue/test-discovery.test.js.hbs +46 -0
- package/templates/base/tools/testin-nutin/core/queue/test-queue.js.hbs +154 -0
- package/templates/{features/testinNutin → base/tools}/testin-nutin/core/tests/assertions.test.js.hbs +27 -0
- package/templates/base/tools/testin-nutin/core/tests/clock.test.js.hbs +118 -0
- package/templates/base/tools/testin-nutin/core/tests/globals-each-all.test.js.hbs +28 -0
- package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/create-mock-method.js.hbs +2 -1
- package/templates/base/tools/testin-nutin/mocks/create-mock-method.test.js.hbs +64 -0
- package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/mock-event-bus.js.hbs +3 -2
- package/templates/base/tools/testin-nutin/mocks/mock-event-bus.test.js.hbs +66 -0
- package/templates/base/tools/testin-nutin/mocks/mock-http-client.test.js.hbs +26 -0
- package/templates/base/tools/testin-nutin/mocks/mock-i18n.test.js.hbs +61 -0
- package/templates/base/tools/testin-nutin/mocks/mock-router.test.js.hbs +29 -0
- package/templates/base/tools/testin-nutin/runner.js.hbs +100 -0
- package/templates/base/tools/testin-nutin/watch-tests.js.hbs +37 -0
- package/templates/base/tools/utils/error-exit.js.hbs +8 -0
- package/templates/base/tools/utils/format.js.hbs +10 -10
- package/templates/base/tools/utils/format.test.js.hbs +45 -0
- package/templates/base/tools/utils/get-files-recursive.js.hbs +6 -1
- package/templates/base/tools/utils/get-files-recursive.test.js.hbs +49 -0
- package/templates/base/tools/utils/get-rel-to-core.test.js.hbs +18 -0
- package/templates/base/tools/utils/index.js.hbs +1 -3
- package/templates/base/tools/utils/languages.js.hbs +15 -0
- package/templates/base/tools/utils/languages.test.js.hbs +16 -0
- package/templates/base/tools/utils/print.js.hbs +19 -13
- package/templates/base/tools/utils/print.test.js.hbs +60 -0
- package/templates/base/tools/utils/prompt-boolean.js.hbs +7 -0
- package/templates/base/tools/utils/prompt-boolean.test.js.hbs +54 -0
- package/templates/base/tools/utils/run-command.js.hbs +4 -2
- package/templates/base/tools/utils/run-command.test.js.hbs +19 -0
- package/templates/base/tools/utils/run-script.js.hbs +14 -3
- package/templates/base/tools/utils/run-script.test.js.hbs +40 -0
- package/templates/features/{deployHelper → docker}/.dockerignore.hbs +4 -4
- package/templates/features/docker/tools/docker/Dockerfile.template.hbs +51 -0
- package/templates/features/{deployHelper/tools/deployment/nginx.conf.hbs → docker/tools/docker/nginx.conf.template} +4 -2
- package/templates/features/docker/tools/docker/scripts/docker-build.js.hbs +20 -0
- package/templates/features/docker/tools/docker/scripts/docker-ports.js.hbs +48 -0
- package/templates/features/docker/tools/docker/scripts/docker-ports.test.js.hbs +52 -0
- package/templates/features/docker/tools/docker/scripts/docker-run.js.hbs +28 -0
- package/templates/features/docker/tools/docker/scripts/render-docker-template.js.hbs +23 -0
- package/templates/features/docker/tools/docker/scripts/render-docker-template.test.js.hbs +60 -0
- package/templates/features/docker/tools/docker/scripts/validate-docker.js.hbs +30 -0
- package/lib/src/context-builder.mjs +0 -40
- package/lib/src/file-generator.mjs +0 -109
- package/lib/src/json-generator.mjs +0 -31
- package/lib/src/package-manager.mjs +0 -139
- package/lib/src/print.mjs +0 -32
- package/lib/src/utils.mjs +0 -18
- package/lib/src/version.mjs +0 -1
- package/templates/base/builder.config.js.hbs +0 -36
- package/templates/base/src/app/components/common/anchor/anchor.component.ts.hbs +0 -32
- package/templates/base/src/app/components/common/button/button.component.ts.hbs +0 -40
- package/templates/base/src/app/dom.test.js.hbs +0 -13
- package/templates/base/src/app/services/example/example.service.ts.hbs +0 -18
- package/templates/base/src/app/views/home/home.view.test.js.hbs +0 -26
- package/templates/base/src/core/services/store/store.test.js.hbs +0 -8
- package/templates/base/src/core/services/store/store.ts.hbs +0 -39
- package/templates/base/src/core/utils/anchor-manager/anchor-manager.utils.test.js.hbs +0 -0
- package/templates/base/src/core/utils/anchor-manager/anchor-manager.utils.ts.hbs +0 -113
- package/templates/base/src/core/utils/button-manager/button-manager.utils.test.js.hbs +0 -249
- package/templates/base/src/core/utils/button-manager/button-manager.utils.ts.hbs +0 -131
- package/templates/base/src/core/utils/helpers/attributes.helper.ts.hbs +0 -50
- package/templates/base/src/core/utils/index.ts.hbs +0 -2
- package/templates/base/src/libs/index.ts.hbs +0 -4
- package/templates/base/src/libs/popover/helpers/focus-trap.helper.ts.hbs +0 -197
- package/templates/base/src/libs/popover/helpers/popover-dom.helper.ts.hbs +0 -75
- package/templates/base/src/libs/popover/popover.ts.hbs +0 -138
- package/templates/base/src/libs/snackbar/snackbar.ts.hbs +0 -75
- package/templates/base/src/styles/base/_functions.scss.hbs +0 -9
- package/templates/base/src/styles/core/_anchors.scss.hbs +0 -10
- package/templates/base/src/styles/core/_index.scss.hbs +0 -6
- package/templates/base/src/styles/core/_popover.scss.hbs +0 -96
- package/templates/base/src/styles/core/_snackbar.scss.hbs +0 -50
- package/templates/base/tools/builder/core/esbuild.js.hbs +0 -25
- package/templates/base/tools/builder/core/minify-html.js.hbs +0 -60
- package/templates/base/tools/builder/core/sass.js.hbs +0 -22
- package/templates/base/tools/builder/core/tsc.js.hbs +0 -12
- package/templates/base/tools/generator/templates/service.template.js.hbs +0 -17
- package/templates/base/tools/utils/export-flags.js.hbs +0 -6
- package/templates/features/deployHelper/tools/builder/core/compress-files.js.hbs +0 -56
- package/templates/features/deployHelper/tools/deployment/Dockerfile.hbs +0 -30
- package/templates/features/i18n/src/app/views/home/locales/en.json.hbs +0 -9
- package/templates/features/i18n/src/app/views/not-found/locales/en.json +0 -8
- package/templates/features/i18n/src/app/views/not-found/locales/fr.json +0 -8
- package/templates/features/i18n/src/core/config.ts.hbs +0 -3
- package/templates/features/i18n/src/core/services/i18n/i18n.test.js.hbs +0 -125
- package/templates/features/i18n/tools/generator/templates/json.template.js.hbs +0 -8
- package/templates/features/i18n/tools/utils/languages.js.hbs +0 -7
- package/templates/features/stylinNutin/src/styles/_custom-classes.scss.hbs +0 -9
- package/templates/features/stylinNutin/src/styles/base/_mixins.scss.hbs +0 -372
- package/templates/features/stylinNutin/src/styles/components/_index.scss.hbs +0 -3
- package/templates/features/stylinNutin/src/styles/core/_utilities.scss.hbs +0 -254
- package/templates/features/stylinNutin/src/styles/views/_index.scss.hbs +0 -0
- package/templates/features/stylinNutin/tools/generator/templates/scss.template.js.hbs +0 -4
- package/templates/features/template/src/app/views/home/home.view.html.hbs +0 -56
- package/templates/features/template/src/app/views/not-found/not-found.view.html.hbs +0 -19
- package/templates/features/template/tools/builder/core/merge-templates.js.hbs +0 -49
- package/templates/features/template/tools/generator/templates/html.template.js.hbs +0 -2
- package/templates/features/testinNutin/testin-nutin/core/index.js.hbs +0 -5
- package/templates/features/testinNutin/testin-nutin/core/src/utils/print.js.hbs +0 -64
- package/templates/features/testinNutin/testin-nutin/core/src/utils/test-queue.js.hbs +0 -64
- package/templates/features/testinNutin/testin-nutin/core/tests/globals-each-all.test.js.hbs +0 -28
- package/templates/features/testinNutin/testin-nutin/mocks/mock-store.js.hbs +0 -38
- package/templates/features/testinNutin/testin-nutin/runner.js.hbs +0 -36
- package/templates/features/testinNutin/testin-nutin/watch-tests.js.hbs +0 -21
- package/templates/features/testinNutin/testin-nutin.config.js.hbs +0 -14
- /package/lib/src/{template-compiler.mjs → common/template-compiler.mjs} +0 -0
- /package/templates/{features/i18n → base}/src/core/base-classes/base-component/helpers/i18n.helper.ts.hbs +0 -0
- /package/templates/{features/i18n → base}/src/core/services/i18n/languages.ts.hbs +0 -0
- /package/templates/base/tools/builder/{variables → core/app}/binary-extensions.js.hbs +0 -0
- /package/templates/base/tools/builder/core/{paths.js.hbs → app/paths.js.hbs} +0 -0
- /package/templates/{features/testinNutin/testin-nutin/core/src/utils → base/tools/testin-nutin/core/queue}/queue.js.hbs +0 -0
- /package/templates/{features/testinNutin/testin-nutin/core/src/utils → base/tools/testin-nutin/core/queue}/test-discovery.js.hbs +0 -0
- /package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/mock-http-client.js.hbs +0 -0
- /package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/mock-i18n.js.hbs +0 -0
- /package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/mock-router.js.hbs +0 -0
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { AttributesHelper, IAttributesConfig } from "../helpers/attributes.helper.js";
|
|
2
|
-
|
|
3
|
-
export interface BaseButton extends IAttributesConfig {
|
|
4
|
-
callback: () => void;
|
|
5
|
-
label?: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface ButtonContainerOptions {
|
|
9
|
-
containerClassName?: string;
|
|
10
|
-
containerStyles?: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* ```typescript
|
|
15
|
-
interface IAttributesConfig {
|
|
16
|
-
{{#if i18n}}
|
|
17
|
-
i18nKey?: string;
|
|
18
|
-
{{/if}}
|
|
19
|
-
textContent?: string;
|
|
20
|
-
className?: string;
|
|
21
|
-
style?: string;
|
|
22
|
-
// use regular pipe syntax for arguments / chaining
|
|
23
|
-
pipes?: string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
interface ButtonContainerOptions {
|
|
27
|
-
containerClassName?: string;
|
|
28
|
-
containerStyles?: string;
|
|
29
|
-
}
|
|
30
|
-
```
|
|
31
|
-
*/
|
|
32
|
-
export class ButtonManager {
|
|
33
|
-
private component: any;
|
|
34
|
-
private buttons: BaseButton[];
|
|
35
|
-
private containerOptions: ButtonContainerOptions;
|
|
36
|
-
|
|
37
|
-
constructor(
|
|
38
|
-
component: any,
|
|
39
|
-
buttons: BaseButton[] = [],
|
|
40
|
-
containerOptions: ButtonContainerOptions = {}
|
|
41
|
-
) {
|
|
42
|
-
this.component = component;
|
|
43
|
-
this.buttons = buttons;
|
|
44
|
-
this.containerOptions = {
|
|
45
|
-
containerClassName: 'dynamic-buttons',
|
|
46
|
-
containerStyles: '',
|
|
47
|
-
...containerOptions
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
public createButtonContainer(): HTMLElement | null {
|
|
52
|
-
if (!Array.isArray(this.buttons) || this.buttons.length === 0) {
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const container = document.createElement('div');
|
|
57
|
-
container.className = this.containerOptions.containerClassName || 'dynamic-buttons';
|
|
58
|
-
container.style = this.containerOptions.containerStyles || '';
|
|
59
|
-
|
|
60
|
-
this.buttons.forEach((config, index) => {
|
|
61
|
-
if (config.label) {
|
|
62
|
-
return this.createButtonWithCheckbox(config, index, container);
|
|
63
|
-
} else {
|
|
64
|
-
const button = this.createButton(config, index);
|
|
65
|
-
container.appendChild(button);
|
|
66
|
-
this.bindButtonCallback(config, index);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
return container;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
public appendTo(target: HTMLElement): void {
|
|
74
|
-
const container = this.createButtonContainer();
|
|
75
|
-
if (container) {
|
|
76
|
-
target.appendChild(container);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
private createButtonWithCheckbox(config: BaseButton, index: number, container: HTMLElement): HTMLElement {
|
|
81
|
-
if (!config.label) return container;
|
|
82
|
-
const checkbox = document.createElement('input');
|
|
83
|
-
checkbox.setAttribute('type', 'checkbox');
|
|
84
|
-
checkbox.setAttribute('id', config.label);
|
|
85
|
-
checkbox.hidden = true;
|
|
86
|
-
container.appendChild(checkbox);
|
|
87
|
-
|
|
88
|
-
const label = document.createElement('label');
|
|
89
|
-
label.setAttribute('for', config.label);
|
|
90
|
-
|
|
91
|
-
const button = this.createButton(config, index);
|
|
92
|
-
label.appendChild(button);
|
|
93
|
-
|
|
94
|
-
container.appendChild(label);
|
|
95
|
-
this.bindButtonCallback(config, index, checkbox);
|
|
96
|
-
return container;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
private createButton(config: BaseButton, index: number): HTMLElement {
|
|
100
|
-
const button = document.createElement('button');
|
|
101
|
-
|
|
102
|
-
AttributesHelper.setAttributes(button, config);
|
|
103
|
-
|
|
104
|
-
this.setDataEvent(button, index);
|
|
105
|
-
|
|
106
|
-
return button;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
private setDataEvent(button: HTMLButtonElement, index: number): void {
|
|
110
|
-
button.setAttribute('data-event', `click:onButtonClick_${index}`);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
private bindButtonCallback(config: BaseButton, index: number, checkbox?: HTMLInputElement): void {
|
|
114
|
-
const methodName = `onButtonClick_${index}`;
|
|
115
|
-
|
|
116
|
-
this.component[methodName] = () => {
|
|
117
|
-
if (typeof config.callback === 'function') {
|
|
118
|
-
config.callback();
|
|
119
|
-
if (checkbox) {
|
|
120
|
-
checkbox.checked = !checkbox.checked;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/** Note : doesn't track container
|
|
127
|
-
*/
|
|
128
|
-
public updateButtons(newButtons: BaseButton[]): void {
|
|
129
|
-
this.buttons = newButtons;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
export interface IAttributesConfig {
|
|
2
|
-
{{#if i18n}}
|
|
3
|
-
i18nKey?: string;
|
|
4
|
-
{{/if}}
|
|
5
|
-
textContent?: string;
|
|
6
|
-
className?: string;
|
|
7
|
-
style?: string;
|
|
8
|
-
// use regular pipe syntax for arguments / chaining
|
|
9
|
-
pipes?: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export class AttributesHelper {
|
|
13
|
-
public static setAttributes(element: HTMLElement, config: IAttributesConfig): void {
|
|
14
|
-
this.setContent(element, config);
|
|
15
|
-
this.setPipes(element, config);
|
|
16
|
-
this.setStyle(element, config);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
private static setContent(element: HTMLElement, config: IAttributesConfig): void {
|
|
20
|
-
element.textContent = config.textContent || '';
|
|
21
|
-
{{#if i18n}}
|
|
22
|
-
if (config.i18nKey) {
|
|
23
|
-
element.setAttribute('data-i18n', config.i18nKey);
|
|
24
|
-
}
|
|
25
|
-
{{/if}}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
private static setPipes(element: HTMLElement, config: IAttributesConfig): void {
|
|
29
|
-
if (!config.pipes) return;
|
|
30
|
-
element.setAttribute('data-pipe', config.pipes);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
private static setStyle(element: HTMLElement, config: IAttributesConfig): void {
|
|
34
|
-
const classes = [
|
|
35
|
-
config.className
|
|
36
|
-
].filter(Boolean).join(' ');
|
|
37
|
-
|
|
38
|
-
const style = [
|
|
39
|
-
config.style
|
|
40
|
-
].filter(Boolean).join(' ');
|
|
41
|
-
|
|
42
|
-
if (classes) {
|
|
43
|
-
element.className = classes;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if(style) {
|
|
47
|
-
element.style = style;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
import { AppEventBus } from "../../../core/index.js";
|
|
2
|
-
|
|
3
|
-
type KeyboardEventHandler = (event: KeyboardEvent) => void;
|
|
4
|
-
|
|
5
|
-
export interface IFocusTrapOptions {
|
|
6
|
-
escapeDeactivates?: boolean;
|
|
7
|
-
clickOutsideDeactivates?: boolean;
|
|
8
|
-
returnFocusOnDeactivate?: boolean;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface IFocusTrapHelperParams {
|
|
12
|
-
container: HTMLElement;
|
|
13
|
-
overlay: HTMLElement;
|
|
14
|
-
options?: IFocusTrapOptions;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export class FocusTrapHelper {
|
|
18
|
-
private _container: HTMLElement;
|
|
19
|
-
private _overlay: HTMLElement;
|
|
20
|
-
private _previousActiveElement: HTMLElement | null | undefined = null;
|
|
21
|
-
private _focusableElements: NodeListOf<HTMLElement> | null | undefined = null;
|
|
22
|
-
private _firstFocusableElement: HTMLElement | null | undefined = null;
|
|
23
|
-
private _lastFocusableElement: HTMLElement | null | undefined = null;
|
|
24
|
-
private _boundKeyDown: KeyboardEventHandler;
|
|
25
|
-
private _options: IFocusTrapOptions;
|
|
26
|
-
private _isActive: boolean = false;
|
|
27
|
-
|
|
28
|
-
constructor({container, overlay, options = {}}: IFocusTrapHelperParams) {
|
|
29
|
-
this._container = container;
|
|
30
|
-
this._overlay = overlay;
|
|
31
|
-
this._options = {
|
|
32
|
-
escapeDeactivates: true,
|
|
33
|
-
clickOutsideDeactivates: true,
|
|
34
|
-
returnFocusOnDeactivate: true,
|
|
35
|
-
...options
|
|
36
|
-
};
|
|
37
|
-
this._boundKeyDown = this._handleKeyDown.bind(this);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
private _getFocusableElements(): NodeListOf<HTMLElement> {
|
|
41
|
-
return this._container.querySelectorAll(
|
|
42
|
-
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
43
|
-
) as NodeListOf<HTMLElement>;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
public activate(): void {
|
|
47
|
-
if (this._isActive) return;
|
|
48
|
-
|
|
49
|
-
this._previousActiveElement = document.activeElement as HTMLElement;
|
|
50
|
-
|
|
51
|
-
this._focusableElements = this._getFocusableElements();
|
|
52
|
-
|
|
53
|
-
if (this._focusableElements.length > 0) {
|
|
54
|
-
this._firstFocusableElement = this._focusableElements[0];
|
|
55
|
-
this._lastFocusableElement = this._focusableElements[this._focusableElements.length - 1];
|
|
56
|
-
|
|
57
|
-
this._firstFocusableElement?.focus();
|
|
58
|
-
} else {
|
|
59
|
-
this._container.setAttribute('tabindex', '-1');
|
|
60
|
-
this._container.focus();
|
|
61
|
-
this._firstFocusableElement = this._container;
|
|
62
|
-
this._lastFocusableElement = this._container;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
this._container.addEventListener('keydown', this._boundKeyDown);
|
|
66
|
-
|
|
67
|
-
document.addEventListener('click', this._handleOutsideClick.bind(this));
|
|
68
|
-
|
|
69
|
-
this._disableOutsideTabIndex();
|
|
70
|
-
|
|
71
|
-
this._isActive = true;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
public deactivate(): void {
|
|
75
|
-
if (!this._isActive) return;
|
|
76
|
-
|
|
77
|
-
this._container.removeEventListener('keydown', this._boundKeyDown);
|
|
78
|
-
document.removeEventListener('click', this._handleOutsideClick.bind(this));
|
|
79
|
-
|
|
80
|
-
this._enableOutsideTabIndex();
|
|
81
|
-
|
|
82
|
-
if (this._container.getAttribute('tabindex') === '-1') {
|
|
83
|
-
this._container.removeAttribute('tabindex');
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (this._options.returnFocusOnDeactivate &&
|
|
87
|
-
this._previousActiveElement &&
|
|
88
|
-
this._previousActiveElement.focus
|
|
89
|
-
) {
|
|
90
|
-
this._previousActiveElement.focus();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
this._focusableElements = null;
|
|
94
|
-
this._firstFocusableElement = null;
|
|
95
|
-
this._lastFocusableElement = null;
|
|
96
|
-
this._previousActiveElement = null;
|
|
97
|
-
|
|
98
|
-
this._isActive = false;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
public getIsActive(): boolean {
|
|
102
|
-
return this._isActive;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
public updateFocusableElements(): void {
|
|
106
|
-
if (!this._isActive) return;
|
|
107
|
-
|
|
108
|
-
this._focusableElements = this._getFocusableElements();
|
|
109
|
-
|
|
110
|
-
if (this._focusableElements.length > 0) {
|
|
111
|
-
this._firstFocusableElement = this._focusableElements[0];
|
|
112
|
-
this._lastFocusableElement = this._focusableElements[this._focusableElements.length - 1];
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
private _disableOutsideTabIndex(): void {
|
|
117
|
-
const allElements = document.querySelectorAll('body *') as NodeListOf<HTMLElement>;
|
|
118
|
-
|
|
119
|
-
allElements.forEach((el: HTMLElement) => {
|
|
120
|
-
if (!this._container.contains(el)) {
|
|
121
|
-
const currentTabIndex = el.getAttribute('tabindex');
|
|
122
|
-
if (currentTabIndex !== '-1') {
|
|
123
|
-
const originalTabIndex = currentTabIndex ||
|
|
124
|
-
(el.tabIndex !== -1 ? el.tabIndex.toString() : null);
|
|
125
|
-
|
|
126
|
-
if (originalTabIndex !== null) {
|
|
127
|
-
el.setAttribute('data-original-tabindex', originalTabIndex);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
el.setAttribute('tabindex', '-1');
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
private _enableOutsideTabIndex(): void {
|
|
137
|
-
const allElements = document.querySelectorAll(
|
|
138
|
-
'[data-original-tabindex]'
|
|
139
|
-
) as NodeListOf<HTMLElement>;
|
|
140
|
-
|
|
141
|
-
allElements.forEach((el: HTMLElement) => {
|
|
142
|
-
const originalTabIndex = el.getAttribute('data-original-tabindex');
|
|
143
|
-
|
|
144
|
-
if (originalTabIndex === null) {
|
|
145
|
-
el.removeAttribute('tabindex');
|
|
146
|
-
} else if (originalTabIndex === '0') {
|
|
147
|
-
el.removeAttribute('tabindex');
|
|
148
|
-
} else {
|
|
149
|
-
el.setAttribute('tabindex', originalTabIndex);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
el.removeAttribute('data-original-tabindex');
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
private _handleKeyDown(event: KeyboardEvent): void {
|
|
157
|
-
switch (event.key) {
|
|
158
|
-
case 'Tab':
|
|
159
|
-
this._handleTabKey(event);
|
|
160
|
-
break;
|
|
161
|
-
case 'Escape':
|
|
162
|
-
if (this._options.escapeDeactivates) {
|
|
163
|
-
event.preventDefault();
|
|
164
|
-
AppEventBus.emit('popover-close');
|
|
165
|
-
this.deactivate();
|
|
166
|
-
}
|
|
167
|
-
break;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
private _handleTabKey(event: KeyboardEvent): void {
|
|
172
|
-
if (!this._focusableElements || this._focusableElements.length === 0) return;
|
|
173
|
-
|
|
174
|
-
if (event.shiftKey) {
|
|
175
|
-
if (document.activeElement === this._firstFocusableElement) {
|
|
176
|
-
event.preventDefault();
|
|
177
|
-
this._lastFocusableElement?.focus();
|
|
178
|
-
}
|
|
179
|
-
} else {
|
|
180
|
-
if (document.activeElement === this._lastFocusableElement) {
|
|
181
|
-
event.preventDefault();
|
|
182
|
-
this._firstFocusableElement?.focus();
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
private _handleOutsideClick(event: MouseEvent): void {
|
|
188
|
-
if (!this._options.clickOutsideDeactivates) return;
|
|
189
|
-
this._overlay.addEventListener('click', (e: MouseEvent) => {
|
|
190
|
-
if (e.target === this._overlay){
|
|
191
|
-
event.stopPropagation();
|
|
192
|
-
AppEventBus.emit('popover-close');
|
|
193
|
-
this.deactivate();;
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { ButtonManager } from "src/core/index.js";
|
|
2
|
-
|
|
3
|
-
export interface IPopoverDomElements {
|
|
4
|
-
wrapper: HTMLElement;
|
|
5
|
-
overlay: HTMLElement;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export class PopoverDomHelper {
|
|
9
|
-
public static createDomElements(
|
|
10
|
-
content: HTMLElement,
|
|
11
|
-
buttonManager: ButtonManager
|
|
12
|
-
): IPopoverDomElements {
|
|
13
|
-
const overlay = this.createOverlay();
|
|
14
|
-
const wrapper = this.createWrapper();
|
|
15
|
-
content = this.createContent(content);
|
|
16
|
-
|
|
17
|
-
this.appendCloseButton(content);
|
|
18
|
-
this.appendFooterButtons(content, buttonManager);
|
|
19
|
-
|
|
20
|
-
wrapper.appendChild(content);
|
|
21
|
-
overlay.appendChild(wrapper);
|
|
22
|
-
document.body.appendChild(overlay);
|
|
23
|
-
|
|
24
|
-
return { wrapper, overlay };
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
public static removeDomElements(overlay: HTMLElement | null, onRemoved?: () => void): null {
|
|
28
|
-
if (overlay) {
|
|
29
|
-
const wrapper = overlay.querySelector('.popover-wrapper');
|
|
30
|
-
overlay.classList.remove('show');
|
|
31
|
-
wrapper?.classList.remove('show');
|
|
32
|
-
|
|
33
|
-
setTimeout(() => {
|
|
34
|
-
wrapper?.remove();
|
|
35
|
-
overlay?.remove();
|
|
36
|
-
onRemoved?.();
|
|
37
|
-
}, 300); // match transition duration
|
|
38
|
-
}
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
private static createOverlay(): HTMLElement {
|
|
43
|
-
const overlay = document.createElement('div');
|
|
44
|
-
overlay.className = 'popover-overlay';
|
|
45
|
-
return overlay;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
private static createWrapper(): HTMLElement {
|
|
49
|
-
const wrapper = document.createElement('div');
|
|
50
|
-
wrapper.className = 'popover-wrapper';
|
|
51
|
-
return wrapper;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
private static createContent(content: HTMLElement): HTMLElement {
|
|
55
|
-
content.classList.add('popover-content');
|
|
56
|
-
return content;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
private static appendCloseButton(content: HTMLElement): void {
|
|
60
|
-
const closeButton = document.createElement('button');
|
|
61
|
-
closeButton.className = 'popover-close-button';
|
|
62
|
-
closeButton.innerHTML = '×';
|
|
63
|
-
closeButton.setAttribute('aria-label', 'Close');
|
|
64
|
-
// bind method onCloseClick
|
|
65
|
-
closeButton.setAttribute('data-event', 'click:onCloseClick');
|
|
66
|
-
content.prepend(closeButton);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
private static appendFooterButtons(
|
|
70
|
-
content: HTMLElement,
|
|
71
|
-
buttonManager: ButtonManager
|
|
72
|
-
): void {
|
|
73
|
-
buttonManager.appendTo(content);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import { View, ButtonManager, BaseButton, ComponentConfig, AppPipeRegistry, CatalogConfig, AppEventBus } from '../../core/index.js';
|
|
2
|
-
import { FocusTrapHelper, IFocusTrapOptions } from './helpers/focus-trap.helper.js';
|
|
3
|
-
import { IPopoverDomElements, PopoverDomHelper } from './helpers/popover-dom.helper.js';
|
|
4
|
-
|
|
5
|
-
export interface PopoverButton extends BaseButton {
|
|
6
|
-
// if needed for Popover-specific properties
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface PopoverOptions {
|
|
10
|
-
template: string;
|
|
11
|
-
components?: ComponentConfig[];
|
|
12
|
-
catalogs?: CatalogConfig[];
|
|
13
|
-
viewName?: string;
|
|
14
|
-
onClose?: () => void;
|
|
15
|
-
buttons?: PopoverButton[];
|
|
16
|
-
focusTrapOptions?: IFocusTrapOptions;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export class PopoverView extends View {
|
|
20
|
-
private _onClose?: () => void;
|
|
21
|
-
private _overlay: HTMLElement | null = null;
|
|
22
|
-
private _buttonManager: ButtonManager;
|
|
23
|
-
private _prevTitle: string | undefined;
|
|
24
|
-
private _catalogs: CatalogConfig[];
|
|
25
|
-
private _focusTrap: FocusTrapHelper | null = null;
|
|
26
|
-
private _focusTrapOptions: IFocusTrapOptions;
|
|
27
|
-
private _components: ComponentConfig[];
|
|
28
|
-
|
|
29
|
-
constructor({
|
|
30
|
-
template,
|
|
31
|
-
buttons = [],
|
|
32
|
-
onClose,
|
|
33
|
-
viewName,
|
|
34
|
-
components = [],
|
|
35
|
-
catalogs = [],
|
|
36
|
-
focusTrapOptions = {}
|
|
37
|
-
}: PopoverOptions) {
|
|
38
|
-
super({ template, tagName: 'div', mountTarget: 'body' });
|
|
39
|
-
this._onClose = onClose;
|
|
40
|
-
this._components = components;
|
|
41
|
-
this._catalogs = catalogs;
|
|
42
|
-
this._buttonManager = this.createButtonManager(buttons);
|
|
43
|
-
this.setOptionalViewName(viewName);
|
|
44
|
-
this._focusTrapOptions = focusTrapOptions;
|
|
45
|
-
AppEventBus.subscribe('popover-close', () => this.destroy());
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
public childConfigs(): ComponentConfig[] {
|
|
49
|
-
return [
|
|
50
|
-
...this._components,
|
|
51
|
-
...this.catalogConfigs()
|
|
52
|
-
];
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
public catalogConfigs(): ComponentConfig[] {
|
|
56
|
-
const configs: ComponentConfig[] = []
|
|
57
|
-
this._catalogs.map((catalog) => {
|
|
58
|
-
configs.push(...this.catalogConfig(catalog));
|
|
59
|
-
})
|
|
60
|
-
return configs;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
public override shouldUpdateMetaContent(): boolean {
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
public override render(): HTMLElement {
|
|
68
|
-
document.documentElement.classList.add('no-scroll');
|
|
69
|
-
|
|
70
|
-
const { wrapper, overlay } = this.createPopoverDomElements();
|
|
71
|
-
|
|
72
|
-
this._focusTrap = this.createFocusTrap(wrapper, overlay);
|
|
73
|
-
this._focusTrap.activate();
|
|
74
|
-
|
|
75
|
-
AppEventBus.emit('popover-opened');
|
|
76
|
-
this._overlay = overlay;
|
|
77
|
-
return overlay;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
public override destroy(): void {
|
|
81
|
-
this._focusTrap?.deactivate();
|
|
82
|
-
if (this._prevTitle) document.title = this._prevTitle;
|
|
83
|
-
|
|
84
|
-
this._overlay = PopoverDomHelper.removeDomElements(this._overlay, () => {
|
|
85
|
-
document.documentElement.classList.remove('no-scroll');
|
|
86
|
-
super.destroy();
|
|
87
|
-
if (typeof this._onClose === 'function') {
|
|
88
|
-
this._onClose();
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
private setOptionalViewName(viewName: string | undefined): void {
|
|
94
|
-
if (viewName) {
|
|
95
|
-
this._prevTitle = document.title;
|
|
96
|
-
document.title = AppPipeRegistry.apply('capitalize', viewName);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
private createButtonManager(buttons: PopoverButton[]): ButtonManager {
|
|
101
|
-
return new ButtonManager(
|
|
102
|
-
this,
|
|
103
|
-
buttons,
|
|
104
|
-
{ containerClassName: 'popover-buttons' }
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
private createPopoverDomElements(): IPopoverDomElements {
|
|
109
|
-
const content = super.render();
|
|
110
|
-
const { overlay, wrapper } = PopoverDomHelper.createDomElements(content, this._buttonManager);
|
|
111
|
-
|
|
112
|
-
this.autoBindEvents();
|
|
113
|
-
this.parseDataAttributes();
|
|
114
|
-
this.animateIn(wrapper);
|
|
115
|
-
|
|
116
|
-
return { overlay, wrapper };
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
private createFocusTrap(wrapper: HTMLElement, overlay: HTMLElement): FocusTrapHelper {
|
|
120
|
-
return new FocusTrapHelper({
|
|
121
|
-
container: wrapper,
|
|
122
|
-
overlay: overlay,
|
|
123
|
-
options: this._focusTrapOptions
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Handles the close button (via data-event bound in appendCloseButton)
|
|
128
|
-
private onCloseClick(): void {
|
|
129
|
-
this.destroy();
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
private animateIn(wrapper: HTMLElement): void {
|
|
133
|
-
requestAnimationFrame(() => {
|
|
134
|
-
this._overlay?.classList.add('show');
|
|
135
|
-
wrapper.classList.add('show');
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import {SecurityHelper} from "../../core/base-classes/base-component/helpers/security.helper.js";
|
|
2
|
-
|
|
3
|
-
export type NotifyOptions = {
|
|
4
|
-
type?: 'info' | 'success' | 'error';
|
|
5
|
-
position?: 'top' | 'bottom';
|
|
6
|
-
duration?: number;
|
|
7
|
-
actionText?: string;
|
|
8
|
-
onAction?: () => void;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
type SnackbarItem = {
|
|
12
|
-
message: string;
|
|
13
|
-
options: NotifyOptions;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const queue: SnackbarItem[] = [];
|
|
17
|
-
let isDisplaying = false;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* ```typescript
|
|
21
|
-
type NotifyOptions = {
|
|
22
|
-
type?: 'info' | 'success' | 'error';
|
|
23
|
-
position?: 'top' | 'bottom';
|
|
24
|
-
duration?: number;
|
|
25
|
-
actionText?: string;
|
|
26
|
-
onAction?: () => void;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
type SnackbarItem = {
|
|
30
|
-
message: string;
|
|
31
|
-
options: NotifyOptions;
|
|
32
|
-
};
|
|
33
|
-
```
|
|
34
|
-
*/
|
|
35
|
-
export function notify(message: string, options: NotifyOptions = {}): void {
|
|
36
|
-
queue.push({ message, options });
|
|
37
|
-
if (!isDisplaying) {
|
|
38
|
-
displayNext();
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function displayNext(): void {
|
|
43
|
-
if (queue.length === 0) {
|
|
44
|
-
isDisplaying = false;
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
isDisplaying = true;
|
|
49
|
-
let { message, options } = queue.shift()!;
|
|
50
|
-
let { type = 'info', position = 'bottom', duration = 3000, actionText, onAction } = options;
|
|
51
|
-
message = SecurityHelper.sanitizeTemplate(message);
|
|
52
|
-
actionText = SecurityHelper.sanitizeTemplate(actionText);
|
|
53
|
-
const snackbar = document.createElement('div');
|
|
54
|
-
snackbar.className = `app-snackbar app-snackbar--${type} app-snackbar--${position}`;
|
|
55
|
-
snackbar.innerHTML = `
|
|
56
|
-
<span>${message}</span>
|
|
57
|
-
${actionText ? `<button>${actionText}</button>` : ''}
|
|
58
|
-
`;
|
|
59
|
-
|
|
60
|
-
document.body.appendChild(snackbar);
|
|
61
|
-
|
|
62
|
-
const remove = () => {
|
|
63
|
-
snackbar.remove();
|
|
64
|
-
displayNext();
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
if (actionText && onAction) {
|
|
68
|
-
snackbar.querySelector('button')?.addEventListener('click', () => {
|
|
69
|
-
onAction();
|
|
70
|
-
remove();
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
setTimeout(remove, duration);
|
|
75
|
-
}
|