@gravity-ui/page-constructor 5.13.0 → 5.14.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.
Files changed (80) hide show
  1. package/build/cjs/blocks/Questions/QuestionBlockItem/QuestionBlockItem.css +1 -0
  2. package/build/cjs/editor/components/AddBlock/AddBlock.css +1 -2
  3. package/build/cjs/editor/components/CodeEditor/CodeEditor.css +3 -1
  4. package/build/cjs/editor/components/ControlPanel/ControlPanel.css +2 -4
  5. package/build/cjs/editor/components/ControlPanel/ControlPanel.d.ts +4 -2
  6. package/build/cjs/editor/components/ControlPanel/ControlPanel.js +24 -15
  7. package/build/cjs/editor/components/ControlPanel/i18n/en.json +2 -1
  8. package/build/cjs/editor/components/ControlPanel/i18n/index.d.ts +1 -1
  9. package/build/cjs/editor/components/ControlPanel/i18n/ru.json +2 -1
  10. package/build/cjs/editor/components/Layout/Layout.css +10 -6
  11. package/build/cjs/editor/components/Layout/Layout.d.ts +4 -7
  12. package/build/cjs/editor/components/Layout/Layout.js +8 -10
  13. package/build/cjs/editor/components/PageSettings/PageSettings.css +26 -0
  14. package/build/cjs/editor/components/PageSettings/PageSettings.d.ts +11 -0
  15. package/build/cjs/editor/components/PageSettings/PageSettings.js +30 -0
  16. package/build/cjs/editor/components/PageSettings/i18n/en.json +3 -0
  17. package/build/cjs/editor/components/PageSettings/i18n/index.d.ts +1 -0
  18. package/build/cjs/editor/components/PageSettings/i18n/index.js +9 -0
  19. package/build/cjs/editor/components/PageSettings/i18n/ru.json +3 -0
  20. package/build/cjs/editor/containers/Editor/Editor.css +17 -0
  21. package/build/cjs/editor/containers/Editor/Editor.d.ts +1 -1
  22. package/build/cjs/editor/containers/Editor/Editor.js +17 -65
  23. package/build/cjs/editor/containers/Editor/hooks/useCode.d.ts +14 -0
  24. package/build/cjs/editor/containers/{Form/hooks.js → Editor/hooks/useCode.js} +4 -14
  25. package/build/cjs/editor/containers/Editor/hooks/useEditorState.d.ts +49 -0
  26. package/build/cjs/editor/containers/Editor/hooks/useEditorState.js +99 -0
  27. package/build/cjs/editor/containers/Form/Form.css +0 -10
  28. package/build/cjs/editor/containers/Form/Form.d.ts +1 -8
  29. package/build/cjs/editor/containers/Form/Form.js +14 -39
  30. package/build/cjs/editor/store/main/index.js +1 -1
  31. package/build/cjs/editor/store/settings/index.d.ts +3 -3
  32. package/build/cjs/editor/store/settings/index.js +4 -4
  33. package/build/cjs/editor/store/settings/reducer.d.ts +9 -9
  34. package/build/cjs/editor/store/settings/reducer.js +6 -6
  35. package/build/cjs/editor/types/index.d.ts +3 -4
  36. package/build/cjs/editor/types/index.js +7 -8
  37. package/build/esm/blocks/Questions/QuestionBlockItem/QuestionBlockItem.css +1 -0
  38. package/build/esm/editor/components/AddBlock/AddBlock.css +1 -2
  39. package/build/esm/editor/components/CodeEditor/CodeEditor.css +3 -1
  40. package/build/esm/editor/components/ControlPanel/ControlPanel.css +2 -4
  41. package/build/esm/editor/components/ControlPanel/ControlPanel.d.ts +4 -2
  42. package/build/esm/editor/components/ControlPanel/ControlPanel.js +26 -17
  43. package/build/esm/editor/components/ControlPanel/i18n/en.json +2 -1
  44. package/build/esm/editor/components/ControlPanel/i18n/index.d.ts +1 -1
  45. package/build/esm/editor/components/ControlPanel/i18n/ru.json +2 -1
  46. package/build/esm/editor/components/Layout/Layout.css +10 -6
  47. package/build/esm/editor/components/Layout/Layout.d.ts +4 -7
  48. package/build/esm/editor/components/Layout/Layout.js +9 -11
  49. package/build/esm/editor/components/PageSettings/PageSettings.css +26 -0
  50. package/build/esm/editor/components/PageSettings/PageSettings.d.ts +12 -0
  51. package/build/esm/editor/components/PageSettings/PageSettings.js +27 -0
  52. package/build/esm/editor/components/PageSettings/i18n/en.json +3 -0
  53. package/build/esm/editor/components/PageSettings/i18n/index.d.ts +1 -0
  54. package/build/esm/editor/components/PageSettings/i18n/index.js +5 -0
  55. package/build/esm/editor/components/PageSettings/i18n/ru.json +3 -0
  56. package/build/esm/editor/containers/Editor/Editor.css +17 -0
  57. package/build/esm/editor/containers/Editor/Editor.d.ts +2 -1
  58. package/build/esm/editor/containers/Editor/Editor.js +18 -66
  59. package/build/esm/editor/containers/Editor/hooks/useCode.d.ts +14 -0
  60. package/build/esm/editor/containers/{Form/hooks.js → Editor/hooks/useCode.js} +4 -14
  61. package/build/esm/editor/containers/Editor/hooks/useEditorState.d.ts +49 -0
  62. package/build/esm/editor/containers/Editor/hooks/useEditorState.js +95 -0
  63. package/build/esm/editor/containers/Form/Form.css +0 -10
  64. package/build/esm/editor/containers/Form/Form.d.ts +1 -8
  65. package/build/esm/editor/containers/Form/Form.js +16 -42
  66. package/build/esm/editor/store/main/index.js +1 -1
  67. package/build/esm/editor/store/settings/index.d.ts +3 -3
  68. package/build/esm/editor/store/settings/index.js +5 -5
  69. package/build/esm/editor/store/settings/reducer.d.ts +9 -9
  70. package/build/esm/editor/store/settings/reducer.js +6 -6
  71. package/build/esm/editor/types/index.d.ts +3 -4
  72. package/build/esm/editor/types/index.js +6 -7
  73. package/package.json +1 -1
  74. package/widget/index.js +1 -1
  75. package/build/cjs/editor/components/PagePropsForm/PagePropsForm.d.ts +0 -10
  76. package/build/cjs/editor/components/PagePropsForm/PagePropsForm.js +0 -17
  77. package/build/cjs/editor/containers/Form/hooks.d.ts +0 -8
  78. package/build/esm/editor/components/PagePropsForm/PagePropsForm.d.ts +0 -10
  79. package/build/esm/editor/components/PagePropsForm/PagePropsForm.js +0 -13
  80. package/build/esm/editor/containers/Form/hooks.d.ts +0 -8
