cyberia 3.1.3 → 3.2.9
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/.env.example +0 -2
- package/.github/workflows/engine-cyberia.cd.yml +10 -8
- package/.github/workflows/engine-cyberia.ci.yml +12 -29
- package/.github/workflows/ghpkg.ci.yml +4 -4
- package/.github/workflows/npmpkg.ci.yml +28 -11
- package/.github/workflows/publish.ci.yml +21 -2
- package/.github/workflows/pwa-microservices-template-page.cd.yml +4 -5
- package/.github/workflows/pwa-microservices-template-test.ci.yml +3 -3
- package/.github/workflows/release.cd.yml +14 -10
- package/CHANGELOG.md +783 -1
- package/CLI-HELP.md +95 -18
- package/Dockerfile +0 -2
- package/README.md +290 -220
- package/bin/build.js +24 -7
- package/bin/cyberia.js +2838 -252
- package/bin/deploy.js +747 -125
- package/bin/file.js +9 -0
- package/bin/index.js +2838 -252
- package/bin/vs.js +1 -1
- package/conf.js +99 -65
- package/deployment.yaml +18 -164
- package/hardhat/hardhat.config.js +13 -13
- package/hardhat/ignition/modules/ObjectLayerToken.js +1 -1
- package/hardhat/package-lock.json +2559 -5864
- package/hardhat/package.json +14 -23
- package/hardhat/scripts/deployObjectLayerToken.js +1 -1
- package/hardhat/test/ObjectLayerToken.js +4 -2
- package/hardhat/types/ethers-contracts/ObjectLayerToken.ts +690 -0
- package/hardhat/types/ethers-contracts/common.ts +92 -0
- package/hardhat/types/ethers-contracts/factories/ObjectLayerToken__factory.ts +1055 -0
- package/hardhat/types/ethers-contracts/factories/index.ts +4 -0
- package/hardhat/types/ethers-contracts/hardhat.d.ts +47 -0
- package/hardhat/types/ethers-contracts/index.ts +6 -0
- package/jsconfig.json +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +6 -5
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +6 -5
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +18 -164
- package/manifests/deployment/dd-cyberia-development/proxy.yaml +7 -79
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -6
- package/manifests/deployment/dd-test-development/deployment.yaml +112 -28
- package/manifests/deployment/dd-test-development/proxy.yaml +46 -1
- package/manifests/deployment/playwright/deployment.yaml +1 -1
- package/nodemon.json +1 -1
- package/package.json +39 -24
- package/proxy.yaml +7 -79
- package/scripts/k3s-node-setup.sh +2 -2
- package/scripts/nat-iptables.sh +103 -18
- package/scripts/rhel-grpc-setup.sh +56 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +58 -14
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +23 -14
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +5 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +148 -20
- package/src/api/core/core.controller.js +10 -10
- package/src/api/core/core.service.js +10 -10
- package/src/api/crypto/crypto.controller.js +8 -8
- package/src/api/crypto/crypto.service.js +8 -8
- package/src/api/cyberia-action/cyberia-action.controller.js +74 -0
- package/src/api/cyberia-action/cyberia-action.model.js +87 -0
- package/src/api/cyberia-action/cyberia-action.router.js +27 -0
- package/src/api/cyberia-action/cyberia-action.service.js +42 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +93 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +36 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +29 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +51 -0
- package/src/api/cyberia-entity/cyberia-entity.controller.js +74 -0
- package/src/api/cyberia-entity/cyberia-entity.model.js +24 -0
- package/src/api/cyberia-entity/cyberia-entity.router.js +27 -0
- package/src/api/cyberia-entity/cyberia-entity.service.js +42 -0
- package/src/api/cyberia-instance/cyberia-fallback-world.js +178 -0
- package/src/api/cyberia-instance/cyberia-instance.controller.js +92 -0
- package/src/api/cyberia-instance/cyberia-instance.model.js +87 -0
- package/src/api/cyberia-instance/cyberia-instance.router.js +63 -0
- package/src/api/cyberia-instance/cyberia-instance.service.js +156 -0
- package/src/api/cyberia-instance/cyberia-portal-connector.js +260 -0
- package/src/api/cyberia-instance/cyberia-world-generator.js +505 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +74 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +574 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +231 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +27 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +46 -0
- package/src/api/cyberia-map/cyberia-map.controller.js +79 -0
- package/src/api/cyberia-map/cyberia-map.model.js +30 -0
- package/src/api/cyberia-map/cyberia-map.router.js +40 -0
- package/src/api/cyberia-map/cyberia-map.service.js +74 -0
- package/src/api/cyberia-quest/cyberia-quest.controller.js +74 -0
- package/src/api/cyberia-quest/cyberia-quest.model.js +67 -0
- package/src/api/cyberia-quest/cyberia-quest.router.js +27 -0
- package/src/api/cyberia-quest/cyberia-quest.service.js +42 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +74 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +49 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +27 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +42 -0
- package/src/api/default/default.controller.js +10 -10
- package/src/api/default/default.service.js +10 -10
- package/src/api/document/document.controller.js +12 -12
- package/src/api/document/document.model.js +10 -16
- package/src/api/file/file.controller.js +8 -8
- package/src/api/file/file.model.js +10 -10
- package/src/api/file/file.ref.json +18 -0
- package/src/api/file/file.service.js +36 -36
- package/src/api/instance/instance.controller.js +10 -10
- package/src/api/instance/instance.model.js +4 -10
- package/src/api/instance/instance.service.js +10 -10
- package/src/api/ipfs/ipfs.controller.js +15 -36
- package/src/api/ipfs/ipfs.model.js +47 -47
- package/src/api/ipfs/ipfs.router.js +8 -13
- package/src/api/ipfs/ipfs.service.js +67 -129
- package/src/api/object-layer/object-layer.controller.js +12 -12
- package/src/api/object-layer/object-layer.model.js +4 -17
- package/src/api/object-layer/object-layer.router.js +30 -0
- package/src/api/object-layer/object-layer.service.js +126 -43
- package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +10 -10
- package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +6 -16
- package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +18 -14
- package/src/api/test/test.controller.js +8 -8
- package/src/api/test/test.service.js +8 -8
- package/src/api/user/guest.service.js +99 -0
- package/src/api/user/user.controller.js +6 -6
- package/src/api/user/user.model.js +8 -13
- package/src/api/user/user.service.js +11 -27
- package/src/cli/cluster.js +68 -21
- package/src/cli/db.js +753 -825
- package/src/cli/deploy.js +215 -125
- package/src/cli/env.js +29 -0
- package/src/cli/fs.js +82 -8
- package/src/cli/image.js +43 -1
- package/src/cli/index.js +74 -3
- package/src/cli/kubectl.js +211 -0
- package/src/cli/release.js +340 -0
- package/src/cli/repository.js +475 -74
- package/src/cli/run.js +582 -43
- package/src/cli/secrets.js +73 -0
- package/src/cli/ssh.js +1 -1
- package/src/cli/static.js +43 -115
- package/src/cli/test.js +3 -3
- package/src/client/Cryptokoyn.index.js +18 -22
- package/src/client/CyberiaPortal.index.js +19 -24
- package/src/client/Default.index.js +21 -34
- package/src/client/Itemledger.index.js +20 -27
- package/src/client/Underpost.index.js +19 -24
- package/src/client/components/core/404.js +4 -4
- package/src/client/components/core/500.js +4 -4
- package/src/client/components/core/Account.js +73 -60
- package/src/client/components/core/AgGrid.js +23 -33
- package/src/client/components/core/Alert.js +12 -13
- package/src/client/components/core/AppStore.js +69 -0
- package/src/client/components/core/Auth.js +35 -37
- package/src/client/components/core/Badge.js +7 -13
- package/src/client/components/core/BtnIcon.js +15 -17
- package/src/client/components/core/CalendarCore.js +43 -64
- package/src/client/components/core/Chat.js +13 -15
- package/src/client/components/core/ClientEvents.js +87 -0
- package/src/client/components/core/ColorPaletteElement.js +309 -0
- package/src/client/components/core/Content.js +17 -14
- package/src/client/components/core/Css.js +15 -71
- package/src/client/components/core/CssCore.js +12 -16
- package/src/client/components/core/D3Chart.js +4 -4
- package/src/client/components/core/Docs.js +64 -91
- package/src/client/components/core/DropDown.js +194 -96
- package/src/client/components/core/EventBus.js +92 -0
- package/src/client/components/core/EventsUI.js +14 -17
- package/src/client/components/core/FileExplorer.js +96 -228
- package/src/client/components/core/FullScreen.js +47 -75
- package/src/client/components/core/Input.js +24 -69
- package/src/client/components/core/Keyboard.js +26 -19
- package/src/client/components/core/KeyboardAvoidance.js +145 -0
- package/src/client/components/core/LoadingAnimation.js +25 -31
- package/src/client/components/core/LogIn.js +43 -43
- package/src/client/components/core/LogOut.js +25 -16
- package/src/client/components/core/Modal.js +462 -179
- package/src/client/components/core/NotificationManager.js +14 -18
- package/src/client/components/core/Panel.js +54 -51
- package/src/client/components/core/PanelForm.js +44 -144
- package/src/client/components/core/Polyhedron.js +110 -214
- package/src/client/components/core/PublicProfile.js +39 -32
- package/src/client/components/core/Recover.js +48 -44
- package/src/client/components/core/Responsive.js +88 -32
- package/src/client/components/core/RichText.js +9 -18
- package/src/client/components/core/Router.js +24 -3
- package/src/client/components/core/SearchBox.js +37 -37
- package/src/client/components/core/SignUp.js +39 -30
- package/src/client/components/core/SocketIo.js +112 -30
- package/src/client/components/core/SocketIoHandler.js +75 -0
- package/src/client/components/core/Stream.js +143 -95
- package/src/client/components/core/ToggleSwitch.js +8 -20
- package/src/client/components/core/ToolTip.js +5 -17
- package/src/client/components/core/Translate.js +56 -59
- package/src/client/components/core/Validator.js +26 -16
- package/src/client/components/core/Wallet.js +15 -26
- package/src/client/components/core/Webhook.js +40 -7
- package/src/client/components/core/Worker.js +163 -27
- package/src/client/components/core/windowGetDimensions.js +7 -7
- package/src/client/components/cryptokoyn/{MenuCryptokoyn.js → AppShellCryptokoyn.js} +59 -59
- package/src/client/components/cryptokoyn/AppStoreCryptokoyn.js +5 -0
- package/src/client/components/cryptokoyn/CssCryptokoyn.js +15 -15
- package/src/client/components/cryptokoyn/LogInCryptokoyn.js +9 -7
- package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +8 -6
- package/src/client/components/cryptokoyn/RouterCryptokoyn.js +37 -0
- package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +4 -4
- package/src/client/components/cryptokoyn/SignUpCryptokoyn.js +6 -4
- package/src/client/components/cryptokoyn/SocketIoCryptokoyn.js +3 -51
- package/src/client/components/cyberia/InstanceEngineCyberia.js +781 -0
- package/src/client/components/cyberia/MapEngineCyberia.js +1836 -2
- package/src/client/components/cyberia/ObjectLayerEngine.js +19 -0
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +1220 -99
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +252 -316
- package/src/client/components/cyberia-portal/{MenuCyberiaPortal.js → AppShellCyberiaPortal.js} +136 -103
- package/src/client/components/cyberia-portal/AppStoreCyberiaPortal.js +5 -0
- package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +462 -32
- package/src/client/components/cyberia-portal/CssCyberiaPortal.js +15 -15
- package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +9 -7
- package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +8 -6
- package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +4 -4
- package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +60 -0
- package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +4 -4
- package/src/client/components/cyberia-portal/SignUpCyberiaPortal.js +6 -4
- package/src/client/components/cyberia-portal/SocketIoCyberiaPortal.js +3 -49
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +8 -4
- package/src/client/components/default/{MenuDefault.js → AppShellDefault.js} +91 -91
- package/src/client/components/default/AppStoreDefault.js +5 -0
- package/src/client/components/default/CssDefault.js +12 -12
- package/src/client/components/default/LogInDefault.js +9 -7
- package/src/client/components/default/LogOutDefault.js +8 -6
- package/src/client/components/default/RouterDefault.js +47 -0
- package/src/client/components/default/SettingsDefault.js +4 -4
- package/src/client/components/default/SignUpDefault.js +6 -4
- package/src/client/components/default/SocketIoDefault.js +3 -51
- package/src/client/components/default/TranslateDefault.js +3 -3
- package/src/client/components/itemledger/{MenuItemledger.js → AppShellItemledger.js} +59 -59
- package/src/client/components/itemledger/AppStoreItemledger.js +5 -0
- package/src/client/components/itemledger/CssItemledger.js +15 -15
- package/src/client/components/itemledger/LogInItemledger.js +9 -7
- package/src/client/components/itemledger/LogOutItemledger.js +8 -6
- package/src/client/components/itemledger/RouterItemledger.js +38 -0
- package/src/client/components/itemledger/SettingsItemledger.js +4 -4
- package/src/client/components/itemledger/SignUpItemledger.js +6 -4
- package/src/client/components/itemledger/SocketIoItemledger.js +3 -51
- package/src/client/components/itemledger/TranslateItemledger.js +3 -3
- package/src/client/components/underpost/{MenuUnderpost.js → AppShellUnderpost.js} +92 -92
- package/src/client/components/underpost/AppStoreUnderpost.js +5 -0
- package/src/client/components/underpost/CssUnderpost.js +14 -14
- package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +4 -4
- package/src/client/components/underpost/DocumentSearchProvider.js +1 -1
- package/src/client/components/underpost/LabGalleryUnderpost.js +12 -15
- package/src/client/components/underpost/LogInUnderpost.js +9 -7
- package/src/client/components/underpost/LogOutUnderpost.js +8 -6
- package/src/client/components/underpost/RouterUnderpost.js +45 -0
- package/src/client/components/underpost/SettingsUnderpost.js +4 -4
- package/src/client/components/underpost/SignUpUnderpost.js +6 -4
- package/src/client/components/underpost/SocketIoUnderpost.js +3 -51
- package/src/client/components/underpost/TranslateUnderpost.js +4 -4
- package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +235 -0
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +443 -0
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +417 -0
- package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +313 -0
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +260 -0
- package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +241 -0
- package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +300 -0
- package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +279 -0
- package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +206 -0
- package/src/client/public/cyberia-docs/ROADMAP.md +240 -0
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +732 -0
- package/src/client/services/atlas-sprite-sheet/atlas-sprite-sheet.service.js +14 -20
- package/src/client/services/core/core.service.js +35 -55
- package/src/client/services/crypto/crypto.service.js +8 -13
- package/src/client/services/cyberia-action/cyberia-action.service.js +99 -0
- package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +99 -0
- package/src/client/services/cyberia-entity/cyberia-entity.management.js +57 -0
- package/src/client/services/cyberia-entity/cyberia-entity.service.js +99 -0
- package/src/client/services/cyberia-instance/cyberia-instance.management.js +194 -0
- package/src/client/services/cyberia-instance/cyberia-instance.service.js +116 -0
- package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +99 -0
- package/src/client/services/cyberia-map/cyberia-map.management.js +193 -0
- package/src/client/services/cyberia-map/cyberia-map.service.js +120 -0
- package/src/client/services/cyberia-quest/cyberia-quest.service.js +99 -0
- package/src/client/services/cyberia-quest-progress/cyberia-quest-progress.service.js +99 -0
- package/src/client/services/default/default.management.js +159 -267
- package/src/client/services/default/default.service.js +10 -16
- package/src/client/services/document/document.service.js +14 -19
- package/src/client/services/file/file.service.js +8 -13
- package/src/client/services/instance/instance.management.js +6 -6
- package/src/client/services/instance/instance.service.js +10 -15
- package/src/client/services/ipfs/ipfs.service.js +14 -40
- package/src/client/services/object-layer/object-layer.management.js +14 -14
- package/src/client/services/object-layer/object-layer.service.js +39 -24
- package/src/client/services/object-layer-render-frames/object-layer-render-frames.service.js +10 -16
- package/src/client/services/test/test.service.js +8 -13
- package/src/client/services/user/guest.service.js +86 -0
- package/src/client/services/user/user.management.js +6 -6
- package/src/client/services/user/user.service.js +14 -20
- package/src/client/ssr/body/404.js +3 -3
- package/src/client/ssr/body/500.js +3 -3
- package/src/client/ssr/body/CacheControl.js +5 -2
- package/src/client/ssr/body/DefaultSplashScreen.js +19 -12
- package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +13 -6
- package/src/client/ssr/head/PwaItemledger.js +197 -60
- package/src/client/ssr/mailer/DefaultRecoverEmail.js +19 -20
- package/src/client/ssr/mailer/DefaultVerifyEmail.js +15 -16
- package/src/client/ssr/offline/Maintenance.js +12 -11
- package/src/client/ssr/offline/NoNetworkConnection.js +3 -3
- package/src/client/ssr/pages/CyberiaServerMetrics.js +1 -1
- package/src/client/ssr/pages/Test.js +2 -2
- package/src/client/sw/core.sw.js +212 -0
- package/src/grpc/cyberia/grpc-server.js +642 -0
- package/src/index.js +24 -1
- package/src/runtime/cyberia-client/Dockerfile +80 -0
- package/src/runtime/cyberia-server/Dockerfile +37 -0
- package/src/runtime/express/Dockerfile +5 -1
- package/src/runtime/express/Express.js +18 -1
- package/src/runtime/lampp/Dockerfile +17 -5
- package/src/runtime/lampp/Lampp.js +27 -4
- package/src/runtime/wp/Dockerfile +62 -0
- package/src/runtime/wp/Wp.js +639 -0
- package/src/server/atlas-sprite-sheet-generator.js +4 -2
- package/src/server/auth.js +24 -1
- package/src/server/backup.js +37 -9
- package/src/server/client-build-docs.js +52 -46
- package/src/server/client-build.js +356 -82
- package/src/server/client-formatted.js +140 -57
- package/src/server/conf.js +29 -13
- package/src/server/cron.js +25 -23
- package/src/server/data-query.js +32 -20
- package/src/server/dns.js +24 -1
- package/src/server/ipfs-client.js +253 -89
- package/src/server/object-layer.js +150 -114
- package/src/server/peer.js +8 -0
- package/src/server/process.js +13 -27
- package/src/server/runtime.js +25 -1
- package/src/server/semantic-layer-generator-floor.js +319 -0
- package/src/server/semantic-layer-generator-resource.js +259 -0
- package/src/server/semantic-layer-generator-skin.js +1164 -0
- package/src/server/semantic-layer-generator.js +211 -542
- package/src/server/shape-generator.js +108 -0
- package/src/server/start.js +19 -5
- package/src/server/valkey.js +141 -235
- package/src/ws/IoInterface.js +1 -10
- package/src/ws/IoServer.js +14 -33
- package/src/ws/core/channels/core.ws.chat.js +65 -20
- package/src/ws/core/channels/core.ws.mailer.js +113 -32
- package/src/ws/core/channels/core.ws.stream.js +90 -31
- package/src/ws/core/core.ws.connection.js +12 -33
- package/src/ws/core/core.ws.emit.js +10 -26
- package/src/ws/core/core.ws.server.js +25 -58
- package/src/ws/default/channels/default.ws.main.js +53 -12
- package/src/ws/default/default.ws.connection.js +26 -13
- package/src/ws/default/default.ws.server.js +30 -12
- package/tsconfig.docs.json +15 -0
- package/typedoc.dd-cyberia.json +29 -0
- package/typedoc.json +29 -0
- package/WHITE-PAPER.md +0 -1540
- package/hardhat/README.md +0 -531
- package/hardhat/WHITE-PAPER.md +0 -1540
- package/jsdoc.dd-cyberia.json +0 -59
- package/jsdoc.json +0 -59
- package/src/api/object-layer/README.md +0 -347
- package/src/client/components/core/ColorPalette.js +0 -5267
- package/src/client/components/core/JoyStick.js +0 -80
- package/src/client/components/cryptokoyn/CommonCryptokoyn.js +0 -29
- package/src/client/components/cryptokoyn/ElementsCryptokoyn.js +0 -38
- package/src/client/components/cryptokoyn/RoutesCryptokoyn.js +0 -39
- package/src/client/components/cyberia-portal/ElementsCyberiaPortal.js +0 -38
- package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +0 -58
- package/src/client/components/cyberia-portal/ServerCyberiaPortal.js +0 -136
- package/src/client/components/default/ElementsDefault.js +0 -38
- package/src/client/components/default/RoutesDefault.js +0 -49
- package/src/client/components/itemledger/CommonItemledger.js +0 -29
- package/src/client/components/itemledger/ElementsItemledger.js +0 -38
- package/src/client/components/itemledger/RoutesItemledger.js +0 -40
- package/src/client/components/underpost/CommonUnderpost.js +0 -29
- package/src/client/components/underpost/ElementsUnderpost.js +0 -38
- package/src/client/components/underpost/RoutesUnderpost.js +0 -47
- package/src/client/sw/default.sw.js +0 -127
- package/src/client/sw/template.sw.js +0 -84
- package/src/ws/core/management/core.ws.chat.js +0 -8
- package/src/ws/core/management/core.ws.mailer.js +0 -16
- package/src/ws/core/management/core.ws.stream.js +0 -8
- package/src/ws/default/management/default.ws.main.js +0 -8
|
@@ -39,21 +39,120 @@ import { SearchBox } from './SearchBox.js';
|
|
|
39
39
|
|
|
40
40
|
const logger = loggerFactory(import.meta, { trace: true });
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
/**
|
|
43
|
+
* @typedef {object} ModalBarButton
|
|
44
|
+
* @property {string} [label] - Button label HTML
|
|
45
|
+
* @property {boolean} [disabled] - Whether the button is hidden/disabled
|
|
46
|
+
* @property {Function} [onClick] - Optional click handler override
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @typedef {object} ModalBarConfig
|
|
51
|
+
* @property {{ minimize: ModalBarButton, restore: ModalBarButton, maximize: ModalBarButton, close: ModalBarButton, menu: ModalBarButton }} buttons
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @typedef {object} ModalRenderOptions
|
|
56
|
+
* @property {string} [id=''] - Modal element id/class name. Auto-generated if omitted.
|
|
57
|
+
* @property {ModalBarConfig} [barConfig={}] - Bar button configuration.
|
|
58
|
+
* @property {string} [title=''] - Modal title HTML.
|
|
59
|
+
* @property {string|Function} [html=''] - Modal body HTML or async factory.
|
|
60
|
+
* @property {string} [handleType='bar'] - Drag handle type ('bar' or default full).
|
|
61
|
+
* @property {string} [mode=''] - Layout mode: 'view', 'slide-menu', 'slide-menu-right', 'slide-menu-left', 'dropNotification'.
|
|
62
|
+
* @property {object} [RouterInstance={}] - Router instance for route-aware modals.
|
|
63
|
+
* @property {string[]} [disableTools=[]] - Tool ids to hide ('app-icon', 'text-box', 'profile', 'center', 'lang', 'theme', 'navigator').
|
|
64
|
+
* @property {boolean} [observer=false] - Attach a ResizeObserver to the modal element.
|
|
65
|
+
* @property {boolean} [disableBoxShadow=false] - Remove box shadow from the modal.
|
|
66
|
+
* @property {boolean} [dragDisabled=false] - Disable dragging.
|
|
67
|
+
* @property {boolean} [maximize=false] - Immediately maximize the modal after render.
|
|
68
|
+
* @property {boolean} [disableCenter=false] - Skip auto-centering.
|
|
69
|
+
* @property {object} [style={}] - Inline style overrides applied via renderStyleTag.
|
|
70
|
+
* @property {string} [class=''] - Extra CSS class(es) on the modal wrapper.
|
|
71
|
+
* @property {string} [titleClass=''] - Class for the title element.
|
|
72
|
+
* @property {string} [btnBarModalClass=''] - Class override for the button bar container.
|
|
73
|
+
* @property {string} [btnContainerClass=''] - Class for each bar button.
|
|
74
|
+
* @property {string} [btnIconContainerClass=''] - Class for each bar button inner icon div.
|
|
75
|
+
* @property {string} [barClass=''] - Class for the top/bottom bar flex row.
|
|
76
|
+
* @property {string} [barMode=''] - Bar layout variant ('top-bottom-bar').
|
|
77
|
+
* @property {string} [renderType=''] - Insertion strategy ('prepend' or default append).
|
|
78
|
+
* @property {string} [selector='body'] - Parent selector for insertion.
|
|
79
|
+
* @property {string} [slideMenu=''] - Id of the slide-menu modal this view should attach to.
|
|
80
|
+
* @property {string} [route=''] - URL path segment for view-mode route tracking.
|
|
81
|
+
* @property {string} [status=''] - Status icon descriptor rendered in the bar.
|
|
82
|
+
* @property {boolean} [zIndexSync=false] - Enable z-index management for stacked view modals.
|
|
83
|
+
* @property {boolean} [query=false] - Snapshot the current query string into modal data.
|
|
84
|
+
* @property {string[]} [homeModals=[]] - Modal ids that belong to the home screen (not closed on home nav).
|
|
85
|
+
* @property {Function} [titleRender] - Function returning title HTML (takes priority over title string).
|
|
86
|
+
* @property {Function} [htmlMainBody] - Factory for main-body modal html (slide-menu mode).
|
|
87
|
+
* @property {Function} [slideMenuTopBarBannerFix] - Async factory for top-bar banner content.
|
|
88
|
+
* @property {number} [minSearchQueryLength=1] - Minimum search query length.
|
|
89
|
+
* @property {Function} [onCollapseMenu] - Callback when slide menu collapses.
|
|
90
|
+
* @property {Function} [onExtendMenu] - Callback when slide menu extends.
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @typedef {object} ModalDataEntry
|
|
95
|
+
* @property {ModalRenderOptions} options - Original render options.
|
|
96
|
+
* @property {Object.<string, Function>} onCloseListener - Close event listeners keyed by id.
|
|
97
|
+
* @property {Object.<string, Function>} onMenuListener - Menu button event listeners.
|
|
98
|
+
* @property {Object.<string, Function>} onCollapseMenuListener - Collapse menu listeners.
|
|
99
|
+
* @property {Object.<string, Function>} onExtendMenuListener - Extend menu listeners.
|
|
100
|
+
* @property {Object.<string, Function>} onDragEndListener - Drag-end listeners.
|
|
101
|
+
* @property {Object.<string, Function>} onObserverListener - ResizeObserver listeners.
|
|
102
|
+
* @property {Object.<string, Function>} onClickListener - Click listeners.
|
|
103
|
+
* @property {Object.<string, Function>} onExpandUiListener - UI expand/collapse listeners.
|
|
104
|
+
* @property {Object.<string, Function>} onBarUiOpen - Bar UI open listeners.
|
|
105
|
+
* @property {Object.<string, Function>} onBarUiClose - Bar UI close listeners.
|
|
106
|
+
* @property {Object.<string, Function>} onReloadModalListener - Reload listeners.
|
|
107
|
+
* @property {Object.<string, Function>} onHome - Home navigation listeners.
|
|
108
|
+
* @property {string[]} homeModals - Home modal ids.
|
|
109
|
+
* @property {string} [query] - Snapshotted query string.
|
|
110
|
+
* @property {Function} getTop - Returns computed top offset.
|
|
111
|
+
* @property {Function} getHeight - Returns computed modal height.
|
|
112
|
+
* @property {Function} getMenuLeftStyle - Returns slide menu left CSS value.
|
|
113
|
+
* @property {Function} center - Centers the modal in the viewport.
|
|
114
|
+
* @property {object} [slideMenu] - Active slide-menu link data.
|
|
115
|
+
* @property {ResizeObserver} [observer] - Attached ResizeObserver.
|
|
116
|
+
* @property {Function} [observerCallBack] - ResizeObserver callback.
|
|
117
|
+
* @property {Function} [setDragInstance] - Updates drag options and re-creates the Draggable.
|
|
118
|
+
* @property {object} [dragInstance] - Active Draggable instance.
|
|
119
|
+
* @property {object} [dragOptions] - Current drag configuration.
|
|
120
|
+
*/
|
|
121
|
+
|
|
122
|
+
class Modal {
|
|
123
|
+
/** @type {Object.<string, ModalDataEntry>} */
|
|
124
|
+
static Data = {};
|
|
44
125
|
|
|
45
|
-
|
|
126
|
+
/**
|
|
127
|
+
* Create or reload a modal. When the modal already exists in the DOM the
|
|
128
|
+
* existing instance is reloaded via its onReloadModalListener callbacks.
|
|
129
|
+
* @param {ModalRenderOptions} options
|
|
130
|
+
* @returns {Promise<ModalDataEntry & { id: string }>}
|
|
131
|
+
*/
|
|
132
|
+
static async instance(
|
|
46
133
|
options = {
|
|
47
134
|
id: '',
|
|
48
135
|
barConfig: {},
|
|
49
136
|
title: '',
|
|
50
137
|
html: '',
|
|
51
138
|
handleType: 'bar',
|
|
52
|
-
mode: ''
|
|
139
|
+
mode: '',
|
|
53
140
|
RouterInstance: {},
|
|
54
141
|
disableTools: [],
|
|
55
142
|
observer: false,
|
|
56
143
|
disableBoxShadow: false,
|
|
144
|
+
dragDisabled: false,
|
|
145
|
+
maximize: false,
|
|
146
|
+
disableCenter: false,
|
|
147
|
+
style: {},
|
|
148
|
+
class: '',
|
|
149
|
+
titleClass: '',
|
|
150
|
+
barMode: '',
|
|
151
|
+
route: '',
|
|
152
|
+
slideMenu: '',
|
|
153
|
+
zIndexSync: false,
|
|
154
|
+
query: false,
|
|
155
|
+
homeModals: [],
|
|
57
156
|
},
|
|
58
157
|
) {
|
|
59
158
|
const originHeightBottomBar = 50;
|
|
@@ -145,11 +244,14 @@ const Modal = {
|
|
|
145
244
|
});
|
|
146
245
|
}
|
|
147
246
|
|
|
148
|
-
Responsive.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
247
|
+
Responsive.onChanged(
|
|
248
|
+
() => {
|
|
249
|
+
if (!this.Data[idModal]) return Responsive.offChanged(`view-${idModal}`);
|
|
250
|
+
if (this.Data[idModal].slideMenu) s(`.${idModal}`).style.height = `${this.Data[idModal].getHeight()}px`;
|
|
251
|
+
},
|
|
252
|
+
{ key: `view-${idModal}` },
|
|
253
|
+
);
|
|
254
|
+
Responsive.triggerChanged(`view-${idModal}`);
|
|
153
255
|
|
|
154
256
|
// Handle view mode modal route
|
|
155
257
|
if (options.route) {
|
|
@@ -251,23 +353,30 @@ const Modal = {
|
|
|
251
353
|
// barConfig.buttons.menu.disabled = true;
|
|
252
354
|
// barConfig.buttons.close.disabled = true;
|
|
253
355
|
options.btnBarModalClass = 'hide';
|
|
254
|
-
Responsive.
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
this.Data[_idModal].slideMenu.
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
if (
|
|
265
|
-
if (
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
356
|
+
Responsive.onChanged(
|
|
357
|
+
() => {
|
|
358
|
+
for (const _idModal of Object.keys(this.Data)) {
|
|
359
|
+
if (this.Data[_idModal].slideMenu && this.Data[_idModal].slideMenu.id === idModal)
|
|
360
|
+
this.Data[_idModal].slideMenu.callBack();
|
|
361
|
+
}
|
|
362
|
+
s(`.${idModal}`).style.height = `${Modal.Data[idModal].getHeight()}px`;
|
|
363
|
+
s(`.${idModal}`).style.left = Modal.Data[idModal].getMenuLeftStyle({
|
|
364
|
+
open: s(`.btn-bar-center-icon-menu`).classList.contains('hide') ? true : false,
|
|
365
|
+
});
|
|
366
|
+
if (s(`.main-body-top`)) {
|
|
367
|
+
if (Modal.mobileModal()) {
|
|
368
|
+
if (
|
|
369
|
+
s(`.btn-menu-${idModal}`).classList.contains('hide') &&
|
|
370
|
+
collapseSlideMenuWidth !== slideMenuWidth
|
|
371
|
+
)
|
|
372
|
+
s(`.main-body-top`).classList.remove('hide');
|
|
373
|
+
if (s(`.btn-close-${idModal}`).classList.contains('hide'))
|
|
374
|
+
s(`.main-body-top`).classList.add('hide');
|
|
375
|
+
} else if (!s(`.main-body-top`).classList.contains('hide')) s(`.main-body-top`).classList.add('hide');
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
{ key: `slide-menu-${idModal}` },
|
|
379
|
+
);
|
|
271
380
|
barConfig.buttons.menu.onClick = () => {
|
|
272
381
|
Modal.Data[idModal][options.mode].width = slideMenuWidth;
|
|
273
382
|
s(`.btn-menu-${idModal}`).classList.add('hide');
|
|
@@ -290,7 +399,7 @@ const Modal = {
|
|
|
290
399
|
} else {
|
|
291
400
|
s(`.${idModal}`).style.left = `0px`;
|
|
292
401
|
}
|
|
293
|
-
Responsive.
|
|
402
|
+
Responsive.triggerChanged(`slide-menu-${idModal}`);
|
|
294
403
|
};
|
|
295
404
|
barConfig.buttons.close.onClick = () => {
|
|
296
405
|
Modal.Data[idModal][options.mode].width = 0;
|
|
@@ -313,7 +422,7 @@ const Modal = {
|
|
|
313
422
|
} else {
|
|
314
423
|
s(`.${idModal}`).style.left = `-${originSlideMenuWidth}px`;
|
|
315
424
|
}
|
|
316
|
-
Responsive.
|
|
425
|
+
Responsive.triggerChanged(`slide-menu-${idModal}`);
|
|
317
426
|
};
|
|
318
427
|
transition += `, width 0.3s`;
|
|
319
428
|
|
|
@@ -421,15 +530,17 @@ const Modal = {
|
|
|
421
530
|
for (const event of Object.keys(Modal.Data[idModal].onBarUiOpen))
|
|
422
531
|
Modal.Data[idModal].onBarUiOpen[event]();
|
|
423
532
|
}
|
|
424
|
-
Responsive.
|
|
533
|
+
Responsive.triggerChanged(`slide-menu-modal-menu`);
|
|
425
534
|
Object.keys(this.Data).map((_idModal) => {
|
|
426
535
|
if (this.Data[_idModal].slideMenu) {
|
|
427
536
|
if (s(`.btn-maximize-${_idModal}`)) s(`.btn-maximize-${_idModal}`).click();
|
|
428
537
|
}
|
|
429
538
|
});
|
|
430
|
-
Responsive.
|
|
431
|
-
if (Responsive.
|
|
432
|
-
|
|
539
|
+
Responsive.triggerChanged(`view-${'main-body'}`);
|
|
540
|
+
if (Responsive.hasChangedListener(`view-${'bottom-bar'}`))
|
|
541
|
+
Responsive.triggerChanged(`view-${'bottom-bar'}`);
|
|
542
|
+
if (Responsive.hasChangedListener(`view-${'main-body-top'}`))
|
|
543
|
+
Responsive.triggerChanged(`view-${'main-body-top'}`);
|
|
433
544
|
for (const keyEvent of Object.keys(this.Data[idModal].onExpandUiListener)) {
|
|
434
545
|
this.Data[idModal].onExpandUiListener[keyEvent](
|
|
435
546
|
!s(`.main-body-btn-ui-open`).classList.contains('hide'),
|
|
@@ -447,14 +558,14 @@ const Modal = {
|
|
|
447
558
|
class="fl top-bar ${options.barClass ? options.barClass : ''}"
|
|
448
559
|
style="height: ${originHeightTopBar}px;"
|
|
449
560
|
>
|
|
450
|
-
${await BtnIcon.
|
|
561
|
+
${await BtnIcon.instance({
|
|
451
562
|
style: `height: 100%`,
|
|
452
563
|
class: 'in fll main-btn-menu action-bar-box action-btn-close hide',
|
|
453
564
|
label: html` <div class="${contentIconClass} action-btn-close-render">
|
|
454
565
|
<i class="fa-solid fa-xmark"></i>
|
|
455
566
|
</div>`,
|
|
456
567
|
})}
|
|
457
|
-
${await BtnIcon.
|
|
568
|
+
${await BtnIcon.instance({
|
|
458
569
|
style: `height: 100%`,
|
|
459
570
|
class: `in fll main-btn-menu action-bar-box action-btn-app-icon ${
|
|
460
571
|
options?.disableTools?.includes('app-icon') ? 'hide' : ''
|
|
@@ -466,10 +577,12 @@ const Modal = {
|
|
|
466
577
|
? 'hide'
|
|
467
578
|
: ''}"
|
|
468
579
|
>
|
|
469
|
-
${await Input.
|
|
580
|
+
${await Input.instance({
|
|
470
581
|
id: inputSearchBoxId,
|
|
471
582
|
autocomplete: 'off',
|
|
472
|
-
placeholder: Modal.mobileModal()
|
|
583
|
+
placeholder: Modal.mobileModal()
|
|
584
|
+
? Translate.instance('search', '.top-bar-search-box')
|
|
585
|
+
: undefined, // html`<i class="fa-solid fa-magnifying-glass"></i> ${Translate.instance('search')}`,
|
|
473
586
|
placeholderIcon: html`<div
|
|
474
587
|
class="in fll"
|
|
475
588
|
style="width: ${originHeightTopBar}px; height: ${originHeightTopBar}px;"
|
|
@@ -480,19 +593,19 @@ const Modal = {
|
|
|
480
593
|
class="inl wfm key-shortcut-container-info"
|
|
481
594
|
style="${renderCssAttr({ style: { top: '10px', left: '60px' } })}"
|
|
482
595
|
>
|
|
483
|
-
${await Badge.
|
|
596
|
+
${await Badge.instance({
|
|
484
597
|
id: 'shortcut-key-info-search',
|
|
485
598
|
text: 'Shift',
|
|
486
599
|
classList: 'inl',
|
|
487
600
|
style: { 'z-index': 1 },
|
|
488
601
|
})}
|
|
489
|
-
${await Badge.
|
|
602
|
+
${await Badge.instance({
|
|
490
603
|
id: 'shortcut-key-info-search',
|
|
491
604
|
text: '+',
|
|
492
605
|
classList: 'inl',
|
|
493
606
|
style: { 'z-index': 1, background: 'none', color: '#5f5f5f' },
|
|
494
607
|
})}
|
|
495
|
-
${await Badge.
|
|
608
|
+
${await Badge.instance({
|
|
496
609
|
id: 'shortcut-key-info-search',
|
|
497
610
|
text: 'k',
|
|
498
611
|
classList: 'inl',
|
|
@@ -508,12 +621,12 @@ const Modal = {
|
|
|
508
621
|
<div
|
|
509
622
|
class="abs top-box-profile-container ${options?.disableTools?.includes('profile') ? 'hide' : ''}"
|
|
510
623
|
>
|
|
511
|
-
${await BtnIcon.
|
|
624
|
+
${await BtnIcon.instance({
|
|
512
625
|
style: `height: 100%`,
|
|
513
626
|
class: 'in fll session-in-log-in main-btn-menu action-bar-box action-btn-profile-log-in',
|
|
514
627
|
label: html` <div class="${contentIconClass} action-btn-profile-log-in-render"></div>`,
|
|
515
628
|
})}
|
|
516
|
-
${await BtnIcon.
|
|
629
|
+
${await BtnIcon.instance({
|
|
517
630
|
style: `height: 100%`,
|
|
518
631
|
class: 'in fll session-in-log-out main-btn-menu action-bar-box action-btn-profile-log-out',
|
|
519
632
|
label: html` <div class="${contentIconClass} action-btn-profile-log-out-render">
|
|
@@ -618,8 +731,8 @@ const Modal = {
|
|
|
618
731
|
if (results.length === 0) {
|
|
619
732
|
append(
|
|
620
733
|
`.html-${searchBoxHistoryId}`,
|
|
621
|
-
await BtnIcon.
|
|
622
|
-
label: html`<i class="fas fa-exclamation-circle"></i> ${Translate.
|
|
734
|
+
await BtnIcon.instance({
|
|
735
|
+
label: html`<i class="fas fa-exclamation-circle"></i> ${Translate.instance('no-result-found')}`,
|
|
623
736
|
class: `wfa`,
|
|
624
737
|
style: renderCssAttr({
|
|
625
738
|
style: {
|
|
@@ -784,7 +897,7 @@ const Modal = {
|
|
|
784
897
|
barConfig.buttons.menu.disabled = true;
|
|
785
898
|
barConfig.buttons.close.disabled = false;
|
|
786
899
|
|
|
787
|
-
await Modal.
|
|
900
|
+
await Modal.instance({
|
|
788
901
|
id: searchBoxHistoryId,
|
|
789
902
|
barConfig,
|
|
790
903
|
title: html`<div
|
|
@@ -794,13 +907,13 @@ const Modal = {
|
|
|
794
907
|
<div class="search-box-recent-title">
|
|
795
908
|
${renderViewTitle({
|
|
796
909
|
icon: html`<i class="fas fa-history mini-title"></i>`,
|
|
797
|
-
text: Translate.
|
|
910
|
+
text: Translate.instance('recent'),
|
|
798
911
|
})}
|
|
799
912
|
</div>
|
|
800
913
|
<div class="search-box-result-title hide">
|
|
801
914
|
${renderViewTitle({
|
|
802
915
|
icon: html`<i class="far fa-list-alt mini-title"></i>`,
|
|
803
|
-
text: Translate.
|
|
916
|
+
text: Translate.instance('results'),
|
|
804
917
|
})}
|
|
805
918
|
</div>
|
|
806
919
|
</div>
|
|
@@ -865,7 +978,7 @@ const Modal = {
|
|
|
865
978
|
}
|
|
866
979
|
|
|
867
980
|
// Add clear all button to the bar area, before the close button
|
|
868
|
-
const clearAllBtnHtml = await BtnIcon.
|
|
981
|
+
const clearAllBtnHtml = await BtnIcon.instance({
|
|
869
982
|
class: `btn-search-history-clear-all btn-modal-default btn-modal-default-${searchBoxHistoryId}`,
|
|
870
983
|
label: html`<i class="fas fa-trash-alt"></i>`,
|
|
871
984
|
attrs: `title="Clear all recent items"`,
|
|
@@ -1032,7 +1145,7 @@ const Modal = {
|
|
|
1032
1145
|
barConfig.buttons.menu.disabled = true;
|
|
1033
1146
|
barConfig.buttons.close.disabled = true;
|
|
1034
1147
|
const id = 'main-body';
|
|
1035
|
-
await Modal.
|
|
1148
|
+
await Modal.instance({
|
|
1036
1149
|
id,
|
|
1037
1150
|
barConfig,
|
|
1038
1151
|
html: options.htmlMainBody ? options.htmlMainBody : () => html``,
|
|
@@ -1055,26 +1168,29 @@ const Modal = {
|
|
|
1055
1168
|
const maxWidthInputSearchBox = 450;
|
|
1056
1169
|
const paddingInputSearchBox = 5;
|
|
1057
1170
|
const paddingRightSearchBox = 50;
|
|
1058
|
-
Responsive.
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1171
|
+
Responsive.onChanged(
|
|
1172
|
+
() => {
|
|
1173
|
+
if (!this.Data[id] || !s(`.${id}`)) return Responsive.offChanged(`view-${id}`);
|
|
1174
|
+
const widthInputSearchBox =
|
|
1175
|
+
windowGetW() > maxWidthInputSearchBox ? maxWidthInputSearchBox : windowGetW();
|
|
1176
|
+
s(`.top-bar-search-box-container`).style.width = `${
|
|
1177
|
+
widthInputSearchBox - originHeightTopBar - paddingRightSearchBox - 1
|
|
1178
|
+
}px`;
|
|
1179
|
+
s(`.top-bar-search-box`).style.width = `${
|
|
1180
|
+
widthInputSearchBox -
|
|
1181
|
+
originHeightTopBar * 2 -
|
|
1182
|
+
paddingRightSearchBox -
|
|
1183
|
+
paddingInputSearchBox * 2 /*padding input*/ -
|
|
1184
|
+
10 /* right-margin */
|
|
1185
|
+
}px`;
|
|
1186
|
+
s(`.top-bar-search-box`).style.top = `${
|
|
1187
|
+
(originHeightTopBar - s(`.top-bar-search-box`).clientHeight) / 2
|
|
1188
|
+
}px`;
|
|
1189
|
+
if (this.Data[id].slideMenu) s(`.${id}`).style.height = `${Modal.Data[id].getHeight()}px`;
|
|
1190
|
+
},
|
|
1191
|
+
{ key: `view-${id}` },
|
|
1192
|
+
);
|
|
1193
|
+
Responsive.triggerChanged(`view-${id}`);
|
|
1078
1194
|
Keyboard.instanceMultiPressKey({
|
|
1079
1195
|
id: 'input-search-shortcut-k',
|
|
1080
1196
|
keys: [
|
|
@@ -1127,7 +1243,7 @@ const Modal = {
|
|
|
1127
1243
|
class="fl ${options.barClass ? options.barClass : ''}"
|
|
1128
1244
|
style="height: ${originHeightBottomBar}px;"
|
|
1129
1245
|
>
|
|
1130
|
-
${await BtnIcon.
|
|
1246
|
+
${await BtnIcon.instance({
|
|
1131
1247
|
style: `height: 100%`,
|
|
1132
1248
|
class: `in fl${
|
|
1133
1249
|
options.mode === 'slide-menu-right' ? 'r' : 'l'
|
|
@@ -1142,35 +1258,35 @@ const Modal = {
|
|
|
1142
1258
|
</div>
|
|
1143
1259
|
`,
|
|
1144
1260
|
})}
|
|
1145
|
-
${await BtnIcon.
|
|
1261
|
+
${await BtnIcon.instance({
|
|
1146
1262
|
style: `height: 100%`,
|
|
1147
1263
|
class: `in flr main-btn-menu action-bar-box action-btn-lang ${
|
|
1148
1264
|
options?.disableTools?.includes('lang') ? 'hide' : ''
|
|
1149
1265
|
}`,
|
|
1150
1266
|
label: html` <div class="${contentIconClass} action-btn-lang-render"></div>`,
|
|
1151
1267
|
})}
|
|
1152
|
-
${await BtnIcon.
|
|
1268
|
+
${await BtnIcon.instance({
|
|
1153
1269
|
style: `height: 100%`,
|
|
1154
1270
|
class: `in flr main-btn-menu action-bar-box action-btn-theme ${
|
|
1155
1271
|
options?.disableTools?.includes('theme') ? 'hide' : ''
|
|
1156
1272
|
}`,
|
|
1157
1273
|
label: html` <div class="${contentIconClass} action-btn-theme-render"></div>`,
|
|
1158
1274
|
})}
|
|
1159
|
-
${await BtnIcon.
|
|
1275
|
+
${await BtnIcon.instance({
|
|
1160
1276
|
style: `height: 100%`,
|
|
1161
1277
|
class: `in flr main-btn-menu action-bar-box action-btn-home ${
|
|
1162
1278
|
options?.disableTools?.includes('navigator') ? 'hide' : ''
|
|
1163
1279
|
}`,
|
|
1164
1280
|
label: html` <div class="${contentIconClass}"><i class="fas fa-home"></i></div>`,
|
|
1165
1281
|
})}
|
|
1166
|
-
${await BtnIcon.
|
|
1282
|
+
${await BtnIcon.instance({
|
|
1167
1283
|
style: `height: 100%`,
|
|
1168
1284
|
class: `in flr main-btn-menu action-bar-box action-btn-right ${
|
|
1169
1285
|
options?.disableTools?.includes('navigator') ? 'hide' : ''
|
|
1170
1286
|
}`,
|
|
1171
1287
|
label: html` <div class="${contentIconClass}"><i class="fas fa-chevron-right"></i></div>`,
|
|
1172
1288
|
})}
|
|
1173
|
-
${await BtnIcon.
|
|
1289
|
+
${await BtnIcon.instance({
|
|
1174
1290
|
style: `height: 100%`,
|
|
1175
1291
|
class: `in flr main-btn-menu action-bar-box action-btn-left ${
|
|
1176
1292
|
options?.disableTools?.includes('navigator') ? 'hide' : ''
|
|
@@ -1182,7 +1298,7 @@ const Modal = {
|
|
|
1182
1298
|
if (options.heightBottomBar === 0 && options.heightTopBar > 0) {
|
|
1183
1299
|
append(`.slide-menu-top-bar`, html` <div class="in ${id}">${await html()}</div>`);
|
|
1184
1300
|
} else {
|
|
1185
|
-
await Modal.
|
|
1301
|
+
await Modal.instance({
|
|
1186
1302
|
id,
|
|
1187
1303
|
barConfig,
|
|
1188
1304
|
html,
|
|
@@ -1201,13 +1317,16 @@ const Modal = {
|
|
|
1201
1317
|
// maximize: true,
|
|
1202
1318
|
barMode: options.barMode,
|
|
1203
1319
|
});
|
|
1204
|
-
Responsive.
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1320
|
+
Responsive.onChanged(
|
|
1321
|
+
() => {
|
|
1322
|
+
if (!this.Data[id] || !s(`.${id}`)) return Responsive.offChanged(`view-${id}`);
|
|
1323
|
+
// <div class="in fll right-offset-menu-bottom-bar" style="height: 100%"></div>
|
|
1324
|
+
// s(`.right-offset-menu-bottom-bar`).style.width = `${windowGetW() - slideMenuWidth}px`;
|
|
1325
|
+
s(`.${id}`).style.top = `${Modal.Data['modal-menu'].getTop()}px`;
|
|
1326
|
+
s(`.${id}`).style.width = `${windowGetW()}px`;
|
|
1327
|
+
},
|
|
1328
|
+
{ key: `view-${id}` },
|
|
1329
|
+
);
|
|
1211
1330
|
// Responsive.Event[`view-${id}`]();
|
|
1212
1331
|
}
|
|
1213
1332
|
EventsUI.onClick(`.action-btn-left`, (e) => {
|
|
@@ -1290,12 +1409,12 @@ const Modal = {
|
|
|
1290
1409
|
barConfig.buttons.restore.disabled = true;
|
|
1291
1410
|
barConfig.buttons.menu.disabled = true;
|
|
1292
1411
|
barConfig.buttons.close.disabled = false;
|
|
1293
|
-
await Modal.
|
|
1412
|
+
await Modal.instance({
|
|
1294
1413
|
id,
|
|
1295
1414
|
barConfig,
|
|
1296
1415
|
title: html`${renderViewTitle({
|
|
1297
1416
|
icon: html`<i class="fas fa-language mini-title"></i>`,
|
|
1298
|
-
text: Translate.
|
|
1417
|
+
text: Translate.instance('select lang'),
|
|
1299
1418
|
})}`,
|
|
1300
1419
|
html: async () => html`${await Translate.RenderSetting('action-drop-modal' + id)}`,
|
|
1301
1420
|
titleClass: 'mini-title',
|
|
@@ -1349,7 +1468,7 @@ const Modal = {
|
|
|
1349
1468
|
barConfig.buttons.menu.disabled = true;
|
|
1350
1469
|
barConfig.buttons.close.disabled = true;
|
|
1351
1470
|
const id = 'main-body-top';
|
|
1352
|
-
await Modal.
|
|
1471
|
+
await Modal.instance({
|
|
1353
1472
|
id,
|
|
1354
1473
|
barConfig,
|
|
1355
1474
|
html: () => html``,
|
|
@@ -1357,7 +1476,6 @@ const Modal = {
|
|
|
1357
1476
|
class: 'hide',
|
|
1358
1477
|
style: {
|
|
1359
1478
|
// overflow: 'hidden',
|
|
1360
|
-
background: 'none',
|
|
1361
1479
|
resize: 'none',
|
|
1362
1480
|
'min-width': `${minWidth}px`,
|
|
1363
1481
|
'z-index': 5,
|
|
@@ -1369,24 +1487,27 @@ const Modal = {
|
|
|
1369
1487
|
barMode: options.barMode,
|
|
1370
1488
|
});
|
|
1371
1489
|
|
|
1372
|
-
Responsive.
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
s(
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1490
|
+
Responsive.onChanged(
|
|
1491
|
+
() => {
|
|
1492
|
+
if (!this.Data[id] || !s(`.${id}`)) return Responsive.offChanged(`view-${id}`);
|
|
1493
|
+
s(`.${id}`).style.height =
|
|
1494
|
+
s(`.main-body-btn-ui-close`).classList.contains('hide') &&
|
|
1495
|
+
s(`.btn-restore-${id}`).style.display !== 'none'
|
|
1496
|
+
? `${windowGetH()}px`
|
|
1497
|
+
: `${Modal.Data[id].getHeight()}px`;
|
|
1498
|
+
|
|
1499
|
+
if (
|
|
1500
|
+
s(`.main-body-btn-ui-close`).classList.contains('hide') &&
|
|
1501
|
+
s(`.btn-restore-${id}`).style.display !== 'none'
|
|
1502
|
+
) {
|
|
1503
|
+
s(`.${id}`).style.top = '0px';
|
|
1504
|
+
} else {
|
|
1505
|
+
s(`.${id}`).style.top = `${options.heightTopBar ? options.heightTopBar : heightDefaultTopBar}px`;
|
|
1506
|
+
}
|
|
1507
|
+
},
|
|
1508
|
+
{ key: `view-${id}` },
|
|
1509
|
+
);
|
|
1510
|
+
Responsive.triggerChanged(`view-${id}`);
|
|
1390
1511
|
|
|
1391
1512
|
s(`.main-body-top`).onclick = () => s(`.btn-close-modal-menu`).click();
|
|
1392
1513
|
}
|
|
@@ -1512,7 +1633,7 @@ const Modal = {
|
|
|
1512
1633
|
>
|
|
1513
1634
|
<div class="btn-bar-modal-container-render-${idModal}"></div>
|
|
1514
1635
|
<div class="in flr bar-default-modal" style="z-index: 1">
|
|
1515
|
-
${await BtnIcon.
|
|
1636
|
+
${await BtnIcon.instance({
|
|
1516
1637
|
class: `btn-minimize-${idModal} btn-modal-default btn-modal-default-${idModal} ${
|
|
1517
1638
|
options?.btnContainerClass ? options.btnContainerClass : ''
|
|
1518
1639
|
} ${options?.barConfig?.buttons?.minimize?.disabled ? 'hide' : ''}`,
|
|
@@ -1520,7 +1641,7 @@ const Modal = {
|
|
|
1520
1641
|
${options?.barConfig?.buttons?.minimize?.label ? options.barConfig.buttons.minimize.label : html`_`}
|
|
1521
1642
|
</div>`,
|
|
1522
1643
|
})}
|
|
1523
|
-
${await BtnIcon.
|
|
1644
|
+
${await BtnIcon.instance({
|
|
1524
1645
|
class: `btn-restore-${idModal} btn-modal-default btn-modal-default-${idModal} ${
|
|
1525
1646
|
options?.btnContainerClass ? options.btnContainerClass : ''
|
|
1526
1647
|
} ${options?.barConfig?.buttons?.restore?.disabled ? 'hide' : ''}`,
|
|
@@ -1529,7 +1650,7 @@ const Modal = {
|
|
|
1529
1650
|
</div>`,
|
|
1530
1651
|
style: 'display: none',
|
|
1531
1652
|
})}
|
|
1532
|
-
${await BtnIcon.
|
|
1653
|
+
${await BtnIcon.instance({
|
|
1533
1654
|
class: `btn-maximize-${idModal} btn-modal-default btn-modal-default-${idModal} ${
|
|
1534
1655
|
options?.btnContainerClass ? options.btnContainerClass : ''
|
|
1535
1656
|
} ${options?.barConfig?.buttons?.maximize?.disabled ? 'hide' : ''}`,
|
|
@@ -1537,7 +1658,7 @@ const Modal = {
|
|
|
1537
1658
|
${options?.barConfig?.buttons?.maximize?.label ? options.barConfig.buttons.maximize.label : html`▢`}
|
|
1538
1659
|
</div>`,
|
|
1539
1660
|
})}
|
|
1540
|
-
${await BtnIcon.
|
|
1661
|
+
${await BtnIcon.instance({
|
|
1541
1662
|
class: `btn-close-${idModal} btn-modal-default btn-modal-default-${idModal} ${
|
|
1542
1663
|
options?.btnContainerClass ? options.btnContainerClass : ''
|
|
1543
1664
|
} ${options?.barConfig?.buttons?.close?.disabled ? 'hide' : ''}`,
|
|
@@ -1545,7 +1666,7 @@ const Modal = {
|
|
|
1545
1666
|
${options?.barConfig?.buttons?.close?.label ? options.barConfig.buttons.close.label : html`X`}
|
|
1546
1667
|
</div>`,
|
|
1547
1668
|
})}
|
|
1548
|
-
${await BtnIcon.
|
|
1669
|
+
${await BtnIcon.instance({
|
|
1549
1670
|
class: `btn-menu-${idModal} btn-modal-default btn-modal-default-${idModal} ${
|
|
1550
1671
|
options?.btnContainerClass ? options.btnContainerClass : ''
|
|
1551
1672
|
} ${options?.barConfig?.buttons?.menu?.disabled ? 'hide' : ''}`,
|
|
@@ -1573,7 +1694,7 @@ const Modal = {
|
|
|
1573
1694
|
class="stq modal"
|
|
1574
1695
|
style="${renderCssAttr({ style: { height: '50px', 'z-index': 1, top: '0px' } })}"
|
|
1575
1696
|
>
|
|
1576
|
-
${await BtnIcon.
|
|
1697
|
+
${await BtnIcon.instance({
|
|
1577
1698
|
style: renderCssAttr({ style: { height: '100%', color: '#5f5f5f' } }),
|
|
1578
1699
|
class: `in flr main-btn-menu action-bar-box btn-icon-menu-mode`,
|
|
1579
1700
|
label: html` <div class="abs center">
|
|
@@ -1589,14 +1710,14 @@ const Modal = {
|
|
|
1589
1710
|
></i>
|
|
1590
1711
|
</div>`,
|
|
1591
1712
|
})}
|
|
1592
|
-
${await BtnIcon.
|
|
1713
|
+
${await BtnIcon.instance({
|
|
1593
1714
|
style: renderCssAttr({ style: { height: '100%', color: '#5f5f5f' } }),
|
|
1594
1715
|
class: `in flr main-btn-menu action-bar-box btn-icon-menu-back hide`,
|
|
1595
1716
|
label: html`<div class="abs center"><i class="fas fa-undo-alt"></i></div>`,
|
|
1596
1717
|
})}
|
|
1597
1718
|
<div class="abs sub-menu-title-container-${idModal} ac">
|
|
1598
1719
|
<div class="abs nav-title-display-${idModal}">
|
|
1599
|
-
<!-- <i class="fas fa-home"></i> ${Translate.
|
|
1720
|
+
<!-- <i class="fas fa-home"></i> ${Translate.instance('home')} -->
|
|
1600
1721
|
</div>
|
|
1601
1722
|
</div>
|
|
1602
1723
|
<div class="abs nav-path-container-${idModal} ahc bold">
|
|
@@ -1636,7 +1757,7 @@ const Modal = {
|
|
|
1636
1757
|
case 'slide-menu-right':
|
|
1637
1758
|
case 'slide-menu-left':
|
|
1638
1759
|
const backMenuButtonEvent = async () => {
|
|
1639
|
-
// htmls(`.nav-title-display-${'modal-menu'}`, html`<i class="fas fa-home"></i> ${Translate.
|
|
1760
|
+
// htmls(`.nav-title-display-${'modal-menu'}`, html`<i class="fas fa-home"></i> ${Translate.instance('home')}`);
|
|
1640
1761
|
htmls(`.nav-title-display-${'modal-menu'}`, html``);
|
|
1641
1762
|
htmls(`.nav-path-display-${idModal}`, '');
|
|
1642
1763
|
s(`.btn-icon-menu-back`).classList.add('hide');
|
|
@@ -1668,6 +1789,12 @@ const Modal = {
|
|
|
1668
1789
|
if (options.onCollapseMenu) options.onCollapseMenu();
|
|
1669
1790
|
s(`.sub-menu-title-container-${'modal-menu'}`).classList.add('hide');
|
|
1670
1791
|
s(`.nav-path-container-${'modal-menu'}`).classList.add('hide');
|
|
1792
|
+
// Shrink any already-open submenu containers to icon-only width
|
|
1793
|
+
Object.keys(Modal.subMenuBtnClass).forEach((subMenuId) => {
|
|
1794
|
+
const container = s(`.menu-btn-container-children-${subMenuId}`);
|
|
1795
|
+
if (container && container.style.height && container.style.height !== '0px')
|
|
1796
|
+
container.style.width = `${collapseSlideMenuWidth}px`;
|
|
1797
|
+
});
|
|
1671
1798
|
Object.keys(this.Data[idModal].onCollapseMenuListener).map((keyListener) =>
|
|
1672
1799
|
this.Data[idModal].onCollapseMenuListener[keyListener](),
|
|
1673
1800
|
);
|
|
@@ -1685,12 +1812,18 @@ const Modal = {
|
|
|
1685
1812
|
if (options.onExtendMenu) options.onExtendMenu();
|
|
1686
1813
|
s(`.sub-menu-title-container-${'modal-menu'}`).classList.remove('hide');
|
|
1687
1814
|
s(`.nav-path-container-${'modal-menu'}`).classList.remove('hide');
|
|
1815
|
+
// Expand any already-open submenu containers back to full width
|
|
1816
|
+
Object.keys(Modal.subMenuBtnClass).forEach((subMenuId) => {
|
|
1817
|
+
const container = s(`.menu-btn-container-children-${subMenuId}`);
|
|
1818
|
+
if (container && container.style.height && container.style.height !== '0px')
|
|
1819
|
+
container.style.width = `${originSlideMenuWidth}px`;
|
|
1820
|
+
});
|
|
1688
1821
|
Object.keys(this.Data[idModal].onExtendMenuListener).map((keyListener) =>
|
|
1689
1822
|
this.Data[idModal].onExtendMenuListener[keyListener](),
|
|
1690
1823
|
);
|
|
1691
1824
|
}
|
|
1692
1825
|
Modal.Data[idModal][options.mode].width = slideMenuWidth;
|
|
1693
|
-
Responsive.
|
|
1826
|
+
Responsive.triggerChanged(`slide-menu-${idModal}`);
|
|
1694
1827
|
});
|
|
1695
1828
|
|
|
1696
1829
|
break;
|
|
@@ -1965,22 +2098,25 @@ const Modal = {
|
|
|
1965
2098
|
callBack,
|
|
1966
2099
|
id: options.slideMenu,
|
|
1967
2100
|
};
|
|
1968
|
-
Responsive.
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
s(
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
2101
|
+
Responsive.onChanged(
|
|
2102
|
+
() => {
|
|
2103
|
+
setTimeout(() => {
|
|
2104
|
+
if (!s(`.${idModal}`) || !s(`.main-body-btn-ui-close`)) return;
|
|
2105
|
+
if (s(`.btn-restore-${idModal}`) && s(`.btn-restore-${idModal}`).style.display !== 'none') {
|
|
2106
|
+
s(`.${idModal}`).style.height = s(`.main-body-btn-ui-close`).classList.contains('hide')
|
|
2107
|
+
? `${windowGetH()}px`
|
|
2108
|
+
: `${Modal.Data[idModal].getHeight()}px`;
|
|
2109
|
+
}
|
|
2110
|
+
s(`.${idModal}`).style.top = s(`.main-body-btn-ui-close`).classList.contains('hide')
|
|
2111
|
+
? `0px`
|
|
2112
|
+
: `${options.heightTopBar ? options.heightTopBar : heightDefaultTopBar}px`;
|
|
2113
|
+
});
|
|
2114
|
+
},
|
|
2115
|
+
{ key: 'h-ui-hide-' + idModal },
|
|
2116
|
+
);
|
|
2117
|
+
Responsive.triggerChanged('h-ui-hide-' + idModal);
|
|
1982
2118
|
} else {
|
|
1983
|
-
|
|
2119
|
+
Responsive.offChanged('h-ui-hide-' + idModal);
|
|
1984
2120
|
s(`.${idModal}`).style.width = '100%';
|
|
1985
2121
|
s(`.${idModal}`).style.height = '100%';
|
|
1986
2122
|
s(`.${idModal}`).style.top = `${options.heightTopBar ? options.heightTopBar : heightDefaultTopBar}px`;
|
|
@@ -2030,10 +2166,13 @@ const Modal = {
|
|
|
2030
2166
|
id: idModal,
|
|
2031
2167
|
...this.Data[idModal],
|
|
2032
2168
|
};
|
|
2033
|
-
}
|
|
2034
|
-
|
|
2169
|
+
}
|
|
2170
|
+
|
|
2171
|
+
/** @type {Object.<string, object>} */
|
|
2172
|
+
static subMenuBtnClass = {};
|
|
2035
2173
|
|
|
2036
|
-
|
|
2174
|
+
/** Navigate to the home route and close all non-home modals. */
|
|
2175
|
+
static onHomeRouterEvent = async () => {
|
|
2037
2176
|
// 1. Get list of modals to close.
|
|
2038
2177
|
const modalsToClose = Object.keys(Modal.Data).filter((idModal) => {
|
|
2039
2178
|
const modal = Modal.Data[idModal];
|
|
@@ -2073,9 +2212,16 @@ const Modal = {
|
|
|
2073
2212
|
if (s(`.btn-close-modal-menu`) && !s(`.btn-close-modal-menu`).classList.contains('hide')) {
|
|
2074
2213
|
s(`.btn-close-modal-menu`).click();
|
|
2075
2214
|
}
|
|
2076
|
-
}
|
|
2077
|
-
|
|
2078
|
-
|
|
2215
|
+
};
|
|
2216
|
+
|
|
2217
|
+
/** @type {string} */
|
|
2218
|
+
static currentTopModalId = '';
|
|
2219
|
+
|
|
2220
|
+
/**
|
|
2221
|
+
* Synchronise z-index for view modals, promoting the given modal to top.
|
|
2222
|
+
* @param {{ idModal: string }} param0
|
|
2223
|
+
*/
|
|
2224
|
+
static zIndexSync({ idModal }) {
|
|
2079
2225
|
setTimeout(() => {
|
|
2080
2226
|
if (!this.Data[idModal]) return;
|
|
2081
2227
|
const cleanTopModal = () => {
|
|
@@ -2101,14 +2247,30 @@ const Modal = {
|
|
|
2101
2247
|
}
|
|
2102
2248
|
};
|
|
2103
2249
|
});
|
|
2104
|
-
}
|
|
2105
|
-
|
|
2250
|
+
}
|
|
2251
|
+
|
|
2252
|
+
/**
|
|
2253
|
+
* @param {string} idModal
|
|
2254
|
+
*/
|
|
2255
|
+
static setTopModalCallback(idModal) {
|
|
2106
2256
|
s(`.${idModal}`).style.zIndex = '4';
|
|
2107
2257
|
this.currentTopModalId = `${idModal}`;
|
|
2108
|
-
}
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2260
|
+
/** @returns {boolean} True when the viewport is considered mobile-sized. */
|
|
2261
|
+
static mobileModal = () => windowGetW() < 600 || windowGetH() < 600;
|
|
2262
|
+
|
|
2263
|
+
/**
|
|
2264
|
+
* @param {{ idModal: string, html: string }} param0
|
|
2265
|
+
*/
|
|
2266
|
+
static writeHTML = ({ idModal, html }) => htmls(`.html-${idModal}`, html);
|
|
2267
|
+
|
|
2268
|
+
/**
|
|
2269
|
+
* Update an existing modal's content and/or title.
|
|
2270
|
+
* @param {{ idModal: string, html?: string, title?: string }} param0
|
|
2271
|
+
* @returns {Promise<boolean>}
|
|
2272
|
+
*/
|
|
2273
|
+
static async updateModal({ idModal, html, title }) {
|
|
2112
2274
|
if (!this.Data[idModal] || !s(`.${idModal}`)) {
|
|
2113
2275
|
console.warn(`Modal ${idModal} not found for update`);
|
|
2114
2276
|
return false;
|
|
@@ -2135,19 +2297,32 @@ const Modal = {
|
|
|
2135
2297
|
}
|
|
2136
2298
|
|
|
2137
2299
|
return true;
|
|
2138
|
-
}
|
|
2139
|
-
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2302
|
+
/** @returns {string|undefined} Id of the first open view-mode modal, or undefined. */
|
|
2303
|
+
static viewModalOpen() {
|
|
2140
2304
|
return Object.keys(this.Data).find((idModal) => s(`.${idModal}`) && this.Data[idModal].options.mode === 'view');
|
|
2141
|
-
}
|
|
2142
|
-
|
|
2305
|
+
}
|
|
2306
|
+
|
|
2307
|
+
/**
|
|
2308
|
+
* Remove a modal element and its style tags, and delete its data entry.
|
|
2309
|
+
* @param {string} idModal
|
|
2310
|
+
*/
|
|
2311
|
+
static removeModal(idModal) {
|
|
2143
2312
|
if (!s(`.${idModal}`)) return;
|
|
2144
2313
|
s(`.${idModal}`).remove();
|
|
2145
2314
|
sa(`.style-${idModal}`).forEach((element) => {
|
|
2146
2315
|
element.remove();
|
|
2147
2316
|
});
|
|
2148
2317
|
delete this.Data[idModal];
|
|
2149
|
-
}
|
|
2150
|
-
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
/**
|
|
2321
|
+
* Render a confirmation dialog and return a promise resolving to the user's choice.
|
|
2322
|
+
* @param {{ id: string, html: Function, icon?: string, disableBtnCancel?: boolean }} options
|
|
2323
|
+
* @returns {Promise<{ status: 'confirm'|'cancelled' }>}
|
|
2324
|
+
*/
|
|
2325
|
+
static async RenderConfirm(options) {
|
|
2151
2326
|
const { id } = options;
|
|
2152
2327
|
append(
|
|
2153
2328
|
'body',
|
|
@@ -2190,23 +2365,23 @@ const Modal = {
|
|
|
2190
2365
|
</div>
|
|
2191
2366
|
${await options.html()}
|
|
2192
2367
|
<div class="in section-mp">
|
|
2193
|
-
${await BtnIcon.
|
|
2368
|
+
${await BtnIcon.instance({
|
|
2194
2369
|
class: `in section-mp form-button btn-confirm-${id}`,
|
|
2195
|
-
label: Translate.
|
|
2370
|
+
label: Translate.instance('confirm'),
|
|
2196
2371
|
type: 'submit',
|
|
2197
2372
|
style: `margin: auto`,
|
|
2198
2373
|
})}
|
|
2199
2374
|
</div>
|
|
2200
2375
|
<div class="in section-mp ${options.disableBtnCancel ? 'hide' : ''}">
|
|
2201
|
-
${await BtnIcon.
|
|
2376
|
+
${await BtnIcon.instance({
|
|
2202
2377
|
class: `in section-mp form-button btn-cancel-${id}`,
|
|
2203
|
-
label: Translate.
|
|
2378
|
+
label: Translate.instance('cancel'),
|
|
2204
2379
|
type: 'submit',
|
|
2205
2380
|
style: `margin: auto`,
|
|
2206
2381
|
})}
|
|
2207
2382
|
</div>
|
|
2208
2383
|
`;
|
|
2209
|
-
await Modal.
|
|
2384
|
+
await Modal.instance({
|
|
2210
2385
|
id,
|
|
2211
2386
|
barConfig,
|
|
2212
2387
|
titleClass: 'hide',
|
|
@@ -2243,10 +2418,20 @@ const Modal = {
|
|
|
2243
2418
|
resolve({ status: 'confirm' });
|
|
2244
2419
|
};
|
|
2245
2420
|
});
|
|
2246
|
-
}
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2421
|
+
}
|
|
2422
|
+
|
|
2423
|
+
/** @type {string} */
|
|
2424
|
+
static labelSelectorTopOffsetStartAnimation = `-40px`;
|
|
2425
|
+
|
|
2426
|
+
/** @type {string} */
|
|
2427
|
+
static labelSelectorTopOffsetEndAnimation = `-3px`;
|
|
2428
|
+
|
|
2429
|
+
/**
|
|
2430
|
+
* Animate slide-menu labels into view.
|
|
2431
|
+
* @param {string} idModal - The slide-menu modal id.
|
|
2432
|
+
* @param {string} [subMenuId] - If provided, animate only this sub-menu.
|
|
2433
|
+
*/
|
|
2434
|
+
static menuTextLabelAnimation = (idModal, subMenuId) => {
|
|
2250
2435
|
if (
|
|
2251
2436
|
!s(
|
|
2252
2437
|
`.btn-icon-menu-mode-${Modal.Data[idModal].options.mode === 'slide-menu-right' ? 'left' : 'right'}`,
|
|
@@ -2289,19 +2474,66 @@ const Modal = {
|
|
|
2289
2474
|
});
|
|
2290
2475
|
}, 400);
|
|
2291
2476
|
}
|
|
2292
|
-
}
|
|
2477
|
+
};
|
|
2478
|
+
|
|
2479
|
+
/**
|
|
2480
|
+
* Builds submenu item HTML using the canonical BtnIcon pattern.
|
|
2481
|
+
* Centralises the item-rendering contract so individual submenu owners (e.g. Docs)
|
|
2482
|
+
* only need to supply data — not layout concerns.
|
|
2483
|
+
* @param {string} subMenuId - Submenu identifier (e.g. 'docs')
|
|
2484
|
+
* @param {Array<{type:string, icon:string, text:string, url:function|string}>} items
|
|
2485
|
+
* @param {Object} [options]
|
|
2486
|
+
* @param {function} [options.subMenuIcon] - Optional icon override per item type
|
|
2487
|
+
* @returns {Promise<string>} Rendered HTML string
|
|
2488
|
+
*/
|
|
2489
|
+
static buildSubMenuItemsHtml = async (subMenuId, items = [], options = {}) => {
|
|
2490
|
+
let result = '';
|
|
2491
|
+
const _menuMode = Modal.Data['modal-menu']?.options?.mode;
|
|
2492
|
+
const _tooltipSide = options.tooltipSide || (_menuMode === 'slide-menu-right' ? 'right' : 'left');
|
|
2493
|
+
for (const item of items) {
|
|
2494
|
+
const tabHref = typeof item.url === 'function' ? item.url() : item.url || '';
|
|
2495
|
+
const icon =
|
|
2496
|
+
options.subMenuIcon && typeof options.subMenuIcon === 'function' ? options.subMenuIcon(item.type) : item.icon;
|
|
2497
|
+
result += html`${await BtnIcon.instance({
|
|
2498
|
+
class: `in wfa main-btn-menu submenu-btn btn-${subMenuId} btn-${subMenuId}-${item.type}`,
|
|
2499
|
+
label: html`<span class="inl menu-btn-icon">${icon}</span
|
|
2500
|
+
><span class="menu-label-text menu-label-text-${subMenuId}"> ${item.text} </span>`,
|
|
2501
|
+
tabHref,
|
|
2502
|
+
tooltipHtml: await Badge.instance(buildBadgeToolTipMenuOption(item.text, _tooltipSide)),
|
|
2503
|
+
useMenuBtn: true,
|
|
2504
|
+
})} `;
|
|
2505
|
+
}
|
|
2506
|
+
return result;
|
|
2507
|
+
};
|
|
2508
|
+
|
|
2509
|
+
/**
|
|
2510
|
+
* Injects pre-built submenu item HTML into the submenu container and syncs
|
|
2511
|
+
* the collapse state so labels are hidden when the menu is icon-only.
|
|
2512
|
+
* @param {string} subMenuId
|
|
2513
|
+
* @param {string} itemsHtml
|
|
2514
|
+
*/
|
|
2515
|
+
static subMenuPopulate = (subMenuId, itemsHtml) => {
|
|
2516
|
+
htmls(`.menu-btn-container-children-${subMenuId}`, itemsHtml);
|
|
2517
|
+
const _menuMode = Modal.Data['modal-menu']?.options?.mode;
|
|
2518
|
+
const _collapseIndicatorClass =
|
|
2519
|
+
_menuMode === 'slide-menu-right' ? '.btn-icon-menu-mode-left' : '.btn-icon-menu-mode-right';
|
|
2520
|
+
if (s(_collapseIndicatorClass) && !s(_collapseIndicatorClass).classList.contains('hide')) {
|
|
2521
|
+
sa(`.menu-label-text-${subMenuId}`).forEach((el) => el.classList.add('hide'));
|
|
2522
|
+
}
|
|
2523
|
+
};
|
|
2524
|
+
|
|
2293
2525
|
// Move modal title element into the bar's render container so it aligns with control buttons
|
|
2294
2526
|
/**
|
|
2295
|
-
* Position a modal relative to an anchor element
|
|
2296
|
-
* @param {
|
|
2527
|
+
* Position a modal relative to an anchor element.
|
|
2528
|
+
* @param {object} options - Positioning options
|
|
2297
2529
|
* @param {string} options.modalSelector - CSS selector for the modal element
|
|
2298
2530
|
* @param {string} options.anchorSelector - CSS selector for the anchor element
|
|
2299
|
-
* @param {
|
|
2531
|
+
* @param {object} [options.offset={x: 0, y: 6}] - Offset from anchor
|
|
2300
2532
|
* @param {string} [options.align='right'] - Horizontal alignment ('left' or 'right')
|
|
2301
2533
|
* @param {boolean} [options.autoVertical=true] - Whether to automatically determine vertical position
|
|
2302
2534
|
* @param {boolean} [options.placeAbove] - Force position above/below anchor (overrides autoVertical)
|
|
2303
2535
|
*/
|
|
2304
|
-
positionRelativeToAnchor({
|
|
2536
|
+
static positionRelativeToAnchor({
|
|
2305
2537
|
modalSelector,
|
|
2306
2538
|
anchorSelector,
|
|
2307
2539
|
offset = { x: 0, y: 6 },
|
|
@@ -2373,9 +2605,13 @@ const Modal = {
|
|
|
2373
2605
|
} catch (e) {
|
|
2374
2606
|
console.error('Error positioning modal:', e);
|
|
2375
2607
|
}
|
|
2376
|
-
}
|
|
2608
|
+
}
|
|
2377
2609
|
|
|
2378
|
-
|
|
2610
|
+
/**
|
|
2611
|
+
* Move the title element inside the bar button container for inline alignment.
|
|
2612
|
+
* @param {string} idModal
|
|
2613
|
+
*/
|
|
2614
|
+
static MoveTitleToBar(idModal) {
|
|
2379
2615
|
try {
|
|
2380
2616
|
const titleEl = s(`.title-modal-${idModal}`);
|
|
2381
2617
|
const container = s(`.btn-bar-modal-container-render-${idModal}`);
|
|
@@ -2388,8 +2624,10 @@ const Modal = {
|
|
|
2388
2624
|
} catch (e) {
|
|
2389
2625
|
// non-fatal: keep default placement if structure not present
|
|
2390
2626
|
}
|
|
2391
|
-
}
|
|
2392
|
-
|
|
2627
|
+
}
|
|
2628
|
+
|
|
2629
|
+
/** Update the top-banner anchor href and bind the home-click handler. */
|
|
2630
|
+
static setTopBannerLink() {
|
|
2393
2631
|
if (s(`.a-link-top-banner`)) {
|
|
2394
2632
|
s(`.a-link-top-banner`).setAttribute('href', `${location.origin}${getProxyPath()}`);
|
|
2395
2633
|
EventsUI.onClick(`.a-link-top-banner`, (e) => {
|
|
@@ -2397,32 +2635,72 @@ const Modal = {
|
|
|
2397
2635
|
s(`.action-btn-home`).click();
|
|
2398
2636
|
});
|
|
2399
2637
|
}
|
|
2400
|
-
}
|
|
2401
|
-
|
|
2402
|
-
|
|
2638
|
+
}
|
|
2639
|
+
|
|
2640
|
+
/** @type {number} */
|
|
2641
|
+
static headerTitleHeight = 40;
|
|
2642
|
+
|
|
2643
|
+
/** Toggle the slide-menu open/close via the center action button. */
|
|
2644
|
+
static actionBtnCenter() {
|
|
2403
2645
|
if (!s(`.btn-close-modal-menu`).classList.contains('hide')) {
|
|
2404
2646
|
return s(`.btn-close-modal-menu`).click();
|
|
2405
2647
|
}
|
|
2406
2648
|
if (!s(`.btn-menu-modal-menu`).classList.contains('hide')) {
|
|
2407
2649
|
return s(`.btn-menu-modal-menu`).click();
|
|
2408
2650
|
}
|
|
2409
|
-
}
|
|
2410
|
-
|
|
2651
|
+
}
|
|
2652
|
+
|
|
2653
|
+
/** Hide the top-bar, bottom-bar and slide-menu (full-screen mode). */
|
|
2654
|
+
static cleanUI() {
|
|
2411
2655
|
s(`.top-bar`).classList.add('hide');
|
|
2412
2656
|
s(`.bottom-bar`).classList.add('hide');
|
|
2413
2657
|
s(`.modal-menu`).classList.add('hide');
|
|
2414
|
-
}
|
|
2415
|
-
|
|
2658
|
+
}
|
|
2659
|
+
|
|
2660
|
+
/** Restore the top-bar, bottom-bar and slide-menu after cleanUI. */
|
|
2661
|
+
static restoreUI() {
|
|
2416
2662
|
s(`.top-bar`).classList.remove('hide');
|
|
2417
2663
|
s(`.bottom-bar`).classList.remove('hide');
|
|
2418
2664
|
s(`.modal-menu`).classList.remove('hide');
|
|
2419
|
-
}
|
|
2420
|
-
|
|
2665
|
+
}
|
|
2666
|
+
|
|
2667
|
+
/**
|
|
2668
|
+
* Re-applies canonical top/height layout for maximized slide-menu-backed view modals.
|
|
2669
|
+
* This avoids iframe navigation leaving view containers offset at the top.
|
|
2670
|
+
*/
|
|
2671
|
+
static syncViewLayout() {
|
|
2672
|
+
const modalMenuOptions = this.Data['modal-menu']?.options || {};
|
|
2673
|
+
const uiCollapsed = !!s(`.main-body-btn-ui-close`) && s(`.main-body-btn-ui-close`).classList.contains('hide');
|
|
2674
|
+
const topOffset = uiCollapsed ? 0 : modalMenuOptions.heightTopBar ? modalMenuOptions.heightTopBar : 50;
|
|
2675
|
+
const bottomOffset = uiCollapsed ? 0 : modalMenuOptions.heightBottomBar ? modalMenuOptions.heightBottomBar : 0;
|
|
2676
|
+
const height = `${windowGetH() - topOffset - bottomOffset}px`;
|
|
2677
|
+
|
|
2678
|
+
Object.keys(this.Data).forEach((idModal) => {
|
|
2679
|
+
const modalData = this.Data[idModal];
|
|
2680
|
+
const modalEl = s(`.${idModal}`);
|
|
2681
|
+
if (!modalData || !modalEl || !modalData.slideMenu) return;
|
|
2682
|
+
if (s(`.btn-restore-${idModal}`) && s(`.btn-restore-${idModal}`).style.display === 'none') return;
|
|
2683
|
+
|
|
2684
|
+
modalEl.style.position = 'fixed';
|
|
2685
|
+
modalEl.style.translate = '0px 0px';
|
|
2686
|
+
modalEl.style.transform = '';
|
|
2687
|
+
modalEl.style.top = `${topOffset}px`;
|
|
2688
|
+
modalEl.style.height = height;
|
|
2689
|
+
});
|
|
2690
|
+
|
|
2691
|
+
for (const id of coreUI) {
|
|
2692
|
+
const key = `view-${id}`;
|
|
2693
|
+
if (Responsive.hasChangedListener(key)) Responsive.triggerChanged(key);
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
|
|
2697
|
+
/** Add missing `alt` attributes to all images for SEO/accessibility. */
|
|
2698
|
+
static RenderSeoSanitizer = async () => {
|
|
2421
2699
|
sa('img').forEach((img) => {
|
|
2422
2700
|
if (!img.getAttribute('alt')) img.setAttribute('alt', 'image ' + Worker.title + ' ' + s4());
|
|
2423
2701
|
});
|
|
2424
|
-
}
|
|
2425
|
-
}
|
|
2702
|
+
};
|
|
2703
|
+
}
|
|
2426
2704
|
|
|
2427
2705
|
const renderMenuLabel = ({ img, src, text, icon }) => {
|
|
2428
2706
|
if (!img && !src) return html`<span class="inl menu-btn-icon">${icon}</span> ${text}`;
|
|
@@ -2479,7 +2757,7 @@ const renderViewTitle = (
|
|
|
2479
2757
|
const buildBadgeToolTipMenuOption = (id, sideKey = 'left') => {
|
|
2480
2758
|
const option = {
|
|
2481
2759
|
id: `tooltip-content-main-btn-${id}`,
|
|
2482
|
-
text: `${Translate.
|
|
2760
|
+
text: `${Translate.instance(`${id}`)}`,
|
|
2483
2761
|
classList: 'tooltip-menu',
|
|
2484
2762
|
style: { top: `-40px` },
|
|
2485
2763
|
};
|
|
@@ -2549,9 +2827,14 @@ const subMenuRender = async (subMenuId) => {
|
|
|
2549
2827
|
setTimeout(() => {
|
|
2550
2828
|
Modal.menuTextLabelAnimation('modal-menu', subMenuId);
|
|
2551
2829
|
});
|
|
2552
|
-
// Open animation
|
|
2830
|
+
// Open animation — match the current menu width (collapsed = 50px, extended = 320px)
|
|
2831
|
+
const _menuMode = Modal.Data['modal-menu']?.options?.mode;
|
|
2832
|
+
const _collapseIndicatorClass =
|
|
2833
|
+
_menuMode === 'slide-menu-right' ? '.btn-icon-menu-mode-left' : '.btn-icon-menu-mode-right';
|
|
2834
|
+
const _isMenuCollapsed = s(_collapseIndicatorClass) && !s(_collapseIndicatorClass).classList.contains('hide');
|
|
2835
|
+
const _menuContainerWidth = _isMenuCollapsed ? 50 : 320;
|
|
2553
2836
|
setTimeout(top, 360);
|
|
2554
|
-
menuContainer.style.width =
|
|
2837
|
+
menuContainer.style.width = `${_menuContainerWidth}px`;
|
|
2555
2838
|
menuContainer.style.overflow = null;
|
|
2556
2839
|
menuContainer.style.height = '0px';
|
|
2557
2840
|
menuContainer.style.height = `${_hBtn * 6}px`;
|