@webiny/app-website-builder 6.6.0-alpha.0 → 6.6.0-alpha.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/BaseEditor/commandHandlers/CloneElement.d.ts +1 -0
- package/BaseEditor/commandHandlers/CloneElement.js +17 -0
- package/BaseEditor/commandHandlers/CloneElement.js.map +1 -0
- package/BaseEditor/commandHandlers/index.js +2 -1
- package/BaseEditor/commandHandlers/index.js.map +1 -1
- package/BaseEditor/commands.d.ts +3 -0
- package/BaseEditor/commands.js +2 -0
- package/BaseEditor/commands.js.map +1 -1
- package/BaseEditor/defaultConfig/Content/AddressBar/usePreviewLink.js +4 -1
- package/BaseEditor/defaultConfig/Content/AddressBar/usePreviewLink.js.map +1 -1
- package/BaseEditor/defaultConfig/Content/Preview/DropZoneManager.js.map +1 -1
- package/BaseEditor/defaultConfig/Content/Preview/Iframe.d.ts +2 -2
- package/BaseEditor/defaultConfig/Content/Preview/Overlays/ElementOverlays.d.ts +2 -2
- package/BaseEditor/defaultConfig/DefaultEditorConfig.js +9 -0
- package/BaseEditor/defaultConfig/DefaultEditorConfig.js.map +1 -1
- package/BaseEditor/defaultConfig/DocumentStateEditor/DocumentStateEditor.d.ts +2 -2
- package/BaseEditor/defaultConfig/ElementInputRenderers.js +4 -0
- package/BaseEditor/defaultConfig/ElementInputRenderers.js.map +1 -1
- package/BaseEditor/defaultConfig/Sidebar/ElementActions/CloneElementAction.d.ts +2 -0
- package/BaseEditor/defaultConfig/Sidebar/ElementActions/CloneElementAction.js +25 -0
- package/BaseEditor/defaultConfig/Sidebar/ElementActions/CloneElementAction.js.map +1 -0
- package/BaseEditor/defaultConfig/Sidebar/ElementActions/DeleteElementAction.d.ts +2 -0
- package/BaseEditor/defaultConfig/Sidebar/ElementActions/DeleteElementAction.js +26 -0
- package/BaseEditor/defaultConfig/Sidebar/ElementActions/DeleteElementAction.js.map +1 -0
- package/BaseEditor/defaultConfig/Sidebar/ElementPreview.js +12 -2
- package/BaseEditor/defaultConfig/Sidebar/ElementPreview.js.map +1 -1
- package/BaseEditor/defaultConfig/Sidebar/ElementSettings/ElementInputs.js +1 -6
- package/BaseEditor/defaultConfig/Sidebar/ElementSettings/ElementInputs.js.map +1 -1
- package/BaseEditor/defaultConfig/Sidebar/ElementSettings/ElementSettings.js +11 -2
- package/BaseEditor/defaultConfig/Sidebar/ElementSettings/ElementSettings.js.map +1 -1
- package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Background/BackgroundColor.d.ts +6 -2
- package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Background/BackgroundImage.d.ts +6 -2
- package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Background/BackgroundPosition.d.ts +6 -2
- package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Background/BackgroundScaling.d.ts +6 -2
- package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Border/BorderColor.d.ts +2 -2
- package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Border/BorderRadius.d.ts +2 -2
- package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Border/BorderStyle.d.ts +2 -2
- package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Border/BorderWidth.d.ts +2 -2
- package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Layout/Alignment.d.ts +6 -2
- package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Layout/LengthWithUnitInput.d.ts +2 -2
- package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/MarginPadding/Margin.d.ts +2 -2
- package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/MarginPadding/Padding.d.ts +2 -2
- package/BaseEditor/defaultConfig/Sidebar/StyleSettings/Groups/Visibility/Visibility.d.ts +2 -2
- package/BaseEditor/defaultConfig/Sidebar/StyleSettings/StyleProperties.js +7 -7
- package/BaseEditor/defaultConfig/Sidebar/StyleSettings/StyleProperties.js.map +1 -1
- package/BaseEditor/defaultConfig/Toolbar/Navigator/Navigator.d.ts +2 -2
- package/DocumentEditor/DocumentEditor.d.ts +14 -5
- package/DocumentEditor/DocumentEditor.js +10 -6
- package/DocumentEditor/DocumentEditor.js.map +1 -1
- package/DocumentEditor/StateInspector.d.ts +4 -2
- package/Extension.js +7 -1
- package/Extension.js.map +1 -1
- package/ecommerce/components/ResourcePage.d.ts +6 -2
- package/ecommerce/components/ResourcesList.d.ts +4 -4
- package/ecommerce/components/ResourcesPicker.d.ts +9 -4
- package/editorSdk/CommandBus.js.map +1 -1
- package/editorSdk/utils/$cloneElement.d.ts +2 -0
- package/editorSdk/utils/$cloneElement.js +112 -0
- package/editorSdk/utils/$cloneElement.js.map +1 -0
- package/editorSdk/utils/index.d.ts +1 -0
- package/editorSdk/utils/index.js +1 -0
- package/features/experiments/ExperimentsGateway.d.ts +30 -0
- package/features/experiments/ExperimentsGateway.js +326 -0
- package/features/experiments/ExperimentsGateway.js.map +1 -0
- package/features/experiments/abstractions.d.ts +25 -0
- package/features/experiments/abstractions.js +5 -0
- package/features/experiments/abstractions.js.map +1 -0
- package/features/experiments/feature.d.ts +3 -0
- package/features/experiments/feature.js +17 -0
- package/features/experiments/feature.js.map +1 -0
- package/features/experiments/index.d.ts +3 -0
- package/features/experiments/index.js +2 -0
- package/features/experiments/types.d.ts +61 -0
- package/features/experiments/types.js +0 -0
- package/inputRenderers/ColorPickerInput.d.ts +3 -0
- package/inputRenderers/ColorPickerInput.js +29 -0
- package/inputRenderers/ColorPickerInput.js.map +1 -0
- package/inputRenderers/FileInput.js +93 -8
- package/inputRenderers/FileInput.js.map +1 -1
- package/inputRenderers/LexicalInput/LexicalEditor.js +15 -8
- package/inputRenderers/LexicalInput/LexicalEditor.js.map +1 -1
- package/inputRenderers/LexicalInput/TypographyDropDown.js +3 -2
- package/inputRenderers/LexicalInput/TypographyDropDown.js.map +1 -1
- package/inputRenderers/LexicalInput/wbStaticToolbar.css +72 -103
- package/modules/AbTesting.d.ts +2 -0
- package/modules/AbTesting.js +19 -0
- package/modules/AbTesting.js.map +1 -0
- package/package.json +28 -28
- package/presentation/components/LanguageCodeTag.js +5 -4
- package/presentation/components/LanguageCodeTag.js.map +1 -1
- package/presentation/experiments/ExperimentForm/ExperimentFormPresenter.d.ts +30 -0
- package/presentation/experiments/ExperimentForm/ExperimentFormPresenter.js +202 -0
- package/presentation/experiments/ExperimentForm/ExperimentFormPresenter.js.map +1 -0
- package/presentation/experiments/ExperimentForm/abstractions/ExperimentFormPresenter.d.ts +65 -0
- package/presentation/experiments/ExperimentForm/abstractions/ExperimentFormPresenter.js +5 -0
- package/presentation/experiments/ExperimentForm/abstractions/ExperimentFormPresenter.js.map +1 -0
- package/presentation/experiments/ExperimentForm/components/ExperimentFormView.d.ts +12 -0
- package/presentation/experiments/ExperimentForm/components/ExperimentFormView.js +149 -0
- package/presentation/experiments/ExperimentForm/components/ExperimentFormView.js.map +1 -0
- package/presentation/experiments/ExperimentForm/components/VariantSplitRow.d.ts +17 -0
- package/presentation/experiments/ExperimentForm/components/VariantSplitRow.js +122 -0
- package/presentation/experiments/ExperimentForm/components/VariantSplitRow.js.map +1 -0
- package/presentation/experiments/ExperimentForm/feature.d.ts +3 -0
- package/presentation/experiments/ExperimentForm/feature.js +17 -0
- package/presentation/experiments/ExperimentForm/feature.js.map +1 -0
- package/presentation/experiments/ExperimentForm/index.d.ts +3 -0
- package/presentation/experiments/ExperimentForm/index.js +3 -0
- package/presentation/experiments/ExperimentsEditor/ExperimentsEditorDataSource.d.ts +18 -0
- package/presentation/experiments/ExperimentsEditor/ExperimentsEditorDataSource.js +25 -0
- package/presentation/experiments/ExperimentsEditor/ExperimentsEditorDataSource.js.map +1 -0
- package/presentation/experiments/ExperimentsEditor/ExperimentsEditorPresenter.d.ts +67 -0
- package/presentation/experiments/ExperimentsEditor/ExperimentsEditorPresenter.js +224 -0
- package/presentation/experiments/ExperimentsEditor/ExperimentsEditorPresenter.js.map +1 -0
- package/presentation/experiments/ExperimentsEditor/abstractions/ExperimentsEditorDataSource.d.ts +10 -0
- package/presentation/experiments/ExperimentsEditor/abstractions/ExperimentsEditorDataSource.js +5 -0
- package/presentation/experiments/ExperimentsEditor/abstractions/ExperimentsEditorDataSource.js.map +1 -0
- package/presentation/experiments/ExperimentsEditor/abstractions/ExperimentsEditorPresenter.d.ts +58 -0
- package/presentation/experiments/ExperimentsEditor/abstractions/ExperimentsEditorPresenter.js +5 -0
- package/presentation/experiments/ExperimentsEditor/abstractions/ExperimentsEditorPresenter.js.map +1 -0
- package/presentation/experiments/ExperimentsEditor/components/ExperimentIndicator.d.ts +15 -0
- package/presentation/experiments/ExperimentsEditor/components/ExperimentIndicator.js +110 -0
- package/presentation/experiments/ExperimentsEditor/components/ExperimentIndicator.js.map +1 -0
- package/presentation/experiments/ExperimentsEditor/components/ExperimentPreviewToolbar.d.ts +9 -0
- package/presentation/experiments/ExperimentsEditor/components/ExperimentPreviewToolbar.js +178 -0
- package/presentation/experiments/ExperimentsEditor/components/ExperimentPreviewToolbar.js.map +1 -0
- package/presentation/experiments/ExperimentsEditor/components/ExperimentsButton.d.ts +11 -0
- package/presentation/experiments/ExperimentsEditor/components/ExperimentsButton.js +51 -0
- package/presentation/experiments/ExperimentsEditor/components/ExperimentsButton.js.map +1 -0
- package/presentation/experiments/ExperimentsEditor/components/ExperimentsSwitcher.d.ts +14 -0
- package/presentation/experiments/ExperimentsEditor/components/ExperimentsSwitcher.js +147 -0
- package/presentation/experiments/ExperimentsEditor/components/ExperimentsSwitcher.js.map +1 -0
- package/presentation/experiments/ExperimentsEditor/feature.d.ts +3 -0
- package/presentation/experiments/ExperimentsEditor/feature.js +21 -0
- package/presentation/experiments/ExperimentsEditor/feature.js.map +1 -0
- package/presentation/experiments/ExperimentsEditor/index.d.ts +4 -0
- package/presentation/experiments/ExperimentsEditor/index.js +3 -0
- package/presentation/experiments/ExperimentsManager/ExperimentsManagerPresenter.d.ts +39 -0
- package/presentation/experiments/ExperimentsManager/ExperimentsManagerPresenter.js +219 -0
- package/presentation/experiments/ExperimentsManager/ExperimentsManagerPresenter.js.map +1 -0
- package/presentation/experiments/ExperimentsManager/abstractions/ExperimentsManagerPresenter.d.ts +52 -0
- package/presentation/experiments/ExperimentsManager/abstractions/ExperimentsManagerPresenter.js +5 -0
- package/presentation/experiments/ExperimentsManager/abstractions/ExperimentsManagerPresenter.js.map +1 -0
- package/presentation/experiments/ExperimentsManager/components/ExperimentCard.d.ts +10 -0
- package/presentation/experiments/ExperimentsManager/components/ExperimentCard.js +296 -0
- package/presentation/experiments/ExperimentsManager/components/ExperimentCard.js.map +1 -0
- package/presentation/experiments/ExperimentsManager/components/ExperimentsDrawerView.d.ts +2 -0
- package/presentation/experiments/ExperimentsManager/components/ExperimentsDrawerView.js +92 -0
- package/presentation/experiments/ExperimentsManager/components/ExperimentsDrawerView.js.map +1 -0
- package/presentation/experiments/ExperimentsManager/components/ExperimentsEmptyState.d.ts +6 -0
- package/presentation/experiments/ExperimentsManager/components/ExperimentsEmptyState.js +103 -0
- package/presentation/experiments/ExperimentsManager/components/ExperimentsEmptyState.js.map +1 -0
- package/presentation/experiments/ExperimentsManager/components/ExperimentsListView.d.ts +9 -0
- package/presentation/experiments/ExperimentsManager/components/ExperimentsListView.js +58 -0
- package/presentation/experiments/ExperimentsManager/components/ExperimentsListView.js.map +1 -0
- package/presentation/experiments/ExperimentsManager/feature.d.ts +3 -0
- package/presentation/experiments/ExperimentsManager/feature.js +17 -0
- package/presentation/experiments/ExperimentsManager/feature.js.map +1 -0
- package/presentation/experiments/ExperimentsManager/index.d.ts +4 -0
- package/presentation/experiments/ExperimentsManager/index.js +3 -0
- package/presentation/experiments/VariantPageEditorConfig.d.ts +7 -0
- package/presentation/experiments/VariantPageEditorConfig.js +26 -0
- package/presentation/experiments/VariantPageEditorConfig.js.map +1 -0
- package/presentation/experiments/config/ExperimentsEditorConfig.d.ts +8 -0
- package/presentation/experiments/config/ExperimentsEditorConfig.js +21 -0
- package/presentation/experiments/config/ExperimentsEditorConfig.js.map +1 -0
- package/presentation/experiments/config/VariantAutoSave.d.ts +5 -0
- package/presentation/experiments/config/VariantAutoSave.js +41 -0
- package/presentation/experiments/config/VariantAutoSave.js.map +1 -0
- package/presentation/experiments/shared/variantColors.d.ts +11 -0
- package/presentation/experiments/shared/variantColors.js +13 -0
- package/presentation/experiments/shared/variantColors.js.map +1 -0
- package/presentation/experiments/shared/variantDocument.d.ts +16 -0
- package/presentation/experiments/shared/variantDocument.js +31 -0
- package/presentation/experiments/shared/variantDocument.js.map +1 -0
- package/presentation/navigation/Extension.js +9 -5
- package/presentation/navigation/Extension.js.map +1 -1
- package/presentation/navigation/NextjsConfig/NextjsConfigDialog.d.ts +2 -2
- package/presentation/navigation/StarterKitConfigDialog.js +1 -1
- package/presentation/navigation/StarterKitConfigDialog.js.map +1 -1
- package/presentation/pages/CreatePage/CreatePageDialog.d.ts +2 -2
- package/presentation/pages/CreatePage/CreatePagePresenter.js +1 -1
- package/presentation/pages/CreatePage/CreatePagePresenter.js.map +1 -1
- package/presentation/pages/CreatePage/WithLanguageSelector.js +3 -3
- package/presentation/pages/CreatePage/WithLanguageSelector.js.map +1 -1
- package/presentation/pages/CreatePage/feature.js +3 -3
- package/presentation/pages/CreatePage/feature.js.map +1 -1
- package/presentation/pages/PageEditor/PageEditor.experiments.d.ts +2 -0
- package/presentation/pages/PageEditor/PageEditor.experiments.js +54 -0
- package/presentation/pages/PageEditor/PageEditor.experiments.js.map +1 -0
- package/presentation/pages/PageEditor/PageEditorSurface.d.ts +15 -0
- package/presentation/pages/PageEditor/PageEditorSurface.js +63 -0
- package/presentation/pages/PageEditor/PageEditorSurface.js.map +1 -0
- package/presentation/pages/PageEditor/TopBar/PageSettingsDrawer.d.ts +2 -2
- package/presentation/pages/PageEditor/pageDocument.d.ts +4 -0
- package/presentation/pages/PageEditor/pageDocument.js +15 -0
- package/presentation/pages/PageEditor/pageDocument.js.map +1 -0
- package/presentation/pages/PageList/components/BulkActions/BulkActionDelete.d.ts +2 -2
- package/presentation/pages/PageList/components/BulkActions/BulkActionDuplicate.d.ts +2 -2
- package/presentation/pages/PageList/components/BulkActions/BulkActionMovePage.d.ts +2 -2
- package/presentation/pages/PageList/components/BulkActions/BulkActionPublish.d.ts +2 -2
- package/presentation/pages/PageList/components/BulkActions/BulkActionUnpublish.d.ts +2 -2
- package/presentation/pages/PageList/components/DocumentList.d.ts +2 -2
- package/presentation/pages/PageList/components/PagesList.js +2 -1
- package/presentation/pages/PageList/components/PagesList.js.map +1 -1
- package/presentation/pages/PageList/components/Table/Table.d.ts +2 -2
- package/presentation/pages/PageList/components/WbPagesBreadcrumbs.d.ts +9 -0
- package/presentation/pages/PageList/components/WbPagesBreadcrumbs.js +40 -0
- package/presentation/pages/PageList/components/WbPagesBreadcrumbs.js.map +1 -0
- package/presentation/pages/TranslatePage/TranslatePageConfig.d.ts +1 -1
- package/presentation/pages/TranslatePage/TranslatePageConfig.js +6 -2
- package/presentation/pages/TranslatePage/TranslatePageConfig.js.map +1 -1
- package/presentation/pages/TranslatePage/TranslatePageDialog.js +22 -10
- package/presentation/pages/TranslatePage/TranslatePageDialog.js.map +1 -1
- package/presentation/pages/TranslatePage/translatePageSchema.d.ts +1 -1
- package/presentation/pages/TranslatePage/translatePageSchema.js +1 -1
- package/presentation/pages/TranslatePage/translatePageSchema.js.map +1 -1
- package/presentation/pages/TrashBin/WbTrashBin.d.ts +2 -2
- package/presentation/redirects/RedirectList/components/BulkActionDelete.d.ts +2 -2
- package/presentation/redirects/RedirectList/components/BulkActionMove.d.ts +2 -2
- package/presentation/redirects/RedirectList/components/CreateRedirectDialog.d.ts +2 -2
- package/presentation/redirects/RedirectList/components/DocumentList.d.ts +2 -2
- package/presentation/redirects/RedirectList/components/EditRedirectDialog.d.ts +2 -2
- package/presentation/redirects/RedirectList/components/Table/Table.d.ts +2 -2
- package/shared/fileManagerItemToValue.d.ts +8 -9
- package/shared/fileManagerItemToValue.js +22 -7
- package/shared/fileManagerItemToValue.js.map +1 -1
- package/inputRenderers/LexicalInput/icons/list-ol.js +0 -20
- package/inputRenderers/LexicalInput/icons/list-ol.js.map +0 -1
- package/inputRenderers/LexicalInput/icons/list-ol.svg +0 -1
- package/inputRenderers/LexicalInput/icons/list-ul.js +0 -18
- package/inputRenderers/LexicalInput/icons/list-ul.js.map +0 -1
- package/inputRenderers/LexicalInput/icons/list-ul.svg +0 -1
- package/static/svg/list-ol.d64946f3.svg +0 -1
- package/static/svg/list-ul.1d54da3f.svg +0 -1
package/presentation/experiments/ExperimentsEditor/abstractions/ExperimentsEditorPresenter.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ExperimentDto, UpdateExperimentInput, VariantContentDto, VariantDto } from "../../../../features/experiments/index.js";
|
|
2
|
+
import type { NewExperimentPayload } from "../../ExperimentForm/abstractions/ExperimentFormPresenter.js";
|
|
3
|
+
/** A single "thing you can edit" within an experiment: the control, or one of its variants. */
|
|
4
|
+
export interface VariantOption {
|
|
5
|
+
id: string | null;
|
|
6
|
+
name: string;
|
|
7
|
+
weight: number;
|
|
8
|
+
isControl: boolean;
|
|
9
|
+
color: string;
|
|
10
|
+
}
|
|
11
|
+
/** A row in the top-bar experiment switcher. */
|
|
12
|
+
export interface SwitcherItem {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
status: "active" | "inactive";
|
|
16
|
+
}
|
|
17
|
+
export interface IExperimentsEditorViewModel {
|
|
18
|
+
baselineRevisionId: string;
|
|
19
|
+
pageEntryId: string;
|
|
20
|
+
experiments: ExperimentDto[];
|
|
21
|
+
selectedExperimentId: string | null;
|
|
22
|
+
selectedExperiment: ExperimentDto | null;
|
|
23
|
+
selectedVariantId: string | null;
|
|
24
|
+
selectedVariant: VariantDto | null;
|
|
25
|
+
variantOptions: VariantOption[];
|
|
26
|
+
currentBucket: VariantOption | null;
|
|
27
|
+
runningExperiment: ExperimentDto | null;
|
|
28
|
+
switcherItems: SwitcherItem[];
|
|
29
|
+
paused: boolean;
|
|
30
|
+
drawerOpen: boolean;
|
|
31
|
+
editTarget: ExperimentDto | null;
|
|
32
|
+
}
|
|
33
|
+
export interface IExperimentsEditorPresenter {
|
|
34
|
+
readonly vm: IExperimentsEditorViewModel;
|
|
35
|
+
init(pageRevisionId: string): void;
|
|
36
|
+
reload(): Promise<void>;
|
|
37
|
+
selectExperiment(id: string | null): void;
|
|
38
|
+
selectVariant(variantId: string | null): void;
|
|
39
|
+
syncReadOnlySelection(isReadOnly: boolean): void;
|
|
40
|
+
openManage(): void;
|
|
41
|
+
editExperiment(experiment: ExperimentDto): void;
|
|
42
|
+
closeDrawer(): void;
|
|
43
|
+
pause(): Promise<void>;
|
|
44
|
+
resume(): Promise<void>;
|
|
45
|
+
activate(experimentId: string): Promise<ExperimentDto>;
|
|
46
|
+
deactivate(experimentId: string): Promise<ExperimentDto>;
|
|
47
|
+
createExperiment(payload: NewExperimentPayload): Promise<ExperimentDto>;
|
|
48
|
+
updateExperiment(id: string, input: UpdateExperimentInput): Promise<ExperimentDto>;
|
|
49
|
+
deleteExperiment(experimentId: string): Promise<boolean>;
|
|
50
|
+
getVariant(id: string): Promise<VariantContentDto | null>;
|
|
51
|
+
saveVariant(revisionId: string, doc: Record<string, any>): Promise<VariantDto>;
|
|
52
|
+
}
|
|
53
|
+
export declare const ExperimentsEditorPresenter: import("@webiny/di").Abstraction<IExperimentsEditorPresenter>;
|
|
54
|
+
export declare namespace ExperimentsEditorPresenter {
|
|
55
|
+
type Interface = IExperimentsEditorPresenter;
|
|
56
|
+
type ViewModel = IExperimentsEditorViewModel;
|
|
57
|
+
type Option = VariantOption;
|
|
58
|
+
}
|
package/presentation/experiments/ExperimentsEditor/abstractions/ExperimentsEditorPresenter.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation/experiments/ExperimentsEditor/abstractions/ExperimentsEditorPresenter.js","sources":["../../../../../src/presentation/experiments/ExperimentsEditor/abstractions/ExperimentsEditorPresenter.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\nimport type {\n ExperimentDto,\n UpdateExperimentInput,\n VariantContentDto,\n VariantDto\n} from \"~/features/experiments/index.js\";\nimport type { NewExperimentPayload } from \"../../ExperimentForm/abstractions/ExperimentFormPresenter.js\";\n\n/** A single \"thing you can edit\" within an experiment: the control, or one of its variants. */\nexport interface VariantOption {\n // `null` identifies the control (the baseline page); otherwise the variant entry id.\n id: string | null;\n name: string;\n weight: number;\n isControl: boolean;\n // Palette colour for the bucket, assigned by index (control neutral, variants cycle).\n color: string;\n}\n\n/** A row in the top-bar experiment switcher. */\nexport interface SwitcherItem {\n id: string;\n name: string;\n status: \"active\" | \"inactive\";\n}\n\nexport interface IExperimentsEditorViewModel {\n // Revision id of the page being edited; the baseline for its experiments.\n baselineRevisionId: string;\n // Entry id of the page being edited (derived from the baseline revision id).\n pageEntryId: string;\n experiments: ExperimentDto[];\n selectedExperimentId: string | null;\n selectedExperiment: ExperimentDto | null;\n // Currently edited bucket: `null` = control, otherwise a variant entry id.\n selectedVariantId: string | null;\n // The variant DTO matching `selectedVariantId` (null when editing the control).\n selectedVariant: VariantDto | null;\n variantOptions: VariantOption[];\n // The bucket currently being previewed/edited (control or the selected variant).\n currentBucket: VariantOption | null;\n // The single running experiment on the page, if any (drives the read-only indicator).\n runningExperiment: ExperimentDto | null;\n // Experiments as switcher rows (id + name + active/inactive status).\n switcherItems: SwitcherItem[];\n // Kill-switch state of the selected experiment.\n paused: boolean;\n // Manage/edit drawer UI state.\n drawerOpen: boolean;\n editTarget: ExperimentDto | null;\n}\n\nexport interface IExperimentsEditorPresenter {\n readonly vm: IExperimentsEditorViewModel;\n init(pageRevisionId: string): void;\n reload(): Promise<void>;\n selectExperiment(id: string | null): void;\n selectVariant(variantId: string | null): void;\n // On a published (read-only) page, keep the running experiment selected so the preview tracks it.\n syncReadOnlySelection(isReadOnly: boolean): void;\n openManage(): void;\n editExperiment(experiment: ExperimentDto): void;\n closeDrawer(): void;\n pause(): Promise<void>;\n resume(): Promise<void>;\n activate(experimentId: string): Promise<ExperimentDto>;\n deactivate(experimentId: string): Promise<ExperimentDto>;\n createExperiment(payload: NewExperimentPayload): Promise<ExperimentDto>;\n updateExperiment(id: string, input: UpdateExperimentInput): Promise<ExperimentDto>;\n deleteExperiment(experimentId: string): Promise<boolean>;\n getVariant(id: string): Promise<VariantContentDto | null>;\n saveVariant(revisionId: string, doc: Record<string, any>): Promise<VariantDto>;\n}\n\nexport const ExperimentsEditorPresenter = createAbstraction<IExperimentsEditorPresenter>(\n \"WebsiteBuilder/ExperimentsEditor/Presenter\"\n);\n\nexport namespace ExperimentsEditorPresenter {\n export type Interface = IExperimentsEditorPresenter;\n export type ViewModel = IExperimentsEditorViewModel;\n export type Option = VariantOption;\n}\n"],"names":["ExperimentsEditorPresenter","createAbstraction"],"mappings":";AA2EO,MAAMA,6BAA6BC,kBACtC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { ExperimentDto } from "../../../../features/experiments/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Top-bar indicator shown on a published (read-only) page: names the running experiment, shows
|
|
5
|
+
* whether it's live (Active) or paused (Inactive), and lets the editor toggle the kill-switch.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ExperimentIndicator: (({ experiment }: {
|
|
8
|
+
experiment: ExperimentDto;
|
|
9
|
+
}) => React.JSX.Element) & React.NamedExoticComponent<{
|
|
10
|
+
experiment: ExperimentDto;
|
|
11
|
+
}> & {
|
|
12
|
+
readonly type: ({ experiment }: {
|
|
13
|
+
experiment: ExperimentDto;
|
|
14
|
+
}) => React.JSX.Element;
|
|
15
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import react, { useState } from "react";
|
|
2
|
+
import { observer } from "mobx-react-lite";
|
|
3
|
+
import { useFeature } from "@webiny/app";
|
|
4
|
+
import { ReactComponent } from "@webiny/icons/science.svg";
|
|
5
|
+
import { ReactComponent as pause_svg_ReactComponent } from "@webiny/icons/pause.svg";
|
|
6
|
+
import { ReactComponent as play_arrow_svg_ReactComponent } from "@webiny/icons/play_arrow.svg";
|
|
7
|
+
import { ExperimentsEditorPresenterFeature } from "../feature.js";
|
|
8
|
+
const ExperimentIndicator_ExperimentIndicator = observer(function({ experiment }) {
|
|
9
|
+
const { presenter } = useFeature(ExperimentsEditorPresenterFeature);
|
|
10
|
+
const { paused } = presenter.vm;
|
|
11
|
+
const [busy, setBusy] = useState(false);
|
|
12
|
+
const active = !paused;
|
|
13
|
+
const toggle = async ()=>{
|
|
14
|
+
setBusy(true);
|
|
15
|
+
try {
|
|
16
|
+
await (paused ? presenter.resume() : presenter.pause());
|
|
17
|
+
} finally{
|
|
18
|
+
setBusy(false);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const toggleStyle = {
|
|
22
|
+
display: "inline-flex",
|
|
23
|
+
alignItems: "center",
|
|
24
|
+
gap: 6,
|
|
25
|
+
borderRadius: 8,
|
|
26
|
+
padding: "6px 12px",
|
|
27
|
+
fontWeight: 600,
|
|
28
|
+
fontSize: 13,
|
|
29
|
+
cursor: busy ? "default" : "pointer",
|
|
30
|
+
opacity: busy ? 0.6 : 1,
|
|
31
|
+
...active ? {
|
|
32
|
+
border: "1px solid #d5d7db",
|
|
33
|
+
background: "#fff",
|
|
34
|
+
color: "#1f2937"
|
|
35
|
+
} : {
|
|
36
|
+
border: "none",
|
|
37
|
+
background: "#10b981",
|
|
38
|
+
color: "#fff"
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
return /*#__PURE__*/ react.createElement("div", {
|
|
42
|
+
style: {
|
|
43
|
+
display: "inline-flex",
|
|
44
|
+
alignItems: "center",
|
|
45
|
+
gap: 12,
|
|
46
|
+
border: "1px solid #e5e7eb",
|
|
47
|
+
borderRadius: 8,
|
|
48
|
+
padding: "4px 4px 4px 12px",
|
|
49
|
+
background: "#fff"
|
|
50
|
+
}
|
|
51
|
+
}, /*#__PURE__*/ react.createElement("span", {
|
|
52
|
+
style: {
|
|
53
|
+
display: "inline-flex",
|
|
54
|
+
alignItems: "center",
|
|
55
|
+
gap: 8,
|
|
56
|
+
minWidth: 0
|
|
57
|
+
}
|
|
58
|
+
}, /*#__PURE__*/ react.createElement(ReactComponent, {
|
|
59
|
+
style: {
|
|
60
|
+
width: 18,
|
|
61
|
+
height: 18,
|
|
62
|
+
color: "#e2572a",
|
|
63
|
+
fill: "currentColor"
|
|
64
|
+
}
|
|
65
|
+
}), /*#__PURE__*/ react.createElement("span", {
|
|
66
|
+
style: {
|
|
67
|
+
fontWeight: 600,
|
|
68
|
+
whiteSpace: "nowrap",
|
|
69
|
+
overflow: "hidden",
|
|
70
|
+
textOverflow: "ellipsis"
|
|
71
|
+
}
|
|
72
|
+
}, experiment.name), /*#__PURE__*/ react.createElement("span", {
|
|
73
|
+
style: {
|
|
74
|
+
display: "inline-flex",
|
|
75
|
+
alignItems: "center",
|
|
76
|
+
gap: 5,
|
|
77
|
+
fontSize: 12,
|
|
78
|
+
fontWeight: 500,
|
|
79
|
+
color: active ? "#0f9d58" : "#6b7280",
|
|
80
|
+
whiteSpace: "nowrap"
|
|
81
|
+
}
|
|
82
|
+
}, /*#__PURE__*/ react.createElement("span", {
|
|
83
|
+
style: {
|
|
84
|
+
width: 8,
|
|
85
|
+
height: 8,
|
|
86
|
+
borderRadius: "50%",
|
|
87
|
+
background: active ? "#10b981" : "#9ca3af"
|
|
88
|
+
}
|
|
89
|
+
}), active ? "Active" : "Inactive")), /*#__PURE__*/ react.createElement("button", {
|
|
90
|
+
type: "button",
|
|
91
|
+
onClick: toggle,
|
|
92
|
+
disabled: busy,
|
|
93
|
+
style: toggleStyle
|
|
94
|
+
}, active ? /*#__PURE__*/ react.createElement(pause_svg_ReactComponent, {
|
|
95
|
+
style: {
|
|
96
|
+
width: 16,
|
|
97
|
+
height: 16,
|
|
98
|
+
fill: "currentColor"
|
|
99
|
+
}
|
|
100
|
+
}) : /*#__PURE__*/ react.createElement(play_arrow_svg_ReactComponent, {
|
|
101
|
+
style: {
|
|
102
|
+
width: 16,
|
|
103
|
+
height: 16,
|
|
104
|
+
fill: "currentColor"
|
|
105
|
+
}
|
|
106
|
+
}), active ? "Pause" : "Resume"));
|
|
107
|
+
});
|
|
108
|
+
export { ExperimentIndicator_ExperimentIndicator as ExperimentIndicator };
|
|
109
|
+
|
|
110
|
+
//# sourceMappingURL=ExperimentIndicator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation/experiments/ExperimentsEditor/components/ExperimentIndicator.js","sources":["../../../../../src/presentation/experiments/ExperimentsEditor/components/ExperimentIndicator.tsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { useFeature } from \"@webiny/app\";\nimport { ReactComponent as ScienceIcon } from \"@webiny/icons/science.svg\";\nimport { ReactComponent as PauseIcon } from \"@webiny/icons/pause.svg\";\nimport { ReactComponent as PlayIcon } from \"@webiny/icons/play_arrow.svg\";\nimport { ExperimentsEditorPresenterFeature } from \"../feature.js\";\nimport type { ExperimentDto } from \"~/features/experiments/index.js\";\n\n/**\n * Top-bar indicator shown on a published (read-only) page: names the running experiment, shows\n * whether it's live (Active) or paused (Inactive), and lets the editor toggle the kill-switch.\n */\nexport const ExperimentIndicator = observer(function ExperimentIndicator({\n experiment\n}: {\n experiment: ExperimentDto;\n}) {\n const { presenter } = useFeature(ExperimentsEditorPresenterFeature);\n const { paused } = presenter.vm;\n const [busy, setBusy] = useState(false);\n const active = !paused;\n\n const toggle = async () => {\n setBusy(true);\n try {\n await (paused ? presenter.resume() : presenter.pause());\n } finally {\n setBusy(false);\n }\n };\n\n const toggleStyle: React.CSSProperties = {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n borderRadius: 8,\n padding: \"6px 12px\",\n fontWeight: 600,\n fontSize: 13,\n cursor: busy ? \"default\" : \"pointer\",\n opacity: busy ? 0.6 : 1,\n ...(active\n ? { border: \"1px solid #d5d7db\", background: \"#fff\", color: \"#1f2937\" }\n : { border: \"none\", background: \"#10b981\", color: \"#fff\" })\n };\n\n return (\n <div\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 12,\n border: \"1px solid #e5e7eb\",\n borderRadius: 8,\n padding: \"4px 4px 4px 12px\",\n background: \"#fff\"\n }}\n >\n <span style={{ display: \"inline-flex\", alignItems: \"center\", gap: 8, minWidth: 0 }}>\n <ScienceIcon\n style={{ width: 18, height: 18, color: \"#e2572a\", fill: \"currentColor\" }}\n />\n <span\n style={{\n fontWeight: 600,\n whiteSpace: \"nowrap\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\"\n }}\n >\n {experiment.name}\n </span>\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 5,\n fontSize: 12,\n fontWeight: 500,\n color: active ? \"#0f9d58\" : \"#6b7280\",\n whiteSpace: \"nowrap\"\n }}\n >\n <span\n style={{\n width: 8,\n height: 8,\n borderRadius: \"50%\",\n background: active ? \"#10b981\" : \"#9ca3af\"\n }}\n />\n {active ? \"Active\" : \"Inactive\"}\n </span>\n </span>\n <button type=\"button\" onClick={toggle} disabled={busy} style={toggleStyle}>\n {active ? (\n <PauseIcon style={{ width: 16, height: 16, fill: \"currentColor\" }} />\n ) : (\n <PlayIcon style={{ width: 16, height: 16, fill: \"currentColor\" }} />\n )}\n {active ? \"Pause\" : \"Resume\"}\n </button>\n </div>\n );\n});\n"],"names":["ExperimentIndicator","observer","experiment","presenter","useFeature","ExperimentsEditorPresenterFeature","paused","busy","setBusy","useState","active","toggle","toggleStyle","ScienceIcon","PauseIcon","PlayIcon"],"mappings":";;;;;;;AAaO,MAAMA,0CAAsBC,SAAS,SAA6B,EACrEC,UAAU,EAGb;IACG,MAAM,EAAEC,SAAS,EAAE,GAAGC,WAAWC;IACjC,MAAM,EAAEC,MAAM,EAAE,GAAGH,UAAU,EAAE;IAC/B,MAAM,CAACI,MAAMC,QAAQ,GAAGC,SAAS;IACjC,MAAMC,SAAS,CAACJ;IAEhB,MAAMK,SAAS;QACXH,QAAQ;QACR,IAAI;YACA,MAAOF,CAAAA,SAASH,UAAU,MAAM,KAAKA,UAAU,KAAK,EAAC;QACzD,SAAU;YACNK,QAAQ;QACZ;IACJ;IAEA,MAAMI,cAAmC;QACrC,SAAS;QACT,YAAY;QACZ,KAAK;QACL,cAAc;QACd,SAAS;QACT,YAAY;QACZ,UAAU;QACV,QAAQL,OAAO,YAAY;QAC3B,SAASA,OAAO,MAAM;QACtB,GAAIG,SACE;YAAE,QAAQ;YAAqB,YAAY;YAAQ,OAAO;QAAU,IACpE;YAAE,QAAQ;YAAQ,YAAY;YAAW,OAAO;QAAO,CAAC;IAClE;IAEA,OAAO,WAAP,GACI,oBAAC;QACG,OAAO;YACH,SAAS;YACT,YAAY;YACZ,KAAK;YACL,QAAQ;YACR,cAAc;YACd,SAAS;YACT,YAAY;QAChB;qBAEA,oBAAC;QAAK,OAAO;YAAE,SAAS;YAAe,YAAY;YAAU,KAAK;YAAG,UAAU;QAAE;qBAC7E,oBAACG,gBAAWA;QACR,OAAO;YAAE,OAAO;YAAI,QAAQ;YAAI,OAAO;YAAW,MAAM;QAAe;sBAE3E,oBAAC;QACG,OAAO;YACH,YAAY;YACZ,YAAY;YACZ,UAAU;YACV,cAAc;QAClB;OAECX,WAAW,IAAI,iBAEpB,oBAAC;QACG,OAAO;YACH,SAAS;YACT,YAAY;YACZ,KAAK;YACL,UAAU;YACV,YAAY;YACZ,OAAOQ,SAAS,YAAY;YAC5B,YAAY;QAChB;qBAEA,oBAAC;QACG,OAAO;YACH,OAAO;YACP,QAAQ;YACR,cAAc;YACd,YAAYA,SAAS,YAAY;QACrC;QAEHA,SAAS,WAAW,4BAG7B,oBAAC;QAAO,MAAK;QAAS,SAASC;QAAQ,UAAUJ;QAAM,OAAOK;OACzDF,SAAS,WAATA,GACG,oBAACI,0BAASA;QAAC,OAAO;YAAE,OAAO;YAAI,QAAQ;YAAI,MAAM;QAAe;uBAEhE,oBAACC,+BAAQA;QAAC,OAAO;YAAE,OAAO;YAAI,QAAQ;YAAI,MAAM;QAAe;QAElEL,SAAS,UAAU;AAIpC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* A bar shown between the address bar and the canvas while an experiment is selected. It names the
|
|
4
|
+
* experiment, shows its status and the bucket currently being edited, and lets the editor switch
|
|
5
|
+
* between the control and each variant or jump to editing the experiment.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ExperimentPreviewToolbar: (() => React.JSX.Element | null) & React.NamedExoticComponent<unknown> & {
|
|
8
|
+
readonly type: () => React.JSX.Element | null;
|
|
9
|
+
};
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import react, { useState } from "react";
|
|
2
|
+
import { observer } from "mobx-react-lite";
|
|
3
|
+
import { useFeature } from "@webiny/app";
|
|
4
|
+
import { DropdownMenu } from "@webiny/admin-ui";
|
|
5
|
+
import { ReactComponent } from "@webiny/icons/science.svg";
|
|
6
|
+
import { ReactComponent as swap_horiz_svg_ReactComponent } from "@webiny/icons/swap_horiz.svg";
|
|
7
|
+
import { ReactComponent as check_svg_ReactComponent } from "@webiny/icons/check.svg";
|
|
8
|
+
import { ReactComponent as edit_svg_ReactComponent } from "@webiny/icons/edit.svg";
|
|
9
|
+
import { ExperimentsEditorPresenterFeature } from "../feature.js";
|
|
10
|
+
import { useSelectFromEditor } from "../../../../BaseEditor/hooks/useSelectFromEditor.js";
|
|
11
|
+
const Dot = ({ color })=>/*#__PURE__*/ react.createElement("span", {
|
|
12
|
+
style: {
|
|
13
|
+
width: 8,
|
|
14
|
+
height: 8,
|
|
15
|
+
borderRadius: "50%",
|
|
16
|
+
background: color,
|
|
17
|
+
flexShrink: 0
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
const ExperimentPreviewToolbar_ExperimentPreviewToolbar = observer(function() {
|
|
21
|
+
const { presenter } = useFeature(ExperimentsEditorPresenterFeature);
|
|
22
|
+
const { selectedExperiment, variantOptions: options, currentBucket: current } = presenter.vm;
|
|
23
|
+
const isReadOnly = useSelectFromEditor((state)=>state.isReadOnly);
|
|
24
|
+
const [open, setOpen] = useState(false);
|
|
25
|
+
if (!selectedExperiment || !current) return null;
|
|
26
|
+
const active = "running" === selectedExperiment.status;
|
|
27
|
+
const trigger = /*#__PURE__*/ react.createElement("button", {
|
|
28
|
+
type: "button",
|
|
29
|
+
style: {
|
|
30
|
+
display: "inline-flex",
|
|
31
|
+
alignItems: "center",
|
|
32
|
+
gap: 8,
|
|
33
|
+
border: "1px solid #d5d7db",
|
|
34
|
+
background: "#fff",
|
|
35
|
+
borderRadius: 8,
|
|
36
|
+
padding: "6px 12px",
|
|
37
|
+
fontWeight: 600,
|
|
38
|
+
fontSize: 13,
|
|
39
|
+
cursor: "pointer"
|
|
40
|
+
}
|
|
41
|
+
}, /*#__PURE__*/ react.createElement(swap_horiz_svg_ReactComponent, {
|
|
42
|
+
style: {
|
|
43
|
+
width: 18,
|
|
44
|
+
height: 18
|
|
45
|
+
}
|
|
46
|
+
}), "Switch variant");
|
|
47
|
+
return /*#__PURE__*/ react.createElement("div", {
|
|
48
|
+
className: "w-full bg-neutral-base border-solid border-b-sm border-neutral-dimmed",
|
|
49
|
+
"data-affects-preview": "height",
|
|
50
|
+
style: {
|
|
51
|
+
display: "flex",
|
|
52
|
+
alignItems: "center",
|
|
53
|
+
justifyContent: "space-between",
|
|
54
|
+
gap: 12,
|
|
55
|
+
padding: "8px 16px",
|
|
56
|
+
minHeight: 48
|
|
57
|
+
}
|
|
58
|
+
}, /*#__PURE__*/ react.createElement("div", {
|
|
59
|
+
style: {
|
|
60
|
+
display: "flex",
|
|
61
|
+
alignItems: "center",
|
|
62
|
+
gap: 12,
|
|
63
|
+
minWidth: 0
|
|
64
|
+
}
|
|
65
|
+
}, isReadOnly ? null : /*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(ReactComponent, {
|
|
66
|
+
style: {
|
|
67
|
+
width: 18,
|
|
68
|
+
height: 18,
|
|
69
|
+
color: "#e2572a",
|
|
70
|
+
flexShrink: 0
|
|
71
|
+
}
|
|
72
|
+
}), /*#__PURE__*/ react.createElement("span", {
|
|
73
|
+
style: {
|
|
74
|
+
fontWeight: 600,
|
|
75
|
+
whiteSpace: "nowrap",
|
|
76
|
+
overflow: "hidden",
|
|
77
|
+
textOverflow: "ellipsis"
|
|
78
|
+
}
|
|
79
|
+
}, selectedExperiment.name), /*#__PURE__*/ react.createElement("span", {
|
|
80
|
+
style: {
|
|
81
|
+
display: "inline-flex",
|
|
82
|
+
alignItems: "center",
|
|
83
|
+
gap: 5,
|
|
84
|
+
fontSize: 12,
|
|
85
|
+
fontWeight: 500,
|
|
86
|
+
color: active ? "#0f9d58" : "#6b7280",
|
|
87
|
+
whiteSpace: "nowrap"
|
|
88
|
+
}
|
|
89
|
+
}, /*#__PURE__*/ react.createElement(Dot, {
|
|
90
|
+
color: active ? "#10b981" : "#9ca3af"
|
|
91
|
+
}), active ? "Active" : "Inactive"), /*#__PURE__*/ react.createElement("span", {
|
|
92
|
+
style: {
|
|
93
|
+
width: 1,
|
|
94
|
+
height: 20,
|
|
95
|
+
background: "#e5e7eb",
|
|
96
|
+
flexShrink: 0
|
|
97
|
+
}
|
|
98
|
+
})), /*#__PURE__*/ react.createElement("span", {
|
|
99
|
+
style: {
|
|
100
|
+
fontSize: 13,
|
|
101
|
+
color: "#6b7280",
|
|
102
|
+
whiteSpace: "nowrap"
|
|
103
|
+
}
|
|
104
|
+
}, isReadOnly ? "Previewing" : "You're editing"), /*#__PURE__*/ react.createElement("span", {
|
|
105
|
+
style: {
|
|
106
|
+
display: "inline-flex",
|
|
107
|
+
alignItems: "center",
|
|
108
|
+
gap: 8,
|
|
109
|
+
background: "#3c4043",
|
|
110
|
+
color: "#fff",
|
|
111
|
+
borderRadius: 8,
|
|
112
|
+
padding: "4px 10px",
|
|
113
|
+
fontSize: 13,
|
|
114
|
+
fontWeight: 600,
|
|
115
|
+
whiteSpace: "nowrap"
|
|
116
|
+
}
|
|
117
|
+
}, /*#__PURE__*/ react.createElement(Dot, {
|
|
118
|
+
color: current.color
|
|
119
|
+
}), current.name, /*#__PURE__*/ react.createElement("span", {
|
|
120
|
+
style: {
|
|
121
|
+
opacity: 0.7,
|
|
122
|
+
fontWeight: 500
|
|
123
|
+
}
|
|
124
|
+
}, current.weight, "%"))), /*#__PURE__*/ react.createElement(DropdownMenu, {
|
|
125
|
+
open: open,
|
|
126
|
+
onOpenChange: setOpen,
|
|
127
|
+
trigger: trigger,
|
|
128
|
+
style: {
|
|
129
|
+
minWidth: 260
|
|
130
|
+
}
|
|
131
|
+
}, /*#__PURE__*/ react.createElement(DropdownMenu.Label, {
|
|
132
|
+
text: "Switch variant"
|
|
133
|
+
}), options.map((option)=>/*#__PURE__*/ react.createElement(DropdownMenu.Item, {
|
|
134
|
+
key: option.id ?? "control",
|
|
135
|
+
icon: /*#__PURE__*/ react.createElement(Dot, {
|
|
136
|
+
color: option.color
|
|
137
|
+
}),
|
|
138
|
+
text: /*#__PURE__*/ react.createElement("span", {
|
|
139
|
+
style: {
|
|
140
|
+
display: "flex",
|
|
141
|
+
alignItems: "center",
|
|
142
|
+
justifyContent: "space-between",
|
|
143
|
+
width: "100%",
|
|
144
|
+
gap: 8
|
|
145
|
+
}
|
|
146
|
+
}, /*#__PURE__*/ react.createElement("span", null, option.name), /*#__PURE__*/ react.createElement("span", {
|
|
147
|
+
style: {
|
|
148
|
+
display: "flex",
|
|
149
|
+
alignItems: "center",
|
|
150
|
+
gap: 8
|
|
151
|
+
}
|
|
152
|
+
}, /*#__PURE__*/ react.createElement("span", {
|
|
153
|
+
style: {
|
|
154
|
+
fontSize: 12,
|
|
155
|
+
color: "#6b7280"
|
|
156
|
+
}
|
|
157
|
+
}, option.weight, "%"), option.id === current.id ? /*#__PURE__*/ react.createElement(check_svg_ReactComponent, {
|
|
158
|
+
style: {
|
|
159
|
+
width: 16,
|
|
160
|
+
height: 16,
|
|
161
|
+
color: option.color
|
|
162
|
+
}
|
|
163
|
+
}) : null)),
|
|
164
|
+
onClick: ()=>presenter.selectVariant(option.id)
|
|
165
|
+
})), isReadOnly ? null : /*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(DropdownMenu.Separator, null), /*#__PURE__*/ react.createElement(DropdownMenu.Item, {
|
|
166
|
+
icon: /*#__PURE__*/ react.createElement(edit_svg_ReactComponent, {
|
|
167
|
+
style: {
|
|
168
|
+
width: 18,
|
|
169
|
+
height: 18
|
|
170
|
+
}
|
|
171
|
+
}),
|
|
172
|
+
text: "Edit experiment",
|
|
173
|
+
onClick: ()=>presenter.editExperiment(selectedExperiment)
|
|
174
|
+
}))));
|
|
175
|
+
});
|
|
176
|
+
export { ExperimentPreviewToolbar_ExperimentPreviewToolbar as ExperimentPreviewToolbar };
|
|
177
|
+
|
|
178
|
+
//# sourceMappingURL=ExperimentPreviewToolbar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation/experiments/ExperimentsEditor/components/ExperimentPreviewToolbar.js","sources":["../../../../../src/presentation/experiments/ExperimentsEditor/components/ExperimentPreviewToolbar.tsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { useFeature } from \"@webiny/app\";\nimport { DropdownMenu } from \"@webiny/admin-ui\";\nimport { ReactComponent as ScienceIcon } from \"@webiny/icons/science.svg\";\nimport { ReactComponent as SwapIcon } from \"@webiny/icons/swap_horiz.svg\";\nimport { ReactComponent as CheckIcon } from \"@webiny/icons/check.svg\";\nimport { ReactComponent as EditIcon } from \"@webiny/icons/edit.svg\";\nimport { ExperimentsEditorPresenterFeature } from \"../feature.js\";\nimport { useSelectFromEditor } from \"~/BaseEditor/hooks/useSelectFromEditor.js\";\n\nconst Dot = ({ color }: { color: string }) => (\n <span style={{ width: 8, height: 8, borderRadius: \"50%\", background: color, flexShrink: 0 }} />\n);\n\n/**\n * A bar shown between the address bar and the canvas while an experiment is selected. It names the\n * experiment, shows its status and the bucket currently being edited, and lets the editor switch\n * between the control and each variant or jump to editing the experiment.\n */\nexport const ExperimentPreviewToolbar = observer(function ExperimentPreviewToolbar() {\n const { presenter } = useFeature(ExperimentsEditorPresenterFeature);\n const { selectedExperiment, variantOptions: options, currentBucket: current } = presenter.vm;\n const isReadOnly = useSelectFromEditor(state => state.isReadOnly);\n const [open, setOpen] = useState(false);\n\n if (!selectedExperiment || !current) {\n return null;\n }\n\n const active = selectedExperiment.status === \"running\";\n\n const trigger = (\n <button\n type=\"button\"\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 8,\n border: \"1px solid #d5d7db\",\n background: \"#fff\",\n borderRadius: 8,\n padding: \"6px 12px\",\n fontWeight: 600,\n fontSize: 13,\n cursor: \"pointer\"\n }}\n >\n <SwapIcon style={{ width: 18, height: 18 }} />\n Switch variant\n </button>\n );\n\n return (\n <div\n className=\"w-full bg-neutral-base border-solid border-b-sm border-neutral-dimmed\"\n data-affects-preview={\"height\"}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: 12,\n padding: \"8px 16px\",\n minHeight: 48\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 12, minWidth: 0 }}>\n {/* On a published (read-only) page the experiment name/status live in the top-bar\n indicator, so the toolbar just shows what's being previewed. */}\n {!isReadOnly ? (\n <>\n <ScienceIcon\n style={{ width: 18, height: 18, color: \"#e2572a\", flexShrink: 0 }}\n />\n <span\n style={{\n fontWeight: 600,\n whiteSpace: \"nowrap\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\"\n }}\n >\n {selectedExperiment.name}\n </span>\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 5,\n fontSize: 12,\n fontWeight: 500,\n color: active ? \"#0f9d58\" : \"#6b7280\",\n whiteSpace: \"nowrap\"\n }}\n >\n <Dot color={active ? \"#10b981\" : \"#9ca3af\"} />\n {active ? \"Active\" : \"Inactive\"}\n </span>\n <span\n style={{ width: 1, height: 20, background: \"#e5e7eb\", flexShrink: 0 }}\n />\n </>\n ) : null}\n\n <span style={{ fontSize: 13, color: \"#6b7280\", whiteSpace: \"nowrap\" }}>\n {isReadOnly ? \"Previewing\" : \"You're editing\"}\n </span>\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 8,\n background: \"#3c4043\",\n color: \"#fff\",\n borderRadius: 8,\n padding: \"4px 10px\",\n fontSize: 13,\n fontWeight: 600,\n whiteSpace: \"nowrap\"\n }}\n >\n <Dot color={current.color} />\n {current.name}\n <span style={{ opacity: 0.7, fontWeight: 500 }}>{current.weight}%</span>\n </span>\n </div>\n\n <DropdownMenu\n open={open}\n onOpenChange={setOpen}\n trigger={trigger}\n style={{ minWidth: 260 }}\n >\n <DropdownMenu.Label text=\"Switch variant\" />\n {options.map(option => (\n <DropdownMenu.Item\n key={option.id ?? \"control\"}\n icon={<Dot color={option.color} />}\n text={\n <span\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n width: \"100%\",\n gap: 8\n }}\n >\n <span>{option.name}</span>\n <span style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <span style={{ fontSize: 12, color: \"#6b7280\" }}>\n {option.weight}%\n </span>\n {option.id === current.id ? (\n <CheckIcon\n style={{ width: 16, height: 16, color: option.color }}\n />\n ) : null}\n </span>\n </span>\n }\n onClick={() => presenter.selectVariant(option.id)}\n />\n ))}\n {!isReadOnly ? (\n <>\n <DropdownMenu.Separator />\n <DropdownMenu.Item\n icon={<EditIcon style={{ width: 18, height: 18 }} />}\n text=\"Edit experiment\"\n onClick={() => presenter.editExperiment(selectedExperiment)}\n />\n </>\n ) : null}\n </DropdownMenu>\n </div>\n );\n});\n"],"names":["Dot","color","ExperimentPreviewToolbar","observer","presenter","useFeature","ExperimentsEditorPresenterFeature","selectedExperiment","options","current","isReadOnly","useSelectFromEditor","state","open","setOpen","useState","active","trigger","SwapIcon","ScienceIcon","DropdownMenu","option","CheckIcon","EditIcon"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Top-bar entry point for A/B experiments.
|
|
4
|
+
*
|
|
5
|
+
* On an editable (draft) page it's a switcher for picking an experiment to edit; on a published
|
|
6
|
+
* (read-only) page it's an indicator for the running experiment with a pause/resume kill-switch.
|
|
7
|
+
* State is shared through the editor-wide presenter so the in-preview toolbar tracks the selection.
|
|
8
|
+
*/
|
|
9
|
+
export declare const ExperimentsButton: (() => React.JSX.Element | null) & React.NamedExoticComponent<unknown> & {
|
|
10
|
+
readonly type: () => React.JSX.Element | null;
|
|
11
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import react, { useEffect } from "react";
|
|
2
|
+
import { observer } from "mobx-react-lite";
|
|
3
|
+
import { useFeature } from "@webiny/app";
|
|
4
|
+
import { Button } from "@webiny/admin-ui";
|
|
5
|
+
import { ReactComponent } from "@webiny/icons/science.svg";
|
|
6
|
+
import { useSelectFromEditor } from "../../../../BaseEditor/hooks/useSelectFromEditor.js";
|
|
7
|
+
import { ExperimentsSwitcher } from "./ExperimentsSwitcher.js";
|
|
8
|
+
import { ExperimentIndicator } from "./ExperimentIndicator.js";
|
|
9
|
+
import { ExperimentsEditorPresenterFeature } from "../feature.js";
|
|
10
|
+
const ExperimentsButton_ExperimentsButton = observer(function() {
|
|
11
|
+
const { presenter } = useFeature(ExperimentsEditorPresenterFeature);
|
|
12
|
+
const isReadOnly = useSelectFromEditor((state)=>state.isReadOnly);
|
|
13
|
+
const { runningExperiment, switcherItems, selectedExperimentId } = presenter.vm;
|
|
14
|
+
useEffect(()=>{
|
|
15
|
+
presenter.syncReadOnlySelection(isReadOnly);
|
|
16
|
+
}, [
|
|
17
|
+
presenter,
|
|
18
|
+
isReadOnly,
|
|
19
|
+
runningExperiment,
|
|
20
|
+
selectedExperimentId
|
|
21
|
+
]);
|
|
22
|
+
if (isReadOnly) {
|
|
23
|
+
if (!runningExperiment) return null;
|
|
24
|
+
return /*#__PURE__*/ react.createElement("div", {
|
|
25
|
+
style: {
|
|
26
|
+
display: "flex"
|
|
27
|
+
}
|
|
28
|
+
}, /*#__PURE__*/ react.createElement(ExperimentIndicator, {
|
|
29
|
+
experiment: runningExperiment
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
const items = switcherItems;
|
|
33
|
+
return /*#__PURE__*/ react.createElement("div", {
|
|
34
|
+
style: {
|
|
35
|
+
display: "flex"
|
|
36
|
+
}
|
|
37
|
+
}, 0 === items.length ? /*#__PURE__*/ react.createElement(Button, {
|
|
38
|
+
variant: "secondary",
|
|
39
|
+
icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
|
|
40
|
+
text: "Experiments",
|
|
41
|
+
onClick: ()=>presenter.openManage()
|
|
42
|
+
}) : /*#__PURE__*/ react.createElement(ExperimentsSwitcher, {
|
|
43
|
+
experiments: items,
|
|
44
|
+
selectedId: selectedExperimentId,
|
|
45
|
+
onSelect: (id)=>presenter.selectExperiment(id),
|
|
46
|
+
onManage: ()=>presenter.openManage()
|
|
47
|
+
}));
|
|
48
|
+
});
|
|
49
|
+
export { ExperimentsButton_ExperimentsButton as ExperimentsButton };
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=ExperimentsButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation/experiments/ExperimentsEditor/components/ExperimentsButton.js","sources":["../../../../../src/presentation/experiments/ExperimentsEditor/components/ExperimentsButton.tsx"],"sourcesContent":["import React, { useEffect } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { useFeature } from \"@webiny/app\";\nimport { Button } from \"@webiny/admin-ui\";\nimport { ReactComponent as ScienceIcon } from \"@webiny/icons/science.svg\";\nimport { useSelectFromEditor } from \"~/BaseEditor/hooks/useSelectFromEditor.js\";\nimport { ExperimentsSwitcher, type ExperimentItem } from \"./ExperimentsSwitcher.js\";\nimport { ExperimentIndicator } from \"./ExperimentIndicator.js\";\nimport { ExperimentsEditorPresenterFeature } from \"../feature.js\";\n\n/**\n * Top-bar entry point for A/B experiments.\n *\n * On an editable (draft) page it's a switcher for picking an experiment to edit; on a published\n * (read-only) page it's an indicator for the running experiment with a pause/resume kill-switch.\n * State is shared through the editor-wide presenter so the in-preview toolbar tracks the selection.\n */\nexport const ExperimentsButton = observer(function ExperimentsButton() {\n const { presenter } = useFeature(ExperimentsEditorPresenterFeature);\n const isReadOnly = useSelectFromEditor(state => state.isReadOnly);\n\n const { runningExperiment, switcherItems, selectedExperimentId } = presenter.vm;\n\n // On the published (read-only) view, surface the running experiment and keep it selected so the\n // preview toolbar tracks it. Forwards the editor read-only selector into the presenter.\n useEffect(() => {\n presenter.syncReadOnlySelection(isReadOnly);\n }, [presenter, isReadOnly, runningExperiment, selectedExperimentId]);\n\n if (isReadOnly) {\n if (!runningExperiment) {\n return null;\n }\n return (\n <div style={{ display: \"flex\" }}>\n <ExperimentIndicator experiment={runningExperiment} />\n </div>\n );\n }\n\n const items: ExperimentItem[] = switcherItems;\n\n return (\n <div style={{ display: \"flex\" }}>\n {items.length === 0 ? (\n <Button\n variant=\"secondary\"\n icon={<ScienceIcon />}\n text=\"Experiments\"\n onClick={() => presenter.openManage()}\n />\n ) : (\n <ExperimentsSwitcher\n experiments={items}\n selectedId={selectedExperimentId}\n onSelect={id => presenter.selectExperiment(id)}\n onManage={() => presenter.openManage()}\n />\n )}\n </div>\n );\n});\n"],"names":["ExperimentsButton","observer","presenter","useFeature","ExperimentsEditorPresenterFeature","isReadOnly","useSelectFromEditor","state","runningExperiment","switcherItems","selectedExperimentId","useEffect","ExperimentIndicator","items","Button","ScienceIcon","ExperimentsSwitcher","id"],"mappings":";;;;;;;;;AAiBO,MAAMA,sCAAoBC,SAAS;IACtC,MAAM,EAAEC,SAAS,EAAE,GAAGC,WAAWC;IACjC,MAAMC,aAAaC,oBAAoBC,CAAAA,QAASA,MAAM,UAAU;IAEhE,MAAM,EAAEC,iBAAiB,EAAEC,aAAa,EAAEC,oBAAoB,EAAE,GAAGR,UAAU,EAAE;IAI/ES,UAAU;QACNT,UAAU,qBAAqB,CAACG;IACpC,GAAG;QAACH;QAAWG;QAAYG;QAAmBE;KAAqB;IAEnE,IAAIL,YAAY;QACZ,IAAI,CAACG,mBACD,OAAO;QAEX,OAAO,WAAP,GACI,oBAAC;YAAI,OAAO;gBAAE,SAAS;YAAO;yBAC1B,oBAACI,qBAAmBA;YAAC,YAAYJ;;IAG7C;IAEA,MAAMK,QAA0BJ;IAEhC,OAAO,WAAP,GACI,oBAAC;QAAI,OAAO;YAAE,SAAS;QAAO;OACzBI,AAAiB,MAAjBA,MAAM,MAAM,GAAS,WAAJ,GACd,oBAACC,QAAMA;QACH,SAAQ;QACR,oBAAM,oBAACC,gBAAWA;QAClB,MAAK;QACL,SAAS,IAAMb,UAAU,UAAU;uBAGvC,oBAACc,qBAAmBA;QAChB,aAAaH;QACb,YAAYH;QACZ,UAAUO,CAAAA,KAAMf,UAAU,gBAAgB,CAACe;QAC3C,UAAU,IAAMf,UAAU,UAAU;;AAKxD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface ExperimentItem {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
status: "active" | "inactive";
|
|
6
|
+
}
|
|
7
|
+
interface Props {
|
|
8
|
+
experiments: ExperimentItem[];
|
|
9
|
+
selectedId: string | null;
|
|
10
|
+
onSelect: (id: string | null) => void;
|
|
11
|
+
onManage: () => void;
|
|
12
|
+
}
|
|
13
|
+
export declare const ExperimentsSwitcher: ({ experiments, selectedId, onSelect, onManage }: Props) => React.JSX.Element;
|
|
14
|
+
export {};
|