@@ -0,0 +1,26 @@
1
+ /* use this for style redefinitions to awoid problems with
2
+ unpredictable css rules order in build */
3
+ body {
4
+ --pc-editor-header-height: 48px;
5
+ --pc-editor-code-header-height: 36px;
6
+ --pc-editor-divider-width: 12px;
7
+ --pc-editor-left-column-width: calc(400px + var(--pc-editor-divider-width));
8
+ --pc-editor-base-color: var(--g-color-base-brand);
9
+ --pc-editor-control-color: var(--g-color-base-brand);
10
+ --pc-editor-control-icon-color: var(--g-color-text-dark-primary);
11
+ }
12
+
13
+ .pc-editor-page-settings__container {
14
+ display: flex;
15
+ flex-direction: column;
16
+ align-items: center;
17
+ width: 100%;
18
+ padding: 12px;
19
+ border-bottom: 1px solid var(--g-color-line-generic);
20
+ }
21
+ .pc-editor-page-settings__container .g-disclosure__content {
22
+ width: 100%;
23
+ }
24
+ .pc-editor-page-settings__form {
25
+ margin-top: 16px;
26
+ }
@@ -0,0 +1,12 @@
1
+ import { JSONSchema4 } from 'json-schema';
2
+ import { PageContent } from '../../../models';
3
+ import './PageSettings.css';
4
+ export interface PageSettingsProps {
5
+ content: PageContent;
6
+ schema: JSONSchema4;
7
+ onChange: (content: PageContent) => void;
8
+ }
9
+ export declare const PageSettings: {
10
+ ({ schema, content, onChange }: PageSettingsProps): JSX.Element;
11
+ displayName: string;
12
+ };
@@ -0,0 +1,27 @@
1
+ import { __rest } from "tslib";
2
+ import React, { useMemo } from 'react';
3
+ import { DynamicField } from '@gravity-ui/dynamic-forms';
4
+ import { Disclosure } from '@gravity-ui/uikit';
5
+ import noop from 'lodash/noop';
6
+ import { Form as FinalForm, FormSpy } from 'react-final-form';
7
+ import { block } from '../../../utils';
8
+ import { dynamicConfig } from '../../dynamic-forms-custom/config';
9
+ import useFormSpec from '../../hooks/useFormSpec';
10
+ import { i18n } from './i18n';
11
+ import './PageSettings.css';
12
+ const b = block('editor-page-settings');
13
+ export const PageSettings = ({ schema, content, onChange }) => {
14
+ const spec = useFormSpec(schema);
15
+ const { page: pageSpec } = spec || {};
16
+ const initialPage = useMemo(() => {
17
+ const _a = content || {}, { blocks: _ } = _a, page = __rest(_a, ["blocks"]);
18
+ return page;
19
+ // eslint-disable-next-line react-hooks/exhaustive-deps
20
+ }, []);
21
+ return (React.createElement(Disclosure, { className: b('container'), summary: i18n('page-settings-title'), size: "l" },
22
+ React.createElement("div", { className: b('form') },
23
+ React.createElement(FinalForm, { initialValues: { content: initialPage }, onSubmit: noop }, () => (React.createElement("div", null,
24
+ React.createElement(FormSpy, { onChange: ({ values }) => onChange(Object.assign(Object.assign({}, content), values.content)), subscription: { values: true } }),
25
+ React.createElement(DynamicField, { name: "content", spec: pageSpec, config: dynamicConfig })))))));
26
+ };
27
+ PageSettings.displayName = 'PageSettings';
@@ -0,0 +1,3 @@
1
+ {
2
+ "page-settings-title": "Global page settings"
3
+ }
@@ -0,0 +1 @@
1
+ export declare const i18n: (key: "page-settings-title", params?: import("@gravity-ui/i18n").Params | undefined) => string;
@@ -0,0 +1,5 @@
1
+ import { addComponentKeysets } from '@gravity-ui/uikit/i18n';
2
+ import { NAMESPACE } from '../../../../utils/cn';
3
+ import en from './en.json';
4
+ import ru from './ru.json';
5
+ export const i18n = addComponentKeysets({ en, ru }, `${NAMESPACE}PageSettings`);
@@ -0,0 +1,3 @@
1
+ {
2
+ "page-settings-title": "Глобальные настройки страницы"
3
+ }
@@ -0,0 +1,17 @@
1
+ /* use this for style redefinitions to awoid problems with
2
+ unpredictable css rules order in build */
3
+ body {
4
+ --pc-editor-header-height: 48px;
5
+ --pc-editor-code-header-height: 36px;
6
+ --pc-editor-divider-width: 12px;
7
+ --pc-editor-left-column-width: calc(400px + var(--pc-editor-divider-width));
8
+ --pc-editor-base-color: var(--g-color-base-brand);
9
+ --pc-editor-control-color: var(--g-color-base-brand);
10
+ --pc-editor-control-icon-color: var(--g-color-text-dark-primary);
11
+ }
12
+
13
+ .pc-editor__panel {
14
+ top: 0;
15
+ position: sticky;
16
+ z-index: 2;
17
+ }
@@ -1,2 +1,3 @@
1
1
  import { EditorProps } from '../../types';
