@agent-native/dispatch 0.40.13 → 0.40.14-nightly-20261006010750

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 (34) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/components/connected-app-card.d.ts.map +1 -1
  3. package/dist/components/connected-app-card.js +23 -4
  4. package/dist/components/connected-app-card.js.map +1 -1
  5. package/dist/components/layout/Layout.d.ts.map +1 -1
  6. package/dist/components/layout/Layout.js +116 -60
  7. package/dist/components/layout/Layout.js.map +1 -1
  8. package/dist/components/layout/workspace-apps-rail.d.ts.map +1 -1
  9. package/dist/components/layout/workspace-apps-rail.js +35 -9
  10. package/dist/components/layout/workspace-apps-rail.js.map +1 -1
  11. package/dist/lib/other-apps.d.ts +1 -0
  12. package/dist/lib/other-apps.d.ts.map +1 -1
  13. package/dist/lib/other-apps.js +29 -1
  14. package/dist/lib/other-apps.js.map +1 -1
  15. package/dist/lib/workspace-apps.d.ts +2 -1
  16. package/dist/lib/workspace-apps.d.ts.map +1 -1
  17. package/dist/lib/workspace-apps.js +15 -5
  18. package/dist/lib/workspace-apps.js.map +1 -1
  19. package/dist/routes/pages/apps.d.ts.map +1 -1
  20. package/dist/routes/pages/apps.js +17 -4
  21. package/dist/routes/pages/apps.js.map +1 -1
  22. package/package.json +4 -4
  23. package/src/components/connected-app-card.spec.tsx +100 -0
  24. package/src/components/connected-app-card.tsx +38 -9
  25. package/src/components/layout/Layout.spec.tsx +397 -6
  26. package/src/components/layout/Layout.tsx +173 -85
  27. package/src/components/layout/workspace-apps-rail.spec.tsx +69 -7
  28. package/src/components/layout/workspace-apps-rail.tsx +49 -7
  29. package/src/lib/other-apps.spec.ts +84 -2
  30. package/src/lib/other-apps.ts +39 -1
  31. package/src/lib/workspace-apps.spec.ts +53 -0
  32. package/src/lib/workspace-apps.ts +15 -7
  33. package/src/routes/pages/apps.spec.tsx +132 -0
  34. package/src/routes/pages/apps.tsx +46 -10
