Skip to content

Commit

Permalink
fix: Clone of selective config causes global objects to be cloned. (#217
Browse files Browse the repository at this point in the history
)

Also fixed the partials to only show the add button after the list of partials loads.
  • Loading branch information
Zoramite committed Aug 10, 2021
1 parent 3ef5b15 commit 120af68
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 17 deletions.
16 changes: 16 additions & 0 deletions src/ts/editor/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {EVENT_SAVE} from './events';
import {GrowProjectType} from '../projectType/grow/growProjectType';
import {LiveEditorLabels} from './template';
import {ProjectTypeComponent} from '../projectType/projectType';
import cloneDeep from 'lodash.clonedeep';

/**
* Global configuration used by the selective editor fields.
Expand Down Expand Up @@ -130,3 +131,18 @@ export class LiveEditor {
this.state.setProjectType(projectType);
}
}

/**
* When using the selective configuration for different forms is uses a global
* configuration, but the individual selective editors may try to change the
* config since it is not immutable, so we need to deep copy the configuration
* while preserving the references to objects.
*/
export function cloneSelectiveConfig(
config: LiveEditorSelectiveEditorConfig
): LiveEditorSelectiveEditorConfig {
// TODO: Clone without cloning global key?
const newConfig = cloneDeep(config);
newConfig.global = config.global;
return newConfig;
}
9 changes: 6 additions & 3 deletions src/ts/editor/ui/modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {ApiError} from '../api';
import {BaseUI} from './index';
import {ListenersMixin} from '../../mixin/listeners';
import {UuidMixin} from '@blinkk/selective-edit/dist/mixins/uuid';
import cloneDeep from 'lodash.clonedeep';
import {LiveEditorSelectiveEditorConfig, cloneSelectiveConfig} from '../editor';
import {templateApiError} from './error';

