@manta-eu/react 0.2.1 → 0.4.0

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 (187) hide show
  1. package/dist/components/datastore-management/tree.d.ts +1 -1
  2. package/dist/components/datastore-management/tree.d.ts.map +1 -1
  3. package/dist/components/datastore-management/tree.js +5 -5
  4. package/dist/components/datastore-management/tree.js.map +1 -1
  5. package/dist/components/explain-fact/ExplainFact.js +3 -3
  6. package/dist/components/explain-fact/ExplainFact.js.map +1 -1
  7. package/dist/components/planning/plan-detail-utils.d.ts.map +1 -1
  8. package/dist/components/planning/plan-detail-utils.js +4 -0
  9. package/dist/components/planning/plan-detail-utils.js.map +1 -1
  10. package/dist/components/tool-invocation-card/ListRulesResultDisplay.d.ts +2 -2
  11. package/dist/components/tool-invocation-card/ListRulesResultDisplay.d.ts.map +1 -1
  12. package/dist/components/tool-invocation-card/ToolOutputRenderer.d.ts.map +1 -1
  13. package/dist/components/tool-invocation-card/ToolOutputRenderer.js +7 -4
  14. package/dist/components/tool-invocation-card/ToolOutputRenderer.js.map +1 -1
  15. package/dist/components/tool-invocation-card/types.d.ts +5 -5
  16. package/dist/components/tool-invocation-card/types.d.ts.map +1 -1
  17. package/dist/components/tool-invocation-card/types.js +5 -5
  18. package/dist/components/tool-invocation-card/types.js.map +1 -1
  19. package/dist/explain-fact/rule-presentation.js +2 -2
  20. package/dist/explain-fact/rule-presentation.js.map +1 -1
  21. package/dist/explain-fact/tree-model.js +2 -2
  22. package/dist/explain-fact/tree-model.js.map +1 -1
  23. package/dist/graph/EntityCard.d.ts.map +1 -1
  24. package/dist/graph/EntityCard.js +2 -1
  25. package/dist/graph/EntityCard.js.map +1 -1
  26. package/dist/graph/EntityViewWithLinks.d.ts +7 -0
  27. package/dist/graph/EntityViewWithLinks.d.ts.map +1 -0
  28. package/dist/graph/EntityViewWithLinks.js +28 -0
  29. package/dist/graph/EntityViewWithLinks.js.map +1 -0
  30. package/dist/graph/card-links.d.ts +19 -0
  31. package/dist/graph/card-links.d.ts.map +1 -0
  32. package/dist/graph/card-links.js +23 -0
  33. package/dist/graph/card-links.js.map +1 -0
  34. package/dist/graph/nodes/BrandAssetAnalysisView.d.ts.map +1 -1
  35. package/dist/graph/nodes/BrandAssetAnalysisView.js +1 -1
  36. package/dist/graph/nodes/BrandAssetAnalysisView.js.map +1 -1
  37. package/dist/graph/nodes/BrandFontSuggestionView.d.ts.map +1 -1
  38. package/dist/graph/nodes/BrandFontSuggestionView.js +1 -1
  39. package/dist/graph/nodes/BrandFontSuggestionView.js.map +1 -1
  40. package/dist/graph/nodes/EntityCardShell.d.ts +2 -0
  41. package/dist/graph/nodes/EntityCardShell.d.ts.map +1 -1
  42. package/dist/graph/nodes/EntityCardShell.js +13 -3
  43. package/dist/graph/nodes/EntityCardShell.js.map +1 -1
  44. package/dist/graph/nodes/NodePropertyTable.d.ts +2 -1
  45. package/dist/graph/nodes/NodePropertyTable.d.ts.map +1 -1
  46. package/dist/graph/nodes/NodePropertyTable.js +10 -1
  47. package/dist/graph/nodes/NodePropertyTable.js.map +1 -1
  48. package/dist/graph/nodes/node-property-display.d.ts +0 -1
  49. package/dist/graph/nodes/node-property-display.d.ts.map +1 -1
  50. package/dist/graph/nodes/node-property-display.js +2 -6
  51. package/dist/graph/nodes/node-property-display.js.map +1 -1
  52. package/dist/graph/special-nodes/AttributeList.d.ts.map +1 -1
  53. package/dist/graph/special-nodes/AttributeList.js +3 -2
  54. package/dist/graph/special-nodes/AttributeList.js.map +1 -1
  55. package/dist/graph/special-nodes/RelatedSection.d.ts +6 -0
  56. package/dist/graph/special-nodes/RelatedSection.d.ts.map +1 -0
  57. package/dist/graph/special-nodes/RelatedSection.js +16 -0
  58. package/dist/graph/special-nodes/RelatedSection.js.map +1 -0
  59. package/dist/graph/special-nodes/card-facts.d.ts +2 -0
  60. package/dist/graph/special-nodes/card-facts.d.ts.map +1 -1
  61. package/dist/graph/special-nodes/card-facts.js +11 -0
  62. package/dist/graph/special-nodes/card-facts.js.map +1 -1
  63. package/dist/graph/types.d.ts +2 -2
  64. package/dist/graph/types.d.ts.map +1 -1
  65. package/dist/hooks/use-approve-anyway.d.ts.map +1 -1
  66. package/dist/hooks/use-approve-anyway.js +8 -8
  67. package/dist/hooks/use-approve-anyway.js.map +1 -1
  68. package/dist/hooks/use-connection-problems.d.ts.map +1 -1
  69. package/dist/hooks/useValidateActionPlan.d.ts.map +1 -1
  70. package/dist/ldo-ui.d.ts +1 -0
  71. package/dist/ldo-ui.d.ts.map +1 -1
  72. package/dist/ldo-ui.js +1 -0
  73. package/dist/ldo-ui.js.map +1 -1
  74. package/dist/lib/find-latest-staged-rule.js +1 -1
  75. package/dist/lib/find-latest-staged-rule.js.map +1 -1
  76. package/dist/lib/tool-icons.js +6 -6
  77. package/dist/lib/tool-icons.js.map +1 -1
  78. package/dist/lib/tool-names.d.ts.map +1 -1
  79. package/dist/lib/tool-names.js +0 -1
  80. package/dist/lib/tool-names.js.map +1 -1
  81. package/dist/ontology/skolem.js +2 -2
  82. package/dist/ontology/skolem.js.map +1 -1
  83. package/dist/providers/KnowledgeGraphStateProvider.js +1 -1
  84. package/dist/providers/KnowledgeGraphStateProvider.js.map +1 -1
  85. package/dist/routes/data-explorer/class-properties.js +2 -2
  86. package/dist/routes/data-explorer/class-properties.js.map +1 -1
  87. package/dist/routes/data-explorer/classes.js +2 -2
  88. package/dist/routes/data-explorer/classes.js.map +1 -1
  89. package/dist/routes/data-explorer/components/record-detail/ActionFormDialog.d.ts.map +1 -1
  90. package/dist/routes/data-explorer/components/record-detail/ActionFormDialog.js +7 -21
  91. package/dist/routes/data-explorer/components/record-detail/ActionFormDialog.js.map +1 -1
  92. package/dist/routes/data-explorer/components/record-detail/ChatPreview.d.ts.map +1 -1
  93. package/dist/routes/data-explorer/components/record-detail/ChatPreview.js +2 -2
  94. package/dist/routes/data-explorer/components/record-detail/ChatPreview.js.map +1 -1
  95. package/dist/routes/data-explorer/components/record-detail/action-properties.d.ts +2 -2
  96. package/dist/routes/data-explorer/components/record-detail/action-properties.d.ts.map +1 -1
  97. package/dist/routes/data-explorer/components/record-detail/action-properties.js +3 -3
  98. package/dist/routes/data-explorer/components/record-detail/action-properties.js.map +1 -1
  99. package/dist/routes/data-explorer/recents.js +1 -1
  100. package/dist/routes/data-explorer/recents.js.map +1 -1
  101. package/dist/routes/data-explorer/shapes.js +2 -2
  102. package/dist/routes/data-explorer/shapes.js.map +1 -1
  103. package/dist/routes/integrations/catalog-shape.d.ts +1 -0
  104. package/dist/routes/integrations/catalog-shape.d.ts.map +1 -1
  105. package/dist/routes/integrations/catalog-shape.js.map +1 -1
  106. package/dist/routes/integrations/components/connect-forms/CanvaConnectForm.d.ts +3 -0
  107. package/dist/routes/integrations/components/connect-forms/CanvaConnectForm.d.ts.map +1 -0
  108. package/dist/routes/integrations/components/connect-forms/CanvaConnectForm.js +12 -0
  109. package/dist/routes/integrations/components/connect-forms/CanvaConnectForm.js.map +1 -0
  110. package/dist/routes/integrations/components/connect-forms/MicrosoftAdsConnectForm.d.ts +7 -0
  111. package/dist/routes/integrations/components/connect-forms/MicrosoftAdsConnectForm.d.ts.map +1 -0
  112. package/dist/routes/integrations/components/connect-forms/MicrosoftAdsConnectForm.js +76 -0
  113. package/dist/routes/integrations/components/connect-forms/MicrosoftAdsConnectForm.js.map +1 -0
  114. package/dist/routes/integrations/components/connect-forms/OAuthSetupConnectForm.d.ts +7 -0
  115. package/dist/routes/integrations/components/connect-forms/OAuthSetupConnectForm.d.ts.map +1 -1
  116. package/dist/routes/integrations/components/connect-forms/OAuthSetupConnectForm.js +8 -7
  117. package/dist/routes/integrations/components/connect-forms/OAuthSetupConnectForm.js.map +1 -1
  118. package/dist/routes/integrations/components/connect-forms/inferal-locations.d.ts +3 -0
  119. package/dist/routes/integrations/components/connect-forms/inferal-locations.d.ts.map +1 -0
  120. package/dist/routes/integrations/components/connect-forms/inferal-locations.js +13 -0
  121. package/dist/routes/integrations/components/connect-forms/inferal-locations.js.map +1 -0
  122. package/dist/routes/integrations/connect-forms.d.ts +3 -0
  123. package/dist/routes/integrations/connect-forms.d.ts.map +1 -1
  124. package/dist/routes/integrations/connect-forms.js +3 -0
  125. package/dist/routes/integrations/connect-forms.js.map +1 -1
  126. package/dist/routes/integrations/connection-view.d.ts.map +1 -1
  127. package/dist/routes/integrations/connection-view.js +2 -0
  128. package/dist/routes/integrations/connection-view.js.map +1 -1
  129. package/dist/routes/integrations/types.d.ts +2 -1
  130. package/dist/routes/integrations/types.d.ts.map +1 -1
  131. package/dist/routes/integrations/types.js +1 -0
  132. package/dist/routes/integrations/types.js.map +1 -1
  133. package/dist/routes/rules/hooks/useRuleFactsPreview.js +4 -4
  134. package/dist/routes/rules/hooks/useRuleFactsPreview.js.map +1 -1
  135. package/dist/shacl/form-appearance.d.ts +1 -1
  136. package/dist/shacl/form-appearance.d.ts.map +1 -1
  137. package/dist/shacl/form-appearance.js +1 -1
  138. package/dist/shacl/form-appearance.js.map +1 -1
  139. package/dist/shared/graph-derived-queries.js +2 -2
  140. package/dist/shared/graph-derived-queries.js.map +1 -1
  141. package/package.json +7 -7
  142. package/src/components/datastore-management/tree.ts +5 -5
  143. package/src/components/explain-fact/ExplainFact.tsx +3 -3
  144. package/src/components/planning/plan-detail-utils.tsx +4 -0
  145. package/src/components/tool-invocation-card/ListRulesResultDisplay.tsx +2 -2
  146. package/src/components/tool-invocation-card/ToolOutputRenderer.tsx +10 -8
  147. package/src/components/tool-invocation-card/types.ts +8 -8
  148. package/src/explain-fact/rule-presentation.ts +2 -2
  149. package/src/explain-fact/tree-model.ts +2 -2
  150. package/src/graph/EntityCard.tsx +2 -1
  151. package/src/graph/EntityViewWithLinks.tsx +43 -0
  152. package/src/graph/card-links.tsx +43 -0
  153. package/src/graph/nodes/BrandAssetAnalysisView.tsx +1 -0
  154. package/src/graph/nodes/BrandFontSuggestionView.tsx +1 -0
  155. package/src/graph/nodes/EntityCardShell.tsx +37 -3
  156. package/src/graph/nodes/NodePropertyTable.tsx +16 -2
  157. package/src/graph/nodes/node-property-display.ts +2 -7
  158. package/src/graph/special-nodes/AttributeList.tsx +4 -2
  159. package/src/graph/special-nodes/RelatedSection.tsx +29 -0
  160. package/src/graph/special-nodes/card-facts.ts +13 -0
  161. package/src/graph/types.ts +1 -1
  162. package/src/hooks/use-approve-anyway.ts +8 -11
  163. package/src/ldo-ui.ts +1 -0
  164. package/src/lib/find-latest-staged-rule.ts +1 -1
  165. package/src/lib/tool-icons.ts +6 -6
  166. package/src/lib/tool-names.ts +0 -1
  167. package/src/ontology/skolem.ts +2 -2
  168. package/src/providers/KnowledgeGraphStateProvider.tsx +1 -1
  169. package/src/routes/data-explorer/class-properties.ts +2 -2
  170. package/src/routes/data-explorer/classes.ts +2 -2
  171. package/src/routes/data-explorer/components/record-detail/ActionFormDialog.tsx +7 -29
  172. package/src/routes/data-explorer/components/record-detail/ChatPreview.tsx +6 -1
  173. package/src/routes/data-explorer/components/record-detail/action-properties.ts +3 -3
  174. package/src/routes/data-explorer/recents.ts +1 -1
  175. package/src/routes/data-explorer/shapes.ts +2 -2
  176. package/src/routes/datastores/flatten.ts +1 -1
  177. package/src/routes/integrations/catalog-shape.ts +2 -0
  178. package/src/routes/integrations/components/connect-forms/CanvaConnectForm.tsx +26 -0
  179. package/src/routes/integrations/components/connect-forms/MicrosoftAdsConnectForm.tsx +140 -0
  180. package/src/routes/integrations/components/connect-forms/OAuthSetupConnectForm.tsx +27 -5
  181. package/src/routes/integrations/components/connect-forms/inferal-locations.ts +13 -0
  182. package/src/routes/integrations/connect-forms.ts +3 -0
  183. package/src/routes/integrations/connection-view.ts +2 -0
  184. package/src/routes/integrations/types.ts +2 -0
  185. package/src/routes/rules/hooks/useRuleFactsPreview.ts +4 -4
  186. package/src/shacl/form-appearance.ts +1 -1
  187. package/src/shared/graph-derived-queries.ts +2 -2
