Skip to content

Commit 4ac4ae8

Browse files
Merge pull request #1548 from creative-commoners/pulls/3.0/campaign-admin
ENH Add campaign-admin support back in
2 parents a2c83d2 + 13e535f commit 4ac4ae8

File tree

10 files changed

+76
-16
lines changed

10 files changed

+76
-16
lines changed

client/dist/js/TinyMCE_sslink-file.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/dist/js/TinyMCE_ssmedia.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/dist/js/bundle.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/src/containers/AssetAdmin/AssetAdmin.js

+1
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,7 @@ class AssetAdmin extends Component {
742742
onClose: this.handleCloseFile,
743743
onSubmit: this.handleSubmitEditor,
744744
onUnpublish: this.handleUnpublish,
745+
addToCampaignSchemaUrl: config.form.addToCampaignForm.schemaUrl
745746
};
746747

747748
return <EditorComponent {...editorProps} />;

client/src/containers/AssetAdmin/tests/AssetAdmin-test.js

+3
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ function makeProps(obj = {}) {
142142
fileSearchForm: {
143143
schemaUrl: '',
144144
},
145+
addToCampaignForm: {
146+
schemaUrl: '',
147+
},
145148
},
146149
},
147150
fileId: null,

client/src/containers/Editor/Editor.js

