@griddo/ax 11.10.45 → 11.10.46

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 (29) hide show
  1. package/package.json +2 -2
  2. package/src/components/Fields/IntegrationsField/IntegrationItem/index.tsx +6 -7
  3. package/src/components/LanguageMenu/index.tsx +14 -9
  4. package/src/components/LanguageMenu/style.tsx +6 -4
  5. package/src/components/MainWrapper/AppBar/index.tsx +1 -0
  6. package/src/containers/PageEditor/actions.tsx +102 -95
  7. package/src/locales/en-US.ts +6 -0
  8. package/src/locales/es-ES.ts +6 -0
  9. package/src/locales/index.ts +17 -2
  10. package/src/modules/Analytics/DimensionItem/index.tsx +5 -6
  11. package/src/modules/Analytics/GroupItem/index.tsx +5 -6
  12. package/src/modules/Categories/CategoriesList/CategoryItem/index.tsx +23 -23
  13. package/src/modules/Categories/CategoriesList/index.tsx +14 -5
  14. package/src/modules/Content/PageItem/index.tsx +1 -1
  15. package/src/modules/Content/index.tsx +1 -1
  16. package/src/modules/FileDrive/index.tsx +2 -1
  17. package/src/modules/Forms/FormCategoriesList/CategoryItem/index.tsx +8 -6
  18. package/src/modules/Forms/FormCategoriesList/index.tsx +2 -1
  19. package/src/modules/Forms/FormList/index.tsx +2 -2
  20. package/src/modules/GlobalEditor/index.tsx +3 -3
  21. package/src/modules/MediaGallery/index.tsx +2 -1
  22. package/src/modules/PageEditor/index.tsx +4 -4
  23. package/src/modules/Redirects/index.tsx +2 -1
  24. package/src/modules/Settings/Integrations/index.tsx +3 -2
  25. package/src/modules/StructuredData/StructuredDataList/index.tsx +14 -7
  26. package/src/modules/Users/UserEdit/index.tsx +5 -4
  27. package/src/modules/Users/UserList/UserItem/index.tsx +6 -6
  28. package/src/modules/Users/UserList/index.tsx +5 -1
  29. package/src/types/index.tsx +1 -1
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@griddo/ax",
3
3
  "description": "Griddo Author Experience",
4
- "version": "11.10.45",
4
+ "version": "11.10.46",
5
5
  "authors": [
6
6
  "Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
7
7
  "Diego M. Béjar <diego.bejar@secuoyas.com>",
@@ -217,5 +217,5 @@
217
217
  "publishConfig": {
218
218
  "access": "public"
219
219
  },
220
- "gitHead": "6d4675ea1342dd0cd23de683dc7cfbd16cce126f"
220
+ "gitHead": "fd83d3991eb31335881dc050377bdb915b6c5bb2"
221
221
  }
@@ -1,12 +1,11 @@
1
- import * as React from "react";
2
-
3
- import { Icon, ActionMenu, Tooltip, Button, Toast } from "@ax/components";
1
+ import { ActionMenu, Button, Icon, Toast, Tooltip } from "@ax/components";
4
2
  import { useModal, useToast } from "@ax/hooks";
5
- import { IIntegration, IIntegrationVariable, ILanguage } from "@ax/types";
3
+ import type { IIntegration, IIntegrationVariable, ILanguage } from "@ax/types";
6
4
 
7
- import VariablesPanel from "./VariablesPanel";
8
- import CustomPanel from "./CustomPanel";
9
5
  import { DeleteModal } from "./atoms";
6
+ import CustomPanel from "./CustomPanel";
7
+ import VariablesPanel from "./VariablesPanel";
8
+
10
9
  import * as S from "./style";
11
10
 
