Skip to content

Commit

Permalink
Use GraphQL/Apollo in AssetAdmin (fixes silverstripe#316)
Browse files Browse the repository at this point in the history
At the moment this is limited to "read files"
and "create folder". The remaining API endpoints will be
successively moved over to GraphQL.

The GraphQL type creators are likely temporary,
to be replaced with a shorter scaffolding-based version:
silverstripe/silverstripe-graphql#9
silverstripe/silverstripe-graphql#22
silverstripe/silverstripe-graphql#23

RFC at silverstripe/silverstripe-framework#6245
  • Loading branch information
chillu committed Dec 22, 2016
1 parent e1e82b9 commit e57df7d
Show file tree
Hide file tree
Showing 58 changed files with 3,259 additions and 1,968 deletions.
10 changes: 6 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ before_script:
- "if [ \"$PHPCS_TEST\" = \"1\" ]; then pyrus install pear/PHP_CodeSniffer; fi"
- phpenv rehash
- phpenv config-rm xdebug.ini
- echo 'always_populate_raw_post_data = -1' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
- git clone git://github.com/silverstripe-labs/silverstripe-travis-support.git ~/travis-support
- php ~/travis-support/travis_setup.php --source `pwd` --target ~/builds/ss
- cd ~/builds/ss
- "if [ \"$BEHAT_TEST\" = \"1\" ]; then mkdir asset-admin/artifacts; fi"
- "if [ \"$BEHAT_TEST\" = \"1\" ]; then sh -e /etc/init.d/xvfb start; sleep 3; fi"
- "if [ \"$BEHAT_TEST\" = \"1\" ]; then (vendor/bin/selenium-server-standalone > selenium.log 2>&1 &); fi"
- "if [ \"$BEHAT_TEST\" = \"1\" ]; then (vendor/bin/serve --bootstrap-file cms/tests/behat/serve-bootstrap.php &> serve.log &); fi"
- "if [ \"$BEHAT_TEST\" = \"1\" ]; then (vendor/bin/selenium-server-standalone > asset-admin/artifacts/selenium.log 2>&1 &); fi"
- "if [ \"$BEHAT_TEST\" = \"1\" ]; then (vendor/bin/serve --bootstrap-file cms/tests/behat/serve-bootstrap.php &> asset-admin/artifacts/serve.log &); fi"

script:
- "if [ \"$PHPUNIT_TEST\" = \"1\" ]; then vendor/bin/phpunit asset-admin/tests/php; fi"
Expand All @@ -44,10 +46,10 @@ script:
- "if [ \"$NPM_TEST\" = \"1\" ]; then (cd asset-admin && nvm use 4 && npm run test); fi"
- "if [ \"$NPM_TEST\" = \"1\" ]; then (cd asset-admin && nvm use 4 && npm run lint); fi"
- "if [ \"$BEHAT_TEST\" = \"1\" ]; then vendor/bin/behat @asset-admin --config=./asset-admin/behat.yml; fi"
- "if [ \"$PHPCS_TEST\" = \"1\" ]; then phpcs --standard=asset-admin/tests/phpcs/ruleset.xml asset-admin/code/ asset-admin/tests/; fi"
- "if [ \"$PHPCS_TEST\" = \"1\" ]; then phpcs --standard=asset-admin/tests/phpcs/ruleset.xml asset-admin/code/ asset-admin/tests/; fi"

after_failure:
- php ./framework/tests/behat/travis-upload-artifacts.php --if-env BEHAT_TEST,ARTIFACTS_BUCKET,ARTIFACTS_KEY,ARTIFACTS_SECRET --target-path $TRAVIS_REPO_SLUG/$TRAVIS_BUILD_ID/$TRAVIS_JOB_ID --artifacts-base-url https://s3.amazonaws.com/$ARTIFACTS_BUCKET/
- php ./framework/tests/behat/travis-upload-artifacts.php --if-env BEHAT_TEST,ARTIFACTS_BUCKET,ARTIFACTS_KEY,ARTIFACTS_SECRET --target-path $TRAVIS_REPO_SLUG/$TRAVIS_BUILD_ID/$TRAVIS_JOB_ID --artifacts-base-url https://s3.amazonaws.com/$ARTIFACTS_BUCKET/ --artifacts-path ./asset-admin/artifacts/

notifications:
slack: silverstripeltd:Cls1xnypKBLFhv0YIRtNLzlQ
16 changes: 16 additions & 0 deletions _config/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,19 @@ SilverStripe\Assets\File:
SilverStripe\Admin\LeftAndMain:
extensions:
- SilverStripe\AssetAdmin\Controller\AssetAdminFieldsExtension
SilverStripe\GraphQL:
schema:
types:
DataObjectInterface: 'SilverStripe\GraphQL\DataObjectInterfaceTypeCreator'
File: 'SilverStripe\AssetAdmin\GraphQL\FileTypeCreator'
FileInterface: 'SilverStripe\AssetAdmin\GraphQL\FileInterfaceTypeCreator'
FileInput: 'SilverStripe\AssetAdmin\GraphQL\FileInputTypeCreator'
Folder: 'SilverStripe\AssetAdmin\GraphQL\FolderTypeCreator'
FolderInput: 'SilverStripe\AssetAdmin\GraphQL\FolderInputTypeCreator'
queries:
readFiles: 'SilverStripe\AssetAdmin\GraphQL\ReadFileQueryCreator'
mutations:
createFile: 'SilverStripe\AssetAdmin\GraphQL\CreateFileMutationCreator'
updateFile: 'SilverStripe\AssetAdmin\GraphQL\UpdateFileMutationCreator'
deleteFile: 'SilverStripe\AssetAdmin\GraphQL\DeleteFileMutationCreator'
createFolder: 'SilverStripe\AssetAdmin\GraphQL\CreateFolderMutationCreator'
1 change: 1 addition & 0 deletions behat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ default:
SilverStripe\BehatExtension\Extension:
framework_path: ../framework
bootstrap_file: "cms/tests/behat/serve-bootstrap.php"
screenshot_path: %behat.paths.base%/artifacts/screenshots
Behat\MinkExtension\Extension:
# Adjust this to your local environment
base_url: http://localhost:8080/
Expand Down
Binary file added client/dist/images/folder_icon_large.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1,744 changes: 1,010 additions & 734 deletions client/dist/js/bundle.js

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions client/dist/styles/bundle.css
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,15 @@
max-width:60px;
}

