@edifice.io/react 2.6.5-develop-b2school.20260914145143 → 2.6.5-develop-b2school.20260917151240

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.
@@ -41,5 +41,9 @@ declare const PageLayout: {
41
41
  ({ children, onClose, closeButton, backdrop, className, ...props }: import('./components/PageLayoutOverlay').PageLayoutOverlayProps): import("react/jsx-runtime").JSX.Element;
42
42
  displayName: string;
43
43
  };
44
+ HelpZone: {
45
+ (): import("react/jsx-runtime").JSX.Element;
46
+ displayName: string;
47
+ };
44
48
  };
45
49
  export default PageLayout;
@@ -1,15 +1,16 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { useMemo, Children, isValidElement } from "react";
3
3
  import clsx from "clsx";
4
4
  import PageLayoutBreadcrumb from "./components/PageLayoutBreadcrumb.js";
5
5
  import PageLayoutContent from "./components/PageLayoutContent.js";
6
6
  import PageLayoutHeader from "./components/PageLayoutHeader.js";
7
+ import PageLayoutHelpZone from "./components/PageLayoutHelpZone.js";
7
8
  import PageLayoutOverlay from "./components/PageLayoutOverlay.js";
8
9
  import PageLayoutSidebarLeft from "./components/PageLayoutSidebarLeft.js";
9
10
  import PageLayoutSidebarRight from "./components/PageLayoutSidebarRight.js";
10
11
  import { PageLayoutContext } from "./PageLayoutContext.js";
