airdcpp-webui 2.14.0-beta.13 → 2.14.0-beta.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/index.html +1 -1
  2. package/dist/js/544.73cf8e69cd2348500250.chunk.js +2 -0
  3. package/dist/js/544.73cf8e69cd2348500250.chunk.js.gz +0 -0
  4. package/dist/js/544.73cf8e69cd2348500250.chunk.js.map +1 -0
  5. package/dist/js/{550.43735d298b0c3e70c6bd.chunk.js → 550.10703917b7e833fa8ae9.chunk.js} +2 -2
  6. package/dist/js/550.10703917b7e833fa8ae9.chunk.js.gz +0 -0
  7. package/dist/js/550.10703917b7e833fa8ae9.chunk.js.map +1 -0
  8. package/dist/js/{807.52502ffbf0c34539314f.chunk.js → 807.ae2142c32d74128cca0c.chunk.js} +2 -2
  9. package/dist/js/807.ae2142c32d74128cca0c.chunk.js.gz +0 -0
  10. package/dist/js/{807.52502ffbf0c34539314f.chunk.js.map → 807.ae2142c32d74128cca0c.chunk.js.map} +1 -1
  11. package/dist/js/{926.c344692db21ff4746b0d.chunk.js → 926.b8efc4bf2e958f4b5cb2.chunk.js} +2 -2
  12. package/dist/js/926.b8efc4bf2e958f4b5cb2.chunk.js.gz +0 -0
  13. package/dist/js/926.b8efc4bf2e958f4b5cb2.chunk.js.map +1 -0
  14. package/dist/js/filelists.ce2bf2a0664eef3a9aec.chunk.js +2 -0
  15. package/dist/js/filelists.ce2bf2a0664eef3a9aec.chunk.js.gz +0 -0
  16. package/dist/js/filelists.ce2bf2a0664eef3a9aec.chunk.js.map +1 -0
  17. package/dist/js/{files.64f72b3869667e0d4c7e.chunk.js → files.2424018fc68f621a73ea.chunk.js} +1 -1
  18. package/dist/js/files.2424018fc68f621a73ea.chunk.js.gz +0 -0
  19. package/dist/js/files.2424018fc68f621a73ea.chunk.js.map +1 -0
  20. package/dist/js/{home.e0421a3f337897e900d5.chunk.js → home.630ba9695cb5314daa39.chunk.js} +3 -3
  21. package/dist/js/home.630ba9695cb5314daa39.chunk.js.gz +0 -0
  22. package/dist/js/home.630ba9695cb5314daa39.chunk.js.map +1 -0
  23. package/dist/js/{hubs.82f0f581d104a03d4461.chunk.js → hubs.5dce2652372b61531a37.chunk.js} +2 -2
  24. package/dist/js/hubs.5dce2652372b61531a37.chunk.js.gz +0 -0
  25. package/dist/js/hubs.5dce2652372b61531a37.chunk.js.map +1 -0
  26. package/dist/js/locales/en-webui-main-missing-json.a4704a173bebeebdc24d.chunk.js +1 -0
  27. package/dist/js/locales/en-webui-main-missing-json.a4704a173bebeebdc24d.chunk.js.gz +0 -0
  28. package/dist/js/locales/fr-webui-main-json.a977c3aaad84bfe0f69d.chunk.js +1 -0
  29. package/dist/js/locales/fr-webui-main-json.a977c3aaad84bfe0f69d.chunk.js.gz +0 -0
  30. package/dist/js/locales/pt-br-webui-main-json.1e68869ee8f4ff49c12a.chunk.js +1 -0
  31. package/dist/js/locales/pt-br-webui-main-json.1e68869ee8f4ff49c12a.chunk.js.gz +0 -0
  32. package/dist/js/locales/zh_CN-GB2312-webui-main-json.c56c6d389b7951c4f74d.chunk.js +1 -0
  33. package/dist/js/locales/zh_CN-GB2312-webui-main-json.c56c6d389b7951c4f74d.chunk.js.gz +0 -0
  34. package/dist/js/main.67a9c3fc3a221e13daba.entry.js +3 -0
  35. package/dist/js/main.67a9c3fc3a221e13daba.entry.js.gz +0 -0
  36. package/dist/js/{main.eea930701ff0165c262c.entry.js.map → main.67a9c3fc3a221e13daba.entry.js.map} +1 -1
  37. package/dist/js/messages.3d372056d582e1271e3b.chunk.js +2 -0
  38. package/dist/js/messages.3d372056d582e1271e3b.chunk.js.gz +0 -0
  39. package/dist/js/messages.3d372056d582e1271e3b.chunk.js.map +1 -0
  40. package/dist/js/search.34d3dd17a43e78572dcc.chunk.js +2 -0
  41. package/dist/js/search.34d3dd17a43e78572dcc.chunk.js.gz +0 -0
  42. package/dist/js/search.34d3dd17a43e78572dcc.chunk.js.map +1 -0
  43. package/dist/js/settings.4295b3c85b2d33c23715.chunk.js +2 -0
  44. package/dist/js/settings.4295b3c85b2d33c23715.chunk.js.gz +0 -0
  45. package/dist/js/settings.4295b3c85b2d33c23715.chunk.js.map +1 -0
  46. package/dist/sw.js +1 -1
  47. package/dist/sw.js.gz +0 -0
  48. package/dist/sw.js.map +1 -1
  49. package/package.json +1 -1
  50. package/vitest.config.browser.ts +9 -1
  51. package/vitest.config.common.ts +4 -4
  52. package/vitest.config.node.ts +2 -0
  53. package/vitest.config.ts +10 -0
  54. package/dist/js/544.23c1c02472b86725dbe7.chunk.js +0 -2
  55. package/dist/js/544.23c1c02472b86725dbe7.chunk.js.gz +0 -0
  56. package/dist/js/544.23c1c02472b86725dbe7.chunk.js.map +0 -1
  57. package/dist/js/550.43735d298b0c3e70c6bd.chunk.js.gz +0 -0
  58. package/dist/js/550.43735d298b0c3e70c6bd.chunk.js.map +0 -1
  59. package/dist/js/807.52502ffbf0c34539314f.chunk.js.gz +0 -0
  60. package/dist/js/926.c344692db21ff4746b0d.chunk.js.gz +0 -0
  61. package/dist/js/926.c344692db21ff4746b0d.chunk.js.map +0 -1
  62. package/dist/js/filelists.f098fc396efc445ef837.chunk.js +0 -2
  63. package/dist/js/filelists.f098fc396efc445ef837.chunk.js.gz +0 -0
  64. package/dist/js/filelists.f098fc396efc445ef837.chunk.js.map +0 -1
  65. package/dist/js/files.64f72b3869667e0d4c7e.chunk.js.gz +0 -0
  66. package/dist/js/files.64f72b3869667e0d4c7e.chunk.js.map +0 -1
  67. package/dist/js/home.e0421a3f337897e900d5.chunk.js.gz +0 -0
  68. package/dist/js/home.e0421a3f337897e900d5.chunk.js.map +0 -1
  69. package/dist/js/hubs.82f0f581d104a03d4461.chunk.js.gz +0 -0
  70. package/dist/js/hubs.82f0f581d104a03d4461.chunk.js.map +0 -1
  71. package/dist/js/locales/en-webui-main-missing-json.2d88b62200bc732efcd6.chunk.js +0 -1
  72. package/dist/js/locales/en-webui-main-missing-json.2d88b62200bc732efcd6.chunk.js.gz +0 -0
  73. package/dist/js/locales/fr-webui-main-json.a7018ac9dac9453657bb.chunk.js +0 -1
  74. package/dist/js/locales/fr-webui-main-json.a7018ac9dac9453657bb.chunk.js.gz +0 -0
  75. package/dist/js/locales/pt-br-webui-main-json.a78a76f27d38c856a4b9.chunk.js +0 -1
  76. package/dist/js/locales/pt-br-webui-main-json.a78a76f27d38c856a4b9.chunk.js.gz +0 -0
  77. package/dist/js/main.eea930701ff0165c262c.entry.js +0 -3
  78. package/dist/js/main.eea930701ff0165c262c.entry.js.gz +0 -0
  79. package/dist/js/messages.1a4f756d835c59f6c925.chunk.js +0 -2
  80. package/dist/js/messages.1a4f756d835c59f6c925.chunk.js.gz +0 -0
  81. package/dist/js/messages.1a4f756d835c59f6c925.chunk.js.map +0 -1
  82. package/dist/js/search.52d677e31d86ea727809.chunk.js +0 -2
  83. package/dist/js/search.52d677e31d86ea727809.chunk.js.gz +0 -0
  84. package/dist/js/search.52d677e31d86ea727809.chunk.js.map +0 -1
  85. package/dist/js/settings.064c3f5ee2ec8c698a4c.chunk.js +0 -2
  86. package/dist/js/settings.064c3f5ee2ec8c698a4c.chunk.js.gz +0 -0
  87. package/dist/js/settings.064c3f5ee2ec8c698a4c.chunk.js.map +0 -1
  88. package/vitest.workspace.ts +0 -29
  89. /package/dist/js/{807.52502ffbf0c34539314f.chunk.js.LICENSE.txt → 807.ae2142c32d74128cca0c.chunk.js.LICENSE.txt} +0 -0
  90. /package/dist/js/{home.e0421a3f337897e900d5.chunk.js.LICENSE.txt → home.630ba9695cb5314daa39.chunk.js.LICENSE.txt} +0 -0
  91. /package/dist/js/{main.eea930701ff0165c262c.entry.js.LICENSE.txt → main.67a9c3fc3a221e13daba.entry.js.LICENSE.txt} +0 -0
package/dist/index.html CHANGED
@@ -16,7 +16,7 @@
16
16
  {
17
17
  // We must inject the main chunk dynamically as well because the final path is not known on compile time
18
18
  var script = document.createElement('script');
19
- script.src = getBasePath() + "js/main.eea930701ff0165c262c.entry.js";
19
+ script.src = getBasePath() + "js/main.67a9c3fc3a221e13daba.entry.js";
20
20
  document.body.appendChild(script);
21
21
  }
22
22
 