@@ -1 +1 @@
1
- {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../../src/routes/pages/apps.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AACtD,OAAO,EACL,QAAQ,EACR,eAAe,EACf,cAAc,EACd,UAAU,EACV,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,OAAO,GACR,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EACL,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AACrC,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,uCAAuC,GAExC,MAAM,0BAA0B,CAAC;AAElC,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;AACxC,CAAC;AAQD,MAAM,CAAC,OAAO,UAAU,cAAc;IACpC,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,EAAE,CAAC;IAC9B,OAAO,KAAK,CAAC,CAAC,CAAC,KAAC,MAAM,KAAG,CAAC,CAAC,CAAC,KAAC,SAAS,KAAG,CAAC;AAC5C,CAAC;AAED,SAAS,SAAS;IAChB,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnD,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,YAAY,EAAE,GAAG,qBAAqB,EAAE,CAAC;IAC3E,MAAM,SAAS,GAAG,cAAc,CAAC,qBAAqB,EAAE;QACtD,iBAAiB,EAAE,KAAK;QACxB,eAAe,EAAE,IAAI;KACtB,CAAC,CAAC;IACH,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;IAC9D,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,cAAc,CACxC,oBAAoB,EACpB,EAAE,EACF,EAAE,SAAS,EAAE,MAAM,EAAE,CACtB,CAAC;IACF,MAAM,EAAE,GAAG,SAAsC,CAAC;IAClD,MAAM,cAAc,GAAG,EAAE,EAAE,WAAW,IAAI,EAAE,EAAE,IAAI,IAAI,IAAI,CAAC;IAC3D,MAAM,OAAO,GAAI,IAA8B,CAAC,MAAM,CACpD,uCAAuC,CACxC,CAAC;IACF,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IACzE,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IAC1E,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC3D,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACjE,MAAM,kBAAkB,GAAG,kBAAkB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACnE,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACrE,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAC1D,wBAAwB,CAAC,GAAG,EAAE,WAAW,CAAC,CAC3C,CAAC;IACF,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAC5D,wBAAwB,CAAC,GAAG,EAAE,WAAW,CAAC,CAC3C,CAAC;IACF,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAC9D,wBAAwB,CAAC,GAAG,EAAE,WAAW,CAAC,CAC3C,CAAC;IACF,MAAM,gBAAgB,GACpB,kBAAkB,CAAC,MAAM,GAAG,CAAC;QAC7B,mBAAmB,CAAC,MAAM,GAAG,CAAC;QAC9B,oBAAoB,CAAC,MAAM,GAAG,CAAC,CAAC;IAClC,MAAM,gBAAgB,GAAG,WAAW,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC;IAE7D,OAAO,CACL,KAAC,aAAa,IACZ,KAAK,EAAE,CAAC,CAAC,mBAAmB,CAAC,EAC7B,WAAW,EACT,cAAc;YACZ,CAAC,CAAC,CAAC,CAAC,6CAA6C,EAAE;gBAC/C,SAAS,EAAE,cAAc;aAC1B,CAAC;YACJ,CAAC,CAAC,CAAC,CAAC,gCAAgC,CAAC,YAGzC,eAAK,SAAS,EAAC,WAAW,aACxB,mBAAS,SAAS,EAAC,WAAW,aAC5B,eAAK,SAAS,EAAC,mDAAmD,aAChE,eAAK,SAAS,EAAC,gCAAgC,aAC7C,KAAC,QAAQ,IACP,IAAI,EAAE,EAAE,EACR,SAAS,EAAC,uCAAuC,GACjD,EACF,cAAK,SAAS,EAAC,SAAS,YACtB,aAAI,SAAS,EAAC,gDAAgD,YAC3D,CAAC,CAAC,yBAAyB,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,GACzD,GACD,IACF,EACN,eAAK,SAAS,EAAC,uDAAuD,aACnE,CAAC,gBAAgB,CAAC,CAAC,CAAC,CACnB,KAAC,kBAAkB,IACjB,SAAS,EAAC,qBAAqB,EAC/B,KAAK,EAAE,WAAW,EAClB,aAAa,EAAE,cAAc,GAC7B,CACH,CAAC,CAAC,CAAC,IAAI,EACP,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACjD,KAAC,gBAAgB,IACf,KAAK,EAAC,KAAK,EACX,OAAO,EACL,MAAC,MAAM,IAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAC,SAAS,aACjC,KAAC,QAAQ,IAAC,IAAI,EAAE,EAAE,EAAE,SAAS,EAAC,QAAQ,GAAG,EACxC,CAAC,CAAC,uBAAuB,EAAE;wDAC1B,YAAY,EAAE,SAAS;qDACxB,CAAC,IACK,GAEX,CACH,CAAC,CAAC,CAAC,IAAI,IACJ,IACF,EAEL,CAAC,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAC7D,YAAG,SAAS,EAAC,+BAA+B,EAAC,IAAI,EAAC,QAAQ,YACvD,gBAAgB,KAAK,MAAM;gCAC1B,CAAC,CAAC,CAAC,CAAC,iCAAiC,EAAE;oCACnC,YAAY,EAAE,8BAA8B;iCAC7C,CAAC;gCACJ,CAAC,CAAC,CAAC,CAAC,mCAAmC,EAAE;oCACrC,YAAY,EAAE,yCAAyC;iCACxD,CAAC,GACJ,CACL,CAAC,CAAC,CAAC,IAAI,EAEP,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CACnB,KAAC,gBAAgB,IACf,KAAK,EAAE,SAAS,CAAC,KAAK,EACtB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,SAAS,CAAC,OAAO,EAAE,GACvC,CACH,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CACrB,KAAC,gBAAgB,KAAG,CACrB,CAAC,CAAC,CAAC,CAAC,gBAAgB,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAC5C,KAAC,uBAAuB,IACtB,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,GACjC,CACH,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAClC,KAAC,OAAO,IAAC,SAAS,EAAE,mBAAmB,YACpC,kBAAkB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAC/B,KAAC,gBAAgB,IAEf,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,uBAAuB,EAClC,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,EACzD,cAAc,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,IAJrC,GAAG,CAAC,EAAE,CAKX,CACH,CAAC,GACM,CACX,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACvD,KAAC,oBAAoB,KAAG,CACzB,CAAC,CAAC,CAAC,CACF,KAAC,cAAc,KAAG,CACnB,IACO,EAET,WAAW,CAAC,MAAM,GAAG,CAAC;oBACvB,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CACxD,KAAC,WAAW,IACV,IAAI,EAAE,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,EAChD,YAAY,EAAE,cAAc,YAE5B,mBAAS,SAAS,EAAC,yBAAyB,aAC1C,eAAK,SAAS,EAAC,mDAAmD,aAChE,eAAK,SAAS,EAAC,iCAAiC,aAC9C,KAAC,cAAc,IACb,IAAI,EAAE,EAAE,EACR,SAAS,EAAC,gCAAgC,GAC1C,EACF,eAAK,SAAS,EAAC,SAAS,aACtB,aAAI,SAAS,EAAC,uCAAuC,YAClD,CAAC,CAAC,4BAA4B,CAAC,GAC7B,EACL,YAAG,SAAS,EAAC,+BAA+B,YACzC,CAAC,CAAC,6BAA6B,EAAE;4DAChC,KAAK,EAAE,WAAW,CAAC,MAAM;yDAC1B,CAAC,GACA,IACA,IACF,EACN,KAAC,kBAAkB,IAAC,OAAO,kBACzB,MAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,SAAS,EAAC,SAAS,aAElB,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;oDACzC,CAAC,CAAC,CAAC,CAAC,gCAAgC,CAAC;oDACrC,CAAC,CAAC,CAAC,CAAC,gCAAgC,CAAC,EACvC,KAAC,eAAe,IACd,IAAI,EAAE,EAAE,EACR,SAAS,EAAE,EAAE,CACX,sBAAsB,EACtB,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;wDAC1C,YAAY,CACf,GACD,IACK,GACU,IACjB,EACN,KAAC,kBAAkB,cACjB,KAAC,OAAO,IAAC,SAAS,EAAE,mBAAmB,YACpC,mBAAmB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAChC,KAAC,gBAAgB,IAEf,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,uBAAuB,IAF7B,GAAG,CAAC,EAAE,CAGX,CACH,CAAC,GACM,GACS,IACb,GACE,CACf,CAAC,CAAC,CAAC,IAAI,EAEP,YAAY,CAAC,MAAM,GAAG,CAAC;oBACxB,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CACzD,KAAC,WAAW,IACV,IAAI,EAAE,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,EAC/C,YAAY,EAAE,aAAa,YAE3B,mBAAS,SAAS,EAAC,WAAW,aAC5B,eAAK,SAAS,EAAC,iEAAiE,aAC9E,eAAK,SAAS,EAAC,iCAAiC,aAC9C,KAAC,UAAU,IACT,IAAI,EAAE,EAAE,EACR,SAAS,EAAC,gCAAgC,GAC1C,EACF,eAAK,SAAS,EAAC,SAAS,aACtB,aAAI,SAAS,EAAC,uCAAuC,YAClD,CAAC,CAAC,2BAA2B,CAAC,GAC5B,EACL,YAAG,SAAS,EAAC,+BAA+B,YACzC,CAAC,CAAC,+BAA+B,EAAE;4DAClC,KAAK,EAAE,YAAY,CAAC,MAAM;yDAC3B,CAAC,GACA,IACA,IACF,EACN,KAAC,kBAAkB,IAAC,OAAO,kBACzB,MAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,SAAS,EAAC,SAAS,aAElB,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;oDACxC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC;oDAC1B,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,EAC5B,KAAC,eAAe,IACd,IAAI,EAAE,EAAE,EACR,SAAS,EAAE,EAAE,CACX,sBAAsB,EACtB,CAAC,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;wDACzC,YAAY,CACf,GACD,IACK,GACU,IACjB,EACN,KAAC,kBAAkB,cACjB,KAAC,OAAO,IAAC,SAAS,EAAE,mBAAmB,YACpC,oBAAoB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACjC,KAAC,gBAAgB,IAEf,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,uBAAuB,IAF7B,GAAG,CAAC,EAAE,CAGX,CACH,CAAC,GACM,GACS,IACb,GACE,CACf,CAAC,CAAC,CAAC,IAAI,IACJ,GACQ,CACjB,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB;IACvB,OAAO,CACL,KAAC,OAAO,IAAC,SAAS,EAAE,mBAAmB,YACpC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAC3C,eAEE,SAAS,EAAE,EAAE,CACX,sEAAsE,EACtE,uBAAuB,CACxB,aAED,KAAC,QAAQ,IAAC,SAAS,EAAC,4BAA4B,GAAG,EACnD,eAAK,SAAS,EAAC,0BAA0B,aACvC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,WAAW,GAAG,IAC9B,EACN,KAAC,QAAQ,IAAC,SAAS,EAAC,8BAA8B,GAAG,KAXhD,KAAK,CAYN,CACP,CAAC,GACM,CACX,CAAC;AACJ,CAAC;AAED,SAAS,cAAc;IACrB,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,OAAO,CACL,eAAK,SAAS,EAAC,gEAAgE,aAC7E,cAAK,SAAS,EAAC,4FAA4F,YACzG,KAAC,QAAQ,IAAC,IAAI,EAAE,EAAE,GAAI,GAClB,EACN,aAAI,SAAS,EAAC,4CAA4C,YACvD,CAAC,CAAC,gCAAgC,CAAC,GACjC,EACL,YAAG,SAAS,EAAC,qDAAqD,YAC/D,CAAC,CAAC,2CAA2C,CAAC,GAC7C,EACJ,cAAK,SAAS,EAAC,MAAM,YACnB,KAAC,gBAAgB,IACf,OAAO,EACL,MAAC,MAAM,IAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAC,SAAS,aACjC,KAAC,QAAQ,IAAC,IAAI,EAAE,EAAE,EAAE,SAAS,EAAC,QAAQ,GAAG,EACxC,CAAC,CAAC,uBAAuB,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,IACjD,GAEX,GACE,IACF,CACP,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB;IAC3B,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,OAAO,CACL,eAAK,SAAS,EAAC,gEAAgE,aAC7E,YAAG,SAAS,EAAC,qCAAqC,YAC/C,CAAC,CAAC,sCAAsC,CAAC,GACxC,EACJ,YAAG,SAAS,EAAC,qDAAqD,YAC/D,CAAC,CAAC,iDAAiD,CAAC,GACnD,IACA,CACP,CAAC;AACJ,CAAC","sourcesContent":["import { useActionQuery } from \"@agent-native/core/client/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport {\n IconApps,\n IconChevronDown,\n IconClockHour4,\n IconEyeOff,\n IconPlus,\n} from \"@tabler/icons-react\";\nimport { useState } from \"react\";\nimport { Outlet, useParams } from \"react-router\";\n\nimport { ActionQueryError } from \"../../components/action-query-error\";\nimport {\n APP_LIST_GRID_CLASS,\n APP_LIST_GRID_ROW_CLASS,\n AppList,\n} from \"../../components/app-list-row\";\nimport { CreateAppPopover } from \"../../components/create-app-popover\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"../../components/ui/collapsible\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { WorkspaceAppCard } from \"../../components/workspace-app-card\";\nimport {\n WorkspaceAppSearch,\n WorkspaceAppSearchEmpty,\n} from \"../../components/workspace-app-search\";\nimport { cn } from \"../../lib/utils\";\nimport {\n orderWorkspaceApps,\n useWorkspaceAppLayout,\n workspaceAppMatchesQuery,\n} from \"../../lib/workspace-app-layout\";\nimport {\n isWorkspaceAppVisibleInDefaultLaunchers,\n type WorkspaceAppSummary,\n} from \"../../lib/workspace-apps\";\n\nexport function meta() {\n return [{ title: \"Apps — Dispatch\" }];\n}\n\ninterface WorkspaceInfo {\n name: string | null;\n displayName: string | null;\n appCount: number;\n}\n\nexport default function AppsRouteEntry() {\n const { appId } = useParams();\n return appId ? <Outlet /> : <AppsRoute />;\n}\n\nfunction AppsRoute() {\n const t = useT();\n const [showPending, setShowPending] = useState(false);\n const [showHidden, setShowHidden] = useState(false);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const { layout, persistenceError, togglePinned } = useWorkspaceAppLayout();\n const appsQuery = useActionQuery(\"list-workspace-apps\", {\n includeAgentCards: false,\n includeArchived: true,\n });\n const { data: apps = [], isLoading: appsLoading } = appsQuery;\n const { data: workspace } = useActionQuery(\n \"get-workspace-info\",\n {},\n { staleTime: 60_000 },\n );\n const ws = workspace as WorkspaceInfo | undefined;\n const workspaceLabel = ws?.displayName ?? ws?.name ?? null;\n const allApps = (apps as WorkspaceAppSummary[]).filter(\n isWorkspaceAppVisibleInDefaultLaunchers,\n );\n const visibleApps = allApps.filter((app) => !app.archived);\n const activeApps = visibleApps.filter((app) => app.status !== \"pending\");\n const pendingApps = visibleApps.filter((app) => app.status === \"pending\");\n const archivedApps = allApps.filter((app) => app.archived);\n const orderedActiveApps = orderWorkspaceApps(activeApps, layout);\n const orderedPendingApps = orderWorkspaceApps(pendingApps, layout);\n const orderedArchivedApps = orderWorkspaceApps(archivedApps, layout);\n const filteredActiveApps = orderedActiveApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const filteredPendingApps = orderedPendingApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const filteredArchivedApps = orderedArchivedApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const hasSearchResults =\n filteredActiveApps.length > 0 ||\n filteredPendingApps.length > 0 ||\n filteredArchivedApps.length > 0;\n const showAppSkeletons = appsLoading && allApps.length === 0;\n\n return (\n <DispatchShell\n title={t(\"dispatch.nav.apps\")}\n description={\n workspaceLabel\n ? t(\"dispatch.pages.appsDescriptionWithWorkspace\", {\n workspace: workspaceLabel,\n })\n : t(\"dispatch.pages.appsDescription\")\n }\n >\n <div className=\"space-y-8\">\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-2\">\n <IconApps\n size={16}\n className=\"mt-0.5 shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"truncate text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.yourApps\", { defaultValue: \"Your apps\" })}\n </h2>\n </div>\n </div>\n <div className=\"flex min-w-0 flex-wrap items-center justify-end gap-2\">\n {!showAppSkeletons ? (\n <WorkspaceAppSearch\n className=\"w-full sm:w-[250px]\"\n query={searchQuery}\n onQueryChange={setSearchQuery}\n />\n ) : null}\n {activeApps.length > 0 || pendingApps.length > 0 ? (\n <CreateAppPopover\n align=\"end\"\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.addApp\", {\n defaultValue: \"Add app\",\n })}\n </Button>\n }\n />\n ) : null}\n </div>\n </div>\n\n {!showAppSkeletons && allApps.length > 0 && persistenceError ? (\n <p className=\"text-xs text-muted-foreground\" role=\"status\">\n {persistenceError === \"both\"\n ? t(\"dispatch.pages.appPinSaveFailed\", {\n defaultValue: \"App pins could not be saved.\",\n })\n : t(\"dispatch.pages.appPinSavedLocally\", {\n defaultValue: \"App pins are saved on this device only.\",\n })}\n </p>\n ) : null}\n\n {appsQuery.isError ? (\n <ActionQueryError\n error={appsQuery.error}\n onRetry={() => void appsQuery.refetch()}\n />\n ) : showAppSkeletons ? (\n <AppsSkeletonGrid />\n ) : !hasSearchResults && searchQuery.trim() ? (\n <WorkspaceAppSearchEmpty\n query={searchQuery}\n onClear={() => setSearchQuery(\"\")}\n />\n ) : filteredActiveApps.length > 0 ? (\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredActiveApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n isPinned={layout.pinnedIds.includes(app.id.toLowerCase())}\n onTogglePinned={() => togglePinned(app.id)}\n />\n ))}\n </AppList>\n ) : searchQuery.trim() ? null : pendingApps.length > 0 ? (\n <EmptyActiveAppsState />\n ) : (\n <EmptyAppsState />\n )}\n </section>\n\n {pendingApps.length > 0 &&\n (!searchQuery.trim() || filteredPendingApps.length > 0) ? (\n <Collapsible\n open={showPending || Boolean(searchQuery.trim())}\n onOpenChange={setShowPending}\n >\n <section className=\"space-y-3 border-t pt-6\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconClockHour4\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.pendingApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.pendingCount\", {\n count: pendingApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showPending || Boolean(searchQuery.trim())\n ? t(\"dispatch.pages.hidePendingApps\")\n : t(\"dispatch.pages.showPendingApps\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n (showPending || Boolean(searchQuery.trim())) &&\n \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredPendingApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n\n {archivedApps.length > 0 &&\n (!searchQuery.trim() || filteredArchivedApps.length > 0) ? (\n <Collapsible\n open={showHidden || Boolean(searchQuery.trim())}\n onOpenChange={setShowHidden}\n >\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-t pt-4\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconEyeOff\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.hiddenApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.hiddenAppCount\", {\n count: archivedApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showHidden || Boolean(searchQuery.trim())\n ? t(\"dispatch.pages.hide\")\n : t(\"dispatch.pages.show\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n (showHidden || Boolean(searchQuery.trim())) &&\n \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredArchivedApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n </div>\n </DispatchShell>\n );\n}\n\nfunction AppsSkeletonGrid() {\n return (\n <AppList className={APP_LIST_GRID_CLASS}>\n {Array.from({ length: 3 }).map((_, index) => (\n <div\n key={index}\n className={cn(\n \"flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0\",\n APP_LIST_GRID_ROW_CLASS,\n )}\n >\n <Skeleton className=\"size-8 shrink-0 rounded-md\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n <Skeleton className=\"h-8 w-24 shrink-0 rounded-md\" />\n </div>\n ))}\n </AppList>\n );\n}\n\nfunction EmptyAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <div className=\"mx-auto flex size-10 items-center justify-center rounded-lg bg-muted text-muted-foreground\">\n <IconApps size={18} />\n </div>\n <h3 className=\"mt-3 text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.noWorkspaceApps\")}\n </h3>\n <p className=\"mx-auto mt-1 max-w-sm text-sm text-muted-foreground\">\n {t(\"dispatch.pages.noWorkspaceAppsDescription\")}\n </p>\n <div className=\"mt-4\">\n <CreateAppPopover\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.addApp\", { defaultValue: \"Add app\" })}\n </Button>\n }\n />\n </div>\n </div>\n );\n}\n\nfunction EmptyActiveAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <p className=\"text-sm font-medium text-foreground\">\n {t(\"dispatch.pages.noActiveWorkspaceApps\")}\n </p>\n <p className=\"mx-auto mt-1 max-w-md text-xs text-muted-foreground\">\n {t(\"dispatch.pages.noActiveWorkspaceAppsDescription\")}\n </p>\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../../src/routes/pages/apps.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionQuery } from \"@agent-native/core/client/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport {\n IconApps,\n IconChevronDown,\n IconClockHour4,\n IconEyeOff,\n IconPlus,\n} from \"@tabler/icons-react\";\nimport { useState } from \"react\";\nimport { Outlet, useParams } from \"react-router\";\n\nimport { ActionQueryError } from \"../../components/action-query-error\";\nimport {\n APP_LIST_GRID_CLASS,\n APP_LIST_GRID_ROW_CLASS,\n AppList,\n} from \"../../components/app-list-row\";\nimport { ConnectedAppCard } from \"../../components/connected-app-card\";\nimport { CreateAppPopover } from \"../../components/create-app-popover\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"../../components/ui/collapsible\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { WorkspaceAppCard } from \"../../components/workspace-app-card\";\nimport {\n WorkspaceAppSearch,\n WorkspaceAppSearchEmpty,\n} from \"../../components/workspace-app-search\";\nimport {\n filterBuiltInApps,\n type ConnectedAppSummary,\n} from \"../../lib/other-apps\";\nimport { cn } from \"../../lib/utils\";\nimport {\n orderWorkspaceApps,\n useWorkspaceAppLayout,\n workspaceAppMatchesQuery,\n} from \"../../lib/workspace-app-layout\";\nimport {\n isWorkspaceAppVisibleInDefaultLaunchers,\n type WorkspaceAppSummary,\n} from \"../../lib/workspace-apps\";\n\nexport function meta() {\n return [{ title: \"Apps — Dispatch\" }];\n}\n\ninterface WorkspaceInfo {\n name: string | null;\n displayName: string | null;\n appCount: number;\n}\n\nexport default function AppsRouteEntry() {\n const { appId } = useParams();\n return appId ? <Outlet /> : <AppsRoute />;\n}\n\nfunction AppsRoute() {\n const t = useT();\n const [showPending, setShowPending] = useState(false);\n const [showHidden, setShowHidden] = useState(false);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const { layout, persistenceError, togglePinned } = useWorkspaceAppLayout();\n const appsQuery = useActionQuery(\"list-workspace-apps\", {\n includeAgentCards: false,\n includeArchived: true,\n });\n const connectedAppsQuery = useActionQuery<ConnectedAppSummary[]>(\n \"list-connected-agents\",\n {},\n );\n const { data: apps = [], isLoading: appsLoading } = appsQuery;\n const { data: workspace } = useActionQuery(\n \"get-workspace-info\",\n {},\n { staleTime: 60_000 },\n );\n const ws = workspace as WorkspaceInfo | undefined;\n const workspaceLabel = ws?.displayName ?? ws?.name ?? null;\n const allApps = (apps as WorkspaceAppSummary[]).filter(\n isWorkspaceAppVisibleInDefaultLaunchers,\n );\n const visibleApps = allApps.filter((app) => !app.archived);\n const activeApps = visibleApps.filter((app) => app.status !== \"pending\");\n const pendingApps = visibleApps.filter((app) => app.status === \"pending\");\n const archivedApps = allApps.filter((app) => app.archived);\n const defaultApps = filterBuiltInApps(connectedAppsQuery.data ?? [], allApps);\n const orderedActiveApps = orderWorkspaceApps(activeApps, layout);\n const orderedPendingApps = orderWorkspaceApps(pendingApps, layout);\n const orderedArchivedApps = orderWorkspaceApps(archivedApps, layout);\n const filteredActiveApps = orderedActiveApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const filteredPendingApps = orderedPendingApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const filteredArchivedApps = orderedArchivedApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const filteredDefaultApps = defaultApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const hasSearchResults =\n filteredActiveApps.length > 0 ||\n filteredPendingApps.length > 0 ||\n filteredArchivedApps.length > 0 ||\n filteredDefaultApps.length > 0;\n const showAppSkeletons =\n (appsLoading || connectedAppsQuery.isLoading) &&\n allApps.length === 0 &&\n defaultApps.length === 0;\n const appDiscoveryFailed = appsQuery.isError || connectedAppsQuery.isError;\n\n return (\n <DispatchShell\n title={t(\"dispatch.nav.apps\")}\n description={\n workspaceLabel\n ? t(\"dispatch.pages.appsDescriptionWithWorkspace\", {\n workspace: workspaceLabel,\n })\n : t(\"dispatch.pages.appsDescription\")\n }\n >\n <div className=\"space-y-8\">\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-2\">\n <IconApps\n size={16}\n className=\"mt-0.5 shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"truncate text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.yourApps\", { defaultValue: \"Your apps\" })}\n </h2>\n </div>\n </div>\n <div className=\"flex min-w-0 flex-wrap items-center justify-end gap-2\">\n {!showAppSkeletons ? (\n <WorkspaceAppSearch\n className=\"w-full sm:w-[250px]\"\n query={searchQuery}\n onQueryChange={setSearchQuery}\n />\n ) : null}\n {activeApps.length > 0 ||\n pendingApps.length > 0 ||\n defaultApps.length > 0 ? (\n <CreateAppPopover\n align=\"end\"\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.addApp\", {\n defaultValue: \"Add app\",\n })}\n </Button>\n }\n />\n ) : null}\n </div>\n </div>\n\n {!showAppSkeletons && allApps.length > 0 && persistenceError ? (\n <p className=\"text-xs text-muted-foreground\" role=\"status\">\n {persistenceError === \"both\"\n ? t(\"dispatch.pages.appPinSaveFailed\", {\n defaultValue: \"App pins could not be saved.\",\n })\n : t(\"dispatch.pages.appPinSavedLocally\", {\n defaultValue: \"App pins are saved on this device only.\",\n })}\n </p>\n ) : null}\n\n {appsQuery.isError ? (\n <ActionQueryError\n error={appsQuery.error}\n onRetry={() => void appsQuery.refetch()}\n />\n ) : null}\n {connectedAppsQuery.isError ? (\n <ActionQueryError\n error={connectedAppsQuery.error}\n onRetry={() => void connectedAppsQuery.refetch()}\n />\n ) : null}\n {showAppSkeletons ? (\n <AppsSkeletonGrid />\n ) : filteredActiveApps.length > 0 ||\n filteredDefaultApps.length > 0 ? (\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredActiveApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n isPinned={layout.pinnedIds.includes(app.id.toLowerCase())}\n onTogglePinned={() => togglePinned(app.id)}\n />\n ))}\n {filteredDefaultApps.map((app) => (\n <ConnectedAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n ) : appDiscoveryFailed ? null : !hasSearchResults &&\n searchQuery.trim() ? (\n <WorkspaceAppSearchEmpty\n query={searchQuery}\n onClear={() => setSearchQuery(\"\")}\n />\n ) : searchQuery.trim() ? null : pendingApps.length > 0 ? (\n <EmptyActiveAppsState />\n ) : (\n <EmptyAppsState />\n )}\n </section>\n\n {pendingApps.length > 0 &&\n (!searchQuery.trim() || filteredPendingApps.length > 0) ? (\n <Collapsible\n open={showPending || Boolean(searchQuery.trim())}\n onOpenChange={setShowPending}\n >\n <section className=\"space-y-3 border-t pt-6\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconClockHour4\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.pendingApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.pendingCount\", {\n count: pendingApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showPending || Boolean(searchQuery.trim())\n ? t(\"dispatch.pages.hidePendingApps\")\n : t(\"dispatch.pages.showPendingApps\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n (showPending || Boolean(searchQuery.trim())) &&\n \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredPendingApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n\n {archivedApps.length > 0 &&\n (!searchQuery.trim() || filteredArchivedApps.length > 0) ? (\n <Collapsible\n open={showHidden || Boolean(searchQuery.trim())}\n onOpenChange={setShowHidden}\n >\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-t pt-4\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconEyeOff\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.hiddenApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.hiddenAppCount\", {\n count: archivedApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showHidden || Boolean(searchQuery.trim())\n ? t(\"dispatch.pages.hide\")\n : t(\"dispatch.pages.show\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n (showHidden || Boolean(searchQuery.trim())) &&\n \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredArchivedApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n </div>\n </DispatchShell>\n );\n}\n\nfunction AppsSkeletonGrid() {\n return (\n <AppList className={APP_LIST_GRID_CLASS}>\n {Array.from({ length: 3 }).map((_, index) => (\n <div\n key={index}\n className={cn(\n \"flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0\",\n APP_LIST_GRID_ROW_CLASS,\n )}\n >\n <Skeleton className=\"size-8 shrink-0 rounded-md\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n <Skeleton className=\"h-8 w-24 shrink-0 rounded-md\" />\n </div>\n ))}\n </AppList>\n );\n}\n\nfunction EmptyAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <div className=\"mx-auto flex size-10 items-center justify-center rounded-lg bg-muted text-muted-foreground\">\n <IconApps size={18} />\n </div>\n <h3 className=\"mt-3 text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.noWorkspaceApps\")}\n </h3>\n <p className=\"mx-auto mt-1 max-w-sm text-sm text-muted-foreground\">\n {t(\"dispatch.pages.noWorkspaceAppsDescription\")}\n </p>\n <div className=\"mt-4\">\n <CreateAppPopover\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.addApp\", { defaultValue: \"Add app\" })}\n </Button>\n }\n />\n </div>\n </div>\n );\n}\n\nfunction EmptyActiveAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <p className=\"text-sm font-medium text-foreground\">\n {t(\"dispatch.pages.noActiveWorkspaceApps\")}\n </p>\n <p className=\"mx-auto mt-1 max-w-md text-xs text-muted-foreground\">\n {t(\"dispatch.pages.noActiveWorkspaceAppsDescription\")}\n </p>\n </div>\n );\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/dispatch",
3
- "version": "0.40.13",
3
+ "version": "0.40.14-nightly-20261006010750",
4
4
  "description": "Dispatch — workspace control plane for agent-native apps. Vault, integrations, destinations, scheduled jobs, and cross-app delegation, shipped as a single drop-in package.",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -89,7 +89,7 @@
89
89
  "tailwind-merge": "^3.5.0",
90
90
  "vaul": "^1.1.2",
91
91
  "zod": "^4.3.6",
92
- "@agent-native/toolkit": "0.201.1"
92
+ "@agent-native/toolkit": "0.201.2-nightly-20261006010750"
93
93
  },