11
12
  function analyzeChildren(children) {
12
- let hasLeftSidebar = !1, hasRightSidebar = !1, breadcrumb = null, overlay = null;
13
+ let hasLeftSidebar = !1, hasRightSidebar = !1, breadcrumb = null, overlay = null, helpZone = null;
13
14
  const headerChildren = [], mainChildren = [];
14
15
  return Children.toArray(children).forEach((child) => {
15
16
  if (/* @__PURE__ */ isValidElement(child))
@@ -23,6 +24,9 @@ function analyzeChildren(children) {
23
24
  case PageLayoutOverlay:
24
25
  overlay = child;
25
26
  break;
27
+ case PageLayoutHelpZone:
28
+ helpZone = child;
29
+ break;
26
30
  case PageLayoutSidebarLeft:
27
31
  hasLeftSidebar = !0, mainChildren.push(child);
28
32
  break;
@@ -41,6 +45,7 @@ function analyzeChildren(children) {
41
45
  hasRightSidebar,
42
46
  breadcrumb,
43
47
  overlay,
48
+ helpZone,
44
49
  headerChildren,
45
50
  mainChildren
46
51
  };
@@ -63,6 +68,7 @@ const Root = ({
63
68
  hasRightSidebar,
64
69
  breadcrumb,
65
70
  overlay,
71
+ helpZone,
66
72
  headerChildren,
67
73
  mainChildren
68
74
  } = analyzeChildren(children), mainAreaClasses = clsx("pagelayout-mainarea", {
@@ -71,23 +77,27 @@ const Root = ({
71
77
  "has-right-sidebar-only": !hasLeftSidebar && hasRightSidebar,
72
78
  "has-gap": withGap
73
79
  }), isFullpage = variant === "fullpage";
74
- return /* @__PURE__ */ jsx(PageLayoutContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs("div", { className: clsx("pagelayout", `pagelayout-${variant}`, scrollMode && `pagelayout-scroll-${scrollMode}`, className), ...props, children: [
75
- headerChildren,
76
- headerChildren.length > 0 && /* @__PURE__ */ jsx("div", { className: "pagelayout-headerspacer" }),
77
- !isFullpage && breadcrumb,
78
- /* @__PURE__ */ jsxs("div", { className: mainAreaClasses, children: [
79
- isFullpage && breadcrumb,
80
- mainChildren
80
+ return /* @__PURE__ */ jsxs(PageLayoutContext.Provider, { value: contextValue, children: [
81
+ /* @__PURE__ */ jsxs("div", { className: clsx("pagelayout", `pagelayout-${variant}`, scrollMode && `pagelayout-scroll-${scrollMode}`, className), ...props, children: [
82
+ headerChildren,
83
+ headerChildren.length > 0 && /* @__PURE__ */ jsx("div", { className: "pagelayout-headerspacer" }),
84
+ !isFullpage && breadcrumb,
85
+ /* @__PURE__ */ jsxs("div", { className: mainAreaClasses, children: [
86
+ isFullpage && breadcrumb,
87
+ mainChildren
88
+ ] }),
89
+ overlay
81
90
  ] }),
82
- overlay
83
- ] }) });
91
+ helpZone
92
+ ] });
84
93
  }, PageLayout = Object.assign(Root, {
85
94
  Header: PageLayoutHeader,
86
95
  Breadcrumb: PageLayoutBreadcrumb,
87
96
  SidebarLeft: PageLayoutSidebarLeft,
88
97
  Content: PageLayoutContent,
89
98
  SidebarRight: PageLayoutSidebarRight,
90
- Overlay: PageLayoutOverlay
99
+ Overlay: PageLayoutOverlay,
100
+ HelpZone: PageLayoutHelpZone
91
101
  });
92
102
  export {
93
103
  PageLayout as default
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Opt-in slot: renders the floating Edifice help zone (badge + support
3
+ * button). Requires `EdificeClientProvider` and `EdificeThemeProvider`
4
+ * higher in the tree (used internally by `useZendeskGuide`) — kept opt-in
5
+ * rather than baked into `PageLayout` itself so standalone consumers
6
+ * without those providers don't crash at render.
7
+ */
8
+ declare const PageLayoutHelpZone: {
9
+ (): import("react/jsx-runtime").JSX.Element;
10
+ displayName: string;
11
+ };
12
+ export default PageLayoutHelpZone;
@@ -0,0 +1,6 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { HelpZoneContainer } from "../../../modules/HelpZone/HelpZoneContainer.js";
3
+ const PageLayoutHelpZone = () => /* @__PURE__ */ jsx(HelpZoneContainer, {});
4
+ export {
5
+ PageLayoutHelpZone as default
6
+ };
@@ -1 +1,2 @@
1
1
  export { default as useUploadFiles } from './useUploadFiles';
2
+ export type { UploadSourceFileInfo } from './useUploadFiles';
@@ -1,6 +1,16 @@
1
1
  import { WorkspaceElement, WorkspaceVisibility } from '@edifice.io/client';
2
+ /**
3
+ * Snapshot of a source file taken at upload time, so the upload result can be
4
+ * re-ordered later on against the original file metadata.
5
+ */
6
+ export interface UploadSourceFileInfo {
7
+ /** Original file name. */
8
+ name: string;
9
+ /** `File.lastModified` of the source file (ms since epoch). */
10
+ lastModified: number;
11
+ }
2
12
  declare const useUploadFiles: ({ handleOnChange, visibility, application, }: {
3
- handleOnChange: (uploadedFiles: WorkspaceElement[]) => void;
13
+ handleOnChange: (uploadedFiles: WorkspaceElement[], sourceFilesInfo: Record<string, UploadSourceFileInfo>) => void;
4
14
  visibility?: WorkspaceVisibility;
5
15
  application?: string;
6
16
  }) => {
@@ -1,4 +1,4 @@
1
- import { useState, useCallback, useEffect } from "react";
1
+ import { useState, useRef, useCallback, useEffect } from "react";
2
2
  import { ImageResizer, addTimestampToImageUrl } from "@edifice.io/utilities";
3
3
  import { useDropzoneContext } from "../../components/Dropzone/DropzoneContext.js";
4
4
  import useWorkspaceFile from "../useWorkspaceFile/useWorkspaceFile.js";
@@ -8,7 +8,7 @@ const useUploadFiles = ({
8
8
  visibility,
9
9
  application
10
10
  }) => {
11
- const [uploadedFiles, setUploadedFiles] = useState([]), [editingImage, setEditingImage] = useState(void 0), {
11
+ const [uploadedFiles, setUploadedFiles] = useState([]), sourceFilesInfoRef = useRef({}), [editingImage, setEditingImage] = useState(void 0), {
12
12
  files,
13
13
  deleteFile,
14
14
  replaceFileAt,
@@ -34,7 +34,10 @@ const useUploadFiles = ({
34
34
  } catch (err) {
35
35
  console.error(err);
36
36
  }
37
- !resource && !replacement && (resource = await uploadFile(file)), resource ? setUploadedFiles((prevFiles) => [...prevFiles, resource]) : resetInputValue();
37
+ !resource && !replacement && (resource = await uploadFile(file)), resource ? (resource._id && (sourceFilesInfoRef.current[resource._id] = {
38
+ name: file.name,
39
+ lastModified: file.lastModified
40
+ }), setUploadedFiles((prevFiles) => [...prevFiles, resource])) : resetInputValue();
38
41
  });
39
42
  }, [uploadAlternateFile, uploadFile, replaceFileAt]);
40
43
  useEffect(() => {
@@ -47,15 +50,17 @@ const useUploadFiles = ({
47
50
  newFiles.forEach((file) => file && setUploadStatus(file, "idle")), tryUploading(newFiles);
48
51
  }, [files, uploadedFiles, getUploadStatus, setUploadStatus, tryUploading]), useEffect(() => {
49
52
  const sortedUploadedFiles = sortUploadedFiles(files, uploadedFiles);
50
- handleOnChange(sortedUploadedFiles);
53
+ handleOnChange(sortedUploadedFiles, {
54
+ ...sourceFilesInfoRef.current
55
+ });
51
56
  }, [uploadedFiles]);
52
57
  const sortUploadedFiles = (filesArray, uploadedFilesArray) => {
53
- const orderMap = filesArray.reduce((acc, item, index) => (acc[item.name] = index, acc), {});
54
- return uploadedFilesArray.sort((a, b) => orderMap[a.name] - orderMap[b.name]);
58
+ const orderMap = filesArray.reduce((acc, item, index) => (item.name in acc || (acc[item.name] = index), acc), {});
59
+ return [...uploadedFilesArray].sort((a, b) => (orderMap[a.name] ?? Number.MAX_SAFE_INTEGER) - (orderMap[b.name] ?? Number.MAX_SAFE_INTEGER));
55
60
  };
56
61
  async function removeFile(file) {
57
62
  const resource = uploadedFiles.find((uploadedFile) => uploadedFile.name === file.name);
58
- resource && (await remove(resource), clearUploadStatus(file), setUploadedFiles((prevFiles) => prevFiles.filter((prevFile) => prevFile.name !== (resource == null ? void 0 : resource.name)))), deleteFile(file), resetInputValue();
63
+ resource && (await remove(resource), clearUploadStatus(file), resource._id && delete sourceFilesInfoRef.current[resource._id], setUploadedFiles((prevFiles) => prevFiles.filter((prevFile) => prevFile.name !== (resource == null ? void 0 : resource.name)))), deleteFile(file), resetInputValue();
59
64
  }
60
65
  async function updateImage({
61
66
  blob,
@@ -1,2 +1,14 @@
1
- /** Add Zendesk Guide */
2
- export default function useZendeskGuide(): null;
1
+ export interface UseZendeskGuideAPI {
2
+ /** True once the widget script is loaded and configured. */
3
+ isReady: boolean;
4
+ /** True while the widget panel is open. */
5
+ isOpen: boolean;
6
+ open: () => void;
7
+ close: () => void;
8
+ }
9
+ /**
10
+ * Add Zendesk Guide
11
+ *
12
+ * @param headerColor Overrides the widget panel's theme color.
13
+ */
14
+ export default function useZendeskGuide(headerColor?: string): UseZendeskGuideAPI;
@@ -5,7 +5,7 @@ import { useEdificeTheme } from "../../providers/EdificeThemeProvider/EdificeThe
5
5
  import useUser from "../useUser/useUser.js";
6
6
  import useIsAdml from "../useIsAdml/useIsAdml.js";
7
7
  import useHasWorkflow from "../useHasWorkflow/useHasWorkflow.js";
8
- function useZendeskGuide() {
8
+ function useZendeskGuide(headerColor) {
9
9
  const {
10
10
  currentLanguage
11
11
  } = useEdificeClient(), {
@@ -14,7 +14,13 @@ function useZendeskGuide() {
14
14
  isAdml
15
15
  } = useIsAdml(), {
16
16
  theme
17
- } = useEdificeTheme(), isMobileView = window.innerWidth <= 768, hasSupportWorkflow = useHasWorkflow("net.atos.entng.support.controllers.DisplayController|view"), [locationPathname, setLocationPathname] = useState(""), [dataModule, setDataModule] = useState(void 0), setZendeskGuideLabels = () => {
17
+ } = useEdificeTheme(), isMobileView = window.innerWidth <= 768, hasSupportWorkflow = useHasWorkflow("net.atos.entng.support.controllers.DisplayController|view"), [locationPathname, setLocationPathname] = useState(""), [dataModule, setDataModule] = useState(void 0), [isReady, setIsReady] = useState(!1), [isOpen, setIsOpen] = useState(!1), open = () => {
18
+ var _a;
19
+ (_a = window.zE) == null || _a.call(window, "webWidget", "open");
20
+ }, close = () => {
21
+ var _a;
22
+ (_a = window.zE) == null || _a.call(window, "webWidget", "close");
23
+ }, setZendeskGuideLabels = () => {
18
24
  const modulePathnameSplit = locationPathname.split("/");
19
25
  let moduleLabel = "", labels = "";
20
26
  if (dataModule != null && dataModule.labels && Object.keys(dataModule == null ? void 0 : dataModule.labels).length > 0 && modulePathnameSplit.length > 1) {
@@ -33,8 +39,40 @@ function useZendeskGuide() {
33
39
  return useEffect(() => {
34
40
  window.location.pathname !== locationPathname && setLocationPathname(window.location.pathname), !(dataModule === void 0 || Object.keys(dataModule).length === 0) && setZendeskGuideLabels();
35
41
  }, [window.location.pathname, dataModule]), useEffect(() => {
36
- document.getElementById("ze-snippet") || hasSupportWorkflow === void 0 || (async () => {
37
- const zendeskGuideConfig = await odeServices.http().get("/zendeskGuide/config");
42
+ const registerWidgetHandlers = () => {
43
+ window.zE("webWidget:on", "open", function() {
44
+ setIsOpen(!0), hasSupportWorkflow && window.zE("webWidget", "updateSettings", {
45
+ webWidget: {
46
+ contactForm: {
47
+ suppress: !1
48
+ }
49
+ }
50
+ });
51
+ }), window.zE("webWidget:on", "close", function() {
52
+ setIsOpen(!1);
53
+ }), window.zE("webWidget:on", "userEvent", function(ref) {
54
+ const category = ref.category, action = ref.action, properties = ref.properties;
55
+ action === "Contact Form Shown" && category === "Zendesk Web Widget" && properties && properties.name === "contact-form" && hasSupportWorkflow && (window.zE("webWidget", "updateSettings", {
56
+ webWidget: {
57
+ contactForm: {
58
+ suppress: !0
59
+ }
60
+ }
61
+ }), window.zE("webWidget", "close"), window.open("/support/tickets/new", "_blank"));
62
+ });
63
+ };
64
+ if (document.getElementById("ze-snippet")) {
65
+ window.zE && (registerWidgetHandlers(), setIsReady(!0));
66
+ return;
67
+ }
68
+ hasSupportWorkflow !== void 0 && (async () => {
69
+ let zendeskGuideConfig;
70
+ try {
71
+ zendeskGuideConfig = await odeServices.http().get("/zendeskGuide/config");
72
+ } catch (error) {
73
+ console.warn("[useZendeskGuide] Failed to fetch the support widget config from `/zendeskGuide/config` — the widget (and HelpZone's button) won't show up. If you're running a local dev server, check that `/zendeskGuide` is proxied to your backend in your app's Vite dev proxy config.", error);
74
+ return;
75
+ }
38
76
  if (zendeskGuideConfig && zendeskGuideConfig.key && zendeskGuideConfig.key !== "") {
39
77
  const scriptZendesk = document.createElement("script");
40
78
  scriptZendesk.id = "ze-snippet", scriptZendesk.src = `https://static.zdassets.com/ekr/snippet.js?key=${zendeskGuideConfig.key}`, document.body.appendChild(scriptZendesk).onload = () => {
@@ -45,7 +83,8 @@ function useZendeskGuide() {
45
83
  }), Object.keys(zendeskGuideConfig.module).length > 0 && setDataModule(zendeskGuideConfig.module), window.zE("webWidget", "show"), window.zE("webWidget", "updateSettings", {
46
84
  webWidget: {
47
85
  color: {
48
- theme: zendeskGuideConfig.color || "#ffc400"
86
+ theme: zendeskGuideConfig.color || "#ffc400",
87
+ header: headerColor
49
88
  },
50
89
  zIndex: 3,
51
90
  launcher: {
@@ -74,28 +113,16 @@ function useZendeskGuide() {
74
113
  }
75
114
  }
76
115
  });
77
- }), window.zE("webWidget:on", "open", function() {
78
- hasSupportWorkflow && window.zE("webWidget", "updateSettings", {
79
- webWidget: {
80
- contactForm: {
81
- suppress: !1
82
- }
83
- }
84
- });
85
- }), window.zE("webWidget:on", "userEvent", function(ref) {
86
- const category = ref.category, action = ref.action, properties = ref.properties;
87
- action === "Contact Form Shown" && category === "Zendesk Web Widget" && properties && properties.name === "contact-form" && hasSupportWorkflow && (window.zE("webWidget", "updateSettings", {
88
- webWidget: {
89
- contactForm: {
90
- suppress: !0
91
- }
92
- }
93
- }), window.zE("webWidget", "close"), window.open("/support/tickets/new", "_blank"));
94
- });
116
+ }), registerWidgetHandlers(), setIsReady(!0);
95
117
  };
96
118
  }
97
119
  })();
98
- }, [hasSupportWorkflow]), null;
120
+ }, [hasSupportWorkflow]), {
121
+ isReady,
122
+ isOpen,
123
+ open,
124
+ close
125
+ };
99
126
  }
100
127
  export {
101
128
  useZendeskGuide as default
@@ -0,0 +1,13 @@
1
+ export interface HelpZoneProps {
2
+ /** True once the support widget is loaded and can be opened. */
3
+ isReady: boolean;
4
+ /** True while the support panel is open. */
5
+ isOpen: boolean;
6
+ onOpen: () => void;
7
+ onClose: () => void;
8
+ }
9
+ declare const HelpZone: {
10
+ ({ isReady, isOpen, onOpen, onClose }: HelpZoneProps): import('react').ReactPortal | null;
11
+ displayName: string;
12
+ };
13
+ export default HelpZone;
@@ -0,0 +1,48 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
+ import clsx from "clsx";
4
+ import { createPortal } from "react-dom";
5
+ import { useTranslation } from "react-i18next";
6
+ import SvgIconQuestion from "../icons/components/IconQuestion.js";
7
+ import Tooltip from "../../components/Tooltip/Tooltip.js";
8
+ import SvgIconLogoEdificeSmall from "../icons/components/logo/IconLogoEdificeSmall.js";
9
+ import SvgIconLogoEdificeFull from "../icons/components/logo/IconLogoEdificeFull.js";
10
+ import ButtonBeta from "../../components/ButtonBeta/ButtonBeta.js";
11
+ const HelpZone = ({
12
+ isReady,
13
+ isOpen,
14
+ onOpen,
15
+ onClose
16
+ }) => {
17
+ const {
18
+ t
19
+ } = useTranslation(), [portalRoot, setPortalRoot] = useState(null), [isCompact, setIsCompact] = useState(!1);
20
+ if (useEffect(() => (document.body.classList.add("help-zone-active"), setPortalRoot(document.getElementById("portal")), () => {
21
+ document.body.classList.remove("help-zone-active");
22
+ }), []), useEffect(() => {
23
+ if (isCompact)
24
+ return;
25
+ const goCompact = () => setIsCompact(!0);
26
+ return document.addEventListener("scroll", goCompact, {
27
+ capture: !0,
28
+ passive: !0
29
+ }), document.addEventListener("click", goCompact), () => {
30
+ document.removeEventListener("scroll", goCompact, {
31
+ capture: !0
32
+ }), document.removeEventListener("click", goCompact);
33
+ };
34
+ }, [isCompact]), !isReady || !portalRoot)
35
+ return null;
36
+ const handleClick = () => isOpen ? onClose() : onOpen();
37
+ return /* @__PURE__ */ createPortal(/* @__PURE__ */ jsxs("div", { className: "help-zone", children: [
38
+ /* @__PURE__ */ jsx("a", { className: "help-zone-badge", href: "https://edifice.io/releases/", target: "_blank", rel: "noopener noreferrer", "aria-label": t("help-zone.edifice-releases-notes"), children: /* @__PURE__ */ jsx(Tooltip, { message: t("help-zone.edifice-releases-notes"), placement: "top", children: /* @__PURE__ */ jsx("span", { className: clsx("help-zone-logo", {
39
+ "help-zone-logo--compact": isCompact,
40
+ "help-zone-logo--full": !isCompact
41
+ }), children: isCompact ? /* @__PURE__ */ jsx(SvgIconLogoEdificeSmall, { width: 18, height: 18 }) : /* @__PURE__ */ jsx(SvgIconLogoEdificeFull, { width: 81, height: 18 }) }) }) }),
42
+ /* @__PURE__ */ jsx("span", { className: "help-zone-divider" }),
43
+ /* @__PURE__ */ jsx(ButtonBeta, { className: "help-zone-question", "aria-label": t("help-zone.support.open"), color: "tertiary", variant: "ghost", onClick: handleClick, children: /* @__PURE__ */ jsx(Tooltip, { message: t("help-zone.support.open"), placement: "top", children: /* @__PURE__ */ jsx(SvgIconQuestion, { width: 24, height: 24, color: "white" }) }) })
44
+ ] }), portalRoot);
45
+ };
46
+ export {
47
+ HelpZone as default
48
+ };
@@ -0,0 +1,4 @@
1
+ export declare function HelpZoneContainer(): import("react/jsx-runtime").JSX.Element;
2
+ export declare namespace HelpZoneContainer {
3
+ var displayName: string;
4
+ }
@@ -0,0 +1,18 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import HelpZone from "./HelpZone.js";
3
+ import useZendeskGuide from "../../hooks/useZendeskGuide/useZendeskGuide.js";
4
+ function getHeaderColor() {
5
+ return getComputedStyle(document.documentElement).getPropertyValue("--primitive-blue-400").trim();
6
+ }
7
+ function HelpZoneContainer() {
8
+ const headerColor = getHeaderColor(), {
9
+ isReady,
10
+ isOpen,
11
+ open,
12
+ close
13
+ } = useZendeskGuide(headerColor);
14
+ return /* @__PURE__ */ jsx(HelpZone, { isReady, isOpen, onOpen: open, onClose: close });
15
+ }
16
+ export {
17
+ HelpZoneContainer
18
+ };
@@ -0,0 +1,3 @@
1
+ export * from './HelpZone';
2
+ export { default as HelpZone } from './HelpZone';
3
+ export * from './HelpZoneContainer';
@@ -0,0 +1,7 @@
1
+ import { SVGProps } from 'react';
2
+ interface SVGRProps {
3
+ title?: string;
4
+ titleId?: string;
5
+ }
6
+ declare const SvgIconLogoEdificeFull: ({ title, titleId, ...props }: SVGProps<SVGSVGElement> & SVGRProps) => import("react/jsx-runtime").JSX.Element;
7
+ export default SvgIconLogoEdificeFull;
@@ -0,0 +1,26 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ const SvgIconLogoEdificeFull = ({
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 81 18", "aria-hidden": "true", "aria-labelledby": titleId, ...props, children: [
7
+ title ? /* @__PURE__ */ jsx("title", { id: titleId, children: title }) : null,
8
+ /* @__PURE__ */ jsxs("g", { clipPath: "url(#icon-logo-edifice-full_svg__a)", children: [
9
+ /* @__PURE__ */ jsx("path", { fill: "#C8D3FE", d: "M72.667 1.944c-4.424 0-8.01 3.602-8.01 8.045h16.02c0-4.443-3.586-8.045-8.01-8.045" }),
10
+ /* @__PURE__ */ jsx("path", { fill: "#fff", d: "M76.346 12.173a4.3 4.3 0 0 1-.659.84 4.25 4.25 0 0 1-3.02 1.249 4.26 4.26 0 0 1-3.02-1.249 4.3 4.3 0 0 1-1.27-3.02V9.99h-3.72v.038c.04 4.408 3.61 7.969 8.009 7.969 3.657 0 6.74-2.462 7.7-5.825h-4.022zM55.596 10.014a4.28 4.28 0 0 1 1.253-2.998 4.2 4.2 0 0 1 2.98-1.24h3.618V2.07h-3.67c-4.317.029-7.812 3.552-7.852 7.908v.077c.04 4.356 3.535 7.879 7.85 7.907h3.672v-3.707h-3.618a4.2 4.2 0 0 1-2.98-1.24 4.28 4.28 0 0 1-1.255-2.997v-.007z" }),
11
+ /* @__PURE__ */ jsx("path", { fill: "#C8D3FE", d: "M50.302 7.711h-3.56v10.252h3.56z" }),
12
+ /* @__PURE__ */ jsx("path", { fill: "#fff", d: "M50.302 2.07h-3.56v3.608h3.56z" }),
13
+ /* @__PURE__ */ jsx("path", { fill: "#C8D3FE", d: "M40.983 2.07h-3.56v15.893h3.56z" }),
14
+ /* @__PURE__ */ jsx("path", { fill: "#fff", d: "M44.529 2.07h-3.56v3.576h.222a3.345 3.345 0 0 0 3.337-3.353zM44.529 7.711h-3.56v3.576h.222a3.345 3.345 0 0 0 3.337-3.353z" }),
15
+ /* @__PURE__ */ jsx("path", { fill: "#C8D3FE", d: "M35.19 7.711h-3.56v10.252h3.56z" }),
16
+ /* @__PURE__ */ jsx("path", { fill: "#fff", d: "M35.19 2.07h-3.56v3.608h3.56zM29.636 10.017c0-4.39-3.542-7.947-7.911-7.947v15.893c4.369 0 7.91-3.558 7.91-7.946" }),
17
+ /* @__PURE__ */ jsx("path", { fill: "#C8D3FE", d: "M21.726 2.07h-3.56v15.893h3.56z" }),
18
+ /* @__PURE__ */ jsx("path", { fill: "#fff", d: "M11.677 0H4.952v1.987h6.725z" }),
19
+ /* @__PURE__ */ jsx("path", { fill: "#C8D3FE", d: "M8.316 1.949c-4.424 0-8.01 3.601-8.01 8.045h16.02c0-4.444-3.586-8.045-8.01-8.045" }),
20
+ /* @__PURE__ */ jsx("path", { fill: "#fff", d: "M11.995 12.176a4.3 4.3 0 0 1-.658.84 4.25 4.25 0 0 1-3.021 1.25 4.26 4.26 0 0 1-3.02-1.25 4.3 4.3 0 0 1-1.27-3.02v-.003H.305v.039C.346 14.439 3.916 18 8.315 18c3.657 0 6.74-2.461 7.7-5.825h-4.022z" })
21
+ ] }),
22
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("clipPath", { id: "icon-logo-edifice-full_svg__a", children: /* @__PURE__ */ jsx("path", { fill: "#fff", d: "M0 0h81v18H0z" }) }) })
23
+ ] });
24
+ export {
25
+ SvgIconLogoEdificeFull as default
26
+ };
@@ -0,0 +1,7 @@
1
+ import { SVGProps } from 'react';
2
+ interface SVGRProps {
3
+ title?: string;
4
+ titleId?: string;
5
+ }
6
+ declare const SvgIconLogoEdificeSmall: ({ title, titleId, ...props }: SVGProps<SVGSVGElement> & SVGRProps) => import("react/jsx-runtime").JSX.Element;
7
+ export default SvgIconLogoEdificeSmall;
@@ -0,0 +1,17 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ const SvgIconLogoEdificeSmall = ({
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 18 18", "aria-hidden": "true", "aria-labelledby": titleId, ...props, children: [
7
+ title ? /* @__PURE__ */ jsx("title", { id: titleId, children: title }) : null,
8
+ /* @__PURE__ */ jsxs("g", { clipPath: "url(#icon-logo-edifice-small_svg__a)", children: [
9
+ /* @__PURE__ */ jsx("path", { fill: "#fff", d: "M12.36 0H5.637v1.987h6.725z" }),
10
+ /* @__PURE__ */ jsx("path", { fill: "#C8D3FE", d: "M9 1.949C4.576 1.949.99 5.55.99 9.994h16.02C17.01 5.55 13.424 1.95 9 1.95" }),
11
+ /* @__PURE__ */ jsx("path", { fill: "#fff", d: "M12.679 12.176a4.3 4.3 0 0 1-.659.84A4.25 4.25 0 0 1 9 14.266a4.26 4.26 0 0 1-3.02-1.25 4.3 4.3 0 0 1-1.27-3.02v-.003H.99v.039C1.03 14.439 4.6 18 8.999 18c3.656 0 6.74-2.461 7.7-5.825h-4.022z" })
12
+ ] }),
13
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("clipPath", { id: "icon-logo-edifice-small_svg__a", children: /* @__PURE__ */ jsx("path", { fill: "#fff", d: "M0 0h18v18H0z" }) }) })
14
+ ] });
15
+ export {
16
+ SvgIconLogoEdificeSmall as default
17
+ };
@@ -0,0 +1,2 @@
1
+ export { default as IconLogoEdificeFull } from './IconLogoEdificeFull';
2
+ export { default as IconLogoEdificeSmall } from './IconLogoEdificeSmall';
@@ -1,7 +1,9 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
- import { useMediaLibraryContext } from "../MediaLibraryContext.js";
2
+ import { useState, useRef, useEffect } from "react";
3
3
  import { useTranslation } from "react-i18next";
4
- import Alert from "../../../../components/Alert/Alert.js";
4
+ import { useMediaLibraryContext } from "../MediaLibraryContext.js";
5
+ import Flex from "../../../../components/Flex/Flex.js";
6
+ import Radio from "../../../../components/Radio/Radio.js";
5
7
  import Dropzone from "../../../../components/Dropzone/Dropzone.js";
6
8
  import UploadFiles from "../../UploadFiles/UploadFiles.js";
7
9
  const acceptedTypes = (type) => {
@@ -18,6 +20,17 @@ const acceptedTypes = (type) => {
18
20
  break;
19
21
  }
20
22
  return acceptedTypes2;
23
+ }, orderUploadedFiles = (uploadedFiles, sourceFilesInfo, byAlpha) => {
24
+ const infoOf = (element) => element._id ? sourceFilesInfo[element._id] : void 0, nameOf = (element) => {
25
+ var _a;
26
+ return ((_a = infoOf(element)) == null ? void 0 : _a.name) ?? element.name;
27
+ }, lastModifiedOf = (element) => {
28
+ var _a;
29
+ return ((_a = infoOf(element)) == null ? void 0 : _a.lastModified) ?? 0;
30
+ };
31
+ return byAlpha ? [...uploadedFiles].sort((a, b) => nameOf(a).localeCompare(nameOf(b), void 0, {
32
+ numeric: !0
33
+ })) : [...uploadedFiles].sort((a, b) => lastModifiedOf(b) - lastModifiedOf(a)).reverse();
21
34
  }, Upload = () => {
22
35
  const {
23
36
  t
@@ -27,12 +40,26 @@ const acceptedTypes = (type) => {
27
40
  multiple,
28
41
  setResult,
29
42
  setResultCounter,
30
- setCancellable
31
- } = useMediaLibraryContext(), handleOnFilesChange = (uploadedFiles) => {
32
- uploadedFiles.length ? (setCancellable(uploadedFiles), setResultCounter(uploadedFiles.length), setResult(uploadedFiles)) : (setCancellable([]), setResultCounter(void 0), setResult(void 0));
43
+ setCancellable,
44
+ setPreSuccess
45
+ } = useMediaLibraryContext(), [sortByAlpha, setSortByAlpha] = useState(!0), [uploadedFiles, setUploadedFiles] = useState([]), sourceFilesInfoRef = useRef({}), handleOnFilesChange = (uploadedFiles2, sourceFilesInfo) => {
46
+ sourceFilesInfoRef.current = sourceFilesInfo, setUploadedFiles(uploadedFiles2), uploadedFiles2.length ? (setCancellable(uploadedFiles2), setResultCounter(uploadedFiles2.length), setResult(uploadedFiles2)) : (setCancellable([]), setResultCounter(void 0), setResult(void 0));
33
47
  };
34
- return /* @__PURE__ */ jsxs("div", { className: "flex-grow-1", children: [
35
- multiple && /* @__PURE__ */ jsx(Alert, { type: "info", className: "flex-shrink-0 mb-16", children: t("bbm.upload.alert") }),
48
+ return useEffect(() => {
49
+ if (!multiple || !uploadedFiles.length) {
50
+ setPreSuccess(void 0);
51
+ return;
52
+ }
53
+ setPreSuccess(() => () => Promise.resolve(orderUploadedFiles(uploadedFiles, sourceFilesInfoRef.current, sortByAlpha)));
54
+ }, [multiple, uploadedFiles, sortByAlpha, setPreSuccess]), /* @__PURE__ */ jsxs("div", { className: "flex-grow-1", children: [
55
+ multiple && /* @__PURE__ */ jsxs(Flex, { className: "mb-16 ms-8", align: "start", direction: "column", gap: "8", children: [
56
+ /* @__PURE__ */ jsxs("div", { children: [
57
+ t("bbm.upload.sort.title"),
58
+ " :"
59
+ ] }),
60
+ /* @__PURE__ */ jsx(Radio, { label: t("bbm.upload.sort.alpha"), name: "media-library-upload-sort", value: "alpha", model: sortByAlpha ? "alpha" : "date", checked: sortByAlpha, onChange: () => setSortByAlpha(!0), "data-testid": "media-library-upload-sort-alpha" }),
61
+ /* @__PURE__ */ jsx(Radio, { label: t("bbm.upload.sort.date"), name: "media-library-upload-sort", value: "date", model: sortByAlpha ? "alpha" : "date", checked: !sortByAlpha, onChange: () => setSortByAlpha(!1), "data-testid": "media-library-upload-sort-date" })
62
+ ] }),
36
63
  /* @__PURE__ */ jsx(Dropzone, { multiple, accept: acceptedTypes(type ?? "embedder"), children: /* @__PURE__ */ jsx(UploadFiles, { onFilesChange: handleOnFilesChange, visibility }) })
37
64
  ] });
38
65
  };
@@ -1,7 +1,8 @@
1
1
  import { WorkspaceElement, WorkspaceVisibility } from '@edifice.io/client';
2
+ import { UploadSourceFileInfo } from '../../../hooks';
2
3
  declare const UploadFiles: {
3
4
  ({ onFilesChange, visibility, }: {
4
- onFilesChange: (uploadedFiles: WorkspaceElement[]) => void;
5
+ onFilesChange: (uploadedFiles: WorkspaceElement[], sourceFilesInfo: Record<string, UploadSourceFileInfo>) => void;
5
6
  visibility?: WorkspaceVisibility;
6
7
  }): import("react/jsx-runtime").JSX.Element;
7
8
  displayName: string;
@@ -1,2 +1,2 @@
1
- export * from './Widget';
2
1
  export * from './BookmarkedApps';
2
+ export * from './Widget';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edifice.io/react",
3
- "version": "2.6.5-develop-b2school.20260914145143",
3
+ "version": "2.6.5-develop-b2school.20260917151240",
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.5-develop-b2school.20260914145143",
144
- "@edifice.io/tiptap-extensions": "2.6.5-develop-b2school.20260914145143",
145
- "@edifice.io/utilities": "2.6.5-develop-b2school.20260914145143"
143
+ "@edifice.io/bootstrap": "2.6.5-develop-b2school.20260917151240",
144
+ "@edifice.io/tiptap-extensions": "2.6.5-develop-b2school.20260917151240",
145
+ "@edifice.io/utilities": "2.6.5-develop-b2school.20260917151240"
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.5-develop-b2school.20260914145143",
177
- "@edifice.io/config": "2.6.5-develop-b2school.20260914145143"
176
+ "@edifice.io/client": "2.6.5-develop-b2school.20260917151240",
177
+ "@edifice.io/config": "2.6.5-develop-b2school.20260917151240"
178
178
  },
179
179
  "peerDependencies": {
180
180
  "@react-spring/web": "9.7.5",