12
11
  const IntegrationItem = (props: IProps): JSX.Element => {
@@ -60,7 +59,7 @@ const IntegrationItem = (props: IProps): JSX.Element => {
60
59
  const integrationName = isCustom ? "Custom Code" : integration.name;
61
60
 
62
61
  const mainDeleteModalAction = {
63
- title: "Remove add-on",
62
+ title: "Remove",
64
63
  onClick: removeItem,
65
64
  };
66
65
  const secondaryDeleteModalAction = { title: "Cancel", onClick: toggleModalDelete };
@@ -1,15 +1,12 @@
1
- import React from "react";
2
-
3
1
  import { Flag, Icon } from "@ax/components";
4
- import { ILanguage } from "@ax/types";
2
+ import type { ILanguage } from "@ax/types";
5
3
 
6
4
  import * as S from "./style";
7
5
 
8
6
  const LanguageMenu = (props: ILanguageMenuProps): JSX.Element => {
9
- const { availableLanguages, language, setLanguage, isInAppBar, currentLanguages } = props;
7
+ const { availableLanguages, language, setLanguage, isInAppBar, currentLanguages, isDraft } = props;
10
8
 
11
- const getCurrentLanguage = (lang: string) =>
12
- currentLanguages && currentLanguages.find((currLanguage) => currLanguage.locale === lang);
9
+ const getCurrentLanguage = (lang: string) => currentLanguages?.find((currLanguage) => currLanguage.locale === lang);
13
10
 
14
11
  const isNewVersion = (lang: string) => currentLanguages && !getCurrentLanguage(lang);
15
12
  const isEditableVersion = (lang: string) => currentLanguages && getCurrentLanguage(lang);
@@ -37,11 +34,17 @@ const LanguageMenu = (props: ILanguageMenuProps): JSX.Element => {
37
34
  };
38
35
 
39
36
  const languageMenuItem = (item: ILanguage) => {
40
- const handleClick = () => setLanguage(item);
37
+ const isDisabled = isDraft && isNewVersion(item.locale);
38
+ const handleClick = () => {
39
+ if (!isDisabled) {
40
+ setLanguage(item);
41
+ }
42
+ };
41
43
  return (
42
44
  <S.LanguageItem
43
45
  key={item.locale}
44
46
  selected={item.locale === language}
47
+ disabled={isDisabled}
45
48
  onClick={handleClick}
46
49
  data-testid="language-menu-item"
47
50
  >
@@ -52,9 +55,10 @@ const LanguageMenu = (props: ILanguageMenuProps): JSX.Element => {
52
55
  <S.Locale>{item.label}</S.Locale> - {item.language}
53
56
  </S.LanguageText>
54
57
  </S.LanguageLabel>
55
- {isNewVersion(item.locale) && language !== item.locale && (
56
- <S.LanguageSubtext> Add new version </S.LanguageSubtext>
58
+ {isNewVersion(item.locale) && language !== item.locale && !isDisabled && (
59
+ <S.LanguageSubtext>Add new version</S.LanguageSubtext>
57
60
  )}
61
+ {isDisabled && <S.LanguageSubtext>Draft cannot be translated</S.LanguageSubtext>}
58
62
  </S.LanguageItemWrapper>
59
63
  {getLanguageIcon(item.locale)}
60
64
  </S.LanguageItem>
@@ -73,6 +77,7 @@ export interface ILanguageMenuProps {
73
77
  availableLanguages: ILanguage[];
74
78
  currentLanguages: ILanguage[];
75
79
  isInAppBar?: boolean;
80
+ isDraft?: boolean;
76
81
  setLanguage(lang: ILanguage): void;
77
82
  }
78
83
 
@@ -11,7 +11,7 @@ const LanguageTextWrapper = styled.div`
11
11
  margin-bottom: ${(p) => p.theme.spacing.xxs};
12
12
  `;
13
13
 
14
- const LanguageItem = styled.li<{ selected: boolean }>`
14
+ const LanguageItem = styled.li<{ selected: boolean; disabled?: boolean }>`
15
15
  display: flex;
16
16
  align-items: center;
17
17
  justify-content: space-between;
@@ -20,12 +20,14 @@ const LanguageItem = styled.li<{ selected: boolean }>`
20
20
  padding: ${(p) => p.theme.spacing.s};
21
21
  min-height: ${(p) => p.theme.spacing.l};
22
22
  min-width: calc(${(p) => p.theme.spacing.l} * 4);
23
+ opacity: ${(p) => (p.disabled ? 0.5 : 1)};
24
+ cursor: ${(p) => (p.disabled ? "not-allowed" : "pointer")};
23
25
  &:focus {
24
- background: ${(p) => p.theme.color.overlayFocusPrimary};
26
+ background: ${(p) => (p.disabled ? "transparent" : p.theme.color.overlayFocusPrimary)};
25
27
  }
26
28
  &:hover {
27
- background: ${(p) => p.theme.color.overlayHoverPrimary};
28
- color: ${(p) => (p.selected ? p.theme.color.interactive01 : p.theme.color.textHighEmphasis)};
29
+ background: ${(p) => (p.disabled ? "transparent" : p.theme.color.overlayHoverPrimary)};
30
+ color: ${(p) => (p.disabled ? p.theme.color.textMediumEmphasis : p.selected ? p.theme.color.interactive01 : p.theme.color.textHighEmphasis)};
29
31
  }
30
32
  `;
31
33
 
@@ -227,6 +227,7 @@ const AppBar = (props: IProps): JSX.Element => {
227
227
  currentLanguages={currentLanguages || availableLanguages}
228
228
  setLanguage={handleLanguage}
229
229
  isInAppBar={true}
230
+ isDraft={pageStatus === "modified"}
230
231
  />
231
232
  </FloatingMenu>
232
233
  </Tooltip>
@@ -1,124 +1,123 @@
1
- import type { Dispatch } from "redux";
2
-
3
- import {
4
- isReqOk,
5
- getDefaultSchema,
6
- getDefaultTemplate,
7
- deepClone,
8
- getSchema,
9
- getStructuredDataFromPage,
10
- getCurrentPageStructuredData,
11
- getNullValue,
12
- handleRequest,
13
- protectFormKeys,
14
- } from "@ax/helpers";
1
+ import { pages, sites, structuredData } from "@ax/api";
2
+ import { appActions } from "@ax/containers/App";
3
+ import { navigationActions } from "@ax/containers/Navigation";
4
+ import { sitesActions } from "@ax/containers/Sites";
5
+ import { structuredDataActions } from "@ax/containers/StructuredData";
6
+ import { usersActions } from "@ax/containers/Users";
15
7
  import {
16
- getUpdatedComponents,
17
- getUpdatedSections,
18
- updateComponent,
19
- updateByEditorID,
8
+ checkH1content,
9
+ checkMaxModules,
10
+ evaluateComputedFields,
20
11
  findByEditorID,
12
+ findFieldsErrors,
13
+ findPackagesActivationErrors,
21
14
  generateEditorIDs,
22
- parseData,
23
- getNewBreadcrumb,
24
- moveModule,
25
- getLastModuleEditorID,
26
15
  getLastComponentEditorID,
27
- replaceElements,
28
- findFieldsErrors,
16
+ getLastModuleEditorID,
17
+ getNewBreadcrumb,
29
18
  getParentKey,
30
- checkH1content,
19
+ getUpdatedComponents,
20
+ getUpdatedSections,
21
+ moveModule,
22
+ parseData,
31
23
  parseValidationErrors,
32
- findPackagesActivationErrors,
33
- checkMaxModules,
34
- evaluateComputedFields,
24
+ replaceElements,
25
+ updateByEditorID,
26
+ updateComponent,
35
27
  } from "@ax/forms";
36
- import { appActions } from "@ax/containers/App";
37
- import { navigationActions } from "@ax/containers/Navigation";
38
- import { structuredDataActions } from "@ax/containers/StructuredData";
39
- import { sitesActions } from "@ax/containers/Sites";
40
- import { usersActions } from "@ax/containers/Users";
41
- import { pages, sites, structuredData } from "@ax/api";
42
28
  import {
43
- getDefaultPageNavigation,
44
- getDefaultIntegrations,
45
- getPageData,
46
- getPageNavigation,
47
- getStateValues,
48
- addElementToCollection,
49
- addElementToComponent,
50
- } from "./utils";
29
+ deepClone,
30
+ getCurrentPageStructuredData,
31
+ getDefaultSchema,
32
+ getDefaultTemplate,
33
+ getNullValue,
34
+ getSchema,
35
+ getStructuredDataFromPage,
36
+ handleRequest,
37
+ isReqOk,
38
+ protectFormKeys,
39
+ } from "@ax/helpers";
40
+ import type {
41
+ IBreadcrumbItem,
42
+ IComponent,
43
+ IErrorItem,
44
+ IGetSitePagesParams,
45
+ IModule,
46
+ INotification,
47
+ IPage,
48
+ IPageLanguage,
49
+ IRootState,
50
+ ISavePageParams,
51
+ ISchema,
52
+ IStructuredDataContent,
53
+ IUserEditing,
54
+ } from "@ax/types";
55
+
56
+ import type { Dispatch } from "redux";
57
+
51
58
  import {
59
+ RESET_PAGE_EDITOR_STORE,
52
60
  SET_BREADCRUMB,
53
- SET_SCHEMA,
54
- SET_TAB,
55
- SET_SELECTED_EDITOR_ID,
56
- SET_SELECTED_CONTENT,
57
- SET_EDITOR_CONTENT,
58
- SET_TEMPLATE,
61
+ SET_COPY_MODULE,
59
62
  SET_CURRENT_PAGE_ID,
60
- SET_CURRENT_PAGE_STATUS,
61
- SET_CURRENT_PAGE_NAME,
62
63
  SET_CURRENT_PAGE_LANGUAGES,
63
- SET_IS_NEW_TRANSLATION,
64
- SET_TEMPLATE_CONFIG,
65
- SET_SELECTED_PARENT,
64
+ SET_CURRENT_PAGE_NAME,
65
+ SET_CURRENT_PAGE_STATUS,
66
+ SET_EDITOR_CONTENT,
66
67
  SET_ERRORS,
67
- SET_VALIDATED,
68
- SET_SITE_PAGE_ID,
69
- SET_USER_EDITING,
70
- SET_LAST_ELEMENT_ADDED_ID,
71
- SET_COPY_MODULE,
72
68
  SET_IS_IA_TRANSLATED,
69
+ SET_IS_NEW_TRANSLATION,
70
+ SET_LAST_ELEMENT_ADDED_ID,
73
71
  SET_LAST_TIMEOUT,
74
- RESET_PAGE_EDITOR_STORE,
72
+ SET_SCHEMA,
75
73
  SET_SCROLL_EDITOR_ID,
74
+ SET_SELECTED_CONTENT,
75
+ SET_SELECTED_EDITOR_ID,
76
+ SET_SELECTED_PARENT,
77
+ SET_SITE_PAGE_ID,
78
+ SET_TAB,
79
+ SET_TEMPLATE,
80
+ SET_TEMPLATE_CONFIG,
81
+ SET_USER_EDITING,
82
+ SET_VALIDATED,
76
83
  } from "./constants";
77
-
78
84
  import type {
79
- IPage,
80
- ISavePageParams,
81
- IBreadcrumbItem,
82
- ISchema,
83
- IErrorItem,
84
- IUserEditing,
85
- IStructuredDataContent,
86
- INotification,
87
- IPageLanguage,
88
- IComponent,
89
- IModule,
90
- IRootState,
91
- IGetSitePagesParams,
92
- } from "@ax/types";
93
- import type {
94
- ISetBreadcrumb,
95
- ISetSchema,
96
- ISetTab,
97
- ISetSelectedEditorID,
98
85
  IFieldProps,
99
- ISetEditorContent,
100
- ISetTemplate,
101
- ISetSelectedContent,
86
+ IResetPageEditorStore,
87
+ ISetBreadcrumb,
88
+ ISetCopyModule,
102
89
  ISetCurrentPageIDAction,
103
- ISetCurrentPageStatusAction,
104
- ISetCurrentPageNameAction,
105
90
  ISetCurrentPageLanguagesAction,
106
- ISetIsNewTranslation,
107
- ISetTemplateConfig,
108
- ISetSelectedParent,
91
+ ISetCurrentPageNameAction,
92
+ ISetCurrentPageStatusAction,
93
+ ISetEditorContent,
109
94
  ISetErrors,
110
- ISetValidated,
111
- ISetSitePageID,
112
- ISetUserEditing,
113
- ISetLastElementAddedId,
114
- ISetCopyModule,
115
95
  ISetIsIATranslated,
96
+ ISetIsNewTranslation,
97
+ ISetLastElementAddedId,
116
98
  ISetLastTimeout,
117
- IResetPageEditorStore,
99
+ ISetSchema,
118
100
  ISetScrollEditorID,
101
+ ISetSelectedContent,
102
+ ISetSelectedEditorID,
103
+ ISetSelectedParent,
104
+ ISetSitePageID,
105
+ ISetTab,
106
+ ISetTemplate,
107
+ ISetTemplateConfig,
108
+ ISetUserEditing,
109
+ ISetValidated,
119
110
  } from "./interfaces";
120
-
121
111
  import { pageStatus } from "./interfaces";
112
+ import {
113
+ addElementToCollection,
114
+ addElementToComponent,
115
+ getDefaultIntegrations,
116
+ getDefaultPageNavigation,
117
+ getPageData,
118
+ getPageNavigation,
119
+ getStateValues,
120
+ } from "./utils";
122
121
 
123
122
  const { setIsLoading, setIsSaving, handleError } = appActions;
124
123
  const { getDefaults } = navigationActions;
@@ -330,7 +329,11 @@ function getPageBreadcrumb(pageId: number): (dispatch: Dispatch, getState: () =>
330
329
  };
331
330
  }
332
331
 
333
- function getPage(pageID?: number, global?: boolean): (dispatch: Dispatch, getState: () => IRootState) => Promise<void> {
332
+ function getPage(
333
+ pageID?: number,
334
+ global?: boolean,
335
+ preferDraft?: boolean,
336
+ ): (dispatch: Dispatch, getState: () => IRootState) => Promise<void> {
334
337
  return async (dispatch, getState) => {
335
338
  try {
336
339
  dispatch(setIsLoading(true));
@@ -345,6 +348,10 @@ function getPage(pageID?: number, global?: boolean): (dispatch: Dispatch, getSta
345
348
  const response: { status: number; data: IPage } = await pages.getPageInfo(pageID);
346
349
  const page: IPage = parseData(response.data, true);
347
350
 
351
+ if (preferDraft && page.haveDraftPage) {
352
+ return getPage(page.haveDraftPage, global)(dispatch, getState);
353
+ }
354
+
348
355
  if (currentSiteInfo) {
349
356
  await getPageLanguages(pageID, currentSiteInfo.id, page.entity)(dispatch);
350
357
  } else {
@@ -74,4 +74,10 @@ export const enUS = {
74
74
  user: { one: "user", other: "users" },
75
75
  rol: { one: "rol", other: "roles" },
76
76
  },
77
+ actionLabel: {
78
+ delete: {
79
+ imperative: "delete", // Para botones: "Delete"
80
+ running: "deleting", // Gerundio: "Deleting..."
81
+ },
82
+ },
77
83
  } as const;
@@ -74,4 +74,10 @@ export const esES = {
74
74
  user: { one: "usuario", other: "usuarios" },
75
75
  rol: { one: "rol", other: "roles" },
76
76
  },
77
+ actionLabel: {
78
+ delete: {
79
+ imperative: "borrar", // Para botones: "Delete"
80
+ running: "borrando", // Gerundio: "Deleting..."
81
+ },
82
+ },
77
83
  } as const;
@@ -15,8 +15,23 @@ const allLocales = {
15
15
  * @param entry La entrada del objeto de locales
16
16
  * @param count El número de elementos (por defecto 1)
17
17
  */
18
- export const pluralize = (entry: ItemLabel, count: number = 1): string => {
18
+ export function pluralize(entry: ItemLabel, count: number = 1) {
19
19
  return count === 1 ? entry.one : entry.other;
20
- };
20
+ }
21
+
22
+ /**
23
+ * Converts a given string to Title Case, capitalizing the first letter of every word.
24
+ * @param text - The input string to format.
25
+ * @returns The transformed string with every word capitalized.
26
+ */
27
+ export function toTitleCase(text: string) {
28
+ if (!text) return text;
29
+
30
+ return text
31
+ .toLowerCase()
32
+ .split(" ")
33
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
34
+ .join(" ");
35
+ }
21
36
 
22
37
  export const LOCALE = allLocales[currentLocale as keyof typeof allLocales];
@@ -1,11 +1,10 @@
1
- import React from "react";
2
-
3
- import { IDimension } from "@ax/types";
4
- import { useModal } from "@ax/hooks";
5
- import { splitAndJoin, trimText } from "@ax/helpers";
6
1
  import { Modal } from "@ax/components";
2
+ import { splitAndJoin, trimText } from "@ax/helpers";
3
+ import { useModal } from "@ax/hooks";
4
+ import type { IDimension } from "@ax/types";
7
5
 
8
6
  import DimensionPanel from "../DimensionPanel";
7
+
9
8
  import * as S from "./style";
10
9
 
11
10
  const Item = (props: IProps): JSX.Element => {
@@ -29,7 +28,7 @@ const Item = (props: IProps): JSX.Element => {
29
28
  ];
30
29
 
31
30
  const mainRemoveModalAction = {
32
- title: "Delete Dimension",
31
+ title: "Delete",
33
32
  onClick: removeDimension,
34
33
  };
35
34
 
@@ -1,11 +1,10 @@
1
- import React from "react";
2
-
3
- import { IDimension, IDimensionsGroup } from "@ax/types";
4
- import { useModal } from "@ax/hooks";
5
- import { splitAndJoin } from "@ax/helpers";
6
1
  import { Modal } from "@ax/components";
2
+ import { splitAndJoin } from "@ax/helpers";
3
+ import { useModal } from "@ax/hooks";
4
+ import type { IDimension, IDimensionsGroup } from "@ax/types";
7
5
 
8
6
  import GroupPanel from "../GroupPanel";
7
+
9
8
  import * as S from "./style";
10
9
 
11
10
  const Item = (props: IProps): JSX.Element => {
@@ -29,7 +28,7 @@ const Item = (props: IProps): JSX.Element => {
29
28
  ];
30
29
 
31
30
  const mainRemoveModalAction = {
32
- title: "Delete Group",
31
+ title: "Delete",
33
32
  onClick: removeGroup,
34
33
  };
35
34
 
@@ -1,15 +1,18 @@
1
- import React, { useState } from "react";
1
+ import type React from "react";
2
+ import { useState } from "react";
2
3
  import { connect } from "react-redux";
3
- import { AnimateLayoutChanges, useSortable } from "@dnd-kit/sortable";
4
4
 
5
- import { structuredDataActions } from "@ax/containers/StructuredData";
6
- import { useModal, usePermission } from "@ax/hooks";
7
- import { ICheck, IRootState, IDataLanguage, IStructuredDataCategory, ILanguage, ICategoryGroup } from "@ax/types";
8
- import { CheckField, FloatingMenu, Flag, LanguageMenu, Icon, Tag } from "@ax/components";
9
5
  import { structuredData } from "@ax/api";
6
+ import { CheckField, Flag, FloatingMenu, Icon, LanguageMenu, Tag } from "@ax/components";
7
+ import { structuredDataActions } from "@ax/containers/StructuredData";
10
8
  import { isReqOk } from "@ax/helpers";
11
- import CategoryPanel from "../CategoryPanel";
9
+ import { useModal, usePermission } from "@ax/hooks";
10
+ import type { ICategoryGroup, ICheck, IDataLanguage, ILanguage, IRootState, IStructuredDataCategory } from "@ax/types";
11
+
12
+ import { type AnimateLayoutChanges, useSortable } from "@dnd-kit/sortable";
13
+
12
14
  import { DeleteGroupModal, DeleteModal } from "../atoms";
15
+ import CategoryPanel from "../CategoryPanel";
13
16
  import { isCategory, isCategoryGroup } from "../utils";
14
17
 
15
18
  import * as S from "./style";
@@ -51,8 +54,7 @@ const CategoryItem = (props: ICategoryItemProps): JSX.Element => {
51
54
  const allowedToEditTaxonomy = currentSiteID ? allowedToEditSiteCategory : allowedToEditGlobalCategory;
52
55
  const allowedToDeleteTaxonomy = currentSiteID ? allowedToDeleteSiteCategory : allowedToDeleteGlobalCategory;
53
56
 
54
- const animateLayoutChanges: AnimateLayoutChanges = ({ isSorting, wasDragging }) =>
55
- isSorting || wasDragging ? false : true;
57
+ const animateLayoutChanges: AnimateLayoutChanges = ({ isSorting, wasDragging }) => !(isSorting || wasDragging);
56
58
 
57
59
  const { attributes, isDragging, listeners, setDraggableNodeRef, setDroppableNodeRef, transform, transition } =
58
60
  useSortable({
@@ -111,16 +113,13 @@ const CategoryItem = (props: ICategoryItemProps): JSX.Element => {
111
113
  const getCurrentLanguages = () => {
112
114
  const availables: ILanguage[] = [];
113
115
 
114
- dataLanguages &&
115
- dataLanguages.forEach(
116
- (dataLang) =>
117
- languages &&
118
- languages.forEach((language) => {
119
- if (language.id === dataLang.language) {
120
- availables.push(language);
121
- }
122
- }),
123
- );
116
+ dataLanguages?.forEach((dataLang) => {
117
+ languages?.forEach((language) => {
118
+ if (language.id === dataLang.language) {
119
+ availables.push(language);
120
+ }
121
+ });
122
+ });
124
123
 
125
124
  return availables;
126
125
  };
@@ -148,7 +147,7 @@ const CategoryItem = (props: ICategoryItemProps): JSX.Element => {
148
147
  id: language.id,
149
148
  };
150
149
 
151
- const isNew = currentLanguages.find((l) => l.id === language.id) ? false : true;
150
+ const isNew = !currentLanguages.find((l) => l.id === language.id);
152
151
  let content: IStructuredDataCategory | ICategoryGroup | null = null;
153
152
  if (!isNew) {
154
153
  const translationLang = category.dataLanguages.find((dataLang) => dataLang.language === lang.id);
@@ -183,7 +182,7 @@ const CategoryItem = (props: ICategoryItemProps): JSX.Element => {
183
182
  );
184
183
 
185
184
  const mainDeleteModalAction = {
186
- title: "Yes, delete it",
185
+ title: "delete",
187
186
  onClick: removeCategory,
188
187
  };
189
188
 
@@ -196,7 +195,7 @@ const CategoryItem = (props: ICategoryItemProps): JSX.Element => {
196
195
 
197
196
  const secondaryDeleteGroupModalAction = { title: "Cancel", onClick: toggleGroupModal };
198
197
 
199
- const selectable = isCategoryGroup(category) && category.selectable === false ? false : true;
198
+ const selectable = !(isCategoryGroup(category) && category.selectable === false);
200
199
 
201
200
  return (
202
201
  <>
@@ -216,6 +215,7 @@ const CategoryItem = (props: ICategoryItemProps): JSX.Element => {
216
215
  </S.IconWrapperDrag>
217
216
  <S.IconWrapper onClick={handleCheckClick}>
218
217
  {onCollapse && (
218
+ // biome-ignore lint/a11y/useSemanticElements: TODO: fix this
219
219
  <div onClick={onCollapse} role="button" tabIndex={0} onKeyDown={onCollapse}>
220
220
  {collapsed ? <Icon name="UpArrow" /> : <Icon name="DownArrow" />}
221
221
  </div>
@@ -307,7 +307,7 @@ interface IDispatchProps {
307
307
  type ICategoryItemProps = IProps & IDispatchProps;
308
308
 
309
309
  const mapStateToProps = (state: IRootState) => ({
310
- currentSiteID: state.sites.currentSiteInfo && state.sites.currentSiteInfo.id,
310
+ currentSiteID: state.sites.currentSiteInfo?.id ?? null,
311
311
  });
312
312
 
313
313
  const mapDispatchToProps = {
@@ -6,6 +6,7 @@ import { appActions } from "@ax/containers/App";
6
6
  import { structuredDataActions } from "@ax/containers/StructuredData";
7
7
  import { sortBy } from "@ax/helpers";
8
8
  import { useBulkSelection, useModal, usePermission, useToast } from "@ax/hooks";
9
+ import { LOCALE, toTitleCase } from "@ax/locales";
9
10
  import type {
10
11
  ICategoryGroup,
11
12
  IDataPack,
@@ -345,22 +346,30 @@ const CategoriesList = (props: IProps): JSX.Element => {
345
346
  };
346
347
 
347
348
  const mainDeleteModalAction = {
348
- title: "Yes, delete it",
349
+ title: isBulkLoading ? "deleting" : "delete",
349
350
  onClick: bulkDelete,
351
+ disabled: isBulkLoading,
350
352
  };
351
353
 
352
- const secondaryDeleteModalAction = { title: "Cancel", onClick: toggleDeleteModal };
354
+ const secondaryDeleteModalAction = {
355
+ title: "Cancel",
356
+ onClick: toggleDeleteModal,
357
+ };
353
358
 
354
359
  const mainDeleteGroupModalAction = {
355
- title: "Delete",
360
+ title: isBulkLoading ? "deleting" : "delete",
361
+ disabled: isBulkLoading,
356
362
  onClick: bulkDelete,
357
363
  };
358
364
 
359
- const secondaryDeleteGroupModalAction = { title: "Cancel", onClick: toggleGroupModal };
365
+ const secondaryDeleteGroupModalAction = {
366
+ title: "cancel",
367
+ onClick: toggleGroupModal,
368
+ };
360
369
 
361
370
  return (
362
371
  <MainWrapper
363
- title="Categories"
372
+ title={toTitleCase(LOCALE.entityLabel.category.other)}
364
373
  rightButton={rightButtonProps}
365
374
  language={lang}
366
375
  availableLanguages={availableLanguages}
@@ -451,7 +451,7 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
451
451
  );
452
452
 
453
453
  const mainRemoveModalAction = {
454
- title: "Remove Page",
454
+ title: "Remove",
455
455
  onClick: handleRemoveItemFromSite,
456
456
  };
457
457
 
@@ -824,7 +824,7 @@ const Content = (props: IProps): JSX.Element => {
824
824
  const resetFilter = () => resetFilterQuery();
825
825
 
826
826
  const mainDeleteModalAction = {
827
- title: isDeleting ? "Deleting pages" : "Delete pages",
827
+ title: isDeleting ? "Deleting" : "Delete",
828
828
  onClick: bulkDelete,
829
829
  disabled: isDeleting,
830
830
  };
@@ -582,8 +582,9 @@ const FileDrive = (props: IProps) => {
582
582
  const secondaryNewModalAction = { title: "Cancel", onClick: toggleNewModal };
583
583
 
584
584
  const mainDeleteModalAction = {
585
- title: "Delete documents",
585
+ title: isBulkLoading ? "Deleting" : "Delete",
586
586
  onClick: () => handleBulkDeleteFile(),
587
+ disabled: isBulkLoading,
587
588
  };
588
589
 
589
590
  const secondaryDeleteModalAction = { title: "Cancel", onClick: toggleDeleteModal };
@@ -1,13 +1,15 @@
1
- import React from "react";
1
+ import type React from "react";
2
2
  import { connect } from "react-redux";
3
- import { useSortable } from "@dnd-kit/sortable";
4
3
 
4
+ import { CheckField, Icon } from "@ax/components";
5
5
  import { formsActions } from "@ax/containers/Forms";
6
6
  import { useModal, usePermission } from "@ax/hooks";
7
- import { FormCategory, ICheck } from "@ax/types";
8
- import { CheckField, Icon } from "@ax/components";
9
- import CategoryPanel from "../CategoryPanel";
7
+ import type { FormCategory, ICheck } from "@ax/types";
8
+
9
+ import { useSortable } from "@dnd-kit/sortable";
10
+
10
11
  import { DeleteModal } from "../atoms";
12
+ import CategoryPanel from "../CategoryPanel";
11
13
 
12
14
  import * as S from "./style";
13
15
 
@@ -60,7 +62,7 @@ const CategoryItem = (props: ICategoryItemProps): JSX.Element => {
60
62
  : [];
61
63
 
62
64
  const mainDeleteModalAction = {
63
- title: "Yes, delete it",
65
+ title: "delete",
64
66
  onClick: removeCategory,
65
67
  };
66
68
 
@@ -188,8 +188,9 @@ const FormCategoriesList = (props: IProps): JSX.Element => {
188
188
  };
189
189
 
190
190
  const mainDeleteModalAction = {
191
- title: "Yes, delete it",
191
+ title: isBulkLoading ? "Deleting" : "delete",
192
192
  onClick: bulkDelete,
193
+ disabled: isBulkLoading,
193
194
  };
194
195
 
195
196
  const secondaryDeleteModalAction = { title: "Cancel", onClick: toggleDeleteModal };
@@ -16,7 +16,6 @@ import { formsActions } from "@ax/containers/Forms";
16
16
  import { ITEMS_PER_PAGE } from "@ax/containers/Forms/constants";
17
17
  import { getFormTemplates, getSchemaFormCategories } from "@ax/helpers";
18
18
  import { useBulkSelection, useCategoryColors, useModal, usePermission, useToast } from "@ax/hooks";
19
- import { LOCALE, pluralize } from "@ax/locales";
20
19
  import type {
21
20
  FormContent,
22
21
  FormState,
@@ -303,8 +302,9 @@ const FormList = (props: IUserListProps): JSX.Element => {
303
302
  const secondaryUnpublishModalAction = { title: "Cancel", onClick: toggleUnpublishModal };
304
303
 
305
304
  const mainDeleteModalAction = {
306
- title: `Delete form${selectedItems.all.length > 1 ? "s" : ""}`,
305
+ title: isBulkLoading ? "Deleting" : "Delete",
307
306
  onClick: handleDeleteForm,
307
+ disabled: isBulkLoading,
308
308
  };
309
309
 
310
310
  const secondaryDeleteModalAction = { title: "Cancel", onClick: toggleDeleteModal };
@@ -556,12 +556,12 @@ const GlobalEditor = (props: IProps) => {
556
556
  if (selectedPageLanguage) {
557
557
  createNewTranslation(false);
558
558
  setCurrentPageID(selectedPageLanguage.pageId);
559
- await getPage(selectedPageLanguage.pageId);
559
+ await getPage(selectedPageLanguage.pageId, true, isDraft);
560
560
  resetDirty();
561
561
  } else {
562
562
  isAllowedToEditContentPage && setSelectedTab("edit");
563
563
  createNewTranslation(true);
564
- await getPage(pageID);
564
+ await getPage(pageID, true);
565
565
  }
566
566
  };
567
567
 
@@ -780,7 +780,7 @@ const mapDispatchToProps = {
780
780
  };
781
781
 
782
782
  interface IPageEditorDispatchProps {
783
- getPage(pageID?: number, global?: boolean): Promise<void>;
783
+ getPage(pageID?: number, global?: boolean, preferDraft?: boolean): Promise<void>;
784
784
  savePage(data?: {
785
785
  createDraft?: boolean;
786
786
  publishPage?: { status: string };
@@ -635,8 +635,9 @@ const MediaGallery = (props: IProps) => {
635
635
  const secondaryNewModalAction = { title: "Cancel", onClick: toggleNewModal };
636
636
 
637
637
  const mainDeleteModalAction = {
638
- title: "Delete images",
638
+ title: isBulkLoading ? "Deleting" : "Delete",
639
639
  onClick: () => handleBulkDeleteFile(),
640
+ disabled: isBulkLoading,
640
641
  };
641
642
 
642
643
  const secondaryDeleteModalAction = { title: "Cancel", onClick: toggleDeleteModal };
@@ -601,7 +601,7 @@ const PageEditor = (props: IProps) => {
601
601
  if (selectedPageLanguage) {
602
602
  createNewTranslation(false);
603
603
  setCurrentPageID(selectedPageLanguage.pageId);
604
- await getPage(selectedPageLanguage.pageId);
604
+ await getPage(selectedPageLanguage.pageId, false, isDraft);
605
605
  resetDirty();
606
606
  } else {
607
607
  isAllowedToEditContentPage && setSelectedTab("edit");
@@ -814,8 +814,8 @@ const PageEditor = (props: IProps) => {
814
814
  secondaryAction={secondaryDirtyNavigateAction}
815
815
  >
816
816
  <S.ModalContent>
817
- {dirtyNavigateModalText} If you exit without saving it, it will be lost. Do you want to discard
818
- your changes?
817
+ {dirtyNavigateModalText} If you exit without saving it, it will be lost. Do you want to discard your
818
+ changes?
819
819
  </S.ModalContent>
820
820
  </Modal>
821
821
  </MainWrapper>
@@ -893,7 +893,7 @@ const mapDispatchToProps = {
893
893
  };
894
894
 
895
895
  interface IPageEditorDispatchProps {
896
- getPage(pageID?: number): Promise<void>;
896
+ getPage(pageID?: number, global?: boolean, preferDraft?: boolean): Promise<void>;
897
897
  savePage(data?: {
898
898
  createDraft?: boolean;
899
899
  publishPage?: { status: string };
@@ -235,8 +235,9 @@ const Redirects = (props: IProps): JSX.Element => {
235
235
  };
236
236
 
237
237
  const mainDeleteModalAction = {
238
- title: "Delete redirects",
238
+ title: isBulkLoading ? "Deleting" : "Delete",
239
239
  onClick: bulkDelete,
240
+ disabled: isBulkLoading,
240
241
  };
241
242
 
242
243
  const secondaryDeleteModalAction = { title: "Cancel", onClick: toggleModalDelete };
@@ -210,13 +210,14 @@ const Integrations = (props: IIntegrationsProps): JSX.Element => {
210
210
  };
211
211
 
212
212
  const mainDeleteModalAction = {
213
- title: "Delete add-ons",
213
+ title: isBulkLoading ? "Deleting" : "Delete",
214
214
  onClick: bulkDelete,
215
+ disabled: isBulkLoading,
215
216
  };
216
217
  const secondaryDeleteModalAction = { title: "Cancel", onClick: toggleModalDelete };
217
218
 
218
219
  const mainDeactivateModalAction = {
219
- title: "Deactivate add-ons",
220
+ title: "Deactivate",
220
221
  onClick: bulkDeactivate,
221
222
  };
222
223
  const secondaryDeactivateModalAction = { title: "Cancel", onClick: toggleModalDeactivate };
@@ -58,9 +58,8 @@ import BulkHeader from "./BulkHeader";
58
58
  import ContentFilters from "./ContentFilters";
59
59
  import GlobalPageItem from "./GlobalPageItem";
60
60
  import { useFilterQuery, useSortedListStatus } from "./hooks";
61
- import StructuredDataItem from "./StructuredDataItem";
62
61
  import NewContentModal from "./NewContentModal";
63
-
62
+ import StructuredDataItem from "./StructuredDataItem";
64
63
  import {
65
64
  filterByStatus,
66
65
  getAllLangPagesIds,
@@ -365,8 +364,7 @@ const StructuredDataList = (props: IProps): JSX.Element => {
365
364
  };
366
365
 
367
366
  const bulkDelete = async () => {
368
- toggleDeleteModal();
369
-
367
+ setIsBulkLoading(true);
370
368
  const idsToBeDeleted = getAllLangPagesIds(currentSitePages, selectedItems, deleteAllVersions);
371
369
  const deleted = isStructuredDataFromPage
372
370
  ? await deleteBulk(idsToBeDeleted)
@@ -383,6 +381,8 @@ const StructuredDataList = (props: IProps): JSX.Element => {
383
381
  ? setPage(previousPage)
384
382
  : isStructuredDataFromPage && handleGetGlobalPages();
385
383
  unselectAllItems();
384
+ toggleDeleteModal();
385
+ setIsBulkLoading(false);
386
386
  };
387
387
 
388
388
  const handleBulkDelete = () => {
@@ -436,9 +436,12 @@ const StructuredDataList = (props: IProps): JSX.Element => {
436
436
 
437
437
  const handleAddToBulk = (item: ICheck) => addToBulkSelection(item, bulkFilter);
438
438
 
439
- const bulkPublish = () => (isStructuredDataFromPage ? bulkPublishPage(true) : bulkPublishData("undraft"));
439
+ const bulkPublish = async () => {
440
+ isStructuredDataFromPage ? await bulkPublishPage(true) : await bulkPublishData("undraft");
441
+ };
440
442
 
441
- const bulkUnpublish = () => (isStructuredDataFromPage ? bulkPublishPage(false) : bulkPublishData("draft"));
443
+ const bulkUnpublish = async () =>
444
+ isStructuredDataFromPage ? await bulkPublishPage(false) : await bulkPublishData("draft");
442
445
 
443
446
  const unselectAllItems = () => resetBulkSelection();
444
447
 
@@ -738,7 +741,11 @@ const StructuredDataList = (props: IProps): JSX.Element => {
738
741
  <DeleteModal
739
742
  isOpen={isDeleteOpen}
740
743
  toggleModal={toggleDeleteModal}
741
- mainModalAction={{ title: "Delete pages", onClick: bulkDelete }}
744
+ mainModalAction={{
745
+ title: isBulkLoading ? "Deleting" : "Delete",
746
+ onClick: bulkDelete,
747
+ disabled: isBulkLoading,
748
+ }}
742
749
  secondaryModalAction={{ title: "Cancel", onClick: toggleDeleteModal }}
743
750
  {...{ arePagesTranslated, deleteAllVersions, setDeleteAllVersions }}
744
751
  />
@@ -1,11 +1,12 @@
1
- import React, { useEffect, useState } from "react";
1
+ import { useEffect, useState } from "react";
2
2
  import { connect } from "react-redux";
3
3
 
4
+ import { Loading, MainWrapper, Modal, Toast } from "@ax/components";
4
5
  import { appActions } from "@ax/containers/App";
5
6
  import { usersActions } from "@ax/containers/Users";
6
- import { Loading, MainWrapper, Modal, Toast } from "@ax/components";
7
- import { IRootState, ISite, IUser } from "@ax/types";
8
7
  import { useModal, useShouldBeSaved, useToast } from "@ax/hooks";
8
+ import type { IRootState, ISite, IUser } from "@ax/types";
9
+
9
10
  import UserForm from "../UserForm";
10
11
 
11
12
  import * as S from "./style";
@@ -81,7 +82,7 @@ const UserEdit = (props: IProps) => {
81
82
  };
82
83
 
83
84
  const mainDeleteAction = {
84
- title: isSiteView ? "Remove user" : "Delete User",
85
+ title: isSiteView ? "Remove" : "Delete",
85
86
  onClick: isSiteView ? handleRemoveUserFromSite : handleDelete,
86
87
  };
87
88
 
@@ -1,11 +1,11 @@
1
- import React, { useRef } from "react";
1
+ import { useRef } from "react";
2
2
  import { connect } from "react-redux";
3
3
 
4
- import { ICheck, IUser, ISite, IRole, ISiteRoles } from "@ax/types";
5
- import { useAdaptiveText, useModal, usePermission, useToast } from "@ax/hooks";
6
- import { getDaysAgo } from "@ax/helpers";
4
+ import { Avatar, CheckField, ElementsTooltip, Modal, Tag, Toast, Tooltip } from "@ax/components";
7
5
  import { usersActions } from "@ax/containers/Users";
8
- import { CheckField, Avatar, Modal, Tag, Tooltip, Toast, ElementsTooltip } from "@ax/components";
6
+ import { getDaysAgo } from "@ax/helpers";
7
+ import { useAdaptiveText, useModal, usePermission, useToast } from "@ax/hooks";
8
+ import type { ICheck, IRole, ISite, ISiteRoles, IUser } from "@ax/types";
9
9
 
10
10
  import * as S from "./style";
11
11
 
@@ -89,7 +89,7 @@ const UserItem = (props: IUserItemProps): JSX.Element => {
89
89
  };
90
90
 
91
91
  const mainDeleteAction = {
92
- title: isSiteView ? "Remove user" : "Delete user",
92
+ title: isSiteView ? "Remove" : "Delete",
93
93
  onClick: isSiteView ? handleRemoveUserFromSite : handleDeleteUser,
94
94
  };
95
95
 
@@ -221,7 +221,11 @@ const UserList = (props: IUserListProps): JSX.Element => {
221
221
  toggleToast();
222
222
  };
223
223
 
224
- const mainDeleteAction = { title: isSiteView ? "Remove from this site" : "Delete Users", onClick: bulkDelete };
224
+ const mainDeleteAction = {
225
+ title: isSiteView ? (isBulkLoading ? "Removing" : "Remove") : isBulkLoading ? "Deleting" : "Delete",
226
+ onClick: bulkDelete,
227
+ disabled: isBulkLoading,
228
+ };
225
229
  const secondaryDeleteAction = { title: "Cancel", onClick: toggleModal };
226
230
 
227
231
  const filterLabels = {
@@ -846,7 +846,7 @@ export interface IDataPackConfigImport {
846
846
  export interface IModal {
847
847
  isOpen: boolean;
848
848
  toggleModal: () => void;
849
- mainModalAction?: { title: string; onClick: () => void };
849
+ mainModalAction?: { title: string; onClick: () => void; disabled?: boolean };
850
850
  secondaryModalAction?: { title: string; onClick: () => void };
851
851
  isChild?: boolean;
852
852
  }