@griddo/ax 11.14.2-rc.0 → 11.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/config/jest/reactEasyCropMock.js +15 -0
  2. package/config/jest/reactTimezoneMock.js +13 -0
  3. package/package.json +221 -219
  4. package/public/img/welcome.svg +127 -0
  5. package/src/__tests__/components/Browser/Browser.test.tsx +27 -51
  6. package/src/__tests__/components/CategoryCell/CategoryCell.test.tsx +10 -5
  7. package/src/__tests__/components/ElementsTooltip/ElementsTooltip.test.tsx +27 -14
  8. package/src/__tests__/components/HeadingsPreviewModal/ErrorsBanner/ErrorItem/ErrorItem.test.tsx +2 -0
  9. package/src/__tests__/components/HeadingsPreviewModal/HeadingsPreviewModal.utils.test.tsx +138 -1
  10. package/src/__tests__/components/ImageDragAndDrop/CropStep/CropStep.test.tsx +84 -0
  11. package/src/__tests__/components/ImageDragAndDrop/ImageDragAndDrop.test.tsx +173 -0
  12. package/src/__tests__/components/KeywordsPreviewModal/KeywordsPreviewModal.test.tsx +3 -4
  13. package/src/__tests__/components/ProfileImage/ProfileImage.test.tsx +120 -0
  14. package/src/__tests__/components/ResizePanel/ResizePanel.test.tsx +8 -0
  15. package/src/__tests__/components/UserRolesAndSites/RoleItem/RoleItem.test.tsx +190 -0
  16. package/src/__tests__/components/UserRolesAndSites/UserRolesAndSites.test.tsx +471 -0
  17. package/src/__tests__/modules/FramePreview/HeadingsOverlay/HeadingsOverlay.test.tsx +15 -2
  18. package/src/__tests__/modules/Sites/Sites.test.tsx +68 -224
  19. package/src/__tests__/modules/Sites/SitesList/ListView/BulkHeader/BulkHeader.test.tsx +21 -17
  20. package/src/__tests__/modules/Sites/SitesList/SitesList.test.tsx +65 -565
  21. package/src/__tests__/modules/Sites/SitesList/WelcomeModal/DataStep/DataStep.test.tsx +109 -0
  22. package/src/__tests__/modules/Sites/SitesList/WelcomeModal/FinalStep/FinalStep.test.tsx +157 -0
  23. package/src/__tests__/modules/Sites/SitesList/WelcomeModal/ImageStep/CropView/CropView.test.tsx +51 -0
  24. package/src/__tests__/modules/Sites/SitesList/WelcomeModal/ImageStep/ImageStep.test.tsx +70 -0
  25. package/src/__tests__/modules/Sites/SitesList/WelcomeModal/ImageStep/UploadView/UploadView.test.tsx +92 -0
  26. package/src/__tests__/modules/Sites/SitesList/WelcomeModal/TimezoneStep/TimezoneStep.test.tsx +94 -0
  27. package/src/__tests__/modules/Sites/SitesList/WelcomeModal/WelcomeModal.test.tsx +78 -0
  28. package/src/__tests__/modules/Sites/SitesList/WelcomeModal/WelcomeStep/WelcomeStep.test.tsx +39 -0
  29. package/src/__tests__/modules/Sites/SitesList/WelcomeModal/utils.test.ts +55 -0
  30. package/src/api/sites.tsx +4 -4
  31. package/src/components/Avatar/index.tsx +26 -5
  32. package/src/components/Avatar/style.tsx +20 -10
  33. package/src/components/Browser/index.tsx +7 -1
  34. package/src/components/ConfigPanel/index.tsx +11 -7
  35. package/src/components/ElementsTooltip/index.tsx +96 -34
  36. package/src/components/ElementsTooltip/style.tsx +12 -1
  37. package/src/components/Fields/FileField/index.tsx +16 -18
  38. package/src/components/Fields/HeadingField/index.tsx +1 -1
  39. package/src/components/Fields/ImageField/index.tsx +9 -38
  40. package/src/components/Fields/ImageField/style.tsx +12 -1
  41. package/src/components/Fields/ToggleField/index.tsx +1 -1
  42. package/src/components/Fields/Wysiwyg/index.tsx +25 -20
  43. package/src/components/FileGallery/GalleryPanel/index.tsx +15 -7
  44. package/src/components/FileGallery/index.tsx +33 -28
  45. package/src/components/Gallery/GalleryPanel/index.tsx +5 -16
  46. package/src/components/Gallery/index.tsx +0 -2
  47. package/src/components/HeadingsPreviewModal/ErrorsBanner/ErrorItem/index.tsx +11 -2
  48. package/src/components/HeadingsPreviewModal/ErrorsBanner/index.tsx +21 -3
  49. package/src/components/HeadingsPreviewModal/ErrorsBanner/style.tsx +2 -2
  50. package/src/components/HeadingsPreviewModal/index.tsx +13 -3
  51. package/src/components/HeadingsPreviewModal/style.tsx +18 -0
  52. package/src/components/HeadingsPreviewModal/utils.tsx +31 -3
  53. package/src/components/Image/index.tsx +2 -2
  54. package/src/components/ImageDragAndDrop/CropStep/index.tsx +95 -0
  55. package/src/components/ImageDragAndDrop/CropStep/style.tsx +101 -0
  56. package/src/{modules/MediaGallery → components}/ImageDragAndDrop/index.tsx +103 -40
  57. package/src/{modules/MediaGallery → components}/ImageDragAndDrop/style.tsx +14 -2
  58. package/src/components/KeywordsPreviewModal/atoms.tsx +2 -2
  59. package/src/components/KeywordsPreviewModal/index.tsx +6 -6
  60. package/src/components/KeywordsPreviewModal/utils.tsx +2 -2
  61. package/src/components/ProfileImage/index.tsx +55 -0
  62. package/src/components/ProfileImage/style.tsx +58 -0
  63. package/src/components/ResizePanel/ResizeHandle/index.tsx +44 -6
  64. package/src/components/ResizePanel/ResizeHandle/style.tsx +7 -0
  65. package/src/components/ResizePanel/index.tsx +25 -4
  66. package/src/components/Tabs/style.tsx +1 -1
  67. package/src/components/Tag/index.tsx +0 -1
  68. package/src/components/UserRolesAndSites/RoleItem/index.tsx +42 -0
  69. package/src/components/UserRolesAndSites/RoleItem/style.tsx +29 -0
  70. package/src/components/UserRolesAndSites/index.tsx +102 -0
  71. package/src/components/UserRolesAndSites/style.tsx +67 -0
  72. package/src/components/index.tsx +6 -0
  73. package/src/constants/index.ts +13 -1
  74. package/src/containers/App/actions.tsx +8 -1
  75. package/src/containers/Sites/actions.tsx +26 -0
  76. package/src/containers/Sites/constants.tsx +1 -0
  77. package/src/containers/Sites/interfaces.tsx +6 -0
  78. package/src/containers/Sites/reducer.tsx +5 -1
  79. package/src/containers/Users/reducer.tsx +6 -5
  80. package/src/guards/routeLeaving/index.tsx +9 -11
  81. package/src/helpers/images.tsx +50 -3
  82. package/src/helpers/index.tsx +2 -1
  83. package/src/hooks/forms.tsx +45 -48
  84. package/src/hooks/index.tsx +2 -1
  85. package/src/hooks/modals.tsx +4 -3
  86. package/src/hooks/window.ts +50 -2
  87. package/src/modules/ActivityLog/ItemLogUser/UserItem/index.tsx +1 -1
  88. package/src/modules/App/Routing/Logout/index.tsx +3 -5
  89. package/src/modules/App/Routing/NavMenu/NavItem/index.tsx +73 -52
  90. package/src/modules/App/Routing/NavMenu/NavItem/style.tsx +21 -7
  91. package/src/modules/App/Routing/NavMenu/index.tsx +59 -54
  92. package/src/modules/App/Routing/NavMenu/style.tsx +13 -11
  93. package/src/modules/CreatePass/index.tsx +1 -1
  94. package/src/modules/FileDrive/FileDragAndDrop/index.tsx +11 -8
  95. package/src/modules/FileDrive/FileModal/index.tsx +8 -9
  96. package/src/modules/FileDrive/index.tsx +1 -18
  97. package/src/modules/Forms/FormEditor/index.tsx +1 -1
  98. package/src/modules/FramePreview/HeadingsOverlay/index.tsx +22 -11
  99. package/src/modules/FramePreview/HeadingsOverlay/style.tsx +1 -1
  100. package/src/modules/MediaGallery/ImageModal/index.tsx +1 -5
  101. package/src/modules/MediaGallery/index.tsx +1 -3
  102. package/src/modules/Settings/Globals/constants.tsx +942 -106
  103. package/src/modules/Sites/SitesList/AllSitesHeader/index.tsx +33 -0
  104. package/src/modules/Sites/SitesList/AllSitesHeader/style.tsx +35 -0
  105. package/src/modules/Sites/SitesList/GridView/GridHeaderFilter/index.tsx +5 -5
  106. package/src/modules/Sites/SitesList/GridView/GridSiteItem/index.tsx +23 -119
  107. package/src/modules/Sites/SitesList/ListView/BulkHeader/TableHeader/index.tsx +4 -4
  108. package/src/modules/Sites/SitesList/ListView/BulkHeader/index.tsx +4 -3
  109. package/src/modules/Sites/SitesList/ListView/ListSiteItem/index.tsx +23 -120
  110. package/src/modules/Sites/SitesList/{RecentSiteItem → RecentSites/RecentSiteItem}/index.tsx +4 -5
  111. package/src/modules/Sites/SitesList/RecentSites/index.tsx +49 -0
  112. package/src/modules/Sites/SitesList/RecentSites/style.tsx +92 -0
  113. package/src/modules/Sites/SitesList/SiteModal/index.tsx +8 -7
  114. package/src/modules/Sites/SitesList/WelcomeModal/DataStep/index.tsx +72 -0
  115. package/src/modules/Sites/SitesList/WelcomeModal/DataStep/style.tsx +59 -0
  116. package/src/modules/Sites/SitesList/WelcomeModal/FinalStep/constants.tsx +78 -0
  117. package/src/modules/Sites/SitesList/WelcomeModal/FinalStep/index.tsx +78 -0
  118. package/src/modules/Sites/SitesList/WelcomeModal/FinalStep/style.tsx +141 -0
  119. package/src/modules/Sites/SitesList/WelcomeModal/ImageStep/CropView/index.tsx +93 -0
  120. package/src/modules/Sites/SitesList/WelcomeModal/ImageStep/CropView/style.tsx +77 -0
  121. package/src/modules/Sites/SitesList/WelcomeModal/ImageStep/UploadView/index.tsx +100 -0
  122. package/src/modules/Sites/SitesList/WelcomeModal/ImageStep/UploadView/style.tsx +94 -0
  123. package/src/modules/Sites/SitesList/WelcomeModal/ImageStep/index.tsx +44 -0
  124. package/src/modules/Sites/SitesList/WelcomeModal/ImageStep/style.tsx +31 -0
  125. package/src/modules/Sites/SitesList/WelcomeModal/TimezoneStep/index.tsx +51 -0
  126. package/src/modules/Sites/SitesList/WelcomeModal/TimezoneStep/style.tsx +52 -0
  127. package/src/modules/Sites/SitesList/WelcomeModal/WelcomeStep/index.tsx +40 -0
  128. package/src/modules/Sites/SitesList/WelcomeModal/WelcomeStep/style.tsx +53 -0
  129. package/src/modules/Sites/SitesList/WelcomeModal/index.tsx +215 -0
  130. package/src/modules/Sites/SitesList/WelcomeModal/style.tsx +12 -0
  131. package/src/modules/Sites/SitesList/WelcomeModal/utils.ts +26 -0
  132. package/src/modules/Sites/SitesList/atoms.tsx +4 -4
  133. package/src/modules/Sites/SitesList/hooks.tsx +149 -16
  134. package/src/modules/Sites/SitesList/index.tsx +127 -125
  135. package/src/modules/Sites/SitesList/style.tsx +1 -117
  136. package/src/modules/Sites/SitesList/utils.tsx +9 -2
  137. package/src/modules/Sites/index.tsx +19 -8
  138. package/src/modules/Users/Profile/index.tsx +169 -31
  139. package/src/modules/Users/Profile/style.tsx +81 -1
  140. package/src/modules/Users/Roles/RoleItem/index.tsx +2 -2
  141. package/src/modules/Users/UserCreate/SiteItem/index.tsx +11 -14
  142. package/src/modules/Users/UserForm/atoms.tsx +3 -3
  143. package/src/modules/Users/UserForm/index.tsx +25 -29
  144. package/src/modules/Users/UserForm/style.tsx +15 -2
  145. package/src/modules/Users/UserList/UserItem/index.tsx +4 -4
  146. package/src/routes/index.tsx +1 -0
  147. package/src/types/index.tsx +2 -0
  148. /package/src/modules/Sites/SitesList/{RecentSiteItem → RecentSites/RecentSiteItem}/style.tsx +0 -0