2
- export declare const Editor: ({ customSchema, onChange, providerProps, transformContent, deviceEmulationSettings, theme: editorTheme, ...rest }: EditorProps) => JSX.Element;
2
+ import './Editor.css';
3
+ export declare const Editor: (props: EditorProps) => JSX.Element;
@@ -1,78 +1,30 @@
1
- import { __rest } from "tslib";
2
- import React, { useEffect, useMemo } from 'react';
1
+ import React from 'react';
3
2
  import { PageConstructor, PageConstructorProvider } from '../../../containers/PageConstructor';
4
- import { generateDefaultSchema } from '../../../schema';
3
+ import { block } from '../../../utils';
5
4
  import AddBlock from '../../components/AddBlock/AddBlock';
6
- import EditBlock from '../../components/EditBlock/EditBlock';
5
+ import { CodeEditor } from '../../components/CodeEditor/CodeEditor';
6
+ import ControlPanel from '../../components/ControlPanel/ControlPanel';
7
7
  import { ErrorBoundary } from '../../components/ErrorBoundary/ErrorBoundary';
8
8
  import Layout from '../../components/Layout/Layout';
9
- import { NotFoundBlock } from '../../components/NotFoundBlock/NotFoundBlock';
9
+ import { PageSettings } from '../../components/PageSettings/PageSettings';
10
10
  import { EditorContext } from '../../context';
11
- import { useCodeValidator } from '../../hooks/useCodeValidator';
12
- import { useMainState } from '../../store/main';
13
- import { useSettingsState } from '../../store/settings';
14
- import { ViewModeItem } from '../../types';
15
- import { FormTab } from '../../types/index';
16
- import { addCustomDecorator, checkIsMobile, getBlockId } from '../../utils';
17
11
  import { Form } from '../Form/Form';
