@manta-eu/react 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/README.md +2 -0
  2. package/dist/components/chart/AreaChart.d.ts.map +1 -1
  3. package/dist/components/chart/AreaChart.js +4 -6
  4. package/dist/components/chart/BarChart.d.ts.map +1 -1
  5. package/dist/components/chart/BarChart.js +5 -6
  6. package/dist/components/chart/ComposedChart.d.ts.map +1 -1
  7. package/dist/components/chart/ComposedChart.js +15 -7
  8. package/dist/components/chart/LineChart.d.ts.map +1 -1
  9. package/dist/components/chart/LineChart.js +4 -6
  10. package/dist/components/chart/annotations.d.ts +4 -0
  11. package/dist/components/chart/annotations.d.ts.map +1 -1
  12. package/dist/components/chart/annotations.js +10 -2
  13. package/dist/components/chart/chart-schemas.d.ts +1960 -54
  14. package/dist/components/chart/chart-schemas.d.ts.map +1 -1
  15. package/dist/components/chart/chart-schemas.js +137 -15
  16. package/dist/components/chart/series.d.ts +28 -0
  17. package/dist/components/chart/series.d.ts.map +1 -0
  18. package/dist/components/chart/series.js +61 -0
  19. package/dist/components/chart/stacks.d.ts +9 -0
  20. package/dist/components/chart/stacks.d.ts.map +1 -0
  21. package/dist/components/chart/stacks.js +11 -0
  22. package/dist/components/chat-view/ChatHeaders.d.ts.map +1 -1
  23. package/dist/components/chat-view/ChatHeaders.js +2 -2
  24. package/dist/components/layouts/Sidebar.d.ts.map +1 -1
  25. package/dist/components/layouts/Sidebar.js +14 -3
  26. package/dist/components/planning/ActioningView.d.ts +1 -0
  27. package/dist/components/planning/ActioningView.d.ts.map +1 -1
  28. package/dist/components/planning/ActioningView.js +15 -52
  29. package/dist/components/planning/ExecutionSectionItem.d.ts +6 -4
  30. package/dist/components/planning/ExecutionSectionItem.d.ts.map +1 -1
  31. package/dist/components/planning/ExecutionSectionItem.js +2 -2
  32. package/dist/components/planning/ExecutionSections.d.ts +6 -4
  33. package/dist/components/planning/ExecutionSections.d.ts.map +1 -1
  34. package/dist/components/planning/ExecutionSections.js +2 -2
  35. package/dist/components/planning/ManualActionCard.d.ts +14 -8
  36. package/dist/components/planning/ManualActionCard.d.ts.map +1 -1
  37. package/dist/components/planning/ManualActionCard.js +44 -24
  38. package/dist/components/planning/ManualActionList.d.ts +22 -0
  39. package/dist/components/planning/ManualActionList.d.ts.map +1 -0
  40. package/dist/components/planning/ManualActionList.js +35 -0
  41. package/dist/components/planning/manual-action-targets.d.ts +4 -0
  42. package/dist/components/planning/manual-action-targets.d.ts.map +1 -0
  43. package/dist/components/planning/manual-action-targets.js +19 -0
  44. package/dist/components/select/index.d.ts.map +1 -1
  45. package/dist/components/select/index.js +4 -1
  46. package/dist/components/sidebar/index.d.ts +2 -0
  47. package/dist/components/sidebar/index.d.ts.map +1 -1
  48. package/dist/components/sidebar/index.js +1 -0
  49. package/dist/components/sidebar/nav-user.d.ts +1 -1
  50. package/dist/components/sidebar/nav-user.d.ts.map +1 -1
  51. package/dist/components/sidebar/nav-user.js +3 -3
  52. package/dist/components/sidebar/user-avatar.d.ts +7 -0
  53. package/dist/components/sidebar/user-avatar.d.ts.map +1 -0
  54. package/dist/components/sidebar/user-avatar.js +9 -0
  55. package/dist/globals.css +6 -13
  56. package/dist/hooks/use-connection-problems.d.ts.map +1 -1
  57. package/dist/hooks/use-manual-actions.d.ts +13 -3
  58. package/dist/hooks/use-manual-actions.d.ts.map +1 -1
  59. package/dist/hooks/use-manual-actions.js +16 -10
  60. package/dist/hooks/useAuth.d.ts +1 -0
  61. package/dist/hooks/useAuth.d.ts.map +1 -1
  62. package/dist/hooks/useAuth.js +7 -1
  63. package/dist/hooks/useConversations.d.ts +1 -0
  64. package/dist/hooks/useConversations.d.ts.map +1 -1
  65. package/dist/hooks/useResolveManualAction.d.ts +14 -0
  66. package/dist/hooks/useResolveManualAction.d.ts.map +1 -0
  67. package/dist/hooks/useResolveManualAction.js +47 -0
  68. package/dist/hooks/useValidateActionPlan.d.ts.map +1 -1
  69. package/dist/ldo-ui.d.ts +2 -1
  70. package/dist/ldo-ui.d.ts.map +1 -1
  71. package/dist/ldo-ui.js +2 -1
  72. package/dist/lib/build-config.d.ts +2 -0
  73. package/dist/lib/build-config.d.ts.map +1 -1
  74. package/dist/lib/build-config.js +2 -0
  75. package/dist/lib/chat-types.d.ts +1 -0
  76. package/dist/lib/chat-types.d.ts.map +1 -1
  77. package/dist/lib/datastore-route-table.d.ts +2 -0
  78. package/dist/lib/datastore-route-table.d.ts.map +1 -1
  79. package/dist/lib/datastore-route-table.js +3 -1
  80. package/dist/lib/datastore-routes.d.ts +7 -1
  81. package/dist/lib/datastore-routes.d.ts.map +1 -1
  82. package/dist/lib/datastore-routes.js +7 -2
  83. package/dist/lib/decode-chart-entities.d.ts.map +1 -1
  84. package/dist/lib/decode-chart-entities.js +5 -1
  85. package/dist/lib/manual-actions.d.ts +1 -0
  86. package/dist/lib/manual-actions.d.ts.map +1 -1
  87. package/dist/lib/manual-actions.js +4 -1
  88. package/dist/lib/structured-data/types.d.ts +7 -2
  89. package/dist/lib/structured-data/types.d.ts.map +1 -1
  90. package/dist/providers/ChatManagerProvider.d.ts.map +1 -1
  91. package/dist/providers/ChatManagerProvider.js +18 -16
  92. package/dist/providers/NavExtrasProvider.d.ts +23 -0
  93. package/dist/providers/NavExtrasProvider.d.ts.map +1 -0
  94. package/dist/providers/NavExtrasProvider.js +10 -0
  95. package/dist/providers/index.d.ts +1 -0
  96. package/dist/providers/index.d.ts.map +1 -1
  97. package/dist/providers/index.js +1 -0
  98. package/dist/routes/explain/ExplainEmpty.d.ts.map +1 -1
  99. package/dist/routes/explain/ExplainEmpty.js +2 -1
  100. package/dist/routes/integrations/catalog-shape.d.ts +2 -1
  101. package/dist/routes/integrations/catalog-shape.d.ts.map +1 -1
  102. package/dist/routes/integrations/components/AddIntegrationModal.d.ts.map +1 -1
  103. package/dist/routes/integrations/components/AddIntegrationModal.js +1 -1
  104. package/dist/routes/integrations/components/MantaSyncPluginDownload.d.ts +13 -0
  105. package/dist/routes/integrations/components/MantaSyncPluginDownload.d.ts.map +1 -0
  106. package/dist/routes/integrations/components/MantaSyncPluginDownload.js +23 -0
  107. package/dist/routes/integrations/components/connect-forms/ConnectFormHeader.d.ts +1 -1
  108. package/dist/routes/integrations/components/connect-forms/ConnectFormHeader.d.ts.map +1 -1
  109. package/dist/routes/integrations/components/connect-forms/ConnectWizardShell.d.ts +1 -1
  110. package/dist/routes/integrations/components/connect-forms/ConnectWizardShell.d.ts.map +1 -1
  111. package/dist/routes/integrations/components/connect-forms/ConnectionStringInput.d.ts +11 -0
  112. package/dist/routes/integrations/components/connect-forms/ConnectionStringInput.d.ts.map +1 -0
  113. package/dist/routes/integrations/components/connect-forms/ConnectionStringInput.js +49 -0
  114. package/dist/routes/integrations/components/connect-forms/DashConnectForm.d.ts +7 -0
  115. package/dist/routes/integrations/components/connect-forms/DashConnectForm.d.ts.map +1 -0
  116. package/dist/routes/integrations/components/connect-forms/DashConnectForm.js +87 -0
  117. package/dist/routes/integrations/components/connect-forms/DataConnectionConnectForm.d.ts +20 -0
  118. package/dist/routes/integrations/components/connect-forms/DataConnectionConnectForm.d.ts.map +1 -0
  119. package/dist/routes/integrations/components/connect-forms/DataConnectionConnectForm.js +144 -0
  120. package/dist/routes/integrations/components/connect-forms/DataConnectionFieldInputs.d.ts +8 -0
  121. package/dist/routes/integrations/components/connect-forms/DataConnectionFieldInputs.d.ts.map +1 -0
  122. package/dist/routes/integrations/components/connect-forms/DataConnectionFieldInputs.js +44 -0
  123. package/dist/routes/integrations/components/connect-forms/FigmaConnectForm.d.ts +3 -0
  124. package/dist/routes/integrations/components/connect-forms/FigmaConnectForm.d.ts.map +1 -0
  125. package/dist/routes/integrations/components/connect-forms/FigmaConnectForm.js +20 -0
  126. package/dist/routes/integrations/components/connect-forms/GmailConnectForm.d.ts +3 -0
  127. package/dist/routes/integrations/components/connect-forms/GmailConnectForm.d.ts.map +1 -0
  128. package/dist/routes/integrations/components/connect-forms/GmailConnectForm.js +11 -0
  129. package/dist/routes/integrations/components/connect-forms/GoogleAdsConnectForm.d.ts +3 -0
  130. package/dist/routes/integrations/components/connect-forms/GoogleAdsConnectForm.d.ts.map +1 -0
  131. package/dist/routes/integrations/components/connect-forms/GoogleAdsConnectForm.js +37 -0
  132. package/dist/routes/integrations/components/connect-forms/GoogleAnalyticsConnectForm.d.ts +3 -0
  133. package/dist/routes/integrations/components/connect-forms/GoogleAnalyticsConnectForm.d.ts.map +1 -0
  134. package/dist/routes/integrations/components/connect-forms/GoogleAnalyticsConnectForm.js +37 -0
  135. package/dist/routes/integrations/components/connect-forms/ImportStartedNotice.d.ts +21 -0
  136. package/dist/routes/integrations/components/connect-forms/ImportStartedNotice.d.ts.map +1 -0
  137. package/dist/routes/integrations/components/connect-forms/ImportStartedNotice.js +25 -0
  138. package/dist/routes/integrations/components/connect-forms/InferalCredentialConnectForm.d.ts +45 -0
  139. package/dist/routes/integrations/components/connect-forms/InferalCredentialConnectForm.d.ts.map +1 -0
  140. package/dist/routes/integrations/components/connect-forms/InferalCredentialConnectForm.js +188 -0
  141. package/dist/routes/integrations/components/connect-forms/KlaviyoConnectForm.d.ts +6 -0
  142. package/dist/routes/integrations/components/connect-forms/KlaviyoConnectForm.d.ts.map +1 -0
  143. package/dist/routes/integrations/components/connect-forms/KlaviyoConnectForm.js +68 -0
  144. package/dist/routes/integrations/components/connect-forms/LinkedinConnectForm.d.ts +10 -0
  145. package/dist/routes/integrations/components/connect-forms/LinkedinConnectForm.d.ts.map +1 -0
  146. package/dist/routes/integrations/components/connect-forms/LinkedinConnectForm.js +124 -0
  147. package/dist/routes/integrations/components/connect-forms/MetaAdsConnectForm.d.ts +14 -0
  148. package/dist/routes/integrations/components/connect-forms/MetaAdsConnectForm.d.ts.map +1 -0
  149. package/dist/routes/integrations/components/connect-forms/MetaAdsConnectForm.js +183 -0
  150. package/dist/routes/integrations/components/connect-forms/OAuthConnectLink.d.ts +10 -0
  151. package/dist/routes/integrations/components/connect-forms/OAuthConnectLink.d.ts.map +1 -0
  152. package/dist/routes/integrations/components/connect-forms/OAuthConnectLink.js +17 -0
  153. package/dist/routes/integrations/components/connect-forms/OAuthSetupConnectForm.d.ts +45 -0
  154. package/dist/routes/integrations/components/connect-forms/OAuthSetupConnectForm.d.ts.map +1 -0
  155. package/dist/routes/integrations/components/connect-forms/OAuthSetupConnectForm.js +136 -0
  156. package/dist/routes/integrations/components/connect-forms/OAuthSingleAccountConnectForm.d.ts +23 -0
  157. package/dist/routes/integrations/components/connect-forms/OAuthSingleAccountConnectForm.d.ts.map +1 -0
  158. package/dist/routes/integrations/components/connect-forms/OAuthSingleAccountConnectForm.js +63 -0
  159. package/dist/routes/integrations/components/connect-forms/ShopifyConnectForm.d.ts +3 -0
  160. package/dist/routes/integrations/components/connect-forms/ShopifyConnectForm.d.ts.map +1 -0
  161. package/dist/routes/integrations/components/connect-forms/ShopifyConnectForm.js +14 -0
  162. package/dist/routes/integrations/components/connect-forms/SlackConnectForm.d.ts +3 -0
  163. package/dist/routes/integrations/components/connect-forms/SlackConnectForm.d.ts.map +1 -0
  164. package/dist/routes/integrations/components/connect-forms/SlackConnectForm.js +10 -0
  165. package/dist/routes/integrations/components/connect-forms/TriplewhaleConnectForm.d.ts +5 -0
  166. package/dist/routes/integrations/components/connect-forms/TriplewhaleConnectForm.d.ts.map +1 -0
  167. package/dist/routes/integrations/components/connect-forms/TriplewhaleConnectForm.js +35 -0
  168. package/dist/routes/integrations/components/connect-forms/WoocommerceConnectForm.d.ts +5 -0
  169. package/dist/routes/integrations/components/connect-forms/WoocommerceConnectForm.d.ts.map +1 -0
  170. package/dist/routes/integrations/components/connect-forms/WoocommerceConnectForm.js +47 -0
  171. package/dist/routes/integrations/components/connect-forms/connection-string-fields.d.ts +13 -0
  172. package/dist/routes/integrations/components/connect-forms/connection-string-fields.d.ts.map +1 -0
  173. package/dist/routes/integrations/components/connect-forms/connection-string-fields.js +110 -0
  174. package/dist/routes/integrations/components/connect-forms/dash-folder-tree.d.ts +6 -0
  175. package/dist/routes/integrations/components/connect-forms/dash-folder-tree.d.ts.map +1 -0
  176. package/dist/routes/integrations/components/connect-forms/dash-folder-tree.js +14 -0
  177. package/dist/routes/integrations/components/connect-forms/data-connection-fields.d.ts +35 -0
  178. package/dist/routes/integrations/components/connect-forms/data-connection-fields.d.ts.map +1 -0
  179. package/dist/routes/integrations/components/connect-forms/data-connection-fields.js +88 -0
  180. package/dist/routes/integrations/components/connect-forms/google-ads-account-tree.d.ts +11 -0
  181. package/dist/routes/integrations/components/connect-forms/google-ads-account-tree.d.ts.map +1 -0
  182. package/dist/routes/integrations/components/connect-forms/google-ads-account-tree.js +36 -0
  183. package/dist/routes/integrations/components/connect-forms/google-analytics-property-tree.d.ts +6 -0
  184. package/dist/routes/integrations/components/connect-forms/google-analytics-property-tree.d.ts.map +1 -0
  185. package/dist/routes/integrations/components/connect-forms/google-analytics-property-tree.js +34 -0
  186. package/dist/routes/integrations/components/connect-forms/oauth-setup-phase.d.ts +12 -0
  187. package/dist/routes/integrations/components/connect-forms/oauth-setup-phase.d.ts.map +1 -0
  188. package/dist/routes/integrations/components/connect-forms/oauth-setup-phase.js +33 -0
  189. package/dist/routes/integrations/components/connect-forms/setup-account-unavailable-reason.d.ts +3 -0
  190. package/dist/routes/integrations/components/connect-forms/setup-account-unavailable-reason.d.ts.map +1 -0
  191. package/dist/routes/integrations/components/connect-forms/setup-account-unavailable-reason.js +8 -0
  192. package/dist/routes/integrations/components/connect-forms/types.d.ts +5 -1
  193. package/dist/routes/integrations/components/connect-forms/types.d.ts.map +1 -1
  194. package/dist/routes/integrations/components/connect-forms/useConnectWizard.d.ts +19 -0
  195. package/dist/routes/integrations/components/connect-forms/useConnectWizard.d.ts.map +1 -0
  196. package/dist/routes/integrations/components/connect-forms/useConnectWizard.js +28 -0
  197. package/dist/routes/integrations/components/connect-forms/useConnectedExternalIds.d.ts +4 -0
  198. package/dist/routes/integrations/components/connect-forms/useConnectedExternalIds.d.ts.map +1 -0
  199. package/dist/routes/integrations/components/connect-forms/useConnectedExternalIds.js +17 -0
  200. package/dist/routes/integrations/components/connect-forms/useWindowFocusPoll.d.ts +7 -0
  201. package/dist/routes/integrations/components/connect-forms/useWindowFocusPoll.d.ts.map +1 -0
  202. package/dist/routes/integrations/components/connect-forms/useWindowFocusPoll.js +18 -0
  203. package/dist/routes/integrations/connect-forms.d.ts +16 -0
  204. package/dist/routes/integrations/connect-forms.d.ts.map +1 -0
  205. package/dist/routes/integrations/connect-forms.js +14 -0
  206. package/dist/routes/integrations/filter-connected-providers.d.ts +3 -0
  207. package/dist/routes/integrations/filter-connected-providers.d.ts.map +1 -0
  208. package/dist/routes/integrations/filter-connected-providers.js +15 -0
  209. package/dist/routes/integrations/overview.d.ts +3 -0
  210. package/dist/routes/integrations/overview.d.ts.map +1 -0
  211. package/dist/routes/integrations/overview.js +2 -0
  212. package/dist/routes/integrations/use-connected-account-entities.d.ts +10 -0
  213. package/dist/routes/integrations/use-connected-account-entities.d.ts.map +1 -0
  214. package/dist/routes/integrations/use-connected-account-entities.js +29 -0
  215. package/dist/routes/memories/components/EmptyStates.d.ts.map +1 -1
  216. package/dist/routes/memories/components/EmptyStates.js +2 -1
  217. package/dist/routes/plans/components/ActionPlanPage.d.ts +1 -0
  218. package/dist/routes/plans/components/ActionPlanPage.d.ts.map +1 -1
  219. package/dist/routes/plans/components/ActionPlanPage.js +9 -5
  220. package/dist/routes/plans/components/actionPlansTableConfig.d.ts +12 -12
  221. package/dist/rules/datalog-ast/DatalogBodyFormulaComponent.d.ts.map +1 -1
  222. package/dist/rules/datalog-ast/DatalogBodyFormulaComponent.js +4 -1
  223. package/dist/rules/rule-narrative-aggregates.d.ts +1 -0
  224. package/dist/rules/rule-narrative-aggregates.d.ts.map +1 -1
  225. package/dist/rules/rule-narrative-aggregates.js +20 -0
  226. package/dist/rules/rule-narrative-context.d.ts.map +1 -1
  227. package/dist/rules/rule-narrative-context.js +3 -9
  228. package/dist/rules/rule-narrative-format.d.ts +1 -1
  229. package/dist/rules/rule-narrative.d.ts.map +1 -1
  230. package/dist/rules/rule-narrative.js +22 -7
  231. package/package.json +47 -8
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { withDatastoreQueryParam } from "@manta-eu/client/shared/datastore-path";
3
+ import { Link } from "#components/button/index";
4
+ import { useMantaClient } from "#providers/index";
5
+ const middleMouseButton = 1;
6
+ // Query param, not /d/<id> in the path: the provider's callback URL is fixed, and a prefixed
7
+ // start route isn't reliably reachable past the SW (vite.config.ts).
8
+ // useMantaClient(), not useActiveDatastore(): also covers an explicit datastoreId prop (embedded usage).
9
+ export function OAuthConnectLink(props) {
10
+ const { href, label, onOpened, variant = "primary" } = props;
11
+ const { datastoreId } = useMantaClient();
12
+ const scopedHref = withDatastoreQueryParam(href, datastoreId);
13
+ return (_jsx(Link, { href: scopedHref, variant: variant, onClick: onOpened, onAuxClick: (event) => {
14
+ if (event.button === middleMouseButton)
15
+ onOpened();
16
+ }, children: label }));
17
+ }
@@ -0,0 +1,45 @@
1
+ import { GQLGoogleSetupStateEnum, type GQLIntegration } from "@manta-eu/client";
2
+ import type { ConnectFormProps } from "./types.js";
3
+ import { type TreeMultiSelectProps, type TreeSelectItem } from "#components/tree-multi-select/index";
4
+ export type SetupRow = {
5
+ id: string;
6
+ };
7
+ export type SetupProgress<Row extends SetupRow> = {
8
+ state: GQLGoogleSetupStateEnum[];
9
+ rows?: Row[] | null;
10
+ lastError?: {
11
+ title?: string | null;
12
+ message: string;
13
+ } | null;
14
+ };
15
+ export type OAuthSetup<Row extends SetupRow> = {
16
+ progress?: SetupProgress<Row>;
17
+ refetchProgress: () => unknown;
18
+ resetProgress: () => void;
19
+ connect: (ids: string[]) => Promise<unknown>;
20
+ isConnecting: boolean;
21
+ };
22
+ export type SetupTreeOptions = Pick<TreeMultiSelectProps, "defaultCollapsed" | "includeDescendants">;
23
+ export type SetupCopy = {
24
+ providerName: string;
25
+ identityProviderName: string;
26
+ entitySingular: string;
27
+ entityPlural: string;
28
+ signInDescription: string;
29
+ pickTitle: string;
30
+ pickDescription: string;
31
+ noEntitiesLabel: string;
32
+ noneConnectableLabel: string;
33
+ retryGuidance?: string;
34
+ };
35
+ export type OAuthSetupConnectFormProps<Row extends SetupRow> = ConnectFormProps & {
36
+ integration: GQLIntegration;
37
+ oauthStartPath: string;
38
+ copy: SetupCopy;
39
+ setup: OAuthSetup<Row>;
40
+ treeItems: (rows: Row[], alreadyConnectedExternalIds: ReadonlySet<string>, reconnectableExternalIds: ReadonlySet<string>) => TreeSelectItem[];
41
+ treeOptions?: SetupTreeOptions;
42
+ resumesUnfinishedSetup?: boolean;
43
+ };
44
+ export declare function OAuthSetupConnectForm<Row extends SetupRow>(props: OAuthSetupConnectFormProps<Row>): import("react/jsx-runtime").JSX.Element;
45
+ //# sourceMappingURL=OAuthSetupConnectForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OAuthSetupConnectForm.d.ts","sourceRoot":"","sources":["../../../../../src/routes/integrations/components/connect-forms/OAuthSetupConnectForm.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAWhF,OAAO,KAAK,EAAE,gBAAgB,EAAgB,MAAM,SAAS,CAAC;AAM9D,OAAO,EAAmB,KAAK,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAKtH,MAAM,MAAM,QAAQ,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC,MAAM,MAAM,aAAa,CAAC,GAAG,SAAS,QAAQ,IAAI;IAChD,KAAK,EAAE,uBAAuB,EAAE,CAAC;IACjC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC/D,CAAC;AAGF,MAAM,MAAM,UAAU,CAAC,GAAG,SAAS,QAAQ,IAAI;IAC7C,QAAQ,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAC9B,eAAe,EAAE,MAAM,OAAO,CAAC;IAC/B,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,EAAE,kBAAkB,GAAG,oBAAoB,CAAC,CAAC;AAGrG,MAAM,MAAM,SAAS,GAAG;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAE7B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,0BAA0B,CAAC,GAAG,SAAS,QAAQ,IAAI,gBAAgB,GAAG;IAChF,WAAW,EAAE,cAAc,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;IACvB,SAAS,EAAE,CACT,IAAI,EAAE,GAAG,EAAE,EACX,2BAA2B,EAAE,WAAW,CAAC,MAAM,CAAC,EAChD,wBAAwB,EAAE,WAAW,CAAC,MAAM,CAAC,KAC1C,cAAc,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,GAAG,SAAS,QAAQ,EAAE,KAAK,EAAE,0BAA0B,CAAC,GAAG,CAAC,2CAmHjG"}
@@ -0,0 +1,136 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { GQLGoogleSetupStateEnum } from "@manta-eu/client";
3
+ import { parseError } from "@manta-eu/client/shared/error-utils";
4
+ import { isPresent } from "@manta-eu/lib/present";
5
+ import { ArrowLeft } from "lucide-react";
6
+ import { useEffect, useRef, useState } from "react";
7
+ import { toast } from "sonner";
8
+ import { match } from "ts-pattern";
9
+ import { ConnectFormHeader } from "./ConnectFormHeader.js";
10
+ import { ImportStartedNotice } from "./ImportStartedNotice.js";
11
+ import { activePhases, derivePhase, terminalStates } from "./oauth-setup-phase.js";
12
+ import { OAuthConnectLink } from "./OAuthConnectLink.js";
13
+ import { useConnectedExternalIds, useReconnectableExternalIds } from "./useConnectedExternalIds.js";
14
+ import { useWindowFocusPoll } from "./useWindowFocusPoll.js";
15
+ import { Banner } from "#components/banner/index";
16
+ import { Button } from "#components/button/index";
17
+ import { Loader } from "#components/loader/index";
18
+ import { TreeMultiSelect } from "#components/tree-multi-select/index";
19
+ import { cn } from "#lib/utils";
20
+ const pollIntervalMs = 3000;
21
+ export function OAuthSetupConnectForm(props) {
22
+ const { onBack, onChanged, onDismiss, provider, resumedFromOAuth = false, importNotice } = props;
23
+ const { integration, oauthStartPath, copy, setup, treeItems, treeOptions, resumesUnfinishedSetup } = props;
24
+ const { providerName } = copy;
25
+ const [hasStartedOAuth, setHasStartedOAuth] = useState(resumedFromOAuth);
26
+ const [hasSeenActiveState, setHasSeenActiveState] = useState(resumedFromOAuth);
27
+ const [selectedIds, setSelectedIds] = useState(new Set());
28
+ const hasDismissedRef = useRef(false);
29
+ const states = setup.progress?.state;
30
+ const phase = derivePhase({ states, hasStartedOAuth, hasSeenActiveState, resumesUnfinishedSetup });
31
+ useWindowFocusPoll(setup.refetchProgress, { enabled: activePhases.includes(phase), intervalMs: pollIntervalMs });
32
+ const alreadyConnectedExternalIds = useConnectedExternalIds(integration);
33
+ const reconnectableExternalIds = useReconnectableExternalIds(integration);
34
+ useEffect(() => {
35
+ if (!isPresent(states))
36
+ return;
37
+ const isActive = states.some((state) => !terminalStates.includes(state) && state !== GQLGoogleSetupStateEnum.NotFound);
38
+ if (isActive)
39
+ setHasSeenActiveState(true);
40
+ }, [states]);
41
+ useEffect(() => {
42
+ if (phase !== "done" || hasDismissedRef.current)
43
+ return;
44
+ hasDismissedRef.current = true;
45
+ toast.success(`${providerName} connected`);
46
+ onChanged();
47
+ if (!importNotice)
48
+ onDismiss();
49
+ }, [phase, onChanged, onDismiss, providerName, importNotice]);
50
+ function handleOpened() {
51
+ setup.resetProgress();
52
+ setHasSeenActiveState(false);
53
+ setHasStartedOAuth(true);
54
+ }
55
+ function toggleId(id, checked) {
56
+ setSelectedIds((current) => {
57
+ const next = new Set(current);
58
+ if (checked)
59
+ next.add(id);
60
+ else
61
+ next.delete(id);
62
+ return next;
63
+ });
64
+ }
65
+ async function handleSubmit() {
66
+ if (selectedIds.size === 0)
67
+ return;
68
+ try {
69
+ await setup.connect([...selectedIds]);
70
+ await setup.refetchProgress();
71
+ }
72
+ catch (err) {
73
+ const info = parseError(err, `Failed to connect ${providerName}`);
74
+ toast.error(info.message, { description: info.description });
75
+ }
76
+ }
77
+ function handleRetry() {
78
+ setSelectedIds(new Set());
79
+ hasDismissedRef.current = false;
80
+ setup.resetProgress();
81
+ setHasStartedOAuth(false);
82
+ setHasSeenActiveState(false);
83
+ }
84
+ return (_jsxs("div", { className: "grid gap-6", children: [_jsx(ConnectFormHeader, { provider: provider, status: phase === "done" ? "Connected" : "Not connected" }), _jsx("div", { className: "min-h-40", children: match(phase)
85
+ .with("idle", () => _jsx(IdleView, { copy: copy, oauthStartPath: oauthStartPath, onOpened: handleOpened }))
86
+ .with("awaitingOAuth", () => _jsx(AwaitingOAuthView, { copy: copy }))
87
+ .with("loadingAccounts", () => _jsx(LoadingEntitiesView, { copy: copy }))
88
+ .with("pickingAccount", () => (_jsx(PickingEntityView, { copy: copy, items: treeItems(setup.progress?.rows ?? [], alreadyConnectedExternalIds, reconnectableExternalIds), selectedIds: selectedIds, onToggle: toggleId, treeOptions: treeOptions })))
89
+ .with("submitting", () => _jsx(SubmittingView, { copy: copy }))
90
+ .with("done", () => _jsx(DoneView, { copy: copy, importNotice: importNotice }))
91
+ .with("failed", () => (_jsx(FailedView, { copy: copy, title: setup.progress?.lastError?.title, message: setup.progress?.lastError?.message, onRetry: handleRetry })))
92
+ .exhaustive() }), _jsxs("div", { className: cn("flex items-center pt-2", phase === "done" ? "justify-end" : "justify-between"), children: [phase !== "done" && (_jsx(Button, { variant: "tertiary", onClick: onBack, icon: ArrowLeft, children: "Back" })), phase === "pickingAccount" && (_jsx(Button, { onClick: () => void handleSubmit(), disabled: selectedIds.size === 0, isLoading: setup.isConnecting, children: selectedIds.size > 1
93
+ ? `Connect ${selectedIds.size} ${copy.entityPlural}`
94
+ : `Connect ${copy.entitySingular}` })), phase === "done" && importNotice && _jsx(Button, { onClick: onDismiss, children: "Done" })] })] }));
95
+ }
96
+ function IdleView(props) {
97
+ const { copy, oauthStartPath, onOpened } = props;
98
+ return (_jsxs("div", { className: "grid gap-4", children: [_jsxs("div", { className: "grid gap-1", children: [_jsxs("h2", { className: "typography-large-body-semibold text-default-foreground", children: ["Sign in with ", copy.identityProviderName] }), _jsx("p", { className: "typography-caption text-muted-foreground", children: copy.signInDescription })] }), _jsx(OAuthConnectLink, { href: oauthStartPath, label: `Continue with ${copy.identityProviderName}`, onOpened: onOpened })] }));
99
+ }
100
+ function AwaitingOAuthView(props) {
101
+ const { copy } = props;
102
+ return (_jsxs("div", { className: "grid gap-4", children: [_jsxs("div", { className: "grid gap-1", children: [_jsxs("h2", { className: "typography-large-body-semibold text-default-foreground", children: ["Waiting for ", copy.identityProviderName, " sign-in"] }), _jsxs("p", { className: "typography-caption text-muted-foreground", children: ["Finish signing in to ", copy.identityProviderName, ". We'll pick it up automatically when you come back."] })] }), _jsx(StatusLine, { label: "Listening for the connection\u2026" })] }));
103
+ }
104
+ function LoadingEntitiesView(props) {
105
+ const { copy } = props;
106
+ return (_jsxs("div", { className: "grid gap-4", children: [_jsxs("div", { className: "grid gap-1", children: [_jsxs("h2", { className: "typography-large-body-semibold text-default-foreground", children: ["Loading your ", copy.providerName, " ", copy.entityPlural] }), _jsx("p", { className: "typography-caption text-muted-foreground", children: "This usually takes a few seconds." })] }), _jsx(StatusLine, { label: `Fetching ${copy.entityPlural}…` })] }));
107
+ }
108
+ function PickingEntityView(props) {
109
+ const { copy, items, selectedIds, onToggle, treeOptions } = props;
110
+ if (!isPresent(items)) {
111
+ return _jsx(Banner, { type: "warning", label: copy.noEntitiesLabel });
112
+ }
113
+ const selectableCount = items.filter((item) => item.selectable && item.disabled !== true).length;
114
+ if (selectableCount === 0) {
115
+ return _jsx(Banner, { type: "info", label: copy.noneConnectableLabel });
116
+ }
117
+ return (_jsxs("div", { className: "grid gap-4", children: [_jsxs("div", { className: "grid gap-1", children: [_jsx("h2", { className: "typography-large-body-semibold text-default-foreground", children: copy.pickTitle }), _jsx("p", { className: "typography-caption text-muted-foreground", children: copy.pickDescription })] }), _jsx(TreeMultiSelect, { items: items, selectedIds: selectedIds, onToggle: onToggle, searchPlaceholder: `Search ${copy.entityPlural}...`, ...treeOptions })] }));
118
+ }
119
+ function SubmittingView(props) {
120
+ const { copy } = props;
121
+ return (_jsxs("div", { className: "grid gap-4", children: [_jsxs("div", { className: "grid gap-1", children: [_jsxs("h2", { className: "typography-large-body-semibold text-default-foreground", children: ["Connecting your ", copy.entityPlural] }), _jsx("p", { className: "typography-caption text-muted-foreground", children: "Hold tight \u2014 this usually takes a few seconds." })] }), _jsx(StatusLine, { label: "Provisioning\u2026" })] }));
122
+ }
123
+ function DoneView(props) {
124
+ const { copy, importNotice } = props;
125
+ if (importNotice)
126
+ return _jsx(ImportStartedNotice, { providerName: copy.providerName, notice: importNotice });
127
+ return (_jsxs("div", { className: "grid gap-1", children: [_jsxs("h2", { className: "typography-large-body-semibold text-default-foreground", children: [copy.providerName, " connected"] }), _jsx("p", { className: "typography-caption text-muted-foreground", children: "Closing this dialog\u2026" })] }));
128
+ }
129
+ function FailedView(props) {
130
+ const { copy, title, message, onRetry } = props;
131
+ return (_jsxs("div", { className: "grid gap-4", children: [_jsx(Banner, { type: "error", size: "loose", label: title ?? `${copy.providerName} connection failed`, description: message ?? undefined }), isPresent(copy.retryGuidance) ? (_jsx("p", { className: "typography-caption text-muted-foreground", children: copy.retryGuidance })) : (_jsx(Button, { onClick: onRetry, children: "Try again" }))] }));
132
+ }
133
+ function StatusLine(props) {
134
+ const { label } = props;
135
+ return (_jsxs("div", { className: "flex items-center gap-2 text-muted-foreground typography-caption", role: "status", "aria-live": "polite", children: [_jsx(Loader, { className: "size-4", "aria-hidden": true }), " ", label] }));
136
+ }
@@ -0,0 +1,23 @@
1
+ import { type GQLIntegration } from "@manta-eu/client";
2
+ import type { ReactNode } from "react";
3
+ import type { ConnectFormProps } from "./types.js";
4
+ export type ConnectSuccessStep = {
5
+ title: string;
6
+ description: string;
7
+ content: ReactNode;
8
+ };
9
+ export type OAuthSingleAccountConnectFormProps = ConnectFormProps & {
10
+ integration: GQLIntegration;
11
+ startHref: string;
12
+ ctaLabel: string;
13
+ stepTitle: string;
14
+ stepDescription: string;
15
+ supportingInfo: string;
16
+ permissions: string[];
17
+ waitingLabel: string;
18
+ connectedToastLabel: string;
19
+ successStep?: ConnectSuccessStep;
20
+ precedingSteps?: number;
21
+ };
22
+ export declare function OAuthSingleAccountConnectForm(props: OAuthSingleAccountConnectFormProps): import("react/jsx-runtime").JSX.Element;
23
+ //# sourceMappingURL=OAuthSingleAccountConnectForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OAuthSingleAccountConnectForm.d.ts","sourceRoot":"","sources":["../../../../../src/routes/integrations/components/connect-forms/OAuthSingleAccountConnectForm.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6D,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAKhD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG,gBAAgB,GAAG;IAClE,WAAW,EAAE,cAAc,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IAEjC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAQF,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,kCAAkC,2CA2ItF"}
@@ -0,0 +1,63 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useConnectedAccountsQuery } from "@manta-eu/client";
3
+ import { isPresent } from "@manta-eu/lib/present";
4
+ import { InfoIcon } from "lucide-react";
5
+ import { useEffect, useRef, useState } from "react";
6
+ import { toast } from "sonner";
7
+ import { ConnectWizardShell } from "./ConnectWizardShell.js";
8
+ import { importStartedSuccessStep } from "./ImportStartedNotice.js";
9
+ import { OAuthConnectLink } from "./OAuthConnectLink.js";
10
+ import { useWindowFocusPoll } from "./useWindowFocusPoll.js";
11
+ import { Button } from "#components/button/index";
12
+ import { useMantaClient } from "#providers/index";
13
+ function connectedExternalIds(data, integration) {
14
+ return (data?.connectedAccounts ?? [])
15
+ .filter((account) => account.integration === integration)
16
+ .map((account) => account.externalId);
17
+ }
18
+ export function OAuthSingleAccountConnectForm(props) {
19
+ const { onBack, onChanged, onDismiss, provider, integration, startHref, ctaLabel, stepTitle, stepDescription, supportingInfo, permissions, waitingLabel, connectedToastLabel, successStep: explicitSuccessStep, importNotice, resumedFromOAuth = false, precedingSteps = 0, } = props;
20
+ const successStep = explicitSuccessStep ?? (importNotice ? importStartedSuccessStep(provider.name, importNotice) : undefined);
21
+ const { mantaClient } = useMantaClient();
22
+ const hasSuccessStep = successStep !== undefined;
23
+ const totalSteps = precedingSteps + (hasSuccessStep ? 2 : 1);
24
+ const [waiting, setWaiting] = useState(resumedFromOAuth && hasSuccessStep);
25
+ const [connected, setConnected] = useState(false);
26
+ const knownExternalIds = useRef(new Set());
27
+ const settled = useRef(false);
28
+ const { data, error, refetch } = useConnectedAccountsQuery(mantaClient, undefined, { enabled: false });
29
+ useEffect(() => {
30
+ void refetch();
31
+ }, [refetch]);
32
+ useWindowFocusPoll(refetch, { enabled: waiting });
33
+ useEffect(() => {
34
+ if (!waiting || settled.current)
35
+ return;
36
+ const connected = connectedExternalIds(data, integration).some((id) => !knownExternalIds.current.has(id));
37
+ if (!connected)
38
+ return;
39
+ settled.current = true;
40
+ setWaiting(false);
41
+ toast.success(connectedToastLabel);
42
+ onChanged();
43
+ if (hasSuccessStep) {
44
+ setConnected(true);
45
+ }
46
+ else {
47
+ onDismiss();
48
+ }
49
+ }, [waiting, data, integration, connectedToastLabel, onChanged, onDismiss, hasSuccessStep]);
50
+ function handleOpened() {
51
+ knownExternalIds.current = new Set(connectedExternalIds(data, integration));
52
+ setWaiting(true);
53
+ }
54
+ const accountConnected = isPresent(connectedExternalIds(data, integration));
55
+ const resumeUnanswered = resumedFromOAuth && hasSuccessStep && data === undefined && !isPresent(error);
56
+ if (successStep && (connected || (resumedFromOAuth && accountConnected))) {
57
+ return (_jsx(ConnectWizardShell, { provider: provider, status: "Connected", totalSteps: totalSteps, currentStep: precedingSteps + 2, stepTitle: successStep.title, stepDescription: successStep.description, primaryAction: _jsx(Button, { variant: "secondary", onClick: onDismiss, children: "Done" }), children: successStep.content }));
58
+ }
59
+ if (successStep && resumeUnanswered) {
60
+ return (_jsx(ConnectWizardShell, { provider: provider, status: "Checking", totalSteps: totalSteps, currentStep: precedingSteps + 2, stepTitle: successStep.title, primaryAction: _jsx(Button, { variant: "secondary", disabled: true, children: "Done" }), children: _jsx("p", { className: "typography-caption text-muted-foreground", role: "status", "aria-live": "polite", children: "Confirming the connection\u2026" }) }));
61
+ }
62
+ return (_jsx(ConnectWizardShell, { provider: provider, totalSteps: totalSteps, currentStep: precedingSteps + 1, stepTitle: stepTitle, stepDescription: stepDescription, supportingInfo: _jsxs("div", { className: "rounded-xl bg-info p-3 flex items-start gap-2 typography-small", children: [_jsx(InfoIcon, { size: 20, className: "shrink-0 mt-0.5 text-info-foreground" }), _jsx("p", { className: "text-muted-foreground", children: supportingInfo })] }), onBack: onBack, primaryAction: _jsx(OAuthConnectLink, { href: startHref, label: ctaLabel, onOpened: handleOpened }), children: _jsxs("div", { className: "grid gap-2", children: [_jsx("p", { className: "typography-small text-default-foreground", children: "Manta will be able to:" }), _jsx("ul", { className: "grid gap-1.5", children: permissions.map((permission) => (_jsxs("li", { className: "flex items-start gap-2 typography-caption text-muted-foreground", children: [_jsx("span", { "aria-hidden": true, className: "mt-2 size-1.5 shrink-0 rounded-full bg-muted-foreground" }), permission] }, permission))) }), waiting && (_jsx("p", { className: "typography-caption text-muted-foreground", role: "status", "aria-live": "polite", children: waitingLabel }))] }) }));
63
+ }
@@ -0,0 +1,3 @@
1
+ import type { ConnectFormProps } from "./types.js";
2
+ export declare function ShopifyConnectForm(props: ConnectFormProps): import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=ShopifyConnectForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShopifyConnectForm.d.ts","sourceRoot":"","sources":["../../../../../src/routes/integrations/components/connect-forms/ShopifyConnectForm.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAWhD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,2CAezD"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { GQLIntegration } from "@manta-eu/client";
3
+ import { OAuthSingleAccountConnectForm } from "./OAuthSingleAccountConnectForm.js";
4
+ const shopifyPermissions = [
5
+ "Read your orders, including historical ones.",
6
+ "Read your products, variants, and collections.",
7
+ "Read your customers and their contact details.",
8
+ "Read your inventory, locations, and sales channels.",
9
+ ];
10
+ // No shop is passed: Shopify App Store requirement 2.3.1 forbids asking a merchant to type
11
+ // their store domain, so the start request omits it and Shopify picks the store instead.
12
+ export function ShopifyConnectForm(props) {
13
+ return (_jsx(OAuthSingleAccountConnectForm, { ...props, integration: GQLIntegration.Shopify, startHref: "/oauth/shopify/start", ctaLabel: "Continue with Shopify", stepTitle: "Connect your Shopify store", stepDescription: "Shopify will ask which store to connect, then bring you back here.", supportingInfo: "You'll be taken to Shopify to pick a store and approve access. You can revoke it any time from your Shopify admin.", permissions: shopifyPermissions, waitingLabel: "Waiting for you to finish connecting to Shopify\u2026", connectedToastLabel: "Shopify connected" }));
14
+ }
@@ -0,0 +1,3 @@
1
+ import type { ConnectFormProps } from "./types.js";
2
+ export declare function SlackConnectForm(props: ConnectFormProps): import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=SlackConnectForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SlackConnectForm.d.ts","sourceRoot":"","sources":["../../../../../src/routes/integrations/components/connect-forms/SlackConnectForm.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAOhD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,2CAevD"}
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { GQLIntegration } from "@manta-eu/client";
3
+ import { OAuthSingleAccountConnectForm } from "./OAuthSingleAccountConnectForm.js";
4
+ const slackPermissions = [
5
+ "Read messages and channel activity you grant access to.",
6
+ "Post updates, reports, and alerts to the channels you choose.",
7
+ ];
8
+ export function SlackConnectForm(props) {
9
+ return (_jsx(OAuthSingleAccountConnectForm, { ...props, integration: GQLIntegration.Slack, startHref: "/oauth/slack/start", ctaLabel: "Continue with Slack", stepTitle: "Connect your Slack workspace", stepDescription: "Manta will take you to Slack to ask for permission, then bring you back here.", supportingInfo: "You'll be taken to Slack to approve access. You can revoke it any time from your Slack workspace settings.", permissions: slackPermissions, waitingLabel: "Waiting for you to finish connecting to Slack\u2026", connectedToastLabel: "Slack connected" }));
10
+ }
@@ -0,0 +1,5 @@
1
+ import { type InferalCredentialFormConfig } from "./InferalCredentialConnectForm.js";
2
+ import type { ConnectFormProps } from "./types.js";
3
+ export declare const triplewhaleConfig: InferalCredentialFormConfig<"shopId" | "apiKey">;
4
+ export declare function TriplewhaleConnectForm(props: ConnectFormProps): import("react/jsx-runtime").JSX.Element;
5
+ //# sourceMappingURL=TriplewhaleConnectForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TriplewhaleConnectForm.d.ts","sourceRoot":"","sources":["../../../../../src/routes/integrations/components/connect-forms/TriplewhaleConnectForm.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAChH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,eAAO,MAAM,iBAAiB,EAAE,2BAA2B,CAAC,QAAQ,GAAG,QAAQ,CA6B9E,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,gBAAgB,2CAE7D"}
@@ -0,0 +1,35 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { InferalCredentialConnectForm } from "./InferalCredentialConnectForm.js";
3
+ export const triplewhaleConfig = {
4
+ providerName: "Triple Whale",
5
+ fieldIdPrefix: "triplewhale",
6
+ identifier: {
7
+ key: "shopId",
8
+ label: "Shop ID",
9
+ placeholder: "Your Triple Whale shop ID",
10
+ requiredMessage: "Shop ID is required",
11
+ stepTitle: "Find your Triple Whale shop ID",
12
+ stepDescription: "We use this to identify your store inside Triple Whale.",
13
+ },
14
+ secrets: {
15
+ title: "Generate an API key",
16
+ description: "Manta needs read access to Summary Page and Pixel Attribution.",
17
+ fields: [
18
+ {
19
+ key: "apiKey",
20
+ label: "API key",
21
+ placeholder: "Paste your API key",
22
+ requiredMessage: "API key is required",
23
+ secret: true,
24
+ },
25
+ ],
26
+ },
27
+ streamNamePlaceholder: "abc-store",
28
+ locationStepDescription: "Pick the region closest to your store for the lowest latency.",
29
+ buildProviderInput: (credentials) => ({
30
+ triplewhale: { shopId: credentials.shopId, apiKey: credentials.apiKey },
31
+ }),
32
+ };
33
+ export function TriplewhaleConnectForm(props) {
34
+ return _jsx(InferalCredentialConnectForm, { ...props, config: triplewhaleConfig });
35
+ }
@@ -0,0 +1,5 @@
1
+ import { type InferalCredentialFormConfig } from "./InferalCredentialConnectForm.js";
2
+ import type { ConnectFormProps } from "./types.js";
3
+ export declare const woocommerceConfig: InferalCredentialFormConfig<"sourceUrl" | "consumerKey" | "consumerSecret">;
4
+ export declare function WoocommerceConnectForm(props: ConnectFormProps): import("react/jsx-runtime").JSX.Element;
5
+ //# sourceMappingURL=WoocommerceConnectForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WoocommerceConnectForm.d.ts","sourceRoot":"","sources":["../../../../../src/routes/integrations/components/connect-forms/WoocommerceConnectForm.tsx"],"names":[],"mappings":"AACA,OAAO,EAAgC,KAAK,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAChH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,eAAO,MAAM,iBAAiB,EAAE,2BAA2B,CAAC,WAAW,GAAG,aAAa,GAAG,gBAAgB,CAwCzG,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,gBAAgB,2CAE7D"}
@@ -0,0 +1,47 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { ensureProtocol } from "@manta-eu/lib/url";
3
+ import { InferalCredentialConnectForm } from "./InferalCredentialConnectForm.js";
4
+ export const woocommerceConfig = {
5
+ providerName: "WooCommerce",
6
+ fieldIdPrefix: "woocommerce",
7
+ identifier: {
8
+ key: "sourceUrl",
9
+ label: "Site URL",
10
+ placeholder: "https://shop.example.com",
11
+ requiredMessage: "Site URL is required",
12
+ stepTitle: "Point Manta at your WooCommerce store",
13
+ stepDescription: "We use your site URL to identify which store this integration belongs to.",
14
+ },
15
+ secrets: {
16
+ title: "Generate a REST API key pair",
17
+ description: "Manta needs Read / Write access to sync orders, customers, and products from your WooCommerce store.",
18
+ fields: [
19
+ {
20
+ key: "consumerKey",
21
+ label: "Consumer key",
22
+ placeholder: "ck_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
23
+ requiredMessage: "Consumer key is required",
24
+ secret: true,
25
+ },
26
+ {
27
+ key: "consumerSecret",
28
+ label: "Consumer secret",
29
+ placeholder: "cs_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
30
+ requiredMessage: "Consumer secret is required",
31
+ secret: true,
32
+ },
33
+ ],
34
+ },
35
+ streamNamePlaceholder: "woocommerce-shopexamplecom",
36
+ locationStepDescription: "Pick the region closest to your store for the lowest latency.",
37
+ buildProviderInput: (credentials) => ({
38
+ woocommerce: {
39
+ sourceUrl: ensureProtocol(credentials.sourceUrl),
40
+ consumerKey: credentials.consumerKey,
41
+ consumerSecret: credentials.consumerSecret,
42
+ },
43
+ }),
44
+ };
45
+ export function WoocommerceConnectForm(props) {
46
+ return _jsx(InferalCredentialConnectForm, { ...props, config: woocommerceConfig });
47
+ }
@@ -0,0 +1,13 @@
1
+ import type { DataConnectorType } from "../../types.js";
2
+ import type { ConnectorField } from "./data-connection-fields.js";
3
+ export type ConnectionStringResult = {
4
+ ok: true;
5
+ values: Record<string, string>;
6
+ notice?: string;
7
+ } | {
8
+ ok: false;
9
+ error: string;
10
+ };
11
+ export declare function acceptsConnectionString(connectorType: string): connectorType is DataConnectorType;
12
+ export declare function connectionStringValues(connectorType: string, input: string, fields: readonly ConnectorField[]): ConnectionStringResult;
13
+ //# sourceMappingURL=connection-string-fields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-string-fields.d.ts","sourceRoot":"","sources":["../../../../../src/routes/integrations/components/connect-forms/connection-string-fields.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,MAAM,MAAM,sBAAsB,GAC9B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAYjC,wBAAgB,uBAAuB,CAAC,aAAa,EAAE,MAAM,GAAG,aAAa,IAAI,iBAAiB,CAEjG;AAED,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,SAAS,cAAc,EAAE,GAChC,sBAAsB,CAiBxB"}
@@ -0,0 +1,110 @@
1
+ import { parseConnectionString, unescapeBracedValue } from "@manta-eu/lib/connection-string";
2
+ import { isPresent } from "@manta-eu/lib/present";
3
+ export function acceptsConnectionString(connectorType) {
4
+ return Object.hasOwn(formats, connectorType);
5
+ }
6
+ export function connectionStringValues(connectorType, input, fields) {
7
+ if (!acceptsConnectionString(connectorType)) {
8
+ return { ok: false, error: "This connector does not accept a connection string." };
9
+ }
10
+ const format = formats[connectorType];
11
+ const parsed = parseConnectionString(input, { semicolonProperties: format.semicolonProperties });
12
+ if (!parsed)
13
+ return { ok: false, error: unreadableError(connectorType, input, format.schemes) };
14
+ if (!format.schemes.includes(parsed.scheme))
15
+ return { ok: false, error: schemeHint(format.schemes) };
16
+ const mapped = format.toValues(parsed);
17
+ if ("error" in mapped)
18
+ return { ok: false, error: mapped.error };
19
+ const values = formValues(mapped.values, fields);
20
+ if (!isPresent(values))
21
+ return { ok: false, error: "The connection string holds no value for this form." };
22
+ return mapped.notice ? { ok: true, values, notice: mapped.notice } : { ok: true, values };
23
+ }
24
+ const formats = {
25
+ postgres: urlFormat("postgres", "postgresql"),
26
+ redshift: urlFormat("redshift", "postgres", "postgresql"),
27
+ mysql: urlFormat("mysql", "mariadb"),
28
+ mariadb: urlFormat("mariadb", "mysql"),
29
+ clickhouse: urlFormat("clickhouse"),
30
+ snowflake: { schemes: ["snowflake"], toValues: snowflakeValues },
31
+ sqlserver: { schemes: ["sqlserver", "mssql"], semicolonProperties: true, toValues: sqlServerValues },
32
+ bigquery: { schemes: ["bigquery"], semicolonProperties: true, toValues: bigQueryValues },
33
+ };
34
+ function urlFormat(...schemes) {
35
+ return { schemes, toValues: (parsed) => ({ values: urlValues(parsed) }) };
36
+ }
37
+ function urlValues(parsed) {
38
+ const { host, port, username, password, path, params } = parsed;
39
+ return { ...lowerCaseNames(params), host, port, username, password, database: path[0] };
40
+ }
41
+ function lowerCaseNames(params) {
42
+ return Object.fromEntries(Object.entries(params).map(([name, value]) => [name.toLowerCase(), value]));
43
+ }
44
+ function snowflakeValues(parsed) {
45
+ return { values: { ...urlValues(parsed), schema: parsed.path[1] } };
46
+ }
47
+ const namedInstanceError = "Use host:port or ;instanceName= instead of host\\instance.";
48
+ function sqlServerValues(parsed) {
49
+ const read = sqlServerPropertyReader(parsed.params);
50
+ const host = parsed.host ?? read("serverName");
51
+ if (host?.includes("\\"))
52
+ return { error: namedInstanceError };
53
+ const port = parsed.port ?? read("portNumber", "port");
54
+ return {
55
+ values: {
56
+ host,
57
+ port,
58
+ instance: isPresent(port) ? undefined : read("instanceName"),
59
+ username: parsed.username ?? read("user", "userName"),
60
+ password: parsed.password ?? read("password"),
61
+ database: parsed.path[0] ?? read("databaseName", "database"),
62
+ encrypt: booleanValue(read("encrypt")),
63
+ trust_server_certificate: booleanValue(read("trustServerCertificate")),
64
+ },
65
+ };
66
+ }
67
+ function sqlServerPropertyReader(params) {
68
+ const read = propertyReader(params);
69
+ return (...names) => {
70
+ const value = read(...names);
71
+ return value === undefined ? undefined : unescapeBracedValue(value);
72
+ };
73
+ }
74
+ // JDBC property names are case-insensitive, so the lookup lowers the case of each name.
75
+ function propertyReader(params) {
76
+ const valueByName = new Map(Object.entries(lowerCaseNames(params)));
77
+ return (...names) => names.map((name) => valueByName.get(name.toLowerCase())).find(isPresent);
78
+ }
79
+ function booleanValue(value) {
80
+ const lowered = value?.toLowerCase();
81
+ return lowered === "true" || lowered === "false" ? lowered : undefined;
82
+ }
83
+ const keyFileNotice = "Paste the service account key into the key field. The browser cannot read a key file.";
84
+ function bigQueryValues(parsed) {
85
+ const read = propertyReader(parsed.params);
86
+ const key = read("OAuthPvtKey");
87
+ const inlineKey = key?.trimStart().startsWith("{") ? key : undefined;
88
+ const pointsToKeyFile = isPresent(read("OAuthPvtKeyPath")) || (isPresent(key) && inlineKey === undefined);
89
+ return {
90
+ values: {
91
+ project: read("ProjectId"),
92
+ dataset: read("DefaultDataset"),
93
+ location: read("Location"),
94
+ key_body: inlineKey,
95
+ },
96
+ notice: pointsToKeyFile ? keyFileNotice : undefined,
97
+ };
98
+ }
99
+ function unreadableError(connectorType, input, schemes) {
100
+ return connectorType === "sqlserver" && input.includes("\\") ? namedInstanceError : schemeHint(schemes);
101
+ }
102
+ function schemeHint(schemes) {
103
+ return `Paste a ${schemes.map((scheme) => `${scheme}://`).join(" or ")} connection string.`;
104
+ }
105
+ function formValues(values, fields) {
106
+ return Object.fromEntries(fields.flatMap((field) => {
107
+ const value = values[field.key];
108
+ return isPresent(value) ? [[field.key, value]] : [];
109
+ }));
110
+ }
@@ -0,0 +1,6 @@
1
+ import { type TreeNode, type TreeSelectItem } from "#components/tree-multi-select/index";
2
+ export type DashFolder = TreeNode & {
3
+ position?: number | null;
4
+ };
5
+ export declare function dashFolderTreeItems(folders: DashFolder[]): TreeSelectItem[];
6
+ //# sourceMappingURL=dash-folder-tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dash-folder-tree.d.ts","sourceRoot":"","sources":["../../../../../src/routes/integrations/components/connect-forms/dash-folder-tree.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAEtH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAQjE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,cAAc,EAAE,CAO3E"}
@@ -0,0 +1,14 @@
1
+ import { buildTreeRows, compareNodes } from "#components/tree-multi-select/index";
2
+ // Siblings in Dash's own order; a folder without a position goes last.
3
+ function compareFolders(a, b) {
4
+ const unpositioned = Number.MAX_SAFE_INTEGER;
5
+ return (a.position ?? unpositioned) - (b.position ?? unpositioned) || compareNodes(a, b);
6
+ }
7
+ export function dashFolderTreeItems(folders) {
8
+ return buildTreeRows(folders, compareFolders).map(({ node, depth }) => ({
9
+ id: node.id,
10
+ label: node.name ?? node.id,
11
+ selectable: true,
12
+ depth,
13
+ }));
14
+ }