.gallery__table-image--folder{
background-image:url(../images/folder_icon_large.png);
background-repeat:no-repeat;
background-size:60px auto;
background-position:50%;
height:68px;
width:60px;
}

.gallery__table-image--error{
background:#d40404;
height:68px;
Expand Down
8 changes: 4 additions & 4 deletions client/src/components/AssetDropzone/AssetDropzone.js
Original file line number Diff line number Diff line change
Expand Up @@ -348,10 +348,8 @@ class AssetDropzone extends SilverStripeComponent {
// JS Synonym for AssetAdmin::getObjectFromData()
return loadPreview.then((preview) => {
const details = {
dimensions: {
height: preview.height,
width: preview.width,
},
height: preview.height,
width: preview.width,
category: this.getFileCategory(file.type),
filename: file.name,
queuedId: file._queuedId,
Expand All @@ -360,6 +358,8 @@ class AssetDropzone extends SilverStripeComponent {
extension: getFileExtension(file.name),
type: file.type,
url: preview.thumbnailURL,
thumbnail: preview.thumbnailURL,
smallThumbail: preview.thumbnailURL,
};

this.props.handleAddedFile(details);
Expand Down
25 changes: 19 additions & 6 deletions client/src/components/GalleryItem/GalleryItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,17 @@ class GalleryItem extends SilverStripeComponent {
return this.props.item.uploading;
}

/**
* Check if this item has been successfully uploaded.
* Excludes items not uploaded in this request.
*
* @returns {Boolean}
*/
complete() {
// Uploading is complete if saved with a DB id
return this.uploading() && this.props.item.id > 0;
}

/**
* Determine that this record is an image, and the thumbnail is smaller than the given thumbnail area
*
Expand All @@ -204,13 +215,15 @@ class GalleryItem extends SilverStripeComponent {
if (!this.isImage() || (!this.exists() && !this.uploading())) {
return false;
}
const dimensions = this.props.item.dimensions;
const width = this.props.item.width;
const height = this.props.item.height;

// Note: dimensions will be null if the back-end image is lost
return (
dimensions
&& dimensions.height < CONSTANTS.THUMBNAIL_HEIGHT
&& dimensions.width < CONSTANTS.THUMBNAIL_WIDTH
height
&& width
&& height < CONSTANTS.THUMBNAIL_HEIGHT
&& width < CONSTANTS.THUMBNAIL_WIDTH
);
}

Expand Down Expand Up @@ -253,7 +266,7 @@ class GalleryItem extends SilverStripeComponent {

if (this.hasError()) {
this.props.onRemoveErroredUpload(this.props.item);
} else {
} else if (this.props.onCancelUpload) {
this.props.onCancelUpload(this.props.item);
}
}
Expand All @@ -273,7 +286,7 @@ class GalleryItem extends SilverStripeComponent {
},
};

if (!this.hasError() && this.uploading()) {
if (!this.hasError() && this.uploading() && !this.complete()) {
progressBar = (
<div className="gallery-item__upload-progress">
<div {...progressBarProps}></div>
Expand Down
12 changes: 4 additions & 8 deletions client/src/components/GalleryItem/tests/GalleryItem-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ describe('GalleryItem', () => {
onActivate: jest.genMockFunction(),
handleDelete: jest.genMockFunction(),
item: {
dimensions: {
width: 10,
height: 10,
},
width: 10,
height: 10,
exists: true,
category: 'image',
id: 1,
Expand Down Expand Up @@ -239,10 +237,8 @@ describe('GalleryItem', () => {
});

it('should return false if the dimensions are larger than the default thumbnail size', () => {
props.item.dimensions = {
width: 1000,
height: 1000,
};
props.item.width = 1000;
props.item.height = 1000;

expect(item.isImageSmallerThanThumbnail()).toBe(false);
});
Expand Down
7 changes: 6 additions & 1 deletion client/src/components/PreviewImageField/PreviewImageField.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ class PreviewImageField extends Component {
}

componentWillReceiveProps(nextProps) {
if (this.props.data.url && nextProps.data.url !== this.props.data.url) {
// Check latest version to detect file save actions
if (
(this.props.data.url && nextProps.data.url !== this.props.data.url)
|| (this.props.data.version && nextProps.data.version !== this.props.data.version)
) {
this.props.actions.previewField.removeFile(this.props.id);
}
}
Expand Down Expand Up @@ -321,6 +325,7 @@ PreviewImageField.propTypes = {
onAutofill: PropTypes.func,
data: PropTypes.shape({
parentid: PropTypes.number,
version: PropTypes.number,
url: PropTypes.string,
exists: PropTypes.bool,
preview: PropTypes.string,
Expand Down
10 changes: 6 additions & 4 deletions client/src/components/UploadField/UploadFieldItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,15 @@ class UploadFieldItem extends SilverStripeComponent {
if (!this.isImage() || (!this.exists() && !this.uploading())) {
return false;
}
const dimensions = this.props.item.dimensions;
const width = this.props.item.width;
const height = this.props.item.height;

// Note: dimensions will be null if the back-end image is lost
return (
dimensions
&& dimensions.height < CONSTANTS.SMALL_THUMBNAIL_HEIGHT
&& dimensions.width < CONSTANTS.SMALL_THUMBNAIL_WIDTH
height
&& width
&& height < CONSTANTS.SMALL_THUMBNAIL_HEIGHT
&& width < CONSTANTS.SMALL_THUMBNAIL_WIDTH
);
}

Expand Down
Loading

0 comments on commit e57df7d

Please sign in to comment.