18
- export const Editor = (_a) => {
19
- var { customSchema, onChange, providerProps, transformContent, deviceEmulationSettings, theme: editorTheme } = _a, rest = __rest(_a, ["customSchema", "onChange", "providerProps", "transformContent", "deviceEmulationSettings", "theme"]);
20
- const { content, activeBlockIndex, errorBoundaryState, onContentUpdate, onAdd, onSelect, injectEditBlockProps, } = useMainState(rest);
21
- const { viewMode, theme: constructorTheme, onViewModeUpdate, onThemeUpdate, formTab, onFormTabUpdate, codeFullscreeModeOn, onCodeFullscreeModeOnUpdate, } = useSettingsState();
22
- const isEditingMode = viewMode === ViewModeItem.Edititng;
23
- const isCodeOnlyMode = codeFullscreeModeOn && formTab === FormTab.Code && viewMode === ViewModeItem.Edititng;
24
- const transformedContent = useMemo(() => (transformContent ? transformContent(content, { viewMode }) : content), [content, transformContent, viewMode]);
25
- const schema = useMemo(() => generateDefaultSchema(customSchema), [customSchema]);
26
- const codeValidator = useCodeValidator(schema);
27
- const outgoingProps = useMemo(() => {
28
- const custom = isEditingMode
29
- ? addCustomDecorator([
30
- (props) => React.createElement(NotFoundBlock, Object.assign({}, props)),
31
- (props) => (React.createElement(EditBlock, Object.assign({}, injectEditBlockProps(props)))),
32
- // need errorBoundaryState flag to reset error on content update
33
- (props) => (React.createElement(ErrorBoundary, Object.assign({}, props, { key: `${getBlockId(props)}-${errorBoundaryState}` }))),
34
- ], rest.custom)
35
- : rest.custom;
36
- return {
37
- content: transformedContent,
38
- custom,
39
- viewMode,
40
- };
41
- }, [
42
- injectEditBlockProps,
43
- errorBoundaryState,
44
- isEditingMode,
45
- viewMode,
46
- transformedContent,
47
- rest.custom,
48
- ]);
49
- const context = useMemo(() => ({
50
- constructorProps: {
51
- content: transformedContent,
52
- custom: rest.custom,
53
- },
54
- providerProps: Object.assign(Object.assign({}, providerProps), { isMobile: checkIsMobile(viewMode), theme: constructorTheme }),
55
- deviceEmulationSettings,
56
- theme: editorTheme,
57
- }), [
58
- providerProps,
59
- rest.custom,
60
- viewMode,
61
- transformedContent,
62
- deviceEmulationSettings,
63
- constructorTheme,
64
- editorTheme,
65
- ]);
66
- useEffect(() => {
67
- onChange === null || onChange === void 0 ? void 0 : onChange(content);
68
- }, [content, onChange]);
12
+ import { useEditorState } from './hooks/useEditorState';
13
+ import './Editor.css';
14
+ const b = block('editor');
15
+ export const Editor = (props) => {
16
+ const { providerProps } = props;
17
+ const { context, viewMode, editMode, constructorTheme, onThemeUpdate, onViewModeUpdate, onEditModeUpdate, isCodeEditMode, isFormEditMode, isDesktopViewMode, content, schema, onContentUpdate, code, codeValidator, codeFullscreeModeOn, onCodeFullscreeModeOnUpdate, activeBlockIndex, onSelect, isCodeOnlyMode, errorBoundaryState, outgoingProps, onAdd, } = useEditorState(props);
69
18
  return (React.createElement(EditorContext.Provider, { value: context },
70
- React.createElement(Layout, { mode: viewMode, onModeChange: onViewModeUpdate, theme: constructorTheme, onThemeChange: onThemeUpdate },
71
- isEditingMode && (React.createElement(Layout.Left, null,
72
- React.createElement(Form, { content: content, onChange: onContentUpdate, activeBlockIndex: activeBlockIndex, activeTab: formTab, codeFullscreeModeOn: codeFullscreeModeOn, schema: schema, codeValidator: codeValidator, onActiveTabUpdate: onFormTabUpdate, onCodeFullscreeModeOnUpdate: onCodeFullscreeModeOnUpdate, onSelect: onSelect }))),
19
+ React.createElement(ControlPanel, { viewMode: viewMode, onViewModeChange: onViewModeUpdate, editMode: editMode, onEditModeChange: onEditModeUpdate, theme: constructorTheme, className: b('panel'), onThemeChange: onThemeUpdate }),
20
+ isFormEditMode && isDesktopViewMode && (React.createElement(PageSettings, { content: content, schema: schema, onChange: onContentUpdate })),
21
+ isCodeEditMode && (React.createElement(CodeEditor, { code: code, onChange: onContentUpdate, validator: codeValidator, fullscreenModeOn: codeFullscreeModeOn, onFullscreenModeOnUpdate: onCodeFullscreeModeOnUpdate })),
22
+ React.createElement(Layout, { editMode: editMode, viewMode: viewMode },
23
+ isFormEditMode && isDesktopViewMode && (React.createElement(Layout.Left, null,
24
+ React.createElement(Form, { content: content, onChange: onContentUpdate, activeBlockIndex: activeBlockIndex, schema: schema, onSelect: onSelect }))),
73
25
  !isCodeOnlyMode && (React.createElement(Layout.Right, null,
74
26
  React.createElement(ErrorBoundary, { key: errorBoundaryState },
75
27
  React.createElement(PageConstructorProvider, Object.assign({}, providerProps, { theme: constructorTheme }),
76
28
  React.createElement(PageConstructor, Object.assign({}, outgoingProps)))),
77
- isEditingMode && React.createElement(AddBlock, { onAdd: onAdd }))))));
29
+ isFormEditMode && React.createElement(AddBlock, { onAdd: onAdd }))))));
78
30
  };
@@ -0,0 +1,14 @@
1
+ import { PageContent } from '../../../../models';
2
+ type UseCodeProps = {
3
+ content: PageContent;
4
+ codeFullscreeModeOn: boolean;
5
+ isCodeEditMode: boolean;
6
+ };
7
+ /**
8
+ * Transorms PageConstructor content in JSON to YAML on code editor mode switching
9
+ *
10
+ * @param {Object} props - props parent from form
11
+ * @returns {string} - updated code
12
+ */
13
+ export declare function useCode({ content, codeFullscreeModeOn, isCodeEditMode }: UseCodeProps): string;
14
+ export {};
@@ -1,34 +1,24 @@
1
1
  import { useEffect, useState } from 'react';
2
2
  import yaml from 'js-yaml';
3
- import usePreviousValue from '../../hooks/usePreviousValue';
4
- import { FormTab } from '../../types';
3
+ import usePreviousValue from '../../../hooks/usePreviousValue';
5
4
  /**
6
5
  * Transorms PageConstructor content in JSON to YAML on code editor mode switching
7
6
  *
8
7
  * @param {Object} props - props parent from form
9
8
  * @returns {string} - updated code
10
9
  */
