Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions branding/client/branding.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ <h3 class="panel-title">
</div>
<div class="panel-body">
{{# if branding }}
{{> viewProjectLogo branding=branding }}
{{> uploadProjectLogo branding=branding }}
{{> viewProjectLogo branding=branding }}
{{> uploadProjectLogo branding=branding }}
{{> viewCoverPhoto branding=branding }}
{{> uploadCoverPhoto branding=branding }}
{{# autoForm
id="brandingEdit"
type="update"
Expand Down
4 changes: 4 additions & 0 deletions branding/collection/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Branding.schema = new SimpleSchema({
type: String,
optional: true,
},
coverPhotoFileId: {
type: String,
optional: true,
},
colors: {
type: Object,
optional: true,
Expand Down
5 changes: 4 additions & 1 deletion branding/collection/server/publications.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Meteor package import
import { Meteor } from 'meteor/meteor';
// Apinf collections import
import { Branding } from '/branding/collection';

Meteor.publish('branding', function() {
// Get Branding collection object
return Branding.find({});
return Branding.find();
});
60 changes: 60 additions & 0 deletions branding/cover_photo/client/upload/resumable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Import meteor packages
import { Meteor } from 'meteor/meteor';
import { sAlert } from 'meteor/juliancwirko:s-alert';
import { TAPi18n } from 'meteor/tap:i18n';

// Import apinf collections
import { Branding } from '/branding/collection';
import CoverPhoto from '/branding/cover_photo/collection';
import { fileNameEndsWith } from '/core/helper_functions/file_name_ends_with';

Meteor.startup(function () {
// Set cover photo id to branding collection on Success
CoverPhoto.resumable.on('fileSuccess', function (file) {

// Get the id from project logo file object
const coverPhotoFileId = file.uniqueIdentifier;

// Get branding
const branding = Branding.findOne();

// Update logo id field
Branding.update(branding._id, { $set: { coverPhotoFileId } });

// Get upload success message translation
const message = TAPi18n.__('uploadCoverPhoto_successfully_uploaded');

// Alert user of successful upload
sAlert.success(message);
});

CoverPhoto.resumable.on('fileAdded', function (file) {
return CoverPhoto.insert({
_id: file.uniqueIdentifier,
filename: file.fileName,
contentType: file.file.type,
}, function (err) {
if (err) {
// Create & show a message about failed
const message = `${TAPi18n.__('uploadCoverPhoto_acceptedExtensions_errorText')} ${err}`;
sAlert.warning(message)
return;
}

// Available extensions for pictures
const acceptedExtensions = ['jpg', 'jpeg', 'png', 'gif'];

// Check extensions for uploading file: is it a picture or not?
if (fileNameEndsWith(file.file.name, acceptedExtensions)) {
// Upload the cover photo
return CoverPhoto.resumable.upload();
}

// Get extension error message
const message = TAPi18n.__('uploadCoverPhoto_acceptedExtensions');

// Alert user of extension error
sAlert.error(message);
});
});
});
3 changes: 3 additions & 0 deletions branding/cover_photo/client/upload/upload.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.cover-photo-file {
margin-bottom: 1em;
}
19 changes: 19 additions & 0 deletions branding/cover_photo/client/upload/upload.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<template name="uploadCoverPhoto">
<div class="cover-photo-file">
{{# unless uploadedCoverPhotoFile }}
{{> uploadCoverPhotoButton }}
{{ else }}
<ul class="list-group">
<li class="list-group-item">
<i class="fa fa-file-text-o" aria-hidden="true"></i>
{{ uploadedCoverPhotoFile.filename }}
<span class="pull-right">
<button class="btn btn-xs btn-danger delete-cover-photo">
<i class="fa fa-trash-o fa-lg" aria-hidden="true"></i>
</button>
</span>
</li>
</ul>
{{/ unless }}
</div>
</template>
59 changes: 59 additions & 0 deletions branding/cover_photo/client/upload/upload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Import meteor packages
import { Template } from 'meteor/templating';
import { Mongo } from 'meteor/mongo';
import { ReactiveVar } from 'meteor/reactive-var';
import { TAPi18n } from 'meteor/tap:i18n';
import { sAlert } from 'meteor/juliancwirko:s-alert';
// Import apinf collections
import { Branding } from '/branding/collection';
import CoverPhoto from '/branding/cover_photo/collection';

Template.uploadCoverPhoto.onCreated(function () {
const instance = this;

// Subscribe to Branding collection
instance.subscribe('branding');
// Subscribe to Cover Photo collection
instance.subscribe('coverPhoto');
});

Template.uploadCoverPhoto.helpers({
uploadedCoverPhotoFile () {
// Get cover photo ID
const currentCoverPhotoFileId = this.branding.coverPhotoFileId;

// Convert to Mongo ObjectID
const objectId = new Mongo.Collection.ObjectID(currentCoverPhotoFileId);

// Check if cover photo file is available
return CoverPhoto.findOne(objectId);
},
});

Template.uploadCoverPhoto.events({
'click .delete-cover-photo': function () {
// Show confirmation dialog to user
const confirmation = confirm(TAPi18n.__('uploadCoverPhoto_confirm_delete'));

// Check if user clicked "OK"
if (confirmation) {
// Get cover photo file id from branding
const coverPhotoFileId = this.branding.coverPhotoFileId;

// Convert to Mongo ObjectID
const objectId = new Mongo.Collection.ObjectID(coverPhotoFileId);

// Remove the cover photo object
CoverPhoto.remove(objectId);

// Remove the cover photo file id field
Branding.update(this.branding._id, { $unset: { coverPhotoFileId: '' } });

// Get deletion success message translation
const message = TAPi18n.__('uploadCoverPhoto_successfully_deleted');

// Alert user of successful delete
sAlert.success(message);
}
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<template name="uploadCoverPhotoButton">
<a class="btn btn-primary" id="cover-photo-browse">
{{_ 'uploadCoverPhotoButton_textButton' }}
</a>
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Import meteor packages
import { Template } from 'meteor/templating';
// Import apinf collections
import CoverPhoto from '/branding/cover_photo/collection';

Template.uploadCoverPhotoButton.onRendered(function() {
// Assign resumable browse to element
CoverPhoto.resumable.assignBrowse($('#cover-photo-browse'));
});
4 changes: 4 additions & 0 deletions branding/cover_photo/client/view/view.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.view-cover-photo {
width: 140px;
margin-bottom: 1em;
}
5 changes: 5 additions & 0 deletions branding/cover_photo/client/view/view.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<template name="viewCoverPhoto">
{{# if coverPhotoExists }}
<img class="view-cover-photo" src="{{ uploadedCoverPhotoLink }}" />
{{/ if }}
</template>
41 changes: 41 additions & 0 deletions branding/cover_photo/client/view/view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Import meteor packages
import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
import { Template } from 'meteor/templating';
// Import apinf collections
import { Branding } from '/branding/collection';
import CoverPhoto from '/branding/cover_photo/collection';

Template.viewCoverPhoto.onCreated(function () {
const instance = this;
// Subscribe to Branding collection
instance.subscribe('branding');
// Subscribe to Cover Photo collection
instance.subscribe('coverPhoto');
});

Template.viewCoverPhoto.helpers({
coverPhotoExists () {
// Get Branding collection
const branding = Branding.findOne();

// Check Branding collection and cover photo exist
return branding && branding.coverPhotoFileId;
},
uploadedCoverPhotoLink () {
const currentCoverPhotoFileId = Branding.findOne().coverPhotoFileId;

// Convert to Mongo ObjectID
const objectId = new Mongo.Collection.ObjectID(currentCoverPhotoFileId);

// Get cover photo file Object
const currentCoverPhotoFile = CoverPhoto.findOne(objectId);

// Check if cover photo file is available
if (currentCoverPhotoFile) {
// Get cover photo file URL
return Meteor.absoluteUrl().slice(0, -1) + CoverPhoto.baseURL + '/md5/' + currentCoverPhotoFile.md5;
}
return '';
},
});
19 changes: 19 additions & 0 deletions branding/cover_photo/collection/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Import Meteor packages
import { FileCollection } from 'meteor/vsivsi:file-collection';

const CoverPhoto = new FileCollection('CoverPhoto', {
resumable: true, // Enable built-in resumable.js upload support
http: [
{ method: 'get',
// this will be at route "/gridfs/CoverPhoto/md5/:md5"
path: '/md5/:md5',
// uses express style url params
// a query mapping url to CoverPhoto
lookup: function (params) {
return { md5: params.md5 };
},
},
],
});

export default CoverPhoto;
19 changes: 19 additions & 0 deletions branding/cover_photo/collection/server/permissions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Import meteor package
import { Roles } from 'meteor/alanning:roles';
// Import apinf collection
import CoverPhoto from '/branding/cover_photo/collection';

CoverPhoto.allow({
insert: function (userId) {
return Roles.userIsInRole(userId, ['admin']);
},
remove: function (userId) {
return Roles.userIsInRole(userId, ['admin']);
},
read: function () {
return true;
},
write: function () {
return true;
},
});
12 changes: 12 additions & 0 deletions branding/cover_photo/server/publications.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Import Meteor package
import { Meteor } from 'meteor/meteor';
// Import apinf collection
import CoverPhoto from '/branding/cover_photo/collection';

Meteor.publish('coverPhoto', () => {
return CoverPhoto.find({
'metadata._Resumable': {
$exists: false,
},
});
});
File renamed without changes.
File renamed without changes.
7 changes: 7 additions & 0 deletions core/lib/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -585,10 +585,17 @@
"uploadApiLogoButton": "Upload logo",
"uploadApiLogo_confirm_delete": "Are you sure you want to delete this logo?",
"uploadApiLogo_successfully_deleted": "Logo successfully deleted!",
"uploadCoverPhoto_confirm_delete": "Cover photo area will show primary branding color after photo has been deleted. The image will be removed from the collection.",
"uploadCoverPhoto_acceptedExtensions": "Only .jpg, .jpeg, .png and .gif file formats are allowed.",
"uploadCoverPhoto_acceptedExtensions_errorText": "File creation failed!",
"uploadCoverPhoto_successfully_uploaded": "Your cover photo was successfully uploaded!",
"uploadCoverPhoto_successfully_deleted": "Your cover photo was successfully deleted!",
"uploadCoverPhotoButton_textButton": "Upload cover photo",
"uploadProjectLogo_confirm_delete": "Are you sure you want to delete your project logo?",
"uploadProjectLogo_acceptedExtensions": "Only .jpg, .jpeg, .png and .gif file formats are allowed.",
"uploadProjectLogo_successfully_uploaded": "Your project logo successfully uploaded!",
"uploadProjectLogo_successfully_deleted": "Your project logo successfully deleted!",
"uploadProjectLogoButton_textButton": "Upload logo",
"userMenu_account": "Account",
"userMenu_branding": "Branding",
"userMenu_profile": "Profile",
Expand Down
2 changes: 1 addition & 1 deletion home/client/body/homeBody.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template name="homeBody">
<div class="coverphoto">
<div class="coverphoto" style="background-image: url({{coverPhotoUrl}})">
<div class="container" id="headerwrap">
<div class="row">
<div class="col-lg-10 col-lg-offset-1">
Expand Down
32 changes: 31 additions & 1 deletion home/client/body/homeBody.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { mailSettingsValid, contactEmailValid } from '/core/helper_functions/validate_settings';
// Import Meteor packages
import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
import { Template } from 'meteor/templating';
// Import apinf collections
import CoverPhoto from '/branding/cover_photo/collection';
import { Settings } from '/settings/collection';

Template.homeBody.onCreated(function () {
Expand All @@ -7,6 +12,8 @@ Template.homeBody.onCreated(function () {

// Subscribe to settings publication
instance.subscribe('singleSetting', 'mail.enabled');
// Subscribe to CoverPhoto collection
instance.subscribe('coverPhoto');
});

Template.homeBody.rendered = function () {
Expand All @@ -29,4 +36,27 @@ Template.homeBody.helpers({

return mailEnabled;
},
coverPhotoUrl () {
// Get Branding collection
const branding = this.branding;

// Check Branding collection and cover photo exist
if (branding && branding.coverPhotoFileId) {
// Get ID
const currentCoverPhotoFileId = branding.coverPhotoFileId;

// Convert to Mongo ObjectID
const objectId = new Mongo.Collection.ObjectID(currentCoverPhotoFileId);

// Check if cover photo file is available
const currentCoverPhotoFile = CoverPhoto.findOne(objectId);

// Check if cover photo file is available
if (currentCoverPhotoFile) {
// Get cover photo file URL
return Meteor.absoluteUrl().slice(0, -1) + CoverPhoto.baseURL + '/md5/' + currentCoverPhotoFile.md5;
}
}
return '';
},
});