94
94
  "devDependencies": {
95
95
  "@react-router/dev": "^8.1.0",
@@ -103,10 +103,10 @@
103
103
  "typescript-7": "npm:typescript@^7.0.2",
104
104
  "vite": "8.1.0",
105
105
  "vitest": "^4.1.5",
106
- "@agent-native/core": "0.201.1"
106
+ "@agent-native/core": "0.201.2-nightly-20261006010750"
107
107
  },
108
108
  "peerDependencies": {
109
- "@agent-native/core": ">=0.198.6",
109
+ "@agent-native/core": "0.201.2-nightly-20261006010750",
110
110
  "react": ">=19.2.7",
111
111
  "react-dom": ">=19.2.7",
112
112
  "react-router": ">=8"
@@ -0,0 +1,100 @@
1
+ // @vitest-environment happy-dom
2
+ import React, { act } from "react";
3
+ import { createRoot, type Root } from "react-dom/client";
4
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
+
6
+ import type { ConnectedAppSummary } from "../lib/other-apps";
7
+ import { ConnectedAppCard } from "./connected-app-card";
8
+
9
+ vi.mock("./app-icon", () => ({ AppIcon: () => null }));
10
+ vi.mock("./app-open-actions", () => ({
11
+ AppOpenActions: ({ name, href }: { name: string; href: string }) =>
12
+ React.createElement(
13
+ "a",
14
+ { className: "app-open-actions__primary", href },
15
+ name,
16
+ ),
17
+ }));
18
+
19
+ const app: ConnectedAppSummary = {
20
+ id: "clips",
21
+ name: "Clips",
22
+ url: "https://clips.agent-native.com",
23
+ homeUrl: "https://clips.agent-native.com/home",
24
+ source: "builtin",
25
+ };
26
+ const navigation = vi.hoisted(() => ({
27
+ navigate: vi.fn(() => true),
28
+ shouldOpenInTopWindow: vi.fn(() => false),
29
+ }));
30
+
31
+ vi.mock("../lib/workspace-apps", async (importOriginal) => ({
32
+ ...(await importOriginal<typeof import("../lib/workspace-apps")>()),
33
+ navigateToWorkspaceApp: navigation.navigate,
34
+ shouldOpenWorkspaceAppInTopWindow: navigation.shouldOpenInTopWindow,
35
+ }));
36
+
37
+ describe("ConnectedAppCard", () => {
38
+ let container: HTMLDivElement;
39
+ let root: Root;
40
+
41
+ beforeEach(() => {
42
+ vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
43
+ navigation.navigate.mockClear();
44
+ navigation.navigate.mockReturnValue(true);
45
+ navigation.shouldOpenInTopWindow.mockReturnValue(false);
46
+ container = document.createElement("div");
47
+ document.body.appendChild(container);
48
+ root = createRoot(container);
49
+ });
50
+
51
+ afterEach(() => {
52
+ act(() => root.unmount());
53
+ container.remove();
54
+ vi.unstubAllGlobals();
55
+ });
56
+
57
+ it("keeps a native link unless the host surface needs custom navigation", async () => {
58
+ await act(async () => {
59
+ root.render(<ConnectedAppCard app={app} />);
60
+ });
61
+
62
+ const anchor = container.querySelector<HTMLAnchorElement>(
63
+ ".app-open-actions__primary",
64
+ );
65
+ expect(anchor).not.toBeNull();
66
+ expect(anchor?.getAttribute("href")).toContain(
67
+ "https://clips.agent-native.com/home",
68
+ );
69
+ });
70
+
71
+ it("opens built-in app actions through the host window on primary clicks", async () => {
72
+ navigation.shouldOpenInTopWindow.mockReturnValue(true);
73
+ await act(async () => {
74
+ root.render(<ConnectedAppCard app={app} />);
75
+ });
76
+
77
+ const anchor = container.querySelector<HTMLAnchorElement>(
78
+ ".app-open-actions__primary",
79
+ );
80
+ expect(anchor).not.toBeNull();
81
+ const click = new MouseEvent("click", { bubbles: true, cancelable: true });
82
+ anchor?.dispatchEvent(click);
83
+
84
+ expect(navigation.navigate).toHaveBeenCalledWith(anchor?.href);
85
+ expect(navigation.navigate.mock.calls[0][0]).toContain(
86
+ "https://clips.agent-native.com/home",
87
+ );
88
+ expect(click.defaultPrevented).toBe(true);
89
+
90
+ const modifiedClick = new MouseEvent("click", {
91
+ bubbles: true,
92
+ cancelable: true,
93
+ ctrlKey: true,
94
+ });
95
+ anchor?.dispatchEvent(modifiedClick);
96
+
97
+ expect(navigation.navigate).toHaveBeenCalledTimes(1);
98
+ expect(modifiedClick.defaultPrevented).toBe(false);
99
+ });
100
+ });
@@ -1,6 +1,11 @@
1
1
  import { withBuilderUtmTrackingParams } from "@agent-native/core/shared/builder-link-tracking";
2
+ import type { MouseEvent } from "react";
2
3
 
3
4
  import type { ConnectedAppSummary } from "../lib/other-apps";
5
+ import {
6
+ navigateToWorkspaceApp,
7
+ shouldOpenWorkspaceAppInTopWindow,
8
+ } from "../lib/workspace-apps";
4
9
  import { AppIcon } from "./app-icon";
5
10
  import { AppListRow } from "./app-list-row";
6
11
  import { AppOpenActions } from "./app-open-actions";
@@ -13,6 +18,31 @@ export function ConnectedAppCard({
13
18
  className?: string;
14
19
  }) {
15
20
  const launchUrl = app.homeUrl ?? app.url;
21
+ const trackedLaunchUrl = withBuilderUtmTrackingParams(launchUrl, {
22
+ campaign: "product",
23
+ content: "dispatch_app",
24
+ });
25
+ const handleActionClick = (event: MouseEvent<HTMLDivElement>) => {
26
+ if (
27
+ event.button !== 0 ||
28
+ event.metaKey ||
29
+ event.ctrlKey ||
30
+ event.shiftKey ||
31
+ event.altKey
32
+ ) {
33
+ return;
34
+ }
35
+ const anchor =
36
+ event.target instanceof Element ? event.target.closest("a") : null;
37
+ if (
38
+ !anchor ||
39
+ anchor.target === "_blank" ||
40
+ !shouldOpenWorkspaceAppInTopWindow()
41
+ ) {
42
+ return;
43
+ }
44
+ if (navigateToWorkspaceApp(anchor.href)) event.preventDefault();
45
+ };
16
46
 
17
47
  return (
18
48
  <AppListRow className={className}>
@@ -25,15 +55,14 @@ export function ConnectedAppCard({
25
55
  {app.description || app.url}
26
56
  </div>
27
57
  </div>
28
- <AppOpenActions
29
- name={app.name}
30
- href={withBuilderUtmTrackingParams(launchUrl, {
31
- campaign: "product",
32
- content: "dispatch_app",
33
- })}
34
- rel="noopener noreferrer"
35
- showNewTabOption
36
- />
58
+ <div className="flex shrink-0" onClickCapture={handleActionClick}>
59
+ <AppOpenActions
60
+ name={app.name}
61
+ href={trackedLaunchUrl}
62
+ rel="noopener noreferrer"
63
+ showNewTabOption
64
+ />
65
+ </div>
37
66
  </AppListRow>
38
67
  );
39
68
  }