@knocklabs/react-core 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 12bc993: Use SWR in `useConnectedSlackChannels` hook
8
+
9
+ `useConnectedSlackChannels` now uses [SWR](https://swr.vercel.app/) under the hood. The returned array of connections (`data`) will now update optimistically when `updateConnectedChannels` is called.
10
+
11
+ - Updated dependencies [4f76cd6]
12
+ - @knocklabs/client@0.11.3
13
+
3
14
  ## 0.3.2
4
15
 
5
16
  ### Patch Changes
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const S=require("../hooks/useSlackConnectionStatus.js"),b=require("react");require("swr/infinite");const f=require("../../core/context/KnockProvider.js");require("@knocklabs/client");require("zustand/shallow");const v=require("../../core/utils.js");require("../../i18n/context/KnockI18nProvider.js");function C(e){if(e&&typeof e=="object"&&"default"in e)return e;const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const r in e)if(r!=="default"){const n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:()=>e[r]})}}return t.default=e,Object.freeze(t)}const o=C(b),i=o.createContext(null),P=e=>{const{knockSlackChannelId:t,children:r}=e,n="tenantId"in e?e.tenantId:e.tenant,u=f.useKnockClient(),{connectionStatus:c,setConnectionStatus:l,errorLabel:a,setErrorLabel:s,actionLabel:k,setActionLabel:d}=S(u,t,n);return o.createElement(i.Provider,{key:v.slackProviderKey({knockSlackChannelId:t,tenantId:n,connectionStatus:c,errorLabel:a}),value:{connectionStatus:c,setConnectionStatus:l,errorLabel:a,setErrorLabel:s,actionLabel:k,setActionLabel:d,knockSlackChannelId:t,tenant:n,tenantId:n}},r)},K=()=>{const e=o.useContext(i);if(e===void 0)throw new Error("useKnockSlackClient must be used within a KnockSlackProvider");return e};exports.KnockSlackProvider=P;exports.useKnockSlackClient=K;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const S=require("../hooks/useSlackConnectionStatus.js"),b=require("react");require("swr/infinite");const f=require("../../core/context/KnockProvider.js");require("@knocklabs/client");require("zustand/shallow");const v=require("../../core/utils.js");require("swr");require("../../i18n/context/KnockI18nProvider.js");function C(e){if(e&&typeof e=="object"&&"default"in e)return e;const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const r in e)if(r!=="default"){const n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:()=>e[r]})}}return t.default=e,Object.freeze(t)}const o=C(b),i=o.createContext(null),P=e=>{const{knockSlackChannelId:t,children:r}=e,n="tenantId"in e?e.tenantId:e.tenant,u=f.useKnockClient(),{connectionStatus:c,setConnectionStatus:l,errorLabel:a,setErrorLabel:s,actionLabel:k,setActionLabel:d}=S(u,t,n);return o.createElement(i.Provider,{key:v.slackProviderKey({knockSlackChannelId:t,tenantId:n,connectionStatus:c,errorLabel:a}),value:{connectionStatus:c,setConnectionStatus:l,errorLabel:a,setErrorLabel:s,actionLabel:k,setActionLabel:d,knockSlackChannelId:t,tenant:n,tenantId:n}},r)},q=()=>{const e=o.useContext(i);if(e===void 0)throw new Error("useKnockSlackClient must be used within a KnockSlackProvider");return e};exports.KnockSlackProvider=P;exports.useKnockSlackClient=q;
2
2
  //# sourceMappingURL=KnockSlackProvider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"KnockSlackProvider.js","sources":["../../../../../src/modules/slack/context/KnockSlackProvider.tsx"],"sourcesContent":["import { useSlackConnectionStatus } from \"..\";\nimport * as React from \"react\";\nimport { PropsWithChildren } from \"react\";\n\nimport { slackProviderKey } from \"../../core\";\nimport { useKnockClient } from \"../../core\";\nimport { ConnectionStatus } from \"../hooks/useSlackConnectionStatus\";\n\nexport interface KnockSlackProviderState {\n knockSlackChannelId: string;\n tenantId: string;\n /**\n * @deprecated Use `tenantId` instead. This field will be removed in a future release.\n */\n tenant: string;\n connectionStatus: ConnectionStatus;\n setConnectionStatus: (connectionStatus: ConnectionStatus) => void;\n errorLabel: string | null;\n setErrorLabel: (label: string) => void;\n actionLabel: string | null;\n setActionLabel: (label: string | null) => void;\n}\n\nconst SlackProviderStateContext =\n React.createContext<KnockSlackProviderState | null>(null);\n\nexport type KnockSlackProviderProps =\n | {\n knockSlackChannelId: string;\n /**\n * @deprecated Use `tenantId` instead. This field will be removed in a future release.\n */\n tenant: string;\n }\n | {\n knockSlackChannelId: string;\n tenantId: string;\n };\n\nexport const KnockSlackProvider: React.FC<\n PropsWithChildren<KnockSlackProviderProps>\n> = (props) => {\n const { knockSlackChannelId, children } = props;\n const tenantId = \"tenantId\" in props ? props.tenantId : props.tenant;\n\n const knock = useKnockClient();\n\n const {\n connectionStatus,\n setConnectionStatus,\n errorLabel,\n setErrorLabel,\n actionLabel,\n setActionLabel,\n } = useSlackConnectionStatus(knock, knockSlackChannelId, tenantId);\n\n return (\n <SlackProviderStateContext.Provider\n key={slackProviderKey({\n knockSlackChannelId,\n tenantId,\n connectionStatus,\n errorLabel,\n })}\n value={{\n connectionStatus,\n setConnectionStatus,\n errorLabel,\n setErrorLabel,\n actionLabel,\n setActionLabel,\n knockSlackChannelId,\n // Assign the same value to both tenant and tenantId for backwards compatibility\n tenant: tenantId,\n tenantId,\n }}\n >\n {children}\n </SlackProviderStateContext.Provider>\n );\n};\n\nexport const useKnockSlackClient = (): KnockSlackProviderState => {\n const context = React.useContext(\n SlackProviderStateContext,\n ) as KnockSlackProviderState;\n if (context === undefined) {\n throw new Error(\n \"useKnockSlackClient must be used within a KnockSlackProvider\",\n );\n }\n return context as KnockSlackProviderState;\n};\n"],"names":["SlackProviderStateContext","React","createContext","KnockSlackProvider","props","knockSlackChannelId","children","tenantId","tenant","knock","useKnockClient","connectionStatus","setConnectionStatus","errorLabel","setErrorLabel","actionLabel","setActionLabel","useSlackConnectionStatus","slackProviderKey","useKnockSlackClient","context","useContext","undefined","Error"],"mappings":"usBAuBMA,EACJC,EAAMC,cAA8C,IAAI,EAe7CC,EAEEC,GAAA,CACP,KAAA,CAAEC,oBAAAA,EAAqBC,SAAAA,CAAaF,EAAAA,EACpCG,EAAW,aAAcH,EAAQA,EAAMG,SAAWH,EAAMI,OAExDC,EAAQC,EAAAA,iBAER,CACJC,iBAAAA,EACAC,oBAAAA,EACAC,WAAAA,EACAC,cAAAA,EACAC,YAAAA,EACAC,eAAAA,CACEC,EAAAA,EAAyBR,EAAOJ,EAAqBE,CAAQ,EAEjE,OACGN,EAAA,cAAAD,EAA0B,SAA1B,CACC,IAAKkB,mBAAiB,CACpBb,oBAAAA,EACAE,SAAAA,EACAI,iBAAAA,EACAE,WAAAA,CACD,CAAA,EACD,MAAO,CACLF,iBAAAA,EACAC,oBAAAA,EACAC,WAAAA,EACAC,cAAAA,EACAC,YAAAA,EACAC,eAAAA,EACAX,oBAAAA,EAEAG,OAAQD,EACRA,SAAAA,CAAAA,GAGDD,CACH,CAEJ,EAEaa,EAAsBA,IAA+B,CAC1DC,MAAAA,EAAUnB,EAAMoB,WACpBrB,CACF,EACA,GAAIoB,IAAYE,OACR,MAAA,IAAIC,MACR,8DACF,EAEKH,OAAAA,CACT"}
1
+ {"version":3,"file":"KnockSlackProvider.js","sources":["../../../../../src/modules/slack/context/KnockSlackProvider.tsx"],"sourcesContent":["import { useSlackConnectionStatus } from \"..\";\nimport * as React from \"react\";\nimport { PropsWithChildren } from \"react\";\n\nimport { slackProviderKey } from \"../../core\";\nimport { useKnockClient } from \"../../core\";\nimport { ConnectionStatus } from \"../hooks/useSlackConnectionStatus\";\n\nexport interface KnockSlackProviderState {\n knockSlackChannelId: string;\n tenantId: string;\n /**\n * @deprecated Use `tenantId` instead. This field will be removed in a future release.\n */\n tenant: string;\n connectionStatus: ConnectionStatus;\n setConnectionStatus: (connectionStatus: ConnectionStatus) => void;\n errorLabel: string | null;\n setErrorLabel: (label: string) => void;\n actionLabel: string | null;\n setActionLabel: (label: string | null) => void;\n}\n\nconst SlackProviderStateContext =\n React.createContext<KnockSlackProviderState | null>(null);\n\nexport type KnockSlackProviderProps =\n | {\n knockSlackChannelId: string;\n /**\n * @deprecated Use `tenantId` instead. This field will be removed in a future release.\n */\n tenant: string;\n }\n | {\n knockSlackChannelId: string;\n tenantId: string;\n };\n\nexport const KnockSlackProvider: React.FC<\n PropsWithChildren<KnockSlackProviderProps>\n> = (props) => {\n const { knockSlackChannelId, children } = props;\n const tenantId = \"tenantId\" in props ? props.tenantId : props.tenant;\n\n const knock = useKnockClient();\n\n const {\n connectionStatus,\n setConnectionStatus,\n errorLabel,\n setErrorLabel,\n actionLabel,\n setActionLabel,\n } = useSlackConnectionStatus(knock, knockSlackChannelId, tenantId);\n\n return (\n <SlackProviderStateContext.Provider\n key={slackProviderKey({\n knockSlackChannelId,\n tenantId,\n connectionStatus,\n errorLabel,\n })}\n value={{\n connectionStatus,\n setConnectionStatus,\n errorLabel,\n setErrorLabel,\n actionLabel,\n setActionLabel,\n knockSlackChannelId,\n // Assign the same value to both tenant and tenantId for backwards compatibility\n tenant: tenantId,\n tenantId,\n }}\n >\n {children}\n </SlackProviderStateContext.Provider>\n );\n};\n\nexport const useKnockSlackClient = (): KnockSlackProviderState => {\n const context = React.useContext(\n SlackProviderStateContext,\n ) as KnockSlackProviderState;\n if (context === undefined) {\n throw new Error(\n \"useKnockSlackClient must be used within a KnockSlackProvider\",\n );\n }\n return context as KnockSlackProviderState;\n};\n"],"names":["SlackProviderStateContext","React","createContext","KnockSlackProvider","props","knockSlackChannelId","children","tenantId","tenant","knock","useKnockClient","connectionStatus","setConnectionStatus","errorLabel","setErrorLabel","actionLabel","setActionLabel","useSlackConnectionStatus","slackProviderKey","useKnockSlackClient","context","useContext","undefined","Error"],"mappings":"stBAuBMA,EACJC,EAAMC,cAA8C,IAAI,EAe7CC,EAEEC,GAAA,CACP,KAAA,CAAEC,oBAAAA,EAAqBC,SAAAA,CAAaF,EAAAA,EACpCG,EAAW,aAAcH,EAAQA,EAAMG,SAAWH,EAAMI,OAExDC,EAAQC,EAAAA,iBAER,CACJC,iBAAAA,EACAC,oBAAAA,EACAC,WAAAA,EACAC,cAAAA,EACAC,YAAAA,EACAC,eAAAA,CACEC,EAAAA,EAAyBR,EAAOJ,EAAqBE,CAAQ,EAEjE,OACGN,EAAA,cAAAD,EAA0B,SAA1B,CACC,IAAKkB,mBAAiB,CACpBb,oBAAAA,EACAE,SAAAA,EACAI,iBAAAA,EACAE,WAAAA,CACD,CAAA,EACD,MAAO,CACLF,iBAAAA,EACAC,oBAAAA,EACAC,WAAAA,EACAC,cAAAA,EACAC,YAAAA,EACAC,eAAAA,EACAX,oBAAAA,EAEAG,OAAQD,EACRA,SAAAA,CAAAA,GAGDD,CACH,CAEJ,EAEaa,EAAsBA,IAA+B,CAC1DC,MAAAA,EAAUnB,EAAMoB,WACpBrB,CACF,EACA,GAAIoB,IAAYE,OACR,MAAA,IAAIC,MACR,8DACF,EAEKH,OAAAA,CACT"}
@@ -1,2 +1,2 @@
1
- "use strict";const K=require("../context/KnockSlackProvider.js"),e=require("react");require("../../i18n/context/KnockI18nProvider.js");const b=require("../../i18n/hooks/useTranslations.js");require("swr/infinite");const y=require("../../core/context/KnockProvider.js");require("@knocklabs/client");require("zustand/shallow");require("date-fns");function E({slackChannelsRecipientObject:{objectId:t,collection:a}}){const{t:q}=b.useTranslations(),c=y.useKnockClient(),{connectionStatus:h,knockSlackChannelId:s}=K.useKnockSlackClient(),[o,l]=e.useState(null),[r,i]=e.useState(null),[u,d]=e.useState(!1),[p,k]=e.useState(!1),C=e.useCallback(()=>{d(!0),(async()=>await c.objects.getChannelData({collection:a,objectId:t,channelId:s}))().then(n=>{var S,g;(S=n==null?void 0:n.data)!=null&&S.connections?l((g=n==null?void 0:n.data)==null?void 0:g.connections):l([]),i(null),d(!1)}).catch(()=>{l([]),i(null),d(!1)})},[a,c.objects,s,t]);return e.useEffect(()=>{h==="connected"&&!o&&!r&&!u&&C()},[o,C,u,r,h]),{data:o,updateConnectedChannels:async f=>{k(!0);try{await c.objects.setChannelData({objectId:t,collection:a,channelId:s,data:{connections:f}}),C()}catch{i(q("slackChannelSetError")||"")}k(!1)},updating:p,loading:u,error:r}}module.exports=E;
1
+ "use strict";const q=require("../context/KnockSlackProvider.js"),i=require("react");require("../../i18n/context/KnockI18nProvider.js");const g=require("../../i18n/hooks/useTranslations.js");require("swr/infinite");const E=require("../../core/context/KnockProvider.js");require("@knocklabs/client");require("zustand/shallow");require("date-fns");const _=require("swr"),D=e=>e&&typeof e=="object"&&"default"in e?e:{default:e},K=D(_),R="SLACK_CONNECTED_CHANNELS";function y({slackChannelsRecipientObject:{objectId:e,collection:a}}){const{t:l}=g.useTranslations(),c=E.useKnockClient(),{connectionStatus:d,knockSlackChannelId:s}=q.useKnockSlackClient(),[C,r]=i.useState(null),[h,o]=i.useState(!1),{data:k,mutate:p,isValidating:S,isLoading:f}=K.default(d==="connected"?[R,s,a,e]:null,async()=>c.objects.getChannelData({collection:a,objectId:e,channelId:s}).then(t=>{var n;return((n=t.data)==null?void 0:n.connections)??[]}).catch(()=>[]),{onSuccess:()=>{r(null)}});return{data:k??null,updateConnectedChannels:async t=>{o(!0);try{await p(()=>c.objects.setChannelData({objectId:e,collection:a,channelId:s,data:{connections:t}}).then(n=>{var u;return((u=n.data)==null?void 0:u.connections)??[]}),{populateCache:!0,revalidate:!1,optimisticData:t})}catch{r(l("slackChannelSetError")||"")}o(!1)},updating:h,loading:f||S,error:C}}module.exports=y;
2
2
  //# sourceMappingURL=useConnectedSlackChannels.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useConnectedSlackChannels.js","sources":["../../../../../src/modules/slack/hooks/useConnectedSlackChannels.ts"],"sourcesContent":["import { useKnockSlackClient } from \"..\";\nimport { SlackChannelConnection } from \"@knocklabs/client\";\nimport { useCallback, useEffect, useState } from \"react\";\n\nimport { RecipientObject } from \"../../..\";\nimport { useKnockClient } from \"../../core\";\nimport { useTranslations } from \"../../i18n\";\n\ntype UseConnectedSlackChannelsProps = {\n slackChannelsRecipientObject: RecipientObject;\n};\n\ntype UseConnectedSlackChannelOutput = {\n data: SlackChannelConnection[] | null;\n updateConnectedChannels: (\n connectedChannels: SlackChannelConnection[],\n ) => Promise<void>;\n loading: boolean;\n error: string | null;\n updating: boolean;\n};\n\nfunction useConnectedSlackChannels({\n slackChannelsRecipientObject: { objectId, collection },\n}: UseConnectedSlackChannelsProps): UseConnectedSlackChannelOutput {\n const { t } = useTranslations();\n const knock = useKnockClient();\n const { connectionStatus, knockSlackChannelId } = useKnockSlackClient();\n const [connectedChannels, setConnectedChannels] = useState<\n null | SlackChannelConnection[]\n >(null);\n const [error, setError] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [isUpdating, setIsUpdating] = useState(false);\n\n const fetchAndSetConnectedChannels = useCallback(() => {\n setIsLoading(true);\n const getConnectedChannels = async () =>\n await knock.objects.getChannelData({\n collection,\n objectId,\n channelId: knockSlackChannelId,\n });\n\n getConnectedChannels()\n .then((res) => {\n if (res?.data?.connections) {\n setConnectedChannels(res?.data?.connections);\n } else {\n setConnectedChannels([]);\n }\n setError(null);\n setIsLoading(false);\n })\n .catch(() => {\n setConnectedChannels([]);\n setError(null);\n setIsLoading(false);\n });\n }, [collection, knock.objects, knockSlackChannelId, objectId]);\n\n useEffect(() => {\n if (\n connectionStatus === \"connected\" &&\n !connectedChannels &&\n !error &&\n !isLoading\n ) {\n fetchAndSetConnectedChannels();\n }\n }, [\n connectedChannels,\n fetchAndSetConnectedChannels,\n isLoading,\n error,\n connectionStatus,\n ]);\n\n const updateConnectedChannels = async (\n channelsToSendToKnock: SlackChannelConnection[],\n ) => {\n setIsUpdating(true);\n try {\n await knock.objects.setChannelData({\n objectId,\n collection,\n channelId: knockSlackChannelId,\n data: { connections: channelsToSendToKnock },\n });\n fetchAndSetConnectedChannels();\n } catch (_error) {\n setError(t(\"slackChannelSetError\") || \"\");\n }\n setIsUpdating(false);\n };\n\n return {\n data: connectedChannels,\n updateConnectedChannels,\n updating: isUpdating,\n loading: isLoading,\n error,\n };\n}\n\nexport default useConnectedSlackChannels;\n"],"names":["useConnectedSlackChannels","slackChannelsRecipientObject","objectId","collection","t","useTranslations","knock","useKnockClient","connectionStatus","knockSlackChannelId","useKnockSlackClient","connectedChannels","setConnectedChannels","useState","error","setError","isLoading","setIsLoading","isUpdating","setIsUpdating","fetchAndSetConnectedChannels","useCallback","objects","getChannelData","channelId","then","res","data","connections","catch","useEffect","updateConnectedChannels","channelsToSendToKnock","setChannelData","updating","loading"],"mappings":"yVAsBA,SAASA,EAA0B,CACjCC,6BAA8B,CAAEC,SAAAA,EAAUC,WAAAA,CAAW,CACvB,EAAmC,CAC3D,KAAA,CAAEC,EAAAA,GAAMC,EAAgB,gBAAA,EACxBC,EAAQC,EAAAA,iBACR,CAAEC,iBAAAA,EAAkBC,oBAAAA,GAAwBC,EAAoB,oBAAA,EAChE,CAACC,EAAmBC,CAAoB,EAAIC,WAEhD,IAAI,EACA,CAACC,EAAOC,CAAQ,EAAIF,WAAwB,IAAI,EAChD,CAACG,EAAWC,CAAY,EAAIJ,WAAS,EAAK,EAC1C,CAACK,EAAYC,CAAa,EAAIN,WAAS,EAAK,EAE5CO,EAA+BC,EAAAA,YAAY,IAAM,CACrDJ,EAAa,EAAI,GACY,SAC3B,MAAMX,EAAMgB,QAAQC,eAAe,CACjCpB,WAAAA,EACAD,SAAAA,EACAsB,UAAWf,CAAAA,CACZ,GAEkB,EAClBgB,KAAcC,GAAA,UACTA,EAAAA,GAAAA,YAAAA,EAAKC,OAALD,MAAAA,EAAWE,YACQF,GAAAA,EAAAA,GAAAA,YAAAA,EAAKC,OAALD,YAAAA,EAAWE,WAAW,EAE3ChB,EAAqB,CAAE,CAAA,EAEzBG,EAAS,IAAI,EACbE,EAAa,EAAK,CAAA,CACnB,EACAY,MAAM,IAAM,CACXjB,EAAqB,CAAE,CAAA,EACvBG,EAAS,IAAI,EACbE,EAAa,EAAK,CAAA,CACnB,CAAA,EACF,CAACd,EAAYG,EAAMgB,QAASb,EAAqBP,CAAQ,CAAC,EAE7D4B,OAAAA,EAAAA,UAAU,IAAM,CAEZtB,IAAqB,aACrB,CAACG,GACD,CAACG,GACD,CAACE,GAE4BI,GAC/B,EACC,CACDT,EACAS,EACAJ,EACAF,EACAN,CAAgB,CACjB,EAoBM,CACLmB,KAAMhB,EACNoB,wBApB8B,MAC9BC,GACG,CACHb,EAAc,EAAI,EACd,GAAA,CACIb,MAAAA,EAAMgB,QAAQW,eAAe,CACjC/B,SAAAA,EACAC,WAAAA,EACAqB,UAAWf,EACXkB,KAAM,CAAEC,YAAaI,CAAsB,CAAA,CAC5C,EAC4BZ,SACd,CACNhB,EAAAA,EAAE,sBAAsB,GAAK,EAAE,CAC1C,CACAe,EAAc,EAAK,CAAA,EAMnBe,SAAUhB,EACViB,QAASnB,EACTF,MAAAA,CAAAA,CAEJ"}
