@griddo/ax 11.10.12 → 11.10.13-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@griddo/ax",
3
3
  "description": "Griddo Author Experience",
4
- "version": "11.10.12",
4
+ "version": "11.10.13-rc.1",
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": "9321729f9040a142fa5f3abc6a3b61f743c7f240"
220
+ "gitHead": "f5bb7e21bd1d985da6ebb2ddb0b21494861c935f"
221
221
  }
@@ -1,8 +1,13 @@
1
+ import packageJson from "../../package.json";
2
+
1
3
  const BASE_PATH = process.env.GRIDDO_API_URL || process.env.REACT_APP_API_ENDPOINT;
2
4
 
3
5
  const headers = {
4
6
  "Content-type": "application/json; charset=UTF-8",
5
7
  accept: "application/json",
8
+ "x-application-id": "griddo-ax",
9
+ "x-client-version": packageJson.version,
10
+ "x-client-name": "AX",
6
11
  };
7
12
 
8
13
  export const template = {
@@ -1,8 +1,8 @@
1
- import React, { useState, useEffect } from "react";
1
+ import { useState, useEffect } from "react";
2
2
  import { v4 as uuidv4 } from "uuid";
3
3
 
4
4
  import { Button, FieldsDivider } from "@ax/components";
5
- import { ISite } from "@ax/types";
5
+ import type { ISite } from "@ax/types";
6
6
  import { getDefaultSchema } from "@ax/helpers";
7
7
  import ArrayFieldItem from "./ArrayFieldItem";
8
8
  import ArrayFieldInline from "./ArrayFieldInline";
@@ -28,20 +28,24 @@ const ArrayFieldGroup = (props: IProps): JSX.Element => {
28
28
  const [items, setItems] = useState<any[]>([]);
29
29
  const [isOpen, setIsOpen] = useState<number | null>(null);
30
30
 
31
+ // biome-ignore lint/correctness/useExhaustiveDependencies: false positive
31
32
  useEffect(() => {
32
33
  const initialValue = value ? Object.values(value) : [];
33
- const initialValueMapped = initialValue.map((val: any) => {
34
+ const initialValueMapped = initialValue.map((val) => {
34
35
  return val.id ? val : { id: uuidv4(), ...val };
35
36
  });
36
37
  setItems(initialValueMapped);
37
38
  }, [editorID]);
38
39
 
39
40
  const handleClick = () => {
40
- const defaultValues = getDefaultSchema(selectedContent.component);
41
- const newComponent =
42
- !!defaultValues[objKey] && defaultValues[objKey].length
43
- ? { ...defaultValues[objKey][0], id: uuidv4() }
44
- : { id: uuidv4() };
41
+ let newComponent = { id: uuidv4() };
42
+ if(selectedContent){
43
+ const defaultValues = getDefaultSchema(selectedContent.component);
44
+ newComponent =
45
+ !!defaultValues[objKey] && defaultValues[objKey].length
46
+ ? { ...defaultValues[objKey][0], id: uuidv4() }
47
+ : newComponent;
48
+ }
45
49
 
46
50
  const newItems = [...items, newComponent];
47
51
  setItems(newItems);
@@ -72,40 +76,39 @@ const ArrayFieldGroup = (props: IProps): JSX.Element => {
72
76
  <div>
73
77
  <DividerComponent />
74
78
  <div>
75
- {items &&
76
- items.map((item: any, index: number) => {
77
- const handleFieldChange = (newValue: Record<string, unknown>) => handleChange(newValue, index);
78
- return arrayType === "inline" ? (
79
- <ArrayFieldInline
80
- key={item.id}
81
- fields={innerFields}
82
- item={item}
83
- index={index}
84
- onChange={handleFieldChange}
85
- handleDelete={handleDelete}
86
- site={site}
87
- disabled={disabled}
88
- parentKey={objKey}
89
- actions={actions}
90
- />
91
- ) : (
92
- <ArrayFieldItem
93
- key={item.id}
94
- name={name}
95
- fields={innerFields}
96
- item={item}
97
- index={index}
98
- onChange={handleFieldChange}
99
- handleDelete={handleDelete}
100
- isOpen={isOpen}
101
- setIsOpen={setIsOpen}
102
- site={site}
103
- disabled={disabled}
104
- parentKey={objKey}
105
- actions={actions}
106
- />
107
- );
108
- })}
79
+ {items?.map((item, index) => {
80
+ const handleFieldChange = (newValue: Record<string, unknown>) => handleChange(newValue, index);
81
+ return arrayType === "inline" ? (
82
+ <ArrayFieldInline
83
+ key={item.id}
84
+ fields={innerFields}
85
+ item={item}
86
+ index={index}
87
+ onChange={handleFieldChange}
88
+ handleDelete={handleDelete}
89
+ site={site}
90
+ disabled={disabled}
91
+ parentKey={objKey}
92
+ actions={actions}
93
+ />
94
+ ) : (
95
+ <ArrayFieldItem
96
+ key={item.id}
97
+ name={name}
98
+ fields={innerFields}
99
+ item={item}
100
+ index={index}
101
+ onChange={handleFieldChange}
102
+ handleDelete={handleDelete}
103
+ isOpen={isOpen}
104
+ setIsOpen={setIsOpen}
105
+ site={site}
106
+ disabled={disabled}
107
+ parentKey={objKey}
108
+ actions={actions}
109
+ />
110
+ );
111
+ })}
109
112
  </div>
110
113
  <S.ButtonWrapper>
111
114
  <Button type="button" onClick={handleClick} buttonStyle="line" disabled={disabled}>
@@ -1,6 +1,5 @@
1
- import React from "react";
2
- import { ICheck } from "@ax/types";
3
1
  import Icon from "@ax/components/Icon";
2
+ import type { ICheck } from "@ax/types";
4
3
 
5
4
  import * as S from "./style";
6
5
 
@@ -23,12 +22,12 @@ const CheckField = (props: ICheckFieldProps): JSX.Element => {
23
22
 
24
23
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
25
24
  const isChecked = e.target.checked;
26
- onChange && onChange({ value, isChecked });
25
+ onChange?.({ value, isChecked });
27
26
  };
28
27
 
29
- const handleMouseOver = () => setHoverCheck && setHoverCheck(true);
28
+ const handleMouseOver = () => setHoverCheck?.(true);
30
29
 
31
- const handleMouseLeave = () => setHoverCheck && setHoverCheck(false);
30
+ const handleMouseLeave = () => setHoverCheck?.(false);
32
31
 
33
32
  return (
34
33
  <S.Wrapper className={className}>
@@ -1,7 +1,7 @@
1
- import React, { useState } from "react";
1
+ import { useState } from "react";
2
2
  import { connect } from "react-redux";
3
3
 
4
- import { IDataSource, ILanguage, IRootState, ISchemaField, ISite, IStructuredData } from "@ax/types";
4
+ import type { IDataSource, ILanguage, IRootState, ISchemaField, ISite, IStructuredData } from "@ax/types";
5
5
  import {
6
6
  Button,
7
7
  FloatingMenu,
@@ -14,7 +14,8 @@ import {
14
14
  UniqueCheck,
15
15
  } from "@ax/components";
16
16
 
17
- import { IReferenceState, IRefField, ISource, useReference } from "../Context";
17
+ import type { IReferenceState, IRefField, ISource } from "../Context";
18
+ import { useReference } from "../Context";
18
19
  import AutoItem from "./AutoItem";
19
20
 
20
21
  import * as S from "./style";
@@ -36,9 +37,9 @@ const AutoPanel = (props: IProps): JSX.Element => {
36
37
  };
37
38
  const [configState, setConfigState] = useState<IConfigState>(initConfig);
38
39
  const initToggle = {
39
- isSiteActive: state.site && state.site !== "global" ? true : false,
40
- isLangActive: state.lang ? true : false,
41
- isGlobalActive: state.site && state.site === "global" ? true : false,
40
+ isSiteActive: !!(state.site && state.site !== "global" ),
41
+ isLangActive: !!state.lang,
42
+ isGlobalActive: !!(state.site && state.site === "global" ),
42
43
  errorSite: false,
43
44
  errorLang: false,
44
45
  errorMsg: "",
@@ -130,8 +131,8 @@ const AutoPanel = (props: IProps): JSX.Element => {
130
131
  title: "",
131
132
  value: state.quantity,
132
133
  onChange: (quantity: number) => setState((state: IReferenceState) => ({ ...state, quantity })),
133
- maxValue: validators && validators.maxValue ? validators.maxValue : undefined,
134
- minValue: validators && validators.minValue ? validators.minValue : undefined,
134
+ maxValue: validators?.maxValue ? validators.maxValue : undefined,
135
+ minValue: validators?.minValue ? validators.minValue : undefined,
135
136
  };
136
137
 
137
138
  const checkErrors = (): boolean => {
@@ -258,7 +259,7 @@ const AutoPanel = (props: IProps): JSX.Element => {
258
259
  };
259
260
 
260
261
  const handleLangChange = (value: string) => {
261
- const lang = value.length ? parseInt(value) : undefined;
262
+ const lang = value.length ? parseInt(value, 10) : undefined;
262
263
  setState((state: IReferenceState) => ({ ...state, lang }));
263
264
  if (value) {
264
265
  setToggleState({ ...toggleState, isLangActive: true, errorLang: false, errorMsg: "" });
@@ -295,7 +296,8 @@ const AutoPanel = (props: IProps): JSX.Element => {
295
296
  state.sources.map((singleSource: ISource) => {
296
297
  const source = state.sourceTitles.find((el: IDataSource) => el.id === singleSource.structuredData);
297
298
  const { filters = [], filterOperator, globalOperator } = singleSource;
298
- return source ? (
299
+ if(!source) return null;
300
+ return (
299
301
  <AutoItem
300
302
  key={singleSource.structuredData}
301
303
  source={source}
@@ -309,9 +311,7 @@ const AutoPanel = (props: IProps): JSX.Element => {
309
311
  globalOperator={globalOperator}
310
312
  siteID={state.site || site?.id}
311
313
  />
312
- ) : (
313
- <></>
314
- );
314
+ )
315
315
  })}
316
316
  </S.SourcesWrapper>
317
317
  <S.RadioWrapper>
@@ -383,9 +383,9 @@ const AutoPanel = (props: IProps): JSX.Element => {
383
383
  </S.SubConfigContent>
384
384
  </S.ConfigWrapper>
385
385
  </>
386
- ) : (
387
- <></>
388
- )}
386
+ ) :
387
+ null
388
+ }
389
389
 
390
390
  <S.OptionLabel
391
391
  onClick={() => toggleConfig("isDataOpen")}
@@ -483,7 +483,7 @@ const AutoPanel = (props: IProps): JSX.Element => {
483
483
  <UniqueCheck
484
484
  name="preferenceLanguageCheck"
485
485
  options={[
486
- { value: false, name: "preferenceLanguage", title: `${currentLang} content shown first` },
486
+ { title: `${currentLang} content shown first` },
487
487
  ]}
488
488
  value={state.preferenceLanguage}
489
489
  onChange={handlePreferenceLanguageChange}
@@ -1,8 +1,9 @@
1
- import React from "react";
2
1
  import { CheckField } from "@ax/components";
3
2
 
3
+ import * as S from "./style";
4
+
4
5
  const UniqueCheck = (props: IProps) => {
5
- const { name, value, options, onChange, disabled, inversed = false, className } = props;
6
+ const { name, value, options, onChange, disabled, inversed = false, className, description } = props;
6
7
  const uniqueOption = options[0];
7
8
 
8
9
  const handleChange = (changeEvt: ICheckEvent) => {
@@ -10,17 +11,22 @@ const UniqueCheck = (props: IProps) => {
10
11
  onChange(isChecked);
11
12
  };
12
13
 
14
+ const classes = description ? "with-subtitle" : "";
15
+
13
16
  return (
14
- <CheckField
15
- name={name}
16
- checked={!!value && value}
17
- title={uniqueOption.title}
18
- value={value}
19
- onChange={handleChange}
20
- disabled={disabled}
21
- inversed={inversed}
22
- className={className}
23
- />
17
+ <S.Wrapper className={classes}>
18
+ <CheckField
19
+ name={name}
20
+ checked={!!value}
21
+ title={uniqueOption.title}
22
+ value={value}
23
+ onChange={handleChange}
24
+ disabled={disabled}
25
+ inversed={inversed}
26
+ className={className}
27
+ />
28
+ <S.Subtitle>{description}</S.Subtitle>
29
+ </S.Wrapper>
24
30
  );
25
31
  };
26
32
 
@@ -31,17 +37,16 @@ interface ICheckEvent {
31
37
 
32
38
  interface IProps {
33
39
  name: string;
34
- value: any;
40
+ value: string | number;
35
41
  options: ICheck[];
36
- onChange: any;
42
+ onChange(isChecked: boolean): void;
37
43
  disabled?: boolean;
38
44
  inversed?: boolean;
39
45
  className?: string;
46
+ description?: string;
40
47
  }
41
48
 
42
49
  interface ICheck {
43
- name: string;
44
- value: any;
45
50
  title: string;
46
51
  }
47
52
 
@@ -0,0 +1,17 @@
1
+ import styled from "styled-components";
2
+
3
+ const Wrapper = styled.div`
4
+ &.with-subtitle label {
5
+ ${(p) => p.theme.textStyle.uiL};
6
+ font-weight: 600;
7
+ }
8
+ `;
9
+
10
+ const Subtitle = styled.div`
11
+ ${(p) => p.theme.textStyle.uiS};
12
+ font-weight: 400;
13
+ color: ${(p) => p.theme.color.textHighEmphasis};
14
+ padding-left: ${(p) => p.theme.spacing.m};
15
+ `;
16
+
17
+ export { Wrapper, Subtitle };
@@ -1,9 +1,10 @@
1
- import React, { memo, useEffect, useState } from "react";
1
+ import { memo, useEffect, useState } from "react";
2
2
  import { connect } from "react-redux";
3
- import { IRootState, IFile } from "@ax/types";
3
+
4
4
  import { Button, FieldsBehavior, IconAction } from "@ax/components";
5
- import { formatBytes, getFileIcon, getFormattedDateWithTimezone } from "@ax/helpers";
6
5
  import { fileDriveActions } from "@ax/containers/FileDrive";
6
+ import { formatBytes, getFileIcon, getFormattedDateWithTimezone } from "@ax/helpers";
7
+ import type { IFile, IRootState } from "@ax/types";
7
8
 
8
9
  import * as S from "./style";
9
10
 
@@ -14,6 +15,7 @@ const GalleryDetailPanel = (props: IProps) => {
14
15
  const initState: IFormState = { title: title || "", alt: alt || "", tags: tags || [] };
15
16
  const [form, setForm] = useState(initState);
16
17
 
18
+ // biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
17
19
  useEffect(() => {
18
20
  setForm(initState);
19
21
  }, [selectedFile]);
@@ -105,6 +107,7 @@ const GalleryDetailPanel = (props: IProps) => {
105
107
  fieldType="TagsField"
106
108
  onChange={handleTags}
107
109
  disabled={!isAllowedToEdit}
110
+ helptext="Type a tag and press enter to create it"
108
111
  />
109
112
  </S.FormWrapper>
110
113
  </S.PanelForm>
@@ -1,9 +1,10 @@
1
- import React, { memo, useEffect, useState } from "react";
1
+ import { memo, useEffect, useState } from "react";
2
2
  import { connect } from "react-redux";
3
- import { IRootState, IImage, IGetFolderParams } from "@ax/types";
3
+
4
4
  import { Button, FieldsBehavior, IconAction } from "@ax/components";
5
- import { formatBytes, getFileExtension, getFormattedDateWithTimezone } from "@ax/helpers";
6
5
  import { galleryActions } from "@ax/containers/Gallery";
6
+ import { formatBytes, getFileExtension, getFormattedDateWithTimezone } from "@ax/helpers";
7
+ import type { IGetFolderParams, IImage, IRootState } from "@ax/types";
7
8
 
8
9
  import * as S from "./style";
9
10
 
@@ -114,6 +115,7 @@ const GalleryDetailPanel = (props: IProps) => {
114
115
  fieldType="TagsField"
115
116
  onChange={handleTags}
116
117
  disabled={!isAllowedToEdit}
118
+ helptext="Type a tag and press enter to create it"
117
119
  />
118
120
  </S.FormWrapper>
119
121
  </S.PanelForm>
@@ -1,9 +1,11 @@
1
- import React, { useEffect, useRef, useState } from "react";
1
+ import type { ReactNode } from "react";
2
+ import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
3
+
2
4
  import { useHandleClickOutside } from "@ax/hooks";
3
5
 
4
6
  import * as S from "./style";
5
7
 
6
- const Tooltip = (props: ITooltipProps): JSX.Element => {
8
+ const Tooltip = (props: ITooltipProps) => {
7
9
  const { content, children, hideOnClick = true, bottom, left, expanded, top } = props;
8
10
 
9
11
  const initialState: IState = {
@@ -15,26 +17,31 @@ const Tooltip = (props: ITooltipProps): JSX.Element => {
15
17
  const [state, setState] = useState(initialState);
16
18
  const { active, childrenWidth, clicked, fixOutOfBounds } = state;
17
19
 
18
- const changeState = (value: any) => {
20
+ const changeState = useCallback((value: Partial<IState>) => {
19
21
  setState((state) => ({ ...state, ...value }));
20
- };
22
+ }, []);
21
23
 
22
24
  const childrenRef = useRef<HTMLDivElement>(null);
23
25
  const tipRef = useRef<HTMLDivElement>(null);
24
-
25
- let timeout: any;
26
+ const timeoutRef = useRef<NodeJS.Timeout | null>(null);
26
27
 
27
28
  const showTip = () => {
28
29
  if (!clicked) {
29
- timeout = setTimeout(() => {
30
+ if (timeoutRef.current) {
31
+ clearTimeout(timeoutRef.current);
32
+ }
33
+ timeoutRef.current = setTimeout(() => {
30
34
  changeState({ active: true });
31
35
  }, 1000);
32
36
  }
33
37
  };
34
38
 
35
39
  const hideTip = () => {
36
- clearInterval(timeout);
37
- changeState({ active: false });
40
+ if (timeoutRef.current) {
41
+ clearTimeout(timeoutRef.current);
42
+ timeoutRef.current = null;
43
+ }
44
+ changeState({ active: false, fixOutOfBounds: 0 });
38
45
  };
39
46
 
40
47
  const handleClick = () => {
@@ -44,8 +51,8 @@ const Tooltip = (props: ITooltipProps): JSX.Element => {
44
51
  }
45
52
  };
46
53
 
47
- const handleClickOutside = (e: any) => {
48
- if (childrenRef.current && childrenRef.current.contains(e.target)) {
54
+ const handleClickOutside = (e: MouseEvent | TouchEvent) => {
55
+ if (childrenRef.current?.contains(e.target as Node)) {
49
56
  return;
50
57
  }
51
58
  changeState({ clicked: false });
@@ -53,16 +60,22 @@ const Tooltip = (props: ITooltipProps): JSX.Element => {
53
60
 
54
61
  useHandleClickOutside(clicked, handleClickOutside);
55
62
 
56
- // biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
57
63
  useEffect(() => {
58
- if (childrenRef.current && childrenRef.current.children[0]) {
64
+ return () => {
65
+ if (timeoutRef.current) {
66
+ clearTimeout(timeoutRef.current);
67
+ }
68
+ };
69
+ }, []);
70
+
71
+ useEffect(() => {
72
+ if (childrenRef.current?.children[0]) {
59
73
  const childrenWidth = childrenRef.current.children[0].clientWidth;
60
74
  changeState({ childrenWidth });
61
75
  }
62
- }, [childrenRef]);
76
+ }, [changeState]);
63
77
 
64
- // biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
65
- useEffect(() => {
78
+ useLayoutEffect(() => {
66
79
  if (active && tipRef.current) {
67
80
  const clientRect = tipRef.current.getBoundingClientRect();
68
81
 
@@ -72,11 +85,13 @@ const Tooltip = (props: ITooltipProps): JSX.Element => {
72
85
  changeState({ fixOutOfBounds: left });
73
86
  } else if (right > windowSize) {
74
87
  changeState({ fixOutOfBounds: right - windowSize });
88
+ } else {
89
+ changeState({ fixOutOfBounds: 0 });
75
90
  }
76
91
  }
77
- }, [tipRef, active]);
92
+ }, [active, changeState]);
78
93
 
79
- if (!content) return children;
94
+ if (!content) return <>{children}</>;
80
95
 
81
96
  return (
82
97
  <S.Tooltip
@@ -112,8 +127,8 @@ interface IState {
112
127
  }
113
128
 
114
129
  export interface ITooltipProps {
115
- content?: string | boolean | JSX.Element[] | JSX.Element;
116
- children: any;
130
+ content?: string | boolean | JSX.Element | JSX.Element[];
131
+ children: ReactNode;
117
132
  hideOnClick?: boolean;
118
133
  bottom?: boolean;
119
134
  left?: number;
@@ -151,6 +151,22 @@ export default {
151
151
  },
152
152
  ],
153
153
  },
154
+ {
155
+ title: "GEO (LLMS)",
156
+ type: "FieldGroup",
157
+ key: "geo",
158
+ collapsed: true,
159
+ fields: [
160
+ {
161
+ type: "UniqueCheck",
162
+ key: "isLlmsEnabled",
163
+ options: [
164
+ { "title": "Include this page in LLMs.txt" }
165
+ ],
166
+ description: "If enabled, this page will be listed in LLMs.txt for language models."
167
+ },
168
+ ],
169
+ },
154
170
  {
155
171
  title: "Analytics Data Layer",
156
172
  type: "FieldGroup",
@@ -206,5 +222,6 @@ export default {
206
222
  socialTitle: "",
207
223
  socialDescription: "",
208
224
  socialImage: {},
225
+ isLlmsEnabled: true,
209
226
  },
210
227
  };
@@ -217,6 +217,22 @@ export default {
217
217
  },
218
218
  ],
219
219
  },
220
+ {
221
+ title: "GEO (LLMS)",
222
+ type: "FieldGroup",
223
+ key: "geo",
224
+ collapsed: true,
225
+ fields: [
226
+ {
227
+ type: "UniqueCheck",
228
+ key: "isLlmsEnabled",
229
+ options: [
230
+ { "title": "Include this page in LLMs.txt" }
231
+ ],
232
+ description: "If enabled, this page will be listed in LLMs.txt for language models."
233
+ },
234
+ ],
235
+ },
220
236
  {
221
237
  title: "Analytics Data Layer",
222
238
  type: "FieldGroup",
@@ -280,5 +296,6 @@ export default {
280
296
  customizeThemes: false,
281
297
  headerTheme: null,
282
298
  footerTheme: null,
299
+ isLlmsEnabled: true,
283
300
  },
284
301
  };