@@ -0,0 +1,2 @@
1
+ "use strict";(self.webpackChunkairdcpp_webui=self.webpackChunkairdcpp_webui||[]).push([[544],{20082:(e,n,o)=>{o.d(n,{A:()=>d});var a=o(71354),t=o.n(a),l=o(76314),s=o.n(l)()(t());s.push([e.id,".download-dialog .accordion.download-targets {\n overflow-y: auto;\n}\n\n.download-dialog .main-content,\n.download-dialog .mobile.layout {\n display: flex;\n flex-direction: column;\n}\n\n.download-dialog .main-content .list {\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.download-dialog .content > div,\n.download-dialog .ui.grid .column,\n.download-dialog .main-content {\n height: 100%;\n}\n\n.download-dialog .download-handler {\n display: flex;\n align-items: baseline;\n}\n\n.download-dialog .disk-info {\n color: black;\n font-size: 90%;\n font-style: italic;\n}\n\n.download-dialog .normal.layout .four.wide.column {\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n}\n","",{version:3,sources:["webpack://./src/components/download/style.css"],names:[],mappings:"AAAA;EACE,gBAAgB;AAClB;;AAEA;;EAEE,aAAa;EACb,sBAAsB;AACxB;;AAEA;EACE,gBAAgB;EAChB,kBAAkB;AACpB;;AAEA;;;EAGE,YAAY;AACd;;AAEA;EACE,aAAa;EACb,qBAAqB;AACvB;;AAEA;EACE,YAAY;EACZ,cAAc;EACd,kBAAkB;AACpB;;AAEA;EACE,aAAa;EACb,sBAAsB;EACtB,8BAA8B;AAChC",sourcesContent:[".download-dialog .accordion.download-targets {\n overflow-y: auto;\n}\n\n.download-dialog .main-content,\n.download-dialog .mobile.layout {\n display: flex;\n flex-direction: column;\n}\n\n.download-dialog .main-content .list {\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.download-dialog .content > div,\n.download-dialog .ui.grid .column,\n.download-dialog .main-content {\n height: 100%;\n}\n\n.download-dialog .download-handler {\n display: flex;\n align-items: baseline;\n}\n\n.download-dialog .disk-info {\n color: black;\n font-size: 90%;\n font-style: italic;\n}\n\n.download-dialog .normal.layout .four.wide.column {\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n}\n"],sourceRoot:""}]);const d=s},53213:(e,n,o)=>{o.d(n,{G:()=>t});var a=o(93226);const t=(e,n,o)=>e.post(`${a.Ay.STRINGS_URL}/${n}`,{string:o})},73070:(e,n,o)=>{o.d(n,{Y9:()=>h,fI:()=>c,xA:()=>m});var a=o(74848),t=(o(96540),o(46942)),l=o.n(t),s=o(32389),d=o(42695),i=o(67749);const r=e=>e||(0,a.jsx)(s.x6,{i18nKey:(0,d.j2)("na",i.KV.COMMON),children:"N/A"}),c=({title:e,text:n,className:o,titleWidth:t="four",noText:s})=>(0,a.jsxs)("div",{className:l()("ui row",o),children:[(0,a.jsx)("div",{className:l()(s?"sixteen":t,"wide column title"),children:(0,a.jsx)("div",{className:"ui tiny header",style:{overflow:"hidden"},children:e})}),!s&&(0,a.jsx)("div",{className:"column value",children:r(n)})]}),h=({title:e})=>(0,a.jsx)("div",{className:"ui row",children:(0,a.jsx)("div",{className:"sixteen wide column",children:(0,a.jsx)("div",{className:"ui blue section header",children:e})})}),m=e=>{var{className:n,children:o,columns:t,stackable:s}=e,d=function(e,n){var o={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&n.indexOf(a)<0&&(o[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var t=0;for(a=Object.getOwnPropertySymbols(e);t<a.length;t++)n.indexOf(a[t])<0&&Object.prototype.propertyIsEnumerable.call(e,a[t])&&(o[a[t]]=e[a[t]])}return o}(e,["className","children","columns","stackable"]);return(0,a.jsx)("div",Object.assign({className:l()("ui grid",{[`${t} column`]:!!t},{stackable:s},n)},d,{children:o}))}},79179:(e,n,o)=>{o.d(n,{A:()=>t});const a="favorite_directories",t={MODULE_URL:a,GROUPED_DIRECTORIES_URL:a+"/grouped_paths",DIRECTORIES_URL:a,DIRECTORIES_UPDATED:"favorite_directories_updated"}},88544:(e,n,o)=>{o.d(n,{A:()=>re});var a=o(74848),t=o(96540),l=o(13017),s=o(32389),d=o(93226),i=o(59315),r=o(4425),c=o(88939),h=o(56484),m=o(65385),u=o(99671),A=o(47603),p=o(36076),w=o(42695),f=o(53213),y=o(33968),x=o(8098),v=o(42191),j=o(79179),O=o(27725),g=o(67749),b=o(32728),E=o(83994),C=o(74416),N=o(50489);const I=(e,n,{formatSize:o})=>e.free_space<=0?e.path:` (${n((0,w.j2)("spaceFree",g.KV.COMMON),{defaultValue:"{{freeSpace}} free",replace:{freeSpace:o(e.free_space)}})})`,P=({pathInfo:e,downloadHandler:n,t:o})=>{const t=(0,C.k)();return(0,a.jsxs)("div",{className:"item",children:[(0,a.jsx)(E.A,{icon:r.A.FOLDER}),(0,a.jsx)("div",{className:"content",children:(0,a.jsxs)(N.A,{onClick:()=>n(e.path),"aria-label":e.path,children:[e.path,(0,a.jsx)("span",{className:"disk-info",children:I(e,o,t)})]})})]})},k=(0,h.A)(function({downloadHandler:e,pathInfos:n,t:o}){return(0,a.jsx)("div",{className:"ui relaxed list",children:n.map(n=>(0,a.jsx)(P,{pathInfo:n,downloadHandler:e,t:o},n.path))})},{urls:{pathInfos:({paths:e},n)=>n.post(i.A.DISK_INFO_URL,{paths:e})}}),B=e=>0===e.paths.length?(0,a.jsx)(b.A,{title:(0,w.Tl)("No paths to display",e.t,g.KV.COMMON)}):(0,a.jsx)(k,Object.assign({},e));var D=o(78340);class R extends t.Component{constructor(){super(...arguments),this.formatParent=(e,n)=>{const{downloadHandler:o,t:l}=this.props;return(0,a.jsxs)(t.Fragment,{children:[(0,a.jsxs)(D.J6,{id:e.name,index:n,children:[(0,a.jsx)(E.A,{icon:r.A.DROPDOWN}),e.name]}),(0,a.jsx)(D.ub,{id:e.name,index:n,children:(0,a.jsx)(B,{paths:e.paths,downloadHandler:o,t:l})})]},e.name)}}render(){const{groupedPaths:e,t:n}=this.props;return 0===e.length?(0,a.jsx)(b.A,{title:(0,w.Tl)("No paths to display",n,g.KV.COMMON)}):(0,a.jsx)(D.Ay,{className:"styled download-targets",children:e.map(this.formatParent)})}}const _=R;var S=o(90425);const M=(e,n,o)=>n?[...e,(0,a.jsxs)(O.A,{onClick:n,children:[(0,w.Tl)("Browse",o,g.KV.COMMON),(0,a.jsx)(E.A,{icon:r.A.BROWSE})]},"browse")]:e,T=({menuItems:e,title:n,handleBrowse:o,t,children:l})=>(0,a.jsxs)("div",{className:"mobile layout",children:[(0,a.jsx)(S.A,{selection:!0,caption:n,children:M(e,o,t)}),(0,a.jsx)("div",{className:"ui segment main-content",children:l})]});var H=o(96529),L=o(73070);const V=({menuItems:e,title:n,handleBrowse:o,t,children:l})=>(0,a.jsxs)(L.xA,{className:"normal layout",children:[(0,a.jsxs)("div",{className:"four wide column",children:[(0,a.jsx)("div",{className:"ui vertical fluid tabular menu",role:"navigation","aria-label":"Download sections",children:(0,a.jsx)("div",{role:"tablist",children:e})}),!!o&&(0,a.jsx)(H.A,{className:"fluid basic",caption:(0,w.Tl)("Browse",t,g.KV.COMMON),onClick:o,icon:r.A.BROWSE})]}),(0,a.jsx)("div",{className:"twelve wide stretched column",children:(0,a.jsx)("div",{className:"ui segment main-content",children:l})})]}),U=e=>`download-panel-${e}`,F=e=>`download-tab-${e}`,K=(0,h.A)(e=>{const{t:n}=(0,s.Bd)(),[o,l]=(0,t.useState)("history"),d=t.useMemo(()=>{const{historyPaths:n,sharePaths:o,favoritePaths:t,itemInfo:l}=e;return(e=>{const{sharePaths:n,favoritePaths:o,historyPaths:t,dupePaths:l}=e;return[{name:"Previous",key:"history",list:t,component:({downloadHandler:e,t:n})=>(0,a.jsx)(B,{paths:t,downloadHandler:e,t:n})},{name:"Shared",key:"shared",list:n,component:({downloadHandler:e,t:o})=>(0,a.jsx)(_,{groupedPaths:n,downloadHandler:e,t:o})},{name:"Favorites",key:"favorites",list:o,component:({downloadHandler:e,t:n})=>(0,a.jsx)(_,{groupedPaths:o,downloadHandler:e,t:n})},{name:"Dupes",key:"dupes",list:l,component:({downloadHandler:e,t:n})=>(0,a.jsx)(B,{paths:l,downloadHandler:e,t:n})}]})({historyPaths:n,sharePaths:o,favoritePaths:t,dupePaths:l.dupe?l.dupe.paths.map(e=>(0,y._6)(e)):[]})},[]),i=d.find(e=>e.key===o);if(!i)return null;const r=d.map(e=>((e,n,o,t)=>{const l=t((0,w.j2)(e.key,g.KV.COMMON),e.name);return(0,a.jsx)(O.A,{onClick:()=>o(e.key),active:n===e.key,id:F(e.key),role:"tab","aria-controls":U(e.key),"aria-label":l,children:(0,a.jsxs)(a.Fragment,{children:[l,!!e.list&&(0,a.jsx)("div",{className:"ui small label",children:e.list.length})]})},e.key)})(e,o,l,n)),c=(0,x.vU)()?T:V;return(0,a.jsx)(c,{menuItems:r,title:i.name,handleBrowse:e.handleBrowse,t:n,children:(0,a.jsx)("div",{role:"tabpanel",id:U(i.key),"aria-labelledby":F(i.key),children:(0,a.jsx)(i.component,{t:n,downloadHandler:e.downloadHandler})})},i.key)},{urls:{sharePaths:v.A.GROUPED_ROOTS_GET_URL,favoritePaths:j.A.GROUPED_DIRECTORIES_URL}});var G=o(86038),W=o(85072),$=o.n(W),Y=o(97825),q=o.n(Y),z=o(77659),Z=o.n(z),J=o(55056),Q=o.n(J),X=o(10540),ee=o.n(X),ne=o(41113),oe=o.n(ne),ae=o(20082),te={};te.styleTagTransform=oe(),te.setAttributes=Q(),te.insert=Z().bind(null,"head"),te.domAPI=q(),te.insertStyleElement=ee(),$()(ae.A,te),ae.A&&ae.A.locals&&ae.A.locals;var le=o(39364),se=o(48249),de=o(70756),ie=function(e,n,o,a){return new(o||(o=Promise))(function(t,l){function s(e){try{i(a.next(e))}catch(e){l(e)}}function d(e){try{i(a.throw(e))}catch(e){l(e)}}function i(e){var n;e.done?t(e.value):(n=e.value,n instanceof o?n:new o(function(e){e(n)})).then(s,d)}i((a=a.apply(e,n||[])).next())})};const re=(0,m.A)((0,h.A)(e=>{const{t:n}=(0,s.Bd)(),o=(0,l.Zp)(),t=(0,le.wV)(),h=(0,se.F)(),{downloadHandler:m,itemInfo:x,userGetter:v,params:j,sessionItem:O,historyPaths:b,handleClose:E}=e,C=function(e,n){var o={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&n.indexOf(a)<0&&(o[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var t=0;for(a=Object.getOwnPropertySymbols(e);t<a.length;t++)n.indexOf(a[t])<0&&Object.prototype.propertyIsEnumerable.call(e,a[t])&&(o[a[t]]=e[a[t]])}return o}(e,["downloadHandler","itemInfo","userGetter","params","sessionItem","historyPaths","handleClose"]),N=(o,a)=>ie(void 0,void 0,void 0,function*(){try{const n={itemInfo:x,user:v?v(j.downloadItemId,e):void 0,entity:O},t={target_name:a||x.name,target_directory:o,priority:G.Fm.DEFAULT};yield m(n,t,h)}catch(e){c.A.error({title:n((0,w.j2)("queueingFailed",g.KV.COMMON),{defaultValue:"Failed to queue the item {{item.name}}",replace:{item:x}}),message:e.message})}(0,p.bd)(()=>(0,f.G)(h,d.n2.DOWNLOAD_DIR,o),n)}),I={subHeader:x.name,title:(0,w.Tl)("Download",n,g.KV.COMMON),icon:r.A.DOWNLOAD,closable:!1},P=(0,de.z)(t,G.US.FILESYSTEM_VIEW);return(0,a.jsxs)(l.BV,{children:[(0,a.jsx)(l.qh,{path:"browse/*",element:(0,a.jsx)(A.d,Object.assign({onConfirm:e=>ie(void 0,void 0,void 0,function*(){yield N((0,y.oK)(e),(0,y.WP)(e))}),initialPath:(()=>{const e=b.length>0?b[b.length-1]:"";return"directory"===x.type.id?e:e+x.name})(),selectMode:"directory"===x.type.id?g.bV.DIRECTORY:g.bV.FILE,historyId:i.A.LOCATION_DOWNLOAD,approveCaption:(0,w.Tl)("Download",n,g.KV.COMMON),modalComponent:u.A},I))}),(0,a.jsx)(l.qh,{index:!0,element:(0,a.jsx)(u.A,Object.assign({className:"download-dialog",fullHeight:!0},I,C,{children:(0,a.jsx)(K,{downloadHandler:(e,n)=>ie(void 0,void 0,void 0,function*(){yield N(e,n),yield E()}),handleBrowse:P?()=>{o("browse")}:void 0,historyPaths:b,itemInfo:x})}))})]})},{urls:{historyPaths:`${d.Ay.STRINGS_URL}/${d.n2.DOWNLOAD_DIR}`,itemInfo:({params:e,itemDataGetter:n},o)=>n(e.downloadItemId,o)}}),"/download/:downloadItemId")}}]);
2
+ //# sourceMappingURL=544.73cf8e69cd2348500250.chunk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"js/544.73cf8e69cd2348500250.chunk.js","mappings":"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","sources":["webpack://airdcpp-webui/./src/components/download/style.css","webpack://airdcpp-webui/./src/services/api/HistoryApi.ts","webpack://airdcpp-webui/./src/components/semantic/Grid.tsx","webpack://airdcpp-webui/./src/constants/FavoriteDirectoryConstants.ts","webpack://airdcpp-webui/./src/components/download/layout/sections/PathListItem.tsx","webpack://airdcpp-webui/./src/components/download/layout/sections/PathList.tsx","webpack://airdcpp-webui/./src/components/download/layout/sections/AccordionTargets.tsx","webpack://airdcpp-webui/./src/components/download/layout/MobileDownloadLayout.tsx","webpack://airdcpp-webui/./src/components/download/layout/NormalDownloadLayout.tsx","webpack://airdcpp-webui/./src/components/download/layout/DownloadView.tsx","webpack://airdcpp-webui/./src/components/download/layout/sections/sections.tsx","webpack://airdcpp-webui/./src/components/download/style.css?6643","webpack://airdcpp-webui/./src/components/download/DownloadDialog.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, `.download-dialog .accordion.download-targets {\n overflow-y: auto;\n}\n\n.download-dialog .main-content,\n.download-dialog .mobile.layout {\n display: flex;\n flex-direction: column;\n}\n\n.download-dialog .main-content .list {\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.download-dialog .content > div,\n.download-dialog .ui.grid .column,\n.download-dialog .main-content {\n height: 100%;\n}\n\n.download-dialog .download-handler {\n display: flex;\n align-items: baseline;\n}\n\n.download-dialog .disk-info {\n color: black;\n font-size: 90%;\n font-style: italic;\n}\n\n.download-dialog .normal.layout .four.wide.column {\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n}\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/components/download/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,gBAAgB;AAClB;;AAEA;;EAEE,aAAa;EACb,sBAAsB;AACxB;;AAEA;EACE,gBAAgB;EAChB,kBAAkB;AACpB;;AAEA;;;EAGE,YAAY;AACd;;AAEA;EACE,aAAa;EACb,qBAAqB;AACvB;;AAEA;EACE,YAAY;EACZ,cAAc;EACd,kBAAkB;AACpB;;AAEA;EACE,aAAa;EACb,sBAAsB;EACtB,8BAA8B;AAChC\",\"sourcesContent\":[\".download-dialog .accordion.download-targets {\\n overflow-y: auto;\\n}\\n\\n.download-dialog .main-content,\\n.download-dialog .mobile.layout {\\n display: flex;\\n flex-direction: column;\\n}\\n\\n.download-dialog .main-content .list {\\n overflow-y: auto;\\n overflow-x: hidden;\\n}\\n\\n.download-dialog .content > div,\\n.download-dialog .ui.grid .column,\\n.download-dialog .main-content {\\n height: 100%;\\n}\\n\\n.download-dialog .download-handler {\\n display: flex;\\n align-items: baseline;\\n}\\n\\n.download-dialog .disk-info {\\n color: black;\\n font-size: 90%;\\n font-style: italic;\\n}\\n\\n.download-dialog .normal.layout .four.wide.column {\\n display: flex;\\n flex-direction: column;\\n justify-content: space-between;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","import { APISocket } from '@/services/SocketService';\nimport HistoryConstants from '@/constants/HistoryConstants';\n\nexport const addHistory = (socket: APISocket, historyId: string, text: string) => {\n return socket.post(`${HistoryConstants.STRINGS_URL}/${historyId}`, {\n string: text,\n });\n};\n","import * as React from 'react';\r\nimport classNames from 'classnames';\r\n\r\nimport { Trans } from 'react-i18next';\r\nimport { toI18nKey } from '@/utils/TranslationUtils';\r\n\r\nimport * as UI from '@/types/ui';\r\n\r\nexport interface RowProps {\r\n title: React.ReactNode;\r\n text?: React.ReactNode;\r\n titleWidth?: string;\r\n className?: string;\r\n noText?: boolean;\r\n}\r\n\r\nconst formatText = (text: React.ReactNode) => {\r\n if (!!text) {\r\n return text;\r\n }\r\n\r\n return <Trans i18nKey={toI18nKey('na', UI.Modules.COMMON)}>N/A</Trans>;\r\n};\r\n\r\nexport const Row: React.FC<RowProps> = ({\r\n title,\r\n text,\r\n className,\r\n titleWidth = 'four',\r\n noText,\r\n}) => (\r\n <div className={classNames('ui row', className)}>\r\n <div className={classNames(noText ? 'sixteen' : titleWidth, 'wide column title')}>\r\n <div className=\"ui tiny header\" style={{ overflow: 'hidden' }}>\r\n {title}\r\n </div>\r\n </div>\r\n {!noText && <div className=\"column value\">{formatText(text)}</div>}\r\n </div>\r\n);\r\n\r\nexport interface HeaderProps {\r\n title: React.ReactNode;\r\n}\r\n\r\nexport const Header: React.FC<HeaderProps> = ({ title }) => (\r\n <div className=\"ui row\">\r\n <div className=\"sixteen wide column\">\r\n <div className=\"ui blue section header\">{title}</div>\r\n </div>\r\n </div>\r\n);\r\n\r\nexport interface GridProps extends React.HTMLAttributes<HTMLDivElement> {\r\n columns?: string;\r\n stackable?: boolean;\r\n}\r\n\r\nexport const Grid: React.FC<GridProps> = ({\r\n className,\r\n children,\r\n columns,\r\n stackable,\r\n ...other\r\n}) => (\r\n <div\r\n className={classNames(\r\n 'ui grid',\r\n //`${columns} column`,\r\n { [`${columns} column`]: !!columns },\r\n { stackable: stackable },\r\n className,\r\n )}\r\n {...other}\r\n >\r\n {children}\r\n </div>\r\n);\r\n","const MODULE_URL = 'favorite_directories';\nexport default {\n MODULE_URL: MODULE_URL,\n\n GROUPED_DIRECTORIES_URL: MODULE_URL + '/grouped_paths',\n DIRECTORIES_URL: MODULE_URL,\n\n DIRECTORIES_UPDATED: 'favorite_directories_updated',\n};\n","import * as React from 'react';\n\nimport IconConstants from '@/constants/IconConstants';\n\nimport Icon from '@/components/semantic/Icon';\n\nimport { toI18nKey } from '@/utils/TranslationUtils';\nimport { Formatter, useFormatter } from '@/context/FormatterContext';\n\nimport * as API from '@/types/api';\nimport * as UI from '@/types/ui';\nimport { PathDownloadHandler } from '../../types';\nimport LinkButton from '@/components/semantic/LinkButton';\n\ninterface PathItemProps {\n pathInfo: API.DiskSpaceInfo;\n downloadHandler: PathDownloadHandler;\n t: UI.TranslateF;\n}\n\nconst formatFreeSpace = (\n pathInfo: API.DiskSpaceInfo,\n t: UI.TranslateF,\n { formatSize }: Formatter,\n) => {\n if (pathInfo.free_space <= 0) {\n return pathInfo.path;\n }\n\n return ` (${t(toI18nKey('spaceFree', UI.Modules.COMMON), {\n defaultValue: '{{freeSpace}} free',\n replace: {\n freeSpace: formatSize(pathInfo.free_space),\n },\n })})`;\n};\n\nexport const PathListItem: React.FC<PathItemProps> = ({\n pathInfo,\n downloadHandler,\n t,\n}) => {\n const formatter = useFormatter();\n return (\n <div className=\"item\">\n <Icon icon={IconConstants.FOLDER} />\n <div className=\"content\">\n <LinkButton\n onClick={() => downloadHandler(pathInfo.path)}\n aria-label={pathInfo.path}\n >\n {pathInfo.path}\n <span className=\"disk-info\">{formatFreeSpace(pathInfo, t, formatter)}</span>\n </LinkButton>\n </div>\n </div>\n );\n};\n","import FilesystemConstants from '@/constants/FilesystemConstants';\r\n\r\nimport DataProviderDecorator from '@/decorators/DataProviderDecorator';\r\n\r\nimport Message from '@/components/semantic/Message';\r\n\r\nimport { translate } from '@/utils/TranslationUtils';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport { PathDownloadHandler } from '../../types';\r\nimport { PathListItem } from './PathListItem';\r\n\r\ninterface PathListProps {\r\n // Function handling the path selection\r\n downloadHandler: PathDownloadHandler;\r\n\r\n // Array of paths to list\r\n paths: string[];\r\n t: UI.TranslateF;\r\n}\r\n\r\ninterface PathListDataProps {\r\n pathInfos: API.DiskSpaceInfo[];\r\n}\r\n\r\nconst PathListWithData = DataProviderDecorator<PathListProps, PathListDataProps>(\r\n function PathList({ downloadHandler, pathInfos, t }) {\r\n return (\r\n <div className=\"ui relaxed list\">\r\n {pathInfos.map((pathInfo) => (\r\n <PathListItem\r\n key={pathInfo.path}\r\n pathInfo={pathInfo}\r\n downloadHandler={downloadHandler}\r\n t={t}\r\n />\r\n ))}\r\n </div>\r\n );\r\n },\r\n {\r\n urls: {\r\n pathInfos: ({ paths }, socket) =>\r\n socket.post(FilesystemConstants.DISK_INFO_URL, { paths }),\r\n },\r\n },\r\n);\r\n\r\nconst PathList: React.FC<PathListProps> = (props) => {\r\n if (props.paths.length === 0) {\r\n return (\r\n <Message title={translate('No paths to display', props.t, UI.Modules.COMMON)} />\r\n );\r\n }\r\n\r\n return <PathListWithData {...props} />;\r\n};\r\n\r\nexport default PathList;\r\n","import React, { Component } from 'react';\n\nimport IconConstants from '@/constants/IconConstants';\n\nimport Accordion, {\n AccordionContent,\n AccordionTitle,\n} from '@/components/semantic/Accordion';\nimport Icon from '@/components/semantic/Icon';\nimport Message from '@/components/semantic/Message';\n\nimport { translate } from '@/utils/TranslationUtils';\n\nimport * as API from '@/types/api';\nimport * as UI from '@/types/ui';\nimport { PathDownloadHandler } from '../../types';\n\nimport PathList from './PathList';\n\ninterface AccordionTargetsProps {\n // Grouped paths to list\n groupedPaths: API.GroupedPath[];\n\n // Function handling the path selection. Receives the selected path as argument.\n downloadHandler: PathDownloadHandler;\n\n t: UI.TranslateF;\n}\n\nclass AccordionTargets extends Component<AccordionTargetsProps> {\n formatParent = (parent: API.GroupedPath, index: number) => {\n const { downloadHandler, t } = this.props;\n return (\n <React.Fragment key={parent.name}>\n <AccordionTitle id={parent.name} index={index}>\n <Icon icon={IconConstants.DROPDOWN} />\n {parent.name}\n </AccordionTitle>\n\n <AccordionContent id={parent.name} index={index}>\n <PathList paths={parent.paths} downloadHandler={downloadHandler} t={t} />\n </AccordionContent>\n </React.Fragment>\n );\n };\n\n render() {\n const { groupedPaths, t } = this.props;\n if (groupedPaths.length === 0) {\n return <Message title={translate('No paths to display', t, UI.Modules.COMMON)} />;\n }\n\n return (\n <Accordion className=\"styled download-targets\">\n {groupedPaths.map(this.formatParent)}\n </Accordion>\n );\n }\n}\n\nexport default AccordionTargets;\n","import * as React from 'react';\r\n\r\nimport { translate } from '@/utils/TranslationUtils';\r\n\r\nimport Dropdown from '@/components/semantic/Dropdown';\r\nimport MenuItemLink from '@/components/semantic/MenuItemLink';\r\n\r\nimport * as UI from '@/types/ui';\r\n\r\nimport Icon from '@/components/semantic/Icon';\r\nimport { BrowseHandler, DownloadLayoutProps } from '../types';\r\nimport IconConstants from '@/constants/IconConstants';\r\n\r\nconst appendBrowseItem = (\r\n menuItems: React.ReactNode[],\r\n handleBrowse: BrowseHandler,\r\n t: UI.TranslateF,\r\n) => {\r\n if (!handleBrowse) {\r\n return menuItems;\r\n }\r\n\r\n return [\r\n ...menuItems,\r\n <MenuItemLink key=\"browse\" onClick={handleBrowse}>\r\n {translate('Browse', t, UI.Modules.COMMON)}\r\n <Icon icon={IconConstants.BROWSE} />\r\n </MenuItemLink>,\r\n ];\r\n};\r\n\r\nexport const MobileDownloadLayout: React.FC<DownloadLayoutProps> = ({\r\n menuItems,\r\n title,\r\n handleBrowse,\r\n t,\r\n children,\r\n}) => (\r\n <div className=\"mobile layout\">\r\n <Dropdown selection={true} caption={title}>\r\n {appendBrowseItem(menuItems, handleBrowse, t)}\r\n </Dropdown>\r\n <div className=\"ui segment main-content\">{children}</div>\r\n </div>\r\n);\r\n","import * as React from 'react';\n\nimport IconConstants from '@/constants/IconConstants';\n\nimport { translate } from '@/utils/TranslationUtils';\n\nimport Button from '@/components/semantic/Button';\nimport { Grid } from '@/components/semantic/Grid';\n\nimport * as UI from '@/types/ui';\nimport { DownloadLayoutProps } from '../types';\n\nexport const NormalDownloadLayout: React.FC<DownloadLayoutProps> = ({\n menuItems,\n title,\n handleBrowse,\n t,\n children,\n}) => (\n <Grid className=\"normal layout\">\n <div className=\"four wide column\">\n <div\n className=\"ui vertical fluid tabular menu\"\n role=\"navigation\"\n aria-label=\"Download sections\"\n >\n <div role=\"tablist\">{menuItems}</div>\n </div>\n {!!handleBrowse && (\n <Button\n className=\"fluid basic\"\n caption={translate('Browse', t, UI.Modules.COMMON)}\n onClick={handleBrowse}\n icon={IconConstants.BROWSE}\n />\n )}\n </div>\n <div className=\"twelve wide stretched column\">\n <div className=\"ui segment main-content\">{children}</div>\n </div>\n </Grid>\n);\n","import { useState } from 'react';\r\nimport * as React from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\n\r\nimport { getParentPath } from '@/utils/FileUtils';\r\nimport { usingMobileLayout } from '@/utils/BrowserUtils';\r\nimport { toI18nKey } from '@/utils/TranslationUtils';\r\n\r\nimport ShareConstants from '@/constants/ShareConstants';\r\nimport FavoriteDirectoryConstants from '@/constants/FavoriteDirectoryConstants';\r\n\r\nimport MenuItemLink from '@/components/semantic/MenuItemLink';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport { getDownloadSections, DownloadSection } from './sections';\r\nimport { BrowseHandler, PathDownloadHandler } from '../types';\r\n\r\nimport { MobileDownloadLayout } from './MobileDownloadLayout';\r\nimport { NormalDownloadLayout } from './NormalDownloadLayout';\r\nimport DataProviderDecorator from '@/decorators/DataProviderDecorator';\r\n\r\nconst toPanelId = (key: string) => `download-panel-${key}`;\r\nconst toTabId = (key: string) => `download-tab-${key}`;\r\n\r\nexport interface DownloadLayoutDataProps {\r\n sharePaths: API.GroupedPath[];\r\n favoritePaths: API.GroupedPath[];\r\n}\r\n\r\nexport interface DownloadLayoutProps<\r\n ItemT extends UI.DownloadableItemInfo = UI.DownloadableItemInfo,\r\n> {\r\n downloadHandler: PathDownloadHandler;\r\n handleBrowse: BrowseHandler;\r\n\r\n historyPaths: string[];\r\n itemInfo: ItemT;\r\n}\r\n\r\nconst getMenuItem = (\r\n section: DownloadSection,\r\n activeSection: string,\r\n onClick: (key: string) => void,\r\n t: UI.TranslateF,\r\n) => {\r\n const label = t(toI18nKey(section.key, UI.Modules.COMMON), section.name);\r\n return (\r\n <MenuItemLink\r\n key={section.key}\r\n onClick={() => onClick(section.key)}\r\n active={activeSection === section.key}\r\n id={toTabId(section.key)}\r\n role=\"tab\"\r\n aria-controls={toPanelId(section.key)}\r\n aria-label={label}\r\n >\r\n <>\r\n {label}\r\n {!!section.list && <div className=\"ui small label\">{section.list.length}</div>}\r\n </>\r\n </MenuItemLink>\r\n );\r\n};\r\n\r\ntype Props<ItemT extends UI.DownloadableItemInfo = UI.DownloadableItemInfo> =\r\n DownloadLayoutProps<ItemT> & DownloadLayoutDataProps;\r\n\r\nconst DownloadLayout: React.FC<Props> = (props) => {\r\n const { t } = useTranslation();\r\n const [activeSectionKey, setActiveSectionKey] = useState('history');\r\n\r\n const sections = React.useMemo(() => {\r\n const { historyPaths, sharePaths, favoritePaths, itemInfo } = props;\r\n const dupePaths = itemInfo.dupe\r\n ? itemInfo.dupe.paths.map((path) => getParentPath(path))\r\n : [];\r\n\r\n return getDownloadSections({\r\n historyPaths,\r\n sharePaths,\r\n favoritePaths,\r\n dupePaths,\r\n });\r\n }, []);\r\n\r\n const activeSection = sections.find((s) => s.key === activeSectionKey);\r\n if (!activeSection) {\r\n return null;\r\n }\r\n\r\n const menuItems = sections.map((s) =>\r\n getMenuItem(s, activeSectionKey, setActiveSectionKey, t),\r\n );\r\n\r\n const Component = usingMobileLayout() ? MobileDownloadLayout : NormalDownloadLayout;\r\n\r\n return (\r\n <Component\r\n key={activeSection.key} // Ensure that section-specific data is refetched\r\n menuItems={menuItems}\r\n title={activeSection.name}\r\n handleBrowse={props.handleBrowse}\r\n t={t}\r\n >\r\n <div\r\n role=\"tabpanel\"\r\n id={toPanelId(activeSection.key)}\r\n aria-labelledby={toTabId(activeSection.key)}\r\n >\r\n <activeSection.component t={t} downloadHandler={props.downloadHandler} />\r\n </div>\r\n </Component>\r\n );\r\n};\r\n\r\nconst DownloadLayoutDecorated = DataProviderDecorator<\r\n DownloadLayoutProps,\r\n DownloadLayoutDataProps\r\n>(DownloadLayout, {\r\n urls: {\r\n sharePaths: ShareConstants.GROUPED_ROOTS_GET_URL,\r\n favoritePaths: FavoriteDirectoryConstants.GROUPED_DIRECTORIES_URL,\r\n },\r\n});\r\n\r\nexport { DownloadLayoutDecorated as DownloadLayout };\r\n","import * as React from 'react';\n\nimport PathList from './PathList';\nimport AccordionTargets from './AccordionTargets';\n\nimport * as API from '@/types/api';\nimport * as UI from '@/types/ui';\n\nimport { PathDownloadHandler } from '../../types';\n\nexport interface DownloadSectionChildProps {\n t: UI.TranslateF;\n downloadHandler: PathDownloadHandler;\n}\n\nexport interface DownloadSection {\n name: string;\n key: string;\n list?: string[] | API.GroupedPath[];\n component: React.ComponentType<DownloadSectionChildProps>;\n}\n\ninterface PathInfo {\n sharePaths: API.GroupedPath[];\n favoritePaths: API.GroupedPath[];\n historyPaths: string[];\n dupePaths: string[];\n}\n\nexport const getDownloadSections = (pathInfo: PathInfo) => {\n const { sharePaths, favoritePaths, historyPaths, dupePaths } = pathInfo;\n\n const sections: DownloadSection[] = [\n {\n name: 'Previous',\n key: 'history',\n list: historyPaths,\n component: ({ downloadHandler, t }) => (\n <PathList paths={historyPaths} downloadHandler={downloadHandler} t={t} />\n ),\n },\n {\n name: 'Shared',\n key: 'shared',\n list: sharePaths,\n component: ({ downloadHandler, t }) => (\n <AccordionTargets\n groupedPaths={sharePaths}\n downloadHandler={downloadHandler}\n t={t}\n />\n ),\n },\n {\n name: 'Favorites',\n key: 'favorites',\n list: favoritePaths,\n component: ({ downloadHandler, t }) => (\n <AccordionTargets\n groupedPaths={favoritePaths}\n downloadHandler={downloadHandler}\n t={t}\n />\n ),\n },\n {\n name: 'Dupes',\n key: 'dupes',\n list: dupePaths,\n component: ({ downloadHandler, t }) => (\n <PathList paths={dupePaths} downloadHandler={downloadHandler} t={t} />\n ),\n },\n ];\n\n return sections;\n};\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 * as React from 'react';\r\nimport { Route, Routes, useNavigate } from 'react-router';\r\nimport { useTranslation } from 'react-i18next';\r\n\r\nimport {\r\n default as HistoryConstants,\r\n HistoryStringEnum,\r\n} from '@/constants/HistoryConstants';\r\nimport FilesystemConstants from '@/constants/FilesystemConstants';\r\nimport IconConstants from '@/constants/IconConstants';\r\n\r\nimport NotificationActions from '@/actions/NotificationActions';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from '@/decorators/DataProviderDecorator';\r\nimport ModalRouteDecorator, {\r\n ModalRouteDecoratorChildProps,\r\n} from '@/decorators/ModalRouteDecorator';\r\n\r\nimport RouteModal, { RouteModalProps } from '@/components/semantic/RouteModal';\r\nimport { FileBrowserDialog } from '@/components/filebrowser';\r\n\r\nimport { runBackgroundSocketAction } from '@/utils/ActionUtils';\r\nimport { toI18nKey, translate } from '@/utils/TranslationUtils';\r\nimport { addHistory } from '@/services/api/HistoryApi';\r\n\r\nimport { DownloadLayout } from './layout';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\nimport { PathDownloadHandler } from './types';\r\n\r\nimport './style.css';\r\nimport { useSession } from '@/context/AppStoreContext';\r\nimport { useSocket } from '@/context/SocketContext';\r\nimport { getFileName, getFilePath } from '@/utils/FileUtils';\r\nimport { hasAccess } from '@/utils/AuthUtils';\r\n\r\nexport type DownloadDialogProps<\r\n ItemT extends UI.DownloadableItemInfo = UI.DownloadableItemInfo,\r\n> = UI.ItemDownloadHandler<ItemT, Props<ItemT>>;\r\n\r\ntype DownloadDialogRouteProps = ModalRouteDecoratorChildProps;\r\n\r\ninterface DownloadDialogDataProps<\r\n ItemT extends UI.DownloadableItemInfo = UI.DownloadableItemInfo,\r\n> extends DataProviderDecoratorChildProps {\r\n historyPaths: string[];\r\n itemInfo: ItemT;\r\n}\r\n\r\ntype Props<ItemT extends UI.DownloadableItemInfo = UI.DownloadableItemInfo> =\r\n DownloadDialogProps<ItemT> & DownloadDialogDataProps<ItemT> & DownloadDialogRouteProps;\r\n\r\nconst DownloadDialog: React.FC<Props> = (props) => {\r\n const { t } = useTranslation();\r\n const navigate = useNavigate();\r\n const session = useSession();\r\n const socket = useSocket();\r\n\r\n const {\r\n downloadHandler,\r\n itemInfo,\r\n userGetter,\r\n params,\r\n sessionItem,\r\n historyPaths,\r\n handleClose,\r\n ...other\r\n } = props;\r\n\r\n const handleDownload: PathDownloadHandler = async (targetPath, targetFilename) => {\r\n try {\r\n const itemData = {\r\n itemInfo,\r\n user: !!userGetter ? userGetter(params.downloadItemId!, props) : undefined,\r\n entity: sessionItem,\r\n };\r\n\r\n const downloadData = {\r\n target_name: !!targetFilename ? targetFilename : itemInfo.name,\r\n target_directory: targetPath,\r\n priority: API.QueuePriorityEnum.DEFAULT,\r\n };\r\n\r\n await downloadHandler(itemData, downloadData, socket);\r\n } catch (e) {\r\n NotificationActions.error({\r\n title: t(toI18nKey('queueingFailed', UI.Modules.COMMON), {\r\n defaultValue: 'Failed to queue the item {{item.name}}',\r\n replace: {\r\n item: itemInfo,\r\n },\r\n }),\r\n message: e.message,\r\n });\r\n }\r\n\r\n runBackgroundSocketAction(\r\n () => addHistory(socket, HistoryStringEnum.DOWNLOAD_DIR, targetPath),\r\n t,\r\n );\r\n };\r\n\r\n const getInitialBrowsePath = () => {\r\n const path = historyPaths.length > 0 ? historyPaths[historyPaths.length - 1] : '';\r\n return itemInfo.type.id === 'directory' ? path : path + itemInfo.name;\r\n };\r\n\r\n const handleBrowse = () => {\r\n navigate(`browse`);\r\n };\r\n\r\n const commonDialogProps: RouteModalProps = {\r\n subHeader: itemInfo.name,\r\n title: translate('Download', t, UI.Modules.COMMON),\r\n icon: IconConstants.DOWNLOAD,\r\n closable: false,\r\n };\r\n\r\n const hasFileBrowserAccess = hasAccess(session, API.AccessEnum.FILESYSTEM_VIEW);\r\n return (\r\n <Routes>\r\n <Route\r\n path=\"browse/*\"\r\n element={\r\n <FileBrowserDialog\r\n onConfirm={async (path) => {\r\n await handleDownload(getFilePath(path), getFileName(path));\r\n }}\r\n initialPath={getInitialBrowsePath()}\r\n selectMode={\r\n itemInfo.type.id === 'directory'\r\n ? UI.FileSelectModeEnum.DIRECTORY\r\n : UI.FileSelectModeEnum.FILE\r\n }\r\n historyId={FilesystemConstants.LOCATION_DOWNLOAD}\r\n approveCaption={translate('Download', t, UI.Modules.COMMON)}\r\n modalComponent={RouteModal}\r\n {...commonDialogProps}\r\n />\r\n }\r\n />\r\n <Route\r\n index\r\n element={\r\n <RouteModal\r\n className=\"download-dialog\"\r\n fullHeight={true}\r\n {...commonDialogProps}\r\n {...other}\r\n >\r\n <DownloadLayout\r\n downloadHandler={async (targetPath, targetFilename) => {\r\n await handleDownload(targetPath, targetFilename);\r\n await handleClose();\r\n }}\r\n handleBrowse={hasFileBrowserAccess ? handleBrowse : undefined}\r\n historyPaths={historyPaths}\r\n itemInfo={itemInfo}\r\n />\r\n </RouteModal>\r\n }\r\n />\r\n </Routes>\r\n );\r\n};\r\n\r\nexport default ModalRouteDecorator<DownloadDialogProps>(\r\n DataProviderDecorator<\r\n DownloadDialogProps & DownloadDialogRouteProps,\r\n DownloadDialogDataProps\r\n >(DownloadDialog, {\r\n urls: {\r\n historyPaths: `${HistoryConstants.STRINGS_URL}/${HistoryStringEnum.DOWNLOAD_DIR}`,\r\n itemInfo: ({ params, itemDataGetter }, socket) => {\r\n return itemDataGetter(params.downloadItemId!, socket);\r\n },\r\n },\r\n }),\r\n '/download/:downloadItemId',\r\n);\r\n"],"names":["___CSS_LOADER_EXPORT___","push","module","id","addHistory","socket","historyId","text","post","STRINGS_URL","string","formatText","i18nKey","COMMON","Row","title","className","titleWidth","noText","style","overflow","Header","Grid","children","columns","stackable","other","MODULE_URL","GROUPED_DIRECTORIES_URL","DIRECTORIES_URL","DIRECTORIES_UPDATED","formatFreeSpace","pathInfo","t","formatSize","free_space","path","defaultValue","replace","freeSpace","PathListItem","downloadHandler","formatter","Icon","icon","IconConstants","FOLDER","LinkButton","onClick","PathListWithData","DataProviderDecorator","pathInfos","map","urls","paths","FilesystemConstants","DISK_INFO_URL","props","length","Message","AccordionTargets","Component","formatParent","parent","index","this","Accordion","name","DROPDOWN","render","groupedPaths","appendBrowseItem","menuItems","handleBrowse","MenuItemLink","BROWSE","MobileDownloadLayout","Dropdown","selection","caption","NormalDownloadLayout","role","Button","toPanelId","key","toTabId","DownloadLayoutDecorated","activeSectionKey","setActiveSectionKey","useState","sections","historyPaths","sharePaths","favoritePaths","itemInfo","dupePaths","list","component","getDownloadSections","dupe","activeSection","find","s","section","label","active","getMenuItem","ShareConstants","GROUPED_ROOTS_GET_URL","FavoriteDirectoryConstants","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","locals","ModalRouteDecorator","navigate","session","userGetter","params","sessionItem","handleClose","handleDownload","targetPath","targetFilename","itemData","user","downloadItemId","undefined","entity","downloadData","target_name","target_directory","priority","DEFAULT","e","NotificationActions","error","item","message","DOWNLOAD_DIR","commonDialogProps","subHeader","DOWNLOAD","closable","hasFileBrowserAccess","FILESYSTEM_VIEW","element","onConfirm","initialPath","type","getInitialBrowsePath","selectMode","DIRECTORY","FILE","LOCATION_DOWNLOAD","approveCaption","modalComponent","RouteModal","fullHeight","HistoryConstants","itemDataGetter"],"sourceRoot":""}
@@ -1,2 +1,2 @@
1
- "use strict";(self.webpackChunkairdcpp_webui=self.webpackChunkairdcpp_webui||[]).push([[550],{4112:(n,e,s)=>{s.d(e,{R:()=>t});var i=s(4425);const t=(n,e)=>({id:"remove",displayName:"Close",access:e,icon:i.A.REMOVE,handler:({itemData:e,socket:s})=>s.delete(`${n}/${e.id}`)})},38453:(n,e,s)=>{s.d(e,{J:()=>t,q:()=>o});var i=s(74848);s(96540);const t=({label:n,text:e})=>(0,i.jsx)("div",{className:"grid-item",children:(0,i.jsx)("div",{className:"item-inner",children:n&&"string"==typeof e?`${n}: ${e}`:e})}),o=({children:n})=>(0,i.jsxs)("div",{className:"session-footer",children:[(0,i.jsx)("div",{className:"ui footer divider"}),(0,i.jsx)("div",{className:"info-grid ui",children:n})]})},46510:(n,e,s)=>{s.d(e,{A:()=>a});var i=s(71354),t=s.n(i),o=s(76314),r=s.n(o)()(t());r.push([n.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(100dvh - 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 span.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.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,gCAAgC;EAChC,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(100dvh - 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 span.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.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:""}]);const a=r},78046:(n,e,s)=>{s.d(e,{Z:()=>c});var i=s(74848),t=(s(96540),s(99347)),o=s(67749),r=s(32389),a=s(42695),A=s(13017),l=s(97145);const c=(n,e,s)=>c=>{const{t:d}=(0,r.Bd)(),m=(0,a.lw)(d,s),u=(0,A.g)(),p=(0,l.c7)(n=>e(n).sessions);return p?(0,i.jsx)(n,{items:p,params:u,sessionT:m}):(0,i.jsx)(t.A,{text:(0,a.Tl)("Loading sessions",d,o.KV.COMMON)})}},80783:(n,e,s)=>{s.d(e,{q:()=>l});var i=s(96540),t=s(97145),o=s(48249),r=s(39364),a=s(80377),A=s(35106);const l=(n,e,s,l=!1)=>{const c=(0,r.sL)(),d=(0,o.F)(),m=(0,t.c7)(n=>n.activity.userActive),u=(0,t.c7)(n=>s(n).setActiveSession),p=i.useRef(void 0),h=n=>{(0,A.m)(n,()=>{e.setRead(n,d)}),p.current=void 0};i.useEffect(()=>()=>{u(null)},[]),i.useEffect(()=>(u(n),()=>{p.current&&(clearTimeout(p.current),n&&h(n))}),[n.id]),i.useEffect(()=>{m&&(n=>{const e=l?1e3*c.getState().settings.getValue(a.x.UNREAD_LABEL_DELAY):0;p.current=window.setTimeout(()=>h(n),e)})(n)},[m,n.id])}},91950:(n,e,s)=>{s.d(e,{A:()=>en});var i=s(74848),t=s(96540),o=s(99347),r=s(8098),a=s(68514),A=s(31104),l=s(19247),c=s(25906),d=s(67749),m=s(42695),u=s(4425),p=s(32389),h=s(97145);const E=({sessionMenuItems:n,newButton:e,sessionStoreSelector:s,listActionMenuGetter:t})=>{const{t:o}=(0,p.Bd)(),r=(0,h.c7)(n=>s(n).getTotalUrgencies);return(0,i.jsxs)(A.A,{triggerIcon:(0,i.jsx)(c.Z,{label:"Session menu",urgencies:r()}),children:[(0,i.jsx)(l.A,{caption:(0,m.Tl)("New",o,d.KV.COMMON),children:e}),(0,i.jsx)(l.A,{caption:(0,m.Tl)("Current sessions",o,d.KV.COMMON),children:n}),(0,i.jsx)(l.A,{children:t()})]})},g=({actions:n,activeItem:e})=>{if(!e||(0,r.vU)())return null;const s=Object.values(n.actions)[Object.values(n.actions).length-1];return(0,i.jsx)(a.A,{className:"basic small item close-button",action:s,moduleData:n.moduleData,itemData:e,icon:u.A.CLOSE})},B=({itemHeaderIcon:n,itemHeaderTitle:e})=>(0,i.jsxs)("div",{className:"session-header",children:[n,e]}),x=n=>{var{children:e,onKeyDown:s}=n,t=function(n,e){var s={};for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&e.indexOf(i)<0&&(s[i]=n[i]);if(null!=n&&"function"==typeof Object.getOwnPropertySymbols){var t=0;for(i=Object.getOwnPropertySymbols(n);t<i.length;t++)e.indexOf(i[t])<0&&Object.prototype.propertyIsEnumerable.call(n,i[t])&&(s[i[t]]=n[i[t]])}return s}(n,["children","onKeyDown"]);return(0,i.jsxs)("div",{className:"session-container vertical",onKeyDown:s,tabIndex:0,children:[(0,i.jsxs)("div",{className:"ui main menu menu-bar",children:[(0,i.jsxs)("div",{className:"content-left",children:[(0,i.jsx)(E,Object.assign({},t)),(0,i.jsx)(B,Object.assign({},t))]}),(0,i.jsx)(g,Object.assign({},t))]}),(0,i.jsx)("div",{className:"session-layout",children:e})]})};var f=s(31224),v=s(73070);const C=({sessionMenuItems:n,newButton:e,itemHeaderIcon:s,itemHeaderTitle:o,children:r,itemHeaderDescription:a,onKeyDown:A})=>(e&&(e=t.cloneElement(e,{className:e.props.className+" ui fluid button"})),(0,i.jsxs)(v.xA,{className:"session-container horizontal",onKeyDown:A,tabIndex:0,children:[(0,i.jsxs)("div",{className:"four wide column menu-column",children:[e,!!n.length&&(0,i.jsx)("div",{className:"ui vertical secondary menu",role:"menubar",children:n})]}),(0,i.jsx)("div",{className:"twelve wide stretched column content-column session",children:(0,i.jsxs)("div",{className:"ui segment session-layout",children:[(0,i.jsx)(f.A,{className:"session-header",icon:s,title:(0,i.jsx)("div",{className:"title",children:o}),subHeader:a}),(0,i.jsx)("div",{className:"ui divider",style:{margin:"5px 0px 0px 0px"}}),r]})})]}));var w=s(32728),b=s(18220),y=s(13017),j=s(20311),I=s.n(j);const N=({baseUrl:n})=>{const e=(0,y.Zp)(),s=e=>(I()(!!e,"Trying to get session URL without a session"),`/${n}/session/${e}`),i=`/${n}/new`;return{newUrl:`/${n}/new`,replaceNew:()=>{e(i,{replace:!0})},getSessionUrl:s,pushSession:n=>{e(s(n))},replaceSession:(n,i)=>{e(s(n),{replace:!0,state:i})}}};var O=s(48249);const S=(n,e)=>n.find(n=>n.id===e);var z=s(71352),k=s(46942),T=s.n(k),M=s(45325);const D=({url:n,title:e,className:s})=>(0,i.jsx)(M.A,{className:T()("new",s),icon:u.A.CREATE,url:n,children:e},"button-new"),H=({sessionItem:n,status:e,name:s,unreadInfoStoreSelector:t,url:o})=>(0,i.jsx)(M.A,{url:o,className:"session-item",icon:e,sessionItem:n,unreadInfoStoreSelector:t,children:s});var U=s(83994),K=s(27725),L=s(39364),G=s(85072),V=s.n(G),Y=s(97825),W=s.n(Y),R=s(77659),$=s.n(R),q=s(55056),_=s.n(q),F=s(10540),P=s.n(F),Z=s(41113),J=s.n(Z),X=s(46510),Q={};Q.styleTagTransform=J(),Q.setAttributes=_(),Q.insert=$().bind(null,"head"),Q.domAPI=W(),Q.insertStyleElement=P(),V()(X.A,Q),X.A&&X.A.locals&&X.A.locals;var nn=s(70756);const en=n=>{const e=(0,L.wV)(),s=(0,b.y)(),a=(0,y.Zp)(),A=(0,y.zy)(),{activeItem:l,onKeyDown:c}=(n=>{const[e,s]=t.useState(null),i=(0,y.zy)(),o=(0,O.F)(),{pushSession:a,replaceSession:A,newUrl:l,replaceNew:c}=N({baseUrl:n.baseUrl}),d=()=>`${n.baseUrl}_last_active`;return t.useLayoutEffect(()=>{if(i.pathname===l)return void(e&&s(null));if((()=>{const e=i,t=e.state&&e.state.pending,o=S(n.items,n.activeId);return o?t?(A(o.id,{pending:!1}),!0):(s(o),(0,r.MS)(d(),n.activeId),!0):!!t||0===n.items.length&&(c(),s(null),!0)})())return;if(!e){const e=(0,r.H5)(d());if(e&&S(n.items,e))return void A(e)}const{items:t,activeId:o}=n;let a=0;const m=S(t,o);m&&(a=t.indexOf(m),a===t.length-1&&(a-=1)),A(t[a].id)},[i,n.items]),{onKeyDown:e=>{const{key:s,altKey:i}=e;if(!i||"ArrowUp"!==s&&"ArrowDown"!==s){if(i&&"Insert"===s)e.preventDefault(),c();else if(i&&"Delete"===s){e.preventDefault();const{items:s,activeId:i,sessionApi:t}=n,r=S(s,i);r&&t.removeSession(r,o)}}else{e.preventDefault();const{items:i,activeId:t}=n,o=S(i,t);if(!o)return;const r=i.indexOf(o);if(-1===r)return;const A=i["ArrowUp"===s?r-1:r+1];A&&a(A.id)}},activeItem:e}})(n),h=(0,nn.z)(e,n.editAccess),E=!!n.newLayout&&A.pathname.endsWith("/new"),{disableSideMenu:g,items:B,sessionStoreSelector:f,sessionT:v,uiActions:j}=n,I=g||(0,r.vU)(s),{getItemHeaderTitle:k,getItemHeaderDescription:T,getItemHeaderIcon:M,getNewButton:G,getSessionMenuItems:V,getSessionActionMenuItems:Y}=(n=>{const e=(0,O.F)(),s=(0,y.zy)(),{t}=(0,p.Bd)(),{newUrl:o,getSessionUrl:r}=N({baseUrl:n.baseUrl}),a=e=>{const{itemStatusGetter:s,itemHeaderIconGetter:t}=n;return s?(0,i.jsx)("div",{className:"ui session-status empty circular left mini label "+s(e)}):(0,i.jsx)(U.A,{icon:t(e)})};return{getItemHeaderDescription:()=>{const{itemHeaderDescriptionGetter:e,newDescription:s,activeItem:i,isNewLayout:t}=n;return t?s:i?e(i):null},getItemHeaderIcon:()=>{const{itemHeaderIconGetter:e,newIcon:s,activeItem:t,isNewLayout:o}=n;return o?(0,i.jsx)(U.A,{icon:s}):t?(0,i.jsx)(U.A,{icon:e(t)}):null},getItemHeaderTitle:()=>{const{activeItem:e,newCaption:t,remoteMenuId:o,isNewLayout:r}=n;if(r)return(0,i.jsx)("div",{children:t});if(!e)return null;const{uiActions:a,actionIds:A,itemNameGetter:l,itemHeaderTitleGetter:c}=n,d=A?[...A,"divider","remove"]:void 0,m=(0,i.jsx)(z.Wy,{caption:l(e),actions:a,itemData:e,ids:d,remoteMenuId:o});if(c){const n=c(e,s,m);if(n)return n}return m},getSessionActionMenuItems:()=>{const{items:s,hasEditAccess:o}=n;return o&&0!==s.length?(0,i.jsx)(K.A,{onClick:()=>{const{sessionApi:s,items:i}=n;i.forEach(n=>s.removeSession(n,e))},icon:u.A.REMOVE,children:(0,m.Tl)("Close all",t,d.KV.COMMON)},"close"):null},getNewButton:()=>{const{newCaption:e,hasEditAccess:s}=n;return s&&e?(0,i.jsx)(D,{title:e,url:o},"new-button"):null},getSessionMenuItems:()=>n.items.map(e=>{const{itemNameGetter:s,sessionStoreSelector:t}=n;return(0,i.jsx)(H,{url:r(e.id),name:s(e),unreadInfoStoreSelector:t,status:a(e),sessionItem:e},e.id)})}})(Object.assign(Object.assign({},n),{activeItem:l,hasEditAccess:h,isNewLayout:E}));if(!h&&0===B.length)return(0,i.jsx)(w.A,{title:(0,m.Tl)("No items to show",v.plainT,d.KV.COMMON),description:v.plainT((0,m.j2)("noSessionEditAccess",d.KV.COMMON),"You aren't allowed to open new sessions")});const W=I?x:C;return(0,i.jsx)(W,{itemHeaderTitle:k(),itemHeaderDescription:T(),itemHeaderIcon:M(),newButton:G(),sessionMenuItems:V(),listActionMenuGetter:Y,activeItem:l,sessionStoreSelector:f,onKeyDown:c,actions:j,children:(()=>{const{newLayout:e,sessionT:s}=n;return E&&e?(0,i.jsx)(e,{navigate:a,location:A,sessionT:s}):(()=>{const{activeId:e,items:s,sessionItemLayout:t,sessionApi:r,uiActions:c,sessionT:u,baseUrl:p}=n;if(!l){const{state:n}=A;return n&&n.pending?(0,i.jsx)(o.A,{text:(0,m.Tl)("Waiting for server response",u.plainT,d.KV.COMMON)}):e||0!==s.length?(0,i.jsx)(o.A,{text:(0,m.Tl)("Loading session",u.plainT,d.KV.COMMON)}):void console.error("SessionLayout route: active session missing")}return(0,i.jsx)(t,{sessionItem:l,sessionApi:r,uiActions:c,location:A,navigate:a,sessionT:u,baseUrl:p})})()})()})}}}]);
2
- //# sourceMappingURL=550.43735d298b0c3e70c6bd.chunk.js.map
1
+ "use strict";(self.webpackChunkairdcpp_webui=self.webpackChunkairdcpp_webui||[]).push([[550],{4112:(n,e,s)=>{s.d(e,{R:()=>t});var i=s(4425);const t=(n,e)=>({id:"remove",displayName:"Close",access:e,icon:i.A.REMOVE,handler:({itemData:e,socket:s})=>s.delete(`${n}/${e.id}`)})},38453:(n,e,s)=>{s.d(e,{J:()=>t,q:()=>o});var i=s(74848);s(96540);const t=({label:n,text:e})=>(0,i.jsx)("div",{className:"grid-item",children:(0,i.jsx)("div",{className:"item-inner",children:n&&"string"==typeof e?`${n}: ${e}`:e})}),o=({children:n})=>(0,i.jsxs)("div",{className:"session-footer",children:[(0,i.jsx)("div",{className:"ui footer divider"}),(0,i.jsx)("div",{className:"info-grid ui",children:n})]})},46510:(n,e,s)=>{s.d(e,{A:()=>a});var i=s(71354),t=s.n(i),o=s(76314),r=s.n(o)()(t());r.push([n.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(100dvh - 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 span.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.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,gCAAgC;EAChC,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(100dvh - 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 span.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.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:""}]);const a=r},78046:(n,e,s)=>{s.d(e,{Z:()=>c});var i=s(74848),t=(s(96540),s(99347)),o=s(67749),r=s(32389),a=s(42695),A=s(13017),l=s(97145);const c=(n,e,s)=>c=>{const{t:d}=(0,r.Bd)(),m=(0,a.lw)(d,s),u=(0,A.g)(),p=(0,l.c7)(n=>e(n).sessions);return p?(0,i.jsx)(n,{items:p,params:u,sessionT:m}):(0,i.jsx)(t.A,{text:(0,a.Tl)("Loading sessions",d,o.KV.COMMON)})}},80783:(n,e,s)=>{s.d(e,{q:()=>l});var i=s(96540),t=s(97145),o=s(48249),r=s(39364),a=s(80377),A=s(35106);const l=(n,e,s,l=!1)=>{const c=(0,r.sL)(),d=(0,o.F)(),m=(0,t.c7)(n=>n.activity.userActive),u=(0,t.c7)(n=>s(n).setActiveSession),p=i.useRef(void 0),h=n=>{(0,A.m)(n,()=>{e.setRead(n,d)}),p.current=void 0};i.useEffect(()=>()=>{u(null)},[]),i.useEffect(()=>(u(n),()=>{p.current&&(clearTimeout(p.current),n&&h(n))}),[n.id]),i.useEffect(()=>{m&&(n=>{const e=l?1e3*c.getState().settings.getValue(a.x.UNREAD_LABEL_DELAY):0;p.current=window.setTimeout(()=>h(n),e)})(n)},[m,n.id])}},91950:(n,e,s)=>{s.d(e,{A:()=>sn});var i=s(74848),t=s(96540),o=s(99347),r=s(8098),a=s(68514),A=s(31104),l=s(19247),c=s(25906),d=s(67749),m=s(42695),u=s(4425),p=s(32389),h=s(97145);const g=({sessionMenuItemsGetter:n,newButtonGetter:e,sessionStoreSelector:s,listActionMenuGetter:t})=>{const{t:o}=(0,p.Bd)(),r=(0,h.c7)(n=>s(n).getTotalUrgencies),a=n({role:"menuitem"}),u=e({role:"menuitem"});return(0,i.jsxs)(A.A,{triggerIcon:(0,i.jsx)(c.Z,{label:"Session menu",urgencies:r()}),children:[(0,i.jsx)(l.A,{caption:(0,m.Tl)("New",o,d.KV.COMMON),children:u}),(0,i.jsx)(l.A,{caption:(0,m.Tl)("Current sessions",o,d.KV.COMMON),children:a}),(0,i.jsx)(l.A,{children:t()})]})},E=({actions:n,activeItem:e})=>{if(!e||(0,r.vU)())return null;const s=Object.values(n.actions)[Object.values(n.actions).length-1];return(0,i.jsx)(a.A,{className:"basic small item close-button",action:s,moduleData:n.moduleData,itemData:e,icon:u.A.CLOSE})},f=({itemHeaderIcon:n,itemHeaderTitle:e})=>(0,i.jsxs)("div",{className:"session-header",children:[n,e]}),B=n=>{var{children:e,onKeyDown:s}=n,t=function(n,e){var s={};for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&e.indexOf(i)<0&&(s[i]=n[i]);if(null!=n&&"function"==typeof Object.getOwnPropertySymbols){var t=0;for(i=Object.getOwnPropertySymbols(n);t<i.length;t++)e.indexOf(i[t])<0&&Object.prototype.propertyIsEnumerable.call(n,i[t])&&(s[i[t]]=n[i[t]])}return s}(n,["children","onKeyDown"]);return(0,i.jsxs)("div",{className:"session-container vertical",onKeyDown:s,tabIndex:0,children:[(0,i.jsxs)("div",{className:"ui main menu menu-bar",children:[(0,i.jsxs)("div",{className:"content-left",children:[(0,i.jsx)(g,Object.assign({},t)),(0,i.jsx)(f,Object.assign({},t))]}),(0,i.jsx)(E,Object.assign({},t))]}),(0,i.jsx)("div",{className:"session-layout",children:e})]})};var x=s(31224),v=s(73070);const C="session-content-panel",w=({sessionMenuItemsGetter:n,newButtonGetter:e,itemHeaderIcon:s,itemHeaderTitle:t,children:o,itemHeaderDescription:r,onKeyDown:a})=>{const A=e({role:"tab","aria-controls":C,className:"ui fluid button"}),l=n({role:"tab","aria-controls":C});return(0,i.jsxs)(v.xA,{className:"session-container horizontal",onKeyDown:a,children:[(0,i.jsxs)("nav",{className:"four wide column menu-column","aria-label":"Session items",children:[A,!!l.length&&(0,i.jsx)("div",{className:"ui vertical secondary menu",role:"tablist","aria-orientation":"vertical",children:l})]}),(0,i.jsx)("div",{id:C,role:"tabpanel",className:"twelve wide stretched column content-column session",children:(0,i.jsxs)("div",{className:"ui segment session-layout",children:[(0,i.jsx)(x.A,{className:"session-header",icon:s,title:(0,i.jsx)("div",{className:"title",children:t}),subHeader:r}),(0,i.jsx)("div",{className:"ui divider",style:{margin:"5px 0px 0px 0px"}}),o]})})]})};var b=s(32728),y=s(18220),j=s(13017),O=s(20311),I=s.n(O);const N=({baseUrl:n})=>{const e=(0,j.Zp)(),s=e=>(I()(!!e,"Trying to get session URL without a session"),`/${n}/session/${e}`),i=`/${n}/new`;return{newUrl:`/${n}/new`,replaceNew:()=>{e(i,{replace:!0})},getSessionUrl:s,pushSession:n=>{e(s(n))},replaceSession:(n,i)=>{e(s(n),{replace:!0,state:i})}}};var S=s(48249);const z=(n,e)=>n.find(n=>n.id===e);var k=s(71352),T=s(46942),M=s.n(T),D=s(45325);const H=n=>{var{url:e,title:s,className:t}=n,o=function(n,e){var s={};for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&e.indexOf(i)<0&&(s[i]=n[i]);if(null!=n&&"function"==typeof Object.getOwnPropertySymbols){var t=0;for(i=Object.getOwnPropertySymbols(n);t<i.length;t++)e.indexOf(i[t])<0&&Object.prototype.propertyIsEnumerable.call(n,i[t])&&(s[i[t]]=n[i[t]])}return s}(n,["url","title","className"]);return(0,i.jsx)(D.A,Object.assign({className:M()("new",t),icon:u.A.CREATE,url:e},o,{children:s}),"button-new")};const U=n=>{var{sessionItem:e,status:s,name:t,unreadInfoStoreSelector:o,url:r}=n,a=function(n,e){var s={};for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&e.indexOf(i)<0&&(s[i]=n[i]);if(null!=n&&"function"==typeof Object.getOwnPropertySymbols){var t=0;for(i=Object.getOwnPropertySymbols(n);t<i.length;t++)e.indexOf(i[t])<0&&Object.prototype.propertyIsEnumerable.call(n,i[t])&&(s[i[t]]=n[i[t]])}return s}(n,["sessionItem","status","name","unreadInfoStoreSelector","url"]);return(0,i.jsx)(D.A,Object.assign({url:r,className:"session-item",icon:s,sessionItem:e,unreadInfoStoreSelector:o,"aria-label":t},a,{children:t}))};var G=s(83994),K=s(27725),L=s(39364),V=s(85072),Y=s.n(V),P=s(97825),W=s.n(P),R=s(77659),$=s.n(R),q=s(55056),_=s.n(q),F=s(10540),Z=s.n(F),J=s(41113),X=s.n(J),Q=s(46510),nn={};nn.styleTagTransform=X(),nn.setAttributes=_(),nn.insert=$().bind(null,"head"),nn.domAPI=W(),nn.insertStyleElement=Z(),Y()(Q.A,nn),Q.A&&Q.A.locals&&Q.A.locals;var en=s(70756);const sn=n=>{const e=(0,L.wV)(),s=(0,y.y)(),a=(0,j.Zp)(),A=(0,j.zy)(),{activeItem:l,onKeyDown:c}=(n=>{const[e,s]=t.useState(null),i=(0,j.zy)(),o=(0,S.F)(),{pushSession:a,replaceSession:A,newUrl:l,replaceNew:c}=N({baseUrl:n.baseUrl}),d=()=>`${n.baseUrl}_last_active`;return t.useLayoutEffect(()=>{if(i.pathname===l)return void(e&&s(null));if((()=>{const e=i,t=e.state&&e.state.pending,o=z(n.items,n.activeId);return o?t?(A(o.id,{pending:!1}),!0):(s(o),(0,r.MS)(d(),n.activeId),!0):!!t||0===n.items.length&&(c(),s(null),!0)})())return;if(!e){const e=(0,r.H5)(d());if(e&&z(n.items,e))return void A(e)}const{items:t,activeId:o}=n;let a=0;const m=z(t,o);m&&(a=t.indexOf(m),a===t.length-1&&(a-=1)),A(t[a].id)},[i,n.items]),{onKeyDown:e=>{const{key:s,altKey:i}=e;if(!i||"ArrowUp"!==s&&"ArrowDown"!==s){if(i&&"Insert"===s)e.preventDefault(),c();else if(i&&"Delete"===s){e.preventDefault();const{items:s,activeId:i,sessionApi:t}=n,r=z(s,i);r&&t.removeSession(r,o)}}else{e.preventDefault();const{items:i,activeId:t}=n,o=z(i,t);if(!o)return;const r=i.indexOf(o);if(-1===r)return;const A=i["ArrowUp"===s?r-1:r+1];A&&a(A.id)}},activeItem:e}})(n),h=(0,en.z)(e,n.editAccess),g=!!n.newLayout&&A.pathname.endsWith("/new"),{disableSideMenu:E,items:f,sessionStoreSelector:x,sessionT:v,uiActions:C}=n,O=E||(0,r.vU)(s),{getItemHeaderTitle:I,getItemHeaderDescription:T,getItemHeaderIcon:M,getNewButton:D,getSessionMenuItems:V,getSessionActionMenuItems:Y}=(n=>{const e=(0,S.F)(),s=(0,j.zy)(),{t:o}=(0,p.Bd)(),{newUrl:r,getSessionUrl:a}=N({baseUrl:n.baseUrl}),A=e=>{const{itemStatusGetter:s,itemHeaderIconGetter:t}=n;return s?(0,i.jsx)("div",{className:"ui session-status empty circular left mini label "+s(e)}):(0,i.jsx)(G.A,{icon:t(e)})};return{getItemHeaderDescription:()=>{const{itemHeaderDescriptionGetter:e,newDescription:s,activeItem:i,isNewLayout:t}=n;return t?s:i?e(i):null},getItemHeaderIcon:()=>{const{itemHeaderIconGetter:e,newIcon:s,activeItem:t,isNewLayout:o}=n;return o?(0,i.jsx)(G.A,{icon:s}):t?(0,i.jsx)(G.A,{icon:e(t)}):null},getItemHeaderTitle:()=>{const{activeItem:e,newCaption:t,remoteMenuId:o,isNewLayout:r}=n;if(r)return(0,i.jsx)("div",{children:t});if(!e)return null;const{uiActions:a,actionIds:A,itemNameGetter:l,itemHeaderTitleGetter:c}=n,d=A?[...A,"divider","remove"]:void 0,m=(0,i.jsx)(k.Wy,{caption:l(e),actions:a,itemData:e,ids:d,remoteMenuId:o});if(c){const n=c(e,s,m);if(n)return n}return m},getSessionActionMenuItems:()=>{const{items:s,hasEditAccess:t}=n;return t&&0!==s.length?(0,i.jsx)(K.A,{onClick:()=>{const{sessionApi:s,items:i}=n;i.forEach(n=>s.removeSession(n,e))},icon:u.A.REMOVE,children:(0,m.Tl)("Close all",o,d.KV.COMMON)},"close"):null},getNewButton:e=>{const{newCaption:s,hasEditAccess:t}=n;return t&&s?(0,i.jsx)(H,Object.assign({title:s,url:r},e),"new-button"):null},getSessionMenuItems:e=>n.items.map(s=>{const{itemNameGetter:i,sessionStoreSelector:o}=n;return(0,t.createElement)(U,Object.assign({},e,{key:s.id,url:a(s.id),name:i(s),unreadInfoStoreSelector:o,status:A(s),sessionItem:s}))})}})(Object.assign(Object.assign({},n),{activeItem:l,hasEditAccess:h,isNewLayout:g}));if(!h&&0===f.length)return(0,i.jsx)(b.A,{title:(0,m.Tl)("No items to show",v.plainT,d.KV.COMMON),description:v.plainT((0,m.j2)("noSessionEditAccess",d.KV.COMMON),"You aren't allowed to open new sessions")});const P=O?B:w;return(0,i.jsx)(P,{itemHeaderTitle:I(),itemHeaderDescription:T(),itemHeaderIcon:M(),newButtonGetter:D,sessionMenuItemsGetter:V,listActionMenuGetter:Y,activeItem:l,sessionStoreSelector:x,onKeyDown:c,actions:C,children:(()=>{const{newLayout:e,sessionT:s}=n;return g&&e?(0,i.jsx)(e,{navigate:a,location:A,sessionT:s}):(()=>{const{activeId:e,items:s,sessionItemLayout:t,sessionApi:r,uiActions:c,sessionT:u,baseUrl:p}=n;if(!l){const{state:n}=A;return n&&n.pending?(0,i.jsx)(o.A,{text:(0,m.Tl)("Waiting for server response",u.plainT,d.KV.COMMON)}):e||0!==s.length?(0,i.jsx)(o.A,{text:(0,m.Tl)("Loading session",u.plainT,d.KV.COMMON)}):void console.error("SessionLayout route: active session missing")}return(0,i.jsx)(t,{sessionItem:l,sessionApi:r,uiActions:c,location:A,navigate:a,sessionT:u,baseUrl:p})})()})()})}}}]);
2
+ //# sourceMappingURL=550.10703917b7e833fa8ae9.chunk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"js/550.10703917b7e833fa8ae9.chunk.js","mappings":"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","sources":["webpack://airdcpp-webui/./src/actions/ui/decorators/SessionActionDecorator.ts","webpack://airdcpp-webui/./src/routes/Sidebar/components/SessionFooter.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/sessions.css","webpack://airdcpp-webui/./src/routes/Sidebar/decorators/SessionProviderDecorator.tsx","webpack://airdcpp-webui/./src/effects/ActiveSessionEffect.ts","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/components/SessionNewButton.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/components/SessionMenuItem.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/sessions.css?90b7","webpack://airdcpp-webui/./src/routes/Sidebar/components/SessionLayout.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/components/SessionMenuComponents.tsx"],"sourcesContent":["import 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> = ({\r\n itemData: session,\r\n socket,\r\n }) => {\r\n return socket.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 * 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","// 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(100dvh - 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 span.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.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,gCAAgC;EAChC,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(100dvh - 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 span.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.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 * as React from 'react';\r\n\r\nimport Loader from '@/components/semantic/Loader';\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';\r\nimport { useSessionStoreProperty } from '@/context/SessionStoreContext';\r\n\r\nexport interface SessionProviderDecoratorProps {}\r\n\r\nexport interface SessionProviderDecoratorChildProps<SessionT extends UI.SessionItem> {\r\n items: SessionT[];\r\n sessionT: UI.ModuleTranslator;\r\n params: UI.RouteParams;\r\n}\r\n\r\nconst SessionProviderDecorator = <SessionT extends UI.SessionItem>(\r\n Component: React.ComponentType<SessionProviderDecoratorChildProps<SessionT>>,\r\n sessionStoreSelector: UI.SessionStoreSelector<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\r\n const sessions = useSessionStoreProperty(\r\n (state) => sessionStoreSelector(state).sessions,\r\n );\r\n if (!sessions) {\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","import * as React from 'react';\r\n\r\nimport * as UI from '@/types/ui';\r\n\r\nimport { useSessionStoreProperty } from '@/context/SessionStoreContext';\r\nimport { useSocket } from '@/context/SocketContext';\r\nimport { useAppStoreApi } from '@/context/AppStoreContext';\r\nimport { LocalSettings } from '@/constants/LocalSettingConstants';\r\nimport { checkUnreadSessionInfo } from '@/utils/SessionUtils';\r\n\r\nexport const useActiveSession = (\r\n sessionItem: UI.SessionItem,\r\n actions: UI.SessionAPIActions<UI.SessionItem>,\r\n sessionStoreSelector: UI.SessionStoreSelector,\r\n useReadDelay = false,\r\n) => {\r\n const appStoreApi = useAppStoreApi();\r\n const socket = useSocket();\r\n const userActive = useSessionStoreProperty((state) => state.activity.userActive);\r\n const activeSessionStoreSetter = useSessionStoreProperty(\r\n (state) => sessionStoreSelector(state).setActiveSession,\r\n );\r\n\r\n const readTimeout = React.useRef<number | undefined>(undefined);\r\n\r\n const checkSetRead = (sessionItemRead: UI.SessionItem) => {\r\n checkUnreadSessionInfo(sessionItemRead, () => {\r\n actions.setRead(sessionItemRead, socket);\r\n });\r\n\r\n readTimeout.current = undefined;\r\n };\r\n\r\n const scheduleCheckSetRead = (sessionItemNew: UI.SessionItem) => {\r\n const timeout = !useReadDelay\r\n ? 0\r\n : appStoreApi\r\n .getState()\r\n .settings.getValue<number>(LocalSettings.UNREAD_LABEL_DELAY) * 1000;\r\n\r\n readTimeout.current = window.setTimeout(() => checkSetRead(sessionItemNew), timeout);\r\n };\r\n\r\n React.useEffect(() => {\r\n return () => {\r\n activeSessionStoreSetter(null);\r\n };\r\n }, []);\r\n\r\n React.useEffect(() => {\r\n activeSessionStoreSetter(sessionItem);\r\n return () => {\r\n if (readTimeout.current) {\r\n // Set the previously active session as read\r\n clearTimeout(readTimeout.current);\r\n\r\n if (sessionItem) {\r\n checkSetRead(sessionItem);\r\n }\r\n }\r\n };\r\n }, [sessionItem.id]);\r\n\r\n React.useEffect(() => {\r\n if (userActive) {\r\n scheduleCheckSetRead(sessionItem);\r\n }\r\n }, [userActive, sessionItem.id]);\r\n};\r\n","import * as React from 'react';\r\nimport { usingMobileLayout } 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\nimport { useSessionStoreProperty } from '@/context/SessionStoreContext';\r\n\r\ntype SessionDropdownProps<SessionT extends UI.SessionItemBase> = Pick<\r\n SessionMainLayoutProps<SessionT>,\r\n | 'sessionMenuItemsGetter'\r\n | 'newButtonGetter'\r\n | 'sessionStoreSelector'\r\n | 'listActionMenuGetter'\r\n>;\r\n\r\nconst SessionDropdown = <SessionT extends UI.SessionItemBase>({\r\n sessionMenuItemsGetter,\r\n newButtonGetter,\r\n sessionStoreSelector,\r\n listActionMenuGetter,\r\n}: SessionDropdownProps<SessionT>) => {\r\n const { t } = useTranslation();\r\n const getTotalUrgencies = useSessionStoreProperty(\r\n (state) => sessionStoreSelector(state).getTotalUrgencies,\r\n );\r\n\r\n const sessionMenuItems = sessionMenuItemsGetter({\r\n role: 'menuitem',\r\n });\r\n const newButton = newButtonGetter({\r\n role: 'menuitem',\r\n });\r\n\r\n return (\r\n <SectionedDropdown\r\n triggerIcon={<MenuIcon label=\"Session menu\" urgencies={getTotalUrgencies()} />}\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 || usingMobileLayout()) {\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\nexport default TopMenuLayout;\r\n","import * 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\n// Define a static ID for the content panel so the tabs can control it.\r\nconst CONTENT_PANEL_ID = 'session-content-panel';\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 sessionMenuItemsGetter,\r\n newButtonGetter,\r\n itemHeaderIcon,\r\n itemHeaderTitle,\r\n children,\r\n itemHeaderDescription,\r\n onKeyDown,\r\n}: SessionMainLayoutProps<SessionT, SessionApiT, UIActionsT>) => {\r\n const newButton = newButtonGetter({\r\n role: 'tab',\r\n 'aria-controls': CONTENT_PANEL_ID,\r\n className: 'ui fluid button',\r\n });\r\n\r\n // Find the active menu item to link the panel to its controlling tab\r\n // const activeItem = sessionMenuItems.find((item) => item.props.active);\r\n\r\n const sessionMenuItems = sessionMenuItemsGetter({\r\n role: 'tab',\r\n 'aria-controls': CONTENT_PANEL_ID,\r\n });\r\n\r\n return (\r\n // The onKeyDown handler for roving focus is correct, but the container itself should not be a tab stop.\r\n <Grid className=\"session-container horizontal\" onKeyDown={onKeyDown}>\r\n {/* This <nav> element provides a navigation landmark for screen readers */}\r\n <nav className=\"four wide column menu-column\" aria-label=\"Session items\">\r\n {newButton}\r\n {!!sessionMenuItems.length && (\r\n <div\r\n className=\"ui vertical secondary menu\"\r\n role=\"tablist\"\r\n aria-orientation=\"vertical\"\r\n >\r\n {/* The sessionMenuItems passed in must have role=\"tab\" */}\r\n {sessionMenuItems}\r\n </div>\r\n )}\r\n </nav>\r\n {/* This is the content panel controlled by the tabs. */}\r\n <div\r\n id={CONTENT_PANEL_ID}\r\n role=\"tabpanel\"\r\n // It is labelled by the currently active tab.\r\n // This assumes the menu item component has a unique `id` prop.\r\n // aria-labelledby={activeItem ? activeItem.props.id : undefined}\r\n className=\"twelve wide stretched column content-column session\"\r\n >\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\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';\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 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';\r\nimport { useSessionRouteHelpers } from './useSessionHelpers';\r\nimport { SessionLocationState } from '../types';\r\nimport { useSocket } from '@/context/SocketContext';\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.SessionAPIActions<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 const socket = useSocket();\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, socket);\r\n }\r\n }\r\n };\r\n\r\n return {\r\n onKeyDown,\r\n activeItem,\r\n };\r\n};\r\n","import * as React from 'react';\r\nimport classNames from 'classnames';\r\n\r\nimport IconConstants from '@/constants/IconConstants';\r\nimport RouterMenuItemLink, {\r\n RouterMenuItemLinkProps,\r\n} from '@/components/semantic/RouterMenuItemLink';\r\n\r\ninterface SessionNewButtonProps extends Omit<RouterMenuItemLinkProps, 'url' | 'title'> {\r\n url: string;\r\n title: string;\r\n className?: string;\r\n}\r\n\r\nconst SessionNewButton: React.FC<SessionNewButtonProps> = ({\r\n url,\r\n title,\r\n className,\r\n ...other\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 {...other}\r\n >\r\n {title}\r\n </RouterMenuItemLink>\r\n);\r\n\r\nexport default SessionNewButton;\r\n","import * as React from 'react';\r\n\r\nimport RouterMenuItemLink, {\r\n RouterMenuItemLinkProps,\r\n} from '@/components/semantic/RouterMenuItemLink';\r\n\r\nimport * as UI from '@/types/ui';\r\n\r\nexport interface SessionMenuItemProps extends Partial<RouterMenuItemLinkProps> {\r\n url: string;\r\n name: string;\r\n unreadInfoStoreSelector: UI.SessionStoreSelector;\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 unreadInfoStoreSelector,\r\n url,\r\n ...other\r\n}) => (\r\n <RouterMenuItemLink\r\n url={url}\r\n className=\"session-item\"\r\n icon={status}\r\n sessionItem={sessionItem}\r\n unreadInfoStoreSelector={unreadInfoStoreSelector}\r\n aria-label={name}\r\n {...other}\r\n >\r\n {name}\r\n </RouterMenuItemLink>\r\n);\r\n\r\nexport default SessionMenuItem;\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\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 { usingMobileLayout } 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 {\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\nimport { useSession } from '@/context/AppStoreContext';\r\n\r\nimport '../sessions.css';\r\nimport { hasAccess } from '@/utils/AuthUtils';\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 session = useSession();\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 = hasAccess(session, props.editAccess);\r\n const isNewLayout = !!props.newLayout && location.pathname.endsWith('/new');\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 baseUrl,\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 sessionItem={activeItem}\r\n sessionApi={sessionApi}\r\n uiActions={uiActions}\r\n location={location}\r\n navigate={navigate}\r\n sessionT={sessionT}\r\n baseUrl={baseUrl}\r\n />\r\n );\r\n };\r\n\r\n const getChildren = () => {\r\n const { newLayout: NewLayout, sessionT } = props;\r\n if (isNewLayout && 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, sessionStoreSelector, sessionT, uiActions } = props;\r\n\r\n const useTopMenu = disableSideMenu || usingMobileLayout(layoutWidth);\r\n\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, isNewLayout });\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(\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 MenuLayout = useTopMenu ? TopMenuLayout : SideMenuLayout;\r\n return (\r\n <MenuLayout\r\n itemHeaderTitle={getItemHeaderTitle()}\r\n itemHeaderDescription={getItemHeaderDescription()}\r\n itemHeaderIcon={getItemHeaderIcon()}\r\n newButtonGetter={getNewButton}\r\n sessionMenuItemsGetter={getSessionMenuItems}\r\n listActionMenuGetter={getSessionActionMenuItems}\r\n activeItem={activeItem}\r\n sessionStoreSelector={sessionStoreSelector}\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 { 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';\r\nimport { useSessionRouteHelpers } from './effects/useSessionHelpers';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useSocket } from '@/context/SocketContext';\r\nimport { RouterMenuItemLinkProps } from '@/components/semantic/RouterMenuItemLink';\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 isNewLayout: boolean;\r\n } & SessionLayoutLabels &\r\n SessionLayoutManageProps<SessionT, SessionApiT, UIActionT>,\r\n) => {\r\n const socket = useSocket();\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 // Current session\r\n getItemHeaderDescription: () => {\r\n const { itemHeaderDescriptionGetter, newDescription, activeItem, isNewLayout } =\r\n props;\r\n if (isNewLayout) {\r\n return newDescription;\r\n }\r\n\r\n if (activeItem) {\r\n return itemHeaderDescriptionGetter(activeItem);\r\n }\r\n\r\n return null;\r\n },\r\n getItemHeaderIcon: () => {\r\n const { itemHeaderIconGetter, newIcon, activeItem, isNewLayout } = props;\r\n if (isNewLayout) {\r\n return <Icon icon={newIcon} />;\r\n }\r\n\r\n if (activeItem) {\r\n return <Icon icon={itemHeaderIconGetter(activeItem)} />;\r\n }\r\n\r\n return null;\r\n },\r\n getItemHeaderTitle: () => {\r\n const { activeItem, newCaption, remoteMenuId, isNewLayout } = props;\r\n if (isNewLayout) {\r\n return <div>{newCaption}</div>;\r\n }\r\n\r\n if (!activeItem) {\r\n return null;\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 remoteMenuId={remoteMenuId}\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\r\n // Other\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, socket));\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: (menuItemProps?: Partial<RouterMenuItemLinkProps>) => {\r\n const { newCaption, hasEditAccess } = props;\r\n if (!hasEditAccess || !newCaption) {\r\n return null;\r\n }\r\n\r\n return (\r\n <SessionNewButton\r\n key=\"new-button\"\r\n title={newCaption}\r\n url={newUrl}\r\n {...menuItemProps}\r\n />\r\n );\r\n },\r\n getSessionMenuItems: (menuItemProps?: Partial<RouterMenuItemLinkProps>) => {\r\n const getSessionMenuItem = (sessionItem: SessionT) => {\r\n const { itemNameGetter, sessionStoreSelector } = props;\r\n return (\r\n <SessionMenuItem\r\n {...menuItemProps}\r\n key={sessionItem.id}\r\n url={getSessionUrl(sessionItem.id)}\r\n name={itemNameGetter(sessionItem)}\r\n unreadInfoStoreSelector={sessionStoreSelector}\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"],"names":["BuildRemoveSessionAction","sessionsUrl","editAccess","id","displayName","access","icon","REMOVE","handler","itemData","session","socket","delete","FooterItem","label","text","className","SessionFooter","children","___CSS_LOADER_EXPORT___","push","module","SessionProviderDecorator","Component","sessionStoreSelector","moduleId","props","t","sessionT","params","sessions","state","items","COMMON","useActiveSession","sessionItem","actions","useReadDelay","appStoreApi","userActive","activity","activeSessionStoreSetter","setActiveSession","readTimeout","undefined","checkSetRead","sessionItemRead","setRead","current","clearTimeout","sessionItemNew","timeout","getState","settings","getValue","UNREAD_LABEL_DELAY","window","setTimeout","scheduleCheckSetRead","SessionDropdown","sessionMenuItemsGetter","newButtonGetter","listActionMenuGetter","getTotalUrgencies","sessionMenuItems","role","newButton","SectionedDropdown","triggerIcon","MenuIcon","urgencies","MenuSection","caption","CloseButton","activeItem","closeAction","Object","values","length","ActionButton","A","action","moduleData","IconConstants","CLOSE","SessionItemHeader","itemHeaderIcon","itemHeaderTitle","onKeyDown","tabIndex","CONTENT_PANEL_ID","itemHeaderDescription","Grid","LayoutHeader","title","subHeader","style","margin","useSessionRouteHelpers","baseUrl","navigate","getSessionUrl","newUrl","replaceNew","replace","pushSession","replaceSession","findItem","find","item","url","other","RouterMenuItemLink","CREATE","status","name","unreadInfoStoreSelector","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","locals","layoutWidth","location","setActiveItem","getStorageKey","pathname","routerLocation","pending","activeItemNew","activeId","checkActiveItem","lastId","newItemPos","oldItem","indexOf","event","key","altKey","preventDefault","sessionApi","removeSession","currentIndex","newSession","useSessionManager","hasEditAccess","isNewLayout","newLayout","endsWith","disableSideMenu","uiActions","useTopMenu","getItemHeaderTitle","getItemHeaderDescription","getItemHeaderIcon","getNewButton","getSessionMenuItems","getSessionActionMenuItems","getItemStatus","itemStatusGetter","itemHeaderIconGetter","Icon","itemHeaderDescriptionGetter","newDescription","newIcon","newCaption","remoteMenuId","actionIds","itemNameGetter","itemHeaderTitleGetter","ids","actionMenu","header","MenuItemLink","onClick","forEach","menuItemProps","map","useComponents","Message","plainT","description","MenuLayout","NewLayout","sessionItemLayout","SessionItemLayout","Loader","console","error","getSessionChildren","getChildren"],"sourceRoot":""}