1
+ {"version":3,"file":"useConnectedSlackChannels.js","sources":["../../../../../src/modules/slack/hooks/useConnectedSlackChannels.ts"],"sourcesContent":["import { useKnockSlackClient } from \"..\";\nimport { SlackChannelConnection } from \"@knocklabs/client\";\nimport { GenericData } from \"@knocklabs/types\";\nimport { useState } from \"react\";\nimport useSWR from \"swr\";\n\nimport { RecipientObject } from \"../../..\";\nimport { useKnockClient } from \"../../core\";\nimport { useTranslations } from \"../../i18n\";\n\nconst QUERY_KEY = \"SLACK_CONNECTED_CHANNELS\";\n\ntype UseConnectedSlackChannelsProps = {\n slackChannelsRecipientObject: RecipientObject;\n};\n\ntype UseConnectedSlackChannelsOutput = {\n data: SlackChannelConnection[] | null;\n updateConnectedChannels: (\n connectedChannels: SlackChannelConnection[],\n ) => Promise<void>;\n loading: boolean;\n error: string | null;\n updating: boolean;\n};\n\nfunction useConnectedSlackChannels({\n slackChannelsRecipientObject: { objectId, collection },\n}: UseConnectedSlackChannelsProps): UseConnectedSlackChannelsOutput {\n const { t } = useTranslations();\n const knock = useKnockClient();\n const { connectionStatus, knockSlackChannelId } = useKnockSlackClient();\n\n const [error, setError] = useState<string | null>(null);\n const [isUpdating, setIsUpdating] = useState(false);\n\n const {\n data: connectedChannels,\n mutate,\n isValidating,\n isLoading,\n } = useSWR<SlackChannelConnection[]>(\n // Only fetch when Slack is connected\n connectionStatus === \"connected\"\n ? [QUERY_KEY, knockSlackChannelId, collection, objectId]\n : null,\n async () => {\n return knock.objects\n .getChannelData({\n collection,\n objectId,\n channelId: knockSlackChannelId,\n })\n .then((res) => res.data?.connections ?? [])\n .catch(() => []);\n },\n {\n onSuccess: () => {\n setError(null);\n },\n },\n );\n\n const updateConnectedChannels = async (\n channelsToSendToKnock: SlackChannelConnection[],\n ) => {\n setIsUpdating(true);\n try {\n await mutate(\n () =>\n knock.objects\n .setChannelData({\n objectId,\n collection,\n channelId: knockSlackChannelId,\n data: { connections: channelsToSendToKnock },\n })\n .then((res) => (res as GenericData).data?.connections ?? []),\n {\n populateCache: true,\n revalidate: false,\n optimisticData: channelsToSendToKnock,\n },\n );\n } catch (_error) {\n setError(t(\"slackChannelSetError\") || \"\");\n }\n setIsUpdating(false);\n };\n\n return {\n data: connectedChannels ?? null,\n updateConnectedChannels,\n updating: isUpdating,\n loading: isLoading || isValidating,\n error,\n };\n}\n\nexport default useConnectedSlackChannels;\n"],"names":["QUERY_KEY","useConnectedSlackChannels","slackChannelsRecipientObject","objectId","collection","t","useTranslations","knock","useKnockClient","connectionStatus","knockSlackChannelId","useKnockSlackClient","error","setError","useState","isUpdating","setIsUpdating","data","connectedChannels","mutate","isValidating","isLoading","useSWR","objects","getChannelData","channelId","then","res","connections","catch","onSuccess","updateConnectedChannels","channelsToSendToKnock","setChannelData","populateCache","revalidate","optimisticData","updating","loading"],"mappings":"+aAUMA,EAAY,2BAgBlB,SAASC,EAA0B,CACjCC,6BAA8B,CAAEC,SAAAA,EAAUC,WAAAA,CAAW,CACvB,EAAoC,CAC5D,KAAA,CAAEC,EAAAA,GAAMC,EAAgB,gBAAA,EACxBC,EAAQC,EAAAA,iBACR,CAAEC,iBAAAA,EAAkBC,oBAAAA,GAAwBC,EAAoB,oBAAA,EAEhE,CAACC,EAAOC,CAAQ,EAAIC,WAAwB,IAAI,EAChD,CAACC,EAAYC,CAAa,EAAIF,WAAS,EAAK,EAE5C,CACJG,KAAMC,EACNC,OAAAA,EACAC,aAAAA,EACAC,UAAAA,CAAAA,EACEC,EAAAA,QAEFb,IAAqB,YACjB,CAACT,EAAWU,EAAqBN,EAAYD,CAAQ,EACrD,KACJ,SACSI,EAAMgB,QACVC,eAAe,CACdpB,WAAAA,EACAD,SAAAA,EACAsB,UAAWf,CACZ,CAAA,EACAgB,KAAMC,GAAAA,OAAQA,QAAAA,EAAAA,EAAIV,OAAJU,YAAAA,EAAUC,cAAe,GAAE,EACzCC,MAAM,IAAM,CAAE,CAAA,EAEnB,CACEC,UAAWA,IAAM,CACfjB,EAAS,IAAI,CACf,CACF,CAAA,EA8BK,MAAA,CACLI,KAAMC,GAAqB,KAC3Ba,wBA7B8B,MAC9BC,GACG,CACHhB,EAAc,EAAI,EACd,GAAA,CACF,MAAMG,EACJ,IACEZ,EAAMgB,QACHU,eAAe,CACd9B,SAAAA,EACAC,WAAAA,EACAqB,UAAWf,EACXO,KAAM,CAAEW,YAAaI,CAAsB,CAAA,CAC5C,EACAN,KAAMC,GAAAA,OAASA,QAAAA,EAAAA,EAAoBV,OAApBU,YAAAA,EAA0BC,cAAe,CAAA,EAAE,EAC/D,CACEM,cAAe,GACfC,WAAY,GACZC,eAAgBJ,CAAAA,CAEpB,OACe,CACN3B,EAAAA,EAAE,sBAAsB,GAAK,EAAE,CAC1C,CACAW,EAAc,EAAK,CAAA,EAMnBqB,SAAUtB,EACVuB,QAASjB,GAAaD,EACtBR,MAAAA,CAAAA,CAEJ"}
@@ -1,2 +1,2 @@
1
- "use strict";const _=require("../context/KnockSlackProvider.js"),k=require("react");require("../../i18n/context/KnockI18nProvider.js");require("swr/infinite");const S=require("../../core/context/KnockProvider.js"),d=require("@knocklabs/client");require("zustand/shallow");require("date-fns");const C="https://slack.com/oauth/v2/authorize",l=["chat:write","chat:write.public","channels:read","groups:read"];function A(s,a,o){const e=S.useKnockClient(),{setConnectionStatus:c,knockSlackChannelId:n,tenantId:r,setActionLabel:i}=_.useKnockSlackClient(),u=o&&o.length>0?Array.from(new Set(l.concat(o))):l,h=k.useCallback(async()=>{i(null),c("disconnecting");try{const t=await e.slack.revokeAccessToken({tenant:r,knockChannelId:n});c(t==="ok"?"disconnected":"error")}catch{c("error")}},[c,e.slack,r,n,i]);return{buildSlackAuthUrl:k.useCallback(()=>{const t={state:JSON.stringify({redirect_url:a,access_token_object:{object_id:r,collection:d.TENANT_OBJECT_COLLECTION},channel_id:n,public_key:e.apiKey,user_token:e.userToken}),client_id:s,scope:u.join(",")};return`${C}?${new URLSearchParams(t)}`},[a,r,n,e.apiKey,e.userToken,s,u]),disconnectFromSlack:h}}module.exports=A;
1
+ "use strict";const _=require("../context/KnockSlackProvider.js"),k=require("react");require("../../i18n/context/KnockI18nProvider.js");require("swr/infinite");const S=require("../../core/context/KnockProvider.js"),d=require("@knocklabs/client");require("zustand/shallow");require("date-fns");require("swr");const C="https://slack.com/oauth/v2/authorize",l=["chat:write","chat:write.public","channels:read","groups:read"];function A(s,a,o){const e=S.useKnockClient(),{setConnectionStatus:c,knockSlackChannelId:n,tenantId:r,setActionLabel:i}=_.useKnockSlackClient(),u=o&&o.length>0?Array.from(new Set(l.concat(o))):l,h=k.useCallback(async()=>{i(null),c("disconnecting");try{const t=await e.slack.revokeAccessToken({tenant:r,knockChannelId:n});c(t==="ok"?"disconnected":"error")}catch{c("error")}},[c,e.slack,r,n,i]);return{buildSlackAuthUrl:k.useCallback(()=>{const t={state:JSON.stringify({redirect_url:a,access_token_object:{object_id:r,collection:d.TENANT_OBJECT_COLLECTION},channel_id:n,public_key:e.apiKey,user_token:e.userToken}),client_id:s,scope:u.join(",")};return`${C}?${new URLSearchParams(t)}`},[a,r,n,e.apiKey,e.userToken,s,u]),disconnectFromSlack:h}}module.exports=A;
2
2
  //# sourceMappingURL=useSlackAuth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSlackAuth.js","sources":["../../../../../src/modules/slack/hooks/useSlackAuth.ts"],"sourcesContent":["import { useKnockSlackClient } from \"..\";\nimport { TENANT_OBJECT_COLLECTION } from \"@knocklabs/client\";\nimport { useCallback } from \"react\";\n\nimport { useKnockClient } from \"../../core\";\n\nconst SLACK_AUTHORIZE_URL = \"https://slack.com/oauth/v2/authorize\";\nconst DEFAULT_SLACK_SCOPES = [\n \"chat:write\",\n \"chat:write.public\",\n \"channels:read\",\n \"groups:read\",\n];\n\ntype UseSlackAuthOutput = {\n buildSlackAuthUrl: () => string;\n disconnectFromSlack: () => void;\n};\n\nfunction useSlackAuth(\n slackClientId: string,\n redirectUrl?: string,\n additionalScopes?: string[],\n): UseSlackAuthOutput {\n const knock = useKnockClient();\n const { setConnectionStatus, knockSlackChannelId, tenantId, setActionLabel } =\n useKnockSlackClient();\n\n const combinedScopes =\n additionalScopes && additionalScopes.length > 0\n ? Array.from(new Set(DEFAULT_SLACK_SCOPES.concat(additionalScopes)))\n : DEFAULT_SLACK_SCOPES;\n\n const disconnectFromSlack = useCallback(async () => {\n setActionLabel(null);\n setConnectionStatus(\"disconnecting\");\n try {\n const revoke = await knock.slack.revokeAccessToken({\n tenant: tenantId,\n knockChannelId: knockSlackChannelId,\n });\n\n if (revoke === \"ok\") {\n setConnectionStatus(\"disconnected\");\n } else {\n setConnectionStatus(\"error\");\n }\n } catch (_error) {\n setConnectionStatus(\"error\");\n }\n }, [\n setConnectionStatus,\n knock.slack,\n tenantId,\n knockSlackChannelId,\n setActionLabel,\n ]);\n\n const buildSlackAuthUrl = useCallback(() => {\n const rawParams = {\n state: JSON.stringify({\n redirect_url: redirectUrl,\n access_token_object: {\n object_id: tenantId,\n collection: TENANT_OBJECT_COLLECTION,\n },\n channel_id: knockSlackChannelId,\n public_key: knock.apiKey,\n user_token: knock.userToken,\n }),\n client_id: slackClientId,\n scope: combinedScopes.join(\",\"),\n };\n return `${SLACK_AUTHORIZE_URL}?${new URLSearchParams(rawParams)}`;\n }, [\n redirectUrl,\n tenantId,\n knockSlackChannelId,\n knock.apiKey,\n knock.userToken,\n slackClientId,\n combinedScopes,\n ]);\n\n return {\n buildSlackAuthUrl,\n disconnectFromSlack,\n };\n}\n\nexport default useSlackAuth;\n"],"names":["SLACK_AUTHORIZE_URL","DEFAULT_SLACK_SCOPES","useSlackAuth","slackClientId","redirectUrl","additionalScopes","knock","useKnockClient","setConnectionStatus","knockSlackChannelId","tenantId","setActionLabel","useKnockSlackClient","combinedScopes","length","Array","from","Set","concat","disconnectFromSlack","useCallback","revoke","slack","revokeAccessToken","tenant","knockChannelId","buildSlackAuthUrl","rawParams","state","JSON","stringify","redirect_url","access_token_object","object_id","collection","TENANT_OBJECT_COLLECTION","channel_id","public_key","apiKey","user_token","userToken","client_id","scope","join","URLSearchParams"],"mappings":"oSAMA,MAAMA,EAAsB,uCACtBC,EAAuB,CAC3B,aACA,oBACA,gBACA,aAAa,EAQf,SAASC,EACPC,EACAC,EACAC,EACoB,CACpB,MAAMC,EAAQC,EAAAA,iBACR,CAAEC,oBAAAA,EAAqBC,oBAAAA,EAAqBC,SAAAA,EAAUC,eAAAA,GAC1DC,EAAoB,oBAAA,EAEhBC,EACJR,GAAoBA,EAAiBS,OAAS,EAC1CC,MAAMC,KAAK,IAAIC,IAAIhB,EAAqBiB,OAAOb,CAAgB,CAAC,CAAC,EACjEJ,EAEAkB,EAAsBC,EAAAA,YAAY,SAAY,CAClDT,EAAe,IAAI,EACnBH,EAAoB,eAAe,EAC/B,GAAA,CACF,MAAMa,EAAS,MAAMf,EAAMgB,MAAMC,kBAAkB,CACjDC,OAAQd,EACRe,eAAgBhB,CAAAA,CACjB,EAGCD,EADEa,IAAW,KACO,eAEA,OAFc,OAIrB,CACfb,EAAoB,OAAO,CAC7B,CAAA,EACC,CACDA,EACAF,EAAMgB,MACNZ,EACAD,EACAE,CAAc,CACf,EA4BM,MAAA,CACLe,kBA3BwBN,EAAAA,YAAY,IAAM,CAC1C,MAAMO,EAAY,CAChBC,MAAOC,KAAKC,UAAU,CACpBC,aAAc3B,EACd4B,oBAAqB,CACnBC,UAAWvB,EACXwB,WAAYC,EAAAA,wBACd,EACAC,WAAY3B,EACZ4B,WAAY/B,EAAMgC,OAClBC,WAAYjC,EAAMkC,SAAAA,CACnB,EACDC,UAAWtC,EACXuC,MAAO7B,EAAe8B,KAAK,GAAG,CAAA,EAEhC,MAAO,GAAG3C,CAAmB,IAAI,IAAI4C,gBAAgBjB,CAAS,CAAC,EACjE,EAAG,CACDvB,EACAM,EACAD,EACAH,EAAMgC,OACNhC,EAAMkC,UACNrC,EACAU,CAAc,CACf,EAICM,oBAAAA,CAAAA,CAEJ"}