11
- export function useCode({ activeTab, content, codeFullscreeModeOn, }) {
10
+ export function useCode({ content, codeFullscreeModeOn, isCodeEditMode }) {
12
11
  var _a;
13
12
  const [code, setCode] = useState('');
14
- const prevTab = usePreviousValue(activeTab);
15
13
  const prevContentLength = usePreviousValue((_a = content.blocks) === null || _a === void 0 ? void 0 : _a.length);
16
14
  const prevCodeFullscreeModeOn = usePreviousValue(codeFullscreeModeOn);
17
15
  useEffect(() => {
18
16
  var _a;
19
- const switchedToCodeEditing = activeTab !== prevTab && activeTab === FormTab.Code;
20
17
  const blocksCountChanged = prevContentLength !== ((_a = content.blocks) === null || _a === void 0 ? void 0 : _a.length);
21
18
  const codeModeSwitched = codeFullscreeModeOn !== prevCodeFullscreeModeOn;
22
- if (blocksCountChanged || switchedToCodeEditing || codeModeSwitched) {
19
+ if (blocksCountChanged || isCodeEditMode || codeModeSwitched) {
23
20
  setCode(yaml.dump(content, { lineWidth: -1 }));
24
21
  }
25
- }, [
26
- activeTab,
27
- prevTab,
28
- content,
29
- prevContentLength,
30
- codeFullscreeModeOn,
31
- prevCodeFullscreeModeOn,
32
- ]);
22
+ }, [isCodeEditMode, content, prevContentLength, codeFullscreeModeOn, prevCodeFullscreeModeOn]);
33
23
  return code;
34
24
  }
@@ -0,0 +1,49 @@
1
+ import { EditModeItem, EditorProps, ViewModeItem } from '../../../types';
2
+ export declare const useEditorState: ({ customSchema, onChange, providerProps, transformContent, deviceEmulationSettings, theme: editorTheme, ...rest }: EditorProps) => {
3
+ context: {
4
+ constructorProps: {
5
+ content: import("../../../../models").PageContent;
6
+ custom: import("../../../../models").CustomConfig | undefined;
7
+ };
8
+ providerProps: {
9
+ isMobile: boolean;
10
+ theme: import("../../../../models").Theme;
11
+ locale?: import("../../../../context/localeContext").LocaleContextProps | undefined;
12
+ location?: import("../../../../context/locationContext").LocationContextProps | undefined;
13
+ ssrConfig?: import("../../../../context/ssrContext").SSRContextProps | undefined;
14
+ mapsContext?: import("../../../../context/mapsContext/mapsContext").MapsContextType | undefined;
15
+ projectSettings?: import("../../../../context/projectSettingsContext").ProjectSettingsContextProps | undefined;
16
+ analytics?: import("../../../..").AnalyticsContextProps | undefined;
17
+ forms?: import("../../../../context/formsContext").FormsContextProps | undefined;
18
+ image?: import("../../../../context/imageContext").ImageContextProps | undefined;
19
+ };
20
+ deviceEmulationSettings: import("../../../types").DeviceEmulationSettings | undefined;
21
+ theme: import("../../../../models").Theme | undefined;
22
+ };
23
+ viewMode: ViewModeItem;
24
+ editMode: EditModeItem;
25
+ constructorTheme: import("../../../../models").Theme;
26
+ onThemeUpdate: (newTheme: import("../../../../models").Theme) => void;
27
+ onViewModeUpdate: (newViewMode: ViewModeItem) => void;
28
+ onEditModeUpdate: (newEditMode: EditModeItem) => void;
29
+ isCodeEditMode: boolean;
30
+ isDesktopViewMode: boolean;
31
+ content: import("../../../../models").PageContent;
32
+ schema: import("json-schema").JSONSchema4;
33
+ onContentUpdate: (newContent: import("../../../../models").PageContent) => void;
34
+ code: string;
35
+ codeValidator: import("../../../hooks/useCodeValidator").CodeValidator;
36
+ codeFullscreeModeOn: boolean;
37
+ onCodeFullscreeModeOnUpdate: (newCodeFullscreeModeOn: boolean) => void;
38
+ activeBlockIndex: number;
39
+ onSelect: (index: number) => void;
40
+ isCodeOnlyMode: boolean;
41
+ errorBoundaryState: number;
42
+ outgoingProps: {
43
+ content: import("../../../../models").PageContent;
44
+ custom: import("../../../../models").CustomConfig | undefined;
45
+ viewMode: ViewModeItem;
46
+ };
47
+ onAdd: (block: import("../../../../models").Block) => void;
48
+ isFormEditMode: boolean;
49
+ };
@@ -0,0 +1,95 @@
1
+ import { __rest } from "tslib";
2
+ import React, { useEffect, useMemo } from 'react';
3
+ import { generateDefaultSchema } from '../../../../schema';
4
+ import EditBlock from '../../../components/EditBlock/EditBlock';
5
+ import { ErrorBoundary } from '../../../components/ErrorBoundary/ErrorBoundary';
6
+ import { NotFoundBlock } from '../../../components/NotFoundBlock/NotFoundBlock';
7
+ import { useCodeValidator } from '../../../hooks/useCodeValidator';
8
+ import { useMainState } from '../../../store/main';
9
+ import { useSettingsState } from '../../../store/settings';
10
+ import { EditModeItem, ViewModeItem } from '../../../types';
11
+ import { addCustomDecorator, checkIsMobile, getBlockId } from '../../../utils';
12
+ import { useCode } from './useCode';
13
+ // Editor business logic
14
+ export const useEditorState = (_a) => {
15
+ var { customSchema, onChange, providerProps, transformContent, deviceEmulationSettings, theme: editorTheme } = _a, rest = __rest(_a, ["customSchema", "onChange", "providerProps", "transformContent", "deviceEmulationSettings", "theme"]);
16
+ const { content, activeBlockIndex, errorBoundaryState, onContentUpdate, onAdd, onSelect, injectEditBlockProps, } = useMainState(rest);
17
+ const { viewMode, editMode, onEditModeUpdate, theme: constructorTheme, onViewModeUpdate, onThemeUpdate, codeFullscreeModeOn, onCodeFullscreeModeOnUpdate, } = useSettingsState();
18
+ const isCodeEditMode = editMode === EditModeItem.Code;
19
+ const isViewEditMode = editMode === EditModeItem.View;
20
+ const isFormEditMode = editMode === EditModeItem.Form;
21
+ const isDesktopViewMode = viewMode === ViewModeItem.Desktop;
22
+ const isCodeOnlyMode = codeFullscreeModeOn && isCodeEditMode;
23
+ const transformedContent = useMemo(() => (transformContent ? transformContent(content, { viewMode }) : content), [content, transformContent, viewMode]);
24
+ const schema = useMemo(() => generateDefaultSchema(customSchema), [customSchema]);
25
+ const codeValidator = useCodeValidator(schema);
26
+ const outgoingProps = useMemo(() => {
27
+ const custom = isCodeEditMode || isViewEditMode
28
+ ? rest.custom
29
+ : addCustomDecorator([
30
+ (props) => React.createElement(NotFoundBlock, Object.assign({}, props)),
31
+ (props) => (React.createElement(EditBlock, Object.assign({}, injectEditBlockProps(props)))),
32
+ // need errorBoundaryState flag to reset error on content update
33
+ (props) => (React.createElement(ErrorBoundary, Object.assign({}, props, { key: `${getBlockId(props)}-${errorBoundaryState}` }))),
34
+ ], rest.custom);
35
+ return {
36
+ content: transformedContent,
37
+ custom,
38
+ viewMode,
39
+ };
40
+ }, [
41
+ injectEditBlockProps,
42
+ errorBoundaryState,
43
+ viewMode,
44
+ transformedContent,
45
+ rest.custom,
46
+ isCodeEditMode,
47
+ isViewEditMode,
48
+ ]);
49
+ const context = useMemo(() => ({
50
+ constructorProps: {
51
+ content: transformedContent,
52
+ custom: rest.custom,
53
+ },
54
+ providerProps: Object.assign(Object.assign({}, providerProps), { isMobile: checkIsMobile(viewMode), theme: constructorTheme }),
55
+ deviceEmulationSettings,
56
+ theme: editorTheme,
57
+ }), [
58
+ providerProps,
59
+ rest.custom,
60
+ viewMode,
61
+ transformedContent,
62
+ deviceEmulationSettings,
63
+ constructorTheme,
64
+ editorTheme,
65
+ ]);
66
+ useEffect(() => {
67
+ onChange === null || onChange === void 0 ? void 0 : onChange(content);
68
+ }, [content, onChange]);
69
+ const code = useCode({ isCodeEditMode, content, codeFullscreeModeOn });
70
+ return {
71
+ context,
72
+ viewMode,
73
+ editMode,
74
+ constructorTheme,
75
+ onThemeUpdate,
76
+ onViewModeUpdate,
77
+ onEditModeUpdate,
78
+ isCodeEditMode,
79
+ isDesktopViewMode,
80
+ content,
81
+ schema,
82
+ onContentUpdate,
83
+ code,
84
+ codeValidator,
85
+ codeFullscreeModeOn,
86
+ onCodeFullscreeModeOnUpdate,
87
+ activeBlockIndex,
88
+ onSelect,
89
+ isCodeOnlyMode,
90
+ errorBoundaryState,
91
+ outgoingProps,
92
+ onAdd,
93
+ isFormEditMode,
94
+ };
95
+ };
@@ -82,16 +82,6 @@ unpredictable css rules order in build */
82
82
  .pc-editor-form + .pc-editor-form {
83
83
  margin-top: 12px;
84
84
  }