+35-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { bindActionCreators, compose } from 'redux';
55
import React, { Component } from 'react';
66
import CONSTANTS from 'constants/index';
77
import FormBuilderLoader from 'containers/FormBuilderLoader/FormBuilderLoader';
8+
import FormBuilderModal from 'components/FormBuilderModal/FormBuilderModal';
89
import * as UnsavedFormsActions from 'state/unsavedForms/UnsavedFormsActions';
910
import PropTypes from 'prop-types';
1011
import { inject } from 'lib/Injector';
@@ -31,10 +32,13 @@ class Editor extends Component {
3132
this.handleLoadingSuccess = this.handleLoadingSuccess.bind(this);
3233
this.handleLoadingError = this.handleLoadingError.bind(this);
3334
this.handleFetchingSchema = this.handleFetchingSchema.bind(this);
35+
this.closeModal = this.closeModal.bind(this);
36+
this.openModal = this.openModal.bind(this);
3437
this.createFn = this.createFn.bind(this);
3538
this.editorHeader = this.editorHeader.bind(this);
3639

3740
this.state = {
41+
openModal: false,
3842
loadingForm: false,
3943
loadingError: null,
4044
file: null,
@@ -87,6 +91,12 @@ class Editor extends Component {
8791
handleAction(event) {
8892
const file = this.state.file;
8993
switch (event.currentTarget.name) {
94+
// intercept the Add to Campaign submit and open the modal dialog instead
95+
case 'action_addtocampaign':
96+
this.openModal();
97+
event.preventDefault();
98+
99+
break;
90100
case 'action_replacefile':
91101
this.replaceFile();
92102
event.preventDefault();
@@ -152,13 +162,22 @@ class Editor extends Component {
152162
} else {
153163
// If we're already at the top of the form stack, close the editor form
154164
onClose();
165+
this.closeModal();
155166
}
156167

157168
if (event) {
158169
event.preventDefault();
159170
}
160171
}
161172

173+
openModal() {
174+
this.setState({ openModal: true });
175+
}
176+
177+
closeModal() {
178+
this.setState({ openModal: false });
179+
}
180+
162181
replaceFile() {
163182
const hiddenFileInput = document.querySelector('.dz-input-PreviewImage');
164183

@@ -270,8 +289,9 @@ class Editor extends Component {
270289
if (!this.state.file) {
271290
return null;
272291
}
273-
const { FormBuilderLoaderComponent } = this.props;
292+
const { FormBuilderLoaderComponent, FormBuilderModalComponent } = this.props;
274293
const formSchemaUrl = this.getFormSchemaUrl();
294+
const modalSchemaUrl = `${this.props.addToCampaignSchemaUrl}/${this.props.fileId}`;
275295
const editorClasses = classnames(
276296
'panel', 'form--no-dividers', 'editor', {
277297
'editor--asset-dropzone--disable': !this.props.enableDropzone
@@ -291,6 +311,7 @@ class Editor extends Component {
291311
<div className="editor__file-preview-message--file-missing">{message}</div>
292312
);
293313
}
314+
const campaignTitle = i18n._t('Admin.ADD_TO_CAMPAIGN', 'Add to campaign');
294315
const Loading = this.props.loadingComponent;
295316

296317
return (<div className={editorClasses}>
@@ -307,6 +328,16 @@ class Editor extends Component {
307328
file={this.state.file}
308329
/>
309330
{error}
331+
<FormBuilderModalComponent
332+
title={campaignTitle}
333+
identifier="AssetAdmin.AddToCampaign"
334+
isOpen={this.state.openModal}
335+
onClosed={this.closeModal}
336+
schemaUrl={modalSchemaUrl}
337+
bodyClassName="modal__dialog"
338+
responseClassBad="modal__response modal__response--error"
339+
responseClassGood="modal__response modal__response--good"
340+
/>
310341
{ this.state.loadingForm && <Loading />}
311342
</div>
312343
</div>);
@@ -325,16 +356,19 @@ Editor.propTypes = {
325356
name: PropTypes.string,
326357
value: PropTypes.any,
327358
})),
359+
addToCampaignSchemaUrl: PropTypes.string,
328360
actions: PropTypes.object,
329361
showingSubForm: PropTypes.bool,
330362
nextType: PropTypes.string,
331363
EditorHeaderComponent: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
332364
FormBuilderLoaderComponent: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
365+
FormBuilderModalComponent: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
333366
};
334367

335368
Editor.defaultProps = {
336369
EditorHeaderComponent: EditorHeader,
337370
FormBuilderLoaderComponent: FormBuilderLoader,
371+
FormBuilderModalComponent: FormBuilderModal,
338372
};
339373

340374
function mapDispatchToProps(dispatch) {

client/src/containers/Editor/tests/Editor-test.js

+26-10
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,20 @@ function makeProps(obj = {}) {
7878
FormBuilderLoaderComponent: ({ createFn, onAction, schemaUrl }) => (
7979
<div data-testid="test-form-builder-loader" onClick={() => onAction(...nextParams)} data-schema-url={schemaUrl}>{createFn(...createFnParams)}</div>
8080
),
81+
FormBuilderModalComponent: ({ isOpen }) => <div data-testid="test-form-builder-modal" data-is-open={isOpen}/>,
8182
...obj
8283
};
8384
}
8485

85-
async function awaitLoader() {
86-
await screen.findByTestId('test-form-builder-loader');
86+
async function openModal() {
87+
const loader = await screen.findByTestId('test-form-builder-loader');
88+
nextParams = [{
89+
preventDefault: () => null,
90+
currentTarget: {
91+
name: 'action_addtocampaign'
92+
}
93+
}];
94+
fireEvent.click(loader);
8795
nextParams = [{
8896
preventDefault: () => null,
8997
currentTarget: {
@@ -109,12 +117,16 @@ test('Editor handleClose Closing editor', async () => {
109117
/>
110118
);
111119
resolveBackendGet(makeReadFileResponse());
112-
awaitLoader();
120+
openModal();
121+
let modal = await screen.findByTestId('test-form-builder-modal');
122+
expect(modal.getAttribute('data-is-open')).toBe('true');
113123
const header = await screen.findByTestId('test-editor-header');
114124
nextAction = 'cancel';
115125
fireEvent.click(header);
116126
expect(popFormStackEntry).not.toHaveBeenCalled();
117127
expect(onClose).toHaveBeenCalled();
128+
modal = await screen.findByTestId('test-form-builder-modal');
129+
expect(modal.getAttribute('data-is-open')).toBe('false');
118130
expect(header.getAttribute('data-show-button')).toBe(buttonStates.SWITCH);
119131
});
120132

@@ -135,12 +147,16 @@ test('Editor handleClose Closing sub form', async () => {
135147
/>
136148
);
137149
resolveBackendGet(makeReadFileResponse());
138-
awaitLoader();
150+
openModal();
151+
let modal = await screen.findByTestId('test-form-builder-modal');
152+
expect(modal.getAttribute('data-is-open')).toBe('true');
139153
const header = await screen.findByTestId('test-editor-header');
140154
nextAction = 'cancel';
141155
fireEvent.click(header);
142156
expect(popFormStackEntry).toHaveBeenCalled();
143157
expect(onClose).not.toHaveBeenCalled();
158+
modal = await screen.findByTestId('test-form-builder-modal');
159+
expect(modal.getAttribute('data-is-open')).toBe('true');
144160
expect(header.getAttribute('data-show-button')).toBe(buttonStates.SWITCH);
145161
});
146162

@@ -173,7 +189,7 @@ test('Editor editorHeader Top Form with detail in dialog', async () => {
173189
/>
174190
);
175191
resolveBackendGet(makeReadFileResponse());
176-
awaitLoader();
192+
openModal();
177193
const header = await screen.findByTestId('test-editor-header');
178194
nextAction = 'details';
179195
fireEvent.click(header);
@@ -192,7 +208,7 @@ test('Editor editorHeader Sub form in dialog', async () => {
192208
/>
193209
);
194210
resolveBackendGet(makeReadFileResponse());
195-
awaitLoader();
211+
openModal();
196212
const header = await screen.findByTestId('test-editor-header');
197213
expect(header.getAttribute('data-show-button')).toBe(buttonStates.ALWAYS_BACK);
198214
});
@@ -212,7 +228,7 @@ test('Editor editorHeader Form for folder', async () => {
212228
type: 'folder',
213229
})
214230
});
215-
awaitLoader();
231+
openModal();
216232
const header = await screen.findByTestId('test-editor-header');
217233
expect(header.getAttribute('data-show-button')).toBe(buttonStates.SWITCH);
218234
});
@@ -226,7 +242,7 @@ test('Editor getFormSchemaUrl Plain URL', async () => {
226242
/>
227243
);
228244
resolveBackendGet(makeReadFileResponse());
229-
awaitLoader();
245+
openModal();
230246
const loader = await screen.findByTestId('test-form-builder-loader');
231247
expect(loader.getAttribute('data-schema-url')).toBe('edit/file/123');
232248
});
@@ -240,7 +256,7 @@ test('Editor getFormSchemaUrl Plain URL', async () => {
240256
/>
241257
);
242258
resolveBackendGet(makeReadFileResponse());
243-
awaitLoader();
259+
openModal();
244260
const loader = await screen.findByTestId('test-form-builder-loader');
245261
expect(loader.getAttribute('data-schema-url')).toBe('edit/file/123?q=search');
246262
});
@@ -257,7 +273,7 @@ test('Editor getFormSchemaUrl Plain URL', async () => {
257273
/>
258274
);
259275
resolveBackendGet(makeReadFileResponse());
260-
awaitLoader();
276+
openModal();
261277
const loader = await screen.findByTestId('test-form-builder-loader');
262278
expect(loader.getAttribute('data-schema-url')).toBe('edit/file/123?q=search&foo=bar');
263279
});

code/Controller/AssetAdmin.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
use SilverStripe\ORM\DataList;
4848
use SilverStripe\Forms\DateField;
4949
use SilverStripe\ORM\DataQuery;
50+
use SilverStripe\Core\ArrayLib;
5051

5152
/**
5253
* AssetAdmin is the 'file store' section of the CMS.
@@ -212,7 +213,7 @@ public function getClientConfig(): array
212213

213214
$parentClientConfig = parent::getClientConfig();
214215
$modalController = ModalController::singleton();
215-
return array_merge($parentClientConfig, [
216+
return ArrayLib::array_merge_recursive($parentClientConfig, [
216217
'reactRouter' => true,
217218
'bustCache' => static::config()->get('bust_cache'),
218219
'endpoints' => array_merge($parentClientConfig['endpoints'], [

tests/php/Forms/FileFormBuilderTest.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ protected function tearDown(): void
5151

5252
public function testEditFileForm()
5353
{
54+
// Ensure no external extensions have been applied
55+
Config::modify()->remove(FileFormFactory::class, 'extensions');
56+
5457
$this->logInWithPermission('ADMIN');
5558

5659
$file = $this->objFromFixture(File::class, 'file1');
@@ -112,7 +115,6 @@ public function testEditFileFormWithPermissions()
112115
$this->assertNull($form->Actions()->fieldByName('PopoverActions'));
113116
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_delete'));
114117
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_replacefile'));
115-
116118
$this->assertNull($form->Actions()->fieldByName('PopoverActions.action_unpublish'));
117119

118120
FileExtension::$canDelete = false;

tests/php/Forms/FolderCreateFormFactoryTest.php

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ class FolderCreateFormFactoryTest extends SapphireTest
1313
{
1414
public function testEditFileForm()
1515
{
16+
// Ensure no external extensions have been applied
17+
Config::modify()->remove(FileFormFactory::class, 'extensions');
18+
1619
$this->logInWithPermission('ADMIN');
1720

1821
$controller = new AssetAdmin();

0 commit comments

Comments
 (0)