@knocklabs/react-core 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 1b86a0c: fix: correct pagination logic in useSlackChannels hook (KNO-7995)
8
+
3
9
  ## 0.4.0
4
10
 
5
11
  ### Minor Changes
@@ -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");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;
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:r,isValidating:s,size:u,setSize:f,mutate:I}=g.default(z,m,{initialSize:0}),l=(e==null?void 0:e.length)||0,k=l===0||e&&l>0&&((h=e[l-1])==null?void 0:h.next_cursor)&&((C=e[l-1])==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&&!r&&!s&&o.length<_&&f(u+1)},[o.length,f,u,k,r,s,_,i,a]),{data:o,isLoading:r||s,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":"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"}
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 // Check if we have data and if the last page has a next cursor\n const hasNextPage =\n currentPage === 0 ||\n (data &&\n currentPage > 0 &&\n data[currentPage - 1]?.next_cursor &&\n data[currentPage - 1]?.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,EAG9BC,EACJF,IAAgB,GACfT,GACCS,EAAc,KACdT,EAAAA,EAAKS,EAAc,CAAC,IAApBT,YAAAA,EAAuBnB,gBACvBmB,EAAAA,EAAKS,EAAc,CAAC,IAApBT,YAAAA,EAAuBnB,eAAgB,GAErC+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"}
@@ -31,19 +31,19 @@ function W({
31
31
  }), {
32
32
  data: t,
33
33
  error: i,
34
- isLoading: l,
35
- isValidating: o,
34
+ isLoading: o,
35
+ isValidating: r,
36
36
  size: m,
37
37
  setSize: f,
38
38
  mutate: E
39
39
  } = g(z, x, {
40
40
  initialSize: 0
41
- }), r = (t == null ? void 0 : t.length) || 0, h = r === 0 || t && ((C = t[r]) == null ? void 0 : C.next_cursor) && ((_ = t[r]) == null ? void 0 : _.next_cursor) !== "", s = L(() => (t ?? []).flatMap((c) => c == null ? void 0 : c.slack_channels).filter((c) => !!c), [t]), k = (n == null ? void 0 : n.maxCount) || P;
41
+ }), l = (t == null ? void 0 : t.length) || 0, h = l === 0 || t && l > 0 && ((C = t[l - 1]) == null ? void 0 : C.next_cursor) && ((_ = t[l - 1]) == null ? void 0 : _.next_cursor) !== "", s = L(() => (t ?? []).flatMap((c) => c == null ? void 0 : c.slack_channels).filter((c) => !!c), [t]), k = (n == null ? void 0 : n.maxCount) || P;
42
42
  return N(() => {
43
- a === "connected" && !i && h && !l && !o && s.length < k && f(m + 1);
44
- }, [s.length, f, m, h, l, o, k, i, a]), {
43
+ a === "connected" && !i && h && !o && !r && s.length < k && f(m + 1);
44
+ }, [s.length, f, m, h, o, r, k, i, a]), {
45
45
  data: s,
46
- isLoading: l || o,
46
+ isLoading: o || r,
47
47
  refetch: () => E()
48
48
  };
49
49
  }
@@ -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 // Check if we have data and if the last page has a next cursor\n const hasNextPage =\n currentPage === 0 ||\n (data &&\n currentPage > 0 &&\n data[currentPage - 1]?.next_cursor &&\n data[currentPage - 1]?.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,GAG9BC,IACJF,MAAgB,KACfT,KACCS,IAAc,OACdT,IAAAA,EAAKS,IAAc,CAAC,MAApBT,gBAAAA,EAAuBnB,kBACvBmB,IAAAA,EAAKS,IAAc,CAAC,MAApBT,gBAAAA,EAAuBnB,iBAAgB,IAErC+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 +1 @@
1
- {"version":3,"file":"useSlackChannels.d.ts","sourceRoot":"","sources":["../../../../../src/modules/slack/hooks/useSlackChannels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAuB,MAAM,IAAI,CAAC;AACnE,OAAO,EAA4B,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAY3E,KAAK,qBAAqB,GAAG;IAC3B,YAAY,CAAC,EAAE,wBAAwB,CAAC;CACzC,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC3B,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAsBF,iBAAS,gBAAgB,CAAC,EACxB,YAAY,GACb,EAAE,qBAAqB,GAAG,qBAAqB,CAuE/C;AAED,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"useSlackChannels.d.ts","sourceRoot":"","sources":["../../../../../src/modules/slack/hooks/useSlackChannels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAuB,MAAM,IAAI,CAAC;AACnE,OAAO,EAA4B,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAY3E,KAAK,qBAAqB,GAAG;IAC3B,YAAY,CAAC,EAAE,wBAAwB,CAAC;CACzC,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC3B,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAsBF,iBAAS,gBAAgB,CAAC,EACxB,YAAY,GACb,EAAE,qBAAqB,GAAG,qBAAqB,CAyE/C;AAED,eAAe,gBAAgB,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.4.0",
5
+ "version": "0.4.1",
6
6
  "license": "MIT",
7
7
  "main": "dist/cjs/index.js",
8
8
  "module": "dist/esm/index.mjs",
@@ -62,7 +62,7 @@
62
62
  "@vitejs/plugin-react": "^4.3.4",
63
63
  "babel-plugin-react-require": "^4.0.3",
64
64
  "eslint": "^8.56.0",
65
- "eslint-plugin-react-hooks": "^5.0.0",
65
+ "eslint-plugin-react-hooks": "^5.2.0",
66
66
  "eslint-plugin-react-refresh": "^0.4.14",
67
67
  "jsdom": "^25.0.1",
68
68
  "react": "^18.2.0",
@@ -68,11 +68,13 @@ function useSlackChannels({
68
68
 
69
69
  const currentPage = data?.length || 0;
70
70
 
71
+ // Check if we have data and if the last page has a next cursor
71
72
  const hasNextPage =
72
73
  currentPage === 0 ||
73
74
  (data &&
74
- data[currentPage]?.next_cursor &&
75
- data[currentPage]?.next_cursor !== "");
75
+ currentPage > 0 &&
76
+ data[currentPage - 1]?.next_cursor &&
77
+ data[currentPage - 1]?.next_cursor !== "");
76
78
 
77
79
  const slackChannels: SlackChannel[] = useMemo(
78
80
  () =>