85
- .pc-editor-form__tabs {
86
- --g-color-base-brand: var(--pc-color-base-neon);
87
- margin-bottom: 20px;
88
- }
89
85
  .pc-editor-form__block-form {
90
86
  margin-bottom: 16px;
91
- }
92
- .pc-editor-form_code-editor-active {
93
- height: calc(100% - var(--pc-editor-code-header-height));
94
- }
95
- .pc-editor-form_code-editor-active .pc-editor-form__tabs {
96
- margin-bottom: 0;
97
87
  }
@@ -1,19 +1,12 @@
1
1
  import React from 'react';
2
2
  import { JSONSchema4 } from 'json-schema';
3
3
  import { PageContent } from '../../../models';
4
- import { FormTab } from '../../types';
5
- import { CodeEditorMessageProps } from '../../utils/validation';
6
4
  import './Form.css';
7
5
  export interface FormProps {
8
6
  content: PageContent;
9
7
  schema: JSONSchema4;
10
8
  activeBlockIndex: number;
11
- activeTab: FormTab;
12
- codeFullscreeModeOn: boolean;
13
- onActiveTabUpdate: (tab: FormTab) => void;
14
- onCodeFullscreeModeOnUpdate: (codeFullscreeModeOn: boolean) => void;
15
- codeValidator: (code: string) => CodeEditorMessageProps;
16
9
  onChange: (content: PageContent) => void;
17
10
  onSelect: (index: number) => void;
18
11
  }
