@authhero/react-admin 0.30.0 → 0.32.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.
- package/CHANGELOG.md +24 -0
- package/package.json +1 -1
- package/src/App.tsx +10 -0
- package/src/auth0DataProvider.ts +187 -0
- package/src/components/prompts/edit.tsx +1155 -0
- package/src/components/prompts/index.ts +2 -0
- package/src/components/prompts/list.tsx +14 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @authhero/react-admin
|
|
2
2
|
|
|
3
|
+
## 0.32.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 44b76d9: Update the custom text behaviour
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [44b76d9]
|
|
12
|
+
- @authhero/widget@0.10.0
|
|
13
|
+
|
|
14
|
+
## 0.31.0
|
|
15
|
+
|
|
16
|
+
### Minor Changes
|
|
17
|
+
|
|
18
|
+
- ac8af37: Add custom text support
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- Updated dependencies [88a03cd]
|
|
23
|
+
- Updated dependencies [ac8af37]
|
|
24
|
+
- @authhero/widget@0.9.0
|
|
25
|
+
- @authhero/adapter-interfaces@0.130.0
|
|
26
|
+
|
|
3
27
|
## 0.30.0
|
|
4
28
|
|
|
5
29
|
### Minor Changes
|
package/package.json
CHANGED
package/src/App.tsx
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
DomainList,
|
|
26
26
|
} from "./components/custom-domains";
|
|
27
27
|
import { BrandingList, BrandingEdit } from "./components/branding";
|
|
28
|
+
import { PromptsList, PromptsEdit } from "./components/prompts";
|
|
28
29
|
import { LogsList, LogShow } from "./components/logs";
|
|
29
30
|
import { HookEdit, HookList, HooksCreate } from "./components/hooks";
|
|
30
31
|
import { SessionEdit } from "./components/sessions";
|
|
@@ -41,6 +42,7 @@ import {
|
|
|
41
42
|
import WebhookIcon from "@mui/icons-material/Webhook";
|
|
42
43
|
import DnsIcon from "@mui/icons-material/Dns";
|
|
43
44
|
import PaletteIcon from "@mui/icons-material/Palette";
|
|
45
|
+
import TextFieldsIcon from "@mui/icons-material/TextFields";
|
|
44
46
|
import StorageIcon from "@mui/icons-material/Storage";
|
|
45
47
|
import AccountTreeIcon from "@mui/icons-material/AccountTree";
|
|
46
48
|
import { useMemo, useState, useEffect } from "react";
|
|
@@ -251,6 +253,14 @@ export function App(props: AppProps) {
|
|
|
251
253
|
edit={BrandingEdit}
|
|
252
254
|
show={ShowGuesser}
|
|
253
255
|
/>
|
|
256
|
+
<Resource
|
|
257
|
+
icon={TextFieldsIcon}
|
|
258
|
+
name="prompts"
|
|
259
|
+
options={{ hasSingle: true }}
|
|
260
|
+
list={PromptsList}
|
|
261
|
+
edit={PromptsEdit}
|
|
262
|
+
show={ShowGuesser}
|
|
263
|
+
/>
|
|
254
264
|
<Resource
|
|
255
265
|
icon={StorageIcon}
|
|
256
266
|
name="resource-servers"
|
package/src/auth0DataProvider.ts
CHANGED
|
@@ -346,6 +346,61 @@ export default (
|
|
|
346
346
|
);
|
|
347
347
|
}
|
|
348
348
|
|
|
349
|
+
// Handle prompts singleton resource
|
|
350
|
+
if (resource === "prompts") {
|
|
351
|
+
const headers = createHeaders(tenantId);
|
|
352
|
+
try {
|
|
353
|
+
const res = await httpClient(`${apiUrl}/api/v2/prompts`, { headers });
|
|
354
|
+
// Also fetch custom text entries list
|
|
355
|
+
let customTextEntries: Array<{ prompt: string; language: string }> =
|
|
356
|
+
[];
|
|
357
|
+
try {
|
|
358
|
+
const customTextRes = await httpClient(
|
|
359
|
+
`${apiUrl}/api/v2/prompts/custom-text`,
|
|
360
|
+
{ headers },
|
|
361
|
+
);
|
|
362
|
+
customTextEntries = customTextRes.json || [];
|
|
363
|
+
} catch {
|
|
364
|
+
// Custom text list might not exist yet
|
|
365
|
+
}
|
|
366
|
+
return {
|
|
367
|
+
data: [{ ...res.json, customTextEntries, id: resource }],
|
|
368
|
+
total: 1,
|
|
369
|
+
};
|
|
370
|
+
} catch (error) {
|
|
371
|
+
console.error("Error fetching prompts:", error);
|
|
372
|
+
return {
|
|
373
|
+
data: [{ id: resource, customTextEntries: [] }],
|
|
374
|
+
total: 1,
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Handle custom-text resource (for individual custom text entries)
|
|
380
|
+
if (resource === "custom-text") {
|
|
381
|
+
const headers = createHeaders(tenantId);
|
|
382
|
+
try {
|
|
383
|
+
const res = await httpClient(
|
|
384
|
+
`${apiUrl}/api/v2/prompts/custom-text`,
|
|
385
|
+
{ headers },
|
|
386
|
+
);
|
|
387
|
+
const entries = res.json || [];
|
|
388
|
+
return {
|
|
389
|
+
data: entries.map(
|
|
390
|
+
(e: { prompt: string; language: string }, idx: number) => ({
|
|
391
|
+
id: `${e.prompt}:${e.language}`,
|
|
392
|
+
prompt: e.prompt,
|
|
393
|
+
language: e.language,
|
|
394
|
+
}),
|
|
395
|
+
),
|
|
396
|
+
total: entries.length,
|
|
397
|
+
};
|
|
398
|
+
} catch (error) {
|
|
399
|
+
console.error("Error fetching custom-text list:", error);
|
|
400
|
+
return { data: [], total: 0 };
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
349
404
|
// Handle organizations with client-side paging and search (fetch 500, filter locally)
|
|
350
405
|
if (resource === "organizations" && !resourcePath.includes("/")) {
|
|
351
406
|
const result = await managementClient.organizations.list({
|
|
@@ -587,6 +642,62 @@ export default (
|
|
|
587
642
|
};
|
|
588
643
|
}
|
|
589
644
|
|
|
645
|
+
// Handle prompts singleton resource
|
|
646
|
+
if (resource === "prompts") {
|
|
647
|
+
const headers = createHeaders(tenantId);
|
|
648
|
+
try {
|
|
649
|
+
const res = await httpClient(`${apiUrl}/api/v2/prompts`, { headers });
|
|
650
|
+
// Also fetch custom text entries list
|
|
651
|
+
let customTextEntries: Array<{ prompt: string; language: string }> =
|
|
652
|
+
[];
|
|
653
|
+
try {
|
|
654
|
+
const customTextRes = await httpClient(
|
|
655
|
+
`${apiUrl}/api/v2/prompts/custom-text`,
|
|
656
|
+
{ headers },
|
|
657
|
+
);
|
|
658
|
+
customTextEntries = customTextRes.json || [];
|
|
659
|
+
} catch {
|
|
660
|
+
// Custom text list might not exist yet
|
|
661
|
+
}
|
|
662
|
+
return {
|
|
663
|
+
data: { ...res.json, customTextEntries, id: resource },
|
|
664
|
+
};
|
|
665
|
+
} catch (error) {
|
|
666
|
+
console.error("Error fetching prompts:", error);
|
|
667
|
+
return {
|
|
668
|
+
data: { id: resource, customTextEntries: [] },
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// Handle custom-text resource (individual entries)
|
|
674
|
+
if (resource === "custom-text") {
|
|
675
|
+
// ID format is "prompt:language"
|
|
676
|
+
const [prompt, language] = params.id.split(":");
|
|
677
|
+
if (!prompt || !language) {
|
|
678
|
+
throw new Error("Invalid custom-text ID format");
|
|
679
|
+
}
|
|
680
|
+
try {
|
|
681
|
+
const result = await managementClient.prompts.customText.get(
|
|
682
|
+
prompt as any,
|
|
683
|
+
language as any,
|
|
684
|
+
);
|
|
685
|
+
return {
|
|
686
|
+
data: {
|
|
687
|
+
id: params.id,
|
|
688
|
+
prompt,
|
|
689
|
+
language,
|
|
690
|
+
texts: result || {},
|
|
691
|
+
},
|
|
692
|
+
};
|
|
693
|
+
} catch (error) {
|
|
694
|
+
console.error("Error fetching custom-text:", error);
|
|
695
|
+
return {
|
|
696
|
+
data: { id: params.id, prompt, language, texts: {} },
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
590
701
|
// Handle stats/active-users endpoint
|
|
591
702
|
if (resource === "stats/active-users") {
|
|
592
703
|
const headers = createHeaders(tenantId);
|
|
@@ -948,6 +1059,44 @@ export default (
|
|
|
948
1059
|
};
|
|
949
1060
|
}
|
|
950
1061
|
|
|
1062
|
+
// Handle prompts singleton resource
|
|
1063
|
+
if (resource === "prompts") {
|
|
1064
|
+
const headers = createHeaders(tenantId);
|
|
1065
|
+
headers.set("Content-Type", "application/json");
|
|
1066
|
+
// Don't send customTextEntries to the settings endpoint
|
|
1067
|
+
const { customTextEntries, ...promptsData } = cleanParams.data;
|
|
1068
|
+
const res = await httpClient(`${apiUrl}/api/v2/prompts`, {
|
|
1069
|
+
method: "PATCH",
|
|
1070
|
+
headers,
|
|
1071
|
+
body: JSON.stringify(promptsData),
|
|
1072
|
+
});
|
|
1073
|
+
return {
|
|
1074
|
+
data: { ...res.json, customTextEntries, id: resource },
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
// Handle custom-text resource
|
|
1079
|
+
if (resource === "custom-text") {
|
|
1080
|
+
// ID format is "prompt:language"
|
|
1081
|
+
const [prompt, language] = params.id.split(":");
|
|
1082
|
+
if (!prompt || !language) {
|
|
1083
|
+
throw new Error("Invalid custom-text ID format");
|
|
1084
|
+
}
|
|
1085
|
+
await managementClient.prompts.customText.set(
|
|
1086
|
+
prompt as any,
|
|
1087
|
+
language as any,
|
|
1088
|
+
cleanParams.data.texts || {},
|
|
1089
|
+
);
|
|
1090
|
+
return {
|
|
1091
|
+
data: {
|
|
1092
|
+
id: params.id,
|
|
1093
|
+
prompt,
|
|
1094
|
+
language,
|
|
1095
|
+
texts: cleanParams.data.texts || {},
|
|
1096
|
+
},
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1099
|
+
|
|
951
1100
|
// Special handling for branding to update theme data separately
|
|
952
1101
|
if (resource === "branding") {
|
|
953
1102
|
// Extract themes from the payload - it's updated via a separate endpoint
|
|
@@ -1123,6 +1272,27 @@ export default (
|
|
|
1123
1272
|
if (tenantId) headers.set("tenant-id", tenantId);
|
|
1124
1273
|
const managementClient = await getManagementClient();
|
|
1125
1274
|
|
|
1275
|
+
// Handle custom-text resource
|
|
1276
|
+
if (resource === "custom-text") {
|
|
1277
|
+
const { prompt, language, texts } = params.data;
|
|
1278
|
+
if (!prompt || !language) {
|
|
1279
|
+
throw new Error("prompt and language are required");
|
|
1280
|
+
}
|
|
1281
|
+
await managementClient.prompts.customText.set(
|
|
1282
|
+
prompt as any,
|
|
1283
|
+
language as any,
|
|
1284
|
+
texts || {},
|
|
1285
|
+
);
|
|
1286
|
+
return {
|
|
1287
|
+
data: {
|
|
1288
|
+
id: `${prompt}:${language}`,
|
|
1289
|
+
prompt,
|
|
1290
|
+
language,
|
|
1291
|
+
texts: texts || {},
|
|
1292
|
+
},
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1126
1296
|
// Helper for POST requests
|
|
1127
1297
|
const post = async (endpoint: string, body: any) =>
|
|
1128
1298
|
httpClient(`${apiUrl}/api/v2/${endpoint}`, {
|
|
@@ -1276,6 +1446,23 @@ export default (
|
|
|
1276
1446
|
const headers = new Headers({ "content-type": "application/json" });
|
|
1277
1447
|
if (tenantId) headers.set("tenant-id", tenantId);
|
|
1278
1448
|
|
|
1449
|
+
// Handle custom-text resource
|
|
1450
|
+
if (resource === "custom-text") {
|
|
1451
|
+
// ID format is "prompt:language"
|
|
1452
|
+
const [prompt, language] = String(params.id).split(":");
|
|
1453
|
+
if (!prompt || !language) {
|
|
1454
|
+
throw new Error("Invalid custom-text ID format");
|
|
1455
|
+
}
|
|
1456
|
+
// Auth0 SDK doesn't have delete, so we set to empty object
|
|
1457
|
+
// Our backend also supports DELETE, but using set({}) is compatible with Auth0
|
|
1458
|
+
await managementClient.prompts.customText.set(
|
|
1459
|
+
prompt as any,
|
|
1460
|
+
language as any,
|
|
1461
|
+
{},
|
|
1462
|
+
);
|
|
1463
|
+
return { data: { id: params.id } };
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1279
1466
|
// Helper for DELETE requests
|
|
1280
1467
|
const del = async (endpoint: string, body?: any) =>
|
|
1281
1468
|
httpClient(`${apiUrl}/api/v2/${endpoint}`, {
|