1
+ {"version":3,"file":"useSlackAuth.js","sources":["../../../../../src/modules/slack/hooks/useSlackAuth.ts"],"sourcesContent":["import { useKnockSlackClient } from \"..\";\nimport { TENANT_OBJECT_COLLECTION } from \"@knocklabs/client\";\nimport { useCallback } from \"react\";\n\nimport { useKnockClient } from \"../../core\";\n\nconst SLACK_AUTHORIZE_URL = \"https://slack.com/oauth/v2/authorize\";\nconst DEFAULT_SLACK_SCOPES = [\n \"chat:write\",\n \"chat:write.public\",\n \"channels:read\",\n \"groups:read\",\n];\n\ntype UseSlackAuthOutput = {\n buildSlackAuthUrl: () => string;\n disconnectFromSlack: () => void;\n};\n\nfunction useSlackAuth(\n slackClientId: string,\n redirectUrl?: string,\n additionalScopes?: string[],\n): UseSlackAuthOutput {\n const knock = useKnockClient();\n const { setConnectionStatus, knockSlackChannelId, tenantId, setActionLabel } =\n useKnockSlackClient();\n\n const combinedScopes =\n additionalScopes && additionalScopes.length > 0\n ? Array.from(new Set(DEFAULT_SLACK_SCOPES.concat(additionalScopes)))\n : DEFAULT_SLACK_SCOPES;\n\n const disconnectFromSlack = useCallback(async () => {\n setActionLabel(null);\n setConnectionStatus(\"disconnecting\");\n try {\n const revoke = await knock.slack.revokeAccessToken({\n tenant: tenantId,\n knockChannelId: knockSlackChannelId,\n });\n\n if (revoke === \"ok\") {\n setConnectionStatus(\"disconnected\");\n } else {\n setConnectionStatus(\"error\");\n }\n } catch (_error) {\n setConnectionStatus(\"error\");\n }\n }, [\n setConnectionStatus,\n knock.slack,\n tenantId,\n knockSlackChannelId,\n setActionLabel,\n ]);\n\n const buildSlackAuthUrl = useCallback(() => {\n const rawParams = {\n state: JSON.stringify({\n redirect_url: redirectUrl,\n access_token_object: {\n object_id: tenantId,\n collection: TENANT_OBJECT_COLLECTION,\n },\n channel_id: knockSlackChannelId,\n public_key: knock.apiKey,\n user_token: knock.userToken,\n }),\n client_id: slackClientId,\n scope: combinedScopes.join(\",\"),\n };\n return `${SLACK_AUTHORIZE_URL}?${new URLSearchParams(rawParams)}`;\n }, [\n redirectUrl,\n tenantId,\n knockSlackChannelId,\n knock.apiKey,\n knock.userToken,\n slackClientId,\n combinedScopes,\n ]);\n\n return {\n buildSlackAuthUrl,\n disconnectFromSlack,\n };\n}\n\nexport default useSlackAuth;\n"],"names":["SLACK_AUTHORIZE_URL","DEFAULT_SLACK_SCOPES","useSlackAuth","slackClientId","redirectUrl","additionalScopes","knock","useKnockClient","setConnectionStatus","knockSlackChannelId","tenantId","setActionLabel","useKnockSlackClient","combinedScopes","length","Array","from","Set","concat","disconnectFromSlack","useCallback","revoke","slack","revokeAccessToken","tenant","knockChannelId","buildSlackAuthUrl","rawParams","state","JSON","stringify","redirect_url","access_token_object","object_id","collection","TENANT_OBJECT_COLLECTION","channel_id","public_key","apiKey","user_token","userToken","client_id","scope","join","URLSearchParams"],"mappings":"mTAMA,MAAMA,EAAsB,uCACtBC,EAAuB,CAC3B,aACA,oBACA,gBACA,aAAa,EAQf,SAASC,EACPC,EACAC,EACAC,EACoB,CACpB,MAAMC,EAAQC,EAAAA,iBACR,CAAEC,oBAAAA,EAAqBC,oBAAAA,EAAqBC,SAAAA,EAAUC,eAAAA,GAC1DC,EAAoB,oBAAA,EAEhBC,EACJR,GAAoBA,EAAiBS,OAAS,EAC1CC,MAAMC,KAAK,IAAIC,IAAIhB,EAAqBiB,OAAOb,CAAgB,CAAC,CAAC,EACjEJ,EAEAkB,EAAsBC,EAAAA,YAAY,SAAY,CAClDT,EAAe,IAAI,EACnBH,EAAoB,eAAe,EAC/B,GAAA,CACF,MAAMa,EAAS,MAAMf,EAAMgB,MAAMC,kBAAkB,CACjDC,OAAQd,EACRe,eAAgBhB,CAAAA,CACjB,EAGCD,EADEa,IAAW,KACO,eAEA,OAFc,OAIrB,CACfb,EAAoB,OAAO,CAC7B,CAAA,EACC,CACDA,EACAF,EAAMgB,MACNZ,EACAD,EACAE,CAAc,CACf,EA4BM,MAAA,CACLe,kBA3BwBN,EAAAA,YAAY,IAAM,CAC1C,MAAMO,EAAY,CAChBC,MAAOC,KAAKC,UAAU,CACpBC,aAAc3B,EACd4B,oBAAqB,CACnBC,UAAWvB,EACXwB,WAAYC,EAAAA,wBACd,EACAC,WAAY3B,EACZ4B,WAAY/B,EAAMgC,OAClBC,WAAYjC,EAAMkC,SAAAA,CACnB,EACDC,UAAWtC,EACXuC,MAAO7B,EAAe8B,KAAK,GAAG,CAAA,EAEhC,MAAO,GAAG3C,CAAmB,IAAI,IAAI4C,gBAAgBjB,CAAS,CAAC,EACjE,EAAG,CACDvB,EACAM,EACAD,EACAH,EAAMgC,OACNhC,EAAMkC,UACNrC,EACAU,CAAc,CACf,EAICM,oBAAAA,CAAAA,CAEJ"}
@@ -1,2 +1,2 @@
1
- "use strict";const P=require("../context/KnockSlackProvider.js"),d=require("react");require("../../i18n/context/KnockI18nProvider.js");const K=require("swr/infinite"),L=require("../../core/context/KnockProvider.js");require("@knocklabs/client");require("zustand/shallow");require("date-fns");const N=n=>n&&typeof n=="object"&&"default"in n?n:{default:n},g=N(K),A=1e3,R=200,M="private_channel,public_channel",S="SLACK_CHANNELS";function z(n,c){return n===0?[S,""]:c&&["",null].includes(c.next_cursor)?null:[S,c.next_cursor??""]}function T({queryOptions:n}){var h,C;const c=L.useKnockClient(),{knockSlackChannelId:x,tenantId:E,connectionStatus:a}=P.useKnockSlackClient(),m=t=>c.slack.getChannels({tenant:E,knockChannelId:x,queryOptions:{...n,cursor:t?t[1]:"",limit:(n==null?void 0:n.limitPerPage)||R,types:(n==null?void 0:n.types)||M}}),{data:e,error:i,isLoading:l,isValidating:r,size:u,setSize:f,mutate:I}=g.default(z,m,{initialSize:0}),s=(e==null?void 0:e.length)||0,k=s===0||e&&((h=e[s])==null?void 0:h.next_cursor)&&((C=e[s])==null?void 0:C.next_cursor)!=="",o=d.useMemo(()=>(e??[]).flatMap(t=>t==null?void 0:t.slack_channels).filter(t=>!!t),[e]),_=(n==null?void 0:n.maxCount)||A;return d.useEffect(()=>{a==="connected"&&!i&&k&&!l&&!r&&o.length<_&&f(u+1)},[o.length,f,u,k,l,r,_,i,a]),{data:o,isLoading:l||r,refetch:()=>I()}}module.exports=T;
1
+ "use strict";const P=require("../context/KnockSlackProvider.js"),d=require("react");require("../../i18n/context/KnockI18nProvider.js");const K=require("swr/infinite"),L=require("../../core/context/KnockProvider.js");require("@knocklabs/client");require("zustand/shallow");require("date-fns");require("swr");const N=n=>n&&typeof n=="object"&&"default"in n?n:{default:n},g=N(K),A=1e3,R=200,M="private_channel,public_channel",S="SLACK_CHANNELS";function z(n,c){return n===0?[S,""]:c&&["",null].includes(c.next_cursor)?null:[S,c.next_cursor??""]}function T({queryOptions:n}){var h,C;const c=L.useKnockClient(),{knockSlackChannelId:x,tenantId:E,connectionStatus:a}=P.useKnockSlackClient(),m=t=>c.slack.getChannels({tenant:E,knockChannelId:x,queryOptions:{...n,cursor:t?t[1]:"",limit:(n==null?void 0:n.limitPerPage)||R,types:(n==null?void 0:n.types)||M}}),{data:e,error:i,isLoading:l,isValidating:r,size:u,setSize:f,mutate:I}=g.default(z,m,{initialSize:0}),s=(e==null?void 0:e.length)||0,k=s===0||e&&((h=e[s])==null?void 0:h.next_cursor)&&((C=e[s])==null?void 0:C.next_cursor)!=="",o=d.useMemo(()=>(e??[]).flatMap(t=>t==null?void 0:t.slack_channels).filter(t=>!!t),[e]),_=(n==null?void 0:n.maxCount)||A;return d.useEffect(()=>{a==="connected"&&!i&&k&&!l&&!r&&o.length<_&&f(u+1)},[o.length,f,u,k,l,r,_,i,a]),{data:o,isLoading:l||r,refetch:()=>I()}}module.exports=T;
2
2
  //# sourceMappingURL=useSlackChannels.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSlackChannels.js","sources":["../../../../../src/modules/slack/hooks/useSlackChannels.ts"],"sourcesContent":["import { SlackChannelQueryOptions, useKnockSlackClient } from \"..\";\nimport { GetSlackChannelsResponse, SlackChannel } from \"@knocklabs/client\";\nimport { useEffect, useMemo } from \"react\";\nimport useSWRInfinite from \"swr/infinite\";\n\nimport { useKnockClient } from \"../../core\";\n\nconst MAX_COUNT = 1000;\nconst LIMIT_PER_PAGE = 200;\nconst CHANNEL_TYPES = \"private_channel,public_channel\";\n\nconst QUERY_KEY = \"SLACK_CHANNELS\";\n\ntype UseSlackChannelsProps = {\n queryOptions?: SlackChannelQueryOptions;\n};\n\ntype UseSlackChannelOutput = {\n data: SlackChannel[];\n isLoading: boolean;\n refetch: () => void;\n};\n\ntype QueryKey = [key: string, cursor: string] | null;\n\nfunction getQueryKey(\n pageIndex: number,\n previousPageData: GetSlackChannelsResponse,\n): QueryKey {\n // First page so just pass empty\n if (pageIndex === 0) {\n return [QUERY_KEY, \"\"];\n }\n\n // If there's no more data then return an empty next cursor\n if (previousPageData && [\"\", null].includes(previousPageData.next_cursor)) {\n return null;\n }\n\n // Next cursor exists so pass it\n return [QUERY_KEY, previousPageData.next_cursor ?? \"\"];\n}\n\nfunction useSlackChannels({\n queryOptions,\n}: UseSlackChannelsProps): UseSlackChannelOutput {\n const knock = useKnockClient();\n const { knockSlackChannelId, tenantId, connectionStatus } =\n useKnockSlackClient();\n\n const fetchChannels = (queryKey: QueryKey) => {\n return knock.slack.getChannels({\n tenant: tenantId,\n knockChannelId: knockSlackChannelId,\n queryOptions: {\n ...queryOptions,\n cursor: queryKey ? queryKey[1] : \"\",\n limit: queryOptions?.limitPerPage || LIMIT_PER_PAGE,\n types: queryOptions?.types || CHANNEL_TYPES,\n },\n });\n };\n\n const { data, error, isLoading, isValidating, size, setSize, mutate } =\n useSWRInfinite<GetSlackChannelsResponse>(getQueryKey, fetchChannels, {\n initialSize: 0,\n });\n\n const currentPage = data?.length || 0;\n\n const hasNextPage =\n currentPage === 0 ||\n (data &&\n data[currentPage]?.next_cursor &&\n data[currentPage]?.next_cursor !== \"\");\n\n const slackChannels: SlackChannel[] = useMemo(\n () =>\n (data ?? [])\n .flatMap((page) => page?.slack_channels)\n .filter((channel) => !!channel),\n [data],\n );\n\n const maxCount = queryOptions?.maxCount || MAX_COUNT;\n\n useEffect(() => {\n if (\n connectionStatus === \"connected\" &&\n !error &&\n hasNextPage &&\n !isLoading &&\n !isValidating &&\n slackChannels.length < maxCount\n ) {\n // Fetch a page at a time until we have nothing else left to fetch\n // or we've already hit the max amount of channels to fetch\n setSize(size + 1);\n }\n }, [\n slackChannels.length,\n setSize,\n size,\n hasNextPage,\n isLoading,\n isValidating,\n maxCount,\n error,\n connectionStatus,\n ]);\n\n return {\n data: slackChannels,\n isLoading: isLoading || isValidating,\n refetch: () => mutate(),\n };\n}\n\nexport default useSlackChannels;\n"],"names":["MAX_COUNT","LIMIT_PER_PAGE","CHANNEL_TYPES","QUERY_KEY","getQueryKey","pageIndex","previousPageData","includes","next_cursor","useSlackChannels","queryOptions","knock","useKnockClient","knockSlackChannelId","tenantId","connectionStatus","useKnockSlackClient","fetchChannels","queryKey","slack","getChannels","tenant","knockChannelId","cursor","limit","limitPerPage","types","data","error","isLoading","isValidating","size","setSize","mutate","useSWRInfinite","initialSize","currentPage","length","hasNextPage","slackChannels","useMemo","flatMap","page","slack_channels","filter","channel","maxCount","useEffect","refetch"],"mappings":"yWAOMA,EAAY,IACZC,EAAiB,IACjBC,EAAgB,iCAEhBC,EAAY,iBAclB,SAASC,EACPC,EACAC,EACU,CAEV,OAAID,IAAc,EACT,CAACF,EAAW,EAAE,EAInBG,GAAoB,CAAC,GAAI,IAAI,EAAEC,SAASD,EAAiBE,WAAW,EAC/D,KAIF,CAACL,EAAWG,EAAiBE,aAAe,EAAE,CACvD,CAEA,SAASC,EAAiB,CACxBC,aAAAA,CACqB,EAA0B,SAC/C,MAAMC,EAAQC,EAAAA,iBACR,CAAEC,oBAAAA,EAAqBC,SAAAA,EAAUC,iBAAAA,GACrCC,EAAoB,oBAAA,EAEhBC,EAAiBC,GACdP,EAAMQ,MAAMC,YAAY,CAC7BC,OAAQP,EACRQ,eAAgBT,EAChBH,aAAc,CACZ,GAAGA,EACHa,OAAQL,EAAWA,EAAS,CAAC,EAAI,GACjCM,OAAOd,GAAAA,YAAAA,EAAce,eAAgBxB,EACrCyB,OAAOhB,GAAAA,YAAAA,EAAcgB,QAASxB,CAChC,CAAA,CACD,EAGG,CAAEyB,KAAAA,EAAMC,MAAAA,EAAOC,UAAAA,EAAWC,aAAAA,EAAcC,KAAAA,EAAMC,QAAAA,EAASC,OAAAA,CAAAA,EAC3DC,EAAyC9B,QAAAA,EAAaa,EAAe,CACnEkB,YAAa,CAAA,CACd,EAEGC,GAAcT,GAAAA,YAAAA,EAAMU,SAAU,EAE9BC,EACJF,IAAgB,GACfT,KACCA,EAAAA,EAAKS,CAAW,IAAhBT,YAAAA,EAAmBnB,gBACnBmB,EAAAA,EAAKS,CAAW,IAAhBT,YAAAA,EAAmBnB,eAAgB,GAEjC+B,EAAgCC,EAAAA,QACpC,KACGb,GAAQ,IACNc,QAAkBC,GAAAA,GAAAA,YAAAA,EAAMC,cAAc,EACtCC,UAAoB,CAAC,CAACC,CAAO,EAClC,CAAClB,CAAI,CACP,EAEMmB,GAAWpC,GAAAA,YAAAA,EAAcoC,WAAY9C,EAE3C+C,OAAAA,EAAAA,UAAU,IAAM,CAEZhC,IAAqB,aACrB,CAACa,GACDU,GACA,CAACT,GACD,CAACC,GACDS,EAAcF,OAASS,GAIvBd,EAAQD,EAAO,CAAC,CAEjB,EAAA,CACDQ,EAAcF,OACdL,EACAD,EACAO,EACAT,EACAC,EACAgB,EACAlB,EACAb,CAAgB,CACjB,EAEM,CACLY,KAAMY,EACNV,UAAWA,GAAaC,EACxBkB,QAASA,IAAMf,EAAO,CAAA,CAE1B"}