@@ -0,0 +1,140 @@
1
+ import {
2
+ GQLInferalLocation,
3
+ GQLIntegration,
4
+ useMicrosoftAdsSetupConnectMutation,
5
+ useMicrosoftAdsSetupProgressQuery,
6
+ type GQLMicrosoftAdsAccount,
7
+ } from "@manta-eu/client";
8
+ import { useQueryClient } from "@tanstack/react-query";
9
+ import { useState } from "react";
10
+ import { inferalLocationLabels } from "./inferal-locations";
11
+ import { OAuthSetupConnectForm, type OAuthSetup, type SetupCopy } from "./OAuthSetupConnectForm";
12
+ import type { ConnectFormProps } from "./types";
13
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "#components/select/index";
14
+ import type { TreeSelectItem } from "#components/tree-multi-select/index";
15
+ import { useMantaClient } from "#providers/index";
16
+
17
+ const copy: SetupCopy = {
18
+ providerName: "Microsoft Ads",
19
+ identityProviderName: "Microsoft",
20
+ entitySingular: "account",
21
+ entityPlural: "accounts",
22
+ signInDescription:
23
+ "Sign in the way you sign in to Microsoft Advertising: with a Microsoft account, or with Google if your Advertising login is a Google account.",
24
+ pickTitle: "Pick the Microsoft Ads accounts to connect",
25
+ pickDescription:
26
+ "Manta loads each account's Search campaigns, ad groups, ads and keywords, plus daily campaign, keyword and search-query reports.",
27
+ noEntitiesLabel:
28
+ "We couldn't find any Microsoft Advertising accounts for this Microsoft sign-in. Sign in with a different user or check your account access.",
29
+ noneConnectableLabel:
30
+ "Every Microsoft Advertising account on this sign-in is already connected. Sign in as a different user to connect another one.",
31
+ };
32
+
33
+ export const defaultMicrosoftAdsLocation = GQLInferalLocation.Enam;
34
+
35
+ // Microsoft Advertising refuses a Microsoft token for a login that is a Google account (GoogleAccountIsRequired).
36
+ const googleSignIn = [{ label: "Continue with Google", href: "/oauth/microsoft-ads-google/start" }] as const;
37
+
38
+ const inferalLocations: ReadonlySet<string> = new Set(Object.values(GQLInferalLocation));
39
+
40
+ function isInferalLocation(value: string): value is GQLInferalLocation {
41
+ return inferalLocations.has(value);
42
+ }
43
+
44
+ function accountHint(
45
+ account: GQLMicrosoftAdsAccount,
46
+ alreadyConnected: boolean,
47
+ reconnectable: boolean,
48
+ ): string | undefined {
49
+ if (!account.connectable) return "Unavailable";
50
+ if (reconnectable) return "Reconnect";
51
+ if (alreadyConnected) return "Already connected";
52
+ return undefined;
53
+ }
54
+
55
+ export function microsoftAdsTreeItems(
56
+ accounts: GQLMicrosoftAdsAccount[],
57
+ alreadyConnectedExternalIds: ReadonlySet<string>,
58
+ reconnectableExternalIds: ReadonlySet<string> = new Set(),
59
+ ): TreeSelectItem[] {
60
+ return accounts.map((account) => {
61
+ const reconnectable = reconnectableExternalIds.has(account.id);
62
+ const alreadyConnected = !reconnectable && alreadyConnectedExternalIds.has(account.id);
63
+ return {
64
+ id: account.id,
65
+ label: account.name ?? account.number ?? account.id,
66
+ caption: account.number ?? account.id,
67
+ hint: accountHint(account, alreadyConnected, reconnectable),
68
+ selectable: account.connectable,
69
+ disabled: alreadyConnected,
70
+ depth: 0,
71
+ };
72
+ });
73
+ }
74
+
75
+ function useMicrosoftAdsSetup(location: GQLInferalLocation): OAuthSetup<GQLMicrosoftAdsAccount> {
76
+ const { mantaClient } = useMantaClient();
77
+ const queryClient = useQueryClient();
78
+ const progressQuery = useMicrosoftAdsSetupProgressQuery(mantaClient, undefined, { staleTime: 0 });
79
+ const connectMutation = useMicrosoftAdsSetupConnectMutation(mantaClient);
80
+ const progress = progressQuery.data?.microsoftAdsSetupProgress;
81
+
82
+ return {
83
+ progress: progress && { state: progress.state, rows: progress.accounts, lastError: progress.lastError },
84
+ refetchProgress: progressQuery.refetch,
85
+ resetProgress: () =>
86
+ queryClient.setQueryData(useMicrosoftAdsSetupProgressQuery.getKey(), {
87
+ microsoftAdsSetupProgress: { state: [], accounts: null, lastError: null },
88
+ }),
89
+ connect: async (accountIds) =>
90
+ (await connectMutation.mutateAsync({ accountIds, location })).microsoftAdsSetupConnect,
91
+ isConnecting: connectMutation.isPending,
92
+ };
93
+ }
94
+
95
+ type LocationPickerProps = {
96
+ value: GQLInferalLocation;
97
+ onChange: (location: GQLInferalLocation) => void;
98
+ };
99
+
100
+ function LocationPicker(props: LocationPickerProps) {
101
+ const { value, onChange } = props;
102
+
103
+ return (
104
+ <div className="grid gap-1">
105
+ <Select value={value} onValueChange={(next) => isInferalLocation(next) && onChange(next)}>
106
+ <SelectTrigger label="Stream location" id="microsoft-ads-location" className="w-full h-10">
107
+ <SelectValue placeholder="Select a region" />
108
+ </SelectTrigger>
109
+ <SelectContent>
110
+ {Object.entries(inferalLocationLabels).map(([location, label]) => (
111
+ <SelectItem key={location} value={location}>
112
+ {label}
113
+ </SelectItem>
114
+ ))}
115
+ </SelectContent>
116
+ </Select>
117
+ <p className="typography-caption text-muted-foreground">
118
+ Where the account's data stream runs. Pick the region closest to your account.
119
+ </p>
120
+ </div>
121
+ );
122
+ }
123
+
124
+ export function MicrosoftAdsConnectForm(props: ConnectFormProps) {
125
+ const [location, setLocation] = useState<GQLInferalLocation>(defaultMicrosoftAdsLocation);
126
+ const setup = useMicrosoftAdsSetup(location);
127
+
128
+ return (
129
+ <OAuthSetupConnectForm
130
+ {...props}
131
+ integration={GQLIntegration.MicrosoftAds}
132
+ oauthStartPath="/oauth/microsoft-ads/start"
133
+ copy={copy}
134
+ setup={setup}
135
+ treeItems={microsoftAdsTreeItems}
136
+ pickExtras={<LocationPicker value={location} onChange={setLocation} />}
137
+ alternateSignIns={googleSignIn}
138
+ />
139
+ );
140
+ }
@@ -2,7 +2,7 @@ import { GQLGoogleSetupStateEnum, type GQLIntegration } from "@manta-eu/client";
2
2
  import { parseError } from "@manta-eu/client/shared/error-utils";
