enhancement(media-library-uploadcare): add integration settings to control url operations (#2670)

This commit is contained in:
Aleksandr Grenishin 2019-10-28 21:14:42 +03:00 committed by Shawn Erquhart
parent 5636f5f54c
commit 574477adca
3 changed files with 166 additions and 15 deletions

View File

@ -51,9 +51,10 @@ describe('uploadcare media library', () => {
/**
* Mock to manually call the close dialog registered callback.
*/
simulateCloseDialog = result =>
simulateCloseDialog = (result, files) =>
openDialogCallback({
promise: () => Promise.resolve(result),
...(files ? { files: () => files.map(file => Promise.resolve(file)) } : {}),
});
/**
@ -90,7 +91,7 @@ Object {
});
});
describe('configuration', () => {
describe('widget configuration', () => {
const options = {
config: {
foo: 'bar',
@ -179,13 +180,106 @@ Object {
options.config.multiple = true;
const { result, cdnUrl } = generateMockUrl({ count: 3, cdnUrl: true });
const mockDialogCloseResult = { cdnUrl, count: 3 };
const mockDialogCloseFiles = result.map((cdnUrl, idx) => ({
cdnUrl,
isImage: true,
name: `test${idx}.png`,
}));
const integration = await uploadcareMediaLibrary.init({ options, handleInsert });
await integration.show();
await simulateCloseDialog(mockDialogCloseResult);
await simulateCloseDialog(mockDialogCloseResult, mockDialogCloseFiles);
expect(handleInsert).toHaveBeenCalledWith(result);
});
});
describe('settings', () => {
describe('defaultOperations', () => {
it('should append specified string to the url', async () => {
const options = {
config: {
publicKey: TEST_PUBLIC_KEY,
},
settings: {
defaultOperations: '/preview/',
},
};
const url = generateMockUrl();
const mockResult = { cdnUrl: url, isImage: true };
const integration = await uploadcareMediaLibrary.init({
options,
handleInsert,
});
await integration.show();
await simulateCloseDialog(mockResult);
expect(handleInsert).toHaveBeenCalledWith(url + '-/preview/');
});
it('should work along with `autoFilename` setting enabled', async () => {
const options = {
config: {
publicKey: TEST_PUBLIC_KEY,
},
settings: {
autoFilename: true,
defaultOperations: '/preview/',
},
};
const url = generateMockUrl();
const mockResult = { cdnUrl: url, isImage: true, name: 'test.png' };
const integration = await uploadcareMediaLibrary.init({
options,
handleInsert,
});
await integration.show();
await simulateCloseDialog(mockResult);
expect(handleInsert).toHaveBeenCalledWith(url + '-/preview/test.png');
});
it('should overwrite filename with `autoFilename` setting enabled', async () => {
const options = {
config: {
publicKey: TEST_PUBLIC_KEY,
},
settings: {
autoFilename: true,
defaultOperations: '/preview/another_name.png',
},
};
const url = generateMockUrl();
const mockResult = { cdnUrl: url, isImage: true, name: 'test.png' };
const integration = await uploadcareMediaLibrary.init({
options,
handleInsert,
});
await integration.show();
await simulateCloseDialog(mockResult);
expect(handleInsert).toHaveBeenCalledWith(url + '-/preview/another_name.png');
});
});
describe('autoFilename', () => {
it('should append filename to the url', async () => {
const options = {
config: {
publicKey: TEST_PUBLIC_KEY,
},
settings: {
autoFilename: true,
},
};
const url = generateMockUrl();
const mockResult = { cdnUrl: url, isImage: true, name: 'test.png' };
const integration = await uploadcareMediaLibrary.init({
options,
handleInsert,
});
await integration.show();
await simulateCloseDialog(mockResult);
expect(handleInsert).toHaveBeenCalledWith(url + 'test.png');
});
});
});
describe('enableStandalone method', () => {
it('returns false', async () => {
const integration = await uploadcareMediaLibrary.init();

View File

@ -73,24 +73,47 @@ function getFile(url) {
* Open the standalone dialog. A single instance is created and destroyed for
* each use.
*/
function openDialog(files, config, handleInsert) {
uploadcare.openDialog(files, config).done(({ promise }) =>
promise().then(({ cdnUrl, count }) => {
if (config.multiple) {
const urls = Array.from({ length: count }, (val, idx) => `${cdnUrl}nth/${idx}/`);
handleInsert(urls);
function openDialog({ files, config, handleInsert, settings = {} }) {
if (settings.defaultOperations && !settings.defaultOperations.startsWith('/')) {
console.warn(
'Uploadcare default operations should start with `/`. Example: `/preview/-/resize/100x100/image.png`',
);
}
const buildUrl = fileInfo => {
const { cdnUrl, name, isImage } = fileInfo;
let url =
isImage && settings.defaultOperations ? `${cdnUrl}-${settings.defaultOperations}` : cdnUrl;
const filenameDefined = !url.endsWith('/');
if (!filenameDefined && settings.autoFilename) {
url = url + name;
}
return url;
};
uploadcare.openDialog(files, config).done(({ promise, files }) => {
const isGroup = Boolean(files);
return promise().then(info => {
if (isGroup) {
return Promise.all(
files().map(promise => promise.then(fileInfo => buildUrl(fileInfo))),
).then(urls => handleInsert(urls));
} else {
handleInsert(cdnUrl);
handleInsert(buildUrl(info));
}
}),
);
});
});
}
/**
* Initialization function will only run once, returns an API object for Netlify
* CMS to call methods on.
*/
async function init({ options = { config: {} }, handleInsert } = {}) {
async function init({ options = { config: {}, settings: {} }, handleInsert } = {}) {
const { publicKey, ...globalConfig } = options.config;
const baseConfig = { ...defaultConfig, ...globalConfig };
@ -118,9 +141,21 @@ async function init({ options = { config: {} }, handleInsert } = {}) {
* from the Uploadcare library will have a `state` method.
*/
if (files && !files.state) {
return files.then(result => openDialog(result, resolvedConfig, handleInsert));
return files.then(result =>
openDialog({
files: result,
config: resolvedConfig,
settings: options.settings,
handleInsert,
}),
);
} else {
return openDialog(files, resolvedConfig, handleInsert);
return openDialog({
files,
config: resolvedConfig,
settings: options.settings,
handleInsert,
});
}
},

View File

@ -78,3 +78,25 @@ For example:
multiple: true
previewStep: false
```
## Integration settings
There are several settings that control the behavior of integration with the widget.
* `autoFilename` (`boolean`) - specify whether to add a filename to the end of the url.
Example: `http://ucarecdn.com/:uuid/filename.png`
* `defaultOperations` (`string`) - specify a string added at the end of the url.
This could be useful to apply a set of CDN operations to each image,
for example resizing or compression. All the possible operations are listed
[here](https://uploadcare.com/docs/api_reference/cdn/).
```yaml
media_library:
name: uploadcare
config:
publicKey: demopublickey
settings:
autoFilename: true
defaultOperations: '/resize/800x600/'
```