Skip to content

Commit

Permalink
ENH Add campaign-admin support back in
Browse files Browse the repository at this point in the history
  • Loading branch information
emteknetnz committed Mar 6, 2025
1 parent a2c83d2 commit c066f14
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 16 deletions.
2 changes: 1 addition & 1 deletion client/dist/js/TinyMCE_sslink-file.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/dist/js/TinyMCE_ssmedia.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/dist/js/bundle.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions client/src/containers/AssetAdmin/AssetAdmin.js
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,7 @@ class AssetAdmin extends Component {
onClose: this.handleCloseFile,
onSubmit: this.handleSubmitEditor,
onUnpublish: this.handleUnpublish,
addToCampaignSchemaUrl: config.form.addToCampaignForm.schemaUrl
};

return <EditorComponent {...editorProps} />;
Expand Down
3 changes: 3 additions & 0 deletions client/src/containers/AssetAdmin/tests/AssetAdmin-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ function makeProps(obj = {}) {
fileSearchForm: {
schemaUrl: '',
},
addToCampaignForm: {
schemaUrl: '',
},
},
},
fileId: null,
Expand Down
36 changes: 35 additions & 1 deletion client/src/containers/Editor/Editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { bindActionCreators, compose } from 'redux';
import React, { Component } from 'react';
import CONSTANTS from 'constants/index';
import FormBuilderLoader from 'containers/FormBuilderLoader/FormBuilderLoader';
import FormBuilderModal from 'components/FormBuilderModal/FormBuilderModal';
import * as UnsavedFormsActions from 'state/unsavedForms/UnsavedFormsActions';
import PropTypes from 'prop-types';
import { inject } from 'lib/Injector';
Expand All @@ -31,10 +32,13 @@ class Editor extends Component {
this.handleLoadingSuccess = this.handleLoadingSuccess.bind(this);
this.handleLoadingError = this.handleLoadingError.bind(this);
this.handleFetchingSchema = this.handleFetchingSchema.bind(this);
this.closeModal = this.closeModal.bind(this);
this.openModal = this.openModal.bind(this);
this.createFn = this.createFn.bind(this);
this.editorHeader = this.editorHeader.bind(this);

this.state = {
openModal: false,
loadingForm: false,
loadingError: null,
file: null,
Expand Down Expand Up @@ -87,6 +91,12 @@ class Editor extends Component {
handleAction(event) {
const file = this.state.file;
switch (event.currentTarget.name) {
// intercept the Add to Campaign submit and open the modal dialog instead
case 'action_addtocampaign':
this.openModal();
event.preventDefault();

break;
case 'action_replacefile':
this.replaceFile();
event.preventDefault();
Expand Down Expand Up @@ -152,13 +162,22 @@ class Editor extends Component {
} else {
// If we're already at the top of the form stack, close the editor form
onClose();
this.closeModal();
}

if (event) {
event.preventDefault();
}
}

openModal() {
this.setState({ openModal: true });
}

closeModal() {
this.setState({ openModal: false });
}

replaceFile() {
const hiddenFileInput = document.querySelector('.dz-input-PreviewImage');

Expand Down Expand Up @@ -270,8 +289,9 @@ class Editor extends Component {
if (!this.state.file) {
return null;
}
const { FormBuilderLoaderComponent } = this.props;
const { FormBuilderLoaderComponent, FormBuilderModalComponent } = this.props;
const formSchemaUrl = this.getFormSchemaUrl();
const modalSchemaUrl = `${this.props.addToCampaignSchemaUrl}/${this.props.fileId}`;
const editorClasses = classnames(
'panel', 'form--no-dividers', 'editor', {
'editor--asset-dropzone--disable': !this.props.enableDropzone
Expand All @@ -291,6 +311,7 @@ class Editor extends Component {
<div className="editor__file-preview-message--file-missing">{message}</div>
);
}
const campaignTitle = i18n._t('Admin.ADD_TO_CAMPAIGN', 'Add to campaign');
const Loading = this.props.loadingComponent;

return (<div className={editorClasses}>
Expand All @@ -307,6 +328,16 @@ class Editor extends Component {
file={this.state.file}
/>
{error}
<FormBuilderModalComponent
title={campaignTitle}
identifier="AssetAdmin.AddToCampaign"
isOpen={this.state.openModal}
onClosed={this.closeModal}
schemaUrl={modalSchemaUrl}
bodyClassName="modal__dialog"
responseClassBad="modal__response modal__response--error"
responseClassGood="modal__response modal__response--good"
/>
{ this.state.loadingForm && <Loading />}
</div>
</div>);
Expand All @@ -325,16 +356,19 @@ Editor.propTypes = {
name: PropTypes.string,
value: PropTypes.any,
})),
addToCampaignSchemaUrl: PropTypes.string,
actions: PropTypes.object,
showingSubForm: PropTypes.bool,
nextType: PropTypes.string,
EditorHeaderComponent: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
FormBuilderLoaderComponent: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
FormBuilderModalComponent: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
};

Editor.defaultProps = {
EditorHeaderComponent: EditorHeader,
FormBuilderLoaderComponent: FormBuilderLoader,
FormBuilderModalComponent: FormBuilderModal,
};

function mapDispatchToProps(dispatch) {
Expand Down
36 changes: 26 additions & 10 deletions client/src/containers/Editor/tests/Editor-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,20 @@ function makeProps(obj = {}) {
FormBuilderLoaderComponent: ({ createFn, onAction, schemaUrl }) => (
<div data-testid="test-form-builder-loader" onClick={() => onAction(...nextParams)} data-schema-url={schemaUrl}>{createFn(...createFnParams)}</div>
),
FormBuilderModalComponent: ({ isOpen }) => <div data-testid="test-form-builder-modal" data-is-open={isOpen}/>,
...obj
};
}

async function awaitLoader() {
await screen.findByTestId('test-form-builder-loader');
async function openModal() {
const loader = await screen.findByTestId('test-form-builder-loader');
nextParams = [{
preventDefault: () => null,
currentTarget: {
name: 'action_addtocampaign'
}
}];
fireEvent.click(loader);
nextParams = [{
preventDefault: () => null,
currentTarget: {
Expand All @@ -109,12 +117,16 @@ test('Editor handleClose Closing editor', async () => {
/>
);
resolveBackendGet(makeReadFileResponse());
awaitLoader();
openModal();
let modal = await screen.findByTestId('test-form-builder-modal');
expect(modal.getAttribute('data-is-open')).toBe('true');
const header = await screen.findByTestId('test-editor-header');
nextAction = 'cancel';
fireEvent.click(header);
expect(popFormStackEntry).not.toHaveBeenCalled();
expect(onClose).toHaveBeenCalled();
modal = await screen.findByTestId('test-form-builder-modal');
expect(modal.getAttribute('data-is-open')).toBe('false');
expect(header.getAttribute('data-show-button')).toBe(buttonStates.SWITCH);
});

Expand All @@ -135,12 +147,16 @@ test('Editor handleClose Closing sub form', async () => {
/>
);
resolveBackendGet(makeReadFileResponse());
awaitLoader();
openModal();
let modal = await screen.findByTestId('test-form-builder-modal');
expect(modal.getAttribute('data-is-open')).toBe('true');
const header = await screen.findByTestId('test-editor-header');
nextAction = 'cancel';
fireEvent.click(header);
expect(popFormStackEntry).toHaveBeenCalled();
expect(onClose).not.toHaveBeenCalled();
modal = await screen.findByTestId('test-form-builder-modal');
expect(modal.getAttribute('data-is-open')).toBe('true');
expect(header.getAttribute('data-show-button')).toBe(buttonStates.SWITCH);
});

Expand Down Expand Up @@ -173,7 +189,7 @@ test('Editor editorHeader Top Form with detail in dialog', async () => {
/>
);
resolveBackendGet(makeReadFileResponse());
awaitLoader();
openModal();
const header = await screen.findByTestId('test-editor-header');
nextAction = 'details';
fireEvent.click(header);
Expand All @@ -192,7 +208,7 @@ test('Editor editorHeader Sub form in dialog', async () => {
/>
);
resolveBackendGet(makeReadFileResponse());
awaitLoader();
openModal();
const header = await screen.findByTestId('test-editor-header');
expect(header.getAttribute('data-show-button')).toBe(buttonStates.ALWAYS_BACK);
});
Expand All @@ -212,7 +228,7 @@ test('Editor editorHeader Form for folder', async () => {
type: 'folder',
})
});
awaitLoader();
openModal();
const header = await screen.findByTestId('test-editor-header');
expect(header.getAttribute('data-show-button')).toBe(buttonStates.SWITCH);
});
Expand All @@ -226,7 +242,7 @@ test('Editor getFormSchemaUrl Plain URL', async () => {
/>
);
resolveBackendGet(makeReadFileResponse());
awaitLoader();
openModal();
const loader = await screen.findByTestId('test-form-builder-loader');
expect(loader.getAttribute('data-schema-url')).toBe('edit/file/123');
});
Expand All @@ -240,7 +256,7 @@ test('Editor getFormSchemaUrl Plain URL', async () => {
/>
);
resolveBackendGet(makeReadFileResponse());
awaitLoader();
openModal();
const loader = await screen.findByTestId('test-form-builder-loader');
expect(loader.getAttribute('data-schema-url')).toBe('edit/file/123?q=search');
});
Expand All @@ -257,7 +273,7 @@ test('Editor getFormSchemaUrl Plain URL', async () => {
/>
);
resolveBackendGet(makeReadFileResponse());
awaitLoader();
openModal();
const loader = await screen.findByTestId('test-form-builder-loader');
expect(loader.getAttribute('data-schema-url')).toBe('edit/file/123?q=search&foo=bar');
});
2 changes: 2 additions & 0 deletions code/Controller/AssetAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace SilverStripe\AssetAdmin\Controller;

use Exception;
use RuntimeException;
use InvalidArgumentException;
use SilverStripe\Admin\CMSBatchActionHandler;
use SilverStripe\Admin\LeftAndMain;
Expand All @@ -24,6 +25,7 @@
use SilverStripe\Assets\Image;
use SilverStripe\Assets\Storage\AssetNameGenerator;
use SilverStripe\Assets\Upload;
use SilverStripe\CampaignAdmin\AddToCampaignHandler;
use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\HTTPResponse;
Expand Down
48 changes: 46 additions & 2 deletions tests/php/Forms/FileFormBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use SilverStripe\Core\Config\Config;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Forms\LiteralField;
use SilverStripe\CampaignAdmin\Extensions\FileFormFactoryExtension;

class FileFormBuilderTest extends SapphireTest
{
Expand Down Expand Up @@ -51,6 +52,9 @@ protected function tearDown(): void

public function testEditFileForm()
{
// Ensure campaign-admin extension is not applied!
Config::modify()->remove(FileFormFactory::class, 'extensions');

$this->logInWithPermission('ADMIN');

$file = $this->objFromFixture(File::class, 'file1');
Expand Down Expand Up @@ -91,14 +95,37 @@ public function testEditFileForm()
$this->assertNotNull($form->Actions()->fieldByName('PopoverActions.action_replacefile'));
$this->assertNotNull($form->Actions()->fieldByName('PopoverActions.action_delete'));
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_unpublish'));

if (class_exists(FileFormFactoryExtension::class)) {
// Add to campaign should not be there by default
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_addtocampaign'));

// Add extension for campaign-admin
Config::modify()->merge(
FileFormFactory::class,
'extensions',
[FileFormFactoryExtension::class]
);

$builder = new FileFormFactory();
$form = $builder->getForm($controller, 'EditForm', ['Record' => $file, 'RequireLinkText' => false]);

// Add to campaign should now be available
$this->assertNotNull($form->Actions()->fieldByName('PopoverActions.action_addtocampaign'));
}
}

public function testEditFileFormWithPermissions()
{
// Add extension to simulate different permissions
File::add_extension(FileExtension::class);

$this->logInWithPermission('CMS_ACCESS_AssetAdmin');
if (class_exists(FileFormFactoryExtension::class)) {
FileFormFactory::add_extension(FileFormFactoryExtension::class);
$this->logInWithPermission('CMS_ACCESS_CampaignAdmin');
} else {
$this->logInWithPermission('CMS_ACCESS_AssetAdmin');
}

/** @var File $file */
$file = $this->objFromFixture(File::class, 'file1');
Expand All @@ -112,7 +139,9 @@ public function testEditFileFormWithPermissions()
$this->assertNull($form->Actions()->fieldByName('PopoverActions'));
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_delete'));
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_replacefile'));

if (class_exists(FileFormFactoryExtension::class)) {
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_addtocampaign'));
}
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_unpublish'));

FileExtension::$canDelete = false;
Expand All @@ -121,6 +150,9 @@ public function testEditFileFormWithPermissions()
$form = $builder->getForm($controller, 'EditForm', ['Record' => $file, 'RequireLinkText' => false]);
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_delete'));
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_replacefile'));
if (class_exists(FileFormFactoryExtension::class)) {
$this->assertNotNull($form->Actions()->fieldByName('PopoverActions.action_addtocampaign'));
}
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_unpublish'));

FileExtension::$canDelete = true;
Expand All @@ -129,6 +161,9 @@ public function testEditFileFormWithPermissions()
$form = $builder->getForm($controller, 'EditForm', ['Record' => $file]);
$this->assertNotNull($form->Actions()->fieldByName('PopoverActions.action_delete'));
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_replacefile'));
if (class_exists(FileFormFactoryExtension::class)) {
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_addtocampaign'));
}
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_unpublish'));

FileExtension::$canDelete = false;
Expand All @@ -137,6 +172,9 @@ public function testEditFileFormWithPermissions()
$form = $builder->getForm($controller, 'EditForm', ['Record' => $file]);
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_delete'));
$this->assertNotNull($form->Actions()->fieldByName('PopoverActions.action_replacefile'));
if (class_exists(FileFormFactoryExtension::class)) {
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_addtocampaign'));
}
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_unpublish'));

FileExtension::$canDelete = true;
Expand All @@ -147,8 +185,14 @@ public function testEditFileFormWithPermissions()
$form = $builder->getForm($controller, 'EditForm', ['Record' => $file, 'RequireLinkText' => false]);
$this->assertNotNull($form->Actions()->fieldByName('PopoverActions.action_delete'));
$this->assertNotNull($form->Actions()->fieldByName('PopoverActions.action_replacefile'));
if (class_exists(FileFormFactoryExtension::class)) {
$this->assertNotNull($form->Actions()->fieldByName('PopoverActions.action_addtocampaign'));
}
$this->assertNotNull($form->Actions()->fieldByName('PopoverActions.action_unpublish'));

if (class_exists(FileFormFactoryExtension::class)) {
FileFormFactory::remove_extension(FileFormFactoryExtension::class);
}
File::remove_extension(FileExtension::class);
}

Expand Down
3 changes: 3 additions & 0 deletions tests/php/Forms/FolderCreateFormFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ class FolderCreateFormFactoryTest extends SapphireTest
{
public function testEditFileForm()
{
// Ensure campaign-admin extension is not applied!
Config::modify()->remove(FileFormFactory::class, 'extensions');

$this->logInWithPermission('ADMIN');

$controller = new AssetAdmin();
Expand Down

0 comments on commit c066f14

Please sign in to comment.