3
3
  import { isPresent } from "@manta-eu/lib/present";
4
4
  import { ArrowLeft } from "lucide-react";
5
- import { useEffect, useRef, useState } from "react";
5
+ import { useEffect, useRef, useState, type ReactNode } from "react";
6
6
  import { toast } from "sonner";
7
7
  import { match } from "ts-pattern";
8
8
  import { ConnectFormHeader } from "./ConnectFormHeader";
@@ -66,11 +66,19 @@ export type OAuthSetupConnectFormProps<Row extends SetupRow> = ConnectFormProps
66
66
  ) => TreeSelectItem[];
67
67
  treeOptions?: SetupTreeOptions;
68
68
  resumesUnfinishedSetup?: boolean;
69
+ // Rendered under the list while picking, for a choice the connect needs besides the ids.
70
+ pickExtras?: ReactNode;
71
+ // Other identity providers that lead into the same setup, offered beside the main sign-in.
72
+ alternateSignIns?: readonly AlternateSignIn[];
69
73
  };
70
74
 
75
+ export type AlternateSignIn = { label: string; href: string };
76
+
71
77
  export function OAuthSetupConnectForm<Row extends SetupRow>(props: OAuthSetupConnectFormProps<Row>) {
72
78
  const { onBack, onChanged, onDismiss, provider, resumedFromOAuth = false, importNotice } = props;
73
- const { integration, oauthStartPath, copy, setup, treeItems, treeOptions, resumesUnfinishedSetup } = props;
79
+ const { integration, oauthStartPath, copy, setup, treeItems, treeOptions, resumesUnfinishedSetup, pickExtras } =
80
+ props;
81
+ const { alternateSignIns } = props;
74
82
  const { providerName } = copy;
75
83
  const [hasStartedOAuth, setHasStartedOAuth] = useState(resumedFromOAuth);
76
84
  const [hasSeenActiveState, setHasSeenActiveState] = useState(resumedFromOAuth);
@@ -151,7 +159,14 @@ export function OAuthSetupConnectForm<Row extends SetupRow>(props: OAuthSetupCon
151
159
 
152
160
  <div className="min-h-40">
153
161
  {match(phase)
154
- .with("idle", () => <IdleView copy={copy} oauthStartPath={oauthStartPath} onOpened={handleOpened} />)
162
+ .with("idle", () => (
163
+ <IdleView
164
+ copy={copy}
165
+ oauthStartPath={oauthStartPath}
166
+ alternateSignIns={alternateSignIns}
167
+ onOpened={handleOpened}
168
+ />
169
+ ))
155
170
  .with("awaitingOAuth", () => <AwaitingOAuthView copy={copy} />)
156
171
  .with("loadingAccounts", () => <LoadingEntitiesView copy={copy} />)
157
172
  .with("pickingAccount", () => (
@@ -161,6 +176,7 @@ export function OAuthSetupConnectForm<Row extends SetupRow>(props: OAuthSetupCon
161
176
  selectedIds={selectedIds}
162
177
  onToggle={toggleId}
163
178
  treeOptions={treeOptions}
179
+ extras={pickExtras}
164
180
  />
165
181
  ))
166
182
  .with("submitting", () => <SubmittingView copy={copy} />)
@@ -221,11 +237,12 @@ type CopyProps = {
221
237
 
222
238
  type IdleViewProps = CopyProps & {
223
239
  oauthStartPath: string;
240
+ alternateSignIns?: readonly AlternateSignIn[];
224
241
  onOpened: () => void;
225
242
  };
226
243
 
227
244
  function IdleView(props: IdleViewProps) {
228
- const { copy, oauthStartPath, onOpened } = props;
245
+ const { copy, oauthStartPath, alternateSignIns, onOpened } = props;
229
246
 
230
247
  return (
231
248
  <div className="grid gap-4">
@@ -240,6 +257,9 @@ function IdleView(props: IdleViewProps) {
240
257
  label={`Continue with ${copy.identityProviderName}`}
241
258
  onOpened={onOpened}
242
259
  />
260
+ {alternateSignIns?.map(({ label, href }) => (
261
+ <OAuthConnectLink key={href} href={href} label={label} variant="secondary" onOpened={onOpened} />
262
+ ))}
243
263
  </div>
244
264
  );
245
265
  }
@@ -283,10 +303,11 @@ type PickingEntityViewProps = CopyProps & {
283
303
  selectedIds: ReadonlySet<string>;
284
304
  onToggle: (id: string, checked: boolean) => void;
285
305
  treeOptions?: SetupTreeOptions;
306
+ extras?: ReactNode;
286
307
  };
287
308
 
288
309
  function PickingEntityView(props: PickingEntityViewProps) {
289
- const { copy, items, selectedIds, onToggle, treeOptions } = props;
310
+ const { copy, items, selectedIds, onToggle, treeOptions, extras } = props;
290
311
 
291
312
  if (!isPresent(items)) {
292
313
  return <Banner type="warning" label={copy.noEntitiesLabel} />;
@@ -310,6 +331,7 @@ function PickingEntityView(props: PickingEntityViewProps) {
310
331
  searchPlaceholder={`Search ${copy.entityPlural}...`}
311
332
  {...treeOptions}
312
333
  />
334
+ {extras}
313
335
  </div>
314
336
  );
315
337
  }
@@ -0,0 +1,13 @@
1
+ import { GQLInferalLocation } from "@manta-eu/client";
2
+
3
+ export const inferalLocationLabels: Readonly<Record<GQLInferalLocation, string>> = {
4
+ [GQLInferalLocation.Wnam]: "Western North America",
5
+ [GQLInferalLocation.Enam]: "Eastern North America",
6
+ [GQLInferalLocation.Sam]: "South America",
7
+ [GQLInferalLocation.Weur]: "Western Europe",
8
+ [GQLInferalLocation.Eeur]: "Eastern Europe",
9
+ [GQLInferalLocation.Apac]: "Asia Pacific",
10
+ [GQLInferalLocation.Oc]: "Oceania",
11
+ [GQLInferalLocation.Afr]: "Africa",
12
+ [GQLInferalLocation.Me]: "Middle East",
13
+ };
@@ -6,6 +6,7 @@ export {
6
6
  type StoredConnection,
7
7
  } from "./components/connect-forms/DataConnectionConnectForm";
8
8
  export type { DataConnectionSetting, StoredDataConnection } from "./components/connect-forms/data-connection-fields";
9
+ export { CanvaConnectForm } from "./components/connect-forms/CanvaConnectForm";
9
10
  export { FigmaConnectForm } from "./components/connect-forms/FigmaConnectForm";
10
11
  export { GmailConnectForm } from "./components/connect-forms/GmailConnectForm";
11
12
  export { GoogleAdsConnectForm } from "./components/connect-forms/GoogleAdsConnectForm";
@@ -13,6 +14,7 @@ export { GoogleAnalyticsConnectForm } from "./components/connect-forms/GoogleAna
13
14
  export { KlaviyoConnectForm } from "./components/connect-forms/KlaviyoConnectForm";
14
15
  export { LinkedinConnectForm } from "./components/connect-forms/LinkedinConnectForm";
15
16
  export { MetaAdsConnectForm } from "./components/connect-forms/MetaAdsConnectForm";
17
+ export { MicrosoftAdsConnectForm } from "./components/connect-forms/MicrosoftAdsConnectForm";
16
18
  export { ShopifyConnectForm } from "./components/connect-forms/ShopifyConnectForm";
17
19
  export { SlackConnectForm } from "./components/connect-forms/SlackConnectForm";
18
20
  export { TriplewhaleConnectForm } from "./components/connect-forms/TriplewhaleConnectForm";
@@ -24,3 +26,4 @@ export {
24
26
  type MantaSyncPluginLinkProps,
25
27
  type MantaSyncPluginStepProps,
26
28
  } from "./components/MantaSyncPluginDownload";
29
+ export { inferalLocationLabels } from "./components/connect-forms/inferal-locations";
@@ -36,6 +36,7 @@ export type ConnectionView = {
36
36
  // Fallback nouns shown until the ontology carries rdfs:labels for these classes (MNT-503).
37
37
  // https://linear.app/manta-eu/issue/MNT-503/add-rdfslabel-to-provider-entity-classes-in-the-ontology
38
38
  const oauthAccountNoun = {
39
+ [GQLIntegration.Canva]: "User",
39
40
  [GQLIntegration.Dash]: "Account",
40
41
  [GQLIntegration.Figma]: "User",
41
42
  [GQLIntegration.Slack]: "Workspace",
@@ -43,6 +44,7 @@ const oauthAccountNoun = {
43
44
  [GQLIntegration.GoogleAnalytics]: "Property",
44
45
  [GQLIntegration.Meta]: "Ad account",
45
46
  [GQLIntegration.Linkedin]: "Ad account",
47
+ [GQLIntegration.MicrosoftAds]: "Account",
46
48
  [GQLIntegration.Snapchat]: "Ad account",
47
49
  [GQLIntegration.Shopify]: "Shop",
48
50
  [GQLIntegration.Woocommerce]: "Store",
@@ -11,6 +11,7 @@ import type { ComponentType, SVGProps } from "react";
11
11
  import type { ConnectionView } from "./connection-view";
12
12
 
13
13
  export const gmailProviderId = "GMAIL";
14
+ export const canvaProviderId = "CANVA";
14
15
  export const figmaProviderId = "FIGMA";
15
16
  export const dashProviderId = "DASH";
16
17
  export const dataConnectionProviderIds = {
@@ -29,6 +30,7 @@ export type DataConnectorType = keyof typeof dataConnectionProviderIds;
29
30
  export type ProviderId =
30
31
  | `${GQLInferalIntegrationProvider}`
31
32
  | typeof gmailProviderId
33
+ | typeof canvaProviderId
32
34
  | typeof figmaProviderId
33
35
  | typeof dashProviderId
34
36
  | (typeof dataConnectionProviderIds)[DataConnectorType];
@@ -1,5 +1,5 @@
1
1
  import { useSparqlQueryQuery } from "@manta-eu/client";
2
- import { formatIriForRdfox, compactUri, namespaces } from "@manta-eu/client/shared/rdf-namespaces";
2
+ import { formatIriForSparql, compactUri, namespaces } from "@manta-eu/client/shared/rdf-namespaces";
3
3
  import { isJsonLdNode } from "@manta-eu/client/types/jsonld";
4
4
  import { parseDatalogRule, datalogBodyToSparqlSelect } from "@manta-eu/datalog-parser";
5
5
  import type { DatalogAtom, SparqlSelectResult } from "@manta-eu/datalog-parser";
@@ -241,20 +241,20 @@ function generateTriplePattern(atom: DatalogAtom): string | null {
241
241
  .with("property", () => {
242
242
  if (!isPropertyAtom(atom)) return null;
243
243
  const subject = atom.arguments[0]?.value || "?s";
244
- const predicate = formatIriForRdfox(atom.predicate.value || "");
244
+ const predicate = formatIriForSparql(atom.predicate.value || "");
245
245
  const object = atom.arguments[1]?.value || "?o";
246
246
  return `${subject} ${predicate} ${object}`;
247
247
  })
248
248
  .with("class", () => {
249
249
  if (!isClassAtom(atom)) return null;
250
250
  const subject = atom.arguments[0]?.value || "?s";
251
- const classIRI = formatIriForRdfox(atom.predicate.value || "");
251
+ const classIRI = formatIriForSparql(atom.predicate.value || "");
252
252
  return `${subject} a ${classIRI}`;
253
253
  })
254
254
  .with("triple", () => {
255
255
  if (!isTripleAtom(atom)) return null;
256
256
  const subject = atom.subject.value || "?s";
257
- const predicate = formatIriForRdfox(atom.predicate.value || "");
257
+ const predicate = formatIriForSparql(atom.predicate.value || "");
258
258
  const object = atom.object.value || "?o";
259
259
  return `${subject} ${predicate} ${object}`;
260
260
  })
@@ -168,7 +168,7 @@ function propertyPathsByBlankNode(turtle: string): Map<string, string> {
168
168
  return paths;
169
169
  }
170
170
 
171
- /** RDFox emits `sh:property` in arbitrary order, reshuffling fields on every open; reorder by path local name. */
171
+ /** The datastore emits `sh:property` in arbitrary order, so fields move on every open; reorder by path local name. */
172
172
  export function sortShapeProperties(turtle: string): string {
173
173
  const paths = propertyPathsByBlankNode(turtle);
174
174
  const localName = (node: string) => {
@@ -8,7 +8,7 @@ import {
8
8
  useConversationStartersQuery,
9
9
  useCoverageRulesQuery,
10
10
  useCurrentFactValueQuery,
11
- useExplainRdFoxFactQuery,
11
+ useExplainFactQuery,
12
12
  useGetActionPlansSummaryQuery,
13
13
  useMemoriesQuery,
14
14
  useMemorySchemasQuery,
@@ -34,7 +34,7 @@ export const graphDerivedQueries: QueryWithGetKey[] = [
34
34
  useConversationStartersQuery,
35
35
  useCoverageRulesQuery,
36
36
  useCurrentFactValueQuery,
37
- useExplainRdFoxFactQuery,
37
+ useExplainFactQuery,
38
38
  useGetActionPlansSummaryQuery,
39
39
  useMemoriesQuery,
40
40
  useMemorySchemasQuery,