airdcpp-webui 2.12.1-beta.3 → 2.12.1
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/dist/index.html +1 -1
- package/dist/js/{223.d8381390628f8a92159f.chunk.js → 223.92cf614c9d87cf67385e.chunk.js} +2 -2
- package/dist/js/223.92cf614c9d87cf67385e.chunk.js.gz +0 -0
- package/dist/js/{223.d8381390628f8a92159f.chunk.js.map → 223.92cf614c9d87cf67385e.chunk.js.map} +1 -1
- package/dist/js/{236.a5df8c51dbebe95cc268.chunk.js → 236.6b4fd58c10a23138b7d8.chunk.js} +2 -2
- package/dist/js/236.6b4fd58c10a23138b7d8.chunk.js.gz +0 -0
- package/dist/js/236.6b4fd58c10a23138b7d8.chunk.js.map +1 -0
- package/dist/js/{544.58de40c388788ce8d588.chunk.js → 544.826a806e4535f09cf100.chunk.js} +2 -2
- package/dist/js/{544.58de40c388788ce8d588.chunk.js.gz → 544.826a806e4535f09cf100.chunk.js.gz} +0 -0
- package/dist/js/{544.58de40c388788ce8d588.chunk.js.map → 544.826a806e4535f09cf100.chunk.js.map} +1 -1
- package/dist/js/{616.6af0b2487703c8da4b2c.chunk.js → 616.57a60c241582d79fa280.chunk.js} +2 -2
- package/dist/js/616.57a60c241582d79fa280.chunk.js.gz +0 -0
- package/dist/js/{616.6af0b2487703c8da4b2c.chunk.js.map → 616.57a60c241582d79fa280.chunk.js.map} +1 -1
- package/dist/js/{favorite-hubs.5d14015c002fab9d6e93.chunk.js → favorite-hubs.f1ced66aa7691eeee525.chunk.js} +2 -2
- package/dist/js/favorite-hubs.f1ced66aa7691eeee525.chunk.js.gz +0 -0
- package/dist/js/{favorite-hubs.5d14015c002fab9d6e93.chunk.js.map → favorite-hubs.f1ced66aa7691eeee525.chunk.js.map} +1 -1
- package/dist/js/{filelists.69f099cbc0bb5b67d1b8.chunk.js → filelists.852a6a879bab1f93854e.chunk.js} +2 -2
- package/dist/js/filelists.852a6a879bab1f93854e.chunk.js.gz +0 -0
- package/dist/js/{filelists.69f099cbc0bb5b67d1b8.chunk.js.map → filelists.852a6a879bab1f93854e.chunk.js.map} +1 -1
- package/dist/js/{home.ccd57551ac01ff4fc4ba.chunk.js → home.9a37f3a3c78cb9b3f45c.chunk.js} +3 -3
- package/dist/js/home.9a37f3a3c78cb9b3f45c.chunk.js.gz +0 -0
- package/dist/js/home.9a37f3a3c78cb9b3f45c.chunk.js.map +1 -0
- package/dist/js/{hubs.c2b8880d6d8ccfc9eb3a.chunk.js → hubs.c21b941c411425d4852f.chunk.js} +2 -2
- package/dist/js/hubs.c21b941c411425d4852f.chunk.js.gz +0 -0
- package/dist/js/hubs.c21b941c411425d4852f.chunk.js.map +1 -0
- package/dist/js/main.7a746a54efc4bf96cd20.entry.js +3 -0
- package/dist/js/{main.a7216efbb2c5cd34c7e5.entry.js.LICENSE.txt → main.7a746a54efc4bf96cd20.entry.js.LICENSE.txt} +3 -3
- package/dist/js/main.7a746a54efc4bf96cd20.entry.js.gz +0 -0
- package/dist/js/main.7a746a54efc4bf96cd20.entry.js.map +1 -0
- package/dist/js/{messages.980fd246050252a227cd.chunk.js → messages.6ed02d7d7ec7e06a93f2.chunk.js} +2 -2
- package/dist/js/messages.6ed02d7d7ec7e06a93f2.chunk.js.gz +0 -0
- package/dist/js/{messages.980fd246050252a227cd.chunk.js.map → messages.6ed02d7d7ec7e06a93f2.chunk.js.map} +1 -1
- package/dist/js/{queue.31409106566ce8e19fc3.chunk.js → queue.c73112a5c40baeee7c54.chunk.js} +2 -2
- package/dist/js/queue.c73112a5c40baeee7c54.chunk.js.gz +0 -0
- package/dist/js/{queue.31409106566ce8e19fc3.chunk.js.map → queue.c73112a5c40baeee7c54.chunk.js.map} +1 -1
- package/dist/js/{search.d724d4a3b2c8f3fe2768.chunk.js → search.66bbb5aead0f68100e76.chunk.js} +2 -2
- package/dist/js/search.66bbb5aead0f68100e76.chunk.js.gz +0 -0
- package/dist/js/{search.d724d4a3b2c8f3fe2768.chunk.js.map → search.66bbb5aead0f68100e76.chunk.js.map} +1 -1
- package/dist/js/settings.a509b3c48b03452b6783.chunk.js +2 -0
- package/dist/js/settings.a509b3c48b03452b6783.chunk.js.gz +0 -0
- package/dist/js/settings.a509b3c48b03452b6783.chunk.js.map +1 -0
- package/dist/js/{share.a35d32796acde4fc3d59.chunk.js → share.6efce937acbd036d089d.chunk.js} +2 -2
- package/dist/js/share.6efce937acbd036d089d.chunk.js.gz +0 -0
- package/dist/js/{share.a35d32796acde4fc3d59.chunk.js.map → share.6efce937acbd036d089d.chunk.js.map} +1 -1
- package/dist/js/{system-log.2d9af5f3372752909d83.chunk.js → system-log.3efd872fbf4a90cde8d5.chunk.js} +2 -2
- package/dist/js/system-log.3efd872fbf4a90cde8d5.chunk.js.gz +0 -0
- package/dist/js/{system-log.2d9af5f3372752909d83.chunk.js.map → system-log.3efd872fbf4a90cde8d5.chunk.js.map} +1 -1
- package/dist/js/{transfers.22bad3799f0455da946b.chunk.js → transfers.326119d8de6e6f8176b5.chunk.js} +2 -2
- package/dist/js/transfers.326119d8de6e6f8176b5.chunk.js.gz +0 -0
- package/dist/js/{transfers.22bad3799f0455da946b.chunk.js.map → transfers.326119d8de6e6f8176b5.chunk.js.map} +1 -1
- package/dist/sw.js +1 -1
- package/dist/sw.js.gz +0 -0
- package/jest.config.js +1 -1
- package/package.json +2 -2
- package/tsconfig.json +1 -1
- package/dist/js/223.d8381390628f8a92159f.chunk.js.gz +0 -0
- package/dist/js/236.a5df8c51dbebe95cc268.chunk.js.gz +0 -0
- package/dist/js/236.a5df8c51dbebe95cc268.chunk.js.map +0 -1
- package/dist/js/616.6af0b2487703c8da4b2c.chunk.js.gz +0 -0
- package/dist/js/favorite-hubs.5d14015c002fab9d6e93.chunk.js.gz +0 -0
- package/dist/js/filelists.69f099cbc0bb5b67d1b8.chunk.js.gz +0 -0
- package/dist/js/home.ccd57551ac01ff4fc4ba.chunk.js.gz +0 -0
- package/dist/js/home.ccd57551ac01ff4fc4ba.chunk.js.map +0 -1
- package/dist/js/hubs.c2b8880d6d8ccfc9eb3a.chunk.js.gz +0 -0
- package/dist/js/hubs.c2b8880d6d8ccfc9eb3a.chunk.js.map +0 -1
- package/dist/js/main.a7216efbb2c5cd34c7e5.entry.js +0 -3
- package/dist/js/main.a7216efbb2c5cd34c7e5.entry.js.gz +0 -0
- package/dist/js/main.a7216efbb2c5cd34c7e5.entry.js.map +0 -1
- package/dist/js/messages.980fd246050252a227cd.chunk.js.gz +0 -0
- package/dist/js/queue.31409106566ce8e19fc3.chunk.js.gz +0 -0
- package/dist/js/search.d724d4a3b2c8f3fe2768.chunk.js.gz +0 -0
- package/dist/js/settings.4087d834170e87ff1c53.chunk.js +0 -2
- package/dist/js/settings.4087d834170e87ff1c53.chunk.js.gz +0 -0
- package/dist/js/settings.4087d834170e87ff1c53.chunk.js.map +0 -1
- package/dist/js/share.a35d32796acde4fc3d59.chunk.js.gz +0 -0
- package/dist/js/system-log.2d9af5f3372752909d83.chunk.js.gz +0 -0
- package/dist/js/transfers.22bad3799f0455da946b.chunk.js.gz +0 -0
- /package/dist/js/{home.ccd57551ac01ff4fc4ba.chunk.js.LICENSE.txt → home.9a37f3a3c78cb9b3f45c.chunk.js.LICENSE.txt} +0 -0
package/dist/js/{616.6af0b2487703c8da4b2c.chunk.js.map → 616.57a60c241582d79fa280.chunk.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"js/616.6af0b2487703c8da4b2c.chunk.js","mappings":"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","sources":["webpack://airdcpp-webui/./src/routes/Sidebar/sessions.css","webpack://airdcpp-webui/./src/actions/ui/decorators/SessionActionDecorator.ts","webpack://airdcpp-webui/./src/decorators/ActiveSessionDecorator.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/components/SessionFooter.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/components/TopMenuLayout.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/components/SideMenuLayout.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/components/effects/useSessionHelpers.ts","webpack://airdcpp-webui/./src/routes/Sidebar/components/effects/useSessionManager.ts","webpack://airdcpp-webui/./src/routes/Sidebar/sessions.css?90b7","webpack://airdcpp-webui/./src/routes/Sidebar/components/SessionNewButton.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/components/SessionMenuItem.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/components/SessionMenuComponents.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/components/SessionLayout.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/decorators/SessionProviderDecorator.tsx"],"sourcesContent":["// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.session-container {\n background-color: white;\n}\n\n.session-container.horizontal.ui.grid {\n margin: 0px !important;\n}\n\n.session-container.horizontal .menu-column .item.new {\n padding: 0.78571429em 1.1em !important;\n}\n\n.session-container.horizontal .ui.vertical.menu .item > i.icon {\n margin: 0 0.35714286em 0 0 !important;\n}\n\n.session-container.horizontal .session-layout > .ui.divider {\n margin: 5px 0px 0px 0px;\n}\n\n.session-container.vertical {\n padding: 15px;\n display: flex;\n flex-direction: column;\n}\n.session-layout {\n flex: 100 100 auto;\n display: flex;\n overflow: hidden;\n}\n\n.session-container.horizontal .session-layout {\n flex-direction: column;\n}\n\n.session-container.vertical .menu-bar {\n justify-content: space-between;\n margin: 0px !important;\n}\n\n.session-container.vertical .menu-bar .content-left {\n width: 100%;\n}\n\n.session-container.vertical .menu-bar .close-button.item:before {\n background: none !important;\n}\n\n.session-container.vertical .menu-bar .close-button.item {\n box-shadow: none !important;\n}\n\n.session-container.vertical .menu-bar .content-left > .ui.dropdown {\n float: left;\n}\n\n.session-container.vertical .menu-bar .content-left > .ui.dropdown .menu {\n max-height: calc(100vh - 140px);\n overflow-y: auto;\n overflow-x: hidden;\n max-width: calc(100vw - 30px);\n}\n\n.session-container.vertical .session-item .count.label {\n margin-left: 1em !important;\n}\n\n.session-container.vertical .session-header {\n display: flex;\n align-items: center;\n height: 100%;\n}\n\n.session-container.vertical .session-header > div {\n max-width: 90%; /* Hack, auto width won't work without \"overflow: hidden\", but that would prevent viewing the menu items */\n padding: 0.82857143em 0.4285714em;\n line-height: 1.2;\n}\n\n.session-container.vertical .session-header > div:before {\n background: none !important;\n}\n\n.session-container.vertical .session-header > i {\n margin-left: 10px;\n}\n\n.session-container.vertical .session-header .ui.dropdown > i {\n margin: 0px 5px;\n}\n\n/* Fix a few inconsistencies between 'icon' and 'icons' classnames */\n.session-container.horizontal .session-header .header > i,\n.session-container.vertical .session-header > i {\n width: inherit !important;\n font-size: 1.5em;\n}\n\n.session-container.horizontal .session-header .ui.header {\n align-items: center;\n}\n\n.session-container.vertical .menu-bar {\n border-radius: 0px !important;\n padding-bottom: 0px;\n}\n\n.session-container,\n.session-layout,\n.session-container.horizontal .column {\n height: 100%;\n}\n\n.session-container.horizontal .column > div {\n max-height: 100%;\n}\n\n.session-container .session-item {\n overflow: hidden;\n display: flex !important;\n align-items: center;\n padding: 0.68571429em 0.92857143em !important;\n height: 35px;\n}\n\n.session-container .session-item .session-status {\n float: none !important;\n margin: 0 0.5em 0 0 !important;\n}\n\n.session-container .session-item .session-name {\n overflow: hidden;\n flex: 1 1 100%;\n line-height: 1.2;\n}\n\n.session-container .session-status {\n margin-right: 5px;\n margin-top: 3px;\n}\n\n.session-container.horizontal .menu-column {\n display: flex !important;\n flex-direction: column;\n padding-right: 0px !important;\n}\n\n.session-container.horizontal .menu-column .menu {\n width: initial !important;\n overflow-y: auto;\n padding-top: 10px;\n flex: 1;\n}\n\n.session-container.horizontal .menu-column .session-item span.session-name,\n.session-container .session-header .ui.dropdown .caption {\n overflow: hidden;\n white-space: nowrap;\n}\n\n.session-container .session-header .title .ui.dropdown {\n width: 100%;\n}\n\n.session-layout .sub.header {\n overflow: hidden;\n}\n\n.session-layout .sub.header img {\n vertical-align: text-top;\n}\n\n.session-footer .info-grid {\n margin-top: 7px !important;\n font-size: small;\n color: grey;\n display: flex;\n flex: 1;\n align-items: flex-end;\n}\n\n.session-footer .info-grid > div {\n flex: 1;\n}\n\n.session-footer .info-grid > div:last-child > div {\n float: right;\n}\n\n.session-footer .info-grid > div:only-child > div {\n float: inherit;\n}\n\n.session-footer .ui.checkbox {\n min-height: inherit !important;\n}\n\n.session-footer .divider {\n margin-top: 8px;\n margin-bottom: 0px;\n}\n\n/* New session layout */\n.session.new {\n flex: 100 100 0%;\n display: flex;\n flex-direction: column;\n overflow-y: hidden;\n margin-top: 20px;\n padding: 1px;\n}\n\n.session.new .recents {\n flex: 100 100 0%;\n display: flex;\n flex-direction: column;\n margin-top: 20px;\n overflow-y: hidden;\n}\n\n.session.new .recents .list {\n padding: 3px 5px;\n flex: 100 100 0%;\n overflow-y: auto;\n overflow-x: hidden;\n}\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Sidebar/sessions.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,uBAAuB;AACzB;;AAEA;EACE,sBAAsB;AACxB;;AAEA;EACE,sCAAsC;AACxC;;AAEA;EACE,qCAAqC;AACvC;;AAEA;EACE,uBAAuB;AACzB;;AAEA;EACE,aAAa;EACb,aAAa;EACb,sBAAsB;AACxB;AACA;EACE,kBAAkB;EAClB,aAAa;EACb,gBAAgB;AAClB;;AAEA;EACE,sBAAsB;AACxB;;AAEA;EACE,8BAA8B;EAC9B,sBAAsB;AACxB;;AAEA;EACE,WAAW;AACb;;AAEA;EACE,2BAA2B;AAC7B;;AAEA;EACE,2BAA2B;AAC7B;;AAEA;EACE,WAAW;AACb;;AAEA;EACE,+BAA+B;EAC/B,gBAAgB;EAChB,kBAAkB;EAClB,6BAA6B;AAC/B;;AAEA;EACE,2BAA2B;AAC7B;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,YAAY;AACd;;AAEA;EACE,cAAc,EAAE,2GAA2G;EAC3H,iCAAiC;EACjC,gBAAgB;AAClB;;AAEA;EACE,2BAA2B;AAC7B;;AAEA;EACE,iBAAiB;AACnB;;AAEA;EACE,eAAe;AACjB;;AAEA,oEAAoE;AACpE;;EAEE,yBAAyB;EACzB,gBAAgB;AAClB;;AAEA;EACE,mBAAmB;AACrB;;AAEA;EACE,6BAA6B;EAC7B,mBAAmB;AACrB;;AAEA;;;EAGE,YAAY;AACd;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,gBAAgB;EAChB,wBAAwB;EACxB,mBAAmB;EACnB,6CAA6C;EAC7C,YAAY;AACd;;AAEA;EACE,sBAAsB;EACtB,8BAA8B;AAChC;;AAEA;EACE,gBAAgB;EAChB,cAAc;EACd,gBAAgB;AAClB;;AAEA;EACE,iBAAiB;EACjB,eAAe;AACjB;;AAEA;EACE,wBAAwB;EACxB,sBAAsB;EACtB,6BAA6B;AAC/B;;AAEA;EACE,yBAAyB;EACzB,gBAAgB;EAChB,iBAAiB;EACjB,OAAO;AACT;;AAEA;;EAEE,gBAAgB;EAChB,mBAAmB;AACrB;;AAEA;EACE,WAAW;AACb;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,wBAAwB;AAC1B;;AAEA;EACE,0BAA0B;EAC1B,gBAAgB;EAChB,WAAW;EACX,aAAa;EACb,OAAO;EACP,qBAAqB;AACvB;;AAEA;EACE,OAAO;AACT;;AAEA;EACE,YAAY;AACd;;AAEA;EACE,cAAc;AAChB;;AAEA;EACE,8BAA8B;AAChC;;AAEA;EACE,eAAe;EACf,kBAAkB;AACpB;;AAEA,uBAAuB;AACvB;EACE,gBAAgB;EAChB,aAAa;EACb,sBAAsB;EACtB,kBAAkB;EAClB,gBAAgB;EAChB,YAAY;AACd;;AAEA;EACE,gBAAgB;EAChB,aAAa;EACb,sBAAsB;EACtB,gBAAgB;EAChB,kBAAkB;AACpB;;AAEA;EACE,gBAAgB;EAChB,gBAAgB;EAChB,gBAAgB;EAChB,kBAAkB;AACpB\",\"sourcesContent\":[\".session-container {\\n background-color: white;\\n}\\n\\n.session-container.horizontal.ui.grid {\\n margin: 0px !important;\\n}\\n\\n.session-container.horizontal .menu-column .item.new {\\n padding: 0.78571429em 1.1em !important;\\n}\\n\\n.session-container.horizontal .ui.vertical.menu .item > i.icon {\\n margin: 0 0.35714286em 0 0 !important;\\n}\\n\\n.session-container.horizontal .session-layout > .ui.divider {\\n margin: 5px 0px 0px 0px;\\n}\\n\\n.session-container.vertical {\\n padding: 15px;\\n display: flex;\\n flex-direction: column;\\n}\\n.session-layout {\\n flex: 100 100 auto;\\n display: flex;\\n overflow: hidden;\\n}\\n\\n.session-container.horizontal .session-layout {\\n flex-direction: column;\\n}\\n\\n.session-container.vertical .menu-bar {\\n justify-content: space-between;\\n margin: 0px !important;\\n}\\n\\n.session-container.vertical .menu-bar .content-left {\\n width: 100%;\\n}\\n\\n.session-container.vertical .menu-bar .close-button.item:before {\\n background: none !important;\\n}\\n\\n.session-container.vertical .menu-bar .close-button.item {\\n box-shadow: none !important;\\n}\\n\\n.session-container.vertical .menu-bar .content-left > .ui.dropdown {\\n float: left;\\n}\\n\\n.session-container.vertical .menu-bar .content-left > .ui.dropdown .menu {\\n max-height: calc(100vh - 140px);\\n overflow-y: auto;\\n overflow-x: hidden;\\n max-width: calc(100vw - 30px);\\n}\\n\\n.session-container.vertical .session-item .count.label {\\n margin-left: 1em !important;\\n}\\n\\n.session-container.vertical .session-header {\\n display: flex;\\n align-items: center;\\n height: 100%;\\n}\\n\\n.session-container.vertical .session-header > div {\\n max-width: 90%; /* Hack, auto width won't work without \\\"overflow: hidden\\\", but that would prevent viewing the menu items */\\n padding: 0.82857143em 0.4285714em;\\n line-height: 1.2;\\n}\\n\\n.session-container.vertical .session-header > div:before {\\n background: none !important;\\n}\\n\\n.session-container.vertical .session-header > i {\\n margin-left: 10px;\\n}\\n\\n.session-container.vertical .session-header .ui.dropdown > i {\\n margin: 0px 5px;\\n}\\n\\n/* Fix a few inconsistencies between 'icon' and 'icons' classnames */\\n.session-container.horizontal .session-header .header > i,\\n.session-container.vertical .session-header > i {\\n width: inherit !important;\\n font-size: 1.5em;\\n}\\n\\n.session-container.horizontal .session-header .ui.header {\\n align-items: center;\\n}\\n\\n.session-container.vertical .menu-bar {\\n border-radius: 0px !important;\\n padding-bottom: 0px;\\n}\\n\\n.session-container,\\n.session-layout,\\n.session-container.horizontal .column {\\n height: 100%;\\n}\\n\\n.session-container.horizontal .column > div {\\n max-height: 100%;\\n}\\n\\n.session-container .session-item {\\n overflow: hidden;\\n display: flex !important;\\n align-items: center;\\n padding: 0.68571429em 0.92857143em !important;\\n height: 35px;\\n}\\n\\n.session-container .session-item .session-status {\\n float: none !important;\\n margin: 0 0.5em 0 0 !important;\\n}\\n\\n.session-container .session-item .session-name {\\n overflow: hidden;\\n flex: 1 1 100%;\\n line-height: 1.2;\\n}\\n\\n.session-container .session-status {\\n margin-right: 5px;\\n margin-top: 3px;\\n}\\n\\n.session-container.horizontal .menu-column {\\n display: flex !important;\\n flex-direction: column;\\n padding-right: 0px !important;\\n}\\n\\n.session-container.horizontal .menu-column .menu {\\n width: initial !important;\\n overflow-y: auto;\\n padding-top: 10px;\\n flex: 1;\\n}\\n\\n.session-container.horizontal .menu-column .session-item span.session-name,\\n.session-container .session-header .ui.dropdown .caption {\\n overflow: hidden;\\n white-space: nowrap;\\n}\\n\\n.session-container .session-header .title .ui.dropdown {\\n width: 100%;\\n}\\n\\n.session-layout .sub.header {\\n overflow: hidden;\\n}\\n\\n.session-layout .sub.header img {\\n vertical-align: text-top;\\n}\\n\\n.session-footer .info-grid {\\n margin-top: 7px !important;\\n font-size: small;\\n color: grey;\\n display: flex;\\n flex: 1;\\n align-items: flex-end;\\n}\\n\\n.session-footer .info-grid > div {\\n flex: 1;\\n}\\n\\n.session-footer .info-grid > div:last-child > div {\\n float: right;\\n}\\n\\n.session-footer .info-grid > div:only-child > div {\\n float: inherit;\\n}\\n\\n.session-footer .ui.checkbox {\\n min-height: inherit !important;\\n}\\n\\n.session-footer .divider {\\n margin-top: 8px;\\n margin-bottom: 0px;\\n}\\n\\n/* New session layout */\\n.session.new {\\n flex: 100 100 0%;\\n display: flex;\\n flex-direction: column;\\n overflow-y: hidden;\\n margin-top: 20px;\\n padding: 1px;\\n}\\n\\n.session.new .recents {\\n flex: 100 100 0%;\\n display: flex;\\n flex-direction: column;\\n margin-top: 20px;\\n overflow-y: hidden;\\n}\\n\\n.session.new .recents .list {\\n padding: 3px 5px;\\n flex: 100 100 0%;\\n overflow-y: auto;\\n overflow-x: hidden;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","import SocketService from 'services/SocketService';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\ntype SessionType = UI.SessionItemBase;\r\n\r\nexport const BuildRemoveSessionAction = (\r\n sessionsUrl: string,\r\n editAccess: API.AccessEnum,\r\n) => {\r\n const handleRemoveSession: UI.ActionHandler<SessionType> = ({ itemData: session }) => {\r\n return SocketService.delete(`${sessionsUrl}/${session.id}`);\r\n };\r\n\r\n const SessionRemoveAction = {\r\n id: 'remove',\r\n displayName: 'Close',\r\n access: editAccess,\r\n icon: IconConstants.REMOVE,\r\n handler: handleRemoveSession,\r\n };\r\n\r\n return SessionRemoveAction;\r\n};\r\n","//import PropTypes from 'prop-types';\r\nimport * as React from 'react';\r\n\r\nimport LocalSettingStore from 'stores/LocalSettingStore';\r\nimport { LocalSettings } from 'constants/SettingConstants';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { SessionChildProps } from 'routes/Sidebar/components/types';\r\n\r\ntype SessionType = UI.SessionItemBase;\r\n\r\ninterface ActiveSessionDecoratorProps<\r\n SessionT extends SessionType,\r\n ActionT extends object,\r\n> extends Pick<SessionChildProps<SessionT, ActionT>, 'session'> {\r\n sessionApi: UI.SessionActions<SessionT> & ActionT;\r\n //uiActions:\r\n //session: SessionT;\r\n}\r\n\r\n// This decorator will fire updates for currently active session\r\n// and set them as read\r\nexport default function <\r\n PropsT,\r\n SessionT extends SessionType,\r\n ActionT extends object = UI.EmptyObject,\r\n>(Component: React.ComponentType<PropsT>, useReadDelay = false) {\r\n class ActiveSessionDecorator extends React.Component<\r\n PropsT & ActiveSessionDecoratorProps<SessionT, ActionT>\r\n > {\r\n /*static propTypes = {\r\n session: PropTypes.any, // Required (cloned)\r\n actions: PropTypes.object, // Required (cloned)\r\n };*/\r\n\r\n readTimeout: number | undefined;\r\n\r\n setRead = (session: SessionT) => {\r\n this.props.sessionApi.setRead(session);\r\n this.readTimeout = undefined;\r\n };\r\n\r\n setSession = (session: SessionT | null) => {\r\n if (this.readTimeout) {\r\n // Set the previously active session as read\r\n clearTimeout(this.readTimeout);\r\n this.setRead(this.props.session);\r\n }\r\n\r\n this.props.sessionApi.sessionChanged(session);\r\n if (!session) {\r\n return;\r\n }\r\n\r\n const timeout = !useReadDelay\r\n ? 0\r\n : LocalSettingStore.getValue<number>(LocalSettings.UNREAD_LABEL_DELAY) * 1000;\r\n this.readTimeout = window.setTimeout(() => this.setRead(session), timeout);\r\n };\r\n\r\n componentDidMount() {\r\n this.setSession(this.props.session);\r\n }\r\n\r\n componentWillUnmount() {\r\n this.setSession(null);\r\n }\r\n\r\n componentDidUpdate(prevProps: ActiveSessionDecoratorProps<SessionT, ActionT>) {\r\n if (this.props.session.id !== prevProps.session.id) {\r\n this.setSession(this.props.session);\r\n }\r\n }\r\n\r\n render() {\r\n return <Component {...this.props} />;\r\n }\r\n }\r\n\r\n return ActiveSessionDecorator;\r\n}\r\n","import * as React from 'react';\n\nimport * as UI from 'types/ui';\n\ninterface FooterItemProps {\n label?: string;\n text: string | React.ReactElement<any>;\n}\n\nexport const FooterItem: React.FC<FooterItemProps> = ({ label, text }) => (\n <div className=\"grid-item\">\n <div className=\"item-inner\">\n {!!label && typeof text === 'string' ? `${label}: ${text}` : text}\n </div>\n </div>\n);\n\nexport const SessionFooter: React.FC<UI.PropsWithChildren> = ({ children }) => (\n <div className=\"session-footer\">\n <div className=\"ui footer divider\" />\n <div className=\"info-grid ui\">{children}</div>\n </div>\n);\n","//import PropTypes from 'prop-types';\r\nimport * as React from 'react';\r\nimport { useMobileLayout } from 'utils/BrowserUtils';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport SectionedDropdown from 'components/semantic/SectionedDropdown';\r\nimport MenuSection from 'components/semantic/MenuSection';\r\nimport { MenuIcon } from 'components/icon/MenuIcon';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { translate } from 'utils/TranslationUtils';\r\nimport IconConstants from 'constants/IconConstants';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { SessionMainLayoutProps } from './types';\r\n\r\ntype SessionDropdownProps<SessionT extends UI.SessionItemBase> = Pick<\r\n SessionMainLayoutProps<SessionT>,\r\n 'sessionMenuItems' | 'newButton' | 'unreadInfoStore' | 'listActionMenuGetter'\r\n>;\r\n\r\nconst SessionDropdown = <SessionT extends UI.SessionItemBase>({\r\n sessionMenuItems,\r\n newButton,\r\n unreadInfoStore,\r\n listActionMenuGetter,\r\n}: SessionDropdownProps<SessionT>) => {\r\n const { t } = useTranslation();\r\n return (\r\n <SectionedDropdown\r\n triggerIcon={\r\n <MenuIcon\r\n urgencies={unreadInfoStore ? unreadInfoStore.getTotalUrgencies() : null}\r\n />\r\n }\r\n >\r\n <MenuSection caption={translate('New', t, UI.Modules.COMMON)}>\r\n {newButton}\r\n </MenuSection>\r\n <MenuSection caption={translate('Current sessions', t, UI.Modules.COMMON)}>\r\n {sessionMenuItems}\r\n </MenuSection>\r\n <MenuSection>{listActionMenuGetter()}</MenuSection>\r\n </SectionedDropdown>\r\n );\r\n};\r\n\r\ntype CloseButtonProps<\r\n SessionT extends UI.SessionItemBase,\r\n UIActionsT extends UI.ActionListType<UI.SessionItemBase>,\r\n> = Pick<\r\n SessionMainLayoutProps<SessionT, UI.EmptyObject, UIActionsT>,\r\n 'actions' | 'activeItem'\r\n>;\r\n\r\nconst CloseButton = <\r\n SessionT extends UI.SessionItemBase,\r\n UIActionsT extends UI.ActionListType<UI.SessionItemBase>,\r\n>({\r\n actions,\r\n activeItem,\r\n}: CloseButtonProps<SessionT, UIActionsT>) => {\r\n if (!activeItem || useMobileLayout()) {\r\n return null;\r\n }\r\n\r\n /*const closeAction = Object.values(actions.actions).find(\r\n (action) => !!action && action.id === 'remove',\r\n ) as UI.ActionDefinition<UI.SessionItemBase>;*/\r\n\r\n const closeAction = Object.values(actions.actions)[\r\n Object.values(actions.actions).length - 1\r\n ];\r\n return (\r\n <ActionButton\r\n className=\"basic small item close-button\"\r\n action={closeAction as UI.ActionDefinition<UI.SessionItemBase>}\r\n moduleData={actions.moduleData}\r\n itemData={activeItem}\r\n icon={IconConstants.CLOSE}\r\n />\r\n );\r\n};\r\n\r\ntype SessionItemHeaderProps = Pick<\r\n SessionMainLayoutProps<any>,\r\n 'itemHeaderIcon' | 'itemHeaderTitle'\r\n>;\r\n\r\nconst SessionItemHeader: React.FC<SessionItemHeaderProps> = ({\r\n itemHeaderIcon,\r\n itemHeaderTitle,\r\n}) => (\r\n <div className=\"session-header\">\r\n {itemHeaderIcon}\r\n {itemHeaderTitle}\r\n </div>\r\n);\r\n\r\nconst TopMenuLayout = <\r\n SessionT extends UI.SessionItemBase,\r\n SessionApiT extends object,\r\n UIActionsT extends UI.ActionListType<UI.SessionItemBase>,\r\n>({\r\n children,\r\n onKeyDown,\r\n ...props\r\n}: SessionMainLayoutProps<SessionT, SessionApiT, UIActionsT>) => (\r\n <div className=\"session-container vertical\" onKeyDown={onKeyDown} tabIndex={0}>\r\n <div className=\"ui main menu menu-bar\">\r\n <div className=\"content-left\">\r\n <SessionDropdown {...props} />\r\n <SessionItemHeader {...props} />\r\n </div>\r\n <CloseButton {...props} />\r\n </div>\r\n\r\n <div className=\"session-layout\">{children}</div>\r\n </div>\r\n);\r\n\r\n/*TopMenuLayout.propTypes = {\r\n itemHeaderTitle: PropTypes.node.isRequired,\r\n itemHeaderIcon: PropTypes.node.isRequired,\r\n activeItem: PropTypes.object,\r\n newButton: PropTypes.node,\r\n sessionMenuItems: PropTypes.array.isRequired,\r\n closeAction: PropTypes.func.isRequired,\r\n listActionMenuGetter: PropTypes.func.isRequired,\r\n};*/\r\n\r\nexport default TopMenuLayout;\r\n","//import PropTypes from 'prop-types';\r\nimport * as React from 'react';\r\n\r\nimport LayoutHeader from 'components/semantic/LayoutHeader';\r\nimport { Grid } from 'components/semantic/Grid';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { SessionMainLayoutProps } from './types';\r\n\r\nconst SideMenuLayout = <\r\n SessionT extends UI.SessionItemBase,\r\n SessionApiT extends object,\r\n UIActionsT extends UI.ActionListType<UI.SessionItemBase>,\r\n>({\r\n sessionMenuItems,\r\n newButton,\r\n itemHeaderIcon,\r\n itemHeaderTitle,\r\n children,\r\n itemHeaderDescription,\r\n onKeyDown,\r\n}: SessionMainLayoutProps<SessionT, SessionApiT, UIActionsT>) => {\r\n if (newButton) {\r\n newButton = React.cloneElement(newButton, {\r\n className: newButton.props.className + ' ui fluid button',\r\n });\r\n }\r\n\r\n return (\r\n <Grid className=\"session-container horizontal\" onKeyDown={onKeyDown} tabIndex={0}>\r\n <div className=\"four wide column menu-column\">\r\n {newButton}\r\n {!!sessionMenuItems.length && (\r\n <div className=\"ui vertical secondary menu\">{sessionMenuItems}</div>\r\n )}\r\n </div>\r\n <div className=\"twelve wide stretched column content-column session\">\r\n <div className=\"ui segment session-layout\">\r\n <LayoutHeader\r\n className=\"session-header\"\r\n icon={itemHeaderIcon}\r\n title={<div className=\"title\">{itemHeaderTitle}</div>}\r\n subHeader={itemHeaderDescription}\r\n />\r\n <div className=\"ui divider\" style={{ margin: '5px 0px 0px 0px' }} />\r\n {children}\r\n </div>\r\n </div>\r\n </Grid>\r\n );\r\n};\r\n\r\n/*SideMenuLayout.propTypes = {\r\n newButton: PropTypes.node,\r\n sessionMenuItems: PropTypes.array.isRequired,\r\n\r\n itemHeaderTitle: PropTypes.node,\r\n itemHeaderIcon: PropTypes.node,\r\n itemHeaderDescription: PropTypes.node.isRequired,\r\n};*/\r\n\r\nexport default SideMenuLayout;\r\n","import invariant from 'invariant';\r\n\r\nimport * as API from 'types/api';\r\n\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { SessionLocationState } from '../types';\r\n\r\ninterface SessionRouteHelperProps {\r\n baseUrl: string;\r\n}\r\n\r\nexport const useSessionRouteHelpers = ({ baseUrl }: SessionRouteHelperProps) => {\r\n const navigate = useNavigate();\r\n\r\n // HELPERS\r\n const getSessionUrl = (id: API.IdType) => {\r\n invariant(!!id, 'Trying to get session URL without a session');\r\n return `/${baseUrl}/session/${id}`;\r\n };\r\n\r\n const pushSession = (id: API.IdType) => {\r\n navigate(getSessionUrl(id));\r\n };\r\n\r\n const replaceSession = (id: API.IdType, state?: SessionLocationState) => {\r\n navigate(getSessionUrl(id), { replace: true, state });\r\n };\r\n\r\n const newUrl = `/${baseUrl}/new`;\r\n const replaceNew = () => {\r\n // const { navigate } = props;\r\n navigate(newUrl, { replace: true });\r\n };\r\n\r\n return {\r\n newUrl: `/${baseUrl}/new`,\r\n replaceNew,\r\n\r\n getSessionUrl,\r\n pushSession,\r\n replaceSession,\r\n };\r\n};\r\n","import * as React from 'react';\r\n\r\nimport { loadLocalProperty, saveLocalProperty } from 'utils/BrowserUtils';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { useLocation } from 'react-router-dom';\r\nimport { useSessionRouteHelpers } from './useSessionHelpers';\r\nimport { SessionLocationState } from '../types';\r\n\r\nconst findItem = <SessionT extends UI.SessionItemBase>(\r\n items: SessionT[],\r\n id: API.IdType | undefined,\r\n): SessionT | undefined => {\r\n return items.find((item) => item.id === id);\r\n};\r\n\r\nexport interface SessionManagerProps<\r\n SessionT extends UI.SessionItemBase,\r\n SessionApiT extends object = UI.EmptyObject,\r\n> {\r\n // Item ID that is currently active (if any)\r\n activeId: API.IdType | undefined;\r\n\r\n // Array of the items to list\r\n items: SessionT[];\r\n\r\n baseUrl: string;\r\n\r\n sessionApi: UI.SessionActions<SessionT> & SessionApiT;\r\n}\r\n\r\nexport const useSessionManager = <\r\n SessionT extends UI.SessionItemBase,\r\n SessionApiT extends object = UI.EmptyObject,\r\n>(\r\n props: SessionManagerProps<SessionT, SessionApiT>,\r\n) => {\r\n const [activeItem, setActiveItem] = React.useState<SessionT | null>(null);\r\n const location = useLocation();\r\n\r\n const { pushSession, replaceSession, newUrl, replaceNew } = useSessionRouteHelpers({\r\n baseUrl: props.baseUrl,\r\n });\r\n\r\n // HELPERS\r\n const getStorageKey = () => {\r\n return `${props.baseUrl}_last_active`;\r\n };\r\n\r\n // Common logic for selecting the item to display (after mounting or session updates)\r\n // Returns true active item selection was handled\r\n // Returns false if the active item couldn't be selected but there are valid items to choose from by the caller\r\n const checkActiveItem = () => {\r\n // Did we just create this session?\r\n const routerLocation = location;\r\n const pending =\r\n routerLocation.state && (routerLocation.state as SessionLocationState).pending;\r\n\r\n // Update the active item\r\n const activeItemNew = findItem(props.items, props.activeId);\r\n if (activeItemNew) {\r\n if (pending) {\r\n // Disable pending state\r\n replaceSession(activeItemNew.id, {\r\n pending: false,\r\n });\r\n\r\n return true;\r\n }\r\n\r\n setActiveItem(activeItemNew);\r\n saveLocalProperty(getStorageKey(), props.activeId);\r\n return true;\r\n } else if (pending) {\r\n // We'll just display a loading indicator in 'render', no item needed\r\n return true;\r\n } else if (/*routerLocation.action === 'POP' ||*/ props.items.length === 0) {\r\n // Browsing from history and item removed (or all items removed)... go to \"new session\" page\r\n replaceNew();\r\n setActiveItem(null);\r\n return true;\r\n }\r\n\r\n return false;\r\n };\r\n\r\n // LIFECYCLE/REACT\r\n // Set the session early so that we wont' flash the \"new session\" layout\r\n React.useLayoutEffect(() => {\r\n if (location.pathname === newUrl) {\r\n // Don't redirect to it if the \"new session\" layout is open\r\n if (activeItem) {\r\n setActiveItem(null);\r\n }\r\n return;\r\n }\r\n\r\n if (checkActiveItem()) {\r\n // We got an item\r\n return;\r\n }\r\n\r\n if (!activeItem) {\r\n const lastId = loadLocalProperty<API.IdType>(getStorageKey());\r\n if (lastId && findItem(props.items, lastId)) {\r\n // Previous session exists\r\n replaceSession(lastId);\r\n return;\r\n }\r\n }\r\n\r\n // The old tab was closed or we didn't have any session before\r\n\r\n const { items, activeId } = props;\r\n let newItemPos = 0;\r\n const oldItem = findItem(items, activeId);\r\n if (oldItem) {\r\n // Find the old position and use the item in that position (if possible)\r\n newItemPos = items.indexOf(oldItem);\r\n if (newItemPos === items.length - 1) {\r\n // The last item was removed\r\n newItemPos = newItemPos - 1;\r\n }\r\n }\r\n\r\n replaceSession(items[newItemPos].id);\r\n }, [location, props.items]);\r\n\r\n const onKeyDown = (event: React.KeyboardEvent) => {\r\n const { key, altKey } = event;\r\n\r\n if (altKey && (key === 'ArrowUp' || key === 'ArrowDown')) {\r\n // Arrow up/down\r\n event.preventDefault();\r\n\r\n const { items, activeId } = props;\r\n const item = findItem(items, activeId);\r\n if (!item) {\r\n return;\r\n }\r\n\r\n const currentIndex = items.indexOf(item);\r\n if (currentIndex === -1) {\r\n return;\r\n }\r\n\r\n const newSession = items[key === 'ArrowUp' ? currentIndex - 1 : currentIndex + 1];\r\n if (newSession) {\r\n pushSession(newSession.id);\r\n }\r\n } else if (altKey && key === 'Insert') {\r\n // Insert\r\n event.preventDefault();\r\n\r\n replaceNew();\r\n } else if (altKey && key === 'Delete') {\r\n // Delete\r\n event.preventDefault();\r\n\r\n const { items, activeId, sessionApi } = props;\r\n const item = findItem(items, activeId);\r\n if (!!item) {\r\n sessionApi.removeSession(item);\r\n }\r\n }\r\n };\r\n\r\n return {\r\n onKeyDown,\r\n activeItem,\r\n };\r\n};\r\n","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!./sessions.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\noptions.insert = insertFn.bind(null, \"head\");\noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!./sessions.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as React from 'react';\r\nimport classNames from 'classnames';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\nimport RouterMenuItemLink from 'components/semantic/RouterMenuItemLink';\r\n\r\ninterface SessionNewButtonProps {\r\n url: string;\r\n title: React.ReactNode;\r\n className?: string;\r\n}\r\n\r\nconst SessionNewButton: React.FC<SessionNewButtonProps> = ({\r\n url,\r\n title,\r\n // pushNew,\r\n className,\r\n}) => (\r\n <RouterMenuItemLink\r\n key=\"button-new\"\r\n className={classNames('new', className)}\r\n icon={IconConstants.CREATE}\r\n url={url}\r\n >\r\n {title}\r\n </RouterMenuItemLink>\r\n);\r\n\r\nexport default SessionNewButton;\r\n","//import PropTypes from 'prop-types';\r\nimport * as React from 'react';\r\n\r\nimport RouterMenuItemLink from 'components/semantic/RouterMenuItemLink';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\ninterface SessionMenuItemProps {\r\n url: string;\r\n name: React.ReactNode;\r\n unreadInfoStore: UI.UnreadInfoStore;\r\n status: React.ReactElement<any>;\r\n sessionItem: UI.SessionItemBase;\r\n}\r\n\r\nconst SessionMenuItem: React.FC<SessionMenuItemProps> = ({\r\n sessionItem,\r\n status,\r\n name,\r\n unreadInfoStore,\r\n url,\r\n}) => (\r\n <RouterMenuItemLink\r\n url={url}\r\n className=\"session-item\"\r\n icon={status}\r\n session={sessionItem}\r\n unreadInfoStore={unreadInfoStore}\r\n >\r\n <span className=\"session-name\">{name}</span>\r\n </RouterMenuItemLink>\r\n);\r\n\r\n/*SessionMenuItem.propTypes = {\r\n // Item URL\r\n url: PropTypes.string.isRequired,\r\n\r\n name: PropTypes.node.isRequired,\r\n\r\n unreadInfoStore: PropTypes.object.isRequired,\r\n\r\n status: PropTypes.node.isRequired,\r\n\r\n sessionItem: PropTypes.object.isRequired,\r\n\r\n pushSession: PropTypes.func.isRequired,\r\n};*/\r\n\r\nexport default SessionMenuItem;\r\n","import { ActionMenu } from 'components/action-menu';\r\nimport SessionNewButton from './SessionNewButton';\r\nimport SessionMenuItem from './SessionMenuItem';\r\n\r\nimport Icon from 'components/semantic/Icon';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\nimport MenuItemLink from 'components/semantic/MenuItemLink';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\nimport { translate } from 'utils/TranslationUtils';\r\nimport { SessionLayoutLabels, SessionLayoutManageProps } from './types';\r\nimport { useLocation } from 'react-router-dom';\r\nimport { useSessionRouteHelpers } from './effects/useSessionHelpers';\r\nimport { useTranslation } from 'react-i18next';\r\n\r\nexport const useComponents = <\r\n SessionT extends UI.SessionItemBase,\r\n SessionApiT extends object = UI.EmptyObject,\r\n UIActionT extends UI.ActionListType<UI.SessionItemBase> = UI.EmptyObject,\r\n>(\r\n props: UI.SessionInfoGetter<SessionT> & {\r\n activeItem: SessionT | null;\r\n hasEditAccess: boolean;\r\n } & SessionLayoutLabels &\r\n SessionLayoutManageProps<SessionT, SessionApiT, UIActionT>,\r\n) => {\r\n const location = useLocation();\r\n const { t } = useTranslation();\r\n const { newUrl, getSessionUrl } = useSessionRouteHelpers({\r\n baseUrl: props.baseUrl,\r\n });\r\n\r\n // COMPONENT GETTERS\r\n const getItemStatus = (sessionItem: SessionT) => {\r\n const { itemStatusGetter, itemHeaderIconGetter } = props;\r\n if (itemStatusGetter) {\r\n return (\r\n <div\r\n className={\r\n 'ui session-status empty circular left mini label ' +\r\n itemStatusGetter(sessionItem)\r\n }\r\n />\r\n );\r\n }\r\n\r\n return <Icon icon={itemHeaderIconGetter(sessionItem)} />;\r\n };\r\n\r\n const components = {\r\n getItemHeaderDescription: () => {\r\n const { itemHeaderDescriptionGetter, newDescription, activeItem } = props;\r\n if (!activeItem) {\r\n return newDescription;\r\n }\r\n\r\n return itemHeaderDescriptionGetter(activeItem);\r\n },\r\n getItemHeaderIcon: () => {\r\n const { itemHeaderIconGetter, newIcon, activeItem } = props;\r\n return <Icon icon={activeItem ? itemHeaderIconGetter(activeItem) : newIcon} />;\r\n },\r\n getItemHeaderTitle: () => {\r\n const { activeItem, newCaption } = props;\r\n if (!activeItem) {\r\n return <div>{newCaption}</div>;\r\n }\r\n\r\n const { uiActions, actionIds, itemNameGetter, itemHeaderTitleGetter } = props;\r\n\r\n const ids = actionIds ? [...actionIds, 'divider', 'remove'] : undefined;\r\n const actionMenu = (\r\n <ActionMenu\r\n caption={itemNameGetter(activeItem)}\r\n actions={uiActions}\r\n itemData={activeItem}\r\n ids={ids}\r\n />\r\n );\r\n\r\n // Use the header getter only if there is a getter that returns a valid value\r\n if (itemHeaderTitleGetter) {\r\n const header = itemHeaderTitleGetter(activeItem, location, actionMenu);\r\n if (header) {\r\n return header;\r\n }\r\n }\r\n\r\n return actionMenu;\r\n },\r\n getSessionActionMenuItems: () => {\r\n const { items, hasEditAccess } = props;\r\n if (!hasEditAccess || items.length === 0) {\r\n return null;\r\n }\r\n\r\n const handleCloseAll = () => {\r\n const { sessionApi, items } = props;\r\n items.forEach((session) => sessionApi.removeSession(session));\r\n };\r\n\r\n return (\r\n <MenuItemLink key=\"close\" onClick={handleCloseAll} icon={IconConstants.REMOVE}>\r\n {translate('Close all', t, UI.Modules.COMMON)}\r\n </MenuItemLink>\r\n );\r\n },\r\n getNewButton: () => {\r\n const { newCaption, hasEditAccess } = props;\r\n if (!hasEditAccess || !newCaption) {\r\n return null;\r\n }\r\n\r\n return <SessionNewButton key=\"new-button\" title={newCaption} url={newUrl} />;\r\n },\r\n getSessionMenuItems: () => {\r\n const getSessionMenuItem = (sessionItem: SessionT) => {\r\n const { itemNameGetter, unreadInfoStore } = props;\r\n return (\r\n <SessionMenuItem\r\n key={sessionItem.id}\r\n url={getSessionUrl(sessionItem.id)}\r\n name={itemNameGetter(sessionItem)}\r\n unreadInfoStore={unreadInfoStore}\r\n status={getItemStatus(sessionItem)}\r\n sessionItem={sessionItem}\r\n />\r\n );\r\n };\r\n\r\n return props.items.map(getSessionMenuItem);\r\n },\r\n };\r\n\r\n return components;\r\n};\r\n","import * as React from 'react';\r\n\r\nimport Loader from 'components/semantic/Loader';\r\n\r\nimport TopMenuLayout from './TopMenuLayout';\r\nimport SideMenuLayout from './SideMenuLayout';\r\n\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport LoginStore from 'stores/LoginStore';\r\nimport { useMobileLayout } from 'utils/BrowserUtils';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { translate, toI18nKey } from 'utils/TranslationUtils';\r\nimport { useLayoutWidth } from 'context/LayoutWidthContext';\r\nimport { useSessionManager } from './effects/useSessionManager';\r\nimport { useLocation, useNavigate } from 'react-router';\r\n\r\nimport '../sessions.css';\r\nimport {\r\n NewSessionLayoutProps,\r\n SessionChildProps,\r\n SessionLayoutLabels,\r\n SessionLayoutManageProps,\r\n SessionLocationState,\r\n} from './types';\r\nimport { useComponents } from './SessionMenuComponents';\r\n\r\nexport interface SessionLayoutProps<\r\n SessionT extends UI.SessionItemBase,\r\n SessionApiT extends object = UI.EmptyObject,\r\n UIActionT extends UI.ActionListType<UI.SessionItemBase> = UI.EmptyObject,\r\n> extends UI.SessionInfoGetter<SessionT>,\r\n SessionLayoutLabels,\r\n SessionLayoutManageProps<SessionT, SessionApiT, UIActionT> {\r\n // Item ID that is currently active (if any)\r\n activeId: API.IdType | undefined;\r\n\r\n // Set to false if the side menu should never be shown (the session will use all width that is available)\r\n disableSideMenu?: boolean;\r\n\r\n sessionItemLayout: React.ComponentType<\r\n SessionChildProps<SessionT, SessionApiT, UIActionT>\r\n >;\r\n\r\n newLayout?: React.ComponentType<NewSessionLayoutProps>;\r\n\r\n sessionT: UI.ModuleTranslator;\r\n}\r\n\r\nconst SessionLayout = <\r\n SessionT extends UI.SessionItemBase,\r\n SessionApiT extends object,\r\n UIActionsT extends UI.ActionListType<UI.SessionItemBase>,\r\n>(\r\n props: SessionLayoutProps<SessionT, SessionApiT, UIActionsT>,\r\n) => {\r\n const layoutWidth = useLayoutWidth();\r\n const navigate = useNavigate();\r\n const location = useLocation();\r\n\r\n const { activeItem, onKeyDown } = useSessionManager(props);\r\n\r\n const hasEditAccess = LoginStore.hasAccess(props.editAccess);\r\n\r\n const getSessionChildren = () => {\r\n const {\r\n activeId,\r\n items,\r\n sessionItemLayout: SessionItemLayout,\r\n sessionApi,\r\n uiActions,\r\n sessionT,\r\n } = props;\r\n\r\n if (!activeItem) {\r\n const { state } = location;\r\n if (!!state && (state as SessionLocationState).pending) {\r\n // The session was just created\r\n return (\r\n <Loader\r\n text={translate(\r\n 'Waiting for server response',\r\n sessionT.plainT,\r\n UI.Modules.COMMON,\r\n )}\r\n />\r\n );\r\n } else if (activeId || items.length !== 0) {\r\n // Redirecting to a new page\r\n return (\r\n <Loader\r\n text={translate('Loading session', sessionT.plainT, UI.Modules.COMMON)}\r\n />\r\n );\r\n }\r\n\r\n console.error('SessionLayout route: active session missing');\r\n return;\r\n }\r\n\r\n // We have a session\r\n return (\r\n <SessionItemLayout\r\n session={activeItem}\r\n sessionApi={sessionApi}\r\n uiActions={uiActions}\r\n location={location}\r\n navigate={navigate}\r\n sessionT={sessionT}\r\n />\r\n );\r\n };\r\n\r\n const getChildren = () => {\r\n const { newLayout: NewLayout, sessionT } = props;\r\n if (!props.activeId && NewLayout) {\r\n return <NewLayout navigate={navigate} location={location} sessionT={sessionT} />;\r\n }\r\n\r\n return getSessionChildren();\r\n };\r\n\r\n const { disableSideMenu, items, unreadInfoStore, sessionT, uiActions } = props;\r\n\r\n if (!hasEditAccess && items.length === 0) {\r\n // Nothing to show\r\n return (\r\n <Message\r\n title={translate('No items to show', sessionT.plainT, UI.Modules.COMMON)}\r\n description={sessionT.plainT<string>(\r\n toI18nKey('noSessionEditAccess', UI.Modules.COMMON),\r\n `You aren't allowed to open new sessions`,\r\n )}\r\n />\r\n );\r\n }\r\n\r\n const useTopMenu = disableSideMenu || useMobileLayout(layoutWidth);\r\n\r\n const MenuLayout = useTopMenu ? TopMenuLayout : SideMenuLayout;\r\n const {\r\n getItemHeaderTitle,\r\n getItemHeaderDescription,\r\n getItemHeaderIcon,\r\n getNewButton,\r\n getSessionMenuItems,\r\n getSessionActionMenuItems,\r\n } = useComponents({ ...props, activeItem, hasEditAccess });\r\n return (\r\n <MenuLayout\r\n itemHeaderTitle={getItemHeaderTitle()}\r\n itemHeaderDescription={getItemHeaderDescription()}\r\n itemHeaderIcon={getItemHeaderIcon()}\r\n newButton={getNewButton()}\r\n sessionMenuItems={getSessionMenuItems()}\r\n listActionMenuGetter={getSessionActionMenuItems}\r\n activeItem={activeItem}\r\n unreadInfoStore={unreadInfoStore}\r\n onKeyDown={onKeyDown}\r\n actions={uiActions}\r\n >\r\n {getChildren()}\r\n </MenuLayout>\r\n );\r\n};\r\n\r\nexport default SessionLayout;\r\n","import * as React from 'react';\r\n\r\nimport Loader from 'components/semantic/Loader';\r\nimport { useStore } from 'effects/StoreListenerEffect';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\nimport { useTranslation } from 'react-i18next';\r\nimport { getModuleT, translate } from 'utils/TranslationUtils';\r\nimport { useParams } from 'react-router-dom';\r\n\r\nexport interface SessionProviderDecoratorProps {}\r\n\r\nexport interface SessionProviderDecoratorChildProps<SessionT extends UI.SessionType> {\r\n items: SessionT[];\r\n sessionT: UI.ModuleTranslator;\r\n params: UI.RouteParams;\r\n}\r\n\r\nconst SessionProviderDecorator = <SessionT extends UI.SessionType>(\r\n Component: React.ComponentType<SessionProviderDecoratorChildProps<SessionT>>,\r\n store: UI.SessionStore<SessionT>,\r\n moduleId: UI.Modules,\r\n) => {\r\n const Decorator = (props: SessionProviderDecoratorProps) => {\r\n const { t } = useTranslation();\r\n const sessionT = getModuleT(t, moduleId);\r\n const params = useParams();\r\n const sessions = useStore<SessionT[]>(store);\r\n if (!store.isInitialized()) {\r\n return <Loader text={translate('Loading sessions', t, UI.Modules.COMMON)} />;\r\n }\r\n\r\n return <Component items={sessions} params={params} sessionT={sessionT} />;\r\n };\r\n\r\n return Decorator;\r\n};\r\n\r\nexport { SessionProviderDecorator };\r\n"],"names":["___CSS_LOADER_EXPORT___","push","module","id","BuildRemoveSessionAction","sessionsUrl","editAccess","displayName","access","icon","REMOVE","handler","itemData","session","delete","Component","useReadDelay","ActiveSessionDecorator","setRead","this","props","sessionApi","readTimeout","undefined","setSession","clearTimeout","sessionChanged","timeout","getValue","UNREAD_LABEL_DELAY","window","setTimeout","componentDidMount","componentWillUnmount","componentDidUpdate","prevProps","render","FooterItem","label","text","className","SessionFooter","children","SessionDropdown","sessionMenuItems","newButton","unreadInfoStore","listActionMenuGetter","t","SectionedDropdown","triggerIcon","MenuIcon","urgencies","getTotalUrgencies","MenuSection","caption","COMMON","CloseButton","actions","activeItem","closeAction","Object","values","length","ActionButton","A","action","moduleData","IconConstants","CLOSE","SessionItemHeader","itemHeaderIcon","itemHeaderTitle","onKeyDown","tabIndex","itemHeaderDescription","Grid","LayoutHeader","title","subHeader","style","margin","useSessionRouteHelpers","baseUrl","navigate","getSessionUrl","newUrl","replaceNew","replace","pushSession","replaceSession","state","findItem","items","find","item","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","locals","url","RouterMenuItemLink","CREATE","sessionItem","status","name","layoutWidth","location","setActiveItem","getStorageKey","pathname","routerLocation","pending","activeItemNew","activeId","checkActiveItem","lastId","newItemPos","oldItem","indexOf","event","key","altKey","preventDefault","removeSession","currentIndex","newSession","useSessionManager","hasEditAccess","LoginStore","hasAccess","disableSideMenu","sessionT","uiActions","Message","plainT","description","MenuLayout","getItemHeaderTitle","getItemHeaderDescription","getItemHeaderIcon","getNewButton","getSessionMenuItems","getSessionActionMenuItems","getItemStatus","itemStatusGetter","itemHeaderIconGetter","Icon","itemHeaderDescriptionGetter","newDescription","newIcon","newCaption","actionIds","itemNameGetter","itemHeaderTitleGetter","ids","actionMenu","header","MenuItemLink","onClick","forEach","map","useComponents","newLayout","NewLayout","sessionItemLayout","SessionItemLayout","Loader","console","error","getSessionChildren","getChildren","SessionProviderDecorator","store","moduleId","params","sessions","isInitialized"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"js/616.57a60c241582d79fa280.chunk.js","mappings":"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","sources":["webpack://airdcpp-webui/./src/routes/Sidebar/sessions.css","webpack://airdcpp-webui/./src/actions/ui/decorators/SessionActionDecorator.ts","webpack://airdcpp-webui/./src/decorators/ActiveSessionDecorator.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/components/SessionFooter.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/components/TopMenuLayout.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/components/SideMenuLayout.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/components/effects/useSessionHelpers.ts","webpack://airdcpp-webui/./src/routes/Sidebar/components/effects/useSessionManager.ts","webpack://airdcpp-webui/./src/routes/Sidebar/sessions.css?90b7","webpack://airdcpp-webui/./src/routes/Sidebar/components/SessionNewButton.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/components/SessionMenuItem.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/components/SessionMenuComponents.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/components/SessionLayout.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/decorators/SessionProviderDecorator.tsx"],"sourcesContent":["// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.session-container {\n background-color: white;\n}\n\n.session-container.horizontal.ui.grid {\n margin: 0px !important;\n}\n\n.session-container.horizontal .menu-column .item.new {\n padding: 0.78571429em 1.1em !important;\n}\n\n.session-container.horizontal .ui.vertical.menu .item > i.icon {\n margin: 0 0.35714286em 0 0 !important;\n}\n\n.session-container.horizontal .session-layout > .ui.divider {\n margin: 5px 0px 0px 0px;\n}\n\n.session-container.vertical {\n padding: 15px;\n display: flex;\n flex-direction: column;\n}\n.session-layout {\n flex: 100 100 auto;\n display: flex;\n overflow: hidden;\n}\n\n.session-container.horizontal .session-layout {\n flex-direction: column;\n}\n\n.session-container.vertical .menu-bar {\n justify-content: space-between;\n margin: 0px !important;\n}\n\n.session-container.vertical .menu-bar .content-left {\n width: 100%;\n}\n\n.session-container.vertical .menu-bar .close-button.item:before {\n background: none !important;\n}\n\n.session-container.vertical .menu-bar .close-button.item {\n box-shadow: none !important;\n}\n\n.session-container.vertical .menu-bar .content-left > .ui.dropdown {\n float: left;\n}\n\n.session-container.vertical .menu-bar .content-left > .ui.dropdown .menu {\n max-height: calc(100vh - 140px);\n overflow-y: auto;\n overflow-x: hidden;\n max-width: calc(100vw - 30px);\n}\n\n.session-container.vertical .session-item .count.label {\n margin-left: 1em !important;\n}\n\n.session-container.vertical .session-header {\n display: flex;\n align-items: center;\n height: 100%;\n}\n\n.session-container.vertical .session-header > div {\n max-width: 90%; /* Hack, auto width won't work without \"overflow: hidden\", but that would prevent viewing the menu items */\n padding: 0.82857143em 0.4285714em;\n line-height: 1.2;\n}\n\n.session-container.vertical .session-header > div:before {\n background: none !important;\n}\n\n.session-container.vertical .session-header > i {\n margin-left: 10px;\n}\n\n.session-container.vertical .session-header .ui.dropdown > i {\n margin: 0px 5px;\n}\n\n/* Fix a few inconsistencies between 'icon' and 'icons' classnames */\n.session-container.horizontal .session-header .header > i,\n.session-container.vertical .session-header > i {\n width: inherit !important;\n font-size: 1.5em;\n}\n\n.session-container.horizontal .session-header .ui.header {\n align-items: center;\n}\n\n.session-container.vertical .menu-bar {\n border-radius: 0px !important;\n padding-bottom: 0px;\n}\n\n.session-container,\n.session-layout,\n.session-container.horizontal .column {\n height: 100%;\n}\n\n.session-container.horizontal .column > div {\n max-height: 100%;\n}\n\n.session-container .session-item {\n overflow: hidden;\n display: flex !important;\n align-items: center;\n padding: 0.68571429em 0.92857143em !important;\n height: 35px;\n}\n\n.session-container .session-item .session-status {\n float: none !important;\n margin: 0 0.5em 0 0 !important;\n}\n\n.session-container .session-item .session-name {\n overflow: hidden;\n flex: 1 1 100%;\n line-height: 1.2;\n}\n\n.session-container .session-status {\n margin-right: 5px;\n margin-top: 3px;\n}\n\n.session-container.horizontal .menu-column {\n display: flex !important;\n flex-direction: column;\n padding-right: 0px !important;\n}\n\n.session-container.horizontal .menu-column .menu {\n width: initial !important;\n overflow-y: auto;\n padding-top: 10px;\n flex: 1;\n}\n\n.session-container.horizontal .menu-column .session-item span.session-name,\n.session-container .session-header .ui.dropdown .caption {\n overflow: hidden;\n white-space: nowrap;\n}\n\n.session-container .session-header .title .ui.dropdown {\n width: 100%;\n}\n\n.session-layout .sub.header {\n overflow: hidden;\n}\n\n.session-layout .sub.header img {\n vertical-align: text-top;\n}\n\n.session-footer .info-grid {\n margin-top: 7px !important;\n font-size: small;\n color: grey;\n display: flex;\n flex: 1;\n align-items: flex-end;\n}\n\n.session-footer .info-grid > div {\n flex: 1;\n}\n\n.session-footer .info-grid > div:last-child > div {\n float: right;\n}\n\n.session-footer .info-grid > div:only-child > div {\n float: inherit;\n}\n\n.session-footer .ui.checkbox {\n min-height: inherit !important;\n}\n\n.session-footer .divider {\n margin-top: 8px;\n margin-bottom: 0px;\n}\n\n/* New session layout */\n.session.new {\n flex: 100 100 0%;\n display: flex;\n flex-direction: column;\n overflow-y: hidden;\n margin-top: 20px;\n padding: 1px;\n}\n\n.session.new .recents {\n flex: 100 100 0%;\n display: flex;\n flex-direction: column;\n margin-top: 20px;\n overflow-y: hidden;\n}\n\n.session.new .recents .list {\n padding: 3px 5px;\n flex: 100 100 0%;\n overflow-y: auto;\n overflow-x: hidden;\n}\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Sidebar/sessions.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,uBAAuB;AACzB;;AAEA;EACE,sBAAsB;AACxB;;AAEA;EACE,sCAAsC;AACxC;;AAEA;EACE,qCAAqC;AACvC;;AAEA;EACE,uBAAuB;AACzB;;AAEA;EACE,aAAa;EACb,aAAa;EACb,sBAAsB;AACxB;AACA;EACE,kBAAkB;EAClB,aAAa;EACb,gBAAgB;AAClB;;AAEA;EACE,sBAAsB;AACxB;;AAEA;EACE,8BAA8B;EAC9B,sBAAsB;AACxB;;AAEA;EACE,WAAW;AACb;;AAEA;EACE,2BAA2B;AAC7B;;AAEA;EACE,2BAA2B;AAC7B;;AAEA;EACE,WAAW;AACb;;AAEA;EACE,+BAA+B;EAC/B,gBAAgB;EAChB,kBAAkB;EAClB,6BAA6B;AAC/B;;AAEA;EACE,2BAA2B;AAC7B;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,YAAY;AACd;;AAEA;EACE,cAAc,EAAE,2GAA2G;EAC3H,iCAAiC;EACjC,gBAAgB;AAClB;;AAEA;EACE,2BAA2B;AAC7B;;AAEA;EACE,iBAAiB;AACnB;;AAEA;EACE,eAAe;AACjB;;AAEA,oEAAoE;AACpE;;EAEE,yBAAyB;EACzB,gBAAgB;AAClB;;AAEA;EACE,mBAAmB;AACrB;;AAEA;EACE,6BAA6B;EAC7B,mBAAmB;AACrB;;AAEA;;;EAGE,YAAY;AACd;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,gBAAgB;EAChB,wBAAwB;EACxB,mBAAmB;EACnB,6CAA6C;EAC7C,YAAY;AACd;;AAEA;EACE,sBAAsB;EACtB,8BAA8B;AAChC;;AAEA;EACE,gBAAgB;EAChB,cAAc;EACd,gBAAgB;AAClB;;AAEA;EACE,iBAAiB;EACjB,eAAe;AACjB;;AAEA;EACE,wBAAwB;EACxB,sBAAsB;EACtB,6BAA6B;AAC/B;;AAEA;EACE,yBAAyB;EACzB,gBAAgB;EAChB,iBAAiB;EACjB,OAAO;AACT;;AAEA;;EAEE,gBAAgB;EAChB,mBAAmB;AACrB;;AAEA;EACE,WAAW;AACb;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,wBAAwB;AAC1B;;AAEA;EACE,0BAA0B;EAC1B,gBAAgB;EAChB,WAAW;EACX,aAAa;EACb,OAAO;EACP,qBAAqB;AACvB;;AAEA;EACE,OAAO;AACT;;AAEA;EACE,YAAY;AACd;;AAEA;EACE,cAAc;AAChB;;AAEA;EACE,8BAA8B;AAChC;;AAEA;EACE,eAAe;EACf,kBAAkB;AACpB;;AAEA,uBAAuB;AACvB;EACE,gBAAgB;EAChB,aAAa;EACb,sBAAsB;EACtB,kBAAkB;EAClB,gBAAgB;EAChB,YAAY;AACd;;AAEA;EACE,gBAAgB;EAChB,aAAa;EACb,sBAAsB;EACtB,gBAAgB;EAChB,kBAAkB;AACpB;;AAEA;EACE,gBAAgB;EAChB,gBAAgB;EAChB,gBAAgB;EAChB,kBAAkB;AACpB\",\"sourcesContent\":[\".session-container {\\n background-color: white;\\n}\\n\\n.session-container.horizontal.ui.grid {\\n margin: 0px !important;\\n}\\n\\n.session-container.horizontal .menu-column .item.new {\\n padding: 0.78571429em 1.1em !important;\\n}\\n\\n.session-container.horizontal .ui.vertical.menu .item > i.icon {\\n margin: 0 0.35714286em 0 0 !important;\\n}\\n\\n.session-container.horizontal .session-layout > .ui.divider {\\n margin: 5px 0px 0px 0px;\\n}\\n\\n.session-container.vertical {\\n padding: 15px;\\n display: flex;\\n flex-direction: column;\\n}\\n.session-layout {\\n flex: 100 100 auto;\\n display: flex;\\n overflow: hidden;\\n}\\n\\n.session-container.horizontal .session-layout {\\n flex-direction: column;\\n}\\n\\n.session-container.vertical .menu-bar {\\n justify-content: space-between;\\n margin: 0px !important;\\n}\\n\\n.session-container.vertical .menu-bar .content-left {\\n width: 100%;\\n}\\n\\n.session-container.vertical .menu-bar .close-button.item:before {\\n background: none !important;\\n}\\n\\n.session-container.vertical .menu-bar .close-button.item {\\n box-shadow: none !important;\\n}\\n\\n.session-container.vertical .menu-bar .content-left > .ui.dropdown {\\n float: left;\\n}\\n\\n.session-container.vertical .menu-bar .content-left > .ui.dropdown .menu {\\n max-height: calc(100vh - 140px);\\n overflow-y: auto;\\n overflow-x: hidden;\\n max-width: calc(100vw - 30px);\\n}\\n\\n.session-container.vertical .session-item .count.label {\\n margin-left: 1em !important;\\n}\\n\\n.session-container.vertical .session-header {\\n display: flex;\\n align-items: center;\\n height: 100%;\\n}\\n\\n.session-container.vertical .session-header > div {\\n max-width: 90%; /* Hack, auto width won't work without \\\"overflow: hidden\\\", but that would prevent viewing the menu items */\\n padding: 0.82857143em 0.4285714em;\\n line-height: 1.2;\\n}\\n\\n.session-container.vertical .session-header > div:before {\\n background: none !important;\\n}\\n\\n.session-container.vertical .session-header > i {\\n margin-left: 10px;\\n}\\n\\n.session-container.vertical .session-header .ui.dropdown > i {\\n margin: 0px 5px;\\n}\\n\\n/* Fix a few inconsistencies between 'icon' and 'icons' classnames */\\n.session-container.horizontal .session-header .header > i,\\n.session-container.vertical .session-header > i {\\n width: inherit !important;\\n font-size: 1.5em;\\n}\\n\\n.session-container.horizontal .session-header .ui.header {\\n align-items: center;\\n}\\n\\n.session-container.vertical .menu-bar {\\n border-radius: 0px !important;\\n padding-bottom: 0px;\\n}\\n\\n.session-container,\\n.session-layout,\\n.session-container.horizontal .column {\\n height: 100%;\\n}\\n\\n.session-container.horizontal .column > div {\\n max-height: 100%;\\n}\\n\\n.session-container .session-item {\\n overflow: hidden;\\n display: flex !important;\\n align-items: center;\\n padding: 0.68571429em 0.92857143em !important;\\n height: 35px;\\n}\\n\\n.session-container .session-item .session-status {\\n float: none !important;\\n margin: 0 0.5em 0 0 !important;\\n}\\n\\n.session-container .session-item .session-name {\\n overflow: hidden;\\n flex: 1 1 100%;\\n line-height: 1.2;\\n}\\n\\n.session-container .session-status {\\n margin-right: 5px;\\n margin-top: 3px;\\n}\\n\\n.session-container.horizontal .menu-column {\\n display: flex !important;\\n flex-direction: column;\\n padding-right: 0px !important;\\n}\\n\\n.session-container.horizontal .menu-column .menu {\\n width: initial !important;\\n overflow-y: auto;\\n padding-top: 10px;\\n flex: 1;\\n}\\n\\n.session-container.horizontal .menu-column .session-item span.session-name,\\n.session-container .session-header .ui.dropdown .caption {\\n overflow: hidden;\\n white-space: nowrap;\\n}\\n\\n.session-container .session-header .title .ui.dropdown {\\n width: 100%;\\n}\\n\\n.session-layout .sub.header {\\n overflow: hidden;\\n}\\n\\n.session-layout .sub.header img {\\n vertical-align: text-top;\\n}\\n\\n.session-footer .info-grid {\\n margin-top: 7px !important;\\n font-size: small;\\n color: grey;\\n display: flex;\\n flex: 1;\\n align-items: flex-end;\\n}\\n\\n.session-footer .info-grid > div {\\n flex: 1;\\n}\\n\\n.session-footer .info-grid > div:last-child > div {\\n float: right;\\n}\\n\\n.session-footer .info-grid > div:only-child > div {\\n float: inherit;\\n}\\n\\n.session-footer .ui.checkbox {\\n min-height: inherit !important;\\n}\\n\\n.session-footer .divider {\\n margin-top: 8px;\\n margin-bottom: 0px;\\n}\\n\\n/* New session layout */\\n.session.new {\\n flex: 100 100 0%;\\n display: flex;\\n flex-direction: column;\\n overflow-y: hidden;\\n margin-top: 20px;\\n padding: 1px;\\n}\\n\\n.session.new .recents {\\n flex: 100 100 0%;\\n display: flex;\\n flex-direction: column;\\n margin-top: 20px;\\n overflow-y: hidden;\\n}\\n\\n.session.new .recents .list {\\n padding: 3px 5px;\\n flex: 100 100 0%;\\n overflow-y: auto;\\n overflow-x: hidden;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","import SocketService from 'services/SocketService';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\ntype SessionType = UI.SessionItemBase;\r\n\r\nexport const BuildRemoveSessionAction = (\r\n sessionsUrl: string,\r\n editAccess: API.AccessEnum,\r\n) => {\r\n const handleRemoveSession: UI.ActionHandler<SessionType> = ({ itemData: session }) => {\r\n return SocketService.delete(`${sessionsUrl}/${session.id}`);\r\n };\r\n\r\n const SessionRemoveAction = {\r\n id: 'remove',\r\n displayName: 'Close',\r\n access: editAccess,\r\n icon: IconConstants.REMOVE,\r\n handler: handleRemoveSession,\r\n };\r\n\r\n return SessionRemoveAction;\r\n};\r\n","//import PropTypes from 'prop-types';\r\nimport * as React from 'react';\r\n\r\nimport LocalSettingStore from 'stores/LocalSettingStore';\r\nimport { LocalSettings } from 'constants/SettingConstants';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { SessionChildProps } from 'routes/Sidebar/components/types';\r\n\r\ntype SessionType = UI.SessionItemBase;\r\n\r\ninterface ActiveSessionDecoratorProps<\r\n SessionT extends SessionType,\r\n ActionT extends object,\r\n> extends Pick<SessionChildProps<SessionT, ActionT>, 'session'> {\r\n sessionApi: UI.SessionActions<SessionT> & ActionT;\r\n //uiActions:\r\n //session: SessionT;\r\n}\r\n\r\n// This decorator will fire updates for currently active session\r\n// and set them as read\r\nexport default function <\r\n PropsT,\r\n SessionT extends SessionType,\r\n ActionT extends object = UI.EmptyObject,\r\n>(Component: React.ComponentType<PropsT>, useReadDelay = false) {\r\n class ActiveSessionDecorator extends React.Component<\r\n PropsT & ActiveSessionDecoratorProps<SessionT, ActionT>\r\n > {\r\n /*static propTypes = {\r\n session: PropTypes.any, // Required (cloned)\r\n actions: PropTypes.object, // Required (cloned)\r\n };*/\r\n\r\n readTimeout: number | undefined;\r\n\r\n setRead = (session: SessionT) => {\r\n this.props.sessionApi.setRead(session);\r\n this.readTimeout = undefined;\r\n };\r\n\r\n setSession = (session: SessionT | null) => {\r\n if (this.readTimeout) {\r\n // Set the previously active session as read\r\n clearTimeout(this.readTimeout);\r\n this.setRead(this.props.session);\r\n }\r\n\r\n this.props.sessionApi.sessionChanged(session);\r\n if (!session) {\r\n return;\r\n }\r\n\r\n const timeout = !useReadDelay\r\n ? 0\r\n : LocalSettingStore.getValue<number>(LocalSettings.UNREAD_LABEL_DELAY) * 1000;\r\n this.readTimeout = window.setTimeout(() => this.setRead(session), timeout);\r\n };\r\n\r\n componentDidMount() {\r\n this.setSession(this.props.session);\r\n }\r\n\r\n componentWillUnmount() {\r\n this.setSession(null);\r\n }\r\n\r\n componentDidUpdate(prevProps: ActiveSessionDecoratorProps<SessionT, ActionT>) {\r\n if (this.props.session.id !== prevProps.session.id) {\r\n this.setSession(this.props.session);\r\n }\r\n }\r\n\r\n render() {\r\n return <Component {...this.props} />;\r\n }\r\n }\r\n\r\n return ActiveSessionDecorator;\r\n}\r\n","import * as React from 'react';\n\nimport * as UI from 'types/ui';\n\ninterface FooterItemProps {\n label?: string;\n text: string | React.ReactElement<any>;\n}\n\nexport const FooterItem: React.FC<FooterItemProps> = ({ label, text }) => (\n <div className=\"grid-item\">\n <div className=\"item-inner\">\n {!!label && typeof text === 'string' ? `${label}: ${text}` : text}\n </div>\n </div>\n);\n\nexport const SessionFooter: React.FC<UI.PropsWithChildren> = ({ children }) => (\n <div className=\"session-footer\">\n <div className=\"ui footer divider\" />\n <div className=\"info-grid ui\">{children}</div>\n </div>\n);\n","//import PropTypes from 'prop-types';\r\nimport * as React from 'react';\r\nimport { useMobileLayout } from 'utils/BrowserUtils';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport SectionedDropdown from 'components/semantic/SectionedDropdown';\r\nimport MenuSection from 'components/semantic/MenuSection';\r\nimport { MenuIcon } from 'components/icon/MenuIcon';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { translate } from 'utils/TranslationUtils';\r\nimport IconConstants from 'constants/IconConstants';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { SessionMainLayoutProps } from './types';\r\n\r\ntype SessionDropdownProps<SessionT extends UI.SessionItemBase> = Pick<\r\n SessionMainLayoutProps<SessionT>,\r\n 'sessionMenuItems' | 'newButton' | 'unreadInfoStore' | 'listActionMenuGetter'\r\n>;\r\n\r\nconst SessionDropdown = <SessionT extends UI.SessionItemBase>({\r\n sessionMenuItems,\r\n newButton,\r\n unreadInfoStore,\r\n listActionMenuGetter,\r\n}: SessionDropdownProps<SessionT>) => {\r\n const { t } = useTranslation();\r\n return (\r\n <SectionedDropdown\r\n triggerIcon={\r\n <MenuIcon\r\n urgencies={unreadInfoStore ? unreadInfoStore.getTotalUrgencies() : null}\r\n />\r\n }\r\n >\r\n <MenuSection caption={translate('New', t, UI.Modules.COMMON)}>\r\n {newButton}\r\n </MenuSection>\r\n <MenuSection caption={translate('Current sessions', t, UI.Modules.COMMON)}>\r\n {sessionMenuItems}\r\n </MenuSection>\r\n <MenuSection>{listActionMenuGetter()}</MenuSection>\r\n </SectionedDropdown>\r\n );\r\n};\r\n\r\ntype CloseButtonProps<\r\n SessionT extends UI.SessionItemBase,\r\n UIActionsT extends UI.ActionListType<UI.SessionItemBase>,\r\n> = Pick<\r\n SessionMainLayoutProps<SessionT, UI.EmptyObject, UIActionsT>,\r\n 'actions' | 'activeItem'\r\n>;\r\n\r\nconst CloseButton = <\r\n SessionT extends UI.SessionItemBase,\r\n UIActionsT extends UI.ActionListType<UI.SessionItemBase>,\r\n>({\r\n actions,\r\n activeItem,\r\n}: CloseButtonProps<SessionT, UIActionsT>) => {\r\n if (!activeItem || useMobileLayout()) {\r\n return null;\r\n }\r\n\r\n /*const closeAction = Object.values(actions.actions).find(\r\n (action) => !!action && action.id === 'remove',\r\n ) as UI.ActionDefinition<UI.SessionItemBase>;*/\r\n\r\n const closeAction = Object.values(actions.actions)[\r\n Object.values(actions.actions).length - 1\r\n ];\r\n return (\r\n <ActionButton\r\n className=\"basic small item close-button\"\r\n action={closeAction as UI.ActionDefinition<UI.SessionItemBase>}\r\n moduleData={actions.moduleData}\r\n itemData={activeItem}\r\n icon={IconConstants.CLOSE}\r\n />\r\n );\r\n};\r\n\r\ntype SessionItemHeaderProps = Pick<\r\n SessionMainLayoutProps<any>,\r\n 'itemHeaderIcon' | 'itemHeaderTitle'\r\n>;\r\n\r\nconst SessionItemHeader: React.FC<SessionItemHeaderProps> = ({\r\n itemHeaderIcon,\r\n itemHeaderTitle,\r\n}) => (\r\n <div className=\"session-header\">\r\n {itemHeaderIcon}\r\n {itemHeaderTitle}\r\n </div>\r\n);\r\n\r\nconst TopMenuLayout = <\r\n SessionT extends UI.SessionItemBase,\r\n SessionApiT extends object,\r\n UIActionsT extends UI.ActionListType<UI.SessionItemBase>,\r\n>({\r\n children,\r\n onKeyDown,\r\n ...props\r\n}: SessionMainLayoutProps<SessionT, SessionApiT, UIActionsT>) => (\r\n <div className=\"session-container vertical\" onKeyDown={onKeyDown} tabIndex={0}>\r\n <div className=\"ui main menu menu-bar\">\r\n <div className=\"content-left\">\r\n <SessionDropdown {...props} />\r\n <SessionItemHeader {...props} />\r\n </div>\r\n <CloseButton {...props} />\r\n </div>\r\n\r\n <div className=\"session-layout\">{children}</div>\r\n </div>\r\n);\r\n\r\n/*TopMenuLayout.propTypes = {\r\n itemHeaderTitle: PropTypes.node.isRequired,\r\n itemHeaderIcon: PropTypes.node.isRequired,\r\n activeItem: PropTypes.object,\r\n newButton: PropTypes.node,\r\n sessionMenuItems: PropTypes.array.isRequired,\r\n closeAction: PropTypes.func.isRequired,\r\n listActionMenuGetter: PropTypes.func.isRequired,\r\n};*/\r\n\r\nexport default TopMenuLayout;\r\n","//import PropTypes from 'prop-types';\r\nimport * as React from 'react';\r\n\r\nimport LayoutHeader from 'components/semantic/LayoutHeader';\r\nimport { Grid } from 'components/semantic/Grid';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { SessionMainLayoutProps } from './types';\r\n\r\nconst SideMenuLayout = <\r\n SessionT extends UI.SessionItemBase,\r\n SessionApiT extends object,\r\n UIActionsT extends UI.ActionListType<UI.SessionItemBase>,\r\n>({\r\n sessionMenuItems,\r\n newButton,\r\n itemHeaderIcon,\r\n itemHeaderTitle,\r\n children,\r\n itemHeaderDescription,\r\n onKeyDown,\r\n}: SessionMainLayoutProps<SessionT, SessionApiT, UIActionsT>) => {\r\n if (newButton) {\r\n newButton = React.cloneElement(newButton, {\r\n className: newButton.props.className + ' ui fluid button',\r\n });\r\n }\r\n\r\n return (\r\n <Grid className=\"session-container horizontal\" onKeyDown={onKeyDown} tabIndex={0}>\r\n <div className=\"four wide column menu-column\">\r\n {newButton}\r\n {!!sessionMenuItems.length && (\r\n <div className=\"ui vertical secondary menu\">{sessionMenuItems}</div>\r\n )}\r\n </div>\r\n <div className=\"twelve wide stretched column content-column session\">\r\n <div className=\"ui segment session-layout\">\r\n <LayoutHeader\r\n className=\"session-header\"\r\n icon={itemHeaderIcon}\r\n title={<div className=\"title\">{itemHeaderTitle}</div>}\r\n subHeader={itemHeaderDescription}\r\n />\r\n <div className=\"ui divider\" style={{ margin: '5px 0px 0px 0px' }} />\r\n {children}\r\n </div>\r\n </div>\r\n </Grid>\r\n );\r\n};\r\n\r\n/*SideMenuLayout.propTypes = {\r\n newButton: PropTypes.node,\r\n sessionMenuItems: PropTypes.array.isRequired,\r\n\r\n itemHeaderTitle: PropTypes.node,\r\n itemHeaderIcon: PropTypes.node,\r\n itemHeaderDescription: PropTypes.node.isRequired,\r\n};*/\r\n\r\nexport default SideMenuLayout;\r\n","import invariant from 'invariant';\r\n\r\nimport * as API from 'types/api';\r\n\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { SessionLocationState } from '../types';\r\n\r\ninterface SessionRouteHelperProps {\r\n baseUrl: string;\r\n}\r\n\r\nexport const useSessionRouteHelpers = ({ baseUrl }: SessionRouteHelperProps) => {\r\n const navigate = useNavigate();\r\n\r\n // HELPERS\r\n const getSessionUrl = (id: API.IdType) => {\r\n invariant(!!id, 'Trying to get session URL without a session');\r\n return `/${baseUrl}/session/${id}`;\r\n };\r\n\r\n const pushSession = (id: API.IdType) => {\r\n navigate(getSessionUrl(id));\r\n };\r\n\r\n const replaceSession = (id: API.IdType, state?: SessionLocationState) => {\r\n navigate(getSessionUrl(id), { replace: true, state });\r\n };\r\n\r\n const newUrl = `/${baseUrl}/new`;\r\n const replaceNew = () => {\r\n // const { navigate } = props;\r\n navigate(newUrl, { replace: true });\r\n };\r\n\r\n return {\r\n newUrl: `/${baseUrl}/new`,\r\n replaceNew,\r\n\r\n getSessionUrl,\r\n pushSession,\r\n replaceSession,\r\n };\r\n};\r\n","import * as React from 'react';\r\n\r\nimport { loadLocalProperty, saveLocalProperty } from 'utils/BrowserUtils';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { useLocation } from 'react-router-dom';\r\nimport { useSessionRouteHelpers } from './useSessionHelpers';\r\nimport { SessionLocationState } from '../types';\r\n\r\nconst findItem = <SessionT extends UI.SessionItemBase>(\r\n items: SessionT[],\r\n id: API.IdType | undefined,\r\n): SessionT | undefined => {\r\n return items.find((item) => item.id === id);\r\n};\r\n\r\nexport interface SessionManagerProps<\r\n SessionT extends UI.SessionItemBase,\r\n SessionApiT extends object = UI.EmptyObject,\r\n> {\r\n // Item ID that is currently active (if any)\r\n activeId: API.IdType | undefined;\r\n\r\n // Array of the items to list\r\n items: SessionT[];\r\n\r\n baseUrl: string;\r\n\r\n sessionApi: UI.SessionActions<SessionT> & SessionApiT;\r\n}\r\n\r\nexport const useSessionManager = <\r\n SessionT extends UI.SessionItemBase,\r\n SessionApiT extends object = UI.EmptyObject,\r\n>(\r\n props: SessionManagerProps<SessionT, SessionApiT>,\r\n) => {\r\n const [activeItem, setActiveItem] = React.useState<SessionT | null>(null);\r\n const location = useLocation();\r\n\r\n const { pushSession, replaceSession, newUrl, replaceNew } = useSessionRouteHelpers({\r\n baseUrl: props.baseUrl,\r\n });\r\n\r\n // HELPERS\r\n const getStorageKey = () => {\r\n return `${props.baseUrl}_last_active`;\r\n };\r\n\r\n // Common logic for selecting the item to display (after mounting or session updates)\r\n // Returns true active item selection was handled\r\n // Returns false if the active item couldn't be selected but there are valid items to choose from by the caller\r\n const checkActiveItem = () => {\r\n // Did we just create this session?\r\n const routerLocation = location;\r\n const pending =\r\n routerLocation.state && (routerLocation.state as SessionLocationState).pending;\r\n\r\n // Update the active item\r\n const activeItemNew = findItem(props.items, props.activeId);\r\n if (activeItemNew) {\r\n if (pending) {\r\n // Disable pending state\r\n replaceSession(activeItemNew.id, {\r\n pending: false,\r\n });\r\n\r\n return true;\r\n }\r\n\r\n setActiveItem(activeItemNew);\r\n saveLocalProperty(getStorageKey(), props.activeId);\r\n return true;\r\n } else if (pending) {\r\n // We'll just display a loading indicator in 'render', no item needed\r\n return true;\r\n } else if (/*routerLocation.action === 'POP' ||*/ props.items.length === 0) {\r\n // Browsing from history and item removed (or all items removed)... go to \"new session\" page\r\n replaceNew();\r\n setActiveItem(null);\r\n return true;\r\n }\r\n\r\n return false;\r\n };\r\n\r\n // LIFECYCLE/REACT\r\n // Set the session early so that we wont' flash the \"new session\" layout\r\n React.useLayoutEffect(() => {\r\n if (location.pathname === newUrl) {\r\n // Don't redirect to it if the \"new session\" layout is open\r\n if (activeItem) {\r\n setActiveItem(null);\r\n }\r\n return;\r\n }\r\n\r\n if (checkActiveItem()) {\r\n // We got an item\r\n return;\r\n }\r\n\r\n if (!activeItem) {\r\n const lastId = loadLocalProperty<API.IdType>(getStorageKey());\r\n if (lastId && findItem(props.items, lastId)) {\r\n // Previous session exists\r\n replaceSession(lastId);\r\n return;\r\n }\r\n }\r\n\r\n // The old tab was closed or we didn't have any session before\r\n\r\n const { items, activeId } = props;\r\n let newItemPos = 0;\r\n const oldItem = findItem(items, activeId);\r\n if (oldItem) {\r\n // Find the old position and use the item in that position (if possible)\r\n newItemPos = items.indexOf(oldItem);\r\n if (newItemPos === items.length - 1) {\r\n // The last item was removed\r\n newItemPos = newItemPos - 1;\r\n }\r\n }\r\n\r\n replaceSession(items[newItemPos].id);\r\n }, [location, props.items]);\r\n\r\n const onKeyDown = (event: React.KeyboardEvent) => {\r\n const { key, altKey } = event;\r\n\r\n if (altKey && (key === 'ArrowUp' || key === 'ArrowDown')) {\r\n // Arrow up/down\r\n event.preventDefault();\r\n\r\n const { items, activeId } = props;\r\n const item = findItem(items, activeId);\r\n if (!item) {\r\n return;\r\n }\r\n\r\n const currentIndex = items.indexOf(item);\r\n if (currentIndex === -1) {\r\n return;\r\n }\r\n\r\n const newSession = items[key === 'ArrowUp' ? currentIndex - 1 : currentIndex + 1];\r\n if (newSession) {\r\n pushSession(newSession.id);\r\n }\r\n } else if (altKey && key === 'Insert') {\r\n // Insert\r\n event.preventDefault();\r\n\r\n replaceNew();\r\n } else if (altKey && key === 'Delete') {\r\n // Delete\r\n event.preventDefault();\r\n\r\n const { items, activeId, sessionApi } = props;\r\n const item = findItem(items, activeId);\r\n if (!!item) {\r\n sessionApi.removeSession(item);\r\n }\r\n }\r\n };\r\n\r\n return {\r\n onKeyDown,\r\n activeItem,\r\n };\r\n};\r\n","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!./sessions.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\noptions.insert = insertFn.bind(null, \"head\");\noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!./sessions.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as React from 'react';\r\nimport classNames from 'classnames';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\nimport RouterMenuItemLink from 'components/semantic/RouterMenuItemLink';\r\n\r\ninterface SessionNewButtonProps {\r\n url: string;\r\n title: React.ReactNode;\r\n className?: string;\r\n}\r\n\r\nconst SessionNewButton: React.FC<SessionNewButtonProps> = ({\r\n url,\r\n title,\r\n // pushNew,\r\n className,\r\n}) => (\r\n <RouterMenuItemLink\r\n key=\"button-new\"\r\n className={classNames('new', className)}\r\n icon={IconConstants.CREATE}\r\n url={url}\r\n >\r\n {title}\r\n </RouterMenuItemLink>\r\n);\r\n\r\nexport default SessionNewButton;\r\n","//import PropTypes from 'prop-types';\r\nimport * as React from 'react';\r\n\r\nimport RouterMenuItemLink from 'components/semantic/RouterMenuItemLink';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\ninterface SessionMenuItemProps {\r\n url: string;\r\n name: React.ReactNode;\r\n unreadInfoStore: UI.UnreadInfoStore;\r\n status: React.ReactElement<any>;\r\n sessionItem: UI.SessionItemBase;\r\n}\r\n\r\nconst SessionMenuItem: React.FC<SessionMenuItemProps> = ({\r\n sessionItem,\r\n status,\r\n name,\r\n unreadInfoStore,\r\n url,\r\n}) => (\r\n <RouterMenuItemLink\r\n url={url}\r\n className=\"session-item\"\r\n icon={status}\r\n session={sessionItem}\r\n unreadInfoStore={unreadInfoStore}\r\n >\r\n <span className=\"session-name\">{name}</span>\r\n </RouterMenuItemLink>\r\n);\r\n\r\n/*SessionMenuItem.propTypes = {\r\n // Item URL\r\n url: PropTypes.string.isRequired,\r\n\r\n name: PropTypes.node.isRequired,\r\n\r\n unreadInfoStore: PropTypes.object.isRequired,\r\n\r\n status: PropTypes.node.isRequired,\r\n\r\n sessionItem: PropTypes.object.isRequired,\r\n\r\n pushSession: PropTypes.func.isRequired,\r\n};*/\r\n\r\nexport default SessionMenuItem;\r\n","import { ActionMenu } from 'components/action-menu';\r\nimport SessionNewButton from './SessionNewButton';\r\nimport SessionMenuItem from './SessionMenuItem';\r\n\r\nimport Icon from 'components/semantic/Icon';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\nimport MenuItemLink from 'components/semantic/MenuItemLink';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\nimport { translate } from 'utils/TranslationUtils';\r\nimport { SessionLayoutLabels, SessionLayoutManageProps } from './types';\r\nimport { useLocation } from 'react-router-dom';\r\nimport { useSessionRouteHelpers } from './effects/useSessionHelpers';\r\nimport { useTranslation } from 'react-i18next';\r\n\r\nexport const useComponents = <\r\n SessionT extends UI.SessionItemBase,\r\n SessionApiT extends object = UI.EmptyObject,\r\n UIActionT extends UI.ActionListType<UI.SessionItemBase> = UI.EmptyObject,\r\n>(\r\n props: UI.SessionInfoGetter<SessionT> & {\r\n activeItem: SessionT | null;\r\n hasEditAccess: boolean;\r\n } & SessionLayoutLabels &\r\n SessionLayoutManageProps<SessionT, SessionApiT, UIActionT>,\r\n) => {\r\n const location = useLocation();\r\n const { t } = useTranslation();\r\n const { newUrl, getSessionUrl } = useSessionRouteHelpers({\r\n baseUrl: props.baseUrl,\r\n });\r\n\r\n // COMPONENT GETTERS\r\n const getItemStatus = (sessionItem: SessionT) => {\r\n const { itemStatusGetter, itemHeaderIconGetter } = props;\r\n if (itemStatusGetter) {\r\n return (\r\n <div\r\n className={\r\n 'ui session-status empty circular left mini label ' +\r\n itemStatusGetter(sessionItem)\r\n }\r\n />\r\n );\r\n }\r\n\r\n return <Icon icon={itemHeaderIconGetter(sessionItem)} />;\r\n };\r\n\r\n const components = {\r\n getItemHeaderDescription: () => {\r\n const { itemHeaderDescriptionGetter, newDescription, activeItem } = props;\r\n if (!activeItem) {\r\n return newDescription;\r\n }\r\n\r\n return itemHeaderDescriptionGetter(activeItem);\r\n },\r\n getItemHeaderIcon: () => {\r\n const { itemHeaderIconGetter, newIcon, activeItem } = props;\r\n return <Icon icon={activeItem ? itemHeaderIconGetter(activeItem) : newIcon} />;\r\n },\r\n getItemHeaderTitle: () => {\r\n const { activeItem, newCaption } = props;\r\n if (!activeItem) {\r\n return <div>{newCaption}</div>;\r\n }\r\n\r\n const { uiActions, actionIds, itemNameGetter, itemHeaderTitleGetter } = props;\r\n\r\n const ids = actionIds ? [...actionIds, 'divider', 'remove'] : undefined;\r\n const actionMenu = (\r\n <ActionMenu\r\n caption={itemNameGetter(activeItem)}\r\n actions={uiActions}\r\n itemData={activeItem}\r\n ids={ids}\r\n />\r\n );\r\n\r\n // Use the header getter only if there is a getter that returns a valid value\r\n if (itemHeaderTitleGetter) {\r\n const header = itemHeaderTitleGetter(activeItem, location, actionMenu);\r\n if (header) {\r\n return header;\r\n }\r\n }\r\n\r\n return actionMenu;\r\n },\r\n getSessionActionMenuItems: () => {\r\n const { items, hasEditAccess } = props;\r\n if (!hasEditAccess || items.length === 0) {\r\n return null;\r\n }\r\n\r\n const handleCloseAll = () => {\r\n const { sessionApi, items } = props;\r\n items.forEach((session) => sessionApi.removeSession(session));\r\n };\r\n\r\n return (\r\n <MenuItemLink key=\"close\" onClick={handleCloseAll} icon={IconConstants.REMOVE}>\r\n {translate('Close all', t, UI.Modules.COMMON)}\r\n </MenuItemLink>\r\n );\r\n },\r\n getNewButton: () => {\r\n const { newCaption, hasEditAccess } = props;\r\n if (!hasEditAccess || !newCaption) {\r\n return null;\r\n }\r\n\r\n return <SessionNewButton key=\"new-button\" title={newCaption} url={newUrl} />;\r\n },\r\n getSessionMenuItems: () => {\r\n const getSessionMenuItem = (sessionItem: SessionT) => {\r\n const { itemNameGetter, unreadInfoStore } = props;\r\n return (\r\n <SessionMenuItem\r\n key={sessionItem.id}\r\n url={getSessionUrl(sessionItem.id)}\r\n name={itemNameGetter(sessionItem)}\r\n unreadInfoStore={unreadInfoStore}\r\n status={getItemStatus(sessionItem)}\r\n sessionItem={sessionItem}\r\n />\r\n );\r\n };\r\n\r\n return props.items.map(getSessionMenuItem);\r\n },\r\n };\r\n\r\n return components;\r\n};\r\n","import * as React from 'react';\r\n\r\nimport Loader from 'components/semantic/Loader';\r\n\r\nimport TopMenuLayout from './TopMenuLayout';\r\nimport SideMenuLayout from './SideMenuLayout';\r\n\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport LoginStore from 'stores/LoginStore';\r\nimport { useMobileLayout } from 'utils/BrowserUtils';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { translate, toI18nKey } from 'utils/TranslationUtils';\r\nimport { useLayoutWidth } from 'context/LayoutWidthContext';\r\nimport { useSessionManager } from './effects/useSessionManager';\r\nimport { useLocation, useNavigate } from 'react-router';\r\n\r\nimport '../sessions.css';\r\nimport {\r\n NewSessionLayoutProps,\r\n SessionChildProps,\r\n SessionLayoutLabels,\r\n SessionLayoutManageProps,\r\n SessionLocationState,\r\n} from './types';\r\nimport { useComponents } from './SessionMenuComponents';\r\n\r\nexport interface SessionLayoutProps<\r\n SessionT extends UI.SessionItemBase,\r\n SessionApiT extends object = UI.EmptyObject,\r\n UIActionT extends UI.ActionListType<UI.SessionItemBase> = UI.EmptyObject,\r\n> extends UI.SessionInfoGetter<SessionT>,\r\n SessionLayoutLabels,\r\n SessionLayoutManageProps<SessionT, SessionApiT, UIActionT> {\r\n // Item ID that is currently active (if any)\r\n activeId: API.IdType | undefined;\r\n\r\n // Set to false if the side menu should never be shown (the session will use all width that is available)\r\n disableSideMenu?: boolean;\r\n\r\n sessionItemLayout: React.ComponentType<\r\n SessionChildProps<SessionT, SessionApiT, UIActionT>\r\n >;\r\n\r\n newLayout?: React.ComponentType<NewSessionLayoutProps>;\r\n\r\n sessionT: UI.ModuleTranslator;\r\n}\r\n\r\nconst SessionLayout = <\r\n SessionT extends UI.SessionItemBase,\r\n SessionApiT extends object,\r\n UIActionsT extends UI.ActionListType<UI.SessionItemBase>,\r\n>(\r\n props: SessionLayoutProps<SessionT, SessionApiT, UIActionsT>,\r\n) => {\r\n const layoutWidth = useLayoutWidth();\r\n const navigate = useNavigate();\r\n const location = useLocation();\r\n\r\n const { activeItem, onKeyDown } = useSessionManager(props);\r\n\r\n const hasEditAccess = LoginStore.hasAccess(props.editAccess);\r\n\r\n const getSessionChildren = () => {\r\n const {\r\n activeId,\r\n items,\r\n sessionItemLayout: SessionItemLayout,\r\n sessionApi,\r\n uiActions,\r\n sessionT,\r\n } = props;\r\n\r\n if (!activeItem) {\r\n const { state } = location;\r\n if (!!state && (state as SessionLocationState).pending) {\r\n // The session was just created\r\n return (\r\n <Loader\r\n text={translate(\r\n 'Waiting for server response',\r\n sessionT.plainT,\r\n UI.Modules.COMMON,\r\n )}\r\n />\r\n );\r\n } else if (activeId || items.length !== 0) {\r\n // Redirecting to a new page\r\n return (\r\n <Loader\r\n text={translate('Loading session', sessionT.plainT, UI.Modules.COMMON)}\r\n />\r\n );\r\n }\r\n\r\n console.error('SessionLayout route: active session missing');\r\n return;\r\n }\r\n\r\n // We have a session\r\n return (\r\n <SessionItemLayout\r\n session={activeItem}\r\n sessionApi={sessionApi}\r\n uiActions={uiActions}\r\n location={location}\r\n navigate={navigate}\r\n sessionT={sessionT}\r\n />\r\n );\r\n };\r\n\r\n const getChildren = () => {\r\n const { newLayout: NewLayout, sessionT } = props;\r\n if (!props.activeId && NewLayout) {\r\n return <NewLayout navigate={navigate} location={location} sessionT={sessionT} />;\r\n }\r\n\r\n return getSessionChildren();\r\n };\r\n\r\n const { disableSideMenu, items, unreadInfoStore, sessionT, uiActions } = props;\r\n\r\n if (!hasEditAccess && items.length === 0) {\r\n // Nothing to show\r\n return (\r\n <Message\r\n title={translate('No items to show', sessionT.plainT, UI.Modules.COMMON)}\r\n description={sessionT.plainT<string>(\r\n toI18nKey('noSessionEditAccess', UI.Modules.COMMON),\r\n `You aren't allowed to open new sessions`,\r\n )}\r\n />\r\n );\r\n }\r\n\r\n const useTopMenu = disableSideMenu || useMobileLayout(layoutWidth);\r\n\r\n const MenuLayout = useTopMenu ? TopMenuLayout : SideMenuLayout;\r\n const {\r\n getItemHeaderTitle,\r\n getItemHeaderDescription,\r\n getItemHeaderIcon,\r\n getNewButton,\r\n getSessionMenuItems,\r\n getSessionActionMenuItems,\r\n } = useComponents({ ...props, activeItem, hasEditAccess });\r\n return (\r\n <MenuLayout\r\n itemHeaderTitle={getItemHeaderTitle()}\r\n itemHeaderDescription={getItemHeaderDescription()}\r\n itemHeaderIcon={getItemHeaderIcon()}\r\n newButton={getNewButton()}\r\n sessionMenuItems={getSessionMenuItems()}\r\n listActionMenuGetter={getSessionActionMenuItems}\r\n activeItem={activeItem}\r\n unreadInfoStore={unreadInfoStore}\r\n onKeyDown={onKeyDown}\r\n actions={uiActions}\r\n >\r\n {getChildren()}\r\n </MenuLayout>\r\n );\r\n};\r\n\r\nexport default SessionLayout;\r\n","import * as React from 'react';\r\n\r\nimport Loader from 'components/semantic/Loader';\r\nimport { useStore } from 'effects/StoreListenerEffect';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\nimport { useTranslation } from 'react-i18next';\r\nimport { getModuleT, translate } from 'utils/TranslationUtils';\r\nimport { useParams } from 'react-router-dom';\r\n\r\nexport interface SessionProviderDecoratorProps {}\r\n\r\nexport interface SessionProviderDecoratorChildProps<SessionT extends UI.SessionType> {\r\n items: SessionT[];\r\n sessionT: UI.ModuleTranslator;\r\n params: UI.RouteParams;\r\n}\r\n\r\nconst SessionProviderDecorator = <SessionT extends UI.SessionType>(\r\n Component: React.ComponentType<SessionProviderDecoratorChildProps<SessionT>>,\r\n store: UI.SessionStore<SessionT>,\r\n moduleId: UI.Modules,\r\n) => {\r\n const Decorator = (props: SessionProviderDecoratorProps) => {\r\n const { t } = useTranslation();\r\n const sessionT = getModuleT(t, moduleId);\r\n const params = useParams();\r\n const sessions = useStore<SessionT[]>(store);\r\n if (!store.isInitialized()) {\r\n return <Loader text={translate('Loading sessions', t, UI.Modules.COMMON)} />;\r\n }\r\n\r\n return <Component items={sessions} params={params} sessionT={sessionT} />;\r\n };\r\n\r\n return Decorator;\r\n};\r\n\r\nexport { SessionProviderDecorator };\r\n"],"names":["___CSS_LOADER_EXPORT___","push","module","id","BuildRemoveSessionAction","sessionsUrl","editAccess","displayName","access","icon","REMOVE","handler","itemData","session","delete","Component","useReadDelay","ActiveSessionDecorator","setRead","this","props","sessionApi","readTimeout","undefined","setSession","clearTimeout","sessionChanged","timeout","getValue","UNREAD_LABEL_DELAY","window","setTimeout","componentDidMount","componentWillUnmount","componentDidUpdate","prevProps","render","FooterItem","label","text","className","SessionFooter","children","SessionDropdown","sessionMenuItems","newButton","unreadInfoStore","listActionMenuGetter","t","SectionedDropdown","triggerIcon","MenuIcon","urgencies","getTotalUrgencies","MenuSection","caption","COMMON","CloseButton","actions","activeItem","closeAction","Object","values","length","ActionButton","A","action","moduleData","IconConstants","CLOSE","SessionItemHeader","itemHeaderIcon","itemHeaderTitle","onKeyDown","tabIndex","itemHeaderDescription","Grid","LayoutHeader","title","subHeader","style","margin","useSessionRouteHelpers","baseUrl","navigate","getSessionUrl","newUrl","replaceNew","replace","pushSession","replaceSession","state","findItem","items","find","item","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","locals","url","RouterMenuItemLink","CREATE","sessionItem","status","name","layoutWidth","location","setActiveItem","getStorageKey","pathname","routerLocation","pending","activeItemNew","activeId","checkActiveItem","lastId","newItemPos","oldItem","indexOf","event","key","altKey","preventDefault","removeSession","currentIndex","newSession","useSessionManager","hasEditAccess","LoginStore","hasAccess","disableSideMenu","sessionT","uiActions","Message","plainT","description","MenuLayout","getItemHeaderTitle","getItemHeaderDescription","getItemHeaderIcon","getNewButton","getSessionMenuItems","getSessionActionMenuItems","getItemStatus","itemStatusGetter","itemHeaderIconGetter","Icon","itemHeaderDescriptionGetter","newDescription","newIcon","newCaption","actionIds","itemNameGetter","itemHeaderTitleGetter","ids","actionMenu","header","MenuItemLink","onClick","forEach","map","useComponents","newLayout","NewLayout","sessionItemLayout","SessionItemLayout","Loader","console","error","getSessionChildren","getChildren","SessionProviderDecorator","store","moduleId","params","sessions","isInitialized"],"sourceRoot":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";(self.webpackChunkairdcpp_webui=self.webpackChunkairdcpp_webui||[]).push([[580],{23896:(e,t,n)=>{n.d(t,{A:()=>s});var i=n(71354),a=n.n(i),o=n(76314),r=n.n(o)()(a());r.push([e.id,".virtual-table .cell-wrapper.connected,\n.virtual-table .cell-wrapper.connected span,\n.virtual-table .cell-wrapper.connected strong {\n color: green;\n}\n\n.virtual-table .cell-wrapper.connecting,\n.virtual-table .cell-wrapper.connecting span,\n.virtual-table .cell-wrapper.connecting strong {\n color: orange;\n}\n\n.virtual-table .cell-wrapper.disconnected,\n.virtual-table .cell-wrapper.disconnected span,\n.virtual-table .cell-wrapper.disconnected strong {\n color: dimslategray;\n}\n","",{version:3,sources:["webpack://./src/routes/FavoriteHubs/style.css"],names:[],mappings:"AAAA;;;EAGE,YAAY;AACd;;AAEA;;;EAGE,aAAa;AACf;;AAEA;;;EAGE,mBAAmB;AACrB",sourcesContent:[".virtual-table .cell-wrapper.connected,\n.virtual-table .cell-wrapper.connected span,\n.virtual-table .cell-wrapper.connected strong {\n color: green;\n}\n\n.virtual-table .cell-wrapper.connecting,\n.virtual-table .cell-wrapper.connecting span,\n.virtual-table .cell-wrapper.connecting strong {\n color: orange;\n}\n\n.virtual-table .cell-wrapper.disconnected,\n.virtual-table .cell-wrapper.disconnected span,\n.virtual-table .cell-wrapper.disconnected strong {\n color: dimslategray;\n}\n"],sourceRoot:""}]);const s=r},86818:(e,t,n)=>{n.d(t,{A:()=>a});const i="share_profiles",a={MODULE_URL:i,PROFILES_URL:i,PROFILE_ADDED:"share_profile_added",PROFILE_UPDATED:"share_profile_updated",PROFILE_REMOVED:"share_profile_removed",HIDDEN_PROFILE_ID:1}},71299:(e,t,n)=>{n.d(t,{A:()=>c,T:()=>s});var i=n(2543),a=n(86818),o=n(13546),r=n(98573);const s=e=>({id:e.id,name:e.str}),c=function(e,t,n,s=!0){return(0,o.A)(e,(0,i.merge)(n,{urls:{profiles:a.A.PROFILES_URL},dataConverters:{profiles:(e,{t:n})=>{const i=e.filter((e=>t||e.id!==a.A.HIDDEN_PROFILE_ID)).map((e=>((e,t)=>{let n=e.str;return s&&e.id!==a.A.HIDDEN_PROFILE_ID&&(n+=` (${(0,r.Xq)(e.size,t)})`),Object.assign(Object.assign({},e),{str:n})})(e,n)));return i}},onSocketConnected:(e,{refetchData:t})=>{e(a.A.MODULE_URL,a.A.PROFILE_ADDED,(()=>t())),e(a.A.MODULE_URL,a.A.PROFILE_UPDATED,(()=>t())),e(a.A.MODULE_URL,a.A.PROFILE_REMOVED,(()=>t()))}}))}},7673:(e,t,n)=>{n.r(t),n.d(t,{default:()=>Oe});var i=n(74848),a=n(96540),o=n(22005),r=n.n(o);const s="favorite_hubs",c=s,l=s;var d=n(52267);const p=r().createStore({_viewName:"favorite_hub_view",_apiUrl:c,mixins:[(0,d.A)("name")]});var u=n(75662),h=n(65385),m=n(86818),v=n(26817),A=n(71299),E=n(4425),_=n(51766),y=n(94413),O=n(47456),f=n(86038);const w=({locals:e})=>{const t=(0,a.useRef)();return(0,a.useEffect)((()=>{t.current&&("boolean"==typeof e.value?t.current.indeterminate=!1:t.current.indeterminate=!0)}),[e.value]),(0,i.jsx)("input",Object.assign({ref:t,type:"checkbox"},e.attrs,{onChange:t=>{!1===e.value?e.onChange(null):e.onChange(t.target.checked)}}))},b={renderCheckbox:e=>(0,i.jsx)(w,{locals:e})},I=_.Ay.form.Form.templates.checkbox.clone(b),g=[{id:f.uu.DISABLED,name:"Disabled"},{id:f.uu.ACTIVE_MODE,name:"Active mode"},{id:f.uu.PASSIVE_MODE,name:"Passive mode"}],D=[{key:"generic",title:"Hub properties",type:f.OP.STRUCT,definitions:[{key:"name",title:"Name",type:f.OP.STRING},{key:"hub_url",title:"Hub URL",type:f.OP.STRING},{key:"hub_description",title:"Hub description",type:f.OP.STRING,optional:!0},{key:"share_profile",title:"Share profile",type:f.OP.NUMBER,help:"Custom share profiles can be selected only after entering an ADC hub address (starting with adc:// or adcs://)",optional:!0},{key:"auto_connect",title:"Auto connect",type:f.OP.BOOLEAN}]},{key:"user",title:"User setting overrides",type:f.OP.STRUCT,definitions:[{key:"nick",title:"Nick",type:f.OP.STRING,optional:!0},{key:"user_description",title:"User description",type:f.OP.STRING,optional:!0}]},{key:"connectivityV4",title:"Connectivity setting overrides (IPv4)",type:f.OP.STRUCT,definitions:[{key:"connection_mode_v4",title:"Connectivity mode",type:f.OP.NUMBER,optional:!0,options:g},{key:"connection_ip_v4",title:"IP address",type:f.OP.STRING,optional:!0}]},{key:"connectivityV6",title:"Connectivity setting overrides (IPv6)",type:f.OP.STRUCT,definitions:[{key:"connection_mode_v6",title:"Connectivity mode",type:f.OP.NUMBER,optional:!0,options:g},{key:"connection_ip_v6",title:"IP address",type:f.OP.STRING,optional:!0}]},{key:"misc",title:"Miscellaneous overrides",type:f.OP.STRUCT,definitions:[{key:"use_main_chat_notify",title:"Use chat notification",type:f.OP.BOOLEAN,optional:!0},{key:"show_joins",title:"Show joins/parts",type:f.OP.BOOLEAN,optional:!0},{key:"away_message",title:"Away message",type:f.OP.TEXT,optional:!0}]}],T=e=>!!e&&(0===e.indexOf("adc://")||0===e.indexOf("adcs://"));class C extends a.Component{constructor(e){super(e),this.isNew=()=>!this.props.hubEntry,this.onFieldChanged=(e,t,n)=>e.includes("hub_url")&&!T(t.generic.hub_url)&&t.share_profile!==m.A.HIDDEN_PROFILE_ID?Promise.resolve({share_profile:null}):null,this.save=()=>this.form.save(),this.onSave=e=>{const t=(n=e,Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},n.generic),n.user),n.connectivityV4),n.connectivityV6),n.misc));var n;return this.isNew()?v.A.post(l,t):v.A.patch(`${l}/${this.props.hubEntry.id}`,t)},this.onFieldSetting=(e,t,n)=>{if("share_profile"===e){const e=n.generic?n.generic.hub_url:void 0;Object.assign(t,{nullOption:this.nullOption,factory:_.Ay.form.Select,options:(i=this.props.profiles,a=e,i.filter((e=>T(a)||e.id===m.A.HIDDEN_PROFILE_ID)).map(A.T).map(O.UM)),transformer:O.xs})}else"connection_mode_v4"===e||"connection_mode_v6"===e?Object.assign(t,{nullOption:this.nullOption,transformer:O.xs}):"use_main_chat_notify"!==e&&"show_joins"!==e||Object.assign(t,{template:I,transformer:{format:e=>void 0===e?null:e,parse:e=>e}});var i,a},this.formValue=(e=>{if(e)return{generic:e,user:e,connectivityV4:e,connectivityV6:e,misc:e}})(e.hubEntry),this.definitions=(0,O.Nn)(D,e.favT),this.nullOption={value:"null",text:e.favT.translate("Global default")}}render(){const{translate:e}=this.props.favT,t=e(this.isNew()?"Add favorite hub":"Edit favorite hub");return(0,i.jsx)(u.A,{className:"fav-hub",title:t,onApprove:this.save,closable:!1,icon:E.A.FAVORITE,children:(0,i.jsx)(y.A,{ref:e=>this.form=e,onFieldChanged:this.onFieldChanged,onFieldSetting:this.onFieldSetting,onSave:this.onSave,fieldDefinitions:this.definitions,sourceValue:this.formValue,location:this.props.location})})}}C.displayName="FavoriteHubDialog";const N=(0,h.A)((0,A.A)(C,!0,{urls:{hubEntry:({params:e},t)=>e.entryId?t.get(`${l}/${e.entryId}`):Promise.resolve(void 0)}}),"entries/:entryId?");var S=n(22373),R=n(68465),P=n(44247),U=n(46942),V=n.n(U),j=n(90680),x=n(85258),F=n(83994),k=n(47767);const L=e=>{switch(e.id){case f.uv.CONNECTING:return"yellow remove";case f.uv.CONNECTED:return"grey remove";case f.uv.DISCONNECTED:return"green video play"}return""},H=({width:e,cellData:t,rowDataGetter:n})=>{const a=(0,k.zy)(),o=(0,k.Zp)(),r=()=>{j.A.createSession(n().hub_url,{location:a,navigate:o,sessionStore:x.A})},s=()=>{j.A.removeSession({id:t.current_hub_id})};return(0,i.jsxs)("div",{className:"connect-state",children:[(0,i.jsx)(F.A,{icon:V()("icon large link",L(t)),onClick:(()=>{switch(t.id){case f.uv.CONNECTING:case f.uv.CONNECTED:return s;case f.uv.DISCONNECTED:default:return r}})()}),e>120&&t.str]})};var B=n(71352),G=n(68514),M=n(41860),K=n(85072),$=n.n(K),z=n(97825),X=n.n(z),Y=n(77659),q=n.n(Y),J=n(55056),W=n.n(J),Z=n(10540),Q=n.n(Z),ee=n(41113),te=n.n(ee),ne=n(23896),ie={};ie.styleTagTransform=te(),ie.setAttributes=W(),ie.insert=q().bind(null,"head"),ie.domAPI=X(),ie.insertStyleElement=Q(),$()(ne.A,ie),ne.A&&ne.A.locals&&ne.A.locals;var ae=n(67749),oe=n(42695),re=n(32389),se=n(36076),ce=n(39115);const le={id:"create",displayName:"Add new",access:f.US.FAVORITE_HUBS_EDIT,icon:E.A.CREATE,handler:({navigate:e})=>{e("/favorite-hubs/entries")}},de={edit:{id:"edit",displayName:"Edit",access:f.US.FAVORITE_HUBS_EDIT,icon:E.A.EDIT,handler:({itemData:e,navigate:t})=>{t(`/favorite-hubs/entries/${e.id}`)}},remove:{id:"remove",displayName:"Remove",access:f.US.FAVORITE_HUBS_EDIT,icon:E.A.REMOVE,confirmation:{content:"Are you sure that you want to remove the favorite hub {{item.name}}?",approveCaption:"Remove favorite hub",rejectCaption:"Don't remove"},handler:({itemData:e})=>v.A.delete(l+"/"+e.id)}},pe={moduleId:ae.KV.FAVORITE_HUBS},ue={moduleData:pe,actions:de},he=(e,t)=>v.A.patch(l+"/"+e.id,{password:t}),me=({itemData:e},t)=>he(e,t),ve=({itemData:e})=>e.has_password,Ae={create:{id:"create",displayName:"Set password",access:f.US.FAVORITE_HUBS_EDIT,icon:E.A.LOCK,filter:e=>!ve(e),input:{content:"Set password for the hub {{item.name}}",approveCaption:"Set password",inputProps:{placeholder:"Enter password",type:"password"}},handler:me},change:{id:"change",displayName:"Change password",access:f.US.FAVORITE_HUBS_EDIT,icon:E.A.EDIT,filter:ve,input:{content:"Enter new password for the hub {{item.name}}",approveCaption:"Update password",inputProps:{placeholder:"Enter password",type:"password"}},handler:me},remove:{id:"remove",displayName:"Remove password",access:f.US.FAVORITE_HUBS_EDIT,icon:E.A.REMOVE,filter:ve,confirmation:{content:"Are you sure that you want to reset the password of the hub {{item.name}}?",approveCaption:"Remove password",rejectCaption:"Don't remove"},handler:({itemData:e})=>he(e,null)}},Ee={moduleData:{moduleId:ae.KV.FAVORITE_HUBS,subId:"password"},actions:Ae},_e=({cellData:e,rowDataGetter:t,t:n})=>(0,i.jsx)(B.yj,{caption:e?(0,i.jsx)("strong",{children:(0,oe.Tl)("Set",n,ae.KV.FAVORITE_HUBS)}):(0,oe.Tl)("Not set",n,ae.KV.FAVORITE_HUBS),actions:Ee,itemData:t});class ye extends a.Component{constructor(){super(...arguments),this.rowClassNameGetter=e=>{switch(e.connect_state.id){case f.uv.CONNECTING:return"connecting";case f.uv.CONNECTED:return"connected";case f.uv.DISCONNECTED:return"disconnected"}return""},this.onChangeAutoConnect=(e,t)=>(0,se.bd)((()=>{return n=t,i={auto_connect:e},v.A.patch(l+"/"+n.id,i);var n,i}),this.props.t),this.favT=(0,oe.lw)(this.props.t,ae.KV.FAVORITE_HUBS)}render(){const e=(0,i.jsx)(G.A,{action:le,moduleData:pe}),t=M.A.hasAccess(f.US.HUBS_EDIT);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(S.A,{rowClassNameGetter:this.rowClassNameGetter,footerData:e,store:p,moduleId:ae.KV.FAVORITE_HUBS,children:[(0,i.jsx)(R.VP,{name:"State",width:45,columnKey:"connect_state",cell:t&&(0,i.jsx)(H,{}),flexGrow:3}),(0,i.jsx)(R.VP,{name:"Name",width:150,columnKey:"name",flexGrow:6,cell:(0,i.jsx)(P.K,{actions:ue,remoteMenuId:ce.Ay.FAVORITE_HUB})}),(0,i.jsx)(R.VP,{name:"Address",width:270,columnKey:"hub_url",flexGrow:3,hideWidth:700}),(0,i.jsx)(R.VP,{name:"Auto connect",width:65,columnKey:"auto_connect",cell:t&&(0,i.jsx)(P.AJ,{onChange:this.onChangeAutoConnect,type:"toggle"})}),(0,i.jsx)(R.VP,{name:"Share profile",width:100,columnKey:"share_profile",flexGrow:1}),(0,i.jsx)(R.VP,{name:"Nick",width:100,columnKey:"nick",flexGrow:1}),(0,i.jsx)(R.VP,{name:"Password",width:100,columnKey:"has_password",cell:(0,i.jsx)(_e,{})})]}),(0,i.jsx)(N,{favT:this.favT})]})}}ye.displayName="FavoriteHubs";const Oe=(0,re.CI)()(ye)}}]);
|
|
2
|
-
//# sourceMappingURL=favorite-hubs.
|
|
1
|
+
"use strict";(self.webpackChunkairdcpp_webui=self.webpackChunkairdcpp_webui||[]).push([[580],{23896:(e,t,n)=>{n.d(t,{A:()=>s});var i=n(71354),a=n.n(i),o=n(76314),r=n.n(o)()(a());r.push([e.id,".virtual-table .cell-wrapper.connected,\n.virtual-table .cell-wrapper.connected span,\n.virtual-table .cell-wrapper.connected strong {\n color: green;\n}\n\n.virtual-table .cell-wrapper.connecting,\n.virtual-table .cell-wrapper.connecting span,\n.virtual-table .cell-wrapper.connecting strong {\n color: orange;\n}\n\n.virtual-table .cell-wrapper.disconnected,\n.virtual-table .cell-wrapper.disconnected span,\n.virtual-table .cell-wrapper.disconnected strong {\n color: dimslategray;\n}\n","",{version:3,sources:["webpack://./src/routes/FavoriteHubs/style.css"],names:[],mappings:"AAAA;;;EAGE,YAAY;AACd;;AAEA;;;EAGE,aAAa;AACf;;AAEA;;;EAGE,mBAAmB;AACrB",sourcesContent:[".virtual-table .cell-wrapper.connected,\n.virtual-table .cell-wrapper.connected span,\n.virtual-table .cell-wrapper.connected strong {\n color: green;\n}\n\n.virtual-table .cell-wrapper.connecting,\n.virtual-table .cell-wrapper.connecting span,\n.virtual-table .cell-wrapper.connecting strong {\n color: orange;\n}\n\n.virtual-table .cell-wrapper.disconnected,\n.virtual-table .cell-wrapper.disconnected span,\n.virtual-table .cell-wrapper.disconnected strong {\n color: dimslategray;\n}\n"],sourceRoot:""}]);const s=r},86818:(e,t,n)=>{n.d(t,{A:()=>a});const i="share_profiles",a={MODULE_URL:i,PROFILES_URL:i,PROFILE_ADDED:"share_profile_added",PROFILE_UPDATED:"share_profile_updated",PROFILE_REMOVED:"share_profile_removed",HIDDEN_PROFILE_ID:1}},71299:(e,t,n)=>{n.d(t,{A:()=>c,T:()=>s});var i=n(2543),a=n(86818),o=n(13546),r=n(98573);const s=e=>({id:e.id,name:e.str}),c=function(e,t,n,s=!0){return(0,o.A)(e,(0,i.merge)(n,{urls:{profiles:a.A.PROFILES_URL},dataConverters:{profiles:(e,{t:n})=>{const i=e.filter((e=>t||e.id!==a.A.HIDDEN_PROFILE_ID)).map((e=>((e,t)=>{let n=e.str;return s&&e.id!==a.A.HIDDEN_PROFILE_ID&&(n+=` (${(0,r.Xq)(e.size,t)})`),Object.assign(Object.assign({},e),{str:n})})(e,n)));return i}},onSocketConnected:(e,{refetchData:t})=>{e(a.A.MODULE_URL,a.A.PROFILE_ADDED,(()=>t())),e(a.A.MODULE_URL,a.A.PROFILE_UPDATED,(()=>t())),e(a.A.MODULE_URL,a.A.PROFILE_REMOVED,(()=>t()))}}))}},7673:(e,t,n)=>{n.r(t),n.d(t,{default:()=>Oe});var i=n(74848),a=n(96540),o=n(22005),r=n.n(o);const s="favorite_hubs",c=s,l=s;var d=n(52267);const p=r().createStore({_viewName:"favorite_hub_view",_apiUrl:c,mixins:[(0,d.A)("name")]});var u=n(75662),h=n(65385),m=n(86818),v=n(32811),A=n(71299),E=n(4425),_=n(51766),y=n(94413),O=n(47456),f=n(86038);const w=({locals:e})=>{const t=(0,a.useRef)();return(0,a.useEffect)((()=>{t.current&&("boolean"==typeof e.value?t.current.indeterminate=!1:t.current.indeterminate=!0)}),[e.value]),(0,i.jsx)("input",Object.assign({ref:t,type:"checkbox"},e.attrs,{onChange:t=>{!1===e.value?e.onChange(null):e.onChange(t.target.checked)}}))},b={renderCheckbox:e=>(0,i.jsx)(w,{locals:e})},I=_.Ay.form.Form.templates.checkbox.clone(b),g=[{id:f.uu.DISABLED,name:"Disabled"},{id:f.uu.ACTIVE_MODE,name:"Active mode"},{id:f.uu.PASSIVE_MODE,name:"Passive mode"}],D=[{key:"generic",title:"Hub properties",type:f.OP.STRUCT,definitions:[{key:"name",title:"Name",type:f.OP.STRING},{key:"hub_url",title:"Hub URL",type:f.OP.STRING},{key:"hub_description",title:"Hub description",type:f.OP.STRING,optional:!0},{key:"share_profile",title:"Share profile",type:f.OP.NUMBER,help:"Custom share profiles can be selected only after entering an ADC hub address (starting with adc:// or adcs://)",optional:!0},{key:"auto_connect",title:"Auto connect",type:f.OP.BOOLEAN}]},{key:"user",title:"User setting overrides",type:f.OP.STRUCT,definitions:[{key:"nick",title:"Nick",type:f.OP.STRING,optional:!0},{key:"user_description",title:"User description",type:f.OP.STRING,optional:!0}]},{key:"connectivityV4",title:"Connectivity setting overrides (IPv4)",type:f.OP.STRUCT,definitions:[{key:"connection_mode_v4",title:"Connectivity mode",type:f.OP.NUMBER,optional:!0,options:g},{key:"connection_ip_v4",title:"IP address",type:f.OP.STRING,optional:!0}]},{key:"connectivityV6",title:"Connectivity setting overrides (IPv6)",type:f.OP.STRUCT,definitions:[{key:"connection_mode_v6",title:"Connectivity mode",type:f.OP.NUMBER,optional:!0,options:g},{key:"connection_ip_v6",title:"IP address",type:f.OP.STRING,optional:!0}]},{key:"misc",title:"Miscellaneous overrides",type:f.OP.STRUCT,definitions:[{key:"use_main_chat_notify",title:"Use chat notification",type:f.OP.BOOLEAN,optional:!0},{key:"show_joins",title:"Show joins/parts",type:f.OP.BOOLEAN,optional:!0},{key:"away_message",title:"Away message",type:f.OP.TEXT,optional:!0}]}],T=e=>!!e&&(0===e.indexOf("adc://")||0===e.indexOf("adcs://"));class C extends a.Component{constructor(e){super(e),this.isNew=()=>!this.props.hubEntry,this.onFieldChanged=(e,t,n)=>e.includes("hub_url")&&!T(t.generic.hub_url)&&t.share_profile!==m.A.HIDDEN_PROFILE_ID?Promise.resolve({share_profile:null}):null,this.save=()=>this.form.save(),this.onSave=e=>{const t=(n=e,Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},n.generic),n.user),n.connectivityV4),n.connectivityV6),n.misc));var n;return this.isNew()?v.A.post(l,t):v.A.patch(`${l}/${this.props.hubEntry.id}`,t)},this.onFieldSetting=(e,t,n)=>{if("share_profile"===e){const e=n.generic?n.generic.hub_url:void 0;Object.assign(t,{nullOption:this.nullOption,factory:_.Ay.form.Select,options:(i=this.props.profiles,a=e,i.filter((e=>T(a)||e.id===m.A.HIDDEN_PROFILE_ID)).map(A.T).map(O.UM)),transformer:O.xs})}else"connection_mode_v4"===e||"connection_mode_v6"===e?Object.assign(t,{nullOption:this.nullOption,transformer:O.xs}):"use_main_chat_notify"!==e&&"show_joins"!==e||Object.assign(t,{template:I,transformer:{format:e=>void 0===e?null:e,parse:e=>e}});var i,a},this.formValue=(e=>{if(e)return{generic:e,user:e,connectivityV4:e,connectivityV6:e,misc:e}})(e.hubEntry),this.definitions=(0,O.Nn)(D,e.favT),this.nullOption={value:"null",text:e.favT.translate("Global default")}}render(){const{translate:e}=this.props.favT,t=e(this.isNew()?"Add favorite hub":"Edit favorite hub");return(0,i.jsx)(u.A,{className:"fav-hub",title:t,onApprove:this.save,closable:!1,icon:E.A.FAVORITE,children:(0,i.jsx)(y.A,{ref:e=>this.form=e,onFieldChanged:this.onFieldChanged,onFieldSetting:this.onFieldSetting,onSave:this.onSave,fieldDefinitions:this.definitions,sourceValue:this.formValue,location:this.props.location})})}}C.displayName="FavoriteHubDialog";const N=(0,h.A)((0,A.A)(C,!0,{urls:{hubEntry:({params:e},t)=>e.entryId?t.get(`${l}/${e.entryId}`):Promise.resolve(void 0)}}),"entries/:entryId?");var S=n(22373),R=n(68465),P=n(44247),U=n(46942),V=n.n(U),j=n(90680),x=n(85258),F=n(83994),k=n(47767);const L=e=>{switch(e.id){case f.uv.CONNECTING:return"yellow remove";case f.uv.CONNECTED:return"grey remove";case f.uv.DISCONNECTED:return"green video play"}return""},H=({width:e,cellData:t,rowDataGetter:n})=>{const a=(0,k.zy)(),o=(0,k.Zp)(),r=()=>{j.A.createSession(n().hub_url,{location:a,navigate:o,sessionStore:x.A})},s=()=>{j.A.removeSession({id:t.current_hub_id})};return(0,i.jsxs)("div",{className:"connect-state",children:[(0,i.jsx)(F.A,{icon:V()("icon large link",L(t)),onClick:(()=>{switch(t.id){case f.uv.CONNECTING:case f.uv.CONNECTED:return s;case f.uv.DISCONNECTED:default:return r}})()}),e>120&&t.str]})};var B=n(71352),G=n(68514),M=n(41860),K=n(85072),$=n.n(K),z=n(97825),X=n.n(z),Y=n(77659),q=n.n(Y),J=n(55056),W=n.n(J),Z=n(10540),Q=n.n(Z),ee=n(41113),te=n.n(ee),ne=n(23896),ie={};ie.styleTagTransform=te(),ie.setAttributes=W(),ie.insert=q().bind(null,"head"),ie.domAPI=X(),ie.insertStyleElement=Q(),$()(ne.A,ie),ne.A&&ne.A.locals&&ne.A.locals;var ae=n(67749),oe=n(42695),re=n(32389),se=n(36076),ce=n(39115);const le={id:"create",displayName:"Add new",access:f.US.FAVORITE_HUBS_EDIT,icon:E.A.CREATE,handler:({navigate:e})=>{e("/favorite-hubs/entries")}},de={edit:{id:"edit",displayName:"Edit",access:f.US.FAVORITE_HUBS_EDIT,icon:E.A.EDIT,handler:({itemData:e,navigate:t})=>{t(`/favorite-hubs/entries/${e.id}`)}},remove:{id:"remove",displayName:"Remove",access:f.US.FAVORITE_HUBS_EDIT,icon:E.A.REMOVE,confirmation:{content:"Are you sure that you want to remove the favorite hub {{item.name}}?",approveCaption:"Remove favorite hub",rejectCaption:"Don't remove"},handler:({itemData:e})=>v.A.delete(l+"/"+e.id)}},pe={moduleId:ae.KV.FAVORITE_HUBS},ue={moduleData:pe,actions:de},he=(e,t)=>v.A.patch(l+"/"+e.id,{password:t}),me=({itemData:e},t)=>he(e,t),ve=({itemData:e})=>e.has_password,Ae={create:{id:"create",displayName:"Set password",access:f.US.FAVORITE_HUBS_EDIT,icon:E.A.LOCK,filter:e=>!ve(e),input:{content:"Set password for the hub {{item.name}}",approveCaption:"Set password",inputProps:{placeholder:"Enter password",type:"password"}},handler:me},change:{id:"change",displayName:"Change password",access:f.US.FAVORITE_HUBS_EDIT,icon:E.A.EDIT,filter:ve,input:{content:"Enter new password for the hub {{item.name}}",approveCaption:"Update password",inputProps:{placeholder:"Enter password",type:"password"}},handler:me},remove:{id:"remove",displayName:"Remove password",access:f.US.FAVORITE_HUBS_EDIT,icon:E.A.REMOVE,filter:ve,confirmation:{content:"Are you sure that you want to reset the password of the hub {{item.name}}?",approveCaption:"Remove password",rejectCaption:"Don't remove"},handler:({itemData:e})=>he(e,null)}},Ee={moduleData:{moduleId:ae.KV.FAVORITE_HUBS,subId:"password"},actions:Ae},_e=({cellData:e,rowDataGetter:t,t:n})=>(0,i.jsx)(B.yj,{caption:e?(0,i.jsx)("strong",{children:(0,oe.Tl)("Set",n,ae.KV.FAVORITE_HUBS)}):(0,oe.Tl)("Not set",n,ae.KV.FAVORITE_HUBS),actions:Ee,itemData:t});class ye extends a.Component{constructor(){super(...arguments),this.rowClassNameGetter=e=>{switch(e.connect_state.id){case f.uv.CONNECTING:return"connecting";case f.uv.CONNECTED:return"connected";case f.uv.DISCONNECTED:return"disconnected"}return""},this.onChangeAutoConnect=(e,t)=>(0,se.bd)((()=>{return n=t,i={auto_connect:e},v.A.patch(l+"/"+n.id,i);var n,i}),this.props.t),this.favT=(0,oe.lw)(this.props.t,ae.KV.FAVORITE_HUBS)}render(){const e=(0,i.jsx)(G.A,{action:le,moduleData:pe}),t=M.A.hasAccess(f.US.HUBS_EDIT);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(S.A,{rowClassNameGetter:this.rowClassNameGetter,footerData:e,store:p,moduleId:ae.KV.FAVORITE_HUBS,children:[(0,i.jsx)(R.VP,{name:"State",width:45,columnKey:"connect_state",cell:t&&(0,i.jsx)(H,{}),flexGrow:3}),(0,i.jsx)(R.VP,{name:"Name",width:150,columnKey:"name",flexGrow:6,cell:(0,i.jsx)(P.K,{actions:ue,remoteMenuId:ce.Ay.FAVORITE_HUB})}),(0,i.jsx)(R.VP,{name:"Address",width:270,columnKey:"hub_url",flexGrow:3,hideWidth:700}),(0,i.jsx)(R.VP,{name:"Auto connect",width:65,columnKey:"auto_connect",cell:t&&(0,i.jsx)(P.AJ,{onChange:this.onChangeAutoConnect,type:"toggle"})}),(0,i.jsx)(R.VP,{name:"Share profile",width:100,columnKey:"share_profile",flexGrow:1}),(0,i.jsx)(R.VP,{name:"Nick",width:100,columnKey:"nick",flexGrow:1}),(0,i.jsx)(R.VP,{name:"Password",width:100,columnKey:"has_password",cell:(0,i.jsx)(_e,{})})]}),(0,i.jsx)(N,{favT:this.favT})]})}}ye.displayName="FavoriteHubs";const Oe=(0,re.CI)()(ye)}}]);
|
|
2
|
+
//# sourceMappingURL=favorite-hubs.f1ced66aa7691eeee525.chunk.js.map
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"js/favorite-hubs.5d14015c002fab9d6e93.chunk.js","mappings":"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","sources":["webpack://airdcpp-webui/./src/routes/FavoriteHubs/style.css","webpack://airdcpp-webui/./src/constants/ShareProfileConstants.ts","webpack://airdcpp-webui/./src/decorators/ShareProfileDecorator.tsx","webpack://airdcpp-webui/./src/constants/FavoriteHubConstants.ts","webpack://airdcpp-webui/./src/stores/FavoriteHubStore.js","webpack://airdcpp-webui/./src/components/form/fields/IndeterminateCheckboxField.tsx","webpack://airdcpp-webui/./src/routes/FavoriteHubs/components/FavoriteHubDialog.tsx","webpack://airdcpp-webui/./src/routes/FavoriteHubs/components/ConnectStateCell.tsx","webpack://airdcpp-webui/./src/routes/FavoriteHubs/style.css?f7f3","webpack://airdcpp-webui/./src/actions/ui/favorite-hub/FavoriteHubActions.ts","webpack://airdcpp-webui/./src/actions/ui/favorite-hub/FavoriteHubPasswordActions.ts","webpack://airdcpp-webui/./src/routes/FavoriteHubs/components/FavoriteHubs.tsx","webpack://airdcpp-webui/./src/services/api/FavoriteHubApi.ts"],"sourcesContent":["// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.virtual-table .cell-wrapper.connected,\n.virtual-table .cell-wrapper.connected span,\n.virtual-table .cell-wrapper.connected strong {\n color: green;\n}\n\n.virtual-table .cell-wrapper.connecting,\n.virtual-table .cell-wrapper.connecting span,\n.virtual-table .cell-wrapper.connecting strong {\n color: orange;\n}\n\n.virtual-table .cell-wrapper.disconnected,\n.virtual-table .cell-wrapper.disconnected span,\n.virtual-table .cell-wrapper.disconnected strong {\n color: dimslategray;\n}\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/FavoriteHubs/style.css\"],\"names\":[],\"mappings\":\"AAAA;;;EAGE,YAAY;AACd;;AAEA;;;EAGE,aAAa;AACf;;AAEA;;;EAGE,mBAAmB;AACrB\",\"sourcesContent\":[\".virtual-table .cell-wrapper.connected,\\n.virtual-table .cell-wrapper.connected span,\\n.virtual-table .cell-wrapper.connected strong {\\n color: green;\\n}\\n\\n.virtual-table .cell-wrapper.connecting,\\n.virtual-table .cell-wrapper.connecting span,\\n.virtual-table .cell-wrapper.connecting strong {\\n color: orange;\\n}\\n\\n.virtual-table .cell-wrapper.disconnected,\\n.virtual-table .cell-wrapper.disconnected span,\\n.virtual-table .cell-wrapper.disconnected strong {\\n color: dimslategray;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","const MODULE_URL = 'share_profiles';\nexport default {\n MODULE_URL: MODULE_URL,\n PROFILES_URL: MODULE_URL,\n\n PROFILE_ADDED: 'share_profile_added',\n PROFILE_UPDATED: 'share_profile_updated',\n PROFILE_REMOVED: 'share_profile_removed',\n\n HIDDEN_PROFILE_ID: 1,\n};\n","import * as React from 'react';\r\nimport { merge } from 'lodash';\r\n\r\nimport ShareProfileConstants from 'constants/ShareProfileConstants';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n DataProviderDecoratorSettings,\r\n DataConverter,\r\n} from 'decorators/DataProviderDecorator';\r\n\r\nimport { formatSize } from 'utils/ValueFormat';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\ninterface ShareProfileDecoratorDataProps {\r\n profiles: API.ShareProfile[];\r\n}\r\n\r\nexport const profileToEnumValue = (profile: API.ShareProfile) => {\r\n return {\r\n id: profile.id,\r\n name: profile.str,\r\n };\r\n};\r\n\r\nexport type ShareProfileDecoratorChildProps = DataProviderDecoratorChildProps &\r\n ShareProfileDecoratorDataProps;\r\n\r\nconst ShareProfileDecorator = function <PropsT extends object>(\r\n Component: React.ComponentType<PropsT & ShareProfileDecoratorChildProps>,\r\n listHidden: boolean,\r\n dataProviderDecoratorSettings?: DataProviderDecoratorSettings<\r\n PropsT,\r\n ShareProfileDecoratorDataProps\r\n >,\r\n addSize = true,\r\n) {\r\n const convertProfile = (\r\n profile: API.ShareProfile,\r\n t: UI.TranslateF,\r\n ): API.ShareProfile => {\r\n let str = profile.str;\r\n if (addSize && profile.id !== ShareProfileConstants.HIDDEN_PROFILE_ID) {\r\n str += ` (${formatSize(profile.size, t)})`;\r\n }\r\n\r\n return {\r\n ...profile,\r\n str,\r\n };\r\n };\r\n\r\n const convertProfiles: DataConverter<PropsT> = (data: API.ShareProfile[], { t }) => {\r\n const profiles = data\r\n .filter((p) => listHidden || p.id !== ShareProfileConstants.HIDDEN_PROFILE_ID)\r\n .map((p) => convertProfile(p, t));\r\n\r\n return profiles;\r\n };\r\n\r\n return DataProviderDecorator<PropsT, ShareProfileDecoratorDataProps>(\r\n Component,\r\n merge(dataProviderDecoratorSettings, {\r\n urls: {\r\n profiles: ShareProfileConstants.PROFILES_URL,\r\n },\r\n dataConverters: {\r\n profiles: convertProfiles,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(\r\n ShareProfileConstants.MODULE_URL,\r\n ShareProfileConstants.PROFILE_ADDED,\r\n () => refetchData(),\r\n );\r\n addSocketListener(\r\n ShareProfileConstants.MODULE_URL,\r\n ShareProfileConstants.PROFILE_UPDATED,\r\n () => refetchData(),\r\n );\r\n addSocketListener(\r\n ShareProfileConstants.MODULE_URL,\r\n ShareProfileConstants.PROFILE_REMOVED,\r\n () => refetchData(),\r\n );\r\n },\r\n } as DataProviderDecoratorSettings<PropsT, ShareProfileDecoratorDataProps>),\r\n );\r\n};\r\n\r\nexport default ShareProfileDecorator;\r\n","const MODULE_URL = 'favorite_hubs';\n\nexport default {\n MODULE_URL: MODULE_URL,\n HUBS_URL: MODULE_URL,\n};\n","import Reflux from 'reflux';\n\nimport FavoriteHubConstants from 'constants/FavoriteHubConstants';\nimport ViewStoreMixin from 'mixins/ViewStoreMixin';\n\nexport default Reflux.createStore({\n _viewName: 'favorite_hub_view',\n _apiUrl: FavoriteHubConstants.MODULE_URL,\n mixins: [ViewStoreMixin('name')],\n});\n","import { useEffect, useRef } from 'react';\r\nimport * as React from 'react';\r\n\r\nimport * as UI from 'types/ui';\r\nimport t from 'utils/tcomb-form';\r\n\r\ninterface IndeterminateCheckboxProps {\r\n locals: UI.FormLocals<any, boolean | null, UI.EmptyObject>;\r\n}\r\n\r\nconst IndeterminateCheckbox: React.FC<IndeterminateCheckboxProps> = ({ locals }) => {\r\n const inputRef = useRef<HTMLInputElement>();\r\n\r\n useEffect(() => {\r\n if (!inputRef.current) {\r\n return;\r\n }\r\n\r\n if (typeof locals.value === 'boolean') {\r\n inputRef.current.indeterminate = false;\r\n } else {\r\n inputRef.current.indeterminate = true;\r\n }\r\n }, [locals.value]);\r\n\r\n return (\r\n <input\r\n ref={inputRef}\r\n type=\"checkbox\"\r\n {...locals.attrs}\r\n onChange={(evt) => {\r\n // Toggle between true/false/indeterminate\r\n if (locals.value === false) {\r\n locals.onChange(null);\r\n } else {\r\n locals.onChange(evt.target.checked);\r\n }\r\n }}\r\n />\r\n );\r\n};\r\n\r\ntype TCombTemplate = {\r\n renderCheckbox: (\r\n locals: UI.FormLocals<any, boolean | null, UI.EmptyObject>,\r\n ) => React.ReactNode;\r\n};\r\n\r\nconst IndeterminateCheckboxTemplate: TCombTemplate = {\r\n renderCheckbox(locals) {\r\n return <IndeterminateCheckbox locals={locals} />;\r\n },\r\n};\r\n\r\nexport const IndeterminateCheckboxField = t.form.Form.templates.checkbox.clone(\r\n IndeterminateCheckboxTemplate,\r\n);\r\n","import { Component } from 'react';\r\nimport Modal from 'components/semantic/Modal';\r\n\r\nimport ModalRouteDecorator, {\r\n ModalRouteDecoratorChildProps,\r\n} from 'decorators/ModalRouteDecorator';\r\n\r\nimport ShareProfileConstants from 'constants/ShareProfileConstants';\r\nimport FavoriteHubConstants from 'constants/FavoriteHubConstants';\r\n\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport ShareProfileDecorator, {\r\n profileToEnumValue,\r\n ShareProfileDecoratorChildProps,\r\n} from 'decorators/ShareProfileDecorator';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport t from 'utils/tcomb-form';\r\n\r\nimport Form, {\r\n FormFieldChangeHandler,\r\n FormFieldSettingHandler,\r\n FormSaveHandler,\r\n} from 'components/form/Form';\r\nimport { normalizeEnumValue, intTransformer, translateForm } from 'utils/FormUtils';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { FavoriteHubEntry } from 'types/api';\r\nimport { IndeterminateCheckboxField } from 'components/form/fields/IndeterminateCheckboxField';\r\n\r\nconst ConnectivityModeOptions: API.SettingEnumOption[] = [\r\n {\r\n id: API.ConnectivityModeEnum.DISABLED,\r\n name: 'Disabled',\r\n },\r\n {\r\n id: API.ConnectivityModeEnum.ACTIVE_MODE,\r\n name: 'Active mode',\r\n },\r\n {\r\n id: API.ConnectivityModeEnum.PASSIVE_MODE,\r\n name: 'Passive mode',\r\n },\r\n];\r\n\r\nconst Fields: UI.FormFieldDefinition[] = [\r\n {\r\n key: 'generic',\r\n title: 'Hub properties',\r\n type: API.SettingTypeEnum.STRUCT,\r\n definitions: [\r\n {\r\n key: 'name',\r\n title: 'Name',\r\n type: API.SettingTypeEnum.STRING,\r\n },\r\n {\r\n key: 'hub_url',\r\n title: 'Hub URL',\r\n type: API.SettingTypeEnum.STRING,\r\n },\r\n {\r\n key: 'hub_description',\r\n title: 'Hub description',\r\n type: API.SettingTypeEnum.STRING,\r\n optional: true,\r\n },\r\n {\r\n key: 'share_profile',\r\n title: 'Share profile',\r\n type: API.SettingTypeEnum.NUMBER,\r\n // eslint-disable-next-line max-len\r\n help: 'Custom share profiles can be selected only after entering an ADC hub address (starting with adc:// or adcs://)',\r\n optional: true,\r\n },\r\n {\r\n key: 'auto_connect',\r\n title: 'Auto connect',\r\n type: API.SettingTypeEnum.BOOLEAN,\r\n },\r\n ],\r\n },\r\n {\r\n key: 'user',\r\n title: 'User setting overrides',\r\n type: API.SettingTypeEnum.STRUCT,\r\n definitions: [\r\n {\r\n key: 'nick',\r\n title: 'Nick',\r\n type: API.SettingTypeEnum.STRING,\r\n optional: true,\r\n },\r\n {\r\n key: 'user_description',\r\n title: 'User description',\r\n type: API.SettingTypeEnum.STRING,\r\n optional: true,\r\n },\r\n ],\r\n },\r\n {\r\n key: 'connectivityV4',\r\n title: 'Connectivity setting overrides (IPv4)',\r\n type: API.SettingTypeEnum.STRUCT,\r\n definitions: [\r\n {\r\n key: 'connection_mode_v4',\r\n title: 'Connectivity mode',\r\n type: API.SettingTypeEnum.NUMBER,\r\n optional: true,\r\n options: ConnectivityModeOptions,\r\n },\r\n {\r\n key: 'connection_ip_v4',\r\n title: 'IP address',\r\n type: API.SettingTypeEnum.STRING,\r\n optional: true,\r\n },\r\n ],\r\n },\r\n {\r\n key: 'connectivityV6',\r\n title: 'Connectivity setting overrides (IPv6)',\r\n type: API.SettingTypeEnum.STRUCT,\r\n definitions: [\r\n {\r\n key: 'connection_mode_v6',\r\n title: 'Connectivity mode',\r\n type: API.SettingTypeEnum.NUMBER,\r\n optional: true,\r\n options: ConnectivityModeOptions,\r\n },\r\n {\r\n key: 'connection_ip_v6',\r\n title: 'IP address',\r\n type: API.SettingTypeEnum.STRING,\r\n optional: true,\r\n },\r\n ],\r\n },\r\n {\r\n key: 'misc',\r\n title: 'Miscellaneous overrides',\r\n type: API.SettingTypeEnum.STRUCT,\r\n definitions: [\r\n {\r\n key: 'use_main_chat_notify',\r\n title: 'Use chat notification',\r\n type: API.SettingTypeEnum.BOOLEAN,\r\n optional: true,\r\n },\r\n {\r\n key: 'show_joins',\r\n title: 'Show joins/parts',\r\n type: API.SettingTypeEnum.BOOLEAN,\r\n optional: true,\r\n },\r\n {\r\n key: 'away_message',\r\n title: 'Away message',\r\n type: API.SettingTypeEnum.TEXT,\r\n optional: true,\r\n },\r\n ],\r\n },\r\n];\r\n\r\ninterface Entry extends UI.FormValueMap {\r\n generic: Pick<\r\n FavoriteHubEntry,\r\n 'name' | 'hub_url' | 'hub_description' | 'auto_connect' | 'share_profile'\r\n >;\r\n user: Pick<FavoriteHubEntry, 'nick' | 'user_description'>;\r\n connectivityV4: Pick<FavoriteHubEntry, 'connection_mode_v4' | 'connection_ip_v4'>;\r\n connectivityV6: Pick<FavoriteHubEntry, 'connection_mode_v6' | 'connection_ip_v6'>;\r\n misc: Pick<FavoriteHubEntry, 'use_main_chat_notify' | 'show_joins' | 'away_message'>;\r\n}\r\n\r\nconst toFormEntry = (entry?: API.FavoriteHubEntry): Entry | undefined => {\r\n if (!entry) {\r\n return undefined;\r\n }\r\n\r\n return {\r\n generic: entry,\r\n user: entry,\r\n connectivityV4: entry,\r\n connectivityV6: entry,\r\n misc: entry,\r\n };\r\n};\r\n\r\nconst toFavoriteHub = (\r\n entry: RecursivePartial<Entry>,\r\n): RecursivePartial<API.FavoriteHubEntry> => {\r\n return {\r\n ...entry.generic,\r\n ...entry.user,\r\n ...entry.connectivityV4,\r\n ...entry.connectivityV6,\r\n ...entry.misc,\r\n };\r\n};\r\n\r\nconst isAdcHub = (hubUrl?: string) =>\r\n !!hubUrl && (hubUrl.indexOf('adc://') === 0 || hubUrl.indexOf('adcs://') === 0);\r\n\r\n// Get selection values for the profiles field\r\nconst getFieldProfiles = (\r\n profiles: API.SettingEnumOption[],\r\n url?: string,\r\n): UI.FormOption[] => {\r\n return profiles\r\n .filter((p) => isAdcHub(url) || p.id === ShareProfileConstants.HIDDEN_PROFILE_ID)\r\n .map(profileToEnumValue)\r\n .map(normalizeEnumValue);\r\n};\r\n\r\ninterface FavoriteHubDialogProps {\r\n favT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface DataProps {\r\n hubEntry?: API.FavoriteHubEntry;\r\n}\r\n\r\n/*interface RouteProps {\r\n entryId: string;\r\n}*/\r\n\r\ntype Props = FavoriteHubDialogProps &\r\n DataProps &\r\n ShareProfileDecoratorChildProps &\r\n ModalRouteDecoratorChildProps;\r\n\r\nclass FavoriteHubDialog extends Component<Props> {\r\n static displayName = 'FavoriteHubDialog';\r\n\r\n formValue: Entry | undefined;\r\n\r\n constructor(props: Props) {\r\n super(props);\r\n\r\n this.formValue = toFormEntry(props.hubEntry);\r\n this.definitions = translateForm(Fields, props.favT);\r\n this.nullOption = {\r\n value: 'null',\r\n text: props.favT.translate('Global default'),\r\n };\r\n }\r\n\r\n isNew = () => {\r\n return !this.props.hubEntry;\r\n };\r\n\r\n nullOption: UI.FormOption<string>;\r\n definitions: UI.FormFieldDefinition[];\r\n\r\n form: Form<Entry>;\r\n\r\n onFieldChanged: FormFieldChangeHandler<Entry> = (id, value, hasChanges) => {\r\n if (id.includes('hub_url')) {\r\n if (\r\n !isAdcHub(value.generic!.hub_url) &&\r\n value.share_profile !== ShareProfileConstants.HIDDEN_PROFILE_ID\r\n ) {\r\n // Reset share profile\r\n return Promise.resolve({\r\n share_profile: null,\r\n });\r\n }\r\n }\r\n\r\n return null;\r\n };\r\n\r\n save = () => {\r\n return this.form.save();\r\n };\r\n\r\n onSave: FormSaveHandler<Entry> = (changedFields) => {\r\n const hubEntry = toFavoriteHub(changedFields);\r\n if (this.isNew()) {\r\n return SocketService.post(FavoriteHubConstants.HUBS_URL, hubEntry);\r\n }\r\n\r\n return SocketService.patch(\r\n `${FavoriteHubConstants.HUBS_URL}/${this.props.hubEntry!.id}`,\r\n hubEntry,\r\n );\r\n };\r\n\r\n onFieldSetting: FormFieldSettingHandler<Entry> = (id, fieldOptions, formValue) => {\r\n if (id === 'share_profile') {\r\n const hubUrl = formValue.generic ? formValue.generic.hub_url : undefined;\r\n\r\n // Since the options are added dynamically based on the URL protocol, they must be\r\n // normalized to use the tcomb format\r\n Object.assign(fieldOptions, {\r\n nullOption: this.nullOption,\r\n factory: t.form.Select,\r\n options: getFieldProfiles(this.props.profiles, hubUrl),\r\n transformer: intTransformer,\r\n });\r\n } else if (id === 'connection_mode_v4' || id === 'connection_mode_v6') {\r\n Object.assign(fieldOptions, {\r\n nullOption: this.nullOption,\r\n transformer: intTransformer,\r\n });\r\n } else if (id === 'use_main_chat_notify' || id === 'show_joins') {\r\n Object.assign(fieldOptions, {\r\n template: IndeterminateCheckboxField,\r\n transformer: {\r\n format: (value: boolean | null) => (value === undefined ? null : value),\r\n parse: (value: boolean | null) => value,\r\n },\r\n });\r\n }\r\n };\r\n\r\n render() {\r\n const { translate } = this.props.favT;\r\n const title = translate(this.isNew() ? 'Add favorite hub' : 'Edit favorite hub');\r\n return (\r\n <Modal\r\n className=\"fav-hub\"\r\n title={title}\r\n onApprove={this.save}\r\n closable={false}\r\n icon={IconConstants.FAVORITE}\r\n >\r\n <Form<Entry>\r\n ref={(c) => (this.form = c!)}\r\n onFieldChanged={this.onFieldChanged}\r\n onFieldSetting={this.onFieldSetting}\r\n onSave={this.onSave}\r\n fieldDefinitions={this.definitions}\r\n sourceValue={this.formValue}\r\n location={this.props.location}\r\n />\r\n </Modal>\r\n );\r\n }\r\n}\r\n\r\nexport default ModalRouteDecorator<FavoriteHubDialogProps>(\r\n ShareProfileDecorator(FavoriteHubDialog, true, {\r\n urls: {\r\n hubEntry: ({ params }, socket) => {\r\n if (!params.entryId) {\r\n return Promise.resolve(undefined);\r\n }\r\n\r\n return socket.get(`${FavoriteHubConstants.HUBS_URL}/${params.entryId}`);\r\n },\r\n },\r\n }),\r\n 'entries/:entryId?',\r\n);\r\n","import classNames from 'classnames';\r\n\r\nimport HubActions from 'actions/reflux/HubActions';\r\nimport HubSessionStore from 'stores/HubSessionStore';\r\n\r\nimport Icon from 'components/semantic/Icon';\r\nimport { RowWrapperCellChildProps } from 'components/table/RowWrapperCell';\r\n\r\nimport * as API from 'types/api';\r\nimport { useLocation, useNavigate } from 'react-router-dom';\r\n\r\nexport type ConnectStateCellProps = RowWrapperCellChildProps<\r\n API.FavoriteHubConnectState,\r\n API.FavoriteHubEntry\r\n>;\r\n\r\nconst getIcon = (state: API.FavoriteHubConnectState) => {\r\n switch (state.id) {\r\n case API.FavoriteHubConnectStateEnum.CONNECTING:\r\n return 'yellow remove';\r\n case API.FavoriteHubConnectStateEnum.CONNECTED:\r\n return 'grey remove';\r\n case API.FavoriteHubConnectStateEnum.DISCONNECTED:\r\n return 'green video play';\r\n default:\r\n }\r\n\r\n return '';\r\n};\r\n\r\nconst ConnectStateCell: React.FC<ConnectStateCellProps> = ({\r\n width,\r\n cellData,\r\n rowDataGetter,\r\n}) => {\r\n const location = useLocation();\r\n const navigate = useNavigate();\r\n\r\n const handleCreateSession = () => {\r\n HubActions.createSession(rowDataGetter!().hub_url, {\r\n location,\r\n navigate,\r\n sessionStore: HubSessionStore,\r\n });\r\n };\r\n\r\n const handleRemoveSession = () => {\r\n HubActions.removeSession({ id: cellData!.current_hub_id });\r\n };\r\n\r\n const getClickAction = () => {\r\n switch (cellData!.id) {\r\n case API.FavoriteHubConnectStateEnum.CONNECTING:\r\n case API.FavoriteHubConnectStateEnum.CONNECTED:\r\n return handleRemoveSession;\r\n case API.FavoriteHubConnectStateEnum.DISCONNECTED:\r\n default:\r\n return handleCreateSession;\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"connect-state\">\r\n <Icon\r\n icon={classNames('icon large link', getIcon(cellData!))}\r\n onClick={getClickAction()}\r\n />\r\n {width! > 120 && cellData!.str}\r\n </div>\r\n );\r\n};\r\n\r\nexport default ConnectStateCell;\r\n","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\noptions.insert = insertFn.bind(null, \"head\");\noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import SocketService from 'services/SocketService';\r\n\r\nimport FavoriteHubConstants from 'constants/FavoriteHubConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nconst handleCreate: UI.ActionHandler<undefined> = ({ navigate }) => {\r\n navigate('/favorite-hubs/entries');\r\n};\r\n\r\nconst handleEdit: UI.ActionHandler<API.FavoriteHubEntry> = ({\r\n itemData: hub,\r\n navigate,\r\n}) => {\r\n navigate(`/favorite-hubs/entries/${hub.id}`);\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<API.FavoriteHubEntry> = ({ itemData: hub }) => {\r\n return SocketService.delete(FavoriteHubConstants.HUBS_URL + '/' + hub.id);\r\n};\r\n\r\nexport const FavoriteHubCreateAction = {\r\n id: 'create',\r\n displayName: 'Add new',\r\n access: API.AccessEnum.FAVORITE_HUBS_EDIT,\r\n icon: IconConstants.CREATE,\r\n handler: handleCreate,\r\n};\r\n\r\nexport const FavoriteHubEditAction = {\r\n id: 'edit',\r\n displayName: 'Edit',\r\n access: API.AccessEnum.FAVORITE_HUBS_EDIT,\r\n icon: IconConstants.EDIT,\r\n handler: handleEdit,\r\n};\r\n\r\nexport const FavoriteHubRemoveAction = {\r\n id: 'remove',\r\n displayName: 'Remove',\r\n access: API.AccessEnum.FAVORITE_HUBS_EDIT,\r\n icon: IconConstants.REMOVE,\r\n confirmation: {\r\n content: 'Are you sure that you want to remove the favorite hub {{item.name}}?',\r\n approveCaption: 'Remove favorite hub',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove,\r\n};\r\n\r\nconst FavoriteHubEditActions: UI.ActionListType<API.FavoriteHubEntry> = {\r\n edit: FavoriteHubEditAction,\r\n remove: FavoriteHubRemoveAction,\r\n};\r\n\r\nexport const FavoriteHubActionModule = {\r\n moduleId: UI.Modules.FAVORITE_HUBS,\r\n};\r\n\r\nexport const FavoriteHubEditActionMenu = {\r\n moduleData: FavoriteHubActionModule,\r\n actions: FavoriteHubEditActions,\r\n};\r\n","import SocketService from 'services/SocketService';\r\n\r\nimport FavoriteHubConstants from 'constants/FavoriteHubConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nconst sendPassword = (hub: API.FavoriteHubEntry, password: string | null) => {\r\n return SocketService.patch(FavoriteHubConstants.HUBS_URL + '/' + hub.id, {\r\n password,\r\n });\r\n};\r\n\r\nconst handleSetPassword: UI.ActionHandler<API.FavoriteHubEntry> = (\r\n { itemData: hub },\r\n password: string,\r\n) => {\r\n return sendPassword(hub, password);\r\n};\r\n\r\nconst handleRemovePassword: UI.ActionHandler<API.FavoriteHubEntry> = ({\r\n itemData: hub,\r\n}) => {\r\n return sendPassword(hub, null);\r\n};\r\n\r\ntype Filter = UI.ActionFilter<API.FavoriteHubEntry>;\r\nconst hasPassword: Filter = ({ itemData: data }) => data.has_password;\r\nconst noPassword: Filter = (data) => !hasPassword(data);\r\n\r\nconst FavoriteHubPasswordCreateAction = {\r\n id: 'create',\r\n displayName: 'Set password',\r\n access: API.AccessEnum.FAVORITE_HUBS_EDIT,\r\n icon: IconConstants.LOCK,\r\n filter: noPassword,\r\n input: {\r\n content: 'Set password for the hub {{item.name}}',\r\n approveCaption: 'Set password',\r\n inputProps: {\r\n placeholder: 'Enter password',\r\n type: 'password',\r\n },\r\n },\r\n handler: handleSetPassword,\r\n};\r\n\r\nconst FavoriteHubPasswordChangeAction = {\r\n id: 'change',\r\n displayName: 'Change password',\r\n access: API.AccessEnum.FAVORITE_HUBS_EDIT,\r\n icon: IconConstants.EDIT,\r\n filter: hasPassword,\r\n input: {\r\n content: 'Enter new password for the hub {{item.name}}',\r\n approveCaption: 'Update password',\r\n inputProps: {\r\n placeholder: 'Enter password',\r\n type: 'password',\r\n },\r\n },\r\n handler: handleSetPassword,\r\n};\r\n\r\nconst FavoriteHubPasswordRemoveAction = {\r\n id: 'remove',\r\n displayName: 'Remove password',\r\n access: API.AccessEnum.FAVORITE_HUBS_EDIT,\r\n icon: IconConstants.REMOVE,\r\n filter: hasPassword,\r\n confirmation: {\r\n content: 'Are you sure that you want to reset the password of the hub {{item.name}}?',\r\n approveCaption: 'Remove password',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemovePassword,\r\n};\r\n\r\nconst FavoriteHubPasswordActions: UI.ActionListType<API.FavoriteHubEntry> = {\r\n create: FavoriteHubPasswordCreateAction,\r\n change: FavoriteHubPasswordChangeAction,\r\n remove: FavoriteHubPasswordRemoveAction,\r\n};\r\n\r\nexport const FavoriteHubPasswordActionModule = {\r\n moduleId: UI.Modules.FAVORITE_HUBS,\r\n subId: 'password',\r\n};\r\n\r\nexport const FavoriteHubPasswordActionMenu = {\r\n moduleData: FavoriteHubPasswordActionModule,\r\n actions: FavoriteHubPasswordActions,\r\n};\r\n","import * as React from 'react';\r\n\r\nimport FavoriteHubStore from 'stores/FavoriteHubStore';\r\nimport FavoriteHubDialog from './FavoriteHubDialog';\r\n\r\nimport VirtualTable from 'components/table/VirtualTable';\r\nimport { Column } from 'fixed-data-table-2';\r\nimport { CheckboxCell, ActionMenuCell } from 'components/table/Cell';\r\nimport ConnectStateCell from './ConnectStateCell';\r\n\r\nimport { TableActionMenu } from 'components/action-menu';\r\nimport ActionButton from 'components/ActionButton';\r\nimport { RowWrapperCellChildProps } from 'components/table/RowWrapperCell';\r\n\r\nimport LoginStore from 'stores/LoginStore';\r\n\r\nimport '../style.css';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { translate, getModuleT } from 'utils/TranslationUtils';\r\nimport { withTranslation, WithTranslation } from 'react-i18next';\r\nimport { updateFavoriteHub } from 'services/api/FavoriteHubApi';\r\nimport { runBackgroundSocketAction } from 'utils/ActionUtils';\r\nimport MenuConstants from 'constants/MenuConstants';\r\nimport {\r\n FavoriteHubActionModule,\r\n FavoriteHubCreateAction,\r\n FavoriteHubEditActionMenu,\r\n FavoriteHubPasswordActionMenu,\r\n} from 'actions/ui/favorite-hub';\r\n\r\nconst PasswordCell: React.FC<RowWrapperCellChildProps<string, API.FavoriteHubEntry>> = ({\r\n cellData,\r\n rowDataGetter,\r\n t,\r\n}) => (\r\n <TableActionMenu\r\n caption={\r\n cellData ? (\r\n <strong>{translate('Set', t!, UI.Modules.FAVORITE_HUBS)}</strong>\r\n ) : (\r\n translate('Not set', t!, UI.Modules.FAVORITE_HUBS)\r\n )\r\n }\r\n actions={FavoriteHubPasswordActionMenu}\r\n itemData={rowDataGetter!}\r\n />\r\n);\r\n\r\nclass FavoriteHubs extends React.Component<WithTranslation> {\r\n static displayName = 'FavoriteHubs';\r\n\r\n rowClassNameGetter = (rowData: API.FavoriteHubEntry) => {\r\n switch (rowData.connect_state.id) {\r\n case API.FavoriteHubConnectStateEnum.CONNECTING:\r\n return 'connecting';\r\n case API.FavoriteHubConnectStateEnum.CONNECTED:\r\n return 'connected';\r\n case API.FavoriteHubConnectStateEnum.DISCONNECTED:\r\n return 'disconnected';\r\n default:\r\n }\r\n\r\n return '';\r\n };\r\n\r\n onChangeAutoConnect = (checked: boolean, rowData: API.FavoriteHubEntry) => {\r\n return runBackgroundSocketAction(\r\n () =>\r\n updateFavoriteHub(rowData, {\r\n auto_connect: checked,\r\n }),\r\n this.props.t,\r\n );\r\n };\r\n\r\n favT = getModuleT(this.props.t, UI.Modules.FAVORITE_HUBS);\r\n render() {\r\n const footerData = (\r\n <ActionButton\r\n action={FavoriteHubCreateAction}\r\n moduleData={FavoriteHubActionModule}\r\n />\r\n );\r\n\r\n const editAccess = LoginStore.hasAccess(API.AccessEnum.HUBS_EDIT);\r\n return (\r\n <>\r\n <VirtualTable\r\n rowClassNameGetter={this.rowClassNameGetter}\r\n footerData={footerData}\r\n store={FavoriteHubStore}\r\n moduleId={UI.Modules.FAVORITE_HUBS}\r\n >\r\n <Column\r\n name=\"State\"\r\n width={45}\r\n columnKey=\"connect_state\"\r\n cell={editAccess && <ConnectStateCell />}\r\n flexGrow={3}\r\n />\r\n <Column\r\n name=\"Name\"\r\n width={150}\r\n columnKey=\"name\"\r\n flexGrow={6}\r\n cell={\r\n <ActionMenuCell\r\n actions={FavoriteHubEditActionMenu}\r\n remoteMenuId={MenuConstants.FAVORITE_HUB}\r\n />\r\n }\r\n />\r\n <Column\r\n name=\"Address\"\r\n width={270}\r\n columnKey=\"hub_url\"\r\n flexGrow={3}\r\n hideWidth={700}\r\n />\r\n <Column\r\n name=\"Auto connect\"\r\n width={65}\r\n columnKey=\"auto_connect\"\r\n cell={\r\n editAccess && (\r\n <CheckboxCell onChange={this.onChangeAutoConnect} type=\"toggle\" />\r\n )\r\n }\r\n />\r\n <Column\r\n name=\"Share profile\"\r\n width={100}\r\n columnKey=\"share_profile\"\r\n flexGrow={1}\r\n />\r\n <Column name=\"Nick\" width={100} columnKey=\"nick\" flexGrow={1} />\r\n <Column\r\n name=\"Password\"\r\n width={100}\r\n columnKey=\"has_password\"\r\n cell={<PasswordCell />}\r\n />\r\n </VirtualTable>\r\n <FavoriteHubDialog favT={this.favT} />\r\n </>\r\n );\r\n }\r\n}\r\n\r\nexport default withTranslation()(FavoriteHubs);\r\n","import * as API from 'types/api';\r\n\r\nimport SocketService from 'services/SocketService';\r\nimport FavoriteHubConstants from 'constants/FavoriteHubConstants';\r\n\r\nexport const updateFavoriteHub = (\r\n hub: API.FavoriteHubEntry,\r\n data: Partial<API.FavoriteHubEntryBase>,\r\n) => {\r\n return SocketService.patch(FavoriteHubConstants.HUBS_URL + '/' + hub.id, data);\r\n};\r\n"],"names":["___CSS_LOADER_EXPORT___","push","module","id","MODULE_URL","PROFILES_URL","PROFILE_ADDED","PROFILE_UPDATED","PROFILE_REMOVED","HIDDEN_PROFILE_ID","profileToEnumValue","profile","name","str","Component","listHidden","dataProviderDecoratorSettings","addSize","merge","urls","profiles","dataConverters","data","t","filter","p","map","size","convertProfile","onSocketConnected","addSocketListener","refetchData","_viewName","_apiUrl","FavoriteHubConstants","mixins","ViewStoreMixin","IndeterminateCheckbox","locals","inputRef","useRef","useEffect","current","value","indeterminate","ref","type","attrs","onChange","evt","target","checked","IndeterminateCheckboxTemplate","renderCheckbox","IndeterminateCheckboxField","form","Form","templates","checkbox","clone","ConnectivityModeOptions","DISABLED","ACTIVE_MODE","PASSIVE_MODE","Fields","key","title","STRUCT","definitions","STRING","optional","NUMBER","help","BOOLEAN","options","TEXT","isAdcHub","hubUrl","indexOf","FavoriteHubDialog","constructor","props","super","isNew","this","hubEntry","onFieldChanged","hasChanges","includes","generic","hub_url","share_profile","ShareProfileConstants","Promise","resolve","save","onSave","changedFields","entry","user","connectivityV4","connectivityV6","misc","SocketService","post","patch","onFieldSetting","fieldOptions","formValue","undefined","Object","assign","nullOption","factory","Select","url","transformer","template","format","parse","toFormEntry","favT","text","translate","render","Modal","className","onApprove","closable","icon","IconConstants","FAVORITE","c","fieldDefinitions","sourceValue","location","displayName","ModalRouteDecorator","ShareProfileDecorator","params","socket","entryId","get","getIcon","state","CONNECTING","CONNECTED","DISCONNECTED","width","cellData","rowDataGetter","navigate","handleCreateSession","HubActions","createSession","sessionStore","HubSessionStore","handleRemoveSession","removeSession","current_hub_id","Icon","onClick","getClickAction","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","FavoriteHubCreateAction","access","FAVORITE_HUBS_EDIT","CREATE","handler","FavoriteHubEditActions","edit","EDIT","itemData","hub","remove","REMOVE","confirmation","content","approveCaption","rejectCaption","delete","FavoriteHubActionModule","moduleId","FAVORITE_HUBS","FavoriteHubEditActionMenu","moduleData","actions","sendPassword","password","handleSetPassword","hasPassword","has_password","FavoriteHubPasswordActions","create","LOCK","input","inputProps","placeholder","change","FavoriteHubPasswordActionMenu","subId","PasswordCell","caption","FavoriteHubs","rowClassNameGetter","rowData","connect_state","onChangeAutoConnect","updateFavoriteHub","auto_connect","footerData","ActionButton","A","action","editAccess","LoginStore","hasAccess","HUBS_EDIT","VirtualTable","store","FavoriteHubStore","columnKey","cell","flexGrow","remoteMenuId","MenuConstants","FAVORITE_HUB","hideWidth"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"js/favorite-hubs.f1ced66aa7691eeee525.chunk.js","mappings":"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","sources":["webpack://airdcpp-webui/./src/routes/FavoriteHubs/style.css","webpack://airdcpp-webui/./src/constants/ShareProfileConstants.ts","webpack://airdcpp-webui/./src/decorators/ShareProfileDecorator.tsx","webpack://airdcpp-webui/./src/constants/FavoriteHubConstants.ts","webpack://airdcpp-webui/./src/stores/FavoriteHubStore.js","webpack://airdcpp-webui/./src/components/form/fields/IndeterminateCheckboxField.tsx","webpack://airdcpp-webui/./src/routes/FavoriteHubs/components/FavoriteHubDialog.tsx","webpack://airdcpp-webui/./src/routes/FavoriteHubs/components/ConnectStateCell.tsx","webpack://airdcpp-webui/./src/routes/FavoriteHubs/style.css?f7f3","webpack://airdcpp-webui/./src/actions/ui/favorite-hub/FavoriteHubActions.ts","webpack://airdcpp-webui/./src/actions/ui/favorite-hub/FavoriteHubPasswordActions.ts","webpack://airdcpp-webui/./src/routes/FavoriteHubs/components/FavoriteHubs.tsx","webpack://airdcpp-webui/./src/services/api/FavoriteHubApi.ts"],"sourcesContent":["// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.virtual-table .cell-wrapper.connected,\n.virtual-table .cell-wrapper.connected span,\n.virtual-table .cell-wrapper.connected strong {\n color: green;\n}\n\n.virtual-table .cell-wrapper.connecting,\n.virtual-table .cell-wrapper.connecting span,\n.virtual-table .cell-wrapper.connecting strong {\n color: orange;\n}\n\n.virtual-table .cell-wrapper.disconnected,\n.virtual-table .cell-wrapper.disconnected span,\n.virtual-table .cell-wrapper.disconnected strong {\n color: dimslategray;\n}\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/FavoriteHubs/style.css\"],\"names\":[],\"mappings\":\"AAAA;;;EAGE,YAAY;AACd;;AAEA;;;EAGE,aAAa;AACf;;AAEA;;;EAGE,mBAAmB;AACrB\",\"sourcesContent\":[\".virtual-table .cell-wrapper.connected,\\n.virtual-table .cell-wrapper.connected span,\\n.virtual-table .cell-wrapper.connected strong {\\n color: green;\\n}\\n\\n.virtual-table .cell-wrapper.connecting,\\n.virtual-table .cell-wrapper.connecting span,\\n.virtual-table .cell-wrapper.connecting strong {\\n color: orange;\\n}\\n\\n.virtual-table .cell-wrapper.disconnected,\\n.virtual-table .cell-wrapper.disconnected span,\\n.virtual-table .cell-wrapper.disconnected strong {\\n color: dimslategray;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","const MODULE_URL = 'share_profiles';\nexport default {\n MODULE_URL: MODULE_URL,\n PROFILES_URL: MODULE_URL,\n\n PROFILE_ADDED: 'share_profile_added',\n PROFILE_UPDATED: 'share_profile_updated',\n PROFILE_REMOVED: 'share_profile_removed',\n\n HIDDEN_PROFILE_ID: 1,\n};\n","import * as React from 'react';\r\nimport { merge } from 'lodash';\r\n\r\nimport ShareProfileConstants from 'constants/ShareProfileConstants';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n DataProviderDecoratorSettings,\r\n DataConverter,\r\n} from 'decorators/DataProviderDecorator';\r\n\r\nimport { formatSize } from 'utils/ValueFormat';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\ninterface ShareProfileDecoratorDataProps {\r\n profiles: API.ShareProfile[];\r\n}\r\n\r\nexport const profileToEnumValue = (profile: API.ShareProfile) => {\r\n return {\r\n id: profile.id,\r\n name: profile.str,\r\n };\r\n};\r\n\r\nexport type ShareProfileDecoratorChildProps = DataProviderDecoratorChildProps &\r\n ShareProfileDecoratorDataProps;\r\n\r\nconst ShareProfileDecorator = function <PropsT extends object>(\r\n Component: React.ComponentType<PropsT & ShareProfileDecoratorChildProps>,\r\n listHidden: boolean,\r\n dataProviderDecoratorSettings?: DataProviderDecoratorSettings<\r\n PropsT,\r\n ShareProfileDecoratorDataProps\r\n >,\r\n addSize = true,\r\n) {\r\n const convertProfile = (\r\n profile: API.ShareProfile,\r\n t: UI.TranslateF,\r\n ): API.ShareProfile => {\r\n let str = profile.str;\r\n if (addSize && profile.id !== ShareProfileConstants.HIDDEN_PROFILE_ID) {\r\n str += ` (${formatSize(profile.size, t)})`;\r\n }\r\n\r\n return {\r\n ...profile,\r\n str,\r\n };\r\n };\r\n\r\n const convertProfiles: DataConverter<PropsT> = (data: API.ShareProfile[], { t }) => {\r\n const profiles = data\r\n .filter((p) => listHidden || p.id !== ShareProfileConstants.HIDDEN_PROFILE_ID)\r\n .map((p) => convertProfile(p, t));\r\n\r\n return profiles;\r\n };\r\n\r\n return DataProviderDecorator<PropsT, ShareProfileDecoratorDataProps>(\r\n Component,\r\n merge(dataProviderDecoratorSettings, {\r\n urls: {\r\n profiles: ShareProfileConstants.PROFILES_URL,\r\n },\r\n dataConverters: {\r\n profiles: convertProfiles,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(\r\n ShareProfileConstants.MODULE_URL,\r\n ShareProfileConstants.PROFILE_ADDED,\r\n () => refetchData(),\r\n );\r\n addSocketListener(\r\n ShareProfileConstants.MODULE_URL,\r\n ShareProfileConstants.PROFILE_UPDATED,\r\n () => refetchData(),\r\n );\r\n addSocketListener(\r\n ShareProfileConstants.MODULE_URL,\r\n ShareProfileConstants.PROFILE_REMOVED,\r\n () => refetchData(),\r\n );\r\n },\r\n } as DataProviderDecoratorSettings<PropsT, ShareProfileDecoratorDataProps>),\r\n );\r\n};\r\n\r\nexport default ShareProfileDecorator;\r\n","const MODULE_URL = 'favorite_hubs';\n\nexport default {\n MODULE_URL: MODULE_URL,\n HUBS_URL: MODULE_URL,\n};\n","import Reflux from 'reflux';\n\nimport FavoriteHubConstants from 'constants/FavoriteHubConstants';\nimport ViewStoreMixin from 'mixins/ViewStoreMixin';\n\nexport default Reflux.createStore({\n _viewName: 'favorite_hub_view',\n _apiUrl: FavoriteHubConstants.MODULE_URL,\n mixins: [ViewStoreMixin('name')],\n});\n","import { useEffect, useRef } from 'react';\r\nimport * as React from 'react';\r\n\r\nimport * as UI from 'types/ui';\r\nimport t from 'utils/tcomb-form';\r\n\r\ninterface IndeterminateCheckboxProps {\r\n locals: UI.FormLocals<any, boolean | null, UI.EmptyObject>;\r\n}\r\n\r\nconst IndeterminateCheckbox: React.FC<IndeterminateCheckboxProps> = ({ locals }) => {\r\n const inputRef = useRef<HTMLInputElement>();\r\n\r\n useEffect(() => {\r\n if (!inputRef.current) {\r\n return;\r\n }\r\n\r\n if (typeof locals.value === 'boolean') {\r\n inputRef.current.indeterminate = false;\r\n } else {\r\n inputRef.current.indeterminate = true;\r\n }\r\n }, [locals.value]);\r\n\r\n return (\r\n <input\r\n ref={inputRef}\r\n type=\"checkbox\"\r\n {...locals.attrs}\r\n onChange={(evt) => {\r\n // Toggle between true/false/indeterminate\r\n if (locals.value === false) {\r\n locals.onChange(null);\r\n } else {\r\n locals.onChange(evt.target.checked);\r\n }\r\n }}\r\n />\r\n );\r\n};\r\n\r\ntype TCombTemplate = {\r\n renderCheckbox: (\r\n locals: UI.FormLocals<any, boolean | null, UI.EmptyObject>,\r\n ) => React.ReactNode;\r\n};\r\n\r\nconst IndeterminateCheckboxTemplate: TCombTemplate = {\r\n renderCheckbox(locals) {\r\n return <IndeterminateCheckbox locals={locals} />;\r\n },\r\n};\r\n\r\nexport const IndeterminateCheckboxField = t.form.Form.templates.checkbox.clone(\r\n IndeterminateCheckboxTemplate,\r\n);\r\n","import { Component } from 'react';\r\nimport Modal from 'components/semantic/Modal';\r\n\r\nimport ModalRouteDecorator, {\r\n ModalRouteDecoratorChildProps,\r\n} from 'decorators/ModalRouteDecorator';\r\n\r\nimport ShareProfileConstants from 'constants/ShareProfileConstants';\r\nimport FavoriteHubConstants from 'constants/FavoriteHubConstants';\r\n\r\nimport SocketService from 'services/SocketService';\r\n\r\nimport ShareProfileDecorator, {\r\n profileToEnumValue,\r\n ShareProfileDecoratorChildProps,\r\n} from 'decorators/ShareProfileDecorator';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport t from 'utils/tcomb-form';\r\n\r\nimport Form, {\r\n FormFieldChangeHandler,\r\n FormFieldSettingHandler,\r\n FormSaveHandler,\r\n} from 'components/form/Form';\r\nimport { normalizeEnumValue, intTransformer, translateForm } from 'utils/FormUtils';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { FavoriteHubEntry } from 'types/api';\r\nimport { IndeterminateCheckboxField } from 'components/form/fields/IndeterminateCheckboxField';\r\n\r\nconst ConnectivityModeOptions: API.SettingEnumOption[] = [\r\n {\r\n id: API.ConnectivityModeEnum.DISABLED,\r\n name: 'Disabled',\r\n },\r\n {\r\n id: API.ConnectivityModeEnum.ACTIVE_MODE,\r\n name: 'Active mode',\r\n },\r\n {\r\n id: API.ConnectivityModeEnum.PASSIVE_MODE,\r\n name: 'Passive mode',\r\n },\r\n];\r\n\r\nconst Fields: UI.FormFieldDefinition[] = [\r\n {\r\n key: 'generic',\r\n title: 'Hub properties',\r\n type: API.SettingTypeEnum.STRUCT,\r\n definitions: [\r\n {\r\n key: 'name',\r\n title: 'Name',\r\n type: API.SettingTypeEnum.STRING,\r\n },\r\n {\r\n key: 'hub_url',\r\n title: 'Hub URL',\r\n type: API.SettingTypeEnum.STRING,\r\n },\r\n {\r\n key: 'hub_description',\r\n title: 'Hub description',\r\n type: API.SettingTypeEnum.STRING,\r\n optional: true,\r\n },\r\n {\r\n key: 'share_profile',\r\n title: 'Share profile',\r\n type: API.SettingTypeEnum.NUMBER,\r\n // eslint-disable-next-line max-len\r\n help: 'Custom share profiles can be selected only after entering an ADC hub address (starting with adc:// or adcs://)',\r\n optional: true,\r\n },\r\n {\r\n key: 'auto_connect',\r\n title: 'Auto connect',\r\n type: API.SettingTypeEnum.BOOLEAN,\r\n },\r\n ],\r\n },\r\n {\r\n key: 'user',\r\n title: 'User setting overrides',\r\n type: API.SettingTypeEnum.STRUCT,\r\n definitions: [\r\n {\r\n key: 'nick',\r\n title: 'Nick',\r\n type: API.SettingTypeEnum.STRING,\r\n optional: true,\r\n },\r\n {\r\n key: 'user_description',\r\n title: 'User description',\r\n type: API.SettingTypeEnum.STRING,\r\n optional: true,\r\n },\r\n ],\r\n },\r\n {\r\n key: 'connectivityV4',\r\n title: 'Connectivity setting overrides (IPv4)',\r\n type: API.SettingTypeEnum.STRUCT,\r\n definitions: [\r\n {\r\n key: 'connection_mode_v4',\r\n title: 'Connectivity mode',\r\n type: API.SettingTypeEnum.NUMBER,\r\n optional: true,\r\n options: ConnectivityModeOptions,\r\n },\r\n {\r\n key: 'connection_ip_v4',\r\n title: 'IP address',\r\n type: API.SettingTypeEnum.STRING,\r\n optional: true,\r\n },\r\n ],\r\n },\r\n {\r\n key: 'connectivityV6',\r\n title: 'Connectivity setting overrides (IPv6)',\r\n type: API.SettingTypeEnum.STRUCT,\r\n definitions: [\r\n {\r\n key: 'connection_mode_v6',\r\n title: 'Connectivity mode',\r\n type: API.SettingTypeEnum.NUMBER,\r\n optional: true,\r\n options: ConnectivityModeOptions,\r\n },\r\n {\r\n key: 'connection_ip_v6',\r\n title: 'IP address',\r\n type: API.SettingTypeEnum.STRING,\r\n optional: true,\r\n },\r\n ],\r\n },\r\n {\r\n key: 'misc',\r\n title: 'Miscellaneous overrides',\r\n type: API.SettingTypeEnum.STRUCT,\r\n definitions: [\r\n {\r\n key: 'use_main_chat_notify',\r\n title: 'Use chat notification',\r\n type: API.SettingTypeEnum.BOOLEAN,\r\n optional: true,\r\n },\r\n {\r\n key: 'show_joins',\r\n title: 'Show joins/parts',\r\n type: API.SettingTypeEnum.BOOLEAN,\r\n optional: true,\r\n },\r\n {\r\n key: 'away_message',\r\n title: 'Away message',\r\n type: API.SettingTypeEnum.TEXT,\r\n optional: true,\r\n },\r\n ],\r\n },\r\n];\r\n\r\ninterface Entry extends UI.FormValueMap {\r\n generic: Pick<\r\n FavoriteHubEntry,\r\n 'name' | 'hub_url' | 'hub_description' | 'auto_connect' | 'share_profile'\r\n >;\r\n user: Pick<FavoriteHubEntry, 'nick' | 'user_description'>;\r\n connectivityV4: Pick<FavoriteHubEntry, 'connection_mode_v4' | 'connection_ip_v4'>;\r\n connectivityV6: Pick<FavoriteHubEntry, 'connection_mode_v6' | 'connection_ip_v6'>;\r\n misc: Pick<FavoriteHubEntry, 'use_main_chat_notify' | 'show_joins' | 'away_message'>;\r\n}\r\n\r\nconst toFormEntry = (entry?: API.FavoriteHubEntry): Entry | undefined => {\r\n if (!entry) {\r\n return undefined;\r\n }\r\n\r\n return {\r\n generic: entry,\r\n user: entry,\r\n connectivityV4: entry,\r\n connectivityV6: entry,\r\n misc: entry,\r\n };\r\n};\r\n\r\nconst toFavoriteHub = (\r\n entry: RecursivePartial<Entry>,\r\n): RecursivePartial<API.FavoriteHubEntry> => {\r\n return {\r\n ...entry.generic,\r\n ...entry.user,\r\n ...entry.connectivityV4,\r\n ...entry.connectivityV6,\r\n ...entry.misc,\r\n };\r\n};\r\n\r\nconst isAdcHub = (hubUrl?: string) =>\r\n !!hubUrl && (hubUrl.indexOf('adc://') === 0 || hubUrl.indexOf('adcs://') === 0);\r\n\r\n// Get selection values for the profiles field\r\nconst getFieldProfiles = (\r\n profiles: API.SettingEnumOption[],\r\n url?: string,\r\n): UI.FormOption[] => {\r\n return profiles\r\n .filter((p) => isAdcHub(url) || p.id === ShareProfileConstants.HIDDEN_PROFILE_ID)\r\n .map(profileToEnumValue)\r\n .map(normalizeEnumValue);\r\n};\r\n\r\ninterface FavoriteHubDialogProps {\r\n favT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface DataProps {\r\n hubEntry?: API.FavoriteHubEntry;\r\n}\r\n\r\n/*interface RouteProps {\r\n entryId: string;\r\n}*/\r\n\r\ntype Props = FavoriteHubDialogProps &\r\n DataProps &\r\n ShareProfileDecoratorChildProps &\r\n ModalRouteDecoratorChildProps;\r\n\r\nclass FavoriteHubDialog extends Component<Props> {\r\n static displayName = 'FavoriteHubDialog';\r\n\r\n formValue: Entry | undefined;\r\n\r\n constructor(props: Props) {\r\n super(props);\r\n\r\n this.formValue = toFormEntry(props.hubEntry);\r\n this.definitions = translateForm(Fields, props.favT);\r\n this.nullOption = {\r\n value: 'null',\r\n text: props.favT.translate('Global default'),\r\n };\r\n }\r\n\r\n isNew = () => {\r\n return !this.props.hubEntry;\r\n };\r\n\r\n nullOption: UI.FormOption<string>;\r\n definitions: UI.FormFieldDefinition[];\r\n\r\n form: Form<Entry>;\r\n\r\n onFieldChanged: FormFieldChangeHandler<Entry> = (id, value, hasChanges) => {\r\n if (id.includes('hub_url')) {\r\n if (\r\n !isAdcHub(value.generic!.hub_url) &&\r\n value.share_profile !== ShareProfileConstants.HIDDEN_PROFILE_ID\r\n ) {\r\n // Reset share profile\r\n return Promise.resolve({\r\n share_profile: null,\r\n });\r\n }\r\n }\r\n\r\n return null;\r\n };\r\n\r\n save = () => {\r\n return this.form.save();\r\n };\r\n\r\n onSave: FormSaveHandler<Entry> = (changedFields) => {\r\n const hubEntry = toFavoriteHub(changedFields);\r\n if (this.isNew()) {\r\n return SocketService.post(FavoriteHubConstants.HUBS_URL, hubEntry);\r\n }\r\n\r\n return SocketService.patch(\r\n `${FavoriteHubConstants.HUBS_URL}/${this.props.hubEntry!.id}`,\r\n hubEntry,\r\n );\r\n };\r\n\r\n onFieldSetting: FormFieldSettingHandler<Entry> = (id, fieldOptions, formValue) => {\r\n if (id === 'share_profile') {\r\n const hubUrl = formValue.generic ? formValue.generic.hub_url : undefined;\r\n\r\n // Since the options are added dynamically based on the URL protocol, they must be\r\n // normalized to use the tcomb format\r\n Object.assign(fieldOptions, {\r\n nullOption: this.nullOption,\r\n factory: t.form.Select,\r\n options: getFieldProfiles(this.props.profiles, hubUrl),\r\n transformer: intTransformer,\r\n });\r\n } else if (id === 'connection_mode_v4' || id === 'connection_mode_v6') {\r\n Object.assign(fieldOptions, {\r\n nullOption: this.nullOption,\r\n transformer: intTransformer,\r\n });\r\n } else if (id === 'use_main_chat_notify' || id === 'show_joins') {\r\n Object.assign(fieldOptions, {\r\n template: IndeterminateCheckboxField,\r\n transformer: {\r\n format: (value: boolean | null) => (value === undefined ? null : value),\r\n parse: (value: boolean | null) => value,\r\n },\r\n });\r\n }\r\n };\r\n\r\n render() {\r\n const { translate } = this.props.favT;\r\n const title = translate(this.isNew() ? 'Add favorite hub' : 'Edit favorite hub');\r\n return (\r\n <Modal\r\n className=\"fav-hub\"\r\n title={title}\r\n onApprove={this.save}\r\n closable={false}\r\n icon={IconConstants.FAVORITE}\r\n >\r\n <Form<Entry>\r\n ref={(c) => (this.form = c!)}\r\n onFieldChanged={this.onFieldChanged}\r\n onFieldSetting={this.onFieldSetting}\r\n onSave={this.onSave}\r\n fieldDefinitions={this.definitions}\r\n sourceValue={this.formValue}\r\n location={this.props.location}\r\n />\r\n </Modal>\r\n );\r\n }\r\n}\r\n\r\nexport default ModalRouteDecorator<FavoriteHubDialogProps>(\r\n ShareProfileDecorator(FavoriteHubDialog, true, {\r\n urls: {\r\n hubEntry: ({ params }, socket) => {\r\n if (!params.entryId) {\r\n return Promise.resolve(undefined);\r\n }\r\n\r\n return socket.get(`${FavoriteHubConstants.HUBS_URL}/${params.entryId}`);\r\n },\r\n },\r\n }),\r\n 'entries/:entryId?',\r\n);\r\n","import classNames from 'classnames';\r\n\r\nimport HubActions from 'actions/reflux/HubActions';\r\nimport HubSessionStore from 'stores/HubSessionStore';\r\n\r\nimport Icon from 'components/semantic/Icon';\r\nimport { RowWrapperCellChildProps } from 'components/table/RowWrapperCell';\r\n\r\nimport * as API from 'types/api';\r\nimport { useLocation, useNavigate } from 'react-router-dom';\r\n\r\nexport type ConnectStateCellProps = RowWrapperCellChildProps<\r\n API.FavoriteHubConnectState,\r\n API.FavoriteHubEntry\r\n>;\r\n\r\nconst getIcon = (state: API.FavoriteHubConnectState) => {\r\n switch (state.id) {\r\n case API.FavoriteHubConnectStateEnum.CONNECTING:\r\n return 'yellow remove';\r\n case API.FavoriteHubConnectStateEnum.CONNECTED:\r\n return 'grey remove';\r\n case API.FavoriteHubConnectStateEnum.DISCONNECTED:\r\n return 'green video play';\r\n default:\r\n }\r\n\r\n return '';\r\n};\r\n\r\nconst ConnectStateCell: React.FC<ConnectStateCellProps> = ({\r\n width,\r\n cellData,\r\n rowDataGetter,\r\n}) => {\r\n const location = useLocation();\r\n const navigate = useNavigate();\r\n\r\n const handleCreateSession = () => {\r\n HubActions.createSession(rowDataGetter!().hub_url, {\r\n location,\r\n navigate,\r\n sessionStore: HubSessionStore,\r\n });\r\n };\r\n\r\n const handleRemoveSession = () => {\r\n HubActions.removeSession({ id: cellData!.current_hub_id });\r\n };\r\n\r\n const getClickAction = () => {\r\n switch (cellData!.id) {\r\n case API.FavoriteHubConnectStateEnum.CONNECTING:\r\n case API.FavoriteHubConnectStateEnum.CONNECTED:\r\n return handleRemoveSession;\r\n case API.FavoriteHubConnectStateEnum.DISCONNECTED:\r\n default:\r\n return handleCreateSession;\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"connect-state\">\r\n <Icon\r\n icon={classNames('icon large link', getIcon(cellData!))}\r\n onClick={getClickAction()}\r\n />\r\n {width! > 120 && cellData!.str}\r\n </div>\r\n );\r\n};\r\n\r\nexport default ConnectStateCell;\r\n","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\noptions.insert = insertFn.bind(null, \"head\");\noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import SocketService from 'services/SocketService';\r\n\r\nimport FavoriteHubConstants from 'constants/FavoriteHubConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nconst handleCreate: UI.ActionHandler<undefined> = ({ navigate }) => {\r\n navigate('/favorite-hubs/entries');\r\n};\r\n\r\nconst handleEdit: UI.ActionHandler<API.FavoriteHubEntry> = ({\r\n itemData: hub,\r\n navigate,\r\n}) => {\r\n navigate(`/favorite-hubs/entries/${hub.id}`);\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<API.FavoriteHubEntry> = ({ itemData: hub }) => {\r\n return SocketService.delete(FavoriteHubConstants.HUBS_URL + '/' + hub.id);\r\n};\r\n\r\nexport const FavoriteHubCreateAction = {\r\n id: 'create',\r\n displayName: 'Add new',\r\n access: API.AccessEnum.FAVORITE_HUBS_EDIT,\r\n icon: IconConstants.CREATE,\r\n handler: handleCreate,\r\n};\r\n\r\nexport const FavoriteHubEditAction = {\r\n id: 'edit',\r\n displayName: 'Edit',\r\n access: API.AccessEnum.FAVORITE_HUBS_EDIT,\r\n icon: IconConstants.EDIT,\r\n handler: handleEdit,\r\n};\r\n\r\nexport const FavoriteHubRemoveAction = {\r\n id: 'remove',\r\n displayName: 'Remove',\r\n access: API.AccessEnum.FAVORITE_HUBS_EDIT,\r\n icon: IconConstants.REMOVE,\r\n confirmation: {\r\n content: 'Are you sure that you want to remove the favorite hub {{item.name}}?',\r\n approveCaption: 'Remove favorite hub',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove,\r\n};\r\n\r\nconst FavoriteHubEditActions: UI.ActionListType<API.FavoriteHubEntry> = {\r\n edit: FavoriteHubEditAction,\r\n remove: FavoriteHubRemoveAction,\r\n};\r\n\r\nexport const FavoriteHubActionModule = {\r\n moduleId: UI.Modules.FAVORITE_HUBS,\r\n};\r\n\r\nexport const FavoriteHubEditActionMenu = {\r\n moduleData: FavoriteHubActionModule,\r\n actions: FavoriteHubEditActions,\r\n};\r\n","import SocketService from 'services/SocketService';\r\n\r\nimport FavoriteHubConstants from 'constants/FavoriteHubConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nconst sendPassword = (hub: API.FavoriteHubEntry, password: string | null) => {\r\n return SocketService.patch(FavoriteHubConstants.HUBS_URL + '/' + hub.id, {\r\n password,\r\n });\r\n};\r\n\r\nconst handleSetPassword: UI.ActionHandler<API.FavoriteHubEntry> = (\r\n { itemData: hub },\r\n password: string,\r\n) => {\r\n return sendPassword(hub, password);\r\n};\r\n\r\nconst handleRemovePassword: UI.ActionHandler<API.FavoriteHubEntry> = ({\r\n itemData: hub,\r\n}) => {\r\n return sendPassword(hub, null);\r\n};\r\n\r\ntype Filter = UI.ActionFilter<API.FavoriteHubEntry>;\r\nconst hasPassword: Filter = ({ itemData: data }) => data.has_password;\r\nconst noPassword: Filter = (data) => !hasPassword(data);\r\n\r\nconst FavoriteHubPasswordCreateAction = {\r\n id: 'create',\r\n displayName: 'Set password',\r\n access: API.AccessEnum.FAVORITE_HUBS_EDIT,\r\n icon: IconConstants.LOCK,\r\n filter: noPassword,\r\n input: {\r\n content: 'Set password for the hub {{item.name}}',\r\n approveCaption: 'Set password',\r\n inputProps: {\r\n placeholder: 'Enter password',\r\n type: 'password',\r\n },\r\n },\r\n handler: handleSetPassword,\r\n};\r\n\r\nconst FavoriteHubPasswordChangeAction = {\r\n id: 'change',\r\n displayName: 'Change password',\r\n access: API.AccessEnum.FAVORITE_HUBS_EDIT,\r\n icon: IconConstants.EDIT,\r\n filter: hasPassword,\r\n input: {\r\n content: 'Enter new password for the hub {{item.name}}',\r\n approveCaption: 'Update password',\r\n inputProps: {\r\n placeholder: 'Enter password',\r\n type: 'password',\r\n },\r\n },\r\n handler: handleSetPassword,\r\n};\r\n\r\nconst FavoriteHubPasswordRemoveAction = {\r\n id: 'remove',\r\n displayName: 'Remove password',\r\n access: API.AccessEnum.FAVORITE_HUBS_EDIT,\r\n icon: IconConstants.REMOVE,\r\n filter: hasPassword,\r\n confirmation: {\r\n content: 'Are you sure that you want to reset the password of the hub {{item.name}}?',\r\n approveCaption: 'Remove password',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemovePassword,\r\n};\r\n\r\nconst FavoriteHubPasswordActions: UI.ActionListType<API.FavoriteHubEntry> = {\r\n create: FavoriteHubPasswordCreateAction,\r\n change: FavoriteHubPasswordChangeAction,\r\n remove: FavoriteHubPasswordRemoveAction,\r\n};\r\n\r\nexport const FavoriteHubPasswordActionModule = {\r\n moduleId: UI.Modules.FAVORITE_HUBS,\r\n subId: 'password',\r\n};\r\n\r\nexport const FavoriteHubPasswordActionMenu = {\r\n moduleData: FavoriteHubPasswordActionModule,\r\n actions: FavoriteHubPasswordActions,\r\n};\r\n","import * as React from 'react';\r\n\r\nimport FavoriteHubStore from 'stores/FavoriteHubStore';\r\nimport FavoriteHubDialog from './FavoriteHubDialog';\r\n\r\nimport VirtualTable from 'components/table/VirtualTable';\r\nimport { Column } from 'fixed-data-table-2';\r\nimport { CheckboxCell, ActionMenuCell } from 'components/table/Cell';\r\nimport ConnectStateCell from './ConnectStateCell';\r\n\r\nimport { TableActionMenu } from 'components/action-menu';\r\nimport ActionButton from 'components/ActionButton';\r\nimport { RowWrapperCellChildProps } from 'components/table/RowWrapperCell';\r\n\r\nimport LoginStore from 'stores/LoginStore';\r\n\r\nimport '../style.css';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { translate, getModuleT } from 'utils/TranslationUtils';\r\nimport { withTranslation, WithTranslation } from 'react-i18next';\r\nimport { updateFavoriteHub } from 'services/api/FavoriteHubApi';\r\nimport { runBackgroundSocketAction } from 'utils/ActionUtils';\r\nimport MenuConstants from 'constants/MenuConstants';\r\nimport {\r\n FavoriteHubActionModule,\r\n FavoriteHubCreateAction,\r\n FavoriteHubEditActionMenu,\r\n FavoriteHubPasswordActionMenu,\r\n} from 'actions/ui/favorite-hub';\r\n\r\nconst PasswordCell: React.FC<RowWrapperCellChildProps<string, API.FavoriteHubEntry>> = ({\r\n cellData,\r\n rowDataGetter,\r\n t,\r\n}) => (\r\n <TableActionMenu\r\n caption={\r\n cellData ? (\r\n <strong>{translate('Set', t!, UI.Modules.FAVORITE_HUBS)}</strong>\r\n ) : (\r\n translate('Not set', t!, UI.Modules.FAVORITE_HUBS)\r\n )\r\n }\r\n actions={FavoriteHubPasswordActionMenu}\r\n itemData={rowDataGetter!}\r\n />\r\n);\r\n\r\nclass FavoriteHubs extends React.Component<WithTranslation> {\r\n static displayName = 'FavoriteHubs';\r\n\r\n rowClassNameGetter = (rowData: API.FavoriteHubEntry) => {\r\n switch (rowData.connect_state.id) {\r\n case API.FavoriteHubConnectStateEnum.CONNECTING:\r\n return 'connecting';\r\n case API.FavoriteHubConnectStateEnum.CONNECTED:\r\n return 'connected';\r\n case API.FavoriteHubConnectStateEnum.DISCONNECTED:\r\n return 'disconnected';\r\n default:\r\n }\r\n\r\n return '';\r\n };\r\n\r\n onChangeAutoConnect = (checked: boolean, rowData: API.FavoriteHubEntry) => {\r\n return runBackgroundSocketAction(\r\n () =>\r\n updateFavoriteHub(rowData, {\r\n auto_connect: checked,\r\n }),\r\n this.props.t,\r\n );\r\n };\r\n\r\n favT = getModuleT(this.props.t, UI.Modules.FAVORITE_HUBS);\r\n render() {\r\n const footerData = (\r\n <ActionButton\r\n action={FavoriteHubCreateAction}\r\n moduleData={FavoriteHubActionModule}\r\n />\r\n );\r\n\r\n const editAccess = LoginStore.hasAccess(API.AccessEnum.HUBS_EDIT);\r\n return (\r\n <>\r\n <VirtualTable\r\n rowClassNameGetter={this.rowClassNameGetter}\r\n footerData={footerData}\r\n store={FavoriteHubStore}\r\n moduleId={UI.Modules.FAVORITE_HUBS}\r\n >\r\n <Column\r\n name=\"State\"\r\n width={45}\r\n columnKey=\"connect_state\"\r\n cell={editAccess && <ConnectStateCell />}\r\n flexGrow={3}\r\n />\r\n <Column\r\n name=\"Name\"\r\n width={150}\r\n columnKey=\"name\"\r\n flexGrow={6}\r\n cell={\r\n <ActionMenuCell\r\n actions={FavoriteHubEditActionMenu}\r\n remoteMenuId={MenuConstants.FAVORITE_HUB}\r\n />\r\n }\r\n />\r\n <Column\r\n name=\"Address\"\r\n width={270}\r\n columnKey=\"hub_url\"\r\n flexGrow={3}\r\n hideWidth={700}\r\n />\r\n <Column\r\n name=\"Auto connect\"\r\n width={65}\r\n columnKey=\"auto_connect\"\r\n cell={\r\n editAccess && (\r\n <CheckboxCell onChange={this.onChangeAutoConnect} type=\"toggle\" />\r\n )\r\n }\r\n />\r\n <Column\r\n name=\"Share profile\"\r\n width={100}\r\n columnKey=\"share_profile\"\r\n flexGrow={1}\r\n />\r\n <Column name=\"Nick\" width={100} columnKey=\"nick\" flexGrow={1} />\r\n <Column\r\n name=\"Password\"\r\n width={100}\r\n columnKey=\"has_password\"\r\n cell={<PasswordCell />}\r\n />\r\n </VirtualTable>\r\n <FavoriteHubDialog favT={this.favT} />\r\n </>\r\n );\r\n }\r\n}\r\n\r\nexport default withTranslation()(FavoriteHubs);\r\n","import * as API from 'types/api';\r\n\r\nimport SocketService from 'services/SocketService';\r\nimport FavoriteHubConstants from 'constants/FavoriteHubConstants';\r\n\r\nexport const updateFavoriteHub = (\r\n hub: API.FavoriteHubEntry,\r\n data: Partial<API.FavoriteHubEntryBase>,\r\n) => {\r\n return SocketService.patch(FavoriteHubConstants.HUBS_URL + '/' + hub.id, data);\r\n};\r\n"],"names":["___CSS_LOADER_EXPORT___","push","module","id","MODULE_URL","PROFILES_URL","PROFILE_ADDED","PROFILE_UPDATED","PROFILE_REMOVED","HIDDEN_PROFILE_ID","profileToEnumValue","profile","name","str","Component","listHidden","dataProviderDecoratorSettings","addSize","merge","urls","profiles","dataConverters","data","t","filter","p","map","size","convertProfile","onSocketConnected","addSocketListener","refetchData","_viewName","_apiUrl","FavoriteHubConstants","mixins","ViewStoreMixin","IndeterminateCheckbox","locals","inputRef","useRef","useEffect","current","value","indeterminate","ref","type","attrs","onChange","evt","target","checked","IndeterminateCheckboxTemplate","renderCheckbox","IndeterminateCheckboxField","form","Form","templates","checkbox","clone","ConnectivityModeOptions","DISABLED","ACTIVE_MODE","PASSIVE_MODE","Fields","key","title","STRUCT","definitions","STRING","optional","NUMBER","help","BOOLEAN","options","TEXT","isAdcHub","hubUrl","indexOf","FavoriteHubDialog","constructor","props","super","isNew","this","hubEntry","onFieldChanged","hasChanges","includes","generic","hub_url","share_profile","ShareProfileConstants","Promise","resolve","save","onSave","changedFields","entry","user","connectivityV4","connectivityV6","misc","SocketService","post","patch","onFieldSetting","fieldOptions","formValue","undefined","Object","assign","nullOption","factory","Select","url","transformer","template","format","parse","toFormEntry","favT","text","translate","render","Modal","className","onApprove","closable","icon","IconConstants","FAVORITE","c","fieldDefinitions","sourceValue","location","displayName","ModalRouteDecorator","ShareProfileDecorator","params","socket","entryId","get","getIcon","state","CONNECTING","CONNECTED","DISCONNECTED","width","cellData","rowDataGetter","navigate","handleCreateSession","HubActions","createSession","sessionStore","HubSessionStore","handleRemoveSession","removeSession","current_hub_id","Icon","onClick","getClickAction","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","FavoriteHubCreateAction","access","FAVORITE_HUBS_EDIT","CREATE","handler","FavoriteHubEditActions","edit","EDIT","itemData","hub","remove","REMOVE","confirmation","content","approveCaption","rejectCaption","delete","FavoriteHubActionModule","moduleId","FAVORITE_HUBS","FavoriteHubEditActionMenu","moduleData","actions","sendPassword","password","handleSetPassword","hasPassword","has_password","FavoriteHubPasswordActions","create","LOCK","input","inputProps","placeholder","change","FavoriteHubPasswordActionMenu","subId","PasswordCell","caption","FavoriteHubs","rowClassNameGetter","rowData","connect_state","onChangeAutoConnect","updateFavoriteHub","auto_connect","footerData","ActionButton","A","action","editAccess","LoginStore","hasAccess","HUBS_EDIT","VirtualTable","store","FavoriteHubStore","columnKey","cell","flexGrow","remoteMenuId","MenuConstants","FAVORITE_HUB","hideWidth"],"sourceRoot":""}
|