1
+ {"version":3,"file":"useSlackChannels.js","sources":["../../../../../src/modules/slack/hooks/useSlackChannels.ts"],"sourcesContent":["import { SlackChannelQueryOptions, useKnockSlackClient } from \"..\";\nimport { GetSlackChannelsResponse, SlackChannel } from \"@knocklabs/client\";\nimport { useEffect, useMemo } from \"react\";\nimport useSWRInfinite from \"swr/infinite\";\n\nimport { useKnockClient } from \"../../core\";\n\nconst MAX_COUNT = 1000;\nconst LIMIT_PER_PAGE = 200;\nconst CHANNEL_TYPES = \"private_channel,public_channel\";\n\nconst QUERY_KEY = \"SLACK_CHANNELS\";\n\ntype UseSlackChannelsProps = {\n queryOptions?: SlackChannelQueryOptions;\n};\n\ntype UseSlackChannelOutput = {\n data: SlackChannel[];\n isLoading: boolean;\n refetch: () => void;\n};\n\ntype QueryKey = [key: string, cursor: string] | null;\n\nfunction getQueryKey(\n pageIndex: number,\n previousPageData: GetSlackChannelsResponse,\n): QueryKey {\n // First page so just pass empty\n if (pageIndex === 0) {\n return [QUERY_KEY, \"\"];\n }\n\n // If there's no more data then return an empty next cursor\n if (previousPageData && [\"\", null].includes(previousPageData.next_cursor)) {\n return null;\n }\n\n // Next cursor exists so pass it\n return [QUERY_KEY, previousPageData.next_cursor ?? \"\"];\n}\n\nfunction useSlackChannels({\n queryOptions,\n}: UseSlackChannelsProps): UseSlackChannelOutput {\n const knock = useKnockClient();\n const { knockSlackChannelId, tenantId, connectionStatus } =\n useKnockSlackClient();\n\n const fetchChannels = (queryKey: QueryKey) => {\n return knock.slack.getChannels({\n tenant: tenantId,\n knockChannelId: knockSlackChannelId,\n queryOptions: {\n ...queryOptions,\n cursor: queryKey ? queryKey[1] : \"\",\n limit: queryOptions?.limitPerPage || LIMIT_PER_PAGE,\n types: queryOptions?.types || CHANNEL_TYPES,\n },\n });\n };\n\n const { data, error, isLoading, isValidating, size, setSize, mutate } =\n useSWRInfinite<GetSlackChannelsResponse>(getQueryKey, fetchChannels, {\n initialSize: 0,\n });\n\n const currentPage = data?.length || 0;\n\n const hasNextPage =\n currentPage === 0 ||\n (data &&\n data[currentPage]?.next_cursor &&\n data[currentPage]?.next_cursor !== \"\");\n\n const slackChannels: SlackChannel[] = useMemo(\n () =>\n (data ?? [])\n .flatMap((page) => page?.slack_channels)\n .filter((channel) => !!channel),\n [data],\n );\n\n const maxCount = queryOptions?.maxCount || MAX_COUNT;\n\n useEffect(() => {\n if (\n connectionStatus === \"connected\" &&\n !error &&\n hasNextPage &&\n !isLoading &&\n !isValidating &&\n slackChannels.length < maxCount\n ) {\n // Fetch a page at a time until we have nothing else left to fetch\n // or we've already hit the max amount of channels to fetch\n setSize(size + 1);\n }\n }, [\n slackChannels.length,\n setSize,\n size,\n hasNextPage,\n isLoading,\n isValidating,\n maxCount,\n error,\n connectionStatus,\n ]);\n\n return {\n data: slackChannels,\n isLoading: isLoading || isValidating,\n refetch: () => mutate(),\n };\n}\n\nexport default useSlackChannels;\n"],"names":["MAX_COUNT","LIMIT_PER_PAGE","CHANNEL_TYPES","QUERY_KEY","getQueryKey","pageIndex","previousPageData","includes","next_cursor","useSlackChannels","queryOptions","knock","useKnockClient","knockSlackChannelId","tenantId","connectionStatus","useKnockSlackClient","fetchChannels","queryKey","slack","getChannels","tenant","knockChannelId","cursor","limit","limitPerPage","types","data","error","isLoading","isValidating","size","setSize","mutate","useSWRInfinite","initialSize","currentPage","length","hasNextPage","slackChannels","useMemo","flatMap","page","slack_channels","filter","channel","maxCount","useEffect","refetch"],"mappings":"wXAOMA,EAAY,IACZC,EAAiB,IACjBC,EAAgB,iCAEhBC,EAAY,iBAclB,SAASC,EACPC,EACAC,EACU,CAEV,OAAID,IAAc,EACT,CAACF,EAAW,EAAE,EAInBG,GAAoB,CAAC,GAAI,IAAI,EAAEC,SAASD,EAAiBE,WAAW,EAC/D,KAIF,CAACL,EAAWG,EAAiBE,aAAe,EAAE,CACvD,CAEA,SAASC,EAAiB,CACxBC,aAAAA,CACqB,EAA0B,SAC/C,MAAMC,EAAQC,EAAAA,iBACR,CAAEC,oBAAAA,EAAqBC,SAAAA,EAAUC,iBAAAA,GACrCC,EAAoB,oBAAA,EAEhBC,EAAiBC,GACdP,EAAMQ,MAAMC,YAAY,CAC7BC,OAAQP,EACRQ,eAAgBT,EAChBH,aAAc,CACZ,GAAGA,EACHa,OAAQL,EAAWA,EAAS,CAAC,EAAI,GACjCM,OAAOd,GAAAA,YAAAA,EAAce,eAAgBxB,EACrCyB,OAAOhB,GAAAA,YAAAA,EAAcgB,QAASxB,CAChC,CAAA,CACD,EAGG,CAAEyB,KAAAA,EAAMC,MAAAA,EAAOC,UAAAA,EAAWC,aAAAA,EAAcC,KAAAA,EAAMC,QAAAA,EAASC,OAAAA,CAAAA,EAC3DC,EAAyC9B,QAAAA,EAAaa,EAAe,CACnEkB,YAAa,CAAA,CACd,EAEGC,GAAcT,GAAAA,YAAAA,EAAMU,SAAU,EAE9BC,EACJF,IAAgB,GACfT,KACCA,EAAAA,EAAKS,CAAW,IAAhBT,YAAAA,EAAmBnB,gBACnBmB,EAAAA,EAAKS,CAAW,IAAhBT,YAAAA,EAAmBnB,eAAgB,GAEjC+B,EAAgCC,EAAAA,QACpC,KACGb,GAAQ,IACNc,QAAkBC,GAAAA,GAAAA,YAAAA,EAAMC,cAAc,EACtCC,UAAoB,CAAC,CAACC,CAAO,EAClC,CAAClB,CAAI,CACP,EAEMmB,GAAWpC,GAAAA,YAAAA,EAAcoC,WAAY9C,EAE3C+C,OAAAA,EAAAA,UAAU,IAAM,CAEZhC,IAAqB,aACrB,CAACa,GACDU,GACA,CAACT,GACD,CAACC,GACDS,EAAcF,OAASS,GAIvBd,EAAQD,EAAO,CAAC,CAEjB,EAAA,CACDQ,EAAcF,OACdL,EACAD,EACAO,EACAT,EACAC,EACAgB,EACAlB,EACAb,CAAgB,CACjB,EAEM,CACLY,KAAMY,EACNV,UAAWA,GAAaC,EACxBkB,QAASA,IAAMf,EAAO,CAAA,CAE1B"}
@@ -5,6 +5,7 @@ import { useKnockClient as S } from "../../core/context/KnockProvider.mjs";
5
5
  import "@knocklabs/client";
6
6
  import "zustand/shallow";
7
7
  import { slackProviderKey as C } from "../../core/utils.mjs";
8
+ import "swr";
8
9
  import "../../i18n/context/KnockI18nProvider.mjs";