19
- export declare const Form: React.MemoExoticComponent<({ content, onChange, activeBlockIndex, onSelect, schema, codeValidator, activeTab, onActiveTabUpdate, codeFullscreeModeOn, onCodeFullscreeModeOnUpdate, }: FormProps) => JSX.Element>;
12
+ export declare const Form: React.MemoExoticComponent<({ content, onChange, activeBlockIndex, onSelect, schema }: FormProps) => JSX.Element>;
@@ -1,50 +1,24 @@
1
- import { __rest } from "tslib";
2
- import React, { Fragment, memo } from 'react';
3
- import { Tabs } from '@gravity-ui/uikit';
1
+ import React, { memo } from 'react';
2
+ import { Text } from '@gravity-ui/uikit';
4
3
  import { block, getBlockKey } from '../../../utils';
5
4
  import { BlockForm } from '../../components/BlockForm/BlockForm';
6
- import { CodeEditor } from '../../components/CodeEditor/CodeEditor';
7
- import { PagePropsForm } from '../../components/PagePropsForm/PagePropsForm';
8
5
  import useFormSpec from '../../hooks/useFormSpec';
9
- import { FormTab } from '../../types';
10
- import { useCode } from './hooks';
11
6
  import './Form.css';
12
7
  const b = block('editor-form');
