@ttoss/components 2.14.31 → 2.16.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/README.md +46 -0
- package/dist/index.d.mts +135 -3
- package/dist/index.mjs +561 -143
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -14,6 +14,52 @@ pnpm add @ttoss/components @ttoss/ui @emotion/react @ttoss/react-hooks
|
|
|
14
14
|
|
|
15
15
|
All components are theme-aware and integrate seamlessly with `@ttoss/ui`.
|
|
16
16
|
|
|
17
|
+
### OAuthConsent
|
|
18
|
+
|
|
19
|
+
OAuth consent screen with flat and GitHub-style hierarchical scopes. Granting a parent scope automatically locks all descendants. All visible copy is injected via the `labels` prop — no hardcoded strings. [Docs](https://storybook.ttoss.dev/?path=/docs/components-oauthconsent--docs)
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { OAuthConsent } from '@ttoss/components';
|
|
23
|
+
|
|
24
|
+
<OAuthConsent
|
|
25
|
+
clientName="My App"
|
|
26
|
+
scopes={[
|
|
27
|
+
{
|
|
28
|
+
key: 'openid',
|
|
29
|
+
label: 'OpenID Connect',
|
|
30
|
+
description: 'Verify your identity',
|
|
31
|
+
required: true,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
key: 'profile',
|
|
35
|
+
label: 'Profile',
|
|
36
|
+
description: 'Read your public profile information',
|
|
37
|
+
},
|
|
38
|
+
]}
|
|
39
|
+
onAuthorize={async (grantedScopes) => {
|
|
40
|
+
const res = await authorize({ scopes: grantedScopes });
|
|
41
|
+
return { ok: res.ok };
|
|
42
|
+
}}
|
|
43
|
+
onAuthorized={() => {
|
|
44
|
+
window.location.href = resumeUrl;
|
|
45
|
+
}}
|
|
46
|
+
onDeny={() => navigate('/')}
|
|
47
|
+
labels={{
|
|
48
|
+
title: 'Authorize access',
|
|
49
|
+
requestedBy: (name) => (
|
|
50
|
+
<>
|
|
51
|
+
<strong>{name}</strong> is requesting access.
|
|
52
|
+
</>
|
|
53
|
+
),
|
|
54
|
+
permissionsHeading: 'Requested permissions',
|
|
55
|
+
approve: 'Authorize',
|
|
56
|
+
deny: 'Deny',
|
|
57
|
+
invalidRequestTitle: 'Invalid request',
|
|
58
|
+
invalidRequestBody: 'Missing required OAuth parameters. Please try again.',
|
|
59
|
+
}}
|
|
60
|
+
/>;
|
|
61
|
+
```
|
|
62
|
+
|
|
17
63
|
### Accordion
|
|
18
64
|
|
|
19
65
|
Accessible accordion component with collapsible content sections. [Docs](https://storybook.ttoss.dev/?path=/docs/components-accordion--docs)
|
package/dist/index.d.mts
CHANGED
|
@@ -791,11 +791,30 @@ declare const NavList: {
|
|
|
791
791
|
displayName: string;
|
|
792
792
|
};
|
|
793
793
|
//#endregion
|
|
794
|
+
//#region src/components/NotificationCard/NotificationButton.d.ts
|
|
795
|
+
type NotificationType$1 = 'success' | 'error' | 'warning' | 'info' | 'neutral';
|
|
796
|
+
/** Props for NotificationButton */
|
|
797
|
+
type NotificationButtonProps = Omit<ButtonProps, 'type'> & {
|
|
798
|
+
/** Notification type — controls background and border colors to match the card. */type: NotificationType$1;
|
|
799
|
+
};
|
|
800
|
+
/**
|
|
801
|
+
* A button styled to match the NotificationCard of a given type.
|
|
802
|
+
* Use this for action buttons rendered inside or alongside notification cards.
|
|
803
|
+
*/
|
|
804
|
+
declare const NotificationButton: ({
|
|
805
|
+
type,
|
|
806
|
+
...props
|
|
807
|
+
}: NotificationButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
808
|
+
//#endregion
|
|
794
809
|
//#region src/components/NotificationCard/NotificationCard.d.ts
|
|
795
810
|
type NotificationType = 'success' | 'error' | 'warning' | 'info' | 'neutral';
|
|
796
811
|
type NotificationAction = {
|
|
797
|
-
action
|
|
798
|
-
url
|
|
812
|
+
action: 'open_url';
|
|
813
|
+
url: string;
|
|
814
|
+
label?: string;
|
|
815
|
+
} | {
|
|
816
|
+
action: 'callback';
|
|
817
|
+
onClick: () => void;
|
|
799
818
|
label?: string;
|
|
800
819
|
};
|
|
801
820
|
type NotificationCardProps = {
|
|
@@ -835,6 +854,119 @@ declare const NotificationsMenu: ({
|
|
|
835
854
|
onClearAll
|
|
836
855
|
}: Props) => import("react/jsx-runtime").JSX.Element;
|
|
837
856
|
//#endregion
|
|
857
|
+
//#region src/components/OAuthConsent/OAuthConsent.d.ts
|
|
858
|
+
/**
|
|
859
|
+
* A single OAuth scope, optionally with implied child scopes.
|
|
860
|
+
*/
|
|
861
|
+
type ConsentScope = {
|
|
862
|
+
/** OAuth scope token, e.g. 'repo', 'write:packages', 'read'. */key: string; /** Bold display name shown on the left. Pre-translated by the consumer. */
|
|
863
|
+
label: string; /** Scope description shown below the label. Pre-translated by the consumer. */
|
|
864
|
+
description: string;
|
|
865
|
+
/**
|
|
866
|
+
* Child scopes implied by this one. When this scope is granted, every
|
|
867
|
+
* descendant is granted and locked (checked + disabled).
|
|
868
|
+
*/
|
|
869
|
+
children?: ConsentScope[];
|
|
870
|
+
/**
|
|
871
|
+
* Pre-checked on mount.
|
|
872
|
+
* @default false
|
|
873
|
+
*/
|
|
874
|
+
defaultGranted?: boolean;
|
|
875
|
+
/**
|
|
876
|
+
* Always granted; cannot be unchecked. Renders checked + disabled.
|
|
877
|
+
* @default false
|
|
878
|
+
*/
|
|
879
|
+
required?: boolean;
|
|
880
|
+
};
|
|
881
|
+
/**
|
|
882
|
+
* All visible copy for the consent screen. Pre-translated by the consumer.
|
|
883
|
+
*/
|
|
884
|
+
type OAuthConsentLabels = {
|
|
885
|
+
/** Page heading, e.g. "Authorize access". */title: string; /** Client request line. Receives the client identifier for interpolation. */
|
|
886
|
+
requestedBy: (clientName: string) => React.ReactNode; /** Section heading above the scope list, e.g. "Requested permissions". */
|
|
887
|
+
permissionsHeading: string; /** Approve button label, e.g. "Authorize". */
|
|
888
|
+
approve: string; /** Deny button label, e.g. "Deny". */
|
|
889
|
+
deny: string; /** Heading shown when required OAuth params are missing. */
|
|
890
|
+
invalidRequestTitle: string; /** Body text shown when required OAuth params are missing. */
|
|
891
|
+
invalidRequestBody: string;
|
|
892
|
+
};
|
|
893
|
+
/**
|
|
894
|
+
* Props for the OAuthConsent component.
|
|
895
|
+
*/
|
|
896
|
+
type OAuthConsentProps = {
|
|
897
|
+
/** Display name or identifier of the requesting OAuth client. */clientName: string; /** Scope tree to render. */
|
|
898
|
+
scopes: ConsentScope[];
|
|
899
|
+
/**
|
|
900
|
+
* Called when the user approves. Receives the minimal granted scope set
|
|
901
|
+
* (top-most selected keys; implied descendants omitted). Return `{ ok: true }`
|
|
902
|
+
* to signal success; the component then calls `onAuthorized`.
|
|
903
|
+
*/
|
|
904
|
+
onAuthorize: (grantedScopes: string[]) => Promise<{
|
|
905
|
+
ok: boolean;
|
|
906
|
+
}>;
|
|
907
|
+
/**
|
|
908
|
+
* Called after a successful `onAuthorize`. Use this to redirect to the OAuth
|
|
909
|
+
* server's resumed /authorize URL. The component does not navigate itself.
|
|
910
|
+
*/
|
|
911
|
+
onAuthorized: () => void; /** Called when the user clicks Deny. Use this to navigate away. */
|
|
912
|
+
onDeny: () => void;
|
|
913
|
+
/**
|
|
914
|
+
* True while the authorize call is in flight (disables both buttons).
|
|
915
|
+
* The component also tracks its own internal loading state.
|
|
916
|
+
*/
|
|
917
|
+
isAuthorizing?: boolean;
|
|
918
|
+
/**
|
|
919
|
+
* When false, renders the invalid-request error state instead of the form.
|
|
920
|
+
* @default true
|
|
921
|
+
*/
|
|
922
|
+
isValidRequest?: boolean; /** All visible copy. Pre-translated by the consumer. */
|
|
923
|
+
labels: OAuthConsentLabels;
|
|
924
|
+
};
|
|
925
|
+
/**
|
|
926
|
+
* Walk the scope tree and return the minimal set of granted scope keys.
|
|
927
|
+
* When a node is selected, its key is emitted and its subtree is skipped
|
|
928
|
+
* (the server expands parent scopes to their children). Nodes not in
|
|
929
|
+
* `selected` are recursed into so that individually-selected children
|
|
930
|
+
* are still captured.
|
|
931
|
+
*/
|
|
932
|
+
declare const collectGrantedScopes: (scopes: ConsentScope[], selected: Set<string>) => string[];
|
|
933
|
+
/**
|
|
934
|
+
* Accessible, framework-agnostic OAuth consent screen component.
|
|
935
|
+
*
|
|
936
|
+
* Renders a standards-compliant "authorize this client" page with support for
|
|
937
|
+
* flat and GitHub-style grouped/hierarchical scopes. Granting a parent scope
|
|
938
|
+
* automatically locks all descendant scopes (checked + disabled). All visible
|
|
939
|
+
* copy is injected via `labels`; no strings are hardcoded inside this component.
|
|
940
|
+
*
|
|
941
|
+
* @example
|
|
942
|
+
* ```tsx
|
|
943
|
+
* <OAuthConsent
|
|
944
|
+
* clientName="My App"
|
|
945
|
+
* scopes={[
|
|
946
|
+
* { key: 'read', label: 'Read', description: 'Read access', required: true },
|
|
947
|
+
* { key: 'write', label: 'Write', description: 'Write access' },
|
|
948
|
+
* ]}
|
|
949
|
+
* onAuthorize={async (scopes) => {
|
|
950
|
+
* const res = await authorize({ variables: { scopes } });
|
|
951
|
+
* return { ok: !!res.ok };
|
|
952
|
+
* }}
|
|
953
|
+
* onAuthorized={() => { window.location.href = resumeUrl; }}
|
|
954
|
+
* onDeny={() => navigate('/')}
|
|
955
|
+
* labels={labels}
|
|
956
|
+
* />
|
|
957
|
+
* ```
|
|
958
|
+
*/
|
|
959
|
+
declare const OAuthConsent: ({
|
|
960
|
+
clientName,
|
|
961
|
+
scopes,
|
|
962
|
+
onAuthorize,
|
|
963
|
+
onAuthorized,
|
|
964
|
+
onDeny,
|
|
965
|
+
isAuthorizing,
|
|
966
|
+
isValidRequest,
|
|
967
|
+
labels
|
|
968
|
+
}: OAuthConsentProps) => import("react/jsx-runtime").JSX.Element;
|
|
969
|
+
//#endregion
|
|
838
970
|
//#region src/components/Search/Search.d.ts
|
|
839
971
|
type SearchProps = Omit<InputProps, 'onChange'> & {
|
|
840
972
|
loading?: boolean;
|
|
@@ -907,4 +1039,4 @@ declare const Tabs: {
|
|
|
907
1039
|
declare const ToastContainer: (props: ToastContainerProps) => import("react/jsx-runtime").JSX.Element;
|
|
908
1040
|
declare const toast: typeof toast$1;
|
|
909
1041
|
//#endregion
|
|
910
|
-
export { Accordion, AccordionItem, AccordionProps, AccordionRenderItemProps, BaseMetric, DateMetric, DatePicker, DateRange, Drawer, DrawerProps, EnhancedTitle, EnhancedTitleBadge, EnhancedTitleProps, EnhancedTitleVariant, FileUploadState, FileUploader, FileUploaderProps, InstallPwa, InstallPwaUi, InstallPwaUiProps, JsonEditor, JsonView, type LinkComponentProps, List, ListItem, ListItemProps, ListProps, LockedOverlay, Markdown, MarkdownProps, Menu, MenuProps, Metric, MetricCard, MetricCardProps, Modal, ModalProps, NavList, type NavListGroup, type NavListItem, type NavListProps, Notification, NotificationAction, NotificationCard, NotificationCardProps, NotificationsMenu, NumberMetric, OnFilesChange, OnRemove, OnUpload, OnUploadComplete, OnUploadError, OnUploadProgress, OnUploadStart, PercentageMetric, Search, SearchProps, SpotlightCard, SpotlightCardProps, type TabListProps, type TabPanelProps, type TabProps, Table, Tabs, type TabsProps, ToastContainer, type ToastContainerProps, type ToastOptions, UploadResult, UploadedFile, createCell, createColumnHelper, flexRender, getCoreRowModel, toast, useReactTable };
|
|
1042
|
+
export { Accordion, AccordionItem, AccordionProps, AccordionRenderItemProps, BaseMetric, ConsentScope, DateMetric, DatePicker, DateRange, Drawer, DrawerProps, EnhancedTitle, EnhancedTitleBadge, EnhancedTitleProps, EnhancedTitleVariant, FileUploadState, FileUploader, FileUploaderProps, InstallPwa, InstallPwaUi, InstallPwaUiProps, JsonEditor, JsonView, type LinkComponentProps, List, ListItem, ListItemProps, ListProps, LockedOverlay, Markdown, MarkdownProps, Menu, MenuProps, Metric, MetricCard, MetricCardProps, Modal, ModalProps, NavList, type NavListGroup, type NavListItem, type NavListProps, Notification, NotificationAction, NotificationButton, NotificationButtonProps, NotificationCard, NotificationCardProps, NotificationsMenu, NumberMetric, OAuthConsent, OAuthConsentLabels, OAuthConsentProps, OnFilesChange, OnRemove, OnUpload, OnUploadComplete, OnUploadError, OnUploadProgress, OnUploadStart, PercentageMetric, Search, SearchProps, SpotlightCard, SpotlightCardProps, type TabListProps, type TabPanelProps, type TabProps, Table, Tabs, type TabsProps, ToastContainer, type ToastContainerProps, type ToastOptions, UploadResult, UploadedFile, collectGrantedScopes, createCell, createColumnHelper, flexRender, getCoreRowModel, toast, useReactTable };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
|
|
2
|
-
import { Badge, BaseStyles, Box, Button, Card, CloseButton, Divider, Flex, Heading, IconButton, Input, Label, Link, Stack, Tag, Text, TooltipIcon, keyframes, useResponsiveValue, useTheme } from "@ttoss/ui";
|
|
2
|
+
import { Badge, BaseStyles, Box, Button, Card, Checkbox, CloseButton, Divider, Flex, Heading, IconButton, Input, Label, Link, Stack, Tag, Text, TooltipIcon, keyframes, useResponsiveValue, useTheme } from "@ttoss/ui";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
import { Icon } from "@ttoss/react-icons";
|
|
@@ -2510,168 +2510,265 @@ var NavList = ({
|
|
|
2510
2510
|
};
|
|
2511
2511
|
NavList.displayName = "NavList";
|
|
2512
2512
|
|
|
2513
|
+
//#endregion
|
|
2514
|
+
//#region src/components/NotificationCard/NotificationButton.tsx
|
|
2515
|
+
var sxMap$1 = {
|
|
2516
|
+
success: {
|
|
2517
|
+
backgroundColor: "feedback.background.positive.active",
|
|
2518
|
+
borderColor: "feedback.border.positive.active"
|
|
2519
|
+
},
|
|
2520
|
+
error: {
|
|
2521
|
+
backgroundColor: "feedback.background.negative.active",
|
|
2522
|
+
borderColor: "feedback.border.negative.active"
|
|
2523
|
+
},
|
|
2524
|
+
warning: {
|
|
2525
|
+
backgroundColor: "feedback.background.caution.active",
|
|
2526
|
+
borderColor: "feedback.border.caution.active"
|
|
2527
|
+
},
|
|
2528
|
+
info: {
|
|
2529
|
+
backgroundColor: "feedback.background.primary.active",
|
|
2530
|
+
borderColor: "feedback.border.primary.active"
|
|
2531
|
+
},
|
|
2532
|
+
neutral: {
|
|
2533
|
+
backgroundColor: "feedback.background.primary.active",
|
|
2534
|
+
borderColor: "feedback.border.primary.active"
|
|
2535
|
+
}
|
|
2536
|
+
};
|
|
2537
|
+
/**
|
|
2538
|
+
* A button styled to match the NotificationCard of a given type.
|
|
2539
|
+
* Use this for action buttons rendered inside or alongside notification cards.
|
|
2540
|
+
*/
|
|
2541
|
+
var NotificationButton = ({
|
|
2542
|
+
type,
|
|
2543
|
+
...props
|
|
2544
|
+
}) => {
|
|
2545
|
+
return /* @__PURE__ */jsx(Button, {
|
|
2546
|
+
type: "button",
|
|
2547
|
+
...props,
|
|
2548
|
+
sx: {
|
|
2549
|
+
...sxMap$1[type],
|
|
2550
|
+
color: "display.text.primary.default",
|
|
2551
|
+
borderRadius: "lg",
|
|
2552
|
+
borderWidth: "sm",
|
|
2553
|
+
borderStyle: "solid"
|
|
2554
|
+
}
|
|
2555
|
+
});
|
|
2556
|
+
};
|
|
2557
|
+
|
|
2513
2558
|
//#endregion
|
|
2514
2559
|
//#region src/components/NotificationCard/NotificationCard.tsx
|
|
2515
|
-
var
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
borderColor: "feedback.border.positive.default"
|
|
2521
|
-
}
|
|
2522
|
-
},
|
|
2523
|
-
error: {
|
|
2524
|
-
card: {
|
|
2525
|
-
backgroundColor: "feedback.background.negative.default",
|
|
2526
|
-
borderColor: "feedback.border.negative.default"
|
|
2527
|
-
}
|
|
2528
|
-
},
|
|
2529
|
-
warning: {
|
|
2530
|
-
card: {
|
|
2531
|
-
backgroundColor: "feedback.background.caution.default",
|
|
2532
|
-
borderColor: "feedback.border.caution.default"
|
|
2533
|
-
}
|
|
2534
|
-
},
|
|
2535
|
-
info: {
|
|
2536
|
-
card: {
|
|
2537
|
-
backgroundColor: "feedback.background.primary.default",
|
|
2538
|
-
borderColor: "feedback.border.primary.default"
|
|
2539
|
-
}
|
|
2540
|
-
},
|
|
2541
|
-
neutral: {
|
|
2542
|
-
card: {
|
|
2543
|
-
backgroundColor: "feedback.background.primary.default",
|
|
2544
|
-
borderColor: "feedback.border.primary.default"
|
|
2545
|
-
}
|
|
2560
|
+
var sxMap = {
|
|
2561
|
+
success: {
|
|
2562
|
+
card: {
|
|
2563
|
+
backgroundColor: "feedback.background.positive.default",
|
|
2564
|
+
borderColor: "feedback.border.positive.default"
|
|
2546
2565
|
}
|
|
2547
|
-
}
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2566
|
+
},
|
|
2567
|
+
error: {
|
|
2568
|
+
card: {
|
|
2569
|
+
backgroundColor: "feedback.background.negative.default",
|
|
2570
|
+
borderColor: "feedback.border.negative.default"
|
|
2571
|
+
}
|
|
2572
|
+
},
|
|
2573
|
+
warning: {
|
|
2574
|
+
card: {
|
|
2575
|
+
backgroundColor: "feedback.background.caution.default",
|
|
2576
|
+
borderColor: "feedback.border.caution.default"
|
|
2577
|
+
}
|
|
2578
|
+
},
|
|
2579
|
+
info: {
|
|
2580
|
+
card: {
|
|
2581
|
+
backgroundColor: "feedback.background.primary.default",
|
|
2582
|
+
borderColor: "feedback.border.primary.default"
|
|
2583
|
+
}
|
|
2584
|
+
},
|
|
2585
|
+
neutral: {
|
|
2586
|
+
card: {
|
|
2587
|
+
backgroundColor: "feedback.background.primary.default",
|
|
2588
|
+
borderColor: "feedback.border.primary.default"
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
};
|
|
2592
|
+
var iconMap = {
|
|
2593
|
+
success: "success-circle",
|
|
2594
|
+
error: "error",
|
|
2595
|
+
warning: "warning-alt",
|
|
2596
|
+
info: "info",
|
|
2597
|
+
neutral: "info"
|
|
2598
|
+
};
|
|
2599
|
+
var NotificationCardTags = ({
|
|
2600
|
+
tags
|
|
2601
|
+
}) => {
|
|
2602
|
+
if (!tags) return null;
|
|
2603
|
+
if (Array.isArray(tags)) {
|
|
2604
|
+
if (tags.length === 0) return null;
|
|
2605
|
+
return /* @__PURE__ */jsx(Fragment, {
|
|
2606
|
+
children: tags.map((tag, index) => {
|
|
2607
|
+
return /* @__PURE__ */jsx(Tag, {
|
|
2608
|
+
children: tag
|
|
2609
|
+
}, index);
|
|
2610
|
+
})
|
|
2611
|
+
});
|
|
2612
|
+
}
|
|
2613
|
+
return /* @__PURE__ */jsx(Tag, {
|
|
2614
|
+
children: tags
|
|
2615
|
+
});
|
|
2616
|
+
};
|
|
2617
|
+
var NotificationCardTitle = ({
|
|
2618
|
+
type,
|
|
2619
|
+
title,
|
|
2620
|
+
tags,
|
|
2621
|
+
onClose
|
|
2622
|
+
}) => {
|
|
2623
|
+
return /* @__PURE__ */jsxs(Card.Title, {
|
|
2562
2624
|
sx: {
|
|
2563
|
-
|
|
2564
|
-
|
|
2625
|
+
display: "flex",
|
|
2626
|
+
justifyContent: "space-between",
|
|
2627
|
+
alignItems: "center",
|
|
2628
|
+
fontSize: ["md", "xl"],
|
|
2629
|
+
paddingY: ["1", "2", "4"],
|
|
2630
|
+
paddingX: ["2", "4", "8"]
|
|
2565
2631
|
},
|
|
2566
|
-
children: [
|
|
2632
|
+
children: [/* @__PURE__ */jsxs(Text, {
|
|
2567
2633
|
sx: {
|
|
2568
|
-
display: "flex",
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
paddingX: ["2", "4", "8"]
|
|
2634
|
+
display: "inline-flex",
|
|
2635
|
+
alignItems: "flex-start",
|
|
2636
|
+
gap: "2",
|
|
2637
|
+
flexDirection: "row",
|
|
2638
|
+
flexWrap: "wrap"
|
|
2574
2639
|
},
|
|
2575
|
-
children: [/* @__PURE__ */jsxs(
|
|
2576
|
-
sx: {
|
|
2577
|
-
display: "inline-flex",
|
|
2578
|
-
alignItems: "flex-start",
|
|
2579
|
-
gap: "2",
|
|
2580
|
-
flexDirection: "row",
|
|
2581
|
-
flexWrap: "wrap"
|
|
2582
|
-
},
|
|
2583
|
-
children: [/* @__PURE__ */jsxs(Box, {
|
|
2584
|
-
sx: {
|
|
2585
|
-
display: "flex",
|
|
2586
|
-
alignItems: "center",
|
|
2587
|
-
gap: "2"
|
|
2588
|
-
},
|
|
2589
|
-
children: [/* @__PURE__ */jsx(Icon, {
|
|
2590
|
-
icon: icon[props.type]
|
|
2591
|
-
}), props.title]
|
|
2592
|
-
}), props.tags && (Array.isArray(props.tags) ? props.tags.length > 0 : true) && (Array.isArray(props.tags) ? props.tags.map((tag, index) => {
|
|
2593
|
-
return /* @__PURE__ */jsx(Tag, {
|
|
2594
|
-
children: tag
|
|
2595
|
-
}, index);
|
|
2596
|
-
}) : /* @__PURE__ */jsx(Tag, {
|
|
2597
|
-
children: props.tags
|
|
2598
|
-
}))]
|
|
2599
|
-
}), props.onClose && /* @__PURE__ */jsx(Box, {
|
|
2640
|
+
children: [/* @__PURE__ */jsxs(Box, {
|
|
2600
2641
|
sx: {
|
|
2601
|
-
|
|
2642
|
+
display: "flex",
|
|
2643
|
+
alignItems: "center",
|
|
2644
|
+
gap: "2"
|
|
2602
2645
|
},
|
|
2603
|
-
children: /* @__PURE__ */jsx(
|
|
2604
|
-
|
|
2605
|
-
})
|
|
2646
|
+
children: [/* @__PURE__ */jsx(Icon, {
|
|
2647
|
+
icon: iconMap[type]
|
|
2648
|
+
}), title]
|
|
2649
|
+
}), /* @__PURE__ */jsx(NotificationCardTags, {
|
|
2650
|
+
tags
|
|
2606
2651
|
})]
|
|
2607
|
-
}), /* @__PURE__ */
|
|
2652
|
+
}), onClose && /* @__PURE__ */jsx(Box, {
|
|
2653
|
+
sx: {
|
|
2654
|
+
marginLeft: "auto"
|
|
2655
|
+
},
|
|
2656
|
+
children: /* @__PURE__ */jsx(CloseButton, {
|
|
2657
|
+
onClick: onClose
|
|
2658
|
+
})
|
|
2659
|
+
})]
|
|
2660
|
+
});
|
|
2661
|
+
};
|
|
2662
|
+
var NotificationCardActions = ({
|
|
2663
|
+
type,
|
|
2664
|
+
actions
|
|
2665
|
+
}) => {
|
|
2666
|
+
if (actions.length === 0) return null;
|
|
2667
|
+
return /* @__PURE__ */jsx(Box, {
|
|
2668
|
+
sx: {
|
|
2669
|
+
display: "flex",
|
|
2670
|
+
flexDirection: "row",
|
|
2671
|
+
flexWrap: "wrap",
|
|
2672
|
+
gap: 2,
|
|
2673
|
+
mt: 2
|
|
2674
|
+
},
|
|
2675
|
+
children: actions.map((action, index) => {
|
|
2676
|
+
return /* @__PURE__ */jsx(NotificationButton, {
|
|
2677
|
+
type,
|
|
2678
|
+
onClick: action.action === "open_url" ? () => {
|
|
2679
|
+
return window.open(action.url, "_blank");
|
|
2680
|
+
} : action.onClick,
|
|
2681
|
+
children: action.label || "Acessar"
|
|
2682
|
+
}, index);
|
|
2683
|
+
})
|
|
2684
|
+
});
|
|
2685
|
+
};
|
|
2686
|
+
var NotificationCardBody = ({
|
|
2687
|
+
type,
|
|
2688
|
+
message,
|
|
2689
|
+
actions,
|
|
2690
|
+
caption,
|
|
2691
|
+
onClose,
|
|
2692
|
+
hasTitle
|
|
2693
|
+
}) => {
|
|
2694
|
+
const hasCaption = Boolean(caption);
|
|
2695
|
+
const hasActions = Boolean(actions?.length);
|
|
2696
|
+
const shouldCenter = !hasCaption && !hasActions;
|
|
2697
|
+
const bodyAlign = shouldCenter ? "center" : "flex-start";
|
|
2698
|
+
const bodyMinHeight = shouldCenter && !hasTitle ? "40px" : "auto";
|
|
2699
|
+
return /* @__PURE__ */jsxs(Card.Body, {
|
|
2700
|
+
sx: {
|
|
2701
|
+
...sxMap[type].card,
|
|
2702
|
+
display: "flex",
|
|
2703
|
+
flexDirection: "column",
|
|
2704
|
+
gap: "2",
|
|
2705
|
+
paddingY: ["1", "2", "4"],
|
|
2706
|
+
paddingX: ["2", "4", "8"]
|
|
2707
|
+
},
|
|
2708
|
+
children: [/* @__PURE__ */jsx(Box, {
|
|
2608
2709
|
sx: {
|
|
2609
|
-
...sxMap[props.type].card,
|
|
2610
2710
|
display: "flex",
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2711
|
+
justifyContent: "space-between",
|
|
2712
|
+
minHeight: bodyMinHeight,
|
|
2713
|
+
alignItems: bodyAlign,
|
|
2714
|
+
width: "100%",
|
|
2715
|
+
gap: "4"
|
|
2615
2716
|
},
|
|
2616
|
-
children:
|
|
2617
|
-
sx: {
|
|
2618
|
-
display: "flex",
|
|
2619
|
-
justifyContent: "space-between",
|
|
2620
|
-
minHeight: shouldAddMinHeight ? "40px" : "auto",
|
|
2621
|
-
alignItems: shouldCenterVerticallyWithoutTitle ? "center" : shouldCenterVerticallyWithTitle ? "center" : "flex-start",
|
|
2622
|
-
width: "100%",
|
|
2623
|
-
gap: "4"
|
|
2624
|
-
},
|
|
2625
|
-
children: /* @__PURE__ */jsx(Box, {
|
|
2626
|
-
sx: {
|
|
2627
|
-
flex: 1
|
|
2628
|
-
},
|
|
2629
|
-
children: /* @__PURE__ */jsx(Text, {
|
|
2630
|
-
sx: {
|
|
2631
|
-
fontSize: ["sm", "md"]
|
|
2632
|
-
},
|
|
2633
|
-
children: props.message
|
|
2634
|
-
})
|
|
2635
|
-
})
|
|
2636
|
-
}), props.actions && props.actions.length > 0 && /* @__PURE__ */jsx(Box, {
|
|
2637
|
-
sx: {
|
|
2638
|
-
display: "flex",
|
|
2639
|
-
flexDirection: "column",
|
|
2640
|
-
gap: 2,
|
|
2641
|
-
mt: 2
|
|
2642
|
-
},
|
|
2643
|
-
children: props.actions.map((action, index) => {
|
|
2644
|
-
return action.action === "open_url" ? /* @__PURE__ */jsx(Link, {
|
|
2645
|
-
href: action.url,
|
|
2646
|
-
target: "_blank",
|
|
2647
|
-
rel: "noopener noreferrer",
|
|
2648
|
-
sx: {
|
|
2649
|
-
color: "action.text.accent.default",
|
|
2650
|
-
cursor: "pointer"
|
|
2651
|
-
},
|
|
2652
|
-
children: action.label || "Acessar"
|
|
2653
|
-
}, index) : null;
|
|
2654
|
-
})
|
|
2655
|
-
}), props.caption && /* @__PURE__ */jsx(Box, {
|
|
2717
|
+
children: /* @__PURE__ */jsx(Box, {
|
|
2656
2718
|
sx: {
|
|
2657
|
-
|
|
2658
|
-
mt: 6
|
|
2719
|
+
flex: 1
|
|
2659
2720
|
},
|
|
2660
2721
|
children: /* @__PURE__ */jsx(Text, {
|
|
2661
2722
|
sx: {
|
|
2662
|
-
fontSize: "
|
|
2663
|
-
color: "text.secondary"
|
|
2723
|
+
fontSize: ["sm", "md"]
|
|
2664
2724
|
},
|
|
2665
|
-
children:
|
|
2725
|
+
children: message
|
|
2666
2726
|
})
|
|
2667
|
-
})
|
|
2727
|
+
})
|
|
2728
|
+
}), actions && /* @__PURE__ */jsx(NotificationCardActions, {
|
|
2729
|
+
type,
|
|
2730
|
+
actions
|
|
2731
|
+
}), caption && /* @__PURE__ */jsx(Box, {
|
|
2732
|
+
sx: {
|
|
2733
|
+
whiteSpace: "nowrap",
|
|
2734
|
+
mt: 6
|
|
2735
|
+
},
|
|
2736
|
+
children: /* @__PURE__ */jsx(Text, {
|
|
2668
2737
|
sx: {
|
|
2669
|
-
|
|
2738
|
+
fontSize: "xs",
|
|
2739
|
+
color: "text.secondary"
|
|
2670
2740
|
},
|
|
2671
|
-
children:
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2741
|
+
children: caption
|
|
2742
|
+
})
|
|
2743
|
+
}), !hasTitle && onClose && /* @__PURE__ */jsx(Box, {
|
|
2744
|
+
sx: {
|
|
2745
|
+
alignSelf: "flex-end"
|
|
2746
|
+
},
|
|
2747
|
+
children: /* @__PURE__ */jsx(CloseButton, {
|
|
2748
|
+
onClick: onClose
|
|
2749
|
+
})
|
|
2750
|
+
})]
|
|
2751
|
+
});
|
|
2752
|
+
};
|
|
2753
|
+
var NotificationCard = props => {
|
|
2754
|
+
const hasTitle = Boolean(props.title);
|
|
2755
|
+
return /* @__PURE__ */jsxs(Card, {
|
|
2756
|
+
sx: {
|
|
2757
|
+
...sxMap[props.type].card,
|
|
2758
|
+
width: "full"
|
|
2759
|
+
},
|
|
2760
|
+
children: [props.title && /* @__PURE__ */jsx(NotificationCardTitle, {
|
|
2761
|
+
type: props.type,
|
|
2762
|
+
title: props.title,
|
|
2763
|
+
tags: props.tags,
|
|
2764
|
+
onClose: props.onClose
|
|
2765
|
+
}), /* @__PURE__ */jsx(NotificationCardBody, {
|
|
2766
|
+
type: props.type,
|
|
2767
|
+
message: props.message,
|
|
2768
|
+
actions: props.actions,
|
|
2769
|
+
caption: props.caption,
|
|
2770
|
+
onClose: props.onClose,
|
|
2771
|
+
hasTitle
|
|
2675
2772
|
})]
|
|
2676
2773
|
});
|
|
2677
2774
|
};
|
|
@@ -2883,6 +2980,327 @@ var NotificationsMenu = ({
|
|
|
2883
2980
|
});
|
|
2884
2981
|
};
|
|
2885
2982
|
|
|
2983
|
+
//#endregion
|
|
2984
|
+
//#region src/components/OAuthConsent/OAuthConsent.tsx
|
|
2985
|
+
/**
|
|
2986
|
+
* Walk the scope tree and return the minimal set of granted scope keys.
|
|
2987
|
+
* When a node is selected, its key is emitted and its subtree is skipped
|
|
2988
|
+
* (the server expands parent scopes to their children). Nodes not in
|
|
2989
|
+
* `selected` are recursed into so that individually-selected children
|
|
2990
|
+
* are still captured.
|
|
2991
|
+
*/
|
|
2992
|
+
var collectGrantedScopes = (scopes, selected) => {
|
|
2993
|
+
const result = [];
|
|
2994
|
+
const walk = nodes => {
|
|
2995
|
+
for (const node of nodes) if (selected.has(node.key)) result.push(node.key);else if (node.children) walk(node.children);
|
|
2996
|
+
};
|
|
2997
|
+
walk(scopes);
|
|
2998
|
+
return result;
|
|
2999
|
+
};
|
|
3000
|
+
var initSelected = scopes => {
|
|
3001
|
+
const selected = /* @__PURE__ */new Set();
|
|
3002
|
+
const walk = nodes => {
|
|
3003
|
+
for (const node of nodes) {
|
|
3004
|
+
if (node.required || node.defaultGranted) selected.add(node.key);
|
|
3005
|
+
if (node.children) walk(node.children);
|
|
3006
|
+
}
|
|
3007
|
+
};
|
|
3008
|
+
walk(scopes);
|
|
3009
|
+
return selected;
|
|
3010
|
+
};
|
|
3011
|
+
var getScopeRowState = ({
|
|
3012
|
+
scope,
|
|
3013
|
+
ancestorSelected,
|
|
3014
|
+
selected,
|
|
3015
|
+
busy
|
|
3016
|
+
}) => {
|
|
3017
|
+
const isChecked = ancestorSelected || selected.has(scope.key);
|
|
3018
|
+
const isLocked = !!scope.required || ancestorSelected;
|
|
3019
|
+
return {
|
|
3020
|
+
isChecked,
|
|
3021
|
+
isDisabled: isLocked || busy,
|
|
3022
|
+
isInteractive: !isLocked && !busy
|
|
3023
|
+
};
|
|
3024
|
+
};
|
|
3025
|
+
var ScopeRow = ({
|
|
3026
|
+
scope,
|
|
3027
|
+
ancestorSelected,
|
|
3028
|
+
selected,
|
|
3029
|
+
busy,
|
|
3030
|
+
onToggle
|
|
3031
|
+
}) => {
|
|
3032
|
+
const {
|
|
3033
|
+
isChecked,
|
|
3034
|
+
isDisabled,
|
|
3035
|
+
isInteractive
|
|
3036
|
+
} = getScopeRowState({
|
|
3037
|
+
scope,
|
|
3038
|
+
ancestorSelected,
|
|
3039
|
+
selected,
|
|
3040
|
+
busy
|
|
3041
|
+
});
|
|
3042
|
+
const checkboxId = `consent-scope-${scope.key}`;
|
|
3043
|
+
const descId = `consent-scope-desc-${scope.key}`;
|
|
3044
|
+
return /* @__PURE__ */jsxs(Box, {
|
|
3045
|
+
as: "li",
|
|
3046
|
+
sx: {
|
|
3047
|
+
listStyle: "none"
|
|
3048
|
+
},
|
|
3049
|
+
children: [/* @__PURE__ */jsxs(Flex, {
|
|
3050
|
+
sx: {
|
|
3051
|
+
gap: 3,
|
|
3052
|
+
alignItems: "flex-start",
|
|
3053
|
+
paddingX: 3,
|
|
3054
|
+
paddingY: 3,
|
|
3055
|
+
borderRadius: "md",
|
|
3056
|
+
opacity: ancestorSelected ? .55 : 1,
|
|
3057
|
+
transition: "background-color 0.15s ease",
|
|
3058
|
+
...(isInteractive && {
|
|
3059
|
+
"&:hover": {
|
|
3060
|
+
backgroundColor: "display.background.muted.default"
|
|
3061
|
+
}
|
|
3062
|
+
})
|
|
3063
|
+
},
|
|
3064
|
+
children: [/* @__PURE__ */jsx(Box, {
|
|
3065
|
+
sx: {
|
|
3066
|
+
paddingTop: "3px",
|
|
3067
|
+
flexShrink: 0
|
|
3068
|
+
},
|
|
3069
|
+
children: /* @__PURE__ */jsx(Checkbox, {
|
|
3070
|
+
id: checkboxId,
|
|
3071
|
+
checked: isChecked,
|
|
3072
|
+
disabled: isDisabled,
|
|
3073
|
+
"aria-describedby": descId,
|
|
3074
|
+
onChange: () => {
|
|
3075
|
+
onToggle(scope, ancestorSelected);
|
|
3076
|
+
}
|
|
3077
|
+
})
|
|
3078
|
+
}), /* @__PURE__ */jsxs(Box, {
|
|
3079
|
+
sx: {
|
|
3080
|
+
flex: 1,
|
|
3081
|
+
minWidth: 0
|
|
3082
|
+
},
|
|
3083
|
+
children: [/* @__PURE__ */jsx(Label, {
|
|
3084
|
+
htmlFor: checkboxId,
|
|
3085
|
+
sx: {
|
|
3086
|
+
fontWeight: "semibold",
|
|
3087
|
+
fontSize: "md",
|
|
3088
|
+
lineHeight: "short",
|
|
3089
|
+
cursor: isInteractive ? "pointer" : "default",
|
|
3090
|
+
color: "display.text.primary.default",
|
|
3091
|
+
width: "fit-content"
|
|
3092
|
+
},
|
|
3093
|
+
children: scope.label
|
|
3094
|
+
}), /* @__PURE__ */jsx(Text, {
|
|
3095
|
+
id: descId,
|
|
3096
|
+
sx: {
|
|
3097
|
+
fontSize: "sm",
|
|
3098
|
+
lineHeight: "short",
|
|
3099
|
+
color: "display.text.muted.default",
|
|
3100
|
+
display: "block",
|
|
3101
|
+
marginTop: "1"
|
|
3102
|
+
},
|
|
3103
|
+
children: scope.description
|
|
3104
|
+
})]
|
|
3105
|
+
})]
|
|
3106
|
+
}), scope.children?.length ? /* @__PURE__ */jsx(Box, {
|
|
3107
|
+
as: "ul",
|
|
3108
|
+
sx: {
|
|
3109
|
+
listStyle: "none",
|
|
3110
|
+
margin: 0,
|
|
3111
|
+
padding: 0,
|
|
3112
|
+
marginLeft: 5,
|
|
3113
|
+
paddingLeft: 2,
|
|
3114
|
+
borderLeft: "sm",
|
|
3115
|
+
borderColor: "display.border.muted.default"
|
|
3116
|
+
},
|
|
3117
|
+
children: scope.children?.map(child => {
|
|
3118
|
+
return /* @__PURE__ */jsx(ScopeRow, {
|
|
3119
|
+
scope: child,
|
|
3120
|
+
ancestorSelected: isChecked,
|
|
3121
|
+
selected,
|
|
3122
|
+
busy,
|
|
3123
|
+
onToggle
|
|
3124
|
+
}, child.key);
|
|
3125
|
+
})
|
|
3126
|
+
}) : null]
|
|
3127
|
+
});
|
|
3128
|
+
};
|
|
3129
|
+
/** Shared centered card shell for the consent and invalid-request views. */
|
|
3130
|
+
var ConsentCard = ({
|
|
3131
|
+
children
|
|
3132
|
+
}) => {
|
|
3133
|
+
return /* @__PURE__ */jsx(Flex, {
|
|
3134
|
+
sx: {
|
|
3135
|
+
justifyContent: "center",
|
|
3136
|
+
paddingX: 4,
|
|
3137
|
+
paddingY: 6
|
|
3138
|
+
},
|
|
3139
|
+
children: /* @__PURE__ */jsx(Card, {
|
|
3140
|
+
sx: {
|
|
3141
|
+
width: "100%",
|
|
3142
|
+
maxWidth: 480,
|
|
3143
|
+
alignItems: "stretch",
|
|
3144
|
+
padding: 6
|
|
3145
|
+
},
|
|
3146
|
+
children
|
|
3147
|
+
})
|
|
3148
|
+
});
|
|
3149
|
+
};
|
|
3150
|
+
/**
|
|
3151
|
+
* Accessible, framework-agnostic OAuth consent screen component.
|
|
3152
|
+
*
|
|
3153
|
+
* Renders a standards-compliant "authorize this client" page with support for
|
|
3154
|
+
* flat and GitHub-style grouped/hierarchical scopes. Granting a parent scope
|
|
3155
|
+
* automatically locks all descendant scopes (checked + disabled). All visible
|
|
3156
|
+
* copy is injected via `labels`; no strings are hardcoded inside this component.
|
|
3157
|
+
*
|
|
3158
|
+
* @example
|
|
3159
|
+
* ```tsx
|
|
3160
|
+
* <OAuthConsent
|
|
3161
|
+
* clientName="My App"
|
|
3162
|
+
* scopes={[
|
|
3163
|
+
* { key: 'read', label: 'Read', description: 'Read access', required: true },
|
|
3164
|
+
* { key: 'write', label: 'Write', description: 'Write access' },
|
|
3165
|
+
* ]}
|
|
3166
|
+
* onAuthorize={async (scopes) => {
|
|
3167
|
+
* const res = await authorize({ variables: { scopes } });
|
|
3168
|
+
* return { ok: !!res.ok };
|
|
3169
|
+
* }}
|
|
3170
|
+
* onAuthorized={() => { window.location.href = resumeUrl; }}
|
|
3171
|
+
* onDeny={() => navigate('/')}
|
|
3172
|
+
* labels={labels}
|
|
3173
|
+
* />
|
|
3174
|
+
* ```
|
|
3175
|
+
*/
|
|
3176
|
+
var OAuthConsent = ({
|
|
3177
|
+
clientName,
|
|
3178
|
+
scopes,
|
|
3179
|
+
onAuthorize,
|
|
3180
|
+
onAuthorized,
|
|
3181
|
+
onDeny,
|
|
3182
|
+
isAuthorizing = false,
|
|
3183
|
+
isValidRequest = true,
|
|
3184
|
+
labels
|
|
3185
|
+
}) => {
|
|
3186
|
+
const [selected, setSelected] = React.useState(() => {
|
|
3187
|
+
return initSelected(scopes);
|
|
3188
|
+
});
|
|
3189
|
+
const [isLoading, setIsLoading] = React.useState(false);
|
|
3190
|
+
const busy = isAuthorizing || isLoading;
|
|
3191
|
+
const handleToggle = React.useCallback((scope, ancestorSelected) => {
|
|
3192
|
+
if (scope.required || ancestorSelected) return;
|
|
3193
|
+
setSelected(prev => {
|
|
3194
|
+
const next = new Set(prev);
|
|
3195
|
+
if (next.has(scope.key)) next.delete(scope.key);else next.add(scope.key);
|
|
3196
|
+
return next;
|
|
3197
|
+
});
|
|
3198
|
+
}, []);
|
|
3199
|
+
const handleApprove = React.useCallback(async () => {
|
|
3200
|
+
const grantedScopes = collectGrantedScopes(scopes, selected);
|
|
3201
|
+
setIsLoading(true);
|
|
3202
|
+
try {
|
|
3203
|
+
if ((await onAuthorize(grantedScopes)).ok) onAuthorized();
|
|
3204
|
+
} finally {
|
|
3205
|
+
setIsLoading(false);
|
|
3206
|
+
}
|
|
3207
|
+
}, [scopes, selected, onAuthorize, onAuthorized]);
|
|
3208
|
+
if (!isValidRequest) return /* @__PURE__ */jsxs(ConsentCard, {
|
|
3209
|
+
children: [/* @__PURE__ */jsx(Heading, {
|
|
3210
|
+
as: "h1",
|
|
3211
|
+
sx: {
|
|
3212
|
+
fontSize: "3xl",
|
|
3213
|
+
color: "display.text.primary.default",
|
|
3214
|
+
marginBottom: 3
|
|
3215
|
+
},
|
|
3216
|
+
children: labels.invalidRequestTitle
|
|
3217
|
+
}), /* @__PURE__ */jsx(Text, {
|
|
3218
|
+
sx: {
|
|
3219
|
+
fontSize: "md",
|
|
3220
|
+
lineHeight: "moderate",
|
|
3221
|
+
color: "display.text.secondary.default"
|
|
3222
|
+
},
|
|
3223
|
+
children: labels.invalidRequestBody
|
|
3224
|
+
})]
|
|
3225
|
+
});
|
|
3226
|
+
return /* @__PURE__ */jsxs(ConsentCard, {
|
|
3227
|
+
children: [/* @__PURE__ */jsx(Heading, {
|
|
3228
|
+
as: "h1",
|
|
3229
|
+
sx: {
|
|
3230
|
+
fontSize: "3xl",
|
|
3231
|
+
lineHeight: "shorter",
|
|
3232
|
+
color: "display.text.primary.default",
|
|
3233
|
+
marginBottom: 2
|
|
3234
|
+
},
|
|
3235
|
+
children: labels.title
|
|
3236
|
+
}), /* @__PURE__ */jsx(Text, {
|
|
3237
|
+
sx: {
|
|
3238
|
+
fontSize: "md",
|
|
3239
|
+
lineHeight: "moderate",
|
|
3240
|
+
color: "display.text.secondary.default"
|
|
3241
|
+
},
|
|
3242
|
+
children: labels.requestedBy(clientName)
|
|
3243
|
+
}), /* @__PURE__ */jsx(Divider, {
|
|
3244
|
+
sx: {
|
|
3245
|
+
marginY: 5,
|
|
3246
|
+
borderColor: "display.border.muted.default"
|
|
3247
|
+
}
|
|
3248
|
+
}), /* @__PURE__ */jsx(Heading, {
|
|
3249
|
+
as: "h3",
|
|
3250
|
+
sx: {
|
|
3251
|
+
fontSize: "xs",
|
|
3252
|
+
fontWeight: "semibold",
|
|
3253
|
+
letterSpacing: "wider",
|
|
3254
|
+
textTransform: "uppercase",
|
|
3255
|
+
color: "display.text.muted.default",
|
|
3256
|
+
marginBottom: 2
|
|
3257
|
+
},
|
|
3258
|
+
children: labels.permissionsHeading
|
|
3259
|
+
}), /* @__PURE__ */jsx(Box, {
|
|
3260
|
+
as: "ul",
|
|
3261
|
+
sx: {
|
|
3262
|
+
listStyle: "none",
|
|
3263
|
+
margin: 0,
|
|
3264
|
+
padding: 0
|
|
3265
|
+
},
|
|
3266
|
+
children: scopes.map(scope => {
|
|
3267
|
+
return /* @__PURE__ */jsx(ScopeRow, {
|
|
3268
|
+
scope,
|
|
3269
|
+
ancestorSelected: false,
|
|
3270
|
+
selected,
|
|
3271
|
+
busy,
|
|
3272
|
+
onToggle: handleToggle
|
|
3273
|
+
}, scope.key);
|
|
3274
|
+
})
|
|
3275
|
+
}), /* @__PURE__ */jsxs(Flex, {
|
|
3276
|
+
sx: {
|
|
3277
|
+
gap: 3,
|
|
3278
|
+
marginTop: 6
|
|
3279
|
+
},
|
|
3280
|
+
children: [/* @__PURE__ */jsx(Button, {
|
|
3281
|
+
variant: "secondary",
|
|
3282
|
+
onClick: onDeny,
|
|
3283
|
+
disabled: busy,
|
|
3284
|
+
sx: {
|
|
3285
|
+
flex: 1,
|
|
3286
|
+
justifyContent: "center"
|
|
3287
|
+
},
|
|
3288
|
+
children: labels.deny
|
|
3289
|
+
}), /* @__PURE__ */jsx(Button, {
|
|
3290
|
+
variant: "accent",
|
|
3291
|
+
onClick: handleApprove,
|
|
3292
|
+
disabled: busy,
|
|
3293
|
+
loading: isLoading || isAuthorizing,
|
|
3294
|
+
sx: {
|
|
3295
|
+
flex: 1,
|
|
3296
|
+
justifyContent: "center"
|
|
3297
|
+
},
|
|
3298
|
+
children: labels.approve
|
|
3299
|
+
})]
|
|
3300
|
+
})]
|
|
3301
|
+
});
|
|
3302
|
+
};
|
|
3303
|
+
|
|
2886
3304
|
//#endregion
|
|
2887
3305
|
//#region src/components/Search/Search.tsx
|
|
2888
3306
|
var Search = ({
|
|
@@ -3081,4 +3499,4 @@ var ToastContainer = props => {
|
|
|
3081
3499
|
var toast = toast$1;
|
|
3082
3500
|
|
|
3083
3501
|
//#endregion
|
|
3084
|
-
export { Accordion, DatePicker, Drawer, EnhancedTitle, FileUploader, InstallPwa, InstallPwaUi, JsonEditor, JsonView, List, ListItem, LockedOverlay, Markdown, Menu, MetricCard, Modal, NavList, NotificationCard, NotificationsMenu, Search, SpotlightCard, Table, Tabs, ToastContainer, createCell, createColumnHelper, flexRender, getCoreRowModel, toast, useReactTable };
|
|
3502
|
+
export { Accordion, DatePicker, Drawer, EnhancedTitle, FileUploader, InstallPwa, InstallPwaUi, JsonEditor, JsonView, List, ListItem, LockedOverlay, Markdown, Menu, MetricCard, Modal, NavList, NotificationButton, NotificationCard, NotificationsMenu, OAuthConsent, Search, SpotlightCard, Table, Tabs, ToastContainer, collectGrantedScopes, createCell, createColumnHelper, flexRender, getCoreRowModel, toast, useReactTable };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttoss/components",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.16.0",
|
|
4
4
|
"description": "React components for ttoss ecosystem.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"React",
|
|
@@ -54,19 +54,19 @@
|
|
|
54
54
|
"tsdown": "^0.22.2",
|
|
55
55
|
"tsx": "^4.21.0",
|
|
56
56
|
"@ttoss/config": "^1.37.17",
|
|
57
|
-
"@ttoss/i18n-cli": "^0.8.17",
|
|
58
|
-
"@ttoss/react-i18n": "^2.2.21",
|
|
59
57
|
"@ttoss/react-hooks": "^2.3.20",
|
|
60
58
|
"@ttoss/react-icons": "^0.7.21",
|
|
61
|
-
"@ttoss/
|
|
62
|
-
"@ttoss/test-utils": "^4.2.18"
|
|
59
|
+
"@ttoss/react-i18n": "^2.3.0",
|
|
60
|
+
"@ttoss/test-utils": "^4.2.18",
|
|
61
|
+
"@ttoss/i18n-cli": "^0.8.17",
|
|
62
|
+
"@ttoss/ui": "^6.9.28"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
65
65
|
"react": ">=16.8.0",
|
|
66
66
|
"@ttoss/react-hooks": "^2.3.20",
|
|
67
|
+
"@ttoss/react-i18n": "^2.3.0",
|
|
67
68
|
"@ttoss/react-icons": "^0.7.21",
|
|
68
|
-
"@ttoss/
|
|
69
|
-
"@ttoss/ui": "^6.9.27"
|
|
69
|
+
"@ttoss/ui": "^6.9.28"
|
|
70
70
|
},
|
|
71
71
|
"publishConfig": {
|
|
72
72
|
"access": "public",
|