9
10
  const a = o.createContext(null), I = (t) => {
10
11
  const {
@@ -1 +1 @@
1
- {"version":3,"file":"KnockSlackProvider.mjs","sources":["../../../../../src/modules/slack/context/KnockSlackProvider.tsx"],"sourcesContent":["import { useSlackConnectionStatus } from \"..\";\nimport * as React from \"react\";\nimport { PropsWithChildren } from \"react\";\n\nimport { slackProviderKey } from \"../../core\";\nimport { useKnockClient } from \"../../core\";\nimport { ConnectionStatus } from \"../hooks/useSlackConnectionStatus\";\n\nexport interface KnockSlackProviderState {\n knockSlackChannelId: string;\n tenantId: string;\n /**\n * @deprecated Use `tenantId` instead. This field will be removed in a future release.\n */\n tenant: string;\n connectionStatus: ConnectionStatus;\n setConnectionStatus: (connectionStatus: ConnectionStatus) => void;\n errorLabel: string | null;\n setErrorLabel: (label: string) => void;\n actionLabel: string | null;\n setActionLabel: (label: string | null) => void;\n}\n\nconst SlackProviderStateContext =\n React.createContext<KnockSlackProviderState | null>(null);\n\nexport type KnockSlackProviderProps =\n | {\n knockSlackChannelId: string;\n /**\n * @deprecated Use `tenantId` instead. This field will be removed in a future release.\n */\n tenant: string;\n }\n | {\n knockSlackChannelId: string;\n tenantId: string;\n };\n\nexport const KnockSlackProvider: React.FC<\n PropsWithChildren<KnockSlackProviderProps>\n> = (props) => {\n const { knockSlackChannelId, children } = props;\n const tenantId = \"tenantId\" in props ? props.tenantId : props.tenant;\n\n const knock = useKnockClient();\n\n const {\n connectionStatus,\n setConnectionStatus,\n errorLabel,\n setErrorLabel,\n actionLabel,\n setActionLabel,\n } = useSlackConnectionStatus(knock, knockSlackChannelId, tenantId);\n\n return (\n <SlackProviderStateContext.Provider\n key={slackProviderKey({\n knockSlackChannelId,\n tenantId,\n connectionStatus,\n errorLabel,\n })}\n value={{\n connectionStatus,\n setConnectionStatus,\n errorLabel,\n setErrorLabel,\n actionLabel,\n setActionLabel,\n knockSlackChannelId,\n // Assign the same value to both tenant and tenantId for backwards compatibility\n tenant: tenantId,\n tenantId,\n }}\n >\n {children}\n </SlackProviderStateContext.Provider>\n );\n};\n\nexport const useKnockSlackClient = (): KnockSlackProviderState => {\n const context = React.useContext(\n SlackProviderStateContext,\n ) as KnockSlackProviderState;\n if (context === undefined) {\n throw new Error(\n \"useKnockSlackClient must be used within a KnockSlackProvider\",\n );\n }\n return context as KnockSlackProviderState;\n};\n"],"names":["SlackProviderStateContext","React","createContext","KnockSlackProvider","props","knockSlackChannelId","children","tenantId","tenant","knock","useKnockClient","connectionStatus","setConnectionStatus","errorLabel","setErrorLabel","actionLabel","setActionLabel","useSlackConnectionStatus","slackProviderKey","useKnockSlackClient","context","useContext","undefined","Error"],"mappings":";;;;;;;;AAuBA,MAAMA,IACJC,EAAMC,cAA8C,IAAI,GAe7CC,IAERC,CAAUA,MAAA;AACP,QAAA;AAAA,IAAEC,qBAAAA;AAAAA,IAAqBC,UAAAA;AAAAA,EAAaF,IAAAA,GACpCG,IAAW,cAAcH,IAAQA,EAAMG,WAAWH,EAAMI,QAExDC,IAAQC,KAER;AAAA,IACJC,kBAAAA;AAAAA,IACAC,qBAAAA;AAAAA,IACAC,YAAAA;AAAAA,IACAC,eAAAA;AAAAA,IACAC,aAAAA;AAAAA,IACAC,gBAAAA;AAAAA,EACEC,IAAAA,EAAyBR,GAAOJ,GAAqBE,CAAQ;AAEjE,SACG,gBAAAN,EAAA,cAAAD,EAA0B,UAA1B,EACC,KAAKkB,EAAiB;AAAA,IACpBb,qBAAAA;AAAAA,IACAE,UAAAA;AAAAA,IACAI,kBAAAA;AAAAA,IACAE,YAAAA;AAAAA,EACD,CAAA,GACD,OAAO;AAAA,IACLF,kBAAAA;AAAAA,IACAC,qBAAAA;AAAAA,IACAC,YAAAA;AAAAA,IACAC,eAAAA;AAAAA,IACAC,aAAAA;AAAAA,IACAC,gBAAAA;AAAAA,IACAX,qBAAAA;AAAAA;AAAAA,IAEAG,QAAQD;AAAAA,IACRA,UAAAA;AAAAA,EAAAA,KAGDD,CACH;AAEJ,GAEaa,IAAsBA,MAA+B;AAC1DC,QAAAA,IAAUnB,EAAMoB,WACpBrB,CACF;AACA,MAAIoB,MAAYE;AACR,UAAA,IAAIC,MACR,8DACF;AAEKH,SAAAA;AACT;"}
1
+ {"version":3,"file":"KnockSlackProvider.mjs","sources":["../../../../../src/modules/slack/context/KnockSlackProvider.tsx"],"sourcesContent":["import { useSlackConnectionStatus } from \"..\";\nimport * as React from \"react\";\nimport { PropsWithChildren } from \"react\";\n\nimport { slackProviderKey } from \"../../core\";\nimport { useKnockClient } from \"../../core\";\nimport { ConnectionStatus } from \"../hooks/useSlackConnectionStatus\";\n\nexport interface KnockSlackProviderState {\n knockSlackChannelId: string;\n tenantId: string;\n /**\n * @deprecated Use `tenantId` instead. This field will be removed in a future release.\n */\n tenant: string;\n connectionStatus: ConnectionStatus;\n setConnectionStatus: (connectionStatus: ConnectionStatus) => void;\n errorLabel: string | null;\n setErrorLabel: (label: string) => void;\n actionLabel: string | null;\n setActionLabel: (label: string | null) => void;\n}\n\nconst SlackProviderStateContext =\n React.createContext<KnockSlackProviderState | null>(null);\n\nexport type KnockSlackProviderProps =\n | {\n knockSlackChannelId: string;\n /**\n * @deprecated Use `tenantId` instead. This field will be removed in a future release.\n */\n tenant: string;\n }\n | {\n knockSlackChannelId: string;\n tenantId: string;\n };\n\nexport const KnockSlackProvider: React.FC<\n PropsWithChildren<KnockSlackProviderProps>\n> = (props) => {\n const { knockSlackChannelId, children } = props;\n const tenantId = \"tenantId\" in props ? props.tenantId : props.tenant;\n\n const knock = useKnockClient();\n\n const {\n connectionStatus,\n setConnectionStatus,\n errorLabel,\n setErrorLabel,\n actionLabel,\n setActionLabel,\n } = useSlackConnectionStatus(knock, knockSlackChannelId, tenantId);\n\n return (\n <SlackProviderStateContext.Provider\n key={slackProviderKey({\n knockSlackChannelId,\n tenantId,\n connectionStatus,\n errorLabel,\n })}\n value={{\n connectionStatus,\n setConnectionStatus,\n errorLabel,\n setErrorLabel,\n actionLabel,\n setActionLabel,\n knockSlackChannelId,\n // Assign the same value to both tenant and tenantId for backwards compatibility\n tenant: tenantId,\n tenantId,\n }}\n >\n {children}\n </SlackProviderStateContext.Provider>\n );\n};\n\nexport const useKnockSlackClient = (): KnockSlackProviderState => {\n const context = React.useContext(\n SlackProviderStateContext,\n ) as KnockSlackProviderState;\n if (context === undefined) {\n throw new Error(\n \"useKnockSlackClient must be used within a KnockSlackProvider\",\n );\n }\n return context as KnockSlackProviderState;\n};\n"],"names":["SlackProviderStateContext","React","createContext","KnockSlackProvider","props","knockSlackChannelId","children","tenantId","tenant","knock","useKnockClient","connectionStatus","setConnectionStatus","errorLabel","setErrorLabel","actionLabel","setActionLabel","useSlackConnectionStatus","slackProviderKey","useKnockSlackClient","context","useContext","undefined","Error"],"mappings":";;;;;;;;;AAuBA,MAAMA,IACJC,EAAMC,cAA8C,IAAI,GAe7CC,IAERC,CAAUA,MAAA;AACP,QAAA;AAAA,IAAEC,qBAAAA;AAAAA,IAAqBC,UAAAA;AAAAA,EAAaF,IAAAA,GACpCG,IAAW,cAAcH,IAAQA,EAAMG,WAAWH,EAAMI,QAExDC,IAAQC,KAER;AAAA,IACJC,kBAAAA;AAAAA,IACAC,qBAAAA;AAAAA,IACAC,YAAAA;AAAAA,IACAC,eAAAA;AAAAA,IACAC,aAAAA;AAAAA,IACAC,gBAAAA;AAAAA,EACEC,IAAAA,EAAyBR,GAAOJ,GAAqBE,CAAQ;AAEjE,SACG,gBAAAN,EAAA,cAAAD,EAA0B,UAA1B,EACC,KAAKkB,EAAiB;AAAA,IACpBb,qBAAAA;AAAAA,IACAE,UAAAA;AAAAA,IACAI,kBAAAA;AAAAA,IACAE,YAAAA;AAAAA,EACD,CAAA,GACD,OAAO;AAAA,IACLF,kBAAAA;AAAAA,IACAC,qBAAAA;AAAAA,IACAC,YAAAA;AAAAA,IACAC,eAAAA;AAAAA,IACAC,aAAAA;AAAAA,IACAC,gBAAAA;AAAAA,IACAX,qBAAAA;AAAAA;AAAAA,IAEAG,QAAQD;AAAAA,IACRA,UAAAA;AAAAA,EAAAA,KAGDD,CACH;AAEJ,GAEaa,IAAsBA,MAA+B;AAC1DC,QAAAA,IAAUnB,EAAMoB,WACpBrB,CACF;AACA,MAAIoB,MAAYE;AACR,UAAA,IAAIC,MACR,8DACF;AAEKH,SAAAA;AACT;"}
@@ -1,61 +1,78 @@
1
- import { useKnockSlackClient as b } from "../context/KnockSlackProvider.mjs";
2
- import { useState as t, useCallback as y, useEffect as E } from "react";
1
+ import { useKnockSlackClient as S } from "../context/KnockSlackProvider.mjs";
2
+ import { useState as l } from "react";
3
3
  import "../../i18n/context/KnockI18nProvider.mjs";
4
- import { useTranslations as I } from "../../i18n/hooks/useTranslations.mjs";
4
+ import { useTranslations as g } from "../../i18n/hooks/useTranslations.mjs";
5
5
  import "swr/infinite";
6
- import { useKnockClient as j } from "../../core/context/KnockProvider.mjs";
6
+ import { useKnockClient as E } from "../../core/context/KnockProvider.mjs";
7
7
  import "@knocklabs/client";
8
8
  import "zustand/shallow";
9
9
  import "date-fns";
10
- function _({
10
+ import D from "swr";
11
+ const N = "SLACK_CONNECTED_CHANNELS";
12
+ function j({
11
13
  slackChannelsRecipientObject: {
12
- objectId: e,
13
- collection: a
14
+ objectId: a,
15
+ collection: e
14
16
  }
15
17
  }) {
16
18
  const {
17
- t: g
18
- } = I(), o = j(), {
19
- connectionStatus: h,
20
- knockSlackChannelId: c
21
- } = b(), [s, l] = t(null), [i, d] = t(null), [r, C] = t(!1), [S, f] = t(!1), u = y(() => {
22
- C(!0), (async () => await o.objects.getChannelData({
23
- collection: a,
24
- objectId: e,
25
- channelId: c
26
- }))().then((n) => {
27
- var m, k;
28
- (m = n == null ? void 0 : n.data) != null && m.connections ? l((k = n == null ? void 0 : n.data) == null ? void 0 : k.connections) : l([]), d(null), C(!1);
29
- }).catch(() => {
30
- l([]), d(null), C(!1);
31
- });
32
- }, [a, o.objects, c, e]);
33
- return E(() => {
34
- h === "connected" && !s && !i && !r && u();
35
- }, [s, u, r, i, h]), {
36
- data: s,
37
- updateConnectedChannels: async (p) => {
38
- f(!0);
19
+ t: u
20
+ } = g(), s = E(), {
21
+ connectionStatus: d,
22
+ knockSlackChannelId: o
23
+ } = S(), [p, c] = l(null), [C, r] = l(!1), {
24
+ data: m,
25
+ mutate: h,
26
+ isValidating: f,
27
+ isLoading: k
28
+ } = D(
29
+ // Only fetch when Slack is connected
30
+ d === "connected" ? [N, o, e, a] : null,
31
+ async () => s.objects.getChannelData({
32
+ collection: e,
33
+ objectId: a,
34
+ channelId: o
35
+ }).then((t) => {
36
+ var n;
37
+ return ((n = t.data) == null ? void 0 : n.connections) ?? [];
38
+ }).catch(() => []),
39
+ {
40
+ onSuccess: () => {
41
+ c(null);
42
+ }
43
+ }
44
+ );
45
+ return {
46
+ data: m ?? null,
47
+ updateConnectedChannels: async (t) => {
48
+ r(!0);
39
49
  try {
40
- await o.objects.setChannelData({
41
- objectId: e,
42
- collection: a,
43
- channelId: c,
50
+ await h(() => s.objects.setChannelData({
51
+ objectId: a,
52
+ collection: e,
53
+ channelId: o,
44
54
  data: {
45
- connections: p
55
+ connections: t
46
56
  }
47
- }), u();
57
+ }).then((n) => {
58
+ var i;
59
+ return ((i = n.data) == null ? void 0 : i.connections) ?? [];
60
+ }), {
61
+ populateCache: !0,
62
+ revalidate: !1,
63
+ optimisticData: t
64
+ });
48
65
  } catch {
49
- d(g("slackChannelSetError") || "");
66
+ c(u("slackChannelSetError") || "");
50
67
  }
51
- f(!1);
68
+ r(!1);
52
69
  },
53
- updating: S,
54
- loading: r,
55
- error: i
70
+ updating: C,
71
+ loading: k || f,
72
+ error: p
56
73
  };
57
74
  }
58
75
  export {
59
- _ as default
76
+ j as default
60
77
  };
61
78
  //# sourceMappingURL=useConnectedSlackChannels.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useConnectedSlackChannels.mjs","sources":["../../../../../src/modules/slack/hooks/useConnectedSlackChannels.ts"],"sourcesContent":["import { useKnockSlackClient } from \"..\";\nimport { SlackChannelConnection } from \"@knocklabs/client\";\nimport { useCallback, useEffect, useState } from \"react\";\n\nimport { RecipientObject } from \"../../..\";\nimport { useKnockClient } from \"../../core\";\nimport { useTranslations } from \"../../i18n\";\n\ntype UseConnectedSlackChannelsProps = {\n slackChannelsRecipientObject: RecipientObject;\n};\n\ntype UseConnectedSlackChannelOutput = {\n data: SlackChannelConnection[] | null;\n updateConnectedChannels: (\n connectedChannels: SlackChannelConnection[],\n ) => Promise<void>;\n loading: boolean;\n error: string | null;\n updating: boolean;\n};\n\nfunction useConnectedSlackChannels({\n slackChannelsRecipientObject: { objectId, collection },\n}: UseConnectedSlackChannelsProps): UseConnectedSlackChannelOutput {\n const { t } = useTranslations();\n const knock = useKnockClient();\n const { connectionStatus, knockSlackChannelId } = useKnockSlackClient();\n const [connectedChannels, setConnectedChannels] = useState<\n null | SlackChannelConnection[]\n >(null);\n const [error, setError] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [isUpdating, setIsUpdating] = useState(false);\n\n const fetchAndSetConnectedChannels = useCallback(() => {\n setIsLoading(true);\n const getConnectedChannels = async () =>\n await knock.objects.getChannelData({\n collection,\n objectId,\n channelId: knockSlackChannelId,\n });\n\n getConnectedChannels()\n .then((res) => {\n if (res?.data?.connections) {\n setConnectedChannels(res?.data?.connections);\n } else {\n setConnectedChannels([]);\n }\n setError(null);\n setIsLoading(false);\n })\n .catch(() => {\n setConnectedChannels([]);\n setError(null);\n setIsLoading(false);\n });\n }, [collection, knock.objects, knockSlackChannelId, objectId]);\n\n useEffect(() => {\n if (\n connectionStatus === \"connected\" &&\n !connectedChannels &&\n !error &&\n !isLoading\n ) {\n fetchAndSetConnectedChannels();\n }\n }, [\n connectedChannels,\n fetchAndSetConnectedChannels,\n isLoading,\n error,\n connectionStatus,\n ]);\n\n const updateConnectedChannels = async (\n channelsToSendToKnock: SlackChannelConnection[],\n ) => {\n setIsUpdating(true);\n try {\n await knock.objects.setChannelData({\n objectId,\n collection,\n channelId: knockSlackChannelId,\n data: { connections: channelsToSendToKnock },\n });\n fetchAndSetConnectedChannels();\n } catch (_error) {\n setError(t(\"slackChannelSetError\") || \"\");\n }\n setIsUpdating(false);\n };\n\n return {\n data: connectedChannels,\n updateConnectedChannels,\n updating: isUpdating,\n loading: isLoading,\n error,\n };\n}\n\nexport default useConnectedSlackChannels;\n"],"names":["useConnectedSlackChannels","slackChannelsRecipientObject","objectId","collection","t","useTranslations","knock","useKnockClient","connectionStatus","knockSlackChannelId","useKnockSlackClient","connectedChannels","setConnectedChannels","useState","error","setError","isLoading","setIsLoading","isUpdating","setIsUpdating","fetchAndSetConnectedChannels","useCallback","objects","getChannelData","channelId","then","res","data","connections","catch","useEffect","updateConnectedChannels","channelsToSendToKnock","setChannelData","updating","loading"],"mappings":";;;;;;;;;AAsBA,SAASA,EAA0B;AAAA,EACjCC,8BAA8B;AAAA,IAAEC,UAAAA;AAAAA,IAAUC,YAAAA;AAAAA,EAAW;AACvB,GAAmC;AAC3D,QAAA;AAAA,IAAEC,GAAAA;AAAAA,MAAMC,EAAgB,GACxBC,IAAQC,KACR;AAAA,IAAEC,kBAAAA;AAAAA,IAAkBC,qBAAAA;AAAAA,MAAwBC,EAAoB,GAChE,CAACC,GAAmBC,CAAoB,IAAIC,EAEhD,IAAI,GACA,CAACC,GAAOC,CAAQ,IAAIF,EAAwB,IAAI,GAChD,CAACG,GAAWC,CAAY,IAAIJ,EAAS,EAAK,GAC1C,CAACK,GAAYC,CAAa,IAAIN,EAAS,EAAK,GAE5CO,IAA+BC,EAAY,MAAM;AACrDJ,IAAAA,EAAa,EAAI,IACY,YAC3B,MAAMX,EAAMgB,QAAQC,eAAe;AAAA,MACjCpB,YAAAA;AAAAA,MACAD,UAAAA;AAAAA,MACAsB,WAAWf;AAAAA,IAAAA,CACZ,GAEkB,EAClBgB,KAAMC,CAAQA,MAAA;;AACTA,OAAAA,IAAAA,KAAAA,gBAAAA,EAAKC,SAALD,QAAAA,EAAWE,cACQF,GAAAA,IAAAA,KAAAA,gBAAAA,EAAKC,SAALD,gBAAAA,EAAWE,WAAW,IAE3ChB,EAAqB,CAAE,CAAA,GAEzBG,EAAS,IAAI,GACbE,EAAa,EAAK;AAAA,IAAA,CACnB,EACAY,MAAM,MAAM;AACXjB,MAAAA,EAAqB,CAAE,CAAA,GACvBG,EAAS,IAAI,GACbE,EAAa,EAAK;AAAA,IAAA,CACnB;AAAA,EAAA,GACF,CAACd,GAAYG,EAAMgB,SAASb,GAAqBP,CAAQ,CAAC;AAE7D4B,SAAAA,EAAU,MAAM;AACd,IACEtB,MAAqB,eACrB,CAACG,KACD,CAACG,KACD,CAACE,KAE4BI;EAC/B,GACC,CACDT,GACAS,GACAJ,GACAF,GACAN,CAAgB,CACjB,GAoBM;AAAA,IACLmB,MAAMhB;AAAAA,IACNoB,yBApB8B,OAC9BC,MACG;AACHb,MAAAA,EAAc,EAAI;AACd,UAAA;AACIb,cAAAA,EAAMgB,QAAQW,eAAe;AAAA,UACjC/B,UAAAA;AAAAA,UACAC,YAAAA;AAAAA,UACAqB,WAAWf;AAAAA,UACXkB,MAAM;AAAA,YAAEC,aAAaI;AAAAA,UAAsB;AAAA,QAAA,CAC5C,GAC4BZ;cACd;AACNhB,QAAAA,EAAAA,EAAE,sBAAsB,KAAK,EAAE;AAAA,MAC1C;AACAe,MAAAA,EAAc,EAAK;AAAA,IAAA;AAAA,IAMnBe,UAAUhB;AAAAA,IACViB,SAASnB;AAAAA,IACTF,OAAAA;AAAAA,EAAAA;AAEJ;"}
1
+ {"version":3,"file":"useConnectedSlackChannels.mjs","sources":["../../../../../src/modules/slack/hooks/useConnectedSlackChannels.ts"],"sourcesContent":["import { useKnockSlackClient } from \"..\";\nimport { SlackChannelConnection } from \"@knocklabs/client\";\nimport { GenericData } from \"@knocklabs/types\";\nimport { useState } from \"react\";\nimport useSWR from \"swr\";\n\nimport { RecipientObject } from \"../../..\";\nimport { useKnockClient } from \"../../core\";\nimport { useTranslations } from \"../../i18n\";\n\nconst QUERY_KEY = \"SLACK_CONNECTED_CHANNELS\";\n\ntype UseConnectedSlackChannelsProps = {\n slackChannelsRecipientObject: RecipientObject;\n};\n\ntype UseConnectedSlackChannelsOutput = {\n data: SlackChannelConnection[] | null;\n updateConnectedChannels: (\n connectedChannels: SlackChannelConnection[],\n ) => Promise<void>;\n loading: boolean;\n error: string | null;\n updating: boolean;\n};\n\nfunction useConnectedSlackChannels({\n slackChannelsRecipientObject: { objectId, collection },\n}: UseConnectedSlackChannelsProps): UseConnectedSlackChannelsOutput {\n const { t } = useTranslations();\n const knock = useKnockClient();\n const { connectionStatus, knockSlackChannelId } = useKnockSlackClient();\n\n const [error, setError] = useState<string | null>(null);\n const [isUpdating, setIsUpdating] = useState(false);\n\n const {\n data: connectedChannels,\n mutate,\n isValidating,\n isLoading,\n } = useSWR<SlackChannelConnection[]>(\n // Only fetch when Slack is connected\n connectionStatus === \"connected\"\n ? [QUERY_KEY, knockSlackChannelId, collection, objectId]\n : null,\n async () => {\n return knock.objects\n .getChannelData({\n collection,\n objectId,\n channelId: knockSlackChannelId,\n })\n .then((res) => res.data?.connections ?? [])\n .catch(() => []);\n },\n {\n onSuccess: () => {\n setError(null);\n },\n },\n );\n\n const updateConnectedChannels = async (\n channelsToSendToKnock: SlackChannelConnection[],\n ) => {\n setIsUpdating(true);\n try {\n await mutate(\n () =>\n knock.objects\n .setChannelData({\n objectId,\n collection,\n channelId: knockSlackChannelId,\n data: { connections: channelsToSendToKnock },\n })\n .then((res) => (res as GenericData).data?.connections ?? []),\n {\n populateCache: true,\n revalidate: false,\n optimisticData: channelsToSendToKnock,\n },\n );\n } catch (_error) {\n setError(t(\"slackChannelSetError\") || \"\");\n }\n setIsUpdating(false);\n };\n\n return {\n data: connectedChannels ?? null,\n updateConnectedChannels,\n updating: isUpdating,\n loading: isLoading || isValidating,\n error,\n };\n}\n\nexport default useConnectedSlackChannels;\n"],"names":["QUERY_KEY","useConnectedSlackChannels","slackChannelsRecipientObject","objectId","collection","t","useTranslations","knock","useKnockClient","connectionStatus","knockSlackChannelId","useKnockSlackClient","error","setError","useState","isUpdating","setIsUpdating","data","connectedChannels","mutate","isValidating","isLoading","useSWR","objects","getChannelData","channelId","then","res","connections","catch","onSuccess","updateConnectedChannels","channelsToSendToKnock","setChannelData","populateCache","revalidate","optimisticData","updating","loading"],"mappings":";;;;;;;;;;AAUA,MAAMA,IAAY;AAgBlB,SAASC,EAA0B;AAAA,EACjCC,8BAA8B;AAAA,IAAEC,UAAAA;AAAAA,IAAUC,YAAAA;AAAAA,EAAW;AACvB,GAAoC;AAC5D,QAAA;AAAA,IAAEC,GAAAA;AAAAA,MAAMC,EAAgB,GACxBC,IAAQC,KACR;AAAA,IAAEC,kBAAAA;AAAAA,IAAkBC,qBAAAA;AAAAA,MAAwBC,EAAoB,GAEhE,CAACC,GAAOC,CAAQ,IAAIC,EAAwB,IAAI,GAChD,CAACC,GAAYC,CAAa,IAAIF,EAAS,EAAK,GAE5C;AAAA,IACJG,MAAMC;AAAAA,IACNC,QAAAA;AAAAA,IACAC,cAAAA;AAAAA,IACAC,WAAAA;AAAAA,EAAAA,IACEC;AAAAA;AAAAA,IAEFb,MAAqB,cACjB,CAACT,GAAWU,GAAqBN,GAAYD,CAAQ,IACrD;AAAA,IACJ,YACSI,EAAMgB,QACVC,eAAe;AAAA,MACdpB,YAAAA;AAAAA,MACAD,UAAAA;AAAAA,MACAsB,WAAWf;AAAAA,IACZ,CAAA,EACAgB,KAAMC,CAAAA,MAAAA;;AAAQA,eAAAA,IAAAA,EAAIV,SAAJU,gBAAAA,EAAUC,gBAAe;KAAE,EACzCC,MAAM,MAAM,CAAE,CAAA;AAAA,IAEnB;AAAA,MACEC,WAAWA,MAAM;AACfjB,QAAAA,EAAS,IAAI;AAAA,MACf;AAAA,IACF;AAAA,EAAA;AA8BK,SAAA;AAAA,IACLI,MAAMC,KAAqB;AAAA,IAC3Ba,yBA7B8B,OAC9BC,MACG;AACHhB,MAAAA,EAAc,EAAI;AACd,UAAA;AACF,cAAMG,EACJ,MACEZ,EAAMgB,QACHU,eAAe;AAAA,UACd9B,UAAAA;AAAAA,UACAC,YAAAA;AAAAA,UACAqB,WAAWf;AAAAA,UACXO,MAAM;AAAA,YAAEW,aAAaI;AAAAA,UAAsB;AAAA,QAAA,CAC5C,EACAN,KAAMC,CAAAA,MAAAA;;AAASA,mBAAAA,IAAAA,EAAoBV,SAApBU,gBAAAA,EAA0BC,gBAAe,CAAA;AAAA,SAAE,GAC/D;AAAA,UACEM,eAAe;AAAA,UACfC,YAAY;AAAA,UACZC,gBAAgBJ;AAAAA,QAAAA,CAEpB;AAAA,cACe;AACN3B,QAAAA,EAAAA,EAAE,sBAAsB,KAAK,EAAE;AAAA,MAC1C;AACAW,MAAAA,EAAc,EAAK;AAAA,IAAA;AAAA,IAMnBqB,UAAUtB;AAAAA,IACVuB,SAASjB,KAAaD;AAAAA,IACtBR,OAAAA;AAAAA,EAAAA;AAEJ;"}
@@ -1,40 +1,41 @@
1
- import { useKnockSlackClient as h } from "../context/KnockSlackProvider.mjs";
1
+ import { useKnockSlackClient as p } from "../context/KnockSlackProvider.mjs";
2
2
  import { useCallback as k } from "react";
3
3
  import "../../i18n/context/KnockI18nProvider.mjs";
4
4
  import "swr/infinite";
5
- import { useKnockClient as p } from "../../core/context/KnockProvider.mjs";
5
+ import { useKnockClient as h } from "../../core/context/KnockProvider.mjs";
6
6
  import { TENANT_OBJECT_COLLECTION as _ } from "@knocklabs/client";
7
7
  import "zustand/shallow";
8
8
  import "date-fns";
9
+ import "swr";
9
10
  const S = "https://slack.com/oauth/v2/authorize", u = ["chat:write", "chat:write.public", "channels:read", "groups:read"];
10
- function E(a, s, r) {
11
- const e = p(), {
11
+ function K(a, s, r) {
12
+ const e = h(), {
12
13
  setConnectionStatus: t,
13
- knockSlackChannelId: n,
14
- tenantId: o,
14
+ knockSlackChannelId: o,
15
+ tenantId: n,
15
16
  setActionLabel: i
16
- } = h(), l = r && r.length > 0 ? Array.from(new Set(u.concat(r))) : u, m = k(async () => {
17
+ } = p(), l = r && r.length > 0 ? Array.from(new Set(u.concat(r))) : u, m = k(async () => {
17
18
  i(null), t("disconnecting");
18
19
  try {
19
20
  const c = await e.slack.revokeAccessToken({
20
- tenant: o,
21
- knockChannelId: n
21
+ tenant: n,
22
+ knockChannelId: o
22
23
  });
23
24
  t(c === "ok" ? "disconnected" : "error");
24
25
  } catch {
25
26
  t("error");
26
27
  }
27
- }, [t, e.slack, o, n, i]);
28
+ }, [t, e.slack, n, o, i]);
28
29
  return {
29
30
  buildSlackAuthUrl: k(() => {
30
31
  const c = {
31
32
  state: JSON.stringify({
32
33
  redirect_url: s,
33
34
  access_token_object: {
34
- object_id: o,
35
+ object_id: n,
35
36
  collection: _
36
37
  },
37
- channel_id: n,
38
+ channel_id: o,
38
39
  public_key: e.apiKey,
39
40
  user_token: e.userToken
40
41
  }),
@@ -42,11 +43,11 @@ function E(a, s, r) {
42
43
  scope: l.join(",")
43
44
  };
44
45
  return `${S}?${new URLSearchParams(c)}`;
45
- }, [s, o, n, e.apiKey, e.userToken, a, l]),
46
+ }, [s, n, o, e.apiKey, e.userToken, a, l]),
46
47
  disconnectFromSlack: m
47
48
  };
48
49
  }
49
50
  export {
50
- E as default
51
+ K as default
51
52
  };
52
53
  //# sourceMappingURL=useSlackAuth.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSlackAuth.mjs","sources":["../../../../../src/modules/slack/hooks/useSlackAuth.ts"],"sourcesContent":["import { useKnockSlackClient } from \"..\";\nimport { TENANT_OBJECT_COLLECTION } from \"@knocklabs/client\";\nimport { useCallback } from \"react\";\n\nimport { useKnockClient } from \"../../core\";\n\nconst SLACK_AUTHORIZE_URL = \"https://slack.com/oauth/v2/authorize\";\nconst DEFAULT_SLACK_SCOPES = [\n \"chat:write\",\n \"chat:write.public\",\n \"channels:read\",\n \"groups:read\",\n];\n\ntype UseSlackAuthOutput = {\n buildSlackAuthUrl: () => string;\n disconnectFromSlack: () => void;\n};\n\nfunction useSlackAuth(\n slackClientId: string,\n redirectUrl?: string,\n additionalScopes?: string[],\n): UseSlackAuthOutput {\n const knock = useKnockClient();\n const { setConnectionStatus, knockSlackChannelId, tenantId, setActionLabel } =\n useKnockSlackClient();\n\n const combinedScopes =\n additionalScopes && additionalScopes.length > 0\n ? Array.from(new Set(DEFAULT_SLACK_SCOPES.concat(additionalScopes)))\n : DEFAULT_SLACK_SCOPES;\n\n const disconnectFromSlack = useCallback(async () => {\n setActionLabel(null);\n setConnectionStatus(\"disconnecting\");\n try {\n const revoke = await knock.slack.revokeAccessToken({\n tenant: tenantId,\n knockChannelId: knockSlackChannelId,\n });\n\n if (revoke === \"ok\") {\n setConnectionStatus(\"disconnected\");\n } else {\n setConnectionStatus(\"error\");\n }\n } catch (_error) {\n setConnectionStatus(\"error\");\n }\n }, [\n setConnectionStatus,\n knock.slack,\n tenantId,\n knockSlackChannelId,\n setActionLabel,\n ]);\n\n const buildSlackAuthUrl = useCallback(() => {\n const rawParams = {\n state: JSON.stringify({\n redirect_url: redirectUrl,\n access_token_object: {\n object_id: tenantId,\n collection: TENANT_OBJECT_COLLECTION,\n },\n channel_id: knockSlackChannelId,\n public_key: knock.apiKey,\n user_token: knock.userToken,\n }),\n client_id: slackClientId,\n scope: combinedScopes.join(\",\"),\n };\n return `${SLACK_AUTHORIZE_URL}?${new URLSearchParams(rawParams)}`;\n }, [\n redirectUrl,\n tenantId,\n knockSlackChannelId,\n knock.apiKey,\n knock.userToken,\n slackClientId,\n combinedScopes,\n ]);\n\n return {\n buildSlackAuthUrl,\n disconnectFromSlack,\n };\n}\n\nexport default useSlackAuth;\n"],"names":["SLACK_AUTHORIZE_URL","DEFAULT_SLACK_SCOPES","useSlackAuth","slackClientId","redirectUrl","additionalScopes","knock","useKnockClient","setConnectionStatus","knockSlackChannelId","tenantId","setActionLabel","useKnockSlackClient","combinedScopes","length","Array","from","Set","concat","disconnectFromSlack","useCallback","revoke","slack","revokeAccessToken","tenant","knockChannelId","buildSlackAuthUrl","rawParams","state","JSON","stringify","redirect_url","access_token_object","object_id","collection","TENANT_OBJECT_COLLECTION","channel_id","public_key","apiKey","user_token","userToken","client_id","scope","join","URLSearchParams"],"mappings":";;;;;;;;AAMA,MAAMA,IAAsB,wCACtBC,IAAuB,CAC3B,cACA,qBACA,iBACA,aAAa;AAQf,SAASC,EACPC,GACAC,GACAC,GACoB;AACpB,QAAMC,IAAQC,KACR;AAAA,IAAEC,qBAAAA;AAAAA,IAAqBC,qBAAAA;AAAAA,IAAqBC,UAAAA;AAAAA,IAAUC,gBAAAA;AAAAA,MAC1DC,EAAoB,GAEhBC,IACJR,KAAoBA,EAAiBS,SAAS,IAC1CC,MAAMC,KAAK,IAAIC,IAAIhB,EAAqBiB,OAAOb,CAAgB,CAAC,CAAC,IACjEJ,GAEAkB,IAAsBC,EAAY,YAAY;AAClDT,IAAAA,EAAe,IAAI,GACnBH,EAAoB,eAAe;AAC/B,QAAA;AACF,YAAMa,IAAS,MAAMf,EAAMgB,MAAMC,kBAAkB;AAAA,QACjDC,QAAQd;AAAAA,QACRe,gBAAgBhB;AAAAA,MAAAA,CACjB;AAED,MACED,EADEa,MAAW,OACO,iBAEA,OAFc;AAAA,YAIrB;AACfb,MAAAA,EAAoB,OAAO;AAAA,IAC7B;AAAA,EAAA,GACC,CACDA,GACAF,EAAMgB,OACNZ,GACAD,GACAE,CAAc,CACf;AA4BM,SAAA;AAAA,IACLe,mBA3BwBN,EAAY,MAAM;AAC1C,YAAMO,IAAY;AAAA,QAChBC,OAAOC,KAAKC,UAAU;AAAA,UACpBC,cAAc3B;AAAAA,UACd4B,qBAAqB;AAAA,YACnBC,WAAWvB;AAAAA,YACXwB,YAAYC;AAAAA,UACd;AAAA,UACAC,YAAY3B;AAAAA,UACZ4B,YAAY/B,EAAMgC;AAAAA,UAClBC,YAAYjC,EAAMkC;AAAAA,QAAAA,CACnB;AAAA,QACDC,WAAWtC;AAAAA,QACXuC,OAAO7B,EAAe8B,KAAK,GAAG;AAAA,MAAA;AAEhC,aAAO,GAAG3C,CAAmB,IAAI,IAAI4C,gBAAgBjB,CAAS,CAAC;AAAA,IACjE,GAAG,CACDvB,GACAM,GACAD,GACAH,EAAMgC,QACNhC,EAAMkC,WACNrC,GACAU,CAAc,CACf;AAAA,IAICM,qBAAAA;AAAAA,EAAAA;AAEJ;"}
1
+ {"version":3,"file":"useSlackAuth.mjs","sources":["../../../../../src/modules/slack/hooks/useSlackAuth.ts"],"sourcesContent":["import { useKnockSlackClient } from \"..\";\nimport { TENANT_OBJECT_COLLECTION } from \"@knocklabs/client\";\nimport { useCallback } from \"react\";\n\nimport { useKnockClient } from \"../../core\";\n\nconst SLACK_AUTHORIZE_URL = \"https://slack.com/oauth/v2/authorize\";\nconst DEFAULT_SLACK_SCOPES = [\n \"chat:write\",\n \"chat:write.public\",\n \"channels:read\",\n \"groups:read\",\n];\n\ntype UseSlackAuthOutput = {\n buildSlackAuthUrl: () => string;\n disconnectFromSlack: () => void;\n};\n\nfunction useSlackAuth(\n slackClientId: string,\n redirectUrl?: string,\n additionalScopes?: string[],\n): UseSlackAuthOutput {\n const knock = useKnockClient();\n const { setConnectionStatus, knockSlackChannelId, tenantId, setActionLabel } =\n useKnockSlackClient();\n\n const combinedScopes =\n additionalScopes && additionalScopes.length > 0\n ? Array.from(new Set(DEFAULT_SLACK_SCOPES.concat(additionalScopes)))\n : DEFAULT_SLACK_SCOPES;\n\n const disconnectFromSlack = useCallback(async () => {\n setActionLabel(null);\n setConnectionStatus(\"disconnecting\");\n try {\n const revoke = await knock.slack.revokeAccessToken({\n tenant: tenantId,\n knockChannelId: knockSlackChannelId,\n });\n\n if (revoke === \"ok\") {\n setConnectionStatus(\"disconnected\");\n } else {\n setConnectionStatus(\"error\");\n }\n } catch (_error) {\n setConnectionStatus(\"error\");\n }\n }, [\n setConnectionStatus,\n knock.slack,\n tenantId,\n knockSlackChannelId,\n setActionLabel,\n ]);\n\n const buildSlackAuthUrl = useCallback(() => {\n const rawParams = {\n state: JSON.stringify({\n redirect_url: redirectUrl,\n access_token_object: {\n object_id: tenantId,\n collection: TENANT_OBJECT_COLLECTION,\n },\n channel_id: knockSlackChannelId,\n public_key: knock.apiKey,\n user_token: knock.userToken,\n }),\n client_id: slackClientId,\n scope: combinedScopes.join(\",\"),\n };\n return `${SLACK_AUTHORIZE_URL}?${new URLSearchParams(rawParams)}`;\n }, [\n redirectUrl,\n tenantId,\n knockSlackChannelId,\n knock.apiKey,\n knock.userToken,\n slackClientId,\n combinedScopes,\n ]);\n\n return {\n buildSlackAuthUrl,\n disconnectFromSlack,\n };\n}\n\nexport default useSlackAuth;\n"],"names":["SLACK_AUTHORIZE_URL","DEFAULT_SLACK_SCOPES","useSlackAuth","slackClientId","redirectUrl","additionalScopes","knock","useKnockClient","setConnectionStatus","knockSlackChannelId","tenantId","setActionLabel","useKnockSlackClient","combinedScopes","length","Array","from","Set","concat","disconnectFromSlack","useCallback","revoke","slack","revokeAccessToken","tenant","knockChannelId","buildSlackAuthUrl","rawParams","state","JSON","stringify","redirect_url","access_token_object","object_id","collection","TENANT_OBJECT_COLLECTION","channel_id","public_key","apiKey","user_token","userToken","client_id","scope","join","URLSearchParams"],"mappings":";;;;;;;;;AAMA,MAAMA,IAAsB,wCACtBC,IAAuB,CAC3B,cACA,qBACA,iBACA,aAAa;AAQf,SAASC,EACPC,GACAC,GACAC,GACoB;AACpB,QAAMC,IAAQC,KACR;AAAA,IAAEC,qBAAAA;AAAAA,IAAqBC,qBAAAA;AAAAA,IAAqBC,UAAAA;AAAAA,IAAUC,gBAAAA;AAAAA,MAC1DC,EAAoB,GAEhBC,IACJR,KAAoBA,EAAiBS,SAAS,IAC1CC,MAAMC,KAAK,IAAIC,IAAIhB,EAAqBiB,OAAOb,CAAgB,CAAC,CAAC,IACjEJ,GAEAkB,IAAsBC,EAAY,YAAY;AAClDT,IAAAA,EAAe,IAAI,GACnBH,EAAoB,eAAe;AAC/B,QAAA;AACF,YAAMa,IAAS,MAAMf,EAAMgB,MAAMC,kBAAkB;AAAA,QACjDC,QAAQd;AAAAA,QACRe,gBAAgBhB;AAAAA,MAAAA,CACjB;AAED,MACED,EADEa,MAAW,OACO,iBAEA,OAFc;AAAA,YAIrB;AACfb,MAAAA,EAAoB,OAAO;AAAA,IAC7B;AAAA,EAAA,GACC,CACDA,GACAF,EAAMgB,OACNZ,GACAD,GACAE,CAAc,CACf;AA4BM,SAAA;AAAA,IACLe,mBA3BwBN,EAAY,MAAM;AAC1C,YAAMO,IAAY;AAAA,QAChBC,OAAOC,KAAKC,UAAU;AAAA,UACpBC,cAAc3B;AAAAA,UACd4B,qBAAqB;AAAA,YACnBC,WAAWvB;AAAAA,YACXwB,YAAYC;AAAAA,UACd;AAAA,UACAC,YAAY3B;AAAAA,UACZ4B,YAAY/B,EAAMgC;AAAAA,UAClBC,YAAYjC,EAAMkC;AAAAA,QAAAA,CACnB;AAAA,QACDC,WAAWtC;AAAAA,QACXuC,OAAO7B,EAAe8B,KAAK,GAAG;AAAA,MAAA;AAEhC,aAAO,GAAG3C,CAAmB,IAAI,IAAI4C,gBAAgBjB,CAAS,CAAC;AAAA,IACjE,GAAG,CACDvB,GACAM,GACAD,GACAH,EAAMgC,QACNhC,EAAMkC,WACNrC,GACAU,CAAc,CACf;AAAA,IAICM,qBAAAA;AAAAA,EAAAA;AAEJ;"}
@@ -6,11 +6,12 @@ import { useKnockClient as A } from "../../core/context/KnockProvider.mjs";
6
6
  import "@knocklabs/client";
7
7
  import "zustand/shallow";
8
8
  import "date-fns";
9
+ import "swr";
9
10
  const P = 1e3, K = 200, M = "private_channel,public_channel", u = "SLACK_CHANNELS";
10
11
  function z(n, e) {
11
12
  return n === 0 ? [u, ""] : e && ["", null].includes(e.next_cursor) ? null : [u, e.next_cursor ?? ""];
12
13
  }
13
- function V({
14
+ function W({
14
15
  queryOptions: n
15
16
  }) {
16
17
  var C, _;
@@ -47,6 +48,6 @@ function V({
47
48
  };
48
49
  }
49
50
  export {
50
- V as default
51
+ W as default
51
52
  };
52
53
  //# sourceMappingURL=useSlackChannels.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSlackChannels.mjs","sources":["../../../../../src/modules/slack/hooks/useSlackChannels.ts"],"sourcesContent":["import { SlackChannelQueryOptions, useKnockSlackClient } from \"..\";\nimport { GetSlackChannelsResponse, SlackChannel } from \"@knocklabs/client\";\nimport { useEffect, useMemo } from \"react\";\nimport useSWRInfinite from \"swr/infinite\";\n\nimport { useKnockClient } from \"../../core\";\n\nconst MAX_COUNT = 1000;\nconst LIMIT_PER_PAGE = 200;\nconst CHANNEL_TYPES = \"private_channel,public_channel\";\n\nconst QUERY_KEY = \"SLACK_CHANNELS\";\n\ntype UseSlackChannelsProps = {\n queryOptions?: SlackChannelQueryOptions;\n};\n\ntype UseSlackChannelOutput = {\n data: SlackChannel[];\n isLoading: boolean;\n refetch: () => void;\n};\n\ntype QueryKey = [key: string, cursor: string] | null;\n\nfunction getQueryKey(\n pageIndex: number,\n previousPageData: GetSlackChannelsResponse,\n): QueryKey {\n // First page so just pass empty\n if (pageIndex === 0) {\n return [QUERY_KEY, \"\"];\n }\n\n // If there's no more data then return an empty next cursor\n if (previousPageData && [\"\", null].includes(previousPageData.next_cursor)) {\n return null;\n }\n\n // Next cursor exists so pass it\n return [QUERY_KEY, previousPageData.next_cursor ?? \"\"];\n}\n\nfunction useSlackChannels({\n queryOptions,\n}: UseSlackChannelsProps): UseSlackChannelOutput {\n const knock = useKnockClient();\n const { knockSlackChannelId, tenantId, connectionStatus } =\n useKnockSlackClient();\n\n const fetchChannels = (queryKey: QueryKey) => {\n return knock.slack.getChannels({\n tenant: tenantId,\n knockChannelId: knockSlackChannelId,\n queryOptions: {\n ...queryOptions,\n cursor: queryKey ? queryKey[1] : \"\",\n limit: queryOptions?.limitPerPage || LIMIT_PER_PAGE,\n types: queryOptions?.types || CHANNEL_TYPES,\n },\n });\n };\n\n const { data, error, isLoading, isValidating, size, setSize, mutate } =\n useSWRInfinite<GetSlackChannelsResponse>(getQueryKey, fetchChannels, {\n initialSize: 0,\n });\n\n const currentPage = data?.length || 0;\n\n const hasNextPage =\n currentPage === 0 ||\n (data &&\n data[currentPage]?.next_cursor &&\n data[currentPage]?.next_cursor !== \"\");\n\n const slackChannels: SlackChannel[] = useMemo(\n () =>\n (data ?? [])\n .flatMap((page) => page?.slack_channels)\n .filter((channel) => !!channel),\n [data],\n );\n\n const maxCount = queryOptions?.maxCount || MAX_COUNT;\n\n useEffect(() => {\n if (\n connectionStatus === \"connected\" &&\n !error &&\n hasNextPage &&\n !isLoading &&\n !isValidating &&\n slackChannels.length < maxCount\n ) {\n // Fetch a page at a time until we have nothing else left to fetch\n // or we've already hit the max amount of channels to fetch\n setSize(size + 1);\n }\n }, [\n slackChannels.length,\n setSize,\n size,\n hasNextPage,\n isLoading,\n isValidating,\n maxCount,\n error,\n connectionStatus,\n ]);\n\n return {\n data: slackChannels,\n isLoading: isLoading || isValidating,\n refetch: () => mutate(),\n };\n}\n\nexport default useSlackChannels;\n"],"names":["MAX_COUNT","LIMIT_PER_PAGE","CHANNEL_TYPES","QUERY_KEY","getQueryKey","pageIndex","previousPageData","includes","next_cursor","useSlackChannels","queryOptions","knock","useKnockClient","knockSlackChannelId","tenantId","connectionStatus","useKnockSlackClient","fetchChannels","queryKey","slack","getChannels","tenant","knockChannelId","cursor","limit","limitPerPage","types","data","error","isLoading","isValidating","size","setSize","mutate","useSWRInfinite","initialSize","currentPage","length","hasNextPage","slackChannels","useMemo","flatMap","page","slack_channels","filter","channel","maxCount","useEffect","refetch"],"mappings":";;;;;;;;AAOA,MAAMA,IAAY,KACZC,IAAiB,KACjBC,IAAgB,kCAEhBC,IAAY;AAclB,SAASC,EACPC,GACAC,GACU;AAEV,SAAID,MAAc,IACT,CAACF,GAAW,EAAE,IAInBG,KAAoB,CAAC,IAAI,IAAI,EAAEC,SAASD,EAAiBE,WAAW,IAC/D,OAIF,CAACL,GAAWG,EAAiBE,eAAe,EAAE;AACvD;AAEA,SAASC,EAAiB;AAAA,EACxBC,cAAAA;AACqB,GAA0B;;AAC/C,QAAMC,IAAQC,KACR;AAAA,IAAEC,qBAAAA;AAAAA,IAAqBC,UAAAA;AAAAA,IAAUC,kBAAAA;AAAAA,MACrCC,EAAoB,GAEhBC,IAAgBA,CAACC,MACdP,EAAMQ,MAAMC,YAAY;AAAA,IAC7BC,QAAQP;AAAAA,IACRQ,gBAAgBT;AAAAA,IAChBH,cAAc;AAAA,MACZ,GAAGA;AAAAA,MACHa,QAAQL,IAAWA,EAAS,CAAC,IAAI;AAAA,MACjCM,QAAOd,KAAAA,gBAAAA,EAAce,iBAAgBxB;AAAAA,MACrCyB,QAAOhB,KAAAA,gBAAAA,EAAcgB,UAASxB;AAAAA,IAChC;AAAA,EAAA,CACD,GAGG;AAAA,IAAEyB,MAAAA;AAAAA,IAAMC,OAAAA;AAAAA,IAAOC,WAAAA;AAAAA,IAAWC,cAAAA;AAAAA,IAAcC,MAAAA;AAAAA,IAAMC,SAAAA;AAAAA,IAASC,QAAAA;AAAAA,EAAAA,IAC3DC,EAAyC9B,GAAaa,GAAe;AAAA,IACnEkB,aAAa;AAAA,EAAA,CACd,GAEGC,KAAcT,KAAAA,gBAAAA,EAAMU,WAAU,GAE9BC,IACJF,MAAgB,KACfT,OACCA,IAAAA,EAAKS,CAAW,MAAhBT,gBAAAA,EAAmBnB,kBACnBmB,IAAAA,EAAKS,CAAW,MAAhBT,gBAAAA,EAAmBnB,iBAAgB,IAEjC+B,IAAgCC,EACpC,OACGb,KAAQ,IACNc,QAASC,CAASA,MAAAA,KAAAA,gBAAAA,EAAMC,cAAc,EACtCC,OAAQC,OAAY,CAAC,CAACA,CAAO,GAClC,CAAClB,CAAI,CACP,GAEMmB,KAAWpC,KAAAA,gBAAAA,EAAcoC,aAAY9C;AAE3C+C,SAAAA,EAAU,MAAM;AAEZhC,IAAAA,MAAqB,eACrB,CAACa,KACDU,KACA,CAACT,KACD,CAACC,KACDS,EAAcF,SAASS,KAIvBd,EAAQD,IAAO,CAAC;AAAA,EAEjB,GAAA,CACDQ,EAAcF,QACdL,GACAD,GACAO,GACAT,GACAC,GACAgB,GACAlB,GACAb,CAAgB,CACjB,GAEM;AAAA,IACLY,MAAMY;AAAAA,IACNV,WAAWA,KAAaC;AAAAA,IACxBkB,SAASA,MAAMf,EAAO;AAAA,EAAA;AAE1B;"}
1
+ {"version":3,"file":"useSlackChannels.mjs","sources":["../../../../../src/modules/slack/hooks/useSlackChannels.ts"],"sourcesContent":["import { SlackChannelQueryOptions, useKnockSlackClient } from \"..\";\nimport { GetSlackChannelsResponse, SlackChannel } from \"@knocklabs/client\";\nimport { useEffect, useMemo } from \"react\";\nimport useSWRInfinite from \"swr/infinite\";\n\nimport { useKnockClient } from \"../../core\";\n\nconst MAX_COUNT = 1000;\nconst LIMIT_PER_PAGE = 200;\nconst CHANNEL_TYPES = \"private_channel,public_channel\";\n\nconst QUERY_KEY = \"SLACK_CHANNELS\";\n\ntype UseSlackChannelsProps = {\n queryOptions?: SlackChannelQueryOptions;\n};\n\ntype UseSlackChannelOutput = {\n data: SlackChannel[];\n isLoading: boolean;\n refetch: () => void;\n};\n\ntype QueryKey = [key: string, cursor: string] | null;\n\nfunction getQueryKey(\n pageIndex: number,\n previousPageData: GetSlackChannelsResponse,\n): QueryKey {\n // First page so just pass empty\n if (pageIndex === 0) {\n return [QUERY_KEY, \"\"];\n }\n\n // If there's no more data then return an empty next cursor\n if (previousPageData && [\"\", null].includes(previousPageData.next_cursor)) {\n return null;\n }\n\n // Next cursor exists so pass it\n return [QUERY_KEY, previousPageData.next_cursor ?? \"\"];\n}\n\nfunction useSlackChannels({\n queryOptions,\n}: UseSlackChannelsProps): UseSlackChannelOutput {\n const knock = useKnockClient();\n const { knockSlackChannelId, tenantId, connectionStatus } =\n useKnockSlackClient();\n\n const fetchChannels = (queryKey: QueryKey) => {\n return knock.slack.getChannels({\n tenant: tenantId,\n knockChannelId: knockSlackChannelId,\n queryOptions: {\n ...queryOptions,\n cursor: queryKey ? queryKey[1] : \"\",\n limit: queryOptions?.limitPerPage || LIMIT_PER_PAGE,\n types: queryOptions?.types || CHANNEL_TYPES,\n },\n });\n };\n\n const { data, error, isLoading, isValidating, size, setSize, mutate } =\n useSWRInfinite<GetSlackChannelsResponse>(getQueryKey, fetchChannels, {\n initialSize: 0,\n });\n\n const currentPage = data?.length || 0;\n\n const hasNextPage =\n currentPage === 0 ||\n (data &&\n data[currentPage]?.next_cursor &&\n data[currentPage]?.next_cursor !== \"\");\n\n const slackChannels: SlackChannel[] = useMemo(\n () =>\n (data ?? [])\n .flatMap((page) => page?.slack_channels)\n .filter((channel) => !!channel),\n [data],\n );\n\n const maxCount = queryOptions?.maxCount || MAX_COUNT;\n\n useEffect(() => {\n if (\n connectionStatus === \"connected\" &&\n !error &&\n hasNextPage &&\n !isLoading &&\n !isValidating &&\n slackChannels.length < maxCount\n ) {\n // Fetch a page at a time until we have nothing else left to fetch\n // or we've already hit the max amount of channels to fetch\n setSize(size + 1);\n }\n }, [\n slackChannels.length,\n setSize,\n size,\n hasNextPage,\n isLoading,\n isValidating,\n maxCount,\n error,\n connectionStatus,\n ]);\n\n return {\n data: slackChannels,\n isLoading: isLoading || isValidating,\n refetch: () => mutate(),\n };\n}\n\nexport default useSlackChannels;\n"],"names":["MAX_COUNT","LIMIT_PER_PAGE","CHANNEL_TYPES","QUERY_KEY","getQueryKey","pageIndex","previousPageData","includes","next_cursor","useSlackChannels","queryOptions","knock","useKnockClient","knockSlackChannelId","tenantId","connectionStatus","useKnockSlackClient","fetchChannels","queryKey","slack","getChannels","tenant","knockChannelId","cursor","limit","limitPerPage","types","data","error","isLoading","isValidating","size","setSize","mutate","useSWRInfinite","initialSize","currentPage","length","hasNextPage","slackChannels","useMemo","flatMap","page","slack_channels","filter","channel","maxCount","useEffect","refetch"],"mappings":";;;;;;;;;AAOA,MAAMA,IAAY,KACZC,IAAiB,KACjBC,IAAgB,kCAEhBC,IAAY;AAclB,SAASC,EACPC,GACAC,GACU;AAEV,SAAID,MAAc,IACT,CAACF,GAAW,EAAE,IAInBG,KAAoB,CAAC,IAAI,IAAI,EAAEC,SAASD,EAAiBE,WAAW,IAC/D,OAIF,CAACL,GAAWG,EAAiBE,eAAe,EAAE;AACvD;AAEA,SAASC,EAAiB;AAAA,EACxBC,cAAAA;AACqB,GAA0B;;AAC/C,QAAMC,IAAQC,KACR;AAAA,IAAEC,qBAAAA;AAAAA,IAAqBC,UAAAA;AAAAA,IAAUC,kBAAAA;AAAAA,MACrCC,EAAoB,GAEhBC,IAAgBA,CAACC,MACdP,EAAMQ,MAAMC,YAAY;AAAA,IAC7BC,QAAQP;AAAAA,IACRQ,gBAAgBT;AAAAA,IAChBH,cAAc;AAAA,MACZ,GAAGA;AAAAA,MACHa,QAAQL,IAAWA,EAAS,CAAC,IAAI;AAAA,MACjCM,QAAOd,KAAAA,gBAAAA,EAAce,iBAAgBxB;AAAAA,MACrCyB,QAAOhB,KAAAA,gBAAAA,EAAcgB,UAASxB;AAAAA,IAChC;AAAA,EAAA,CACD,GAGG;AAAA,IAAEyB,MAAAA;AAAAA,IAAMC,OAAAA;AAAAA,IAAOC,WAAAA;AAAAA,IAAWC,cAAAA;AAAAA,IAAcC,MAAAA;AAAAA,IAAMC,SAAAA;AAAAA,IAASC,QAAAA;AAAAA,EAAAA,IAC3DC,EAAyC9B,GAAaa,GAAe;AAAA,IACnEkB,aAAa;AAAA,EAAA,CACd,GAEGC,KAAcT,KAAAA,gBAAAA,EAAMU,WAAU,GAE9BC,IACJF,MAAgB,KACfT,OACCA,IAAAA,EAAKS,CAAW,MAAhBT,gBAAAA,EAAmBnB,kBACnBmB,IAAAA,EAAKS,CAAW,MAAhBT,gBAAAA,EAAmBnB,iBAAgB,IAEjC+B,IAAgCC,EACpC,OACGb,KAAQ,IACNc,QAASC,CAASA,MAAAA,KAAAA,gBAAAA,EAAMC,cAAc,EACtCC,OAAQC,OAAY,CAAC,CAACA,CAAO,GAClC,CAAClB,CAAI,CACP,GAEMmB,KAAWpC,KAAAA,gBAAAA,EAAcoC,aAAY9C;AAE3C+C,SAAAA,EAAU,MAAM;AAEZhC,IAAAA,MAAqB,eACrB,CAACa,KACDU,KACA,CAACT,KACD,CAACC,KACDS,EAAcF,SAASS,KAIvBd,EAAQD,IAAO,CAAC;AAAA,EAEjB,GAAA,CACDQ,EAAcF,QACdL,GACAD,GACAO,GACAT,GACAC,GACAgB,GACAlB,GACAb,CAAgB,CACjB,GAEM;AAAA,IACLY,MAAMY;AAAAA,IACNV,WAAWA,KAAaC;AAAAA,IACxBkB,SAASA,MAAMf,EAAO;AAAA,EAAA;AAE1B;"}
@@ -3,13 +3,13 @@ import { RecipientObject } from '../../..';
3
3
  type UseConnectedSlackChannelsProps = {
4
4
  slackChannelsRecipientObject: RecipientObject;
5
5
  };
6
- type UseConnectedSlackChannelOutput = {
6
+ type UseConnectedSlackChannelsOutput = {
7
7
  data: SlackChannelConnection[] | null;
8
8
  updateConnectedChannels: (connectedChannels: SlackChannelConnection[]) => Promise<void>;
9
9
  loading: boolean;
10
10
  error: string | null;
11
11
  updating: boolean;
12
12
  };
13
- declare function useConnectedSlackChannels({ slackChannelsRecipientObject: { objectId, collection }, }: UseConnectedSlackChannelsProps): UseConnectedSlackChannelOutput;
13
+ declare function useConnectedSlackChannels({ slackChannelsRecipientObject: { objectId, collection }, }: UseConnectedSlackChannelsProps): UseConnectedSlackChannelsOutput;
14
14
  export default useConnectedSlackChannels;
15
15
  //# sourceMappingURL=useConnectedSlackChannels.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useConnectedSlackChannels.d.ts","sourceRoot":"","sources":["../../../../../src/modules/slack/hooks/useConnectedSlackChannels.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAI3C,KAAK,8BAA8B,GAAG;IACpC,4BAA4B,EAAE,eAAe,CAAC;CAC/C,CAAC;AAEF,KAAK,8BAA8B,GAAG;IACpC,IAAI,EAAE,sBAAsB,EAAE,GAAG,IAAI,CAAC;IACtC,uBAAuB,EAAE,CACvB,iBAAiB,EAAE,sBAAsB,EAAE,KACxC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,iBAAS,yBAAyB,CAAC,EACjC,4BAA4B,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,GACvD,EAAE,8BAA8B,GAAG,8BAA8B,CA+EjE;AAED,eAAe,yBAAyB,CAAC"}
1
+ {"version":3,"file":"useConnectedSlackChannels.d.ts","sourceRoot":"","sources":["../../../../../src/modules/slack/hooks/useConnectedSlackChannels.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAK3D,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAM3C,KAAK,8BAA8B,GAAG;IACpC,4BAA4B,EAAE,eAAe,CAAC;CAC/C,CAAC;AAEF,KAAK,+BAA+B,GAAG;IACrC,IAAI,EAAE,sBAAsB,EAAE,GAAG,IAAI,CAAC;IACtC,uBAAuB,EAAE,CACvB,iBAAiB,EAAE,sBAAsB,EAAE,KACxC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,iBAAS,yBAAyB,CAAC,EACjC,4BAA4B,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,GACvD,EAAE,8BAA8B,GAAG,+BAA+B,CAqElE;AAED,eAAe,yBAAyB,CAAC"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@knocklabs/react-core",
3
3
  "description": "A set of React components to build notification experiences powered by Knock",
4
4
  "author": "@knocklabs",
5
- "version": "0.3.2",
5
+ "version": "0.3.3",
6
6
  "license": "MIT",
7
7
  "main": "dist/cjs/index.js",
8
8
  "module": "dist/esm/index.mjs",
@@ -49,7 +49,7 @@
49
49
  "react": "^16.11.0 || ^17.0.0 || ^18.0.0"
50
50
  },
51
51
  "dependencies": {
52
- "@knocklabs/client": "^0.11.2",
52
+ "@knocklabs/client": "^0.11.3",
53
53
  "date-fns": "^4.0.0",
54
54
  "swr": "^2.2.5",
55
55
  "zustand": "^3.7.2"
@@ -1,16 +1,20 @@
1
1
  import { useKnockSlackClient } from "..";
2
2
  import { SlackChannelConnection } from "@knocklabs/client";
3
- import { useCallback, useEffect, useState } from "react";
3
+ import { GenericData } from "@knocklabs/types";
4
+ import { useState } from "react";
5
+ import useSWR from "swr";
4
6
 
5
7
  import { RecipientObject } from "../../..";
6
8
  import { useKnockClient } from "../../core";
7
9
  import { useTranslations } from "../../i18n";
8
10
 
11
+ const QUERY_KEY = "SLACK_CONNECTED_CHANNELS";
12
+
9
13
  type UseConnectedSlackChannelsProps = {
10
14
  slackChannelsRecipientObject: RecipientObject;
11
15
  };
12
16
 
13
- type UseConnectedSlackChannelOutput = {
17
+ type UseConnectedSlackChannelsOutput = {
14
18
  data: SlackChannelConnection[] | null;
15
19
  updateConnectedChannels: (
16
20
  connectedChannels: SlackChannelConnection[],
@@ -22,72 +26,62 @@ type UseConnectedSlackChannelOutput = {
22
26
 
23
27
  function useConnectedSlackChannels({
24
28
  slackChannelsRecipientObject: { objectId, collection },
25
- }: UseConnectedSlackChannelsProps): UseConnectedSlackChannelOutput {
29
+ }: UseConnectedSlackChannelsProps): UseConnectedSlackChannelsOutput {
26
30
  const { t } = useTranslations();
27
31
  const knock = useKnockClient();
28
32
  const { connectionStatus, knockSlackChannelId } = useKnockSlackClient();
29
- const [connectedChannels, setConnectedChannels] = useState<
30
- null | SlackChannelConnection[]
31
- >(null);
33
+
32
34
  const [error, setError] = useState<string | null>(null);
33
- const [isLoading, setIsLoading] = useState(false);
34
35
  const [isUpdating, setIsUpdating] = useState(false);
35
36
 
36
- const fetchAndSetConnectedChannels = useCallback(() => {
37
- setIsLoading(true);
38
- const getConnectedChannels = async () =>
39
- await knock.objects.getChannelData({
40
- collection,
41
- objectId,
42
- channelId: knockSlackChannelId,
43
- });
44
-
45
- getConnectedChannels()
46
- .then((res) => {
47
- if (res?.data?.connections) {
48
- setConnectedChannels(res?.data?.connections);
49
- } else {
50
- setConnectedChannels([]);
51
- }
52
- setError(null);
53
- setIsLoading(false);
54
- })
55
- .catch(() => {
56
- setConnectedChannels([]);
57
- setError(null);
58
- setIsLoading(false);
59
- });
60
- }, [collection, knock.objects, knockSlackChannelId, objectId]);
61
-
62
- useEffect(() => {
63
- if (
64
- connectionStatus === "connected" &&
65
- !connectedChannels &&
66
- !error &&
67
- !isLoading
68
- ) {
69
- fetchAndSetConnectedChannels();
70
- }
71
- }, [
72
- connectedChannels,
73
- fetchAndSetConnectedChannels,
37
+ const {
38
+ data: connectedChannels,
39
+ mutate,
40
+ isValidating,
74
41
  isLoading,
75
- error,
76
- connectionStatus,
77
- ]);
42
+ } = useSWR<SlackChannelConnection[]>(
43
+ // Only fetch when Slack is connected
44
+ connectionStatus === "connected"
45
+ ? [QUERY_KEY, knockSlackChannelId, collection, objectId]
46
+ : null,
47
+ async () => {
48
+ return knock.objects
49
+ .getChannelData({
50
+ collection,
51
+ objectId,
52
+ channelId: knockSlackChannelId,
53
+ })
54
+ .then((res) => res.data?.connections ?? [])
55
+ .catch(() => []);
56
+ },
57
+ {
58
+ onSuccess: () => {
59
+ setError(null);
60
+ },
61
+ },
62
+ );
78
63
 
79
64
  const updateConnectedChannels = async (
80
65
  channelsToSendToKnock: SlackChannelConnection[],
81
66
  ) => {
82
67
  setIsUpdating(true);
83
68
  try {
84
- await knock.objects.setChannelData({
85
- objectId,
86
- collection,
87
- channelId: knockSlackChannelId,
88
- data: { connections: channelsToSendToKnock },
89
- });
90
- fetchAndSetConnectedChannels();
69
+ await mutate(
70
+ () =>
71
+ knock.objects
72
+ .setChannelData({
73
+ objectId,
74
+ collection,
75
+ channelId: knockSlackChannelId,
76
+ data: { connections: channelsToSendToKnock },
77
+ })
78
+ .then((res) => (res as GenericData).data?.connections ?? []),
79
+ {
80
+ populateCache: true,
81
+ revalidate: false,
82
+ optimisticData: channelsToSendToKnock,
83
+ },
84
+ );
91
85
  } catch (_error) {
92
86
  setError(t("slackChannelSetError") || "");
93
87
  }
@@ -95,10 +89,10 @@ function useConnectedSlackChannels({
95
89
  };
96
90
 
97
91
  return {
98
- data: connectedChannels,
92
+ data: connectedChannels ?? null,
99
93
  updateConnectedChannels,
100
94
  updating: isUpdating,
101
- loading: isLoading,
95
+ loading: isLoading || isValidating,
102
96
  error,
103
97
  };
104
98
  }