@edifice.io/react 2.6.6-develop-b2school.20260924174112 → 2.6.6-develop-b2school.20260925172645
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/dist/components/Input/Input.js +8 -3
- package/dist/components/LinkPill/LinkPill.d.ts +3 -7
- package/dist/components/LinkPill/LinkPill.js +3 -2
- package/dist/homepage.js +4 -0
- package/dist/hooks/useZendeskGuide/useZendeskGuide.js +1 -2
- package/dist/icons.js +404 -402
- package/dist/modules/homepage/components/Favorites/Favorites.js +2 -2
- package/dist/modules/homepage/components/HomeCard/HomeCard.d.ts +1 -1
- package/dist/modules/homepage/components/HomeCard/HomeCardHeader.d.ts +15 -1
- package/dist/modules/homepage/components/HomeCard/HomeCardHeader.js +2 -1
- package/dist/modules/homepage/components/Notifications/components/ReportNotificationModal.js +1 -1
- package/dist/modules/homepage/components/UsefulLinks/LinkForm.js +9 -9
- package/dist/modules/homepage/components/UsefulLinks/UsefulLinks.js +5 -3
- package/dist/modules/homepage/components/UsefulLinks/UsefulLinksModal.js +9 -9
- package/dist/modules/homepage/components/UserSpace/UserSpace.d.ts +3 -1
- package/dist/modules/homepage/components/UserSpace/UserSpace.js +13 -7
- package/dist/modules/homepage/components/UserSpace/UserSpaceContainer.d.ts +4 -2
- package/dist/modules/homepage/components/UserSpace/UserSpaceContainer.js +3 -2
- package/dist/modules/homepage/components/WidgetsPersonalizationPanel/WidgetToggle.d.ts +16 -0
- package/dist/modules/homepage/components/WidgetsPersonalizationPanel/WidgetToggle.js +15 -0
- package/dist/modules/homepage/components/WidgetsPersonalizationPanel/WidgetsPersonalizationPanel.d.ts +21 -0
- package/dist/modules/homepage/components/WidgetsPersonalizationPanel/WidgetsPersonalizationPanel.js +47 -0
- package/dist/modules/homepage/components/WidgetsPersonalizationPanel/index.d.ts +2 -0
- package/dist/modules/homepage/components/index.d.ts +1 -0
- package/dist/modules/icons/components/IconAddWidget.d.ts +7 -0
- package/dist/modules/icons/components/IconAddWidget.js +12 -0
- package/dist/modules/icons/components/index.d.ts +1 -0
- package/package.json +6 -6
|
@@ -16,10 +16,10 @@ function Favorites({
|
|
|
16
16
|
sensitivity: "base"
|
|
17
17
|
})), [apps, t]);
|
|
18
18
|
return /* @__PURE__ */ jsxs(HomeCard, { variant: "secondary", children: [
|
|
19
|
-
/* @__PURE__ */ jsx(HomeCard.Header, { title: t("homepage.favorites.title"
|
|
19
|
+
/* @__PURE__ */ jsx(HomeCard.Header, { title: t("homepage.favorites.title"), actionLabel: t("homepage.favorites.all"), onActionClick: onSeeAllClick, actionRightIcon: /* @__PURE__ */ jsx(SvgIconArrowRight, {}) }),
|
|
20
20
|
/* @__PURE__ */ jsx(HomeCard.Content, { children: /* @__PURE__ */ jsx("div", { className: "favorites-content", children: visibleApps.length === 0 ? /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "12", children: [
|
|
21
21
|
/* @__PURE__ */ jsx("img", { src: illuEmptyFavorite, alt: "", width: 50, height: 50 }),
|
|
22
|
-
/* @__PURE__ */ jsx("span", { className: "favorites-empty-text", children: t("homepage.favorites.empty"
|
|
22
|
+
/* @__PURE__ */ jsx("span", { className: "favorites-empty-text", children: t("homepage.favorites.empty") })
|
|
23
23
|
] }) : /* @__PURE__ */ jsx(Flex, { wrap: "wrap", gap: "8 16", children: visibleApps.map((app) => {
|
|
24
24
|
const appName = getAppName(app), opensInNewTab = app.isExternal || app.target === "_blank";
|
|
25
25
|
return /* @__PURE__ */ jsx("a", { href: app.address, "aria-label": appName, title: appName, target: opensInNewTab ? "_blank" : void 0, rel: opensInNewTab ? "noopener noreferrer" : void 0, children: /* @__PURE__ */ jsx(AppIcon, { app, size: "40", variant: "square" }) }, app.name);
|
|
@@ -30,7 +30,7 @@ declare const HomeCard: {
|
|
|
30
30
|
displayName: string;
|
|
31
31
|
} & {
|
|
32
32
|
Header: {
|
|
33
|
-
({ title, actionLabel, onActionClick, actionLeftIcon, actionRightIcon, className, ...rest }: HomeCardHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
({ title, actionLabel, onActionClick, actionLeftIcon, actionRightIcon, actionProps, className, ...rest }: HomeCardHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
34
34
|
displayName: string;
|
|
35
35
|
};
|
|
36
36
|
Content: {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ComponentPropsWithoutRef, MouseEventHandler, ReactNode } from 'react';
|
|
2
|
+
import { ButtonBeta } from '../../../../components';
|
|
2
3
|
export interface HomeCardHeaderProps extends Omit<ComponentPropsWithoutRef<'div'>, 'title'> {
|
|
3
4
|
/** Title displayed on the left side of the header. */
|
|
4
5
|
title: ReactNode;
|
|
@@ -10,9 +11,22 @@ export interface HomeCardHeaderProps extends Omit<ComponentPropsWithoutRef<'div'
|
|
|
10
11
|
actionLeftIcon?: ReactNode;
|
|
11
12
|
/** Optional right icon of the action button. */
|
|
12
13
|
actionRightIcon?: ReactNode;
|
|
14
|
+
/**
|
|
15
|
+
* Extra props spread onto the action button (e.g. `data-testid`) — its
|
|
16
|
+
* default `data-testid` (`home-card-header-action`) isn't unique across
|
|
17
|
+
* the several `HomeCard`s a page can render, so consumers doing that
|
|
18
|
+
* should override it here. The `data-*` index signature covers
|
|
19
|
+
* attributes like `data-testid` that `ButtonBetaProps` doesn't declare:
|
|
20
|
+
* TypeScript's built-in allowance for undeclared `data-*`/`aria-*`
|
|
21
|
+
* attributes only applies to attributes written directly on a JSX
|
|
22
|
+
* element, not to a plain object literal passed as a prop value.
|
|
23
|
+
*/
|
|
24
|
+
actionProps?: ComponentPropsWithoutRef<typeof ButtonBeta> & {
|
|
25
|
+
[key: `data-${string}`]: string;
|
|
26
|
+
};
|
|
13
27
|
}
|
|
14
28
|
declare const HomeCardHeader: {
|
|
15
|
-
({ title, actionLabel, onActionClick, actionLeftIcon, actionRightIcon, className, ...rest }: HomeCardHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
({ title, actionLabel, onActionClick, actionLeftIcon, actionRightIcon, actionProps, className, ...rest }: HomeCardHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
16
30
|
displayName: string;
|
|
17
31
|
};
|
|
18
32
|
export default HomeCardHeader;
|
|
@@ -8,13 +8,14 @@ const HomeCardHeader = ({
|
|
|
8
8
|
onActionClick,
|
|
9
9
|
actionLeftIcon,
|
|
10
10
|
actionRightIcon,
|
|
11
|
+
actionProps,
|
|
11
12
|
className,
|
|
12
13
|
...rest
|
|
13
14
|
}) => {
|
|
14
15
|
const hasAction = !!actionLabel && !!onActionClick;
|
|
15
16
|
return /* @__PURE__ */ jsxs(Flex, { align: "center", justify: "between", gap: "8", className: clsx("home-card-header", className), ...rest, children: [
|
|
16
17
|
/* @__PURE__ */ jsx("h3", { className: "home-card-header-title", children: title }),
|
|
17
|
-
hasAction && /* @__PURE__ */ jsx(ButtonBeta, { color: "tertiary", size: "sm", variant: "ghost", onClick: onActionClick, leftIcon: actionLeftIcon, rightIcon: actionRightIcon, "data-testid": "home-card-header-action", children: actionLabel })
|
|
18
|
+
hasAction && /* @__PURE__ */ jsx(ButtonBeta, { color: "tertiary", size: "sm", variant: "ghost", onClick: onActionClick, leftIcon: actionLeftIcon, rightIcon: actionRightIcon, "data-testid": "home-card-header-action", ...actionProps, children: actionLabel })
|
|
18
19
|
] });
|
|
19
20
|
};
|
|
20
21
|
export {
|
package/dist/modules/homepage/components/Notifications/components/ReportNotificationModal.js
CHANGED
|
@@ -11,7 +11,7 @@ const ReportNotificationModal = ({
|
|
|
11
11
|
const {
|
|
12
12
|
t
|
|
13
13
|
} = useTranslation();
|
|
14
|
-
return /* @__PURE__ */ jsxs(Modal, { id: "report-notification-modal", size: "
|
|
14
|
+
return /* @__PURE__ */ jsxs(Modal, { id: "report-notification-modal", size: "sm", isOpen, onModalClose: onCancel, children: [
|
|
15
15
|
/* @__PURE__ */ jsx(Modal.Header, { onModalClose: onCancel, children: t("homepage.notifications.report-modal.title", {
|
|
16
16
|
defaultValue: "Signaler une notification"
|
|
17
17
|
}) }),
|
|
@@ -6,7 +6,7 @@ import FormControl from "../../../../components/Form/FormControl.js";
|
|
|
6
6
|
import Label from "../../../../components/Label/Label.js";
|
|
7
7
|
import Input from "../../../../components/Input/Input.js";
|
|
8
8
|
import ButtonBeta from "../../../../components/ButtonBeta/ButtonBeta.js";
|
|
9
|
-
const NAME_MAX_LENGTH = 80,
|
|
9
|
+
const NAME_MAX_LENGTH = 80, URL_PATTERN = /^https?:\/\/.+/i;
|
|
10
10
|
function LinkForm({
|
|
11
11
|
mode,
|
|
12
12
|
link,
|
|
@@ -31,7 +31,7 @@ function LinkForm({
|
|
|
31
31
|
name: (link == null ? void 0 : link.name) ?? "",
|
|
32
32
|
url: (link == null ? void 0 : link.url) ?? ""
|
|
33
33
|
}
|
|
34
|
-
}), title = mode === "add" ?
|
|
34
|
+
}), title = t(mode === "add" ? "homepage.usefulLinks.form.addTitle" : "homepage.usefulLinks.form.editTitle"), handleFormSubmit = (data) => {
|
|
35
35
|
onSubmit({
|
|
36
36
|
name: data.name.trim(),
|
|
37
37
|
url: data.url.trim()
|
|
@@ -41,24 +41,24 @@ function LinkForm({
|
|
|
41
41
|
/* @__PURE__ */ jsx(ModalBeta.Header, { onModalClose: onClose, children: title }),
|
|
42
42
|
/* @__PURE__ */ jsx(ModalBeta.Body, { children: /* @__PURE__ */ jsxs("form", { id: formId, onSubmit: handleSubmit(handleFormSubmit), children: [
|
|
43
43
|
/* @__PURE__ */ jsxs(FormControl, { id: "useful-link-name", className: "mb-16", isRequired: !0, children: [
|
|
44
|
-
/* @__PURE__ */ jsx(Label, { children: t("homepage.usefulLinks.form.name"
|
|
45
|
-
/* @__PURE__ */ jsx(Input, { type: "text", size: "md", maxLength: NAME_MAX_LENGTH, showCounter: !0, clearable: !0, "data-testid": "usefullinks-input-name", placeholder: t("homepage.usefulLinks.form.name.placeholder"
|
|
44
|
+
/* @__PURE__ */ jsx(Label, { children: t("homepage.usefulLinks.form.name") }),
|
|
45
|
+
/* @__PURE__ */ jsx(Input, { type: "text", size: "md", maxLength: NAME_MAX_LENGTH, showCounter: !0, clearable: !0, "data-testid": "usefullinks-input-name", placeholder: t("homepage.usefulLinks.form.name.placeholder"), ...register("name", {
|
|
46
46
|
required: !0,
|
|
47
47
|
maxLength: NAME_MAX_LENGTH
|
|
48
48
|
}) })
|
|
49
49
|
] }),
|
|
50
50
|
/* @__PURE__ */ jsxs(FormControl, { id: "useful-link-url", isRequired: !0, status: errors.url ? "invalid" : void 0, children: [
|
|
51
|
-
/* @__PURE__ */ jsx(Label, { children: t("homepage.usefulLinks.form.url"
|
|
52
|
-
/* @__PURE__ */ jsx(Input, { type: "text", size: "md", "data-testid": "usefullinks-input-url", placeholder: t("homepage.usefulLinks.form.url.placeholder"
|
|
51
|
+
/* @__PURE__ */ jsx(Label, { children: t("homepage.usefulLinks.form.url") }),
|
|
52
|
+
/* @__PURE__ */ jsx(Input, { type: "text", size: "md", "data-testid": "usefullinks-input-url", placeholder: t("homepage.usefulLinks.form.url.placeholder"), ...register("url", {
|
|
53
53
|
required: !0,
|
|
54
54
|
pattern: URL_PATTERN
|
|
55
55
|
}) }),
|
|
56
|
-
errors.url && /* @__PURE__ */ jsx(FormControl.Text, { children: t("homepage.usefulLinks.form.url.error"
|
|
56
|
+
errors.url && /* @__PURE__ */ jsx(FormControl.Text, { children: t("homepage.usefulLinks.form.url.error") })
|
|
57
57
|
] })
|
|
58
58
|
] }) }),
|
|
59
59
|
/* @__PURE__ */ jsxs(ModalBeta.Footer, { children: [
|
|
60
|
-
/* @__PURE__ */ jsx(ButtonBeta, { type: "button", variant: "ghost", color: "tertiary", "data-testid": "usefullinks-button-cancel", onClick: onCancel, children: t("homepage.usefulLinks.form.cancel"
|
|
61
|
-
/* @__PURE__ */ jsx(ButtonBeta, { form: formId, type: "submit", isLoading: isSubmitting, disabled: !isValid || !isDirty || isSubmitting, "data-testid": "usefullinks-button-save", children: t("homepage.usefulLinks.form.save"
|
|
60
|
+
/* @__PURE__ */ jsx(ButtonBeta, { type: "button", variant: "ghost", color: "tertiary", "data-testid": "usefullinks-button-cancel", onClick: onCancel, children: t("homepage.usefulLinks.form.cancel") }),
|
|
61
|
+
/* @__PURE__ */ jsx(ButtonBeta, { form: formId, type: "submit", isLoading: isSubmitting, disabled: !isValid || !isDirty || isSubmitting, "data-testid": "usefullinks-button-save", children: t("homepage.usefulLinks.form.save") })
|
|
62
62
|
] })
|
|
63
63
|
] });
|
|
64
64
|
}
|
|
@@ -14,14 +14,16 @@ function UsefulLinks({
|
|
|
14
14
|
t
|
|
15
15
|
} = useTranslation();
|
|
16
16
|
return /* @__PURE__ */ jsxs(HomeCard, { variant: "primary", children: [
|
|
17
|
-
/* @__PURE__ */ jsx(HomeCard.Header, { title: t("homepage.usefulLinks.title"
|
|
17
|
+
/* @__PURE__ */ jsx(HomeCard.Header, { title: t("homepage.usefulLinks.title"), actionLabel: t("homepage.usefulLinks.edit"), actionLeftIcon: /* @__PURE__ */ jsx(SvgIconEdit, {}), onActionClick: onEditClick, actionProps: {
|
|
18
|
+
"data-testid": "usefullinks-button-edit"
|
|
19
|
+
} }),
|
|
18
20
|
/* @__PURE__ */ jsx(HomeCard.Content, { children: links.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "useful-links-widget__empty", children: [
|
|
19
21
|
/* @__PURE__ */ jsx(Image, { src: illuEmptyUsefulLinks, alt: "", "aria-hidden": "true", style: {
|
|
20
22
|
width: 160,
|
|
21
23
|
height: 87
|
|
22
24
|
} }),
|
|
23
|
-
/* @__PURE__ */ jsx("p", { className: "useful-links-widget__empty-text", children: t("homepage.usefulLinks.empty"
|
|
24
|
-
] }) : /* @__PURE__ */ jsx(Flex, { direction: "column", gap: "8", children: links.map((link) => /* @__PURE__ */ jsx(LinkPill, { href: link.url, label: link.name }, link.id)) }) })
|
|
25
|
+
/* @__PURE__ */ jsx("p", { className: "useful-links-widget__empty-text", children: t("homepage.usefulLinks.empty") })
|
|
26
|
+
] }) : /* @__PURE__ */ jsx(Flex, { direction: "column", gap: "8", children: links.map((link) => /* @__PURE__ */ jsx(LinkPill, { href: link.url, label: link.name, "data-testid": `usefullinks-link-${link.id}` }, link.id)) }) })
|
|
25
27
|
] });
|
|
26
28
|
}
|
|
27
29
|
export {
|
|
@@ -23,9 +23,9 @@ function UsefulLinksModal({
|
|
|
23
23
|
t
|
|
24
24
|
} = useTranslation(), {
|
|
25
25
|
md
|
|
26
|
-
} = useBreakpoint(), addLinkButton = /* @__PURE__ */ jsx(ButtonBeta, { type: "button", variant: "outline", leftIcon: /* @__PURE__ */ jsx(SvgIconPlus, {}), onClick: onAddClick, disabled: !canAddLink, "data-testid": "usefullinks-button-add", children: t("homepage.usefulLinks.modal.add"
|
|
26
|
+
} = useBreakpoint(), addLinkButton = /* @__PURE__ */ jsx(ButtonBeta, { type: "button", variant: "outline", leftIcon: /* @__PURE__ */ jsx(SvgIconPlus, {}), onClick: onAddClick, disabled: !canAddLink, "data-testid": "usefullinks-button-add", children: t("homepage.usefulLinks.modal.add") });
|
|
27
27
|
return /* @__PURE__ */ jsxs(ModalBeta, { id: "useful-links-modal", isOpen, size: "l", onModalClose: onClose, children: [
|
|
28
|
-
/* @__PURE__ */ jsx(ModalBeta.Header, { onModalClose: onClose, children: t("homepage.usefulLinks.modal.title"
|
|
28
|
+
/* @__PURE__ */ jsx(ModalBeta.Header, { onModalClose: onClose, children: t("homepage.usefulLinks.modal.title") }),
|
|
29
29
|
/* @__PURE__ */ jsx(ModalBeta.Body, { children: links.length === 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
30
30
|
/* @__PURE__ */ jsx(Flex, { justify: "end", className: "mb-16", children: addLinkButton }),
|
|
31
31
|
/* @__PURE__ */ jsxs("div", { className: "useful-links-modal__empty", children: [
|
|
@@ -33,14 +33,14 @@ function UsefulLinksModal({
|
|
|
33
33
|
width: 200,
|
|
34
34
|
height: 109
|
|
35
35
|
} }),
|
|
36
|
-
/* @__PURE__ */ jsx("p", { className: "useful-links-modal__empty-title", children: t("homepage.usefulLinks.modal.empty.title"
|
|
37
|
-
/* @__PURE__ */ jsx("p", { className: "useful-links-modal__empty-text", children: t("homepage.usefulLinks.modal.empty.text"
|
|
36
|
+
/* @__PURE__ */ jsx("p", { className: "useful-links-modal__empty-title", children: t("homepage.usefulLinks.modal.empty.title") }),
|
|
37
|
+
/* @__PURE__ */ jsx("p", { className: "useful-links-modal__empty-text", children: t("homepage.usefulLinks.modal.empty.text") })
|
|
38
38
|
] })
|
|
39
39
|
] }) : /* @__PURE__ */ jsx("div", { className: "useful-links-table", children: /* @__PURE__ */ jsxs(Table, { children: [
|
|
40
40
|
/* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
41
|
-
/* @__PURE__ */ jsx(Table.Th, { className: "visually-hidden", children: t("homepage.usefulLinks.modal.table.name"
|
|
42
|
-
/* @__PURE__ */ jsx(Table.Th, { className: "visually-hidden", children: t("homepage.usefulLinks.modal.table.url"
|
|
43
|
-
/* @__PURE__ */ jsx(Table.Th, { className: "visually-hidden", children: t("homepage.usefulLinks.modal.table.actions"
|
|
41
|
+
/* @__PURE__ */ jsx(Table.Th, { className: "visually-hidden", children: t("homepage.usefulLinks.modal.table.name") }),
|
|
42
|
+
/* @__PURE__ */ jsx(Table.Th, { className: "visually-hidden", children: t("homepage.usefulLinks.modal.table.url") }),
|
|
43
|
+
/* @__PURE__ */ jsx(Table.Th, { className: "visually-hidden", children: t("homepage.usefulLinks.modal.table.actions") })
|
|
44
44
|
] }) }),
|
|
45
45
|
/* @__PURE__ */ jsxs(Table.Tbody, { children: [
|
|
46
46
|
/* @__PURE__ */ jsx(Table.Tr, { className: "useful-links-table__action-row", children: /* @__PURE__ */ jsx(Table.Td, { colSpan: md ? 3 : 2, children: /* @__PURE__ */ jsx(Flex, { justify: "end", children: addLinkButton }) }) }),
|
|
@@ -48,10 +48,10 @@ function UsefulLinksModal({
|
|
|
48
48
|
/* @__PURE__ */ jsx(Table.Td, { className: "useful-links-table__name", children: link.name }),
|
|
49
49
|
/* @__PURE__ */ jsx(Table.Td, { className: "useful-links-table__url", children: link.url }),
|
|
50
50
|
/* @__PURE__ */ jsx(Table.Td, { className: "useful-links-table__actions", children: /* @__PURE__ */ jsxs(Flex, { gap: "4", justify: "end", children: [
|
|
51
|
-
/* @__PURE__ */ jsx(ButtonBeta, { type: "button", variant: "ghost", color: "tertiary", size: "sm", leftIcon: /* @__PURE__ */ jsx(SvgIconEdit, {}), "aria-label": t("homepage.usefulLinks.modal.table.edit",
|
|
51
|
+
/* @__PURE__ */ jsx(ButtonBeta, { type: "button", variant: "ghost", color: "tertiary", size: "sm", leftIcon: /* @__PURE__ */ jsx(SvgIconEdit, {}), "aria-label": t("homepage.usefulLinks.modal.table.edit", {
|
|
52
52
|
name: link.name
|
|
53
53
|
}), "data-testid": `usefullinks-button-edit-${link.id}`, onClick: () => onEditLink(link) }),
|
|
54
|
-
/* @__PURE__ */ jsx(ButtonBeta, { type: "button", variant: "ghost", color: "tertiary", size: "sm", leftIcon: /* @__PURE__ */ jsx(SvgIconClose, {}), "aria-label": t("homepage.usefulLinks.modal.table.delete",
|
|
54
|
+
/* @__PURE__ */ jsx(ButtonBeta, { type: "button", variant: "ghost", color: "tertiary", size: "sm", leftIcon: /* @__PURE__ */ jsx(SvgIconClose, {}), "aria-label": t("homepage.usefulLinks.modal.table.delete", {
|
|
55
55
|
name: link.name
|
|
56
56
|
}), "data-testid": `usefullinks-button-delete-${link.id}`, onClick: () => onDeleteLink(link.id) })
|
|
57
57
|
] }) })
|
|
@@ -5,8 +5,10 @@ export type UserSpaceProps = {
|
|
|
5
5
|
avatar: string;
|
|
6
6
|
profile: UserProfile[number];
|
|
7
7
|
children?: ReactNode;
|
|
8
|
+
/** Renders a trigger button in the top-right corner when provided. */
|
|
9
|
+
onCustomizeWidgetsClick?: () => void;
|
|
8
10
|
};
|
|
9
|
-
declare function UserSpace({ name, avatar, profile, children, }: UserSpaceProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
declare function UserSpace({ name, avatar, profile, children, onCustomizeWidgetsClick, }: UserSpaceProps): import("react/jsx-runtime").JSX.Element;
|
|
10
12
|
declare namespace UserSpace {
|
|
11
13
|
var displayName: string;
|
|
12
14
|
}
|
|
@@ -1,27 +1,33 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useTranslation } from "react-i18next";
|
|
3
|
+
import SvgIconAddWidget from "../../../icons/components/IconAddWidget.js";
|
|
3
4
|
import SvgIconClass from "../../../icons/components/IconClass.js";
|
|
4
5
|
import { useProfileLinks } from "./hooks/useProfileLinks.js";
|
|
5
6
|
import HomeCard from "../HomeCard/HomeCard.js";
|
|
6
7
|
import Flex from "../../../../components/Flex/Flex.js";
|
|
7
8
|
import Avatar from "../../../../components/Avatar/Avatar.js";
|
|
9
|
+
import IconButton from "../../../../components/Button/IconButton.js";
|
|
8
10
|
import ButtonBeta from "../../../../components/ButtonBeta/ButtonBeta.js";
|
|
9
11
|
function UserSpace({
|
|
10
12
|
name,
|
|
11
13
|
avatar,
|
|
12
14
|
profile,
|
|
13
|
-
children
|
|
15
|
+
children,
|
|
16
|
+
onCustomizeWidgetsClick
|
|
14
17
|
}) {
|
|
15
18
|
const {
|
|
16
19
|
t
|
|
17
20
|
} = useTranslation(), links = useProfileLinks(profile);
|
|
18
21
|
return /* @__PURE__ */ jsxs(HomeCard, { variant: "user", footer: !!links && /* @__PURE__ */ jsx(Flex, { children: links.map((link, index) => /* @__PURE__ */ jsx(ButtonBeta, { size: "sm", variant: "ghost", leftIcon: /* @__PURE__ */ jsx(SvgIconClass, {}), onClick: () => window.location.href = link.url, children: link.text }, `${link.url}-${index}`)) }), children: [
|
|
19
|
-
/* @__PURE__ */ jsxs(Flex, { className: "user-space", direction: "row", gap: "8", children: [
|
|
20
|
-
/* @__PURE__ */
|
|
21
|
-
|
|
22
|
-
/* @__PURE__ */
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
/* @__PURE__ */ jsxs(Flex, { className: "user-space", direction: "row", justify: "between", gap: "8", children: [
|
|
23
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "row", gap: "8", children: [
|
|
24
|
+
/* @__PURE__ */ jsx(Avatar, { className: "user-space--avatar", size: "auto", alt: name, src: avatar, variant: "circle" }),
|
|
25
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "column", children: [
|
|
26
|
+
/* @__PURE__ */ jsx("div", { "data-testid": "user-space-name", className: "user-space--name", children: name }),
|
|
27
|
+
/* @__PURE__ */ jsx("div", { "data-testid": "user-space-profile", className: "user-space--profile", children: t(profile) })
|
|
28
|
+
] })
|
|
29
|
+
] }),
|
|
30
|
+
onCustomizeWidgetsClick && /* @__PURE__ */ jsx(IconButton, { className: "user-space--customize-widgets", icon: /* @__PURE__ */ jsx(SvgIconAddWidget, {}), variant: "ghost", color: "tertiary", "aria-label": t("homepage.userSpace.customizeWidgets", "Personnaliser mes widgets"), onClick: onCustomizeWidgetsClick })
|
|
25
31
|
] }),
|
|
26
32
|
children && /* @__PURE__ */ jsx(HomeCard.Content, { children })
|
|
27
33
|
] });
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
export
|
|
2
|
+
export interface UserSpaceContainerProps {
|
|
3
3
|
children?: ReactNode;
|
|
4
|
-
|
|
4
|
+
onCustomizeWidgetsClick?: () => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function UserSpaceContainer({ children, onCustomizeWidgetsClick, }: UserSpaceContainerProps): import("react/jsx-runtime").JSX.Element | null;
|
|
5
7
|
export declare namespace UserSpaceContainer {
|
|
6
8
|
var displayName: string;
|
|
7
9
|
}
|
|
@@ -2,7 +2,8 @@ import { jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import UserSpace from "./UserSpace.js";
|
|
3
3
|
import useUser from "../../../../hooks/useUser/useUser.js";
|
|
4
4
|
function UserSpaceContainer({
|
|
5
|
-
children
|
|
5
|
+
children,
|
|
6
|
+
onCustomizeWidgetsClick
|
|
6
7
|
}) {
|
|
7
8
|
var _a;
|
|
8
9
|
const {
|
|
@@ -12,7 +13,7 @@ function UserSpaceContainer({
|
|
|
12
13
|
} = useUser();
|
|
13
14
|
if (!user || !userDescription) return null;
|
|
14
15
|
const name = user.username || "", profile = ((_a = userDescription.profiles) == null ? void 0 : _a[0]) || "Guest";
|
|
15
|
-
return /* @__PURE__ */ jsx(UserSpace, { name, profile, avatar, children });
|
|
16
|
+
return /* @__PURE__ */ jsx(UserSpace, { name, profile, avatar, onCustomizeWidgetsClick, children });
|
|
16
17
|
}
|
|
17
18
|
export {
|
|
18
19
|
UserSpaceContainer
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef } from 'react';
|
|
2
|
+
export interface WidgetToggleProps extends Omit<ComponentPropsWithoutRef<'button'>, 'onClick' | 'type' | 'role' | 'aria-checked'> {
|
|
3
|
+
'checked': boolean;
|
|
4
|
+
'onChange': () => void;
|
|
5
|
+
'aria-label': string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Dedicated on/off control for a widget row in `WidgetsPersonalizationPanel`.
|
|
9
|
+
* The generic `Switch` component doesn't match this panel's design (size,
|
|
10
|
+
* filled-vs-outlined states), so this is a small purpose-built control
|
|
11
|
+
* rather than a `Switch` variant.
|
|
12
|
+
*/
|
|
13
|
+
export declare function WidgetToggle({ checked, onChange, disabled, ...rest }: WidgetToggleProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export declare namespace WidgetToggle {
|
|
15
|
+
var displayName: string;
|
|
16
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import clsx from "clsx";
|
|
3
|
+
function WidgetToggle({
|
|
4
|
+
checked,
|
|
5
|
+
onChange,
|
|
6
|
+
disabled,
|
|
7
|
+
...rest
|
|
8
|
+
}) {
|
|
9
|
+
return /* @__PURE__ */ jsx("button", { type: "button", role: "switch", "aria-checked": checked, disabled, className: clsx("widget-toggle", {
|
|
10
|
+
"widget-toggle--checked": checked
|
|
11
|
+
}), onClick: onChange, ...rest, children: /* @__PURE__ */ jsx("span", { className: "widget-toggle__knob" }) });
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
WidgetToggle
|
|
15
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface WidgetPersonalizationItem {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
icon: ReactNode;
|
|
6
|
+
checked: boolean;
|
|
7
|
+
/** When true, the widget is pinned by an admin: no toggle, lock icon instead. */
|
|
8
|
+
locked?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface WidgetsPersonalizationPanelProps {
|
|
11
|
+
items: WidgetPersonalizationItem[];
|
|
12
|
+
isLoading?: boolean;
|
|
13
|
+
onToggle: (id: string) => void;
|
|
14
|
+
onClose: () => void;
|
|
15
|
+
title?: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function WidgetsPersonalizationPanel({ items, isLoading, onToggle, onClose, title, description, }: WidgetsPersonalizationPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
export declare namespace WidgetsPersonalizationPanel {
|
|
20
|
+
var displayName: string;
|
|
21
|
+
}
|
package/dist/modules/homepage/components/WidgetsPersonalizationPanel/WidgetsPersonalizationPanel.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useTranslation } from "react-i18next";
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
import SvgIconClose from "../../../icons/components/IconClose.js";
|
|
5
|
+
import SvgIconLock from "../../../icons/components/IconLock.js";
|
|
6
|
+
import { WidgetToggle } from "./WidgetToggle.js";
|
|
7
|
+
import Heading from "../../../../components/Heading/Heading.js";
|
|
8
|
+
import IconButton from "../../../../components/Button/IconButton.js";
|
|
9
|
+
import TextSkeleton from "../../../../components/Skeleton/TextSkeleton.js";
|
|
10
|
+
const SKELETON_ROWS = 5;
|
|
11
|
+
function WidgetsPersonalizationPanel({
|
|
12
|
+
items,
|
|
13
|
+
isLoading = !1,
|
|
14
|
+
onToggle,
|
|
15
|
+
onClose,
|
|
16
|
+
title,
|
|
17
|
+
description
|
|
18
|
+
}) {
|
|
19
|
+
const {
|
|
20
|
+
t
|
|
21
|
+
} = useTranslation();
|
|
22
|
+
return /* @__PURE__ */ jsxs("div", { className: "widgets-personalization-panel", children: [
|
|
23
|
+
/* @__PURE__ */ jsxs("div", { className: "widgets-personalization-panel__header", children: [
|
|
24
|
+
/* @__PURE__ */ jsx(Heading, { level: "h2", headingStyle: "h5", className: "widgets-personalization-panel__title", children: title ?? t("homepage.widgetsPersonalization.title") }),
|
|
25
|
+
/* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(SvgIconClose, {}), variant: "ghost", color: "tertiary", "aria-label": t("close"), onClick: onClose, "data-testid": "widgetspersonalization-button-close" })
|
|
26
|
+
] }),
|
|
27
|
+
/* @__PURE__ */ jsx("p", { className: "widgets-personalization-panel__description", children: description ?? t("homepage.widgetsPersonalization.description") }),
|
|
28
|
+
isLoading ? /* @__PURE__ */ jsx("ul", { className: "widgets-personalization-panel__list", "aria-hidden": "true", children: Array.from({
|
|
29
|
+
length: SKELETON_ROWS
|
|
30
|
+
}).map((_, index) => /* @__PURE__ */ jsxs("li", { className: "widgets-personalization-panel__item widgets-personalization-panel__item--skeleton", children: [
|
|
31
|
+
/* @__PURE__ */ jsx(TextSkeleton, { className: "widgets-personalization-panel__item-icon-skeleton" }),
|
|
32
|
+
/* @__PURE__ */ jsx(TextSkeleton, { className: "widgets-personalization-panel__item-label-skeleton" })
|
|
33
|
+
] }, index)) }) : items.length === 0 ? /* @__PURE__ */ jsx("div", { className: "widgets-personalization-panel__empty", children: /* @__PURE__ */ jsx("p", { className: "widgets-personalization-panel__empty-text", children: t("homepage.widgetsPersonalization.empty") }) }) : /* @__PURE__ */ jsx("ul", { className: "widgets-personalization-panel__list", children: items.map((item) => /* @__PURE__ */ jsxs("li", { className: clsx("widgets-personalization-panel__item", {
|
|
34
|
+
"widgets-personalization-panel__item--checked": item.checked && !item.locked,
|
|
35
|
+
"widgets-personalization-panel__item--locked": item.locked
|
|
36
|
+
}), "data-testid": `widgetspersonalization-item-${item.id}`, children: [
|
|
37
|
+
/* @__PURE__ */ jsx("span", { className: "widgets-personalization-panel__item-icon", "aria-hidden": "true", children: item.icon }),
|
|
38
|
+
/* @__PURE__ */ jsx("span", { className: "widgets-personalization-panel__item-label", children: item.label }),
|
|
39
|
+
item.locked ? /* @__PURE__ */ jsx("span", { className: "widgets-personalization-panel__item-lock", role: "img", "aria-label": t("homepage.widgetsPersonalization.locked"), "data-testid": `widgetspersonalization-lock-${item.id}`, children: /* @__PURE__ */ jsx(SvgIconLock, {}) }) : /* @__PURE__ */ jsx(WidgetToggle, { checked: item.checked, onChange: () => onToggle(item.id), "aria-label": t("homepage.widgetsPersonalization.toggle", {
|
|
40
|
+
label: item.label
|
|
41
|
+
}), "data-testid": `widgetspersonalization-toggle-${item.id}` })
|
|
42
|
+
] }, item.id)) })
|
|
43
|
+
] });
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
WidgetsPersonalizationPanel
|
|
47
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SVGProps } from 'react';
|
|
2
|
+
interface SVGRProps {
|
|
3
|
+
title?: string;
|
|
4
|
+
titleId?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const SvgIconAddWidget: ({ title, titleId, ...props }: SVGProps<SVGSVGElement> & SVGRProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default SvgIconAddWidget;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
const SvgIconAddWidget = ({
|
|
3
|
+
title,
|
|
4
|
+
titleId,
|
|
5
|
+
...props
|
|
6
|
+
}) => /* @__PURE__ */ jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", fill: "none", viewBox: "0 0 20 20", "aria-hidden": "true", "aria-labelledby": titleId, ...props, children: [
|
|
7
|
+
title ? /* @__PURE__ */ jsx("title", { id: titleId, children: title }) : null,
|
|
8
|
+
/* @__PURE__ */ jsx("path", { fill: "currentColor", fillRule: "evenodd", d: "M15.834 10.833c.46 0 .833.373.833.834v2.5h2.5a.833.833 0 0 1 0 1.666h-2.5v2.5a.833.833 0 0 1-1.667 0v-2.5h-2.5a.833.833 0 0 1 0-1.666H15v-2.5c0-.46.373-.834.834-.834M8.333 3.333A.833.833 0 0 0 7.5 2.5h-5a.833.833 0 0 0-.833.833v13.334c0 .46.373.833.833.833h5c.46 0 .833-.373.833-.833zM10 16.667a2.5 2.5 0 0 1-2.5 2.5h-5a2.5 2.5 0 0 1-2.5-2.5V3.333a2.5 2.5 0 0 1 2.5-2.5h5a2.5 2.5 0 0 1 2.5 2.5zM18.334 3.333A.833.833 0 0 0 17.5 2.5h-3.333a.833.833 0 0 0-.833.833v3.334c0 .46.373.833.833.833H17.5c.46 0 .834-.373.834-.833zM20 6.667a2.5 2.5 0 0 1-2.5 2.5h-3.333a2.5 2.5 0 0 1-2.5-2.5V3.333a2.5 2.5 0 0 1 2.5-2.5H17.5a2.5 2.5 0 0 1 2.5 2.5z", clipRule: "evenodd" })
|
|
9
|
+
] });
|
|
10
|
+
export {
|
|
11
|
+
SvgIconAddWidget as default
|
|
12
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { default as IconAddUser } from './IconAddUser';
|
|
2
|
+
export { default as IconAddWidget } from './IconAddWidget';
|
|
2
3
|
export { default as IconAdd } from './IconAdd';
|
|
3
4
|
export { default as IconAdjustSettings } from './IconAdjustSettings';
|
|
4
5
|
export { default as IconAiFill } from './IconAiFill';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edifice.io/react",
|
|
3
|
-
"version": "2.6.6-develop-b2school.
|
|
3
|
+
"version": "2.6.6-develop-b2school.20260925172645",
|
|
4
4
|
"description": "Edifice React Library",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -140,9 +140,9 @@
|
|
|
140
140
|
"swiper": "10.1.0",
|
|
141
141
|
"ua-parser-js": "1.0.36",
|
|
142
142
|
"zustand": "4.5.7",
|
|
143
|
-
"@edifice.io/bootstrap": "2.6.6-develop-b2school.
|
|
144
|
-
"@edifice.io/tiptap-extensions": "2.6.6-develop-b2school.
|
|
145
|
-
"@edifice.io/utilities": "2.6.6-develop-b2school.
|
|
143
|
+
"@edifice.io/bootstrap": "2.6.6-develop-b2school.20260925172645",
|
|
144
|
+
"@edifice.io/tiptap-extensions": "2.6.6-develop-b2school.20260925172645",
|
|
145
|
+
"@edifice.io/utilities": "2.6.6-develop-b2school.20260925172645"
|
|
146
146
|
},
|
|
147
147
|
"devDependencies": {
|
|
148
148
|
"@babel/plugin-transform-react-pure-annotations": "7.27.1",
|
|
@@ -173,8 +173,8 @@
|
|
|
173
173
|
"vite": "5.4.14",
|
|
174
174
|
"vite-plugin-dts": "4.5.4",
|
|
175
175
|
"vite-tsconfig-paths": "5.1.4",
|
|
176
|
-
"@edifice.io/client": "2.6.6-develop-b2school.
|
|
177
|
-
"@edifice.io/config": "2.6.6-develop-b2school.
|
|
176
|
+
"@edifice.io/client": "2.6.6-develop-b2school.20260925172645",
|
|
177
|
+
"@edifice.io/config": "2.6.6-develop-b2school.20260925172645"
|
|
178
178
|
},
|
|
179
179
|
"peerDependencies": {
|
|
180
180
|
"@react-spring/web": "9.7.5",
|