@@ -1,18 +1,17 @@
1
- import React, { useState } from "react";
1
+ import { useState } from "react";
2
2
  import { connect } from "react-redux";
3
- import { RouteComponentProps, withRouter } from "react-router-dom";
4
- import { version } from "./../../../../../package.json";
5
-
6
- import { IRouter, multisite, site } from "@ax/routes";
3
+ import { type RouteComponentProps, withRouter } from "react-router-dom";
7
4
 
8
- import { ILanguage, IRootState, ISite, IStructuredData } from "@ax/types";
9
- import { IGlobalSettings } from "@ax/containers/App/reducer";
10
- import { appActions } from "@ax/containers/App";
11
5
  import { Icon, Tag } from "@ax/components";
6
+ import { appActions } from "@ax/containers/App";
7
+ import type { IGlobalSettings } from "@ax/containers/App/reducer";
12
8
  import { Restricted } from "@ax/guards";
9
+ import { type IRouter, multisite, site } from "@ax/routes";
10
+ import type { ILanguage, IRootState, ISite, IStructuredData, IUser } from "@ax/types";
13
11
 
14
- import NavItem from "./NavItem";
12
+ import { version } from "./../../../../../package.json";
15
13
  import { NavProvider } from "./context";
14
+ import NavItem from "./NavItem";
16
15
 