/**
Expand Down Expand Up @@ -357,9 +357,12 @@ export class FormDialogModal extends DialogModal {
super(config);
this.config = config;
this.data = new DeepObject({});

// Clone to prevent shared values if editor changes config.
this.selective = new SelectiveEditor(
// Clone to prevent shared values if editor changes config.
cloneDeep(this.config.selectiveConfig)
cloneSelectiveConfig(
this.config.selectiveConfig as LiveEditorSelectiveEditorConfig
)
);

// When the project type is updated the selective editor changes.
Expand Down
9 changes: 7 additions & 2 deletions src/ts/editor/ui/parts/content/section.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ import {
html,
} from '@blinkk/selective-edit';
import {EditorState, StatePromiseKeys} from '../../../../editor/state';
import {
LiveEditorSelectiveEditorConfig,
cloneSelectiveConfig,
} from '../../../editor';
import {
ProjectTypeComponent,
updateSelectiveForProjectType,
} from '../../../../projectType/projectType';

import {DataStorage} from '../../../../utility/dataStorage';
import {LiveEditorAutoFields} from '../../../autoFields';
import cloneDeep from 'lodash.clonedeep';

export const STORAGE_CONTENT_SECTION = 'live.content.section';

Expand Down Expand Up @@ -48,7 +51,9 @@ export class ContentSectionPart extends BasePart implements UiPartComponent {
this.config = config;
this.selective = new SelectiveEditor(
// Clone to prevent shared values if editor changes config.
cloneDeep(this.config.selectiveConfig)
cloneSelectiveConfig(
this.config.selectiveConfig as LiveEditorSelectiveEditorConfig
)
);

// Override the autofields class.
Expand Down
22 changes: 14 additions & 8 deletions src/ts/editor/ui/parts/menu/site.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@ import {
IncludeExcludeFilter,
IncludeExcludeFilterConfig,
} from '../../../../utility/filter';
import {
LiveEditor,
LiveEditorSelectiveEditorConfig,
cloneSelectiveConfig,
} from '../../../editor';
import {MenuSectionPart, MenuSectionPartConfig} from './index';

import {DataStorage} from '../../../../utility/dataStorage';
import {EVENT_FILE_LOAD} from '../../../events';
import {LiveEditor} from '../../../editor';
import {RuleConfig} from '@blinkk/selective-edit/dist/selective/validationRules';
import {StatePromiseKeys} from '../../../state';
import cloneDeep from 'lodash.clonedeep';
import {repeat} from '@blinkk/selective-edit';
import {templateLoading} from '../../../template';

Expand Down Expand Up @@ -62,8 +65,9 @@ export class SitePart extends MenuSectionPart {
protected getOrCreateModalCopy(): FormDialogModal {
if (!this.config.editor.ui.partModals.modals[MODAL_KEY_COPY]) {
// Clone to prevent shared values if editor changes config.
const selectiveConfig = cloneDeep(
this.config.editor.config.selectiveConfig
const selectiveConfig = cloneSelectiveConfig(
this.config.editor.config
.selectiveConfig as LiveEditorSelectiveEditorConfig
);
const modal = new FormDialogModal({
title: 'Copy file',
Expand Down Expand Up @@ -121,8 +125,9 @@ export class SitePart extends MenuSectionPart {
protected getOrCreateModalDelete(): FormDialogModal {
if (!this.config.editor.ui.partModals.modals[MODAL_KEY_DELETE]) {
// Clone to prevent shared values if editor changes config.
const selectiveConfig = cloneDeep(
this.config.editor.config.selectiveConfig
const selectiveConfig = cloneSelectiveConfig(
this.config.editor.config
.selectiveConfig as LiveEditorSelectiveEditorConfig
);
const modal = new FormDialogModal({
title: 'Delete file',
Expand Down Expand Up @@ -172,8 +177,9 @@ export class SitePart extends MenuSectionPart {
protected getOrCreateModalNew(): FormDialogModal {
if (!this.config.editor.ui.partModals.modals[MODAL_KEY_NEW]) {
// Clone to prevent shared values if editor changes config.
const selectiveConfig = cloneDeep(
this.config.editor.config.selectiveConfig
const selectiveConfig = cloneSelectiveConfig(
this.config.editor.config
.selectiveConfig as LiveEditorSelectiveEditorConfig
);
const modal = new FormDialogModal({
title: 'New file',
Expand Down
11 changes: 9 additions & 2 deletions src/ts/editor/ui/parts/menu/workspaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ import {
html,
} from '@blinkk/selective-edit';
import {DialogActionLevel, FormDialogModal} from '../../modal';
import {
LiveEditorSelectiveEditorConfig,
cloneSelectiveConfig,
} from '../../../editor';
import {MenuSectionPart, MenuSectionPartConfig} from './index';

import {EVENT_WORKSPACE_LOAD} from '../../../events';
import {FeatureFlags} from '../../../features';
import cloneDeep from 'lodash.clonedeep';
import merge from 'lodash.merge';
import {repeat} from '@blinkk/selective-edit';
import {templateLoading} from '../../../template';
Expand Down Expand Up @@ -60,7 +64,10 @@ export class WorkspacesPart extends MenuSectionPart {
const selectiveConfig = merge(
{},
// Clone to prevent shared values if editor changes config.
cloneDeep(this.config.editor.config.selectiveConfig),
cloneSelectiveConfig(
this.config.editor.config
.selectiveConfig as LiveEditorSelectiveEditorConfig
),
{
fields: [
{
Expand Down
10 changes: 8 additions & 2 deletions src/ts/editor/ui/parts/overview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@ import {
repeat,
} from '@blinkk/selective-edit';
import {DialogActionLevel, FormDialogModal} from '../modal';
import {
LiveEditorSelectiveEditorConfig,
cloneSelectiveConfig,
} from '../../editor';
import {exampleIcon, githubIcon, localIcon} from '../icons';

import {EVENT_WORKSPACE_LOAD} from '../../events';
import {EditorState} from '../../state';
import {FieldConfig} from '@blinkk/selective-edit/dist/selective/field';
import {NotificationAction} from './notifications';
import TimeAgo from 'javascript-time-ago';
import cloneDeep from 'lodash.clonedeep';
import merge from 'lodash.merge';

const MODAL_KEY_PUBLISH = 'overview_publish';
Expand Down Expand Up @@ -53,7 +56,10 @@ export class OverviewPart extends BasePart implements UiPartComponent {
const selectiveConfig = merge(
{},
// Clone to prevent shared values if editor changes config.
cloneDeep(this.config.editor.config.selectiveConfig),
cloneSelectiveConfig(
this.config.editor.config
.selectiveConfig as LiveEditorSelectiveEditorConfig
),
{
fields: fields,
}
Expand Down
8 changes: 8 additions & 0 deletions src/ts/projectType/generic/field/partials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,14 @@ export class GenericPartialsField
throw new Error('Not implemented.');
}

templateFooter(editor: SelectiveEditor, data: DeepObject): TemplateResult {
if (!this.partials) {
return html``;
}

return super.templateFooter(editor, data);
}

templateInput(editor: SelectiveEditor, data: DeepObject): TemplateResult {
// While waiting for the partials config show the loading indicator.
if (!this.partials) {
Expand Down

0 comments on commit 120af68

Please sign in to comment.