13
- const tabsItems = Object.values(FormTab).map((tab) => ({
14
- id: tab,
15
- title: tab,
16
- }));
17
- export const Form = memo(({ content, onChange, activeBlockIndex, onSelect, schema, codeValidator, activeTab, onActiveTabUpdate, codeFullscreeModeOn, onCodeFullscreeModeOnUpdate, }) => {
18
- const _a = content || {}, { blocks } = _a, page = __rest(_a, ["blocks"]);
19
- const code = useCode({ activeTab, content, codeFullscreeModeOn });
8
+ // TODO in https://github.com/gravity-ui/page-constructor/issues/884 this component will be extremely refactor
9
+ export const Form = memo(({ content, onChange, activeBlockIndex, onSelect, schema }) => {
10
+ const { blocks } = content || {};
20
11
  const spec = useFormSpec(schema);
21
- const { blocks: blocksSpec, page: pageSpec } = spec || {};
22
- let form;
23
- switch (activeTab) {
24
- case FormTab.Page: {
25
- form = (React.createElement(PagePropsForm, { spec: pageSpec, data: page, onChange: (data) => {
26
- return onChange(Object.assign(Object.assign({}, content), data));
27
- } }));
28
- break;
29
- }
30
- case FormTab.Blocks: {
31
- form = (React.createElement(Fragment, null, blocks.map((blockData, index) => blocksSpec[blockData.type] ? (React.createElement("div", { className: b('block-form'), key: getBlockKey(blockData, index) },
32
- React.createElement(BlockForm, { spec: blocksSpec[blockData.type], data: blockData, active: activeBlockIndex === index, onChange: (data) => {
33
- onChange(Object.assign(Object.assign({}, content), { blocks: [
34
- ...blocks.slice(0, index),
35
- data,
36
- ...blocks.slice(index + 1),
37
- ] }));
38
- }, onSelect: () => onSelect(index) }))) : null)));
39
- break;
40
- }
41
- case FormTab.Code: {
42
- form = (React.createElement(CodeEditor, { code: code, onChange: onChange, validator: codeValidator, fullscreenModeOn: codeFullscreeModeOn, onFullscreenModeOnUpdate: onCodeFullscreeModeOnUpdate }));
43
- break;
44
- }
45
- }
46
- return (React.createElement("div", { className: b({ 'code-editor-active': activeTab === FormTab.Code }) },
47
- React.createElement(Tabs, { activeTab: activeTab, className: b('tabs'), items: tabsItems, onSelectTab: onActiveTabUpdate }),
48
- form));
12
+ const { blocks: blocksSpec } = spec || {};
13
+ return (React.createElement("div", { className: b() },
14
+ React.createElement(Text, { variant: "body-2" }, 'Blocks'),
15
+ blocks.map((blockData, index) => blocksSpec[blockData.type] ? (React.createElement("div", { className: b('block-form'), key: getBlockKey(blockData, index) },
16
+ React.createElement(BlockForm, { spec: blocksSpec[blockData.type], data: blockData, active: activeBlockIndex === index, onChange: (data) => {
17
+ onChange(Object.assign(Object.assign({}, content), { blocks: [
18
+ ...blocks.slice(0, index),
19
+ data,
20
+ ...blocks.slice(index + 1),
21
+ ] }));
22
+ }, onSelect: () => onSelect(index) }))) : null)));
49
23
  });
50
24
  Form.displayName = 'Form';
@@ -12,7 +12,7 @@ export function useMainState({ content: intialContent, custom }) {
12
12
  activeBlockIndex: 0,
13
13
  errorBoundaryState: 0,
14
14
  content: addEditorProps(intialContent),
15
- viewMode: ViewModeItem.Edititng,
15
+ viewMode: ViewModeItem.Desktop,
16
16
  theme: DEFAULT_THEME,
17
17
  });
18
18
  return useMemo(() => {
@@ -1,12 +1,12 @@
1
1
  import { Theme } from '../../../models';
2
- import { FormTab, ViewModeItem } from '../../types';
2
+ import { EditModeItem, ViewModeItem } from '../../types';
3
3
  export declare function useSettingsState(): {
4
- formTab: FormTab;
5
4
  viewMode: ViewModeItem;
5
+ editMode: EditModeItem;
6
6
  theme: Theme;
7
7
  codeFullscreeModeOn: boolean;
8
- onFormTabUpdate: (newFormTab: FormTab) => void;
9
8
  onViewModeUpdate: (newViewMode: ViewModeItem) => void;
9
+ onEditModeUpdate: (newEditMode: EditModeItem) => void;
10
10
  onThemeUpdate: (newTheme: Theme) => void;
11
11
  onCodeFullscreeModeOnUpdate: (newCodeFullscreeModeOn: boolean) => void;
12
12
  };
@@ -1,17 +1,17 @@
1
1
  import { useMemo, useReducer } from 'react';
2
- import { UPDATE_CODE_FULLSCREEN_MODE_ON, UPDATE_FORM_TAB, UPDATE_THEME, UPDATE_VIEW_MODE, initialState, reducer, } from './reducer';
2
+ import { UPDATE_CODE_FULLSCREEN_MODE_ON, UPDATE_EDIT_MODE, UPDATE_THEME, UPDATE_VIEW_MODE, initialState, reducer, } from './reducer';
3
3
  export function useSettingsState() {
4
- const [{ formTab, viewMode, theme, codeFullscreeModeOn }, dispatch] = useReducer(reducer, initialState);
4
+ const [{ viewMode, editMode, theme, codeFullscreeModeOn }, dispatch] = useReducer(reducer, initialState);
5
5
  return useMemo(() => {
6
6
  return {
7
- formTab,
8
7
  viewMode,
8
+ editMode,
9
9
  theme,
10
10
  codeFullscreeModeOn,
11
- onFormTabUpdate: (newFormTab) => dispatch({ type: UPDATE_FORM_TAB, payload: newFormTab }),
12
11
  onViewModeUpdate: (newViewMode) => dispatch({ type: UPDATE_VIEW_MODE, payload: newViewMode }),
12
+ onEditModeUpdate: (newEditMode) => dispatch({ type: UPDATE_EDIT_MODE, payload: newEditMode }),
13
13
  onThemeUpdate: (newTheme) => dispatch({ type: UPDATE_THEME, payload: newTheme }),
14
14
  onCodeFullscreeModeOnUpdate: (newCodeFullscreeModeOn) => dispatch({ type: UPDATE_CODE_FULLSCREEN_MODE_ON, payload: newCodeFullscreeModeOn }),
15
15
  };
16
- }, [formTab, viewMode, theme, codeFullscreeModeOn]);
16
+ }, [viewMode, theme, codeFullscreeModeOn, editMode]);
17
17
  }
@@ -1,19 +1,23 @@
1
1
  import { Theme } from '../../../models';
2
- import { FormTab, ViewModeItem } from '../../types';
3
- export declare const UPDATE_FORM_TAB = "UPDATE_FORM_TAB";
2
+ import { EditModeItem, ViewModeItem } from '../../types';
4
3
  export declare const UPDATE_CODE_FULLSCREEN_MODE_ON = "UPDATE_CODE_FULLSCREEN_MODE_ON";
5
4
  export declare const UPDATE_VIEW_MODE = "UPDATE_VIEW_MODE";
5
+ export declare const UPDATE_EDIT_MODE = "UPDATE_EDIT_MODE";
6
6
  export declare const UPDATE_THEME = "UPDATE_THEME";
7
7
  interface EditorSettingsState {
8
8
  theme: Theme;
9
9
  viewMode: ViewModeItem;
10
+ editMode: EditModeItem;
10
11
  codeFullscreeModeOn: boolean;
11
- formTab: FormTab;
12
12
  }
13
13
  interface UpdateViewMode {
14
14
  type: typeof UPDATE_VIEW_MODE;
15
15
  payload: ViewModeItem;
16
16
  }
17
+ interface UpdateEditMode {
18
+ type: typeof UPDATE_EDIT_MODE;
19
+ payload: EditModeItem;
20
+ }
17
21
  interface UpdateTheme {
18
22
  type: typeof UPDATE_THEME;
19
23
  payload: Theme;
@@ -22,16 +26,12 @@ interface UpdateCodeFullscreenModeOn {
22
26
  type: typeof UPDATE_CODE_FULLSCREEN_MODE_ON;
23
27
  payload: boolean;
24
28
  }
25
- interface UpdateFormTab {
26
- type: typeof UPDATE_FORM_TAB;
27
- payload: FormTab;
28
- }
29
- export type EditorSettingsAction = UpdateViewMode | UpdateTheme | UpdateCodeFullscreenModeOn | UpdateFormTab;
29
+ export type EditorSettingsAction = UpdateViewMode | UpdateEditMode | UpdateTheme | UpdateCodeFullscreenModeOn;
30
30
  export declare const reducer: (state: EditorSettingsState, action: EditorSettingsAction) => EditorSettingsState;
31
31
  export declare const initialState: {
32
32
  viewMode: ViewModeItem;
33
+ editMode: EditModeItem;
33
34
  theme: Theme;
34
35
  codeFullscreeModeOn: boolean;
35
- formTab: FormTab;
36
36
  };
37
37
  export {};