17
16
  import * as S from "./style";
18
17
 
@@ -20,13 +19,14 @@ const NavMenu = (props: IProps) => {
20
19
  const {
21
20
  location,
22
21
  setHistoryPush,
23
- logout,
22
+ logoutAndNavigate,
24
23
  currentSiteInfo,
25
24
  siteLanguages,
26
25
  lang,
27
26
  categories,
28
27
  globalSettings,
29
28
  structuredData,
29
+ currentUser,
30
30
  } = props;
31
31
 
32
32
  const { useForms } = globalSettings;
@@ -48,9 +48,8 @@ const NavMenu = (props: IProps) => {
48
48
  setIsOpened(!isOpened);
49
49
  };
50
50
 
51
- const siteLogo = currentSiteInfo && currentSiteInfo.bigAvatar ? currentSiteInfo.bigAvatar : logoPlaceholder;
52
- const siteLogoMini =
53
- currentSiteInfo && currentSiteInfo.smallAvatar ? currentSiteInfo.smallAvatar : logoMiniPlaceholder;
51
+ const siteLogo = currentSiteInfo?.bigAvatar ? currentSiteInfo.bigAvatar : logoPlaceholder;
52
+ const siteLogoMini = currentSiteInfo?.smallAvatar ? currentSiteInfo.smallAvatar : logoMiniPlaceholder;
54
53
 
55
54
  const sitesPath = "/sites/";
56
55
  const isSite =
@@ -59,7 +58,7 @@ const NavMenu = (props: IProps) => {
59
58
 
60
59
  const goToPublishedSite = () => {
61
60
  const language = siteLanguages.find((l) => l.id === lang.id);
62
- if (language && language.home) {
61
+ if (language?.home) {
63
62
  const urlHome = `${language.home}${language.home.endsWith("/") ? "" : "/"}`;
64
63
  window.open(urlHome, "_blank");
65
64
  }
@@ -74,10 +73,10 @@ const NavMenu = (props: IProps) => {
74
73
  setHistoryPush(profileRoute);
75
74
  };
76
75
 
77
- const filteredSiteRoutes = site.filter((route: IRouter) => useForms || (!useForms && !route.path.includes("/forms")));
78
- const filteredMultisiteRoutes = multisite.filter(
79
- (route: IRouter) => useForms || (!useForms && !route.path.includes("/forms")),
80
- );
76
+ const filterRoutes = (routes: IRouter[]) => routes.filter((route) => useForms || !route.path.includes("/forms"));
77
+
78
+ const filteredSiteRoutes = filterRoutes(site);
79
+ const filteredMultisiteRoutes = filterRoutes(multisite);
81
80
 
82
81
  const config: IConfig = isSite
83
82
  ? {
@@ -114,7 +113,7 @@ const NavMenu = (props: IProps) => {
114
113
  name: "Logout",
115
114
  icon: "Power",
116
115
  path: "",
117
- onClick: logout,
116
+ onClick: logoutAndNavigate,
118
117
  };
119
118
 
120
119
  const profileRoute = {
@@ -123,6 +122,7 @@ const NavMenu = (props: IProps) => {
123
122
  icon: "User",
124
123
  path: isSite ? "/site/profile" : "/profile",
125
124
  onClick: goToProfile,
125
+ avatar: currentUser ? { image: currentUser.image?.url, name: currentUser.name } : undefined,
126
126
  };
127
127
 
128
128
  const toggleIcon = isOpened ? "Collapsed" : "Extend";
@@ -140,15 +140,21 @@ const NavMenu = (props: IProps) => {
140
140
 
141
141
  if (isSite) {
142
142
  const isSiteCategoriesAvailable = !!categories.site.length;
143
- const siteCategoriesRouteIdx = config.routes.findIndex((route: IRouter) => route.path === "/sites/categories");
144
- config.routes[siteCategoriesRouteIdx].showInNav = isSiteCategoriesAvailable;
143
+ config.routes = config.routes.map((route) =>
144
+ route.path === "/sites/categories" ? { ...route, showInNav: isSiteCategoriesAvailable } : route,
145
+ );
145
146
  } else {
146
147
  const isGlobalCategoriesAvailable = !!categories.global.length;
147
148
  const isGlobalDataAvailable = !!structuredData.global.length;
148
- const globalCategoriesRouteIdx = config.routes.findIndex((route: IRouter) => route.path === "/categories");
149
- const globalDataRouteIdx = config.routes.findIndex((route: IRouter) => route.path === "/data");
150
- config.routes[globalCategoriesRouteIdx].showInNav = isGlobalCategoriesAvailable;
151
- config.routes[globalDataRouteIdx].showInNav = isGlobalDataAvailable;
149
+ config.routes = config.routes.map((route) => {
150
+ if (route.path === "/categories") {
151
+ return { ...route, showInNav: isGlobalCategoriesAvailable };
152
+ }
153
+ if (route.path === "/data") {
154
+ return { ...route, showInNav: isGlobalDataAvailable };
155
+ }
156
+ return route;
157
+ });
152
158
  }
153
159
 
154
160
  return (
@@ -165,37 +171,34 @@ const NavMenu = (props: IProps) => {
165
171
  </S.Home>
166
172
  <S.Lists>
167
173
  <S.List>
168
- {config.routes &&
169
- config.routes
170
- .filter((route: IRouter) => route.showInNav)
171
- .map((route: IRouter): JSX.Element => {
172
- const navItem = (
173
- <NavItem
174
- setHistoryPush={setHistoryPush}
175
- key={route.name}
176
- route={route}
177
- location={location}
178
- type={config.type}
179
- isOpened={isOpened}
180
- />
181
- );
182
-
183
- return route.permission ? (
184
- <Restricted key={route.name} to={route.permission}>
185
- {navItem}
186
- </Restricted>
187
- ) : (
188
- navItem
189
- );
190
- })}
174
+ {config.routes
175
+ ?.filter((route: IRouter) => route.showInNav)
176
+ .map((route: IRouter): JSX.Element => {
177
+ const navItem = (
178
+ <NavItem
179
+ setHistoryPush={setHistoryPush}
180
+ key={route.name}
181
+ route={route}
182
+ location={location}
183
+ type={config.type}
184
+ isOpened={isOpened}
185
+ />
186
+ );
187
+
188
+ return route.permission ? (
189
+ <Restricted key={route.name} to={route.permission}>
190
+ {navItem}
191
+ </Restricted>
192
+ ) : (
193
+ navItem
194
+ );
195
+ })}
191
196
  </S.List>
192
197
  <S.List>
193
198
  {isSitePublished && (
194
- <>
195
- <NavItem setHistoryPush={setHistoryPush} route={siteRoute} type={config.type} isOpened={isOpened} />
196
- <S.Separator />
197
- </>
199
+ <NavItem setHistoryPush={setHistoryPush} route={siteRoute} type={config.type} isOpened={isOpened} />
198
200
  )}
201
+ <S.Separator />
199
202
  <NavItem
200
203
  setHistoryPush={setHistoryPush}
201
204
  route={profileRoute}
@@ -214,7 +217,7 @@ const NavMenu = (props: IProps) => {
214
217
  };
215
218
 
216
219
  interface IDispatchProps {
217
- logout(): void;
220
+ logoutAndNavigate(): void;
218
221
  setHistoryPush(path: string): void;
219
222
  }
220
223
 
@@ -237,6 +240,7 @@ interface INavMenuProps {
237
240
  siteLanguages: ILanguage[];
238
241
  lang: { locale: string; id: number };
239
242
  globalSettings: IGlobalSettings;
243
+ currentUser: IUser | null;
240
244
  }
241
245
 
242
246
  const mapStateToProps = (state: IRootState) => ({
@@ -246,12 +250,13 @@ const mapStateToProps = (state: IRootState) => ({
246
250
  siteLanguages: state.sites.currentSiteLanguages,
247
251
  lang: state.app.lang,
248
252
  globalSettings: state.app.globalSettings,
253
+ currentUser: state.users.currentUser,
249
254
  });
250
255
 
251
256
  type IProps = INavMenuProps & IDispatchProps & RouteComponentProps;
252
257
 
253
258
  const mapDispatchToProps = {
254
- logout: appActions.logout,
259
+ logoutAndNavigate: appActions.logoutAndNavigate,
255
260
  setHistoryPush: appActions.setHistoryPush,
256
261
  };
257
262
 
@@ -1,6 +1,6 @@
1
1
  import styled from "styled-components";
2
2
 
3
- export const NavLink = styled.a`
3
+ const NavLink = styled.a`
4
4
  display: flex;
5
5
  align-items: center;
6
6
  overflow: hidden;
@@ -9,12 +9,12 @@ export const NavLink = styled.a`
9
9
  width: 100%;
10
10
  `;
11
11
 
12
- export const GoBack = styled.div`
12
+ const GoBack = styled.div`
13
13
  display: none;
14
14
  width: auto;
15
15
  `;
16
16
 
17
- export const Home = styled.div<{ type: string; isSite: boolean; isOpened: boolean; siteSelector: boolean }>`
17
+ const Home = styled.div<{ type: string; isSite: boolean; isOpened: boolean; siteSelector: boolean }>`
18
18
  padding: ${(p) => `${p.theme.spacing.xs} 12px`};
19
19
  background-color: ${(p) =>
20
20
  p.type === "multisite" ? p.theme.color.uiMainMenuBackground : p.theme.color.uiBarBackground};
@@ -41,7 +41,7 @@ export const Home = styled.div<{ type: string; isSite: boolean; isOpened: boolea
41
41
  }
42
42
  `;
43
43
 
44
- export const Logo = styled.img`
44
+ const Logo = styled.img`
45
45
  max-height: 40px;
46
46
  height: 100%;
47
47
  width: auto;
@@ -52,7 +52,7 @@ export const Logo = styled.img`
52
52
  left: 0;
53
53
  `;
54
54
 
55
- export const LogoSite = styled.img`
55
+ const LogoSite = styled.img`
56
56
  display: block;
57
57
  max-height: 40px;
58
58
  height: 100%;
@@ -64,7 +64,7 @@ export const LogoSite = styled.img`
64
64
  left: 0;
65
65
  `;
66
66
 
67
- export const LogoSiteMini = styled.img`
67
+ const LogoSiteMini = styled.img`
68
68
  margin: 0 auto;
69
69
  max-height: 40px;
70
70
  height: 100%;
@@ -74,7 +74,7 @@ export const LogoSiteMini = styled.img`
74
74
  opacity: 1;
75
75
  `;
76
76
 
77
- export const Title = styled.span`
77
+ const Title = styled.span`
78
78
  bottom: -3px;
79
79
  position: relative;
80
80
  display: flex;
@@ -83,7 +83,7 @@ export const Title = styled.span`
83
83
  color: ${(p) => p.theme.color.textHighEmphasisInverse};
84
84
  `;
85
85
 
86
- export const NavWrapper = styled.nav<{ type: string; isOpened: boolean }>`
86
+ const NavWrapper = styled.nav<{ type: string; isOpened: boolean }>`
87
87
  ${(p) => p.theme.textStyle.uiL};
88
88
  position: relative;
89
89
  width: ${(p) => (p.isOpened ? `calc(${p.theme.spacing.l} * 5)` : `calc(${p.theme.spacing.m} * 3)`)};
@@ -107,7 +107,7 @@ export const NavWrapper = styled.nav<{ type: string; isOpened: boolean }>`
107
107
  }
108
108
  `;
109
109
 
110
- export const Lists = styled.div`
110
+ const Lists = styled.div`
111
111
  display: flex;
112
112
  flex-direction: column;
113
113
  justify-content: space-between;
@@ -115,9 +115,11 @@ export const Lists = styled.div`
115
115
  padding-top: ${(p) => p.theme.spacing.s};
116
116
  `;
117
117
 
118
- export const List = styled.ul``;
118
+ const List = styled.ul``;
119
119
 
120
- export const Separator = styled.li`
120
+ const Separator = styled.li`
121
121
  border-bottom: 1px solid ${(p) => p.theme.color.uiLineInverse};
122
122
  margin: ${(p) => `${p.theme.spacing.s} 0`};
123
123
  `;
124
+
125
+ export { NavLink, GoBack, Home, Logo, LogoSite, LogoSiteMini, Title, NavWrapper, Lists, List, Separator };
@@ -37,7 +37,7 @@ const CreatePass = (props: IProps) => {
37
37
 
38
38
  const passCreated = await createPassword(parseInt(id), params);
39
39
  if (passCreated) {
40
- setHistoryPush("/profile?init=true");
40
+ setHistoryPush("/sites");
41
41
  }
42
42
  };
43
43
 
@@ -1,15 +1,17 @@
1
- import React, { memo, useRef, useState } from "react";
1
+ import type React from "react";
2
+ import { memo, useRef, useState } from "react";
2
3
  import { connect } from "react-redux";
3
4
 
4
- import { Icon, DragAndDrop, ProgressBar } from "@ax/components";
5
- import { IFile, IRootState } from "@ax/types";
5
+ import { DragAndDrop, Icon, ProgressBar } from "@ax/components";
6
+ import { VALID_DOCUMENT_FORMATS, VALID_FILE_FORMATS } from "@ax/constants";
6
7
  import { fileDriveActions } from "@ax/containers/FileDrive";
8
+ import type { IFile, IRootState } from "@ax/types";
7
9
 
8
10
  import * as S from "./style";
9
11
 
10
12
  const FileDragAndDrop = (props: IProps) => {
11
13
  const {
12
- validFormats,
14
+ customFormats,
13
15
  isUploading,
14
16
  isSuccess,
15
17
  isError,
@@ -27,8 +29,9 @@ const FileDragAndDrop = (props: IProps) => {
27
29
  resetError,
28
30
  } = props;
29
31
 
32
+ const validFormats = customFormats ? customFormats : VALID_FILE_FORMATS;
30
33
  const validExtensions = validFormats.map((format) => `.${format}`).join(",");
31
- const videoFormats = ["mov", "mp4", "wmv", "avi", "webm", "mkv"];
34
+ const validFormatsText = customFormats ? customFormats.join(", ") : `${VALID_DOCUMENT_FORMATS.join(", ")} and videos`;
32
35
  const filesInputRef = useRef<any>(null);
33
36
  const filesButtonRef = useRef<any>(null);
34
37
  const [inDropZone, setInDropZone] = useState(false);
@@ -169,7 +172,7 @@ const FileDragAndDrop = (props: IProps) => {
169
172
  Select files
170
173
  </S.FilesButton>
171
174
  <S.DragSubtitle>
172
- Valid formats: {validFormats.filter((format) => !videoFormats.includes(format)).join(", ")} and videos.
175
+ Valid formats: {validFormatsText}.
173
176
  <br />
174
177
  Max. size: 50MB
175
178
  </S.DragSubtitle>
@@ -180,7 +183,7 @@ const FileDragAndDrop = (props: IProps) => {
180
183
  </S.DropIcon>
181
184
  <S.DragTitle>Drop your file</S.DragTitle>
182
185
  <S.DragSubtitle>
183
- Valid formats: {validFormats.filter((format) => !videoFormats.includes(format)).join(", ")} and videos.
186
+ Valid formats: {validFormatsText}.
184
187
  <br />
185
188
  Max. size: 50MB
186
189
  </S.DragSubtitle>
@@ -249,7 +252,7 @@ const FileDragAndDrop = (props: IProps) => {
249
252
  };
250
253
 
251
254
  interface IProps {
252
- validFormats: string[];
255
+ customFormats?: string[];
253
256
  isUploading: boolean;
254
257
  isSuccess: boolean;
255
258
  isError: boolean;
@@ -1,12 +1,14 @@
1
- import React, { useState } from "react";
2
- import { IFile } from "@ax/types";
1
+ import { useState } from "react";
2
+
3
3
  import { Button, FloatingMenu, IconAction, Toast, Tooltip } from "@ax/components";
4
- import { useModal, useToast } from "@ax/hooks";
5
4
  import { getFileIcon } from "@ax/helpers";
6
- import FileDragAndDrop from "../FileDragAndDrop";
5
+ import { useModal, useToast } from "@ax/hooks";
6
+ import type { IFile } from "@ax/types";
7
+
8
+ import type { IFileFormState } from "..";
7
9
  import { NotSavedModal } from "../atoms";
10
+ import FileDragAndDrop from "../FileDragAndDrop";
8
11
  import DetailPanel from "./DetailPanel";
9
- import { IFileFormState } from "..";
10
12
 
11
13
  import * as S from "./style";
12
14
 
@@ -38,8 +40,6 @@ const FileModal = (props: IProps) => {
38
40
  const iconUrl = `/img/icons/${getFileIcon(fileType)}`;
39
41
  const index = items.indexOf(file.id);
40
42
 
41
- const validFormats = ["pdf", "doc", "docx", "xls", "xlsx", "zip", "mov", "mp4", "wmv", "avi", "webm", "mkv"];
42
-
43
43
  const handleArrowClick = (isPrev: boolean) => () => {
44
44
  if (isDirty) {
45
45
  setIsArrowPrev(isPrev);
@@ -117,10 +117,9 @@ const FileModal = (props: IProps) => {
117
117
  {isDNDVisible && (
118
118
  <S.DragAndDropWrapper>
119
119
  <FileDragAndDrop
120
- validFormats={validFormats}
121
120
  handleUpload={handleUpload}
122
121
  inverse={true}
123
- replaceData={{ fileID: id, keepURL: replaceType === "full" ? false : true }}
122
+ replaceData={{ fileID: id, keepURL: replaceType !== "full" }}
124
123
  siteID={site || "global"}
125
124
  />
126
125
  </S.DragAndDropWrapper>
@@ -19,9 +19,9 @@ import {
19
19
  Toast,
20
20
  Tooltip,
21
21
  } from "@ax/components";
22
+ import { VALID_FILE_FORMATS } from "@ax/constants";
22
23
  import { fileDriveActions } from "@ax/containers/FileDrive";
23
24
  import { useBulkSelection, useIsDirty, useModal, usePermission, useResizable, useToast } from "@ax/hooks";
24
- import { LOCALE, pluralize } from "@ax/locales";
25
25
  import type {
26
26
  IBulkAction,
27
27
  IFile,
@@ -126,22 +126,6 @@ const FileDrive = (props: IProps) => {
126
126
  const hasFolders = !!folders.length;
127
127
  const isRoot = !breadcrumb.length;
128
128
  const isGrid = displayMode === "grid";
129
- const validFormats = [
130
- "pdf",
131
- "doc",
132
- "docx",
133
- "xls",
134
- "xlsx",
135
- "zip",
136
- "csv",
137
- "txt",
138
- "mov",
139
- "mp4",
140
- "wmv",
141
- "avi",
142
- "webm",
143
- "mkv",
144
- ];
145
129
 
146
130
  const allowedToAccessGlobalFromSite = usePermission("mediaGallery.accessToGlobalFileDriveFromSite");
147
131
 
@@ -752,7 +736,6 @@ const FileDrive = (props: IProps) => {
752
736
  <Modal isOpen={isUploadOpen} hide={toggleUploadModal} size="XL" title="Upload file">
753
737
  {isUploadOpen && (
754
738
  <FileDragAndDrop
755
- validFormats={validFormats}
756
739
  folderID={currentFolderID}
757
740
  handleUpload={handleUpload}
758
741
  handleMultipleUpload={handleMultipleUpload}
@@ -83,7 +83,7 @@ const FormEditor = (props: IProps) => {
83
83
  const { isOpen: isUseOpen, toggleModal: toggleUseModal } = useModal();
84
84
  const { isOpen: isUpdateOpen, toggleModal: toggleUpdateModal } = useModal();
85
85
 
86
- const { isDirty, setIsDirty } = useShouldBeSaved(formContent || {});
86
+ const { isDirty, setIsDirty } = useShouldBeSaved(formContent);
87
87
  const browserRef = useRef<HTMLDivElement>(null);
88
88
 
89
89
  const deleteFormPermission = isSiteView ? "forms.deleteForms" : "global.forms.deleteForms";
@@ -25,7 +25,9 @@ const isEffectivelyVisible = (el: HTMLElement): boolean => {
25
25
 
26
26
  const HeadingsOverlay = ({ headingFilter }: IHeadingsOverlayProps) => {
27
27
  const [boxes, setBoxes] = useState<HeadingBox[]>([]);
28
+ const [, setTick] = useState(0);
28
29
  const rafRef = useRef<number>(0);
30
+ const frameRef = useRef<number>(0);
29
31
 
30
32
  useEffect(() => {
31
33
  const update = () => {
@@ -33,8 +35,6 @@ const HeadingsOverlay = ({ headingFilter }: IHeadingsOverlayProps) => {
33
35
  rafRef.current = requestAnimationFrame(() => {
34
36
  const selector = headingFilter || "h1, h2, h3, h4, h5, h6";
35
37
  const headings = Array.from(document.querySelectorAll<HTMLElement>(selector));
36
- const scrollX = window.scrollX;
37
- const scrollY = window.scrollY;
38
38
  const boxes: HeadingBox[] = [];
39
39
  for (let i = 0; i < headings.length; i++) {
40
40
  const el = headings[i];
@@ -44,9 +44,6 @@ const HeadingsOverlay = ({ headingFilter }: IHeadingsOverlayProps) => {
44
44
  boxes.push({
45
45
  id: el.dataset.griddoid || `heading-${i}`,
46
46
  tag: el.tagName.toLowerCase(),
47
- rect,
48
- scrollX,
49
- scrollY,
50
47
  });
51
48
  }
52
49
  setBoxes(boxes);
@@ -73,9 +70,26 @@ const HeadingsOverlay = ({ headingFilter }: IHeadingsOverlayProps) => {
73
70
  };
74
71
  }, [headingFilter]);
75
72
 
73
+ useEffect(() => {
74
+ const updateFrame = () => {
75
+ frameRef.current = requestAnimationFrame(() => {
76
+ setTick((t) => t + 1);
77
+ updateFrame();
78
+ });
79
+ };
80
+
81
+ updateFrame();
82
+
83
+ return () => cancelAnimationFrame(frameRef.current);
84
+ }, []);
85
+
76
86
  return createPortal(
77
87
  <div data-testid="headings-overlay">
78
- {boxes.map(({ id, tag, rect, scrollX, scrollY }) => {
88
+ {boxes.map(({ id, tag }) => {
89
+ const el = document.querySelector<HTMLElement>(`[data-griddoid="${id}"]`) ||
90
+ document.querySelector(tag);
91
+ if (!el) return null;
92
+ const rect = el.getBoundingClientRect();
79
93
  const color = headColors[tag];
80
94
  if (!color) return null;
81
95
  const labelAbove = rect.left < 30;
@@ -84,8 +98,8 @@ const HeadingsOverlay = ({ headingFilter }: IHeadingsOverlayProps) => {
84
98
  key={id}
85
99
  $color={color}
86
100
  style={{
87
- top: rect.top + scrollY,
88
- left: rect.left + scrollX,
101
+ top: rect.top,
102
+ left: rect.left,
89
103
  width: rect.width,
90
104
  height: rect.height,
91
105
  }}
@@ -104,9 +118,6 @@ const HeadingsOverlay = ({ headingFilter }: IHeadingsOverlayProps) => {
104
118
  interface HeadingBox {
105
119
  id: string;
106
120
  tag: string;
107
- rect: DOMRect;
108
- scrollX: number;
109
- scrollY: number;
110
121
  }
111
122
 
112
123
  export interface IHeadingsOverlayProps {
@@ -1,7 +1,7 @@
1
1
  import styled from "styled-components";
2
2
 
3
3
  const Box = styled.div<{ $color: string }>`
4
- position: absolute;
4
+ position: fixed;
5
5
  outline: 2px solid ${(p) => p.$color};
6
6
  z-index: 1001;
7
7
  pointer-events: none;
@@ -1,6 +1,6 @@
1
1
  import { useState } from "react";
2
2
 
3
- import { Button, ErrorToast, IconAction, Loader, Toast, Tooltip } from "@ax/components";
3
+ import { Button, ErrorToast, IconAction, ImageDragAndDrop, Loader, Toast, Tooltip } from "@ax/components";
4
4
  import { useModal, useToast } from "@ax/hooks";
5
5
  import type { IGetFolderParams, IImage } from "@ax/types";
6
6
 
@@ -8,7 +8,6 @@ import { type Fields, GriddoImageExp } from "@griddo/core";
8
8
 
9
9
  import type { IImageFormState } from "..";
10
10
  import { NotSavedModal } from "../atoms";
11
- import ImageDragAndDrop from "../ImageDragAndDrop";
12
11
  import DetailPanel from "./DetailPanel";
13
12
 
14
13
  import * as S from "./style";
@@ -39,8 +38,6 @@ const ImageModal = (props: IProps) => {
39
38
 
40
39
  const index = items.indexOf(image.id);
41
40
 
42
- const validFormats = ["jpeg", "jpg", "png", "svg", "gif"];
43
-
44
41
  const handleArrowClick = (isPrev: boolean) => () => {
45
42
  if (isDirty) {
46
43
  setIsArrowPrev(isPrev);
@@ -101,7 +98,6 @@ const ImageModal = (props: IProps) => {
101
98
  {isDNDVisible && (
102
99
  <S.DragAndDropWrapper>
103
100
  <ImageDragAndDrop
104
- validFormats={validFormats}
105
101
  handleUpload={handleUpload}
106
102
  inverse={true}
107
103
  replaceData={{ fileID: id }}
@@ -9,6 +9,7 @@ import {
9
9
  FilterTagsBar,
10
10
  Icon,
11
11
  IconAction,
12
+ ImageDragAndDrop,
12
13
  Loading,
13
14
  MainWrapper,
14
15
  Modal,
@@ -41,7 +42,6 @@ import FolderItem from "./FolderItem";
41
42
  import FolderTree from "./FolderTree";
42
43
  import GridItem from "./GridItem";
43
44
  import { useFilterQuery, useSortedListStatus } from "./hooks";
44
- import ImageDragAndDrop from "./ImageDragAndDrop";
45
45
  import Orientation from "./ImageFilters/Orientation";
46
46
  import SortBy from "./ImageFilters/SortBy";
47
47
  import Type from "./ImageFilters/Type";
@@ -129,7 +129,6 @@ const MediaGallery = (props: IProps) => {
129
129
  const hasFolders = !!folders?.length;
130
130
  const isRoot = !breadcrumb?.length;
131
131
  const isGrid = displayMode === "grid";
132
- const validFormats = ["jpeg", "jpg", "png", "svg", "gif"];
133
132
 
134
133
  const allowedToAccessGlobalFromSite = usePermission("mediaGallery.accessToGlobalGalleryFromSite");
135
134
 
@@ -813,7 +812,6 @@ const MediaGallery = (props: IProps) => {
813
812
  <Modal isOpen={isUploadOpen} hide={toggleUploadModal} size="XL" title="Upload media">
814
813
  {isUploadOpen && (
815
814
  <ImageDragAndDrop
816
- validFormats={validFormats}
817
815
  folderID={currentFolderID}
818
816
  handleUpload={handleUpload}
819
817
  handleMultipleUpload={handleMultipleUpload}