Compare commits
No commits in common. "ostrio-files" and "main" have entirely different histories.
ostrio-fil
...
main
@ -22,4 +22,3 @@ react-meteor-data # React higher-order component for reactively tracking M
|
|||||||
roles@1.0.1
|
roles@1.0.1
|
||||||
accounts-password@3.0.3
|
accounts-password@3.0.3
|
||||||
react-meteor-accounts
|
react-meteor-accounts
|
||||||
ostrio:files
|
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
METEOR@3.1.2
|
METEOR@3.1.1
|
||||||
|
|||||||
@ -23,7 +23,7 @@ ecmascript-runtime@0.8.3
|
|||||||
ecmascript-runtime-client@0.12.2
|
ecmascript-runtime-client@0.12.2
|
||||||
ecmascript-runtime-server@0.11.1
|
ecmascript-runtime-server@0.11.1
|
||||||
ejson@1.1.4
|
ejson@1.1.4
|
||||||
email@3.1.2
|
email@3.1.1
|
||||||
es5-shim@4.8.1
|
es5-shim@4.8.1
|
||||||
facts-base@1.0.2
|
facts-base@1.0.2
|
||||||
fetch@0.1.5
|
fetch@0.1.5
|
||||||
@ -42,7 +42,7 @@ minifier-js@3.0.1
|
|||||||
minimongo@2.0.2
|
minimongo@2.0.2
|
||||||
mobile-experience@1.1.2
|
mobile-experience@1.1.2
|
||||||
mobile-status-bar@1.1.1
|
mobile-status-bar@1.1.1
|
||||||
modern-browsers@0.2.0
|
modern-browsers@0.1.11
|
||||||
modules@0.20.3
|
modules@0.20.3
|
||||||
modules-runtime@0.13.2
|
modules-runtime@0.13.2
|
||||||
modules-runtime-hot@0.14.3
|
modules-runtime-hot@0.14.3
|
||||||
@ -52,8 +52,6 @@ mongo-dev-server@1.1.1
|
|||||||
mongo-id@1.0.9
|
mongo-id@1.0.9
|
||||||
npm-mongo@6.10.2
|
npm-mongo@6.10.2
|
||||||
ordered-dict@1.2.0
|
ordered-dict@1.2.0
|
||||||
ostrio:cookies@2.8.1
|
|
||||||
ostrio:files@3.0.0-beta.6
|
|
||||||
promise@1.0.0
|
promise@1.0.0
|
||||||
random@1.2.2
|
random@1.2.2
|
||||||
rate-limit@1.1.2
|
rate-limit@1.1.2
|
||||||
@ -75,5 +73,5 @@ static-html-tools@1.0.0
|
|||||||
tracker@1.3.4
|
tracker@1.3.4
|
||||||
typescript@5.6.3
|
typescript@5.6.3
|
||||||
url@1.3.5
|
url@1.3.5
|
||||||
webapp@2.0.5
|
webapp@2.0.4
|
||||||
webapp-hashing@1.1.2
|
webapp-hashing@1.1.2
|
||||||
|
|||||||
@ -1,289 +0,0 @@
|
|||||||
import { Meteor } from 'meteor/meteor';
|
|
||||||
import { FilesCollection } from 'meteor/ostrio:files';
|
|
||||||
import { createBucket } from '/imports/api/lib/grid/createBucket.js';
|
|
||||||
import { createObjectId } from '/imports/api/lib/grid/createObjectId.js';
|
|
||||||
import fs from 'fs';
|
|
||||||
|
|
||||||
// import { Mongo } from 'meteor/mongo';
|
|
||||||
|
|
||||||
let filesBucket;
|
|
||||||
|
|
||||||
if (Meteor.isServer) {
|
|
||||||
filesBucket = createBucket('allFiles');
|
|
||||||
}
|
|
||||||
|
|
||||||
const FilesCol = new FilesCollection({
|
|
||||||
collectionName: 'Files',
|
|
||||||
allowClientCode: true,
|
|
||||||
debug: Meteor.isServer && process.env.NODE_ENV === 'development',
|
|
||||||
onBeforeUpload (file) {
|
|
||||||
// if (file.size <= 10485760 && /png|jpg|jpeg/i.test(file.extension)) {
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// return 'Please upload image, with size equal or less than 10MB';
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
onAfterUpload(file) {
|
|
||||||
const self = this;
|
|
||||||
|
|
||||||
// here you could manipulate your file
|
|
||||||
// and create a new version, for example a scaled 'thumbnail'
|
|
||||||
// ...
|
|
||||||
|
|
||||||
console.log("file_versions: ", file.versions);
|
|
||||||
|
|
||||||
// then we read all versions we have got so far
|
|
||||||
Object.keys(file.versions).forEach(versionName => {
|
|
||||||
const metadata = { ...file.meta, versionName, fileId: file._id };
|
|
||||||
fs.createReadStream(file.versions[ versionName ].path)
|
|
||||||
|
|
||||||
// this is where we upload the binary to the bucket
|
|
||||||
.pipe(filesBucket.openUploadStream(
|
|
||||||
file.name,
|
|
||||||
{
|
|
||||||
contentType: file.type || 'binary/octet-stream',
|
|
||||||
metadata
|
|
||||||
}
|
|
||||||
))
|
|
||||||
|
|
||||||
// and we unlink the file from the fs on any error
|
|
||||||
// that occurred during the upload to prevent zombie files
|
|
||||||
.on('error', async err => {
|
|
||||||
console.error(err);
|
|
||||||
self.unlink(await this.collection.findOneAsync(file._id), versionName); // Unlink files from FS
|
|
||||||
})
|
|
||||||
|
|
||||||
// once we are finished, we attach the gridFS Object id on the
|
|
||||||
// FilesCollection document's meta section and finally unlink the
|
|
||||||
// upload file from the filesystem
|
|
||||||
.on('finish', Meteor.bindEnvironment(async ver => {
|
|
||||||
const property = `versions.${versionName}.meta.gridFsFileId`;
|
|
||||||
await self.collection.updateAsync(file._id, {
|
|
||||||
$set: {
|
|
||||||
[ property ]: ver._id.toHexString()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
self.unlink(await this.collection.findOneAsync(file._id), versionName); // Unlink files from FS
|
|
||||||
}))
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
interceptDownload (http, file, versionName) {
|
|
||||||
const { gridFsFileId } = file.versions[ versionName ].meta || {};
|
|
||||||
if (gridFsFileId) {
|
|
||||||
const gfsId = createObjectId({ gridFsFileId });
|
|
||||||
const readStream = filesBucket.openDownloadStream(gfsId);
|
|
||||||
readStream.on('data', (data) => {
|
|
||||||
http.response.write(data);
|
|
||||||
})
|
|
||||||
|
|
||||||
readStream.on('end', () => {
|
|
||||||
http.response.end('end');
|
|
||||||
})
|
|
||||||
|
|
||||||
readStream.on('error', () => {
|
|
||||||
// not found probably
|
|
||||||
// eslint-disable-next-line no-param-reassign
|
|
||||||
http.response.statusCode = 404;
|
|
||||||
http.response.end('not found');
|
|
||||||
})
|
|
||||||
|
|
||||||
http.response.setHeader('Cache-Control', this.cacheControl);
|
|
||||||
http.response.setHeader('Content-Disposition', `inline; filename="${file.name}"`);
|
|
||||||
}
|
|
||||||
return Boolean(gridFsFileId) // Serve file from either GridFS or FS if it wasn't uploaded yet
|
|
||||||
},
|
|
||||||
|
|
||||||
onAfterRemove (files) {
|
|
||||||
files.forEach(file => {
|
|
||||||
Object.keys(file.versions).forEach(versionName => {
|
|
||||||
const gridFsFileId = (file.versions[ versionName ].meta || {}).gridFsFileId;
|
|
||||||
if (gridFsFileId) {
|
|
||||||
const gfsId = createObjectId({ gridFsFileId });
|
|
||||||
filesBucket.deleteAsync(gfsId, err => { if (err) console.error(err); });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// if (Meteor.isClient) {
|
|
||||||
// Meteor.subscribe('files.all');
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (Meteor.isServer) {
|
|
||||||
|
|
||||||
Meteor.publish('files.all', () => {
|
|
||||||
return FilesCol.collection.find({userId: Meteor.userId()});
|
|
||||||
});
|
|
||||||
|
|
||||||
Meteor.publish('avatars.all', () => {
|
|
||||||
return Avatars.collection.find();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
Meteor.publish('avatarsregistre.all', () => {
|
|
||||||
return AvatarsRegistre.collection.find();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Meteor.publish('files.avatar', () => {
|
|
||||||
// return FilesCol.collection.find({
|
|
||||||
// userId: Meteor.userId(),
|
|
||||||
// 'meta.type': 'avatar'
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
|
|
||||||
// Meteor.publish('files.avatarRegister', (avatarId) => {
|
|
||||||
// if (avatarId) {
|
|
||||||
// if (!Meteor.userId()) {
|
|
||||||
// return FilesCol.collection.find({_id: avatarId});
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// return [];
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// Meteor.publish('files.folderTree', () => {
|
|
||||||
// //if (upId) {
|
|
||||||
// if (Meteor.userId()) {
|
|
||||||
// return FilesCol.collection.find({
|
|
||||||
// userId: Meteor.userId(),
|
|
||||||
// "meta.type": "folderTree"
|
|
||||||
// });
|
|
||||||
// } else {
|
|
||||||
// return [];
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// // files.cartellEventUpload
|
|
||||||
// Meteor.publish('files.cartellEventUpload', (cartellId) => {
|
|
||||||
// if (cartellId) {
|
|
||||||
// //if (!Meteor.userId()) {
|
|
||||||
// return FilesCol.collection.find({_id: cartellId});
|
|
||||||
// } else {
|
|
||||||
// return [];
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
|
|
||||||
Meteor.methods({
|
|
||||||
|
|
||||||
'RenameFile'(data){
|
|
||||||
// if (!Meteor.userId()){
|
|
||||||
// throw new Meteor.Error('not-authorized');
|
|
||||||
// }
|
|
||||||
FilesCol.insertAsync({
|
|
||||||
...data,
|
|
||||||
createdAt: new Date(),
|
|
||||||
user: Meteor.userId()
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'ReassignaUserIdFile'(userIdProvisional, uid){
|
|
||||||
// if (!Meteor.userId()){
|
|
||||||
// throw new Meteor.Error('not-authorized');
|
|
||||||
// }
|
|
||||||
|
|
||||||
FilesCol.collection.updateAsync({_id: userIdProvisional}, {
|
|
||||||
$set: {
|
|
||||||
meta: {
|
|
||||||
userId: uid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
'RemoveFile'(fileToRemoveId) {
|
|
||||||
FilesCol.collection.removeAsync(fileToRemoveId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// getFolderTreeFiles() {
|
|
||||||
// return FilesCol.find({
|
|
||||||
// // userId: Meteor.userId(),
|
|
||||||
// // 'meta.type': 'folderTree'
|
|
||||||
// }).fetch();
|
|
||||||
// }
|
|
||||||
// 'dates.update'(data){
|
|
||||||
// // if (Meteor.userId() !== allcod.user){
|
|
||||||
// // throw new Meteor.Error('not-authorized');
|
|
||||||
// // }
|
|
||||||
// DatesCollection.update(data._id, {
|
|
||||||
// $set: {
|
|
||||||
// ...data
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
|
|
||||||
// 'dates.delete'(data){
|
|
||||||
// // if (Meteor.userId() !== allcod.user){
|
|
||||||
// // throw new Meteor.Error('not-authorized');
|
|
||||||
// // }
|
|
||||||
// DatesCollection.remove(data._id);
|
|
||||||
// },
|
|
||||||
|
|
||||||
// 'dates.remove'(id, context) {
|
|
||||||
// DatesCollection.remove(id);
|
|
||||||
// }
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create a new instance of the FilesCollection
|
|
||||||
const AvatarsRegistre = new FilesCollection({
|
|
||||||
collectionName: 'AvatarsRegistre',
|
|
||||||
storagePath: 'assets/avatarRegistreStorage',
|
|
||||||
downloadRoute: '/avatar-registre',
|
|
||||||
permissions: 0o755,
|
|
||||||
cacheControl: 'public, max-age=31536000',
|
|
||||||
allowClientCode: false, // Disallow remove files from Client
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create a new instance of the FilesCollection
|
|
||||||
const Avatars = new FilesCollection({
|
|
||||||
collectionName: 'Avatars',
|
|
||||||
storagePath: 'assets/avatarStorage',
|
|
||||||
downloadRoute: '/avatar',
|
|
||||||
permissions: 0o755,
|
|
||||||
cacheControl: 'public, max-age=31536000',
|
|
||||||
allowClientCode: false, // Disallow remove files from Client
|
|
||||||
});
|
|
||||||
|
|
||||||
Meteor.methods({
|
|
||||||
|
|
||||||
'registraUsuariAmbAvatar'(username, email, password, avatar) {
|
|
||||||
// Check if the username and email are valid
|
|
||||||
if (!username || !email || !password) {
|
|
||||||
throw new Meteor.Error('invalid-input', 'Please fill in all fields');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the avatar is a valid file
|
|
||||||
if (!avatar || !avatar.file) {
|
|
||||||
throw new Meteor.Error('invalid-avatar', 'Please select a valid avatar image');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Upload the avatar to GridFS
|
|
||||||
const avatarId = Avatars.insert(avatar.file, (err, fileObj) => {
|
|
||||||
if (err) {
|
|
||||||
throw new Meteor.Error('avatar-upload-failed', 'Failed to upload avatar');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create the new user
|
|
||||||
const userId = Accounts.createUser({
|
|
||||||
username,
|
|
||||||
email,
|
|
||||||
password,
|
|
||||||
profile: {
|
|
||||||
avatar: avatarId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Return the new user's ID
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
export { FilesCol, AvatarsRegistre, Avatars };
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
import { MongoInternals } from 'meteor/mongo';
|
|
||||||
|
|
||||||
export const createBucket = bucketName => {
|
|
||||||
const options = bucketName ? {bucketName} : (void 0);
|
|
||||||
return new MongoInternals.NpmModule.GridFSBucket(MongoInternals.defaultRemoteCollectionDriver().mongo.db, options);
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import { MongoInternals } from 'meteor/mongo'
|
|
||||||
|
|
||||||
export const createObjectId = ({gridFsFileId}) => new MongoInternals.NpmModule.ObjectID(gridFsFileId);
|
|
||||||
@ -1,110 +0,0 @@
|
|||||||
import { Meteor } from 'meteor/meteor';
|
|
||||||
import { FilesCollection } from 'meteor/ostrio:files';
|
|
||||||
import { createBucket } from '/imports/api/lib/grid/createBucket.js';
|
|
||||||
import { createObjectId } from '/imports/api/lib/grid/createObjectId.js';
|
|
||||||
import fs from 'fs';
|
|
||||||
|
|
||||||
let imagesBucket;
|
|
||||||
if (Meteor.isServer) {
|
|
||||||
imagesBucket = createBucket('allImages');
|
|
||||||
}
|
|
||||||
|
|
||||||
const Images = new FilesCollection({
|
|
||||||
collectionName: 'Images',
|
|
||||||
allowClientCode: true,
|
|
||||||
debug: Meteor.isServer && process.env.NODE_ENV === 'development',
|
|
||||||
onBeforeUpload (file) {
|
|
||||||
if (file.size <= 10485760 && /png|jpg|jpeg/i.test(file.extension)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return 'Please upload image, with size equal or less than 10MB';
|
|
||||||
},
|
|
||||||
onAfterUpload (file) {
|
|
||||||
const self = this;
|
|
||||||
|
|
||||||
// here you could manipulate your file
|
|
||||||
// and create a new version, for example a scaled 'thumbnail'
|
|
||||||
// ...
|
|
||||||
|
|
||||||
// then we read all versions we have got so far
|
|
||||||
Object.keys(file.versions).forEach(versionName => {
|
|
||||||
const metadata = { ...file.meta, versionName, fileId: file._id };
|
|
||||||
fs.createReadStream(file.versions[ versionName ].path)
|
|
||||||
|
|
||||||
// this is where we upload the binary to the bucket
|
|
||||||
.pipe(imagesBucket.openUploadStream(
|
|
||||||
file.name,
|
|
||||||
{
|
|
||||||
contentType: file.type || 'binary/octet-stream',
|
|
||||||
metadata
|
|
||||||
}
|
|
||||||
))
|
|
||||||
|
|
||||||
// and we unlink the file from the fs on any error
|
|
||||||
// that occurred during the upload to prevent zombie files
|
|
||||||
.on('error', err => {
|
|
||||||
console.error(err);
|
|
||||||
self.unlink(this.collection.findOne(file._id), versionName); // Unlink files from FS
|
|
||||||
})
|
|
||||||
|
|
||||||
// once we are finished, we attach the gridFS Object id on the
|
|
||||||
// FilesCollection document's meta section and finally unlink the
|
|
||||||
// upload file from the filesystem
|
|
||||||
.on('finish', Meteor.bindEnvironment(ver => {
|
|
||||||
const property = `versions.${versionName}.meta.gridFsFileId`;
|
|
||||||
self.collection.update(file._id, {
|
|
||||||
$set: {
|
|
||||||
[ property ]: ver._id.toHexString()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
self.unlink(this.collection.findOne(file._id), versionName); // Unlink files from FS
|
|
||||||
}))
|
|
||||||
})
|
|
||||||
},
|
|
||||||
interceptDownload (http, file, versionName) {
|
|
||||||
const { gridFsFileId } = file.versions[ versionName ].meta || {};
|
|
||||||
if (gridFsFileId) {
|
|
||||||
const gfsId = createObjectId({ gridFsFileId });
|
|
||||||
const readStream = imagesBucket.openDownloadStream(gfsId);
|
|
||||||
readStream.on('data', (data) => {
|
|
||||||
http.response.write(data);
|
|
||||||
})
|
|
||||||
|
|
||||||
readStream.on('end', () => {
|
|
||||||
http.response.end('end');
|
|
||||||
})
|
|
||||||
|
|
||||||
readStream.on('error', () => {
|
|
||||||
// not found probably
|
|
||||||
// eslint-disable-next-line no-param-reassign
|
|
||||||
http.response.statusCode = 404;
|
|
||||||
http.response.end('not found');
|
|
||||||
})
|
|
||||||
|
|
||||||
http.response.setHeader('Cache-Control', this.cacheControl);
|
|
||||||
http.response.setHeader('Content-Disposition', `inline; filename="${file.name}"`);
|
|
||||||
}
|
|
||||||
return Boolean(gridFsFileId) // Serve file from either GridFS or FS if it wasn't uploaded yet
|
|
||||||
},
|
|
||||||
onAfterRemove (files) {
|
|
||||||
files.forEach(file => {
|
|
||||||
Object.keys(file.versions).forEach(versionName => {
|
|
||||||
const gridFsFileId = (file.versions[ versionName ].meta || {}).gridFsFileId;
|
|
||||||
if (gridFsFileId) {
|
|
||||||
const gfsId = createObjectId({ gridFsFileId });
|
|
||||||
imagesBucket.delete(gfsId, err => { if (err) console.error(err); });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (Meteor.isClient) {
|
|
||||||
Meteor.subscribe('files.images.all');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Meteor.isServer) {
|
|
||||||
Meteor.publish('files.images.all', () => Images.collection.find({}));
|
|
||||||
}
|
|
||||||
|
|
||||||
export { Images };
|
|
||||||
@ -1,62 +0,0 @@
|
|||||||
import { Mongo } from 'meteor/mongo';
|
|
||||||
import { Images } from './images.js';
|
|
||||||
// import SimpleSchema from 'simpl-schema';
|
|
||||||
|
|
||||||
// SimpleSchema.extendOptions(['autoform']);
|
|
||||||
// SimpleSchema.setDefaultMessages({
|
|
||||||
// initialLanguage: 'en',
|
|
||||||
// messages: {
|
|
||||||
// en: {
|
|
||||||
// uploadError: '{{{value}}}'
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
const Persons = new Mongo.Collection('persons');
|
|
||||||
|
|
||||||
Persons.helpers({
|
|
||||||
profilePic() {
|
|
||||||
return Images.find({_id: this.profilePicId});
|
|
||||||
},
|
|
||||||
backgroundPic() {
|
|
||||||
return Images.find({_id: this.backgroundPicId});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Persons.attachSchema({
|
|
||||||
// name: {
|
|
||||||
// type: String,
|
|
||||||
// label: 'Name'
|
|
||||||
// },
|
|
||||||
// profilePicId: {
|
|
||||||
// type: String,
|
|
||||||
// label: 'Profile Pic Id',
|
|
||||||
// autoform: {
|
|
||||||
// afFieldInput: {
|
|
||||||
// type: 'fileUpload',
|
|
||||||
// collection: 'Images',
|
|
||||||
// insertConfig: {
|
|
||||||
// transport: 'http'
|
|
||||||
// },
|
|
||||||
// uploadTemplate: 'uploadField', // <- Optional
|
|
||||||
// previewTemplate: 'uploadPreview', // <- Optional,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// backgroundPicId: {
|
|
||||||
// type: String,
|
|
||||||
// label: 'Background Pic Id',
|
|
||||||
// autoform: {
|
|
||||||
// afFieldInput: {
|
|
||||||
// type: 'fileUpload',
|
|
||||||
// collection: 'Images',
|
|
||||||
// accept: '.png,.jpg,.jpeg', // use built-in accept config
|
|
||||||
// insertConfig: {
|
|
||||||
// transport: 'http'
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
export { Persons };
|
|
||||||
@ -47,7 +47,7 @@ const useLongPress = (mostraMenu, setMostraMenu) => {
|
|||||||
if (isPressed) {
|
if (isPressed) {
|
||||||
setIsPressed(false);
|
setIsPressed(false);
|
||||||
// Clear any pending timeout
|
// Clear any pending timeout
|
||||||
// clearTimeout(timeoutId?.current);
|
clearTimeout(timeoutId?.current);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -69,7 +69,6 @@ const useLongPress = (mostraMenu, setMostraMenu) => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
// return () => clearTimeout(timeoutId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return () => clearTimeout(timeoutId);
|
return () => clearTimeout(timeoutId);
|
||||||
@ -249,7 +248,7 @@ const UserStat = ({esAdministrador, setEsAdministrador}) => {
|
|||||||
left: 0,
|
left: 0,
|
||||||
top: `5em`,
|
top: `5em`,
|
||||||
padding: `.4em .5em`,
|
padding: `.4em .5em`,
|
||||||
border: `1px solid #aaa`,
|
border: `1px #aaa`,
|
||||||
cursor: `pointer`,
|
cursor: `pointer`,
|
||||||
zIndex: `200`
|
zIndex: `200`
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -1,45 +1,14 @@
|
|||||||
import React, { useState, useEffect, useRef } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Accounts } from 'meteor/accounts-base';
|
import { Accounts } from 'meteor/accounts-base';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Meteor } from 'meteor/meteor';
|
import { Meteor } from 'meteor/meteor';
|
||||||
// import { useTracker, useSubscribe, useFind } from 'meteor/react-meteor-data/suspense';
|
|
||||||
import { useSubscribe, useFind } from 'meteor/react-meteor-data';
|
|
||||||
import { Roles } from 'meteor/roles';
|
import { Roles } from 'meteor/roles';
|
||||||
import { ROLS_GLOBALS } from '../roles';
|
import { ROLS_GLOBALS } from '../roles';
|
||||||
import { AvatarsRegistre } from '/imports/api/files.js';
|
|
||||||
import AvatarFileUpload from '/imports/ui/files/AvatarFileUpload';
|
|
||||||
|
|
||||||
|
|
||||||
export const Login = () => {
|
export const Login = () => {
|
||||||
const [isLogin, setIsLogin] = useState( { initialState: true } );
|
const [isLogin, setIsLogin] = useState( { initialState: true } );
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
// const avatarinput = useRef();
|
|
||||||
|
|
||||||
// const [avatarId, setAvatarId] = useState();
|
|
||||||
// const [avatarLink, setAvatarLink] = useState();
|
|
||||||
|
|
||||||
// const [novaImg, setNovaImg] = useState(false);
|
|
||||||
|
|
||||||
// const [avatar, setAvatar] = useState(null);
|
|
||||||
|
|
||||||
// let files;
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
|
|
||||||
// useSubscribe('avatarsregistre.all');
|
|
||||||
const isLoading = useSubscribe('avatarsregistre.all');
|
|
||||||
|
|
||||||
const files = useFind(() => AvatarsRegistre.find(), []);
|
|
||||||
|
|
||||||
// }, []);
|
|
||||||
|
|
||||||
// const files = useTracker("avatars", () => {
|
|
||||||
// return Avatars.find({}).fetchAsync();
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const handleLogin = (e) => {
|
const handleLogin = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// console.dir(e);
|
// console.dir(e);
|
||||||
@ -75,7 +44,6 @@ export const Login = () => {
|
|||||||
email,
|
email,
|
||||||
password
|
password
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("userId deL NOU USUARI: ", userId);
|
console.log("userId deL NOU USUARI: ", userId);
|
||||||
userId && await Roles.addUsersToRolesAsync(userId, [ROLS_GLOBALS.USUARI]);
|
userId && await Roles.addUsersToRolesAsync(userId, [ROLS_GLOBALS.USUARI]);
|
||||||
navigate('/');
|
navigate('/');
|
||||||
@ -106,8 +74,6 @@ export const Login = () => {
|
|||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
action={async d => {
|
action={async d => {
|
||||||
@ -143,11 +109,7 @@ export const Login = () => {
|
|||||||
password2
|
password2
|
||||||
};
|
};
|
||||||
|
|
||||||
// Meteor.callAsync('creaUsuariAmbCodi', uObj, codi);
|
Meteor.callAsync('creaUsuariAmbCodi', uObj, codi);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Meteor.callAsync('registraUsuariAmbAvatarICodi', uObj, codi, avatarinput.current);
|
|
||||||
|
|
||||||
// userId = await Accounts.createUser({
|
// userId = await Accounts.createUser({
|
||||||
// username,
|
// username,
|
||||||
@ -201,8 +163,7 @@ export const Login = () => {
|
|||||||
backgroundColor: `#eeed`
|
backgroundColor: `#eeed`
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* Avatar:
|
Avatar: <img
|
||||||
<img
|
|
||||||
style={{
|
style={{
|
||||||
width: `3em`,
|
width: `3em`,
|
||||||
height: `3em`,
|
height: `3em`,
|
||||||
@ -218,41 +179,6 @@ export const Login = () => {
|
|||||||
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<label
|
|
||||||
htmlFor="avatarinput"
|
|
||||||
style={{
|
|
||||||
minWidth: `3em`,
|
|
||||||
minHeight: `3em`,
|
|
||||||
borderRadius: `50%`,
|
|
||||||
border: `.6vh solid white`,
|
|
||||||
display: `block`,
|
|
||||||
// backgroundImage: `url(${link}), linear-gradient(to bottom right, transparent, #fffd)`,
|
|
||||||
backgroundSize: `cover`,
|
|
||||||
backgroundRepeat: `no-repeat`,
|
|
||||||
margin: `0 auto -1.5em auto`,
|
|
||||||
aspectRatio: `1/1`
|
|
||||||
}}
|
|
||||||
></label> */}
|
|
||||||
|
|
||||||
|
|
||||||
{/* <input type="file"
|
|
||||||
name="avatarinput"
|
|
||||||
id="avatarinput"
|
|
||||||
disabled={inProgress}
|
|
||||||
ref={avatarinput}
|
|
||||||
onChange={uploadIt}
|
|
||||||
style={{
|
|
||||||
position: `relative`,
|
|
||||||
zIndex: `-1`,
|
|
||||||
opacity: '0'
|
|
||||||
}}
|
|
||||||
accept="image/gif, image/jpeg, image/png"
|
|
||||||
/> */}
|
|
||||||
<hr />
|
|
||||||
<AvatarFileUpload />
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<label htmlFor="username">Nom d'usuari: </label>
|
<label htmlFor="username">Nom d'usuari: </label>
|
||||||
<input id="username" name="username" type="text" required />
|
<input id="username" name="username" type="text" required />
|
||||||
|
|||||||
@ -1,226 +0,0 @@
|
|||||||
import { useTracker, useSubscribe, useFind } from 'meteor/react-meteor-data/suspense';
|
|
||||||
import { Meteor } from 'meteor/meteor';
|
|
||||||
import React, { useState, useRef, Suspense } from 'react';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
import { AvatarsRegistre } from '/imports/api/files.js';
|
|
||||||
|
|
||||||
import IndividualFileStart from '/imports/ui/files/IndividualFile.jsx'; // <-------------------------
|
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
//const debug = require('debug')('demo:file');
|
|
||||||
|
|
||||||
const AvatarFileUpload = (props) => {
|
|
||||||
|
|
||||||
const [uploading, setUploading] = useState([]);
|
|
||||||
const [progress, setProgress] = useState(0);
|
|
||||||
const [inProgress, setInProgress] = useState(false);
|
|
||||||
|
|
||||||
const [preview, setPreview] = useState("");
|
|
||||||
|
|
||||||
// const reseter = useState(0);
|
|
||||||
|
|
||||||
// const refForm = useRef();
|
|
||||||
const fileinput = useRef();
|
|
||||||
|
|
||||||
useSubscribe('avatarsregistre.all');
|
|
||||||
|
|
||||||
const files = useFind(AvatarsRegistre, [
|
|
||||||
{},
|
|
||||||
{ sort: { createdAt: -1 } },
|
|
||||||
]);
|
|
||||||
|
|
||||||
// const files = useTracker("avatars", async () => {
|
|
||||||
// // const docsReadyYet = filesHandle.ready();
|
|
||||||
// const files = await AvatarsRegistre?.find({meta:{userId: props.uidProvisional || Meteor.userId(), entId: props.entId}}, {sort: {name: 1}})//.fetchAsync(); // Meteor.userId() ?? "nop"
|
|
||||||
|
|
||||||
// return files;
|
|
||||||
// }, []);
|
|
||||||
|
|
||||||
function uploadIt(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
//let self = this;
|
|
||||||
|
|
||||||
if (e.currentTarget.files && e.currentTarget.files[0]) {
|
|
||||||
// We upload only one file, in case
|
|
||||||
// there was multiple files selected
|
|
||||||
var file = e.currentTarget.files[0];
|
|
||||||
|
|
||||||
const reader = new FileReader();
|
|
||||||
|
|
||||||
reader.onload = (event) => {
|
|
||||||
console.log("eventTarget: ", event.target);
|
|
||||||
setPreview(event.target.result);
|
|
||||||
};
|
|
||||||
|
|
||||||
reader.readAsDataURL(file);
|
|
||||||
|
|
||||||
// setPreview(file);
|
|
||||||
|
|
||||||
if (file) {
|
|
||||||
let uploadInstance = AvatarsRegistre.insert({
|
|
||||||
file,
|
|
||||||
meta: {
|
|
||||||
locator: props.fileLocator,
|
|
||||||
userId: props.uidProvisional || Meteor.userId(), // Optional, used to check on server for file tampering
|
|
||||||
entId: props.entId
|
|
||||||
},
|
|
||||||
chunkSize: 'dynamic',
|
|
||||||
allowWebWorkers: true // If you see issues with uploads, change this to false
|
|
||||||
}, false)
|
|
||||||
|
|
||||||
setUploading(uploadInstance); // Keep track of this instance to use below
|
|
||||||
setInProgress(true); // Show the progress bar now
|
|
||||||
|
|
||||||
// These are the event functions, don't need most of them, it shows where we are in the process
|
|
||||||
uploadInstance.on('start', function () {
|
|
||||||
console.log('Starting');
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('end', function (error, fileObj) {
|
|
||||||
console.log('On end File Object: ', fileObj);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('uploaded', function (error, fileObj) {
|
|
||||||
console.log('uploaded: ', fileObj);
|
|
||||||
|
|
||||||
// props.setUpId(fileObj._id);
|
|
||||||
|
|
||||||
// Remove the filename from the upload box
|
|
||||||
fileinput.current.value = '';
|
|
||||||
|
|
||||||
// Reset our state for the next file
|
|
||||||
setUploading([]);
|
|
||||||
setProgress(0);
|
|
||||||
setInProgress(false);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('error', function (error, fileObj) {
|
|
||||||
console.log('Error during upload: ' + error)
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.on('progress', function (progress, fileObj) {
|
|
||||||
console.log('Upload Percentage: ' + progress)
|
|
||||||
// Update our progress bar
|
|
||||||
setProgress(progress);
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.start(); // Must manually start the upload
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is our progress bar, bootstrap styled
|
|
||||||
// Remove this function if not needed
|
|
||||||
function UploadingFile({preview}) {
|
|
||||||
|
|
||||||
// console.log('**********************************', uploading);
|
|
||||||
|
|
||||||
if (!_.isEmpty(uploading)) {
|
|
||||||
// console.log("uploading: ", uploading);
|
|
||||||
// console.log("preview: ", preview);
|
|
||||||
return <div>
|
|
||||||
<img
|
|
||||||
src={preview}
|
|
||||||
alt=""
|
|
||||||
style={{
|
|
||||||
border: `solid 3px #6666`,
|
|
||||||
borderRadius: `50%`,
|
|
||||||
width: `5rem`,
|
|
||||||
margin: `0 auto`,
|
|
||||||
display: `block`
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
{/* {uploading.file.name} */}
|
|
||||||
|
|
||||||
<div className="progress progress-bar-default">
|
|
||||||
<div style={{width: progress + '%', backgroundColor: `lime`, borderRadius: `1rem`, textAlign: `center`, boxShadow: `inset 0 0 .5rem .5rem #4447`}} aria-valuemax="100"
|
|
||||||
aria-valuemin="0"
|
|
||||||
aria-valuenow={progress || 0} role="progressbar"
|
|
||||||
className="progress-bar"
|
|
||||||
>
|
|
||||||
<span className="sr-only">{progress}% Complete (success)</span>
|
|
||||||
{/* <span>{progress}%</span> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const Display = async () => await files?.map(async (aFile, key) => {
|
|
||||||
|
|
||||||
let link = await AvatarsRegistre.findOneAsync({_id: aFile._id}); //The "view/download" link
|
|
||||||
let linkOriginalURL = `${window.location.origin}${link._fileRef._downloadRoute}/${link._fileRef._collectionName}/${link._fileRef._id}/original/${link._fileRef._id}.${link._fileRef.extension}`;
|
|
||||||
|
|
||||||
// Send out components that show details of each file
|
|
||||||
|
|
||||||
return <Suspense fallback="<>Loading...</>">
|
|
||||||
<div key={'file' + key}>
|
|
||||||
<IndividualFileStart
|
|
||||||
fileName={aFile.name}
|
|
||||||
fileUrl={linkOriginalURL}
|
|
||||||
fileId={aFile._id}
|
|
||||||
fileSize={aFile.size}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Suspense>
|
|
||||||
}).reverse();
|
|
||||||
|
|
||||||
// Run through each file that the user has stored
|
|
||||||
// (make sure the subscription only sends files owned by this user)
|
|
||||||
// let display =
|
|
||||||
|
|
||||||
return <Suspense fallback="Loading...">
|
|
||||||
|
|
||||||
<button
|
|
||||||
className='btArxiu'
|
|
||||||
onClick={ev => {
|
|
||||||
ev.preventDefault();
|
|
||||||
|
|
||||||
// refForm.current.reset();
|
|
||||||
fileinput.current.click();
|
|
||||||
//reseter[1](reseter[0] + 1);
|
|
||||||
//refForm.current.reset();
|
|
||||||
ev.target.value = null;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="fa-solid fa-paperclip" >Add file</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<input type="file"
|
|
||||||
id="fileinput"
|
|
||||||
disabled={inProgress}
|
|
||||||
ref={fileinput}
|
|
||||||
onChange={uploadIt}
|
|
||||||
style={{display: `none`}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<UploadingFile {...{preview}} />
|
|
||||||
<Display />
|
|
||||||
|
|
||||||
</Suspense>
|
|
||||||
// else return <div>Carregant llista d'arxius...</div>;
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// This is the HOC - included in this file just for convenience, but usually kept
|
|
||||||
// in a separate file to provide separation of concerns.
|
|
||||||
//
|
|
||||||
// export default withTracker( ( props ) => {
|
|
||||||
|
|
||||||
// const filesHandle = Meteor.subscribe('files.all');
|
|
||||||
// const docsReadyYet = filesHandle.ready();
|
|
||||||
// const files = AvatarsRegistre.find({meta:{userId: props.uidProvisional || Meteor.userId()}}, {sort: {name: 1}}).fetch(); // Meteor.userId() ?? "nop"
|
|
||||||
|
|
||||||
// return {
|
|
||||||
// docsReadyYet,
|
|
||||||
// files,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// })(FileUploadComponent);
|
|
||||||
|
|
||||||
export default AvatarFileUpload;
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
const AvatarIndividualFile = props => {
|
|
||||||
|
|
||||||
// propTypes: {
|
|
||||||
// fileName: PropTypes.string.isRequired,
|
|
||||||
// fileSize: PropTypes.number.isRequired,
|
|
||||||
// fileUrl: PropTypes.string,
|
|
||||||
// fileId: PropTypes.string.isRequired
|
|
||||||
// }
|
|
||||||
|
|
||||||
function removeFile(){
|
|
||||||
let conf = confirm('Are you sure you want to delete the file?') || false;
|
|
||||||
if (conf == true) {
|
|
||||||
Meteor.call('RemoveFile', props.fileId, function (err, res) {
|
|
||||||
if (err)
|
|
||||||
console.log(err);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function renameFile(){
|
|
||||||
|
|
||||||
let validName = /[^a-zA-Z0-9 \.:\+()\-_%!&]/gi;
|
|
||||||
let prompt = window.prompt('New file name?', props.fileName);
|
|
||||||
|
|
||||||
// Replace any non valid characters, also do this on the server
|
|
||||||
if (prompt) {
|
|
||||||
prompt = prompt.replace(validName, '-');
|
|
||||||
prompt.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_.isEmpty(prompt)) {
|
|
||||||
Meteor.call('RenameFile', props.fileId, prompt, function (err, res) {
|
|
||||||
if (err)
|
|
||||||
console.log(err);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return <div className="m-t-sm">
|
|
||||||
<img
|
|
||||||
src={props.fileUrl}
|
|
||||||
alt={props.fileName}
|
|
||||||
style={{maxWidth: `200px`, maxHeight: `200px`}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-12">
|
|
||||||
<strong>{props.fileName}</strong>
|
|
||||||
<div className="m-b-sm">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* <div className="row">
|
|
||||||
<div className="col-md-3">
|
|
||||||
<button onClick={renameFile} className="btn btn-outline btn-primary btn-sm">
|
|
||||||
Rename
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div className="col-md-3">
|
|
||||||
<a href={props.fileUrl} className="btn btn-outline btn-primary btn-sm"
|
|
||||||
target="_blank">View</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-md-2">
|
|
||||||
<button onClick={removeFile} className="btn btn-outline btn-danger btn-sm">
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-md-4">
|
|
||||||
Size: {props.fileSize}
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
export default AvatarIndividualFile;
|
|
||||||
@ -1,204 +0,0 @@
|
|||||||
import { useSubscribe, useFind, useTracker } from 'meteor/react-meteor-data';
|
|
||||||
import { Meteor } from 'meteor/meteor';
|
|
||||||
import React, { useState, useRef } from 'react';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
import { FilesCol } from '/imports/api/files.js';
|
|
||||||
|
|
||||||
import IndividualFile from '/imports/ui/files/IndividualFile.jsx';
|
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
// const debug = require('debug')('demo:file');
|
|
||||||
|
|
||||||
const FileUploadComponent = (props) => {
|
|
||||||
|
|
||||||
const [uploading, setUploading] = useState([]);
|
|
||||||
const [progress, setProgress] = useState(0);
|
|
||||||
const [inProgress, setInProgress] = useState(false);
|
|
||||||
|
|
||||||
const fileinput = useRef();
|
|
||||||
|
|
||||||
const isLoading = useSubscribe('files.all');
|
|
||||||
|
|
||||||
const files = useTracker(() => {
|
|
||||||
// const filesHandle = Meteor.subscribe('files.all');
|
|
||||||
// const docsReadyYet = filesHandle.ready();
|
|
||||||
//const files = FilesCol?.find({meta:{userId: props.uidProvisional || Meteor.userId()}}, {sort: {name: 1}}); // Meteor.userId() ?? "nop"
|
|
||||||
|
|
||||||
console.dir("files from FU: ", files.cursor);
|
|
||||||
|
|
||||||
return files;
|
|
||||||
}, [isLoading()]);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
console.dir("fufiles: ", files);
|
|
||||||
|
|
||||||
|
|
||||||
function uploadIt(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
//let self = this;
|
|
||||||
|
|
||||||
if (e.currentTarget.files && e.currentTarget.files[0]) {
|
|
||||||
// We upload only one file, in case
|
|
||||||
// there was multiple files selected
|
|
||||||
var file = e.currentTarget.files[0];
|
|
||||||
|
|
||||||
if (file) {
|
|
||||||
let uploadInstance = FilesCol.insertAsync({
|
|
||||||
file,
|
|
||||||
meta: {
|
|
||||||
locator: props.fileLocator,
|
|
||||||
userId: props.uidProvisional || Meteor.userId() // Optional, used to check on server for file tampering
|
|
||||||
},
|
|
||||||
chunkSize: 'dynamic',
|
|
||||||
allowWebWorkers: true // If you see issues with uploads, change this to false
|
|
||||||
}, false)
|
|
||||||
|
|
||||||
setUploading(uploadInstance); // Keep track of this instance to use below
|
|
||||||
setInProgress(true);// Show the progress bar now
|
|
||||||
|
|
||||||
// These are the event functions, don't need most of them, it shows where we are in the process
|
|
||||||
uploadInstance.on('start', function () {
|
|
||||||
console.log('Starting');
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('end', function (error, fileObj) {
|
|
||||||
console.log('On end File Object: ', fileObj);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('uploaded', function (error, fileObj) {
|
|
||||||
// console.dir("uploaded: this ", this.config.fileId);
|
|
||||||
// console.log('uploaded: ', fileObj);
|
|
||||||
|
|
||||||
// console.log("upError: ", error);
|
|
||||||
props?.setUpId(fileObj?.config.fileId);
|
|
||||||
|
|
||||||
// Remove the filename from the upload box
|
|
||||||
fileinput.current.value = '';
|
|
||||||
|
|
||||||
// Reset our state for the next file
|
|
||||||
setUploading([]);
|
|
||||||
setProgress(0);
|
|
||||||
setInProgress(false);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('error', function (error, fileObj) {
|
|
||||||
console.log('Error during upload: ' + error)
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.on('progress', function (progress, fileObj) {
|
|
||||||
console.log('Upload Percentage: ' + progress)
|
|
||||||
// Update our progress bar
|
|
||||||
setProgress(progress);
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.start(); // Must manually start the upload
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is our progress bar, bootstrap styled
|
|
||||||
// Remove this function if not needed
|
|
||||||
function showUploads() {
|
|
||||||
console.log('**********************************', uploading);
|
|
||||||
|
|
||||||
if (!_.isEmpty(uploading)) {
|
|
||||||
return <div>
|
|
||||||
{uploading.file.name}
|
|
||||||
|
|
||||||
<div className="progress progress-bar-default">
|
|
||||||
<div style={{width: progress + '%'}} aria-valuemax="100"
|
|
||||||
aria-valuemin="0"
|
|
||||||
aria-valuenow={progress || 0} role="progressbar"
|
|
||||||
className="progress-bar"
|
|
||||||
>
|
|
||||||
<span className="sr-only">{progress}% Complete (success)</span>
|
|
||||||
<span>{progress}%</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
// debug("Rendering FileUpload",docsReadyYet);
|
|
||||||
// if(!isLoading() && files)
|
|
||||||
//if (files /* && docsReadyYet*/) {
|
|
||||||
{
|
|
||||||
console.dir("FUfiles: ", files);
|
|
||||||
//let fileCursors = files;
|
|
||||||
|
|
||||||
// console.dir("fileCursors: ", fileCursors);
|
|
||||||
|
|
||||||
// Run through each file that the user has stored
|
|
||||||
// (make sure the subscription only sends files owned by this user)
|
|
||||||
let display = files?.map(async (aFile, key) => {
|
|
||||||
console.log('A file: ', aFile.link(), aFile.get('name'))
|
|
||||||
let link = await FilesCol.findOneAsync({_id: aFile._id}).link(); //The "view/download" link
|
|
||||||
|
|
||||||
console.log("link: ", link);
|
|
||||||
|
|
||||||
// Send out components that show details of each file
|
|
||||||
return <div key={'file' + key}>
|
|
||||||
<IndividualFile
|
|
||||||
fileName={aFile.name}
|
|
||||||
fileUrl={link}
|
|
||||||
fileId={aFile._id}
|
|
||||||
fileSize={aFile.size}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
})
|
|
||||||
|
|
||||||
return <div>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-12">
|
|
||||||
<p>Upload New File:</p>
|
|
||||||
<input type="file"
|
|
||||||
id="fileinput"
|
|
||||||
disabled={inProgress}
|
|
||||||
ref={fileinput}
|
|
||||||
onChange={uploadIt}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row m-t-sm m-b-sm">
|
|
||||||
<div className="col-md-6">
|
|
||||||
|
|
||||||
{showUploads()}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div className="col-md-6">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{display}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
// else return <div>Loading file list</div>;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// This is the HOC - included in this file just for convenience, but usually kept
|
|
||||||
// in a separate file to provide separation of concerns.
|
|
||||||
//
|
|
||||||
// export default withTracker( ( props ) => {
|
|
||||||
|
|
||||||
// const filesHandle = Meteor.subscribe('files.all');
|
|
||||||
// const docsReadyYet = filesHandle.ready();
|
|
||||||
// const files = FilesCol.find({meta:{userId: props.uidProvisional || Meteor.userId()}}, {sort: {name: 1}}).fetch(); // Meteor.userId() ?? "nop"
|
|
||||||
|
|
||||||
// return {
|
|
||||||
// docsReadyYet,
|
|
||||||
// files,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// })(FileUploadComponent);
|
|
||||||
|
|
||||||
export default FileUploadComponent;
|
|
||||||
@ -1,208 +0,0 @@
|
|||||||
import { useTracker } from 'meteor/react-meteor-data';
|
|
||||||
import { Meteor } from 'meteor/meteor';
|
|
||||||
import React, { useState, useRef } from 'react';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
import { FilesCol } from '/imports/api/files.js';
|
|
||||||
import IndividualFile from '/imports/ui/files/IndividualFile.jsx';
|
|
||||||
import _ from 'lodash';
|
|
||||||
// import { useUser } from 'meteor/react-meteor-accounts';
|
|
||||||
// import { Roles } from 'meteor/alanning:roles';
|
|
||||||
// import { GLOBAL_ROLES } from '../roles';
|
|
||||||
// import { useTracker } from 'meteor/react-meteor-data';
|
|
||||||
|
|
||||||
//const debug = require('debug')('demo:file');
|
|
||||||
|
|
||||||
const FileUploadAdmin = (props) => {
|
|
||||||
|
|
||||||
// const user = useUser();
|
|
||||||
// const isAdmin = useTracker(() => Roles.userIsInRole(user?._id, GLOBAL_ROLES.ADMIN));
|
|
||||||
|
|
||||||
const [uploading, setUploading] = useState([]);
|
|
||||||
const [progress, setProgress] = useState(0);
|
|
||||||
const [inProgress, setInProgress] = useState(false);
|
|
||||||
|
|
||||||
const reseter = useState(0);
|
|
||||||
|
|
||||||
const refForm = useRef();
|
|
||||||
const fileinput = useRef();
|
|
||||||
|
|
||||||
const files = useTracker(() => {
|
|
||||||
const filesHandle = Meteor.subscribe('files.all');
|
|
||||||
// const docsReadyYet = filesHandle.ready();
|
|
||||||
const files = FilesCol?.find({meta:{userId: props.uidProvisional || Meteor.userId(), entId: props.entId}}, {sort: {name: 1}}).fetch(); // Meteor.userId() ?? "nop"
|
|
||||||
|
|
||||||
return files;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function uploadIt(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
//let self = this;
|
|
||||||
|
|
||||||
if (e.currentTarget.files && e.currentTarget.files[0]) {
|
|
||||||
// We upload only one file, in case
|
|
||||||
// there was multiple files selected
|
|
||||||
var file = e.currentTarget.files[0];
|
|
||||||
|
|
||||||
if (file) {
|
|
||||||
let uploadInstance = FilesCol.insert({
|
|
||||||
file,
|
|
||||||
meta: {
|
|
||||||
locator: props.fileLocator,
|
|
||||||
userId: props.uidProvisional || Meteor.userId(), // Optional, used to check on server for file tampering
|
|
||||||
entId: props.entId
|
|
||||||
},
|
|
||||||
chunkSize: 'dynamic',
|
|
||||||
allowWebWorkers: true // If you see issues with uploads, change this to false
|
|
||||||
}, false)
|
|
||||||
|
|
||||||
setUploading(uploadInstance); // Keep track of this instance to use below
|
|
||||||
setInProgress(true); // Show the progress bar now
|
|
||||||
|
|
||||||
// These are the event functions, don't need most of them, it shows where we are in the process
|
|
||||||
uploadInstance.on('start', function () {
|
|
||||||
console.log('Starting');
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('end', function (error, fileObj) {
|
|
||||||
console.log('On end File Object: ', fileObj);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('uploaded', function (error, fileObj) {
|
|
||||||
console.log('uploaded: ', fileObj);
|
|
||||||
|
|
||||||
// props.setUpId(fileObj._id);
|
|
||||||
|
|
||||||
// Remove the filename from the upload box
|
|
||||||
fileinput.current.value = '';
|
|
||||||
|
|
||||||
// Reset our state for the next file
|
|
||||||
setUploading([]);
|
|
||||||
setProgress(0);
|
|
||||||
setInProgress(false);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('error', function (error, fileObj) {
|
|
||||||
console.log('Error during upload: ' + error)
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.on('progress', function (progress, fileObj) {
|
|
||||||
console.log('Upload Percentage: ' + progress)
|
|
||||||
// Update our progress bar
|
|
||||||
setProgress(progress);
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.start(); // Must manually start the upload
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is our progress bar, bootstrap styled
|
|
||||||
// Remove this function if not needed
|
|
||||||
function showUploads() {
|
|
||||||
console.log('**********************************', uploading);
|
|
||||||
|
|
||||||
if (!_.isEmpty(uploading)) {
|
|
||||||
return <div>
|
|
||||||
{uploading.file.name}
|
|
||||||
|
|
||||||
<div className="progress progress-bar-default">
|
|
||||||
<div style={{width: progress + '%'}} aria-valuemax="100"
|
|
||||||
aria-valuemin="0"
|
|
||||||
aria-valuenow={progress || 0} role="progressbar"
|
|
||||||
className="progress-bar">
|
|
||||||
<span className="sr-only">{progress}% Complete (success)</span>
|
|
||||||
<span>{progress}%</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
// debug("Rendering FileUpload",docsReadyYet);
|
|
||||||
if (files /* && docsReadyYet*/) {
|
|
||||||
|
|
||||||
let fileCursors = files;
|
|
||||||
|
|
||||||
// Run through each file that the user has stored
|
|
||||||
// (make sure the subscription only sends files owned by this user)
|
|
||||||
let display = fileCursors.map((aFile, key) => {
|
|
||||||
// console.log('A file: ', aFile.link(), aFile.get('name'))
|
|
||||||
let link = FilesCol.findOne({_id: aFile._id}).link(); //The "view/download" link
|
|
||||||
|
|
||||||
// Send out components that show details of each file
|
|
||||||
return <div key={'file' + key}>
|
|
||||||
<IndividualFile
|
|
||||||
fileName={aFile.name}
|
|
||||||
fileUrl={link}
|
|
||||||
fileId={aFile._id}
|
|
||||||
fileSize={aFile.size}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
})
|
|
||||||
|
|
||||||
return <>
|
|
||||||
|
|
||||||
|
|
||||||
<button
|
|
||||||
className='btArxiu'
|
|
||||||
onClick={ev => {
|
|
||||||
ev.preventDefault();
|
|
||||||
|
|
||||||
// refForm.current.reset();
|
|
||||||
fileinput.current.click();
|
|
||||||
//reseter[1](reseter[0] + 1);
|
|
||||||
//refForm.current.reset();
|
|
||||||
ev.target.value = null;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="fas fa-paperclip" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<input type="file"
|
|
||||||
id="fileinput"
|
|
||||||
disabled={inProgress}
|
|
||||||
ref={fileinput}
|
|
||||||
onChange={uploadIt}
|
|
||||||
style={{display: `none`}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
|
||||||
{/* <div className="row m-t-sm m-b-sm">
|
|
||||||
<div className="col-md-6">
|
|
||||||
|
|
||||||
{showUploads()}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
|
|
||||||
{/* {display} */}
|
|
||||||
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
else return <div>Carregant llista d'arxius...</div>;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// This is the HOC - included in this file just for convenience, but usually kept
|
|
||||||
// in a separate file to provide separation of concerns.
|
|
||||||
//
|
|
||||||
// export default withTracker( ( props ) => {
|
|
||||||
|
|
||||||
// const filesHandle = Meteor.subscribe('files.all');
|
|
||||||
// const docsReadyYet = filesHandle.ready();
|
|
||||||
// const files = FilesCol.find({meta:{userId: props.uidProvisional || Meteor.userId()}}, {sort: {name: 1}}).fetch(); // Meteor.userId() ?? "nop"
|
|
||||||
|
|
||||||
// return {
|
|
||||||
// docsReadyYet,
|
|
||||||
// files,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// })(FileUploadComponent);
|
|
||||||
|
|
||||||
export default FileUploadAdmin;
|
|
||||||
@ -1,203 +0,0 @@
|
|||||||
import { useTracker } from 'meteor/react-meteor-data';
|
|
||||||
import { Meteor } from 'meteor/meteor';
|
|
||||||
import React, { useState, useRef } from 'react';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
import { FilesCol } from '/imports/api/files.js';
|
|
||||||
|
|
||||||
import IndividualFile from '/imports/ui/files/IndividualFile.jsx';
|
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
//const debug = require('debug')('demo:file');
|
|
||||||
|
|
||||||
const FileUploadEnt = (props) => {
|
|
||||||
|
|
||||||
const [uploading, setUploading] = useState([]);
|
|
||||||
const [progress, setProgress] = useState(0);
|
|
||||||
const [inProgress, setInProgress] = useState(false);
|
|
||||||
|
|
||||||
const reseter = useState(0);
|
|
||||||
|
|
||||||
const refForm = useRef();
|
|
||||||
const fileinput = useRef();
|
|
||||||
|
|
||||||
const files = useTracker(() => {
|
|
||||||
const filesHandle = Meteor.subscribe('files.all');
|
|
||||||
// const docsReadyYet = filesHandle.ready();
|
|
||||||
const files = FilesCol?.find({meta:{userId: props.uidProvisional || Meteor.userId(), entId: props.entId}}, {sort: {name: 1}}).fetch(); // Meteor.userId() ?? "nop"
|
|
||||||
|
|
||||||
return files;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function uploadIt(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
//let self = this;
|
|
||||||
|
|
||||||
if (e.currentTarget.files && e.currentTarget.files[0]) {
|
|
||||||
// We upload only one file, in case
|
|
||||||
// there was multiple files selected
|
|
||||||
var file = e.currentTarget.files[0];
|
|
||||||
|
|
||||||
if (file) {
|
|
||||||
let uploadInstance = FilesCol.insert({
|
|
||||||
file,
|
|
||||||
meta: {
|
|
||||||
locator: props.fileLocator,
|
|
||||||
userId: props.uidProvisional || Meteor.userId(), // Optional, used to check on server for file tampering
|
|
||||||
entId: props.entId
|
|
||||||
},
|
|
||||||
chunkSize: 'dynamic',
|
|
||||||
allowWebWorkers: true // If you see issues with uploads, change this to false
|
|
||||||
}, false)
|
|
||||||
|
|
||||||
setUploading(uploadInstance); // Keep track of this instance to use below
|
|
||||||
setInProgress(true); // Show the progress bar now
|
|
||||||
|
|
||||||
// These are the event functions, don't need most of them, it shows where we are in the process
|
|
||||||
uploadInstance.on('start', function () {
|
|
||||||
console.log('Starting');
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('end', function (error, fileObj) {
|
|
||||||
console.log('On end File Object: ', fileObj);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('uploaded', function (error, fileObj) {
|
|
||||||
console.log('uploaded: ', fileObj);
|
|
||||||
|
|
||||||
// props.setUpId(fileObj._id);
|
|
||||||
|
|
||||||
// Remove the filename from the upload box
|
|
||||||
fileinput.current.value = '';
|
|
||||||
|
|
||||||
// Reset our state for the next file
|
|
||||||
setUploading([]);
|
|
||||||
setProgress(0);
|
|
||||||
setInProgress(false);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('error', function (error, fileObj) {
|
|
||||||
console.log('Error during upload: ' + error)
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.on('progress', function (progress, fileObj) {
|
|
||||||
console.log('Upload Percentage: ' + progress)
|
|
||||||
// Update our progress bar
|
|
||||||
setProgress(progress);
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.start(); // Must manually start the upload
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is our progress bar, bootstrap styled
|
|
||||||
// Remove this function if not needed
|
|
||||||
function showUploads() {
|
|
||||||
console.log('**********************************', uploading);
|
|
||||||
|
|
||||||
if (!_.isEmpty(uploading)) {
|
|
||||||
return <div>
|
|
||||||
{uploading.file.name}
|
|
||||||
|
|
||||||
<div className="progress progress-bar-default">
|
|
||||||
<div style={{width: progress + '%'}} aria-valuemax="100"
|
|
||||||
aria-valuemin="0"
|
|
||||||
aria-valuenow={progress || 0} role="progressbar"
|
|
||||||
className="progress-bar">
|
|
||||||
<span className="sr-only">{progress}% Complete (success)</span>
|
|
||||||
<span>{progress}%</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
// debug("Rendering FileUpload",docsReadyYet);
|
|
||||||
if (files /* && docsReadyYet*/) {
|
|
||||||
|
|
||||||
let fileCursors = files;
|
|
||||||
|
|
||||||
// Run through each file that the user has stored
|
|
||||||
// (make sure the subscription only sends files owned by this user)
|
|
||||||
let display = fileCursors.map((aFile, key) => {
|
|
||||||
// console.log('A file: ', aFile.link(), aFile.get('name'))
|
|
||||||
let link = FilesCol.findOne({_id: aFile._id}).link(); //The "view/download" link
|
|
||||||
|
|
||||||
// Send out components that show details of each file
|
|
||||||
return <div key={'file' + key}>
|
|
||||||
<IndividualFile
|
|
||||||
fileName={aFile.name}
|
|
||||||
fileUrl={link}
|
|
||||||
fileId={aFile._id}
|
|
||||||
fileSize={aFile.size}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
})
|
|
||||||
|
|
||||||
return <>
|
|
||||||
|
|
||||||
|
|
||||||
<button
|
|
||||||
className='btArxiu'
|
|
||||||
onClick={ev => {
|
|
||||||
ev.preventDefault();
|
|
||||||
|
|
||||||
// refForm.current.reset();
|
|
||||||
fileinput.current.click();
|
|
||||||
//reseter[1](reseter[0] + 1);
|
|
||||||
//refForm.current.reset();
|
|
||||||
ev.target.value = null;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="fas fa-paperclip" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<input type="file"
|
|
||||||
id="fileinput"
|
|
||||||
disabled={inProgress}
|
|
||||||
ref={fileinput}
|
|
||||||
onChange={uploadIt}
|
|
||||||
style={{display: `none`}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
|
||||||
{/* <div className="row m-t-sm m-b-sm">
|
|
||||||
<div className="col-md-6">
|
|
||||||
|
|
||||||
{showUploads()}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
|
|
||||||
{/* {display} */}
|
|
||||||
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
else return <div>Carregant llista d'arxius...</div>;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// This is the HOC - included in this file just for convenience, but usually kept
|
|
||||||
// in a separate file to provide separation of concerns.
|
|
||||||
//
|
|
||||||
// export default withTracker( ( props ) => {
|
|
||||||
|
|
||||||
// const filesHandle = Meteor.subscribe('files.all');
|
|
||||||
// const docsReadyYet = filesHandle.ready();
|
|
||||||
// const files = FilesCol.find({meta:{userId: props.uidProvisional || Meteor.userId()}}, {sort: {name: 1}}).fetch(); // Meteor.userId() ?? "nop"
|
|
||||||
|
|
||||||
// return {
|
|
||||||
// docsReadyYet,
|
|
||||||
// files,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// })(FileUploadComponent);
|
|
||||||
|
|
||||||
export default FileUploadEnt;
|
|
||||||
@ -1,235 +0,0 @@
|
|||||||
import { useTracker, useSubscribe, useFind } from 'meteor/react-meteor-data/suspense';
|
|
||||||
import { Meteor } from 'meteor/meteor';
|
|
||||||
import React, { useState, useRef, Suspense } from 'react';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
import { FilesCol } from '/imports/api/files.js';
|
|
||||||
|
|
||||||
import IndividualFilePOI from '/imports/ui/files/IndividualFilePOI.jsx'; // <-------------------------
|
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
//const debug = require('debug')('demo:file');
|
|
||||||
|
|
||||||
const useFiles = () => {
|
|
||||||
useSubscribe('files.all');
|
|
||||||
|
|
||||||
const files = useTracker("files", () => FilesCol.find({}).fetchAsync(), []);
|
|
||||||
|
|
||||||
return files;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const ShowUploads = ({uploading, progress, filePreviewURI, inProgress}) => {
|
|
||||||
// console.log('**********************************', uploading);
|
|
||||||
|
|
||||||
if (!_.isEmpty(uploading)) {
|
|
||||||
// console.log("uploading: ", uploading);
|
|
||||||
return inProgress && <div style={{
|
|
||||||
border: `1px solid`,
|
|
||||||
borderRadius: `5px`,
|
|
||||||
color: `#cccc`,
|
|
||||||
padding: `1rem`,
|
|
||||||
marginBottom: `1em`
|
|
||||||
}}>
|
|
||||||
{uploading.file.name}
|
|
||||||
|
|
||||||
<img src={filePreviewURI} />
|
|
||||||
<div className="progress progress-bar-default">
|
|
||||||
<div style={{width: progress + '%'}} aria-valuemax="100"
|
|
||||||
aria-valuemin="0"
|
|
||||||
aria-valuenow={progress || 0} role="progressbar"
|
|
||||||
className="progress-bar"
|
|
||||||
>
|
|
||||||
<span className="sr-only">{progress}% Complete (success)</span>
|
|
||||||
<span>{progress}%</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const DisplayUploadFile = ({files}) => files?.map(async (aFile, key) => {
|
|
||||||
|
|
||||||
let link = await FilesCol.findOneAsync({_id: aFile._id}); //The "view/download" link
|
|
||||||
let linkOriginalURL = `${window.location.origin}${link._fileRef._downloadRoute}/${link._fileRef._collectionName}/${link._fileRef._id}/original/${link._fileRef._id}.${link._fileRef.extension}`;
|
|
||||||
|
|
||||||
// Send out components that show details of each file
|
|
||||||
|
|
||||||
return <div key={'file' + key}>
|
|
||||||
<IndividualFilePOI
|
|
||||||
fileName={aFile.name}
|
|
||||||
fileUrl={linkOriginalURL}
|
|
||||||
fileId={aFile._id}
|
|
||||||
fileSize={aFile.size}
|
|
||||||
/>
|
|
||||||
</div>;
|
|
||||||
}).reverse();
|
|
||||||
|
|
||||||
|
|
||||||
const FileUploadPOI = (props) => {
|
|
||||||
|
|
||||||
const [uploading, setUploading] = useState([]);
|
|
||||||
const [progress, setProgress] = useState(0);
|
|
||||||
const [inProgress, setInProgress] = useState(false);
|
|
||||||
|
|
||||||
const [filePreviewURI, setFilePreviewURI] = useState(null);
|
|
||||||
|
|
||||||
const fileinput = useRef();
|
|
||||||
|
|
||||||
const files = useFiles();
|
|
||||||
|
|
||||||
console.log("files: ", files);
|
|
||||||
// console.log("fileinput: ", fileinput);
|
|
||||||
|
|
||||||
function uploadIt(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
console.log("UPLOADING IT");
|
|
||||||
|
|
||||||
if (e.currentTarget.files && e.currentTarget.files[0]) {
|
|
||||||
// We upload only one file, in case
|
|
||||||
// there was multiple files selected
|
|
||||||
var file = e.currentTarget.files[0];
|
|
||||||
|
|
||||||
console.log("E: ", e);
|
|
||||||
console.log("FILE: ", file);
|
|
||||||
|
|
||||||
if (file) {
|
|
||||||
|
|
||||||
let reader = new FileReader();
|
|
||||||
|
|
||||||
console.log("READER: ", reader);
|
|
||||||
|
|
||||||
// reader.onload = (evt) => {
|
|
||||||
// console.log("ONLOAD: ", evt.target.result);
|
|
||||||
// };
|
|
||||||
reader.readAsDataURL(e.currentTarget.files[0]);
|
|
||||||
|
|
||||||
reader.onload = function(ev){
|
|
||||||
|
|
||||||
|
|
||||||
console.log("ev.target.result: ", ev.target.result);
|
|
||||||
|
|
||||||
setFilePreviewURI(ev.target.result);
|
|
||||||
|
|
||||||
console.log("filePreviewURI: ", filePreviewURI);
|
|
||||||
|
|
||||||
|
|
||||||
let uploadInstance = FilesCol.insert({
|
|
||||||
file,
|
|
||||||
meta: {
|
|
||||||
locator: props.fileLocator,
|
|
||||||
userId: props.uidProvisional || Meteor.userId(), // Optional, used to check on server for file tampering
|
|
||||||
entId: props.entId
|
|
||||||
},
|
|
||||||
chunkSize: 'dynamic',
|
|
||||||
allowWebWorkers: true // If you see issues with uploads, change this to false
|
|
||||||
}, false)
|
|
||||||
|
|
||||||
setUploading(uploadInstance); // Keep track of this instance to use below
|
|
||||||
console.log("setInProgress: true");
|
|
||||||
setInProgress(true); // Show the progress bar now
|
|
||||||
|
|
||||||
// These are the event functions, don't need most of them, it shows where we are in the process
|
|
||||||
uploadInstance.on('start', function () {
|
|
||||||
console.log('Starting');
|
|
||||||
console.log("file: ", file);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('End', function (error, fileObj) {
|
|
||||||
console.log('On end File Object: ', fileObj);
|
|
||||||
setProgress(0);
|
|
||||||
console.log("setInProgress: false");
|
|
||||||
setInProgress(false);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('uploaded', function (error, fileObj) {
|
|
||||||
console.log('uploaded: ', fileObj);
|
|
||||||
|
|
||||||
// props.setUpId(fileObj._id);
|
|
||||||
|
|
||||||
// Remove the filename from the upload box
|
|
||||||
fileinput.current.value = '';
|
|
||||||
|
|
||||||
// Reset our state for the next file
|
|
||||||
setUploading([]);
|
|
||||||
setProgress(0);
|
|
||||||
console.log("setInProgress: false");
|
|
||||||
setInProgress(false);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('error', function (error, fileObj) {
|
|
||||||
console.log('Error during upload: ' + error)
|
|
||||||
console.log("setInProgress: false");
|
|
||||||
setInProgress(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.on('progress', function (progress, fileObj) {
|
|
||||||
console.log('Upload Percentage: ' + progress)
|
|
||||||
// Update our progress bar
|
|
||||||
setProgress(progress);
|
|
||||||
if (progress === 100) {
|
|
||||||
console.log("setInProgress: false");
|
|
||||||
setInProgress(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.start(); // Must manually start the upload
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return <>
|
|
||||||
|
|
||||||
<button
|
|
||||||
className='btArxiu'
|
|
||||||
onClick={ev => {
|
|
||||||
ev.preventDefault();
|
|
||||||
ev.stopPropagation();
|
|
||||||
|
|
||||||
// refForm.current.reset();
|
|
||||||
fileinput.current.click();
|
|
||||||
//reseter[1](reseter[0] + 1);
|
|
||||||
//refForm.current.reset();
|
|
||||||
// ev.target.value = null;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="fa-solid fa-image" >Add file</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<input type="file"
|
|
||||||
id="fileinput"
|
|
||||||
disabled={inProgress}
|
|
||||||
ref={fileinput}
|
|
||||||
onChange={() => {
|
|
||||||
setInProgress(true);
|
|
||||||
}}
|
|
||||||
style={{display: `none`}}
|
|
||||||
name="fileinput"
|
|
||||||
onClick={(ev) => {
|
|
||||||
// ev.preventDefault();
|
|
||||||
ev.stopPropagation();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<br /><br />
|
|
||||||
|
|
||||||
<div className="row m-t-sm m-b-sm">
|
|
||||||
<div className="col-md-6">
|
|
||||||
|
|
||||||
<ShowUploads progress={progress} filePreviewURI={filePreviewURI} uploading={uploading} inProgress={inProgress} />
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<DisplayUploadFile files={files} />
|
|
||||||
|
|
||||||
</>;
|
|
||||||
// else return <div>Carregant llista d'arxius...</div>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default FileUploadPOI;
|
|
||||||
@ -1,196 +0,0 @@
|
|||||||
import { useTracker, useSubscribe, useFind } from 'meteor/react-meteor-data/suspense';
|
|
||||||
import { Meteor } from 'meteor/meteor';
|
|
||||||
import React, { useState, useRef, Suspense } from 'react';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
import { FilesCol } from '/imports/api/files.js';
|
|
||||||
|
|
||||||
import IndividualFileStart from '/imports/ui/files/IndividualFile.jsx'; // <-------------------------
|
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
//const debug = require('debug')('demo:file');
|
|
||||||
|
|
||||||
const FileUploadStart = (props) => {
|
|
||||||
|
|
||||||
const [uploading, setUploading] = useState([]);
|
|
||||||
const [progress, setProgress] = useState(0);
|
|
||||||
const [inProgress, setInProgress] = useState(false);
|
|
||||||
|
|
||||||
const reseter = useState(0);
|
|
||||||
|
|
||||||
const refForm = useRef();
|
|
||||||
const fileinput = useRef();
|
|
||||||
|
|
||||||
useSubscribe('files.all');
|
|
||||||
|
|
||||||
const files = useTracker("files", async () => {
|
|
||||||
// const docsReadyYet = filesHandle.ready();
|
|
||||||
const files = await FilesCol?.find({meta:{userId: props.uidProvisional || Meteor.userId(), entId: props.entId}}, {sort: {name: 1}})//.fetchAsync(); // Meteor.userId() ?? "nop"
|
|
||||||
|
|
||||||
return files;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
function uploadIt(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
//let self = this;
|
|
||||||
|
|
||||||
if (e.currentTarget.files && e.currentTarget.files[0]) {
|
|
||||||
// We upload only one file, in case
|
|
||||||
// there was multiple files selected
|
|
||||||
var file = e.currentTarget.files[0];
|
|
||||||
|
|
||||||
if (file) {
|
|
||||||
let uploadInstance = FilesCol.insert({
|
|
||||||
file,
|
|
||||||
meta: {
|
|
||||||
locator: props.fileLocator,
|
|
||||||
userId: props.uidProvisional || Meteor.userId(), // Optional, used to check on server for file tampering
|
|
||||||
entId: props.entId
|
|
||||||
},
|
|
||||||
chunkSize: 'dynamic',
|
|
||||||
allowWebWorkers: true // If you see issues with uploads, change this to false
|
|
||||||
}, false)
|
|
||||||
|
|
||||||
setUploading(uploadInstance); // Keep track of this instance to use below
|
|
||||||
setInProgress(true); // Show the progress bar now
|
|
||||||
|
|
||||||
// These are the event functions, don't need most of them, it shows where we are in the process
|
|
||||||
uploadInstance.on('start', function () {
|
|
||||||
console.log('Starting');
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('end', function (error, fileObj) {
|
|
||||||
console.log('On end File Object: ', fileObj);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('uploaded', function (error, fileObj) {
|
|
||||||
console.log('uploaded: ', fileObj);
|
|
||||||
|
|
||||||
// props.setUpId(fileObj._id);
|
|
||||||
|
|
||||||
// Remove the filename from the upload box
|
|
||||||
fileinput.current.value = '';
|
|
||||||
|
|
||||||
// Reset our state for the next file
|
|
||||||
setUploading([]);
|
|
||||||
setProgress(0);
|
|
||||||
setInProgress(false);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('error', function (error, fileObj) {
|
|
||||||
console.log('Error during upload: ' + error)
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.on('progress', function (progress, fileObj) {
|
|
||||||
console.log('Upload Percentage: ' + progress)
|
|
||||||
// Update our progress bar
|
|
||||||
setProgress(progress);
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.start(); // Must manually start the upload
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is our progress bar, bootstrap styled
|
|
||||||
// Remove this function if not needed
|
|
||||||
function showUploads() {
|
|
||||||
// console.log('**********************************', uploading);
|
|
||||||
|
|
||||||
if (!_.isEmpty(uploading)) {
|
|
||||||
return <div>
|
|
||||||
{uploading.file.name}
|
|
||||||
|
|
||||||
<div className="progress progress-bar-default">
|
|
||||||
<div style={{width: progress + '%'}} aria-valuemax="100"
|
|
||||||
aria-valuemin="0"
|
|
||||||
aria-valuenow={progress || 0} role="progressbar"
|
|
||||||
className="progress-bar"
|
|
||||||
>
|
|
||||||
<span className="sr-only">{progress}% Complete (success)</span>
|
|
||||||
<span>{progress}%</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const Display = async () => await files?.map(async (aFile, key) => {
|
|
||||||
|
|
||||||
let link = await FilesCol.findOneAsync({_id: aFile._id}); //The "view/download" link
|
|
||||||
let linkOriginalURL = `${window.location.origin}${link._fileRef._downloadRoute}/${link._fileRef._collectionName}/${link._fileRef._id}/original/${link._fileRef._id}.${link._fileRef.extension}`;
|
|
||||||
|
|
||||||
// Send out components that show details of each file
|
|
||||||
|
|
||||||
return <Suspense fallback="<>Loading...</>">
|
|
||||||
<div key={'file' + key}>
|
|
||||||
<IndividualFileStart
|
|
||||||
fileName={aFile.name}
|
|
||||||
fileUrl={linkOriginalURL}
|
|
||||||
fileId={aFile._id}
|
|
||||||
fileSize={aFile.size}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Suspense>
|
|
||||||
}).reverse();
|
|
||||||
|
|
||||||
// Run through each file that the user has stored
|
|
||||||
// (make sure the subscription only sends files owned by this user)
|
|
||||||
// let display =
|
|
||||||
|
|
||||||
return <Suspense fallback="Loading...">
|
|
||||||
<button
|
|
||||||
className='btArxiu'
|
|
||||||
onClick={ev => {
|
|
||||||
ev.preventDefault();
|
|
||||||
|
|
||||||
// refForm.current.reset();
|
|
||||||
fileinput.current.click();
|
|
||||||
//reseter[1](reseter[0] + 1);
|
|
||||||
//refForm.current.reset();
|
|
||||||
ev.target.value = null;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="fa-solid fa-paperclip" >Add file</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<input type="file"
|
|
||||||
id="fileinput"
|
|
||||||
disabled={inProgress}
|
|
||||||
ref={fileinput}
|
|
||||||
onChange={uploadIt}
|
|
||||||
style={{display: `none`}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="row m-t-sm m-b-sm">
|
|
||||||
<div className="col-md-6">
|
|
||||||
|
|
||||||
{showUploads()}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Display />
|
|
||||||
</Suspense>
|
|
||||||
// else return <div>Carregant llista d'arxius...</div>;
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// This is the HOC - included in this file just for convenience, but usually kept
|
|
||||||
// in a separate file to provide separation of concerns.
|
|
||||||
//
|
|
||||||
// export default withTracker( ( props ) => {
|
|
||||||
|
|
||||||
// const filesHandle = Meteor.subscribe('files.all');
|
|
||||||
// const docsReadyYet = filesHandle.ready();
|
|
||||||
// const files = FilesCol.find({meta:{userId: props.uidProvisional || Meteor.userId()}}, {sort: {name: 1}}).fetch(); // Meteor.userId() ?? "nop"
|
|
||||||
|
|
||||||
// return {
|
|
||||||
// docsReadyYet,
|
|
||||||
// files,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// })(FileUploadComponent);
|
|
||||||
|
|
||||||
export default FileUploadStart;
|
|
||||||
@ -1,188 +0,0 @@
|
|||||||
import { useTracker } from 'meteor/react-meteor-data';
|
|
||||||
import { Meteor } from 'meteor/meteor';
|
|
||||||
import React, { useState, useRef } from 'react';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
import { FilesCol } from '/imports/api/files.js';
|
|
||||||
|
|
||||||
import IndividualFile from '/imports/ui/files/IndividualFile.jsx';
|
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
const debug = require('debug')('demo:file');
|
|
||||||
|
|
||||||
const FileUploadComponent = (props) => {
|
|
||||||
|
|
||||||
const [uploading, setUploading] = useState([]);
|
|
||||||
const [progress, setProgress] = useState(0);
|
|
||||||
const [inProgress, setInProgress] = useState(false);
|
|
||||||
|
|
||||||
const fileinput = useRef();
|
|
||||||
|
|
||||||
const files = useTracker(() => {
|
|
||||||
const filesHandle = Meteor.subscribe('files.all');
|
|
||||||
// const docsReadyYet = filesHandle.ready();
|
|
||||||
const files = FilesCol?.find({meta:{userId: props?.uidProvisional || Meteor.userId()}}, {sort: {name: 1}}).fetch(); // Meteor.userId() ?? "nop"
|
|
||||||
|
|
||||||
return files;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function uploadIt(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
//let self = this;
|
|
||||||
|
|
||||||
if (e.currentTarget.files && e.currentTarget.files[0]) {
|
|
||||||
// We upload only one file, in case
|
|
||||||
// there was multiple files selected
|
|
||||||
var file = e.currentTarget.files[0];
|
|
||||||
|
|
||||||
if (file) {
|
|
||||||
let uploadInstance = FilesCol.insert({
|
|
||||||
file,
|
|
||||||
meta: {
|
|
||||||
locator: props.fileLocator,
|
|
||||||
userId: props.uidProvisional || Meteor.userId() // Optional, used to check on server for file tampering
|
|
||||||
},
|
|
||||||
chunkSize: 'dynamic',
|
|
||||||
allowWebWorkers: true // If you see issues with uploads, change this to false
|
|
||||||
}, false)
|
|
||||||
|
|
||||||
setUploading(uploadInstance); // Keep track of this instance to use below
|
|
||||||
setInProgress(true);// Show the progress bar now
|
|
||||||
|
|
||||||
// These are the event functions, don't need most of them, it shows where we are in the process
|
|
||||||
uploadInstance.on('start', function () {
|
|
||||||
console.log('Starting');
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('end', function (error, fileObj) {
|
|
||||||
console.log('On end File Object: ', fileObj);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('uploaded', function (error, fileObj) {
|
|
||||||
console.log('uploaded: ', fileObj);
|
|
||||||
|
|
||||||
props.setUpId(fileObj?._id);
|
|
||||||
|
|
||||||
// Remove the filename from the upload box
|
|
||||||
fileinput.current.value = '';
|
|
||||||
|
|
||||||
// Reset our state for the next file
|
|
||||||
setUploading([]);
|
|
||||||
setProgress(0);
|
|
||||||
setInProgress(false);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('error', function (error, fileObj) {
|
|
||||||
console.log('Error during upload: ' + error)
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.on('progress', function (progress, fileObj) {
|
|
||||||
console.log('Upload Percentage: ' + progress)
|
|
||||||
// Update our progress bar
|
|
||||||
setProgress(progress);
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.start(); // Must manually start the upload
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is our progress bar, bootstrap styled
|
|
||||||
// Remove this function if not needed
|
|
||||||
function showUploads() {
|
|
||||||
console.log('**********************************', uploading);
|
|
||||||
|
|
||||||
if (!_.isEmpty(uploading)) {
|
|
||||||
return <div>
|
|
||||||
{uploading.file.name}
|
|
||||||
|
|
||||||
<div className="progress progress-bar-default">
|
|
||||||
<div style={{width: progress + '%'}} aria-valuemax="100"
|
|
||||||
aria-valuemin="0"
|
|
||||||
aria-valuenow={progress || 0} role="progressbar"
|
|
||||||
className="progress-bar">
|
|
||||||
<span className="sr-only">{progress}% Complete (success)</span>
|
|
||||||
<span>{progress}%</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
// debug("Rendering FileUpload",docsReadyYet);
|
|
||||||
if (files /* && docsReadyYet*/) {
|
|
||||||
|
|
||||||
let fileCursors = files;
|
|
||||||
|
|
||||||
// Run through each file that the user has stored
|
|
||||||
// (make sure the subscription only sends files owned by this user)
|
|
||||||
let display = fileCursors.map((aFile, key) => {
|
|
||||||
// console.log('A file: ', aFile.link(), aFile.get('name'))
|
|
||||||
let link = FilesCol.findOne({_id: aFile._id}).link(); //The "view/download" link
|
|
||||||
|
|
||||||
// Send out components that show details of each file
|
|
||||||
return <div key={'file' + key}>
|
|
||||||
<IndividualFile
|
|
||||||
fileName={aFile.name}
|
|
||||||
fileUrl={link}
|
|
||||||
fileId={aFile._id}
|
|
||||||
fileSize={aFile.size}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
})
|
|
||||||
|
|
||||||
return <div>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-12">
|
|
||||||
<p>Upload New File:</p>
|
|
||||||
<input type="file"
|
|
||||||
id="fileinput"
|
|
||||||
disabled={inProgress}
|
|
||||||
ref={fileinput}
|
|
||||||
onChange={uploadIt}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row m-t-sm m-b-sm">
|
|
||||||
<div className="col-md-6">
|
|
||||||
|
|
||||||
{showUploads()}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div className="col-md-6">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{display}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
else return <div>Loading file list</div>;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// This is the HOC - included in this file just for convenience, but usually kept
|
|
||||||
// in a separate file to provide separation of concerns.
|
|
||||||
//
|
|
||||||
// export default withTracker( ( props ) => {
|
|
||||||
|
|
||||||
// const filesHandle = Meteor.subscribe('files.all');
|
|
||||||
// const docsReadyYet = filesHandle.ready();
|
|
||||||
// const files = FilesCol.find({meta:{userId: props.uidProvisional || Meteor.userId()}}, {sort: {name: 1}}).fetch(); // Meteor.userId() ?? "nop"
|
|
||||||
|
|
||||||
// return {
|
|
||||||
// docsReadyYet,
|
|
||||||
// files,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// })(FileUploadComponent);
|
|
||||||
|
|
||||||
export default FileUploadComponent;
|
|
||||||
@ -1,186 +0,0 @@
|
|||||||
import { withTracker } from 'meteor/react-meteor-data';
|
|
||||||
import { Meteor } from 'meteor/meteor';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
import { FilesCol } from '/imports/api/files.js';
|
|
||||||
|
|
||||||
import IndividualFile from '/imports/ui/files/IndividualFile.jsx';
|
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
const debug = require('debug')('demo:file');
|
|
||||||
|
|
||||||
class FileUploadComponent extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
uploading: [],
|
|
||||||
progress: 0,
|
|
||||||
inProgress: false
|
|
||||||
};
|
|
||||||
|
|
||||||
this.uploadIt = this.uploadIt.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
uploadIt(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
let self = this;
|
|
||||||
|
|
||||||
if (e.currentTarget.files && e.currentTarget.files[0]) {
|
|
||||||
// We upload only one file, in case
|
|
||||||
// there was multiple files selected
|
|
||||||
var file = e.currentTarget.files[0];
|
|
||||||
|
|
||||||
if (file) {
|
|
||||||
let uploadInstance = FilesCol.insert({
|
|
||||||
file: file,
|
|
||||||
meta: {
|
|
||||||
locator: self.props.fileLocator,
|
|
||||||
userId: this.props.uidProvisional || Meteor.userId() // Optional, used to check on server for file tampering
|
|
||||||
},
|
|
||||||
chunkSize: 'dynamic',
|
|
||||||
allowWebWorkers: true // If you see issues with uploads, change this to false
|
|
||||||
}, false)
|
|
||||||
|
|
||||||
self.setState({
|
|
||||||
uploading: uploadInstance, // Keep track of this instance to use below
|
|
||||||
inProgress: true // Show the progress bar now
|
|
||||||
});
|
|
||||||
|
|
||||||
// These are the event functions, don't need most of them, it shows where we are in the process
|
|
||||||
uploadInstance.on('start', function () {
|
|
||||||
console.log('Starting');
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('end', function (error, fileObj) {
|
|
||||||
console.log('On end File Object: ', fileObj);
|
|
||||||
//this.props?.setAvatarId(fileObj._id);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('uploaded', function (error, fileObj) {
|
|
||||||
console.log('uploaded: ', fileObj);
|
|
||||||
//console.log(`setAvatarId: ${this.props?.setAvatarId}`);
|
|
||||||
|
|
||||||
// this.props.setUpId(fileObj._id);
|
|
||||||
// Remove the filename from the upload box
|
|
||||||
self.refs['fileinput'].value = '';
|
|
||||||
|
|
||||||
// Reset our state for the next file
|
|
||||||
self.setState({
|
|
||||||
uploading: [],
|
|
||||||
progress: 0,
|
|
||||||
inProgress: false
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('error', function (error, fileObj) {
|
|
||||||
console.log('Error during upload: ' + error)
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.on('progress', function (progress, fileObj) {
|
|
||||||
console.log('Upload Percentage: ' + progress)
|
|
||||||
// Update our progress bar
|
|
||||||
self.setState({
|
|
||||||
progress: progress
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.start(); // Must manually start the upload
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is our progress bar, bootstrap styled
|
|
||||||
// Remove this function if not needed
|
|
||||||
showUploads() {
|
|
||||||
console.log('**********************************', this.state.uploading);
|
|
||||||
|
|
||||||
if (!_.isEmpty(this.state.uploading)) {
|
|
||||||
return <div>
|
|
||||||
{this.state.uploading.file.name}
|
|
||||||
|
|
||||||
<div className="progress progress-bar-default">
|
|
||||||
<div style={{width: this.state.progress + '%'}} aria-valuemax="100"
|
|
||||||
aria-valuemin="0"
|
|
||||||
aria-valuenow={this.state.progress || 0} role="progressbar"
|
|
||||||
className="progress-bar">
|
|
||||||
<span className="sr-only">{this.state.progress}% Complete (success)</span>
|
|
||||||
<span>{this.state.progress}%</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
debug("Rendering FileUpload",this.props.docsReadyYet);
|
|
||||||
if (this.props.files && this.props.docsReadyYet) {
|
|
||||||
|
|
||||||
let fileCursors = this.props.files;
|
|
||||||
|
|
||||||
// Run through each file that the user has stored
|
|
||||||
// (make sure the subscription only sends files owned by this user)
|
|
||||||
let display = fileCursors.map((aFile, key) => {
|
|
||||||
// console.log('A file: ', aFile.link(), aFile.get('name'))
|
|
||||||
let link = FilesCol.findOne({_id: aFile._id}).link(); //The "view/download" link
|
|
||||||
|
|
||||||
// Send out components that show details of each file
|
|
||||||
return <div key={'file' + key}>
|
|
||||||
<IndividualFile
|
|
||||||
fileName={aFile.name}
|
|
||||||
fileUrl={link}
|
|
||||||
fileId={aFile._id}
|
|
||||||
fileSize={aFile.size}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
})
|
|
||||||
|
|
||||||
return <div>
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-12">
|
|
||||||
<p>Upload New File:</p>
|
|
||||||
<input type="file"
|
|
||||||
id="fileinput"
|
|
||||||
disabled={this.state.inProgress}
|
|
||||||
ref="fileinput"
|
|
||||||
onChange={this.uploadIt}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row m-t-sm m-b-sm">
|
|
||||||
<div className="col-md-6">
|
|
||||||
|
|
||||||
{this.showUploads()}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div className="col-md-6">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{display}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
else return <div>Loading file list</div>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// This is the HOC - included in this file just for convenience, but usually kept
|
|
||||||
// in a separate file to provide separation of concerns.
|
|
||||||
//
|
|
||||||
export default withTracker( ( props ) => {
|
|
||||||
const filesHandle = Meteor.subscribe('files.all');
|
|
||||||
const docsReadyYet = filesHandle.ready();
|
|
||||||
const files = FilesCol.find({meta:{userId: props.uidProvisional || Meteor.userId()}}, {sort: {name: 1}}).fetch(); // Meteor.userId() ?? "nop"
|
|
||||||
// const setAvatarId = props.setAvatarId;
|
|
||||||
|
|
||||||
return {
|
|
||||||
docsReadyYet,
|
|
||||||
files,
|
|
||||||
// setAvatarId
|
|
||||||
};
|
|
||||||
})(FileUploadComponent);
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
// import { Meteor } from 'meteor/meteor';
|
|
||||||
import React from 'react';
|
|
||||||
import { useSubscribe, useFind, useTracker } from 'meteor/react-meteor-data/suspense';
|
|
||||||
|
|
||||||
// import { FilesCollection } from '/imports/api/files.js';
|
|
||||||
import { FilesCol } from '/imports/api/files.js';
|
|
||||||
import FileUploadStart from '/imports/ui/files/FileUploadStart.jsx';
|
|
||||||
|
|
||||||
|
|
||||||
const Files = () => {
|
|
||||||
|
|
||||||
useSubscribe('files.all');
|
|
||||||
|
|
||||||
const files = useTracker("files", () => {
|
|
||||||
const files = FilesCol.find({}).fetchAsync();
|
|
||||||
return files;
|
|
||||||
});
|
|
||||||
|
|
||||||
return <>
|
|
||||||
<h1 style={{
|
|
||||||
fontFamily: `cyber`,
|
|
||||||
padding: `.7rem`,
|
|
||||||
color: `#ff0c`,
|
|
||||||
textShadow: `.02em .02em .1em black`
|
|
||||||
}}>Files</h1>
|
|
||||||
{
|
|
||||||
|
|
||||||
<FileUploadStart />
|
|
||||||
|
|
||||||
}
|
|
||||||
</>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export { Files };
|
|
||||||
@ -1,217 +0,0 @@
|
|||||||
import { useTracker } from 'meteor/react-meteor-data';
|
|
||||||
import { Meteor } from 'meteor/meteor';
|
|
||||||
import React, { useState, useRef } from 'react';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
import { FilesCol } from '/imports/api/files.js';
|
|
||||||
|
|
||||||
import { IndividualFileCartellEvent } from '/imports/ui/files/FilesCartellEvent/IndividualFileCartellEvent.jsx';
|
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
//const debug = require('debug')('demo:file');
|
|
||||||
|
|
||||||
const FileUploadCartellEvent = (props) => {
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
const cartellId = new Mongo.ObjectID();
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////
|
|
||||||
const [upId, setUpId] = useState(null);
|
|
||||||
|
|
||||||
const [uploading, setUploading] = useState([]);
|
|
||||||
const [progress, setProgress] = useState(0);
|
|
||||||
const [inProgress, setInProgress] = useState(false);
|
|
||||||
|
|
||||||
const fileinput = useRef();
|
|
||||||
|
|
||||||
const files = useTracker(() => {
|
|
||||||
const filesHandle = Meteor.subscribe('files.cartellEventUpload', upId);
|
|
||||||
// const docsReadyYet = filesHandle.ready();
|
|
||||||
const files = FilesCol?.find(upId).fetch(); // Meteor.userId() ?? "nop" //"meta.avatarId": avatarId
|
|
||||||
|
|
||||||
return files;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function uploadIt(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
//let self = this;
|
|
||||||
|
|
||||||
if (e.currentTarget.files && e.currentTarget.files[0]) {
|
|
||||||
// We upload only one file, in case
|
|
||||||
// there was multiple files selected
|
|
||||||
var file = e.currentTarget.files[0];
|
|
||||||
|
|
||||||
if (file) {
|
|
||||||
let uploadInstance = FilesCol.insert({
|
|
||||||
file,
|
|
||||||
meta: {
|
|
||||||
// locator: props.fileLocator,
|
|
||||||
// userId: props.uidProvisional || Meteor.userId(), // Optional, used to check on server for file tampering
|
|
||||||
// eventId: props.eventId
|
|
||||||
},
|
|
||||||
chunkSize: 'dynamic',
|
|
||||||
allowWebWorkers: true // If you see issues with uploads, change this to false
|
|
||||||
}, false)
|
|
||||||
|
|
||||||
setUploading(uploadInstance); // Keep track of this instance to use below
|
|
||||||
setInProgress(true); // Show the progress bar now
|
|
||||||
|
|
||||||
// These are the event functions, don't need most of them, it shows where we are in the process
|
|
||||||
uploadInstance.on('start', function () {
|
|
||||||
console.log('Starting');
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('end', function (error, fileObj) {
|
|
||||||
console.log('On end File Object: ', fileObj);
|
|
||||||
|
|
||||||
props.setCartellId(fileObj._id);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('uploaded', function (error, fileObj) {
|
|
||||||
console.log('uploaded: ', fileObj);
|
|
||||||
|
|
||||||
setUpId(fileObj._id);
|
|
||||||
|
|
||||||
// Remove the filename from the upload box
|
|
||||||
fileinput.current.value = '';
|
|
||||||
|
|
||||||
// Reset our state for the next file
|
|
||||||
setUploading([]);
|
|
||||||
setProgress(0);
|
|
||||||
setInProgress(false);
|
|
||||||
|
|
||||||
props.setNovaImg(true);
|
|
||||||
})
|
|
||||||
|
|
||||||
uploadInstance.on('error', function (error, fileObj) {
|
|
||||||
console.log('Error during upload: ' + error)
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.on('progress', function (progress, fileObj) {
|
|
||||||
console.log('Upload Percentage: ' + progress)
|
|
||||||
// Update our progress bar
|
|
||||||
setProgress(progress);
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.start(); // Must manually start the upload
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is our progress bar, bootstrap styled
|
|
||||||
// Remove this function if not needed
|
|
||||||
function showUploads() {
|
|
||||||
console.log('**********************************', uploading);
|
|
||||||
|
|
||||||
if (!_.isEmpty(uploading)) {
|
|
||||||
return <div>
|
|
||||||
{uploading.file.name}
|
|
||||||
|
|
||||||
<div className="progress progress-bar-default">
|
|
||||||
<div style={{width: progress + '%', background: "white"}} aria-valuemax="100"
|
|
||||||
aria-valuemin="0"
|
|
||||||
aria-valuenow={progress || 0} role="progressbar"
|
|
||||||
className="progress-bar">
|
|
||||||
<span className="sr-only">{progress}% Complete (success)</span>
|
|
||||||
<span>{progress}%</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//{
|
|
||||||
// debug("Rendering FileUpload",docsReadyYet);
|
|
||||||
// if (files /* && docsReadyYet*/) {
|
|
||||||
|
|
||||||
// let fileCursors = files;
|
|
||||||
|
|
||||||
// Run through each file that the user has stored
|
|
||||||
// (make sure the subscription only sends files owned by this user)
|
|
||||||
let display = files?.map((aFile, key) => {
|
|
||||||
// console.log('A file: ', aFile.link(), aFile.get('name'))
|
|
||||||
let link = FilesCol.findOne({_id: upId})?.link(); //The "view/download" link
|
|
||||||
|
|
||||||
props.setCartellLink(link);
|
|
||||||
|
|
||||||
// Send out components that show details of each file
|
|
||||||
return <div key={'file' + key}>
|
|
||||||
<IndividualFileCartellEvent
|
|
||||||
fileName={aFile.name}
|
|
||||||
fileUrl={link}
|
|
||||||
fileId={aFile._id}
|
|
||||||
fileSize={aFile.size}
|
|
||||||
/>
|
|
||||||
{/* <button onClick={ev => {
|
|
||||||
ev.preventDefault();
|
|
||||||
ev.stopPropagation();
|
|
||||||
|
|
||||||
Meteor.call('userAvatarUpdate', avatarId, avatarLink, () => {
|
|
||||||
setNovaImg(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
// alert(`
|
|
||||||
// avatarId: ${avatarId}
|
|
||||||
// avatarLink: ${avatarLink}`);
|
|
||||||
|
|
||||||
}}>Estableix</button>*/}
|
|
||||||
</div>
|
|
||||||
})
|
|
||||||
|
|
||||||
return <div>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-12">
|
|
||||||
<p>Upload New File:</p>
|
|
||||||
<label htmlFor="fileinput">Tria la imatge de l'event: </label>
|
|
||||||
<br />
|
|
||||||
<input type="file"
|
|
||||||
id="fileinput"
|
|
||||||
disabled={inProgress}
|
|
||||||
ref={fileinput}
|
|
||||||
onChange={uploadIt}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row m-t-sm m-b-sm">
|
|
||||||
<div className="col-md-6">
|
|
||||||
|
|
||||||
{showUploads()}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div className="col-md-6">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{display}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
// }
|
|
||||||
// else return <div>Loading file list</div>;
|
|
||||||
// }
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// This is the HOC - included in this file just for convenience, but usually kept
|
|
||||||
// in a separate file to provide separation of concerns.
|
|
||||||
//
|
|
||||||
// export default withTracker( ( props ) => {
|
|
||||||
|
|
||||||
// const filesHandle = Meteor.subscribe('files.all');
|
|
||||||
// const docsReadyYet = filesHandle.ready();
|
|
||||||
// const files = FilesCol.find({meta:{userId: props.uidProvisional || Meteor.userId()}}, {sort: {name: 1}}).fetch(); // Meteor.userId() ?? "nop"
|
|
||||||
|
|
||||||
// return {
|
|
||||||
// docsReadyYet,
|
|
||||||
// files,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// })(FileUploadComponent);
|
|
||||||
|
|
||||||
export { FileUploadCartellEvent };
|
|
||||||
@ -1,84 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
const IndividualFileCartellEvent = props => {
|
|
||||||
|
|
||||||
// propTypes: {
|
|
||||||
// fileName: PropTypes.string.isRequired,
|
|
||||||
// fileSize: PropTypes.number.isRequired,
|
|
||||||
// fileUrl: PropTypes.string,
|
|
||||||
// fileId: PropTypes.string.isRequired
|
|
||||||
// }
|
|
||||||
|
|
||||||
function removeFile(){
|
|
||||||
let conf = confirm('Are you sure you want to delete the file?') || false;
|
|
||||||
if (conf == true) {
|
|
||||||
Meteor.call('RemoveFile', props.fileId, function (err, res) {
|
|
||||||
if (err)
|
|
||||||
console.log(err);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function renameFile(){
|
|
||||||
|
|
||||||
let validName = /[^a-zA-Z0-9 \.:\+()\-_%!&]/gi;
|
|
||||||
let prompt = window.prompt('New file name?', props.fileName);
|
|
||||||
|
|
||||||
// Replace any non valid characters, also do this on the server
|
|
||||||
if (prompt) {
|
|
||||||
prompt = prompt.replace(validName, '-');
|
|
||||||
prompt.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_.isEmpty(prompt)) {
|
|
||||||
Meteor.call('RenameFile', props.fileId, prompt, function (err, res) {
|
|
||||||
if (err)
|
|
||||||
console.log(err);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return <div className="m-t-sm">
|
|
||||||
<a href={props.fileUrl} target="_blank" >
|
|
||||||
<img
|
|
||||||
src={props.fileUrl}
|
|
||||||
alt={props.fileName}
|
|
||||||
style={{maxWidth: `200px`, maxHeight: `200px`}}
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{/* <div className="row">
|
|
||||||
<div className="col-md-12">
|
|
||||||
<strong>{props.fileName}</strong>
|
|
||||||
<div className="m-b-sm">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-3">
|
|
||||||
<button onClick={renameFile} className="btn btn-outline btn-primary btn-sm">
|
|
||||||
Rename
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div className="col-md-3">
|
|
||||||
<a href={props.fileUrl} className="btn btn-outline btn-primary btn-sm"
|
|
||||||
target="_blank">View</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-md-2">
|
|
||||||
<button onClick={removeFile} className="btn btn-outline btn-danger btn-sm">
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-md-4">
|
|
||||||
Size: {props.fileSize}
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
export { IndividualFileCartellEvent };
|
|
||||||
@ -1,210 +0,0 @@
|
|||||||
import { useTracker } from 'meteor/react-meteor-data';
|
|
||||||
import { Meteor } from 'meteor/meteor';
|
|
||||||
import { Mongo } from 'meteor/mongo';
|
|
||||||
import React, { useState, useRef } from 'react';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
import { FilesCol } from '/imports/api/files.js';
|
|
||||||
|
|
||||||
import FolderTreeIndividualFile from '/imports/ui/files/FolderTreeIndividualFile.jsx';
|
|
||||||
|
|
||||||
import _, { upperCase } from 'lodash';
|
|
||||||
|
|
||||||
const debug = require('debug')('demo:file');
|
|
||||||
|
|
||||||
|
|
||||||
const FolderTreeFileUpload = (props) => {
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
const treeFileId = new Mongo.ObjectID();
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
const [upId, setUpId] = useState(null);
|
|
||||||
|
|
||||||
const [uploading, setUploading] = useState([]);
|
|
||||||
const [progress, setProgress] = useState(0);
|
|
||||||
const [inProgress, setInProgress] = useState(false);
|
|
||||||
|
|
||||||
const fileinput = useRef();
|
|
||||||
|
|
||||||
const files = useTracker(() => {
|
|
||||||
const filesHandle = Meteor.subscribe('files.folderTree', upId);
|
|
||||||
// const docsReadyYet = filesHandle.ready();
|
|
||||||
const files = FilesCol?.find(upId).fetch(); // Meteor.userId() ?? "nop" //"meta.avatarId": avatarId
|
|
||||||
|
|
||||||
return files;
|
|
||||||
});
|
|
||||||
|
|
||||||
function uploadIt(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
//let self = this;
|
|
||||||
|
|
||||||
if (e.currentTarget.files && e.currentTarget.files[0]) {
|
|
||||||
// We upload only one file, in case
|
|
||||||
// there was multiple files selected
|
|
||||||
var file = e.currentTarget.files[0];
|
|
||||||
|
|
||||||
if (file) {
|
|
||||||
console.log("IfFile: ", file);
|
|
||||||
let uploadInstance = FilesCol.insert({
|
|
||||||
file,
|
|
||||||
meta: {
|
|
||||||
//locator: file.link(),
|
|
||||||
userId: Meteor.userId(), // Optional, used to check on server for file tampering
|
|
||||||
type: "folderTree"
|
|
||||||
//avatarId
|
|
||||||
},
|
|
||||||
chunkSize: 'dynamic',
|
|
||||||
allowWebWorkers: true // If you see issues with uploads, change this to false
|
|
||||||
}, false);
|
|
||||||
|
|
||||||
setUploading(uploadInstance); // Keep track of this instance to use below
|
|
||||||
setInProgress(true); // Show the progress bar now
|
|
||||||
|
|
||||||
// These are the event functions, don't need most of them, it shows where we are in the process
|
|
||||||
uploadInstance.on('start', function () {
|
|
||||||
console.log('Starting');
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.on('end', function (error, fileObj) {
|
|
||||||
console.log('On end File Object: ', fileObj);
|
|
||||||
|
|
||||||
props.setFolderTreeId(fileObj._id);
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.on('uploaded', function (error, fileObj) {
|
|
||||||
console.log('uploaded: ', fileObj);
|
|
||||||
|
|
||||||
setUpId(fileObj._id);
|
|
||||||
|
|
||||||
// Remove the filename from the upload box
|
|
||||||
fileinput.current.value = '';
|
|
||||||
|
|
||||||
// Reset our state for the next file
|
|
||||||
setUploading([]);
|
|
||||||
setProgress(0);
|
|
||||||
setInProgress(false);
|
|
||||||
|
|
||||||
props.setNouFolderTree(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.on('error', function (error, fileObj) {
|
|
||||||
console.log('Error during upload: ' + error)
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.on('progress', function (progress, fileObj) {
|
|
||||||
console.log('Upload Percentage: ' + progress)
|
|
||||||
// Update our progress bar
|
|
||||||
setProgress(progress);
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadInstance.start(); // Must manually start the upload
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is our progress bar, bootstrap styled
|
|
||||||
// Remove this function if not needed
|
|
||||||
function showUploads() {
|
|
||||||
console.log('**********************************', uploading);
|
|
||||||
|
|
||||||
if (!_.isEmpty(uploading)) {
|
|
||||||
return <div>
|
|
||||||
{uploading.file.name}
|
|
||||||
|
|
||||||
<div className="progress progress-bar-default">
|
|
||||||
<div style={{width: progress + '%'}} aria-valuemax="100"
|
|
||||||
aria-valuemin="0"
|
|
||||||
aria-valuenow={progress || 0} role="progressbar"
|
|
||||||
className="progress-bar">
|
|
||||||
<span className="sr-only">{progress}% Complete (success)</span>
|
|
||||||
<span>{progress}%</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
// debug("Rendering FileUpload",docsReadyYet);
|
|
||||||
//if (files.length /* && docsReadyYet*/) {
|
|
||||||
|
|
||||||
//let fileCursors = files;
|
|
||||||
|
|
||||||
// Run through each file that the user has stored
|
|
||||||
// (make sure the subscription only sends files owned by this user)
|
|
||||||
let display = files?.map((aFile, key) => {
|
|
||||||
// console.log('A file: ', aFile.link(), aFile.get('name'))
|
|
||||||
let link = FilesCol?.findOne({_id: upId})?.link(); //The "view/download" link
|
|
||||||
|
|
||||||
alert(`Enllaç a l'arxiu: ${link}`);
|
|
||||||
|
|
||||||
props.setFolderTreeLink(link);
|
|
||||||
|
|
||||||
// Send out components that show details of each file
|
|
||||||
return <div key={'file' + key}>
|
|
||||||
{props.nouFolderTree && <FolderTreeIndividualFile
|
|
||||||
fileName={aFile.name}
|
|
||||||
fileUrl={link}
|
|
||||||
fileId={aFile._id}
|
|
||||||
fileSize={aFile.size}
|
|
||||||
/>}
|
|
||||||
</div>
|
|
||||||
})
|
|
||||||
|
|
||||||
return <div>
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-12">
|
|
||||||
<p>Adjunta un arxiu FolderTree*:</p>
|
|
||||||
<input type="file"
|
|
||||||
id="fileinput"
|
|
||||||
disabled={inProgress}
|
|
||||||
ref={fileinput}
|
|
||||||
onChange={uploadIt}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row m-t-sm m-b-sm">
|
|
||||||
<div className="col-md-6">
|
|
||||||
|
|
||||||
{showUploads()}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{display}
|
|
||||||
|
|
||||||
<p>* Un FolderTree és un arxiu en format JSON generat per un commandament 'treedump'** o 'treedumpl'*** </p>
|
|
||||||
<p>{`** treedump () {
|
|
||||||
tree -J -s -f \${@[$#]}
|
|
||||||
}`}</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
// }
|
|
||||||
// return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// This is the HOC - included in this file just for convenience, but usually kept
|
|
||||||
// in a separate file to provide separation of concerns.
|
|
||||||
//
|
|
||||||
// export default withTracker( ( props ) => {
|
|
||||||
|
|
||||||
// const filesHandle = Meteor.subscribe('files.all');
|
|
||||||
// const docsReadyYet = filesHandle.ready();
|
|
||||||
// const files = FilesCol.find({meta:{userId: props.uidProvisional || Meteor.userId()}}, {sort: {name: 1}}).fetch(); // Meteor.userId() ?? "nop"
|
|
||||||
|
|
||||||
// return {
|
|
||||||
// docsReadyYet,
|
|
||||||
// files,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// })(FileUploadComponent);
|
|
||||||
|
|
||||||
export default FolderTreeFileUpload;
|
|
||||||
@ -1,78 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
const FolderTreeIndividualFile = props => {
|
|
||||||
|
|
||||||
// propTypes: {
|
|
||||||
// fileName: PropTypes.string.isRequired,
|
|
||||||
// fileSize: PropTypes.number.isRequired,
|
|
||||||
// fileUrl: PropTypes.string,
|
|
||||||
// fileId: PropTypes.string.isRequired
|
|
||||||
// }
|
|
||||||
|
|
||||||
function removeFile(){
|
|
||||||
let conf = confirm('Are you sure you want to delete the file?') || false;
|
|
||||||
if (conf == true) {
|
|
||||||
Meteor.call('RemoveFile', props.fileId, function (err, res) {
|
|
||||||
if (err)
|
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function renameFile(){
|
|
||||||
|
|
||||||
let validName = /[^a-zA-Z0-9 \.:\+()\-_%!&]/gi;
|
|
||||||
let prompt = window.prompt('New file name?', props.fileName);
|
|
||||||
|
|
||||||
// Replace any non valid characters, also do this on the server
|
|
||||||
if (prompt) {
|
|
||||||
prompt = prompt.replace(validName, '-');
|
|
||||||
prompt.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_.isEmpty(prompt)) {
|
|
||||||
Meteor.call('RenameFile', props.fileId, prompt, function (err, res) {
|
|
||||||
if (err)
|
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return <div className="m-t-sm">
|
|
||||||
<a href={props.fileUrl} ><img src={props.fileUrl} alt={props.fileName} style={{maxWidth: `200px`, maxHeight: `200px`}}/></a>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-12">
|
|
||||||
<strong>{props.fileName}</strong>
|
|
||||||
<div className="m-b-sm">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* <div className="row">
|
|
||||||
<div className="col-md-3">
|
|
||||||
<button onClick={renameFile} className="btn btn-outline btn-primary btn-sm">
|
|
||||||
Rename
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div className="col-md-3">
|
|
||||||
<a href={props.fileUrl} className="btn btn-outline btn-primary btn-sm"
|
|
||||||
target="_blank">View</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-md-2">
|
|
||||||
<button onClick={removeFile} className="btn btn-outline btn-danger btn-sm">
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-md-4">
|
|
||||||
Size: {props.fileSize}
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
export default FolderTreeIndividualFile;
|
|
||||||
@ -1,79 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Meteor } from 'meteor/meteor';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
const IndividualFile = props => {
|
|
||||||
|
|
||||||
// propTypes: {
|
|
||||||
// fileName: PropTypes.string.isRequired,
|
|
||||||
// fileSize: PropTypes.number.isRequired,
|
|
||||||
// fileUrl: PropTypes.string,
|
|
||||||
// fileId: PropTypes.string.isRequired
|
|
||||||
// }
|
|
||||||
|
|
||||||
function removeFile(){
|
|
||||||
let conf = confirm('Are you sure you want to delete the file?') || false;
|
|
||||||
if (conf == true) {
|
|
||||||
Meteor.call('RemoveFile', props.fileId, function (err, res) {
|
|
||||||
if (err)
|
|
||||||
console.log(err);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function renameFile(){
|
|
||||||
|
|
||||||
let validName = /[^a-zA-Z0-9 \.:\+()\-_%!&]/gi;
|
|
||||||
let prompt = window.prompt('New file name?', props.fileName);
|
|
||||||
|
|
||||||
// Replace any non valid characters, also do this on the server
|
|
||||||
if (prompt) {
|
|
||||||
prompt = prompt.replace(validName, '-');
|
|
||||||
prompt.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_.isEmpty(prompt)) {
|
|
||||||
Meteor.call('RenameFile', props.fileId, prompt, function (err, res) {
|
|
||||||
if (err)
|
|
||||||
console.log(err);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return <div className="m-t-sm">
|
|
||||||
<img src={props.fileUrl} alt={props.fileName} style={{maxWidth: `200px`, maxHeight: `200px`}}/>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-12">
|
|
||||||
<strong>{props.fileName}</strong>
|
|
||||||
<div className="m-b-sm">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-3">
|
|
||||||
<button onClick={renameFile} className="btn btn-outline btn-primary btn-sm">
|
|
||||||
Rename
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div className="col-md-3">
|
|
||||||
<a href={props.fileUrl} className="btn btn-outline btn-primary btn-sm"
|
|
||||||
target="_blank">View</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-md-2">
|
|
||||||
<button onClick={removeFile} className="btn btn-outline btn-danger btn-sm">
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-md-4">
|
|
||||||
Size: {props.fileSize}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
export default IndividualFile;
|
|
||||||
@ -1,85 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
const IndividualFileEnt = props => {
|
|
||||||
|
|
||||||
// propTypes: {
|
|
||||||
// fileName: PropTypes.string.isRequired,
|
|
||||||
// fileSize: PropTypes.number.isRequired,
|
|
||||||
// fileUrl: PropTypes.string,
|
|
||||||
// fileId: PropTypes.string.isRequired
|
|
||||||
// }
|
|
||||||
|
|
||||||
function removeFile(){
|
|
||||||
let conf = confirm('Are you sure you want to delete the file?') || false;
|
|
||||||
if (conf == true) {
|
|
||||||
Meteor.call('RemoveFile', props.fileId, function (err, res) {
|
|
||||||
if (err)
|
|
||||||
console.log(err);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function renameFile(){
|
|
||||||
|
|
||||||
let validName = /[^a-zA-Z0-9 \.:\+()\-_%!&]/gi;
|
|
||||||
let prompt = window.prompt('New file name?', props.fileName);
|
|
||||||
|
|
||||||
// Replace any non valid characters, also do this on the server
|
|
||||||
if (prompt) {
|
|
||||||
prompt = prompt.replace(validName, '-');
|
|
||||||
prompt.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_.isEmpty(prompt)) {
|
|
||||||
Meteor.call('RenameFile', props.fileId, prompt, function (err, res) {
|
|
||||||
if (err)
|
|
||||||
console.log(err);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return <div className="m-t-sm">
|
|
||||||
<a href={props.fileUrl} target="_blank" >
|
|
||||||
<img
|
|
||||||
className='imgEnt'
|
|
||||||
src={props.fileUrl}
|
|
||||||
alt={props.fileName}
|
|
||||||
style={{maxWidth: `200px`, maxHeight: `200px`, transform: `rotate(${((Math.random() * 4) - 2)}deg`}}
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{/* <div className="row">
|
|
||||||
<div className="col-md-12">
|
|
||||||
<strong>{props.fileName}</strong>
|
|
||||||
<div className="m-b-sm">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-3">
|
|
||||||
<button onClick={renameFile} className="btn btn-outline btn-primary btn-sm">
|
|
||||||
Rename
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div className="col-md-3">
|
|
||||||
<a href={props.fileUrl} className="btn btn-outline btn-primary btn-sm"
|
|
||||||
target="_blank">View</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-md-2">
|
|
||||||
<button onClick={removeFile} className="btn btn-outline btn-danger btn-sm">
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-md-4">
|
|
||||||
Size: {props.fileSize}
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
export default IndividualFileEnt;
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Meteor } from 'meteor/meteor';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
const IndividualFile = props => {
|
|
||||||
|
|
||||||
// propTypes: {
|
|
||||||
// fileName: PropTypes.string.isRequired,
|
|
||||||
// fileSize: PropTypes.number.isRequired,
|
|
||||||
// fileUrl: PropTypes.string,
|
|
||||||
// fileId: PropTypes.string.isRequired
|
|
||||||
// }
|
|
||||||
|
|
||||||
function removeFile(ev) {
|
|
||||||
// ev.preventDefault();
|
|
||||||
ev.stopPropagation();
|
|
||||||
|
|
||||||
let conf = confirm('Are you sure you want to delete the file?') || false;
|
|
||||||
if (conf == true) {
|
|
||||||
Meteor.callAsync('RemoveFile', props.fileId)
|
|
||||||
.catch (err => {
|
|
||||||
console.log(err);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function renameFile() {
|
|
||||||
let validName = /[^a-zA-Z0-9 \.:\+()\-_%!&]/gi;
|
|
||||||
let prompt = window.prompt('New file name?', props.fileName);
|
|
||||||
|
|
||||||
// Replace any non valid characters, also do this on the server
|
|
||||||
if (prompt) {
|
|
||||||
prompt = prompt.replace(validName, '-');
|
|
||||||
prompt.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_.isEmpty(prompt)) {
|
|
||||||
await Meteor.callAsync('RenameFile', props.fileId, prompt)
|
|
||||||
.catch(err => {
|
|
||||||
console.log(err);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return <div className="m-t-sm">
|
|
||||||
<img src={props.fileUrl} alt={props.fileName} style={{maxWidth: `200px`, maxHeight: `200px`}}/>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-12">
|
|
||||||
<strong>{props.fileName}</strong>
|
|
||||||
<div className="m-b-sm">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-3">
|
|
||||||
<button onClick={renameFile} className="btn btn-outline btn-primary btn-sm">
|
|
||||||
Rename
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div className="col-md-3">
|
|
||||||
<a href={props.fileUrl} className="btn btn-outline btn-primary btn-sm"
|
|
||||||
target="_blank">View</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-md-2">
|
|
||||||
<button onClick={removeFile} className="btn btn-outline btn-danger btn-sm">
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-md-4">
|
|
||||||
Size: {props.fileSize}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
export default IndividualFile;
|
|
||||||
@ -1,86 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Meteor } from 'meteor/meteor';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
const IndividualFileStart = props => {
|
|
||||||
|
|
||||||
// propTypes: {
|
|
||||||
// fileName: PropTypes.string.isRequired,
|
|
||||||
// fileSize: PropTypes.number.isRequired,
|
|
||||||
// fileUrl: PropTypes.string,
|
|
||||||
// fileId: PropTypes.string.isRequired
|
|
||||||
// }
|
|
||||||
|
|
||||||
function removeFile() {
|
|
||||||
let conf = confirm('Are you sure you want to delete the file?') || false;
|
|
||||||
if (conf == true) {
|
|
||||||
Meteor.callAsync('RemoveFile', props.fileId, function (err, res) {
|
|
||||||
if (err)
|
|
||||||
console.log(err);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function renameFile() {
|
|
||||||
|
|
||||||
let validName = /[^a-zA-Z0-9 \.:\+()\-_%!&]/gi;
|
|
||||||
let prompt = window.prompt('New file name?', props.fileName);
|
|
||||||
|
|
||||||
// Replace any non valid characters, also do this on the server
|
|
||||||
if (prompt) {
|
|
||||||
prompt = prompt.replace(validName, '-');
|
|
||||||
prompt.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_.isEmpty(prompt)) {
|
|
||||||
Meteor.callAsync('RenameFile', props.fileId, prompt, function (err, res) {
|
|
||||||
if (err)
|
|
||||||
console.log(err);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return <div className="m-t-sm">
|
|
||||||
<a href={props.fileUrl} target="_blank" >
|
|
||||||
<img
|
|
||||||
className='imgEnt'
|
|
||||||
src={props.fileUrl}
|
|
||||||
alt={props.fileName}
|
|
||||||
style={{maxWidth: `200px`, maxHeight: `200px`, transform: `rotate(${((Math.random() * 4) - 2)}deg`}}
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{/* <div className="row">
|
|
||||||
<div className="col-md-12">
|
|
||||||
<strong>{props.fileName}</strong>
|
|
||||||
<div className="m-b-sm">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-3">
|
|
||||||
<button onClick={renameFile} className="btn btn-outline btn-primary btn-sm">
|
|
||||||
Rename
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div className="col-md-3">
|
|
||||||
<a href={props.fileUrl} className="btn btn-outline btn-primary btn-sm" target="_blank">View</a>
|
|
||||||
</div>
|
|
||||||
*/}
|
|
||||||
|
|
||||||
<div className="col-md-2">
|
|
||||||
<button onClick={removeFile} className="btn btn-outline btn-danger btn-sm">
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-md-4">
|
|
||||||
Size: {props.fileSize}
|
|
||||||
</div>
|
|
||||||
{/* </div> */}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
export default IndividualFileStart;
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { useTracker } from 'meteor/react-meteor-data';
|
|
||||||
|
|
||||||
const ListPersons = () => {
|
|
||||||
|
|
||||||
return <ul class="list-group">
|
|
||||||
{
|
|
||||||
persons.map((person, i) => {
|
|
||||||
return <li class="list-group-item">
|
|
||||||
{{#if update _id}}
|
|
||||||
{{> quickForm type="update" collection="Persons" doc=this id=getFormId}}
|
|
||||||
<button data-button-update class="btn btn-danger">Cancel</button>
|
|
||||||
{{else}}
|
|
||||||
<div class="jumbotron" style='background-image: url("{{#each backgroundPic.each}}{{link}}{{/each}}");'>
|
|
||||||
<h2>{{name}}</h2>
|
|
||||||
{{#each profilePic.each}}
|
|
||||||
<img style="max-width:150px;max-height:150px" src="{{link}}"/>
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
<button data-button-update class="btn btn-default">Update</button>
|
|
||||||
{{/if}}
|
|
||||||
</li>
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
}
|
|
||||||
@ -1,87 +0,0 @@
|
|||||||
import { useTracker } from 'meteor/react-meteor-data';
|
|
||||||
import { Meteor } from 'meteor/meteor';
|
|
||||||
import React, { useState, useRef } from 'react';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
import { FilesCol } from '/imports/api/files.js';
|
|
||||||
|
|
||||||
import IndividualFileEnt from '/imports/ui/files/IndividualFileEnt.jsx';
|
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const LlistaArxiusEnt = (props) => {
|
|
||||||
|
|
||||||
const files = useTracker(() => {
|
|
||||||
const filesHandle = Meteor.subscribe('files.all');
|
|
||||||
// const docsReadyYet = filesHandle.ready();
|
|
||||||
const files = FilesCol?.find({meta:{userId: props.uidProvisional || Meteor.userId(), entId: props.entId}}, {sort: {name: 1}}).fetch(); // Meteor.userId() ?? "nop"
|
|
||||||
|
|
||||||
return files;
|
|
||||||
});
|
|
||||||
|
|
||||||
// This is our progress bar, bootstrap styled
|
|
||||||
// Remove this function if not needed
|
|
||||||
// function showUploads() {
|
|
||||||
// //console.log('**********************************', uploading);
|
|
||||||
|
|
||||||
// if (!_.isEmpty(uploading)) {
|
|
||||||
// return <div>
|
|
||||||
// {uploading.file.name}
|
|
||||||
|
|
||||||
// <div className="progress progress-bar-default">
|
|
||||||
// <div style={{width: progress + '%'}} aria-valuemax="100"
|
|
||||||
// aria-valuemin="0"
|
|
||||||
// aria-valuenow={progress || 0} role="progressbar"
|
|
||||||
// className="progress-bar">
|
|
||||||
// <span className="sr-only">{progress}% Complete (success)</span>
|
|
||||||
// <span>{progress}%</span>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
{
|
|
||||||
// debug("Rendering FileUpload",docsReadyYet);
|
|
||||||
if (files /* && docsReadyYet*/) {
|
|
||||||
|
|
||||||
let fileCursors = files;
|
|
||||||
|
|
||||||
// Run through each file that the user has stored
|
|
||||||
// (make sure the subscription only sends files owned by this user)
|
|
||||||
let display = fileCursors.map((aFile, key) => {
|
|
||||||
// console.log('A file: ', aFile.link(), aFile.get('name'))
|
|
||||||
let link = FilesCol.findOne({_id: aFile._id}).link(); //The "view/download" link
|
|
||||||
|
|
||||||
// Send out components that show details of each file
|
|
||||||
return <div
|
|
||||||
key={'file' + key}
|
|
||||||
>
|
|
||||||
<IndividualFileEnt
|
|
||||||
fileName={aFile.name}
|
|
||||||
fileUrl={link}
|
|
||||||
fileId={aFile._id}
|
|
||||||
fileSize={aFile.size}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
})
|
|
||||||
|
|
||||||
return <div
|
|
||||||
style={{
|
|
||||||
display: `flex`,
|
|
||||||
justifyContent: `space-evenly`,
|
|
||||||
alignItems: `center`,
|
|
||||||
flexWrap: `wrap`
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
|
|
||||||
{display}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
else return <div>Loading file list</div>;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default LlistaArxiusEnt;
|
|
||||||
@ -1,187 +0,0 @@
|
|||||||
import { useTracker } from 'meteor/react-meteor-data';
|
|
||||||
import { Meteor } from 'meteor/meteor';
|
|
||||||
import React, { useState, useRef } from 'react';
|
|
||||||
// import PropTypes from 'prop-types';
|
|
||||||
import { FilesCol } from '/imports/api/files.js';
|
|
||||||
|
|
||||||
import FolderTreeIndividualFile from '/imports/ui/files/FolderTreeIndividualFile.jsx';
|
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
import * as d3 from 'd3';
|
|
||||||
|
|
||||||
|
|
||||||
const TreeMap = ({data, link}) => {
|
|
||||||
|
|
||||||
console.table(data);
|
|
||||||
console.log("Link: ", link);
|
|
||||||
|
|
||||||
fetch(link)
|
|
||||||
.then(x => x.text())
|
|
||||||
.then(x => {
|
|
||||||
if(x.lastIndexOf("\n")>0) {
|
|
||||||
return x.substring(0, x.lastIndexOf("\n"));
|
|
||||||
} else {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
//console.log(x);
|
|
||||||
})
|
|
||||||
// .then(x => x.json())
|
|
||||||
.then(x => JSON.parse(x))
|
|
||||||
|
|
||||||
.then(x => {
|
|
||||||
const dataset = x[0];
|
|
||||||
|
|
||||||
// Necessitem canviar el format de l'arbre i substituir "contents" per "children". De moment.
|
|
||||||
function tmFormat(arbre) {
|
|
||||||
|
|
||||||
if (arbre.hasOwnProperty("contents")) {
|
|
||||||
|
|
||||||
arbre.contents.forEach(node => {
|
|
||||||
|
|
||||||
let nodeMod;
|
|
||||||
|
|
||||||
if (node.hasOwnProperty("children")) {
|
|
||||||
nodeMod = {
|
|
||||||
...node,
|
|
||||||
children: node.contents,
|
|
||||||
value: node.size
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
nodeMod = {
|
|
||||||
...node,
|
|
||||||
value: node.size
|
|
||||||
}
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tmFormat(nodeMod);
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
const nouArbre = {
|
|
||||||
...arbre,
|
|
||||||
value: arbre.size
|
|
||||||
};
|
|
||||||
|
|
||||||
return nouArbre;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const tmData = tmFormat(dataset);
|
|
||||||
|
|
||||||
const hierarchyTree = d3.hierarchy(tmData)
|
|
||||||
.sum(d => d.value) //sum every child's values
|
|
||||||
.sort((a, b) => b.value - a.value)
|
|
||||||
;
|
|
||||||
|
|
||||||
//const hierarchyTree = d3.hierarchy(tmData);
|
|
||||||
|
|
||||||
console.log("Dataset: ", dataset);
|
|
||||||
console.log("TMData: ", tmData);
|
|
||||||
console.log("Hierarchy: ", hierarchyTree);
|
|
||||||
})
|
|
||||||
// .then(x => x.json())
|
|
||||||
// .then(x => console.log(x))
|
|
||||||
//.then(x => console.table(x))
|
|
||||||
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const LlistaArxiusFolderTM = (props) => {
|
|
||||||
|
|
||||||
const files = useTracker(() => {
|
|
||||||
const filesHandle = Meteor.subscribe('files.folderTree');
|
|
||||||
// const docsReadyYet = filesHandle.ready();
|
|
||||||
const files = FilesCol?.find({'meta.type': 'folderTree'}, {sort: {name: 1}}).fetch(); // Meteor.userId() ?? "nop"
|
|
||||||
|
|
||||||
return files;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// const methodCall = (methodName, ...args) =>
|
|
||||||
// new Promise((resolve, reject) => {
|
|
||||||
// Meteor.call(methodName, ...args, (error, result) => {
|
|
||||||
// if (error) reject(error);
|
|
||||||
// else resolve(result);
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// ;
|
|
||||||
|
|
||||||
// const files = await methodCall('getFolderTreeFiles');
|
|
||||||
|
|
||||||
// This is our progress bar, bootstrap styled
|
|
||||||
// Remove this function if not needed
|
|
||||||
// function showUploads() {
|
|
||||||
// //console.log('**********************************', uploading);
|
|
||||||
|
|
||||||
// if (!_.isEmpty(uploading)) {
|
|
||||||
// return <div>
|
|
||||||
// {uploading.file.name}
|
|
||||||
|
|
||||||
// <div className="progress progress-bar-default">
|
|
||||||
// <div style={{width: progress + '%'}} aria-valuemax="100"
|
|
||||||
// aria-valuemin="0"
|
|
||||||
// aria-valuenow={progress || 0} role="progressbar"
|
|
||||||
// className="progress-bar">
|
|
||||||
// <span className="sr-only">{progress}% Complete (success)</span>
|
|
||||||
// <span>{progress}%</span>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
{
|
|
||||||
// debug("Rendering FileUpload",docsReadyYet);
|
|
||||||
if (files /* && docsReadyYet*/) {
|
|
||||||
|
|
||||||
let fileCursors = files;
|
|
||||||
|
|
||||||
// Run through each file that the user has stored
|
|
||||||
// (make sure the subscription only sends files owned by this user)
|
|
||||||
let display = fileCursors.map((aFile, key) => {
|
|
||||||
// console.log('A file: ', aFile.link(), aFile.get('name'))
|
|
||||||
let link = FilesCol.findOne({_id: aFile._id}).link(); //The "view/download" link
|
|
||||||
|
|
||||||
// Send out components that show details of each file
|
|
||||||
return <>
|
|
||||||
<div
|
|
||||||
key={'file' + key}
|
|
||||||
>
|
|
||||||
<FolderTreeIndividualFile
|
|
||||||
fileName={aFile.name}
|
|
||||||
fileUrl={link}
|
|
||||||
fileId={aFile._id}
|
|
||||||
fileSize={aFile.size}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<TreeMap data={aFile} link={link} />
|
|
||||||
</>
|
|
||||||
})
|
|
||||||
|
|
||||||
return <div
|
|
||||||
style={{
|
|
||||||
display: `flex`,
|
|
||||||
justifyContent: `space-evenly`,
|
|
||||||
alignItems: `center`,
|
|
||||||
flexWrap: `wrap`
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
|
|
||||||
{display}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
else return <div>Loading file list</div>;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default LlistaArxiusFolderTM;
|
|
||||||
191
server/main.js
191
server/main.js
@ -1,13 +1,12 @@
|
|||||||
import { Meteor } from 'meteor/meteor';
|
import { Meteor } from 'meteor/meteor';
|
||||||
import { PoblesCollection } from '/imports/api/pobles.js';
|
import { PoblesCollection } from '/imports/api/pobles.js';
|
||||||
// import { check } from "meteor/check";
|
import { check } from "meteor/check";
|
||||||
|
|
||||||
import { Roles } from 'meteor/roles';
|
import { Roles } from 'meteor/roles';
|
||||||
import { ROLS_GLOBALS, ROLS_DE_POBLE } from '../imports/roles';
|
import { ROLS_GLOBALS, ROLS_DE_POBLE } from '../imports/roles';
|
||||||
import { NecessitatsCollection } from '../imports/api/necessitats';
|
import { NecessitatsCollection } from '../imports/api/necessitats';
|
||||||
import { TipusCollection } from '../imports/api/tipus';
|
import { TipusCollection } from '../imports/api/tipus';
|
||||||
import { CodisCollection } from '../imports/api/codis';
|
import { CodisCollection } from '../imports/api/codis';
|
||||||
import { Avatars } from '../imports/api/files';
|
|
||||||
// import { Codis } from '../imports/ui/Codis';
|
// import { Codis } from '../imports/ui/Codis';
|
||||||
|
|
||||||
async function insertPoble({ nomPoble, cp, comarca }) {
|
async function insertPoble({ nomPoble, cp, comarca }) {
|
||||||
@ -440,11 +439,11 @@ Meteor.methods({
|
|||||||
const ara = new Date();
|
const ara = new Date();
|
||||||
let dataIni, dataFi;
|
let dataIni, dataFi;
|
||||||
|
|
||||||
console.log("codiObj.condIni: ", await codiObj.condIni);
|
console.log("codiObj.periode_validesa_ini: ", await codiObj.periode_validesa_ini);
|
||||||
|
|
||||||
if (codiObj.absCond === "cond") {
|
if (codiObj.act_cond === "on") {
|
||||||
dataIni = new Date(await codiObj.condIni);
|
dataIni = new Date(await codiObj.periode_validesa_ini);
|
||||||
dataFi = new Date(await codiObj.condFi);
|
dataFi = new Date(await codiObj.periode_validesa_fi);
|
||||||
}
|
}
|
||||||
// const dataIni = codiObj.act_cond === "on" ? new Date(codiObj.periode_validesa_ini) : null;
|
// const dataIni = codiObj.act_cond === "on" ? new Date(codiObj.periode_validesa_ini) : null;
|
||||||
// const dataFi = codiObj.act_cond === "on" ? new Date(codiObj.periode_validesa_fi) : null;
|
// const dataFi = codiObj.act_cond === "on" ? new Date(codiObj.periode_validesa_fi) : null;
|
||||||
@ -453,12 +452,12 @@ Meteor.methods({
|
|||||||
console.log("ara: ", ara);
|
console.log("ara: ", ara);
|
||||||
console.log("dataIni: ", dataIni);
|
console.log("dataIni: ", dataIni);
|
||||||
console.log("dataFi: ", dataFi);
|
console.log("dataFi: ", dataFi);
|
||||||
console.log(`codiObj.absCond`, codiObj.absCond);
|
console.log(`codiObj.act_cond === "on"`, codiObj.act_cond === "on");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log(`APLICANT CODI "${codi}" sobre "${userId}".`); // Comprovant si ${Meteor.userId()} és Admin: `, esAdmin);
|
console.log(`APLICANT CODI "${codi}" sobre "${userId}".`); // Comprovant si ${Meteor.userId()} és Admin: `, esAdmin);
|
||||||
|
|
||||||
if ((codiObj.absCond==="cond" && (ara >= dataIni && ara <= dataFi)) || codiObj.actAbs ) {
|
if ((codiObj.act_cond==="on" && (ara >= dataIni && ara <= dataFi)) || codiObj.act_abs) {
|
||||||
Roles.addUsersToRolesAsync(userId, codiObj.rol, codiObj.ambit);
|
Roles.addUsersToRolesAsync(userId, codiObj.rol, codiObj.ambit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,182 +467,6 @@ Meteor.methods({
|
|||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async 'registraUsuariAmbAvatarICodi'(uObj, codi, avatar) {
|
|
||||||
|
|
||||||
if (codi) {
|
|
||||||
|
|
||||||
console.log("+codi");
|
|
||||||
|
|
||||||
if (avatar) {
|
|
||||||
|
|
||||||
console.log("+avatar");
|
|
||||||
|
|
||||||
// Upload the avatar to GridFS
|
|
||||||
const avatarId = Avatars.insert(avatar.file, (err, fileObj) => {
|
|
||||||
if (err) {
|
|
||||||
throw new Meteor.Error('avatar-upload-failed', 'Failed to upload avatar');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const codiObj = await CodisCollection.findOneAsync({codi});
|
|
||||||
|
|
||||||
// Create the new user
|
|
||||||
const userId = Accounts.createUserAsync({
|
|
||||||
...uObj,
|
|
||||||
profile: {
|
|
||||||
avatar: avatarId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Return the new user's ID
|
|
||||||
// return userId;
|
|
||||||
|
|
||||||
// const userId = await Accounts.createUserAsync(uObj);
|
|
||||||
|
|
||||||
const ara = new Date();
|
|
||||||
let dataIni, dataFi;
|
|
||||||
|
|
||||||
console.log("codiObj.condIni: ", await codiObj.condIni);
|
|
||||||
|
|
||||||
if (codiObj.absCond === "cond") {
|
|
||||||
dataIni = new Date(await codiObj.condIni);
|
|
||||||
dataFi = new Date(await codiObj.condFi);
|
|
||||||
}
|
|
||||||
// const dataIni = codiObj.act_cond === "on" ? new Date(codiObj.periode_validesa_ini) : null;
|
|
||||||
// const dataFi = codiObj.act_cond === "on" ? new Date(codiObj.periode_validesa_fi) : null;
|
|
||||||
|
|
||||||
console.log("codiObj: ", codiObj);
|
|
||||||
console.log("ara: ", ara);
|
|
||||||
console.log("dataIni: ", dataIni);
|
|
||||||
console.log("dataFi: ", dataFi);
|
|
||||||
console.log(`codiObj.absCond`, codiObj.absCond);
|
|
||||||
|
|
||||||
try {
|
|
||||||
console.log(`APLICANT CODI "${codi}" sobre "${userId}".`); // Comprovant si ${Meteor.userId()} és Admin: `, esAdmin);
|
|
||||||
|
|
||||||
if ((codiObj.absCond === "cond" && (ara >= dataIni && ara <= dataFi)) || codiObj.absActiu) {
|
|
||||||
Roles.addUsersToRolesAsync(userId, codiObj.rol, codiObj.ambit);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
console.log("-avatar");
|
|
||||||
|
|
||||||
const codiObj = await CodisCollection.findOneAsync({codi});
|
|
||||||
|
|
||||||
const userId = await Accounts.createUserAsync({
|
|
||||||
...uObj,
|
|
||||||
profile: {
|
|
||||||
avatar: null
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const ara = new Date();
|
|
||||||
let dataIni, dataFi;
|
|
||||||
|
|
||||||
console.log("codiObj.condIni: ", await codiObj.condIni);
|
|
||||||
|
|
||||||
if (codiObj.absCond === "cond") {
|
|
||||||
dataIni = new Date(await codiObj.condIni);
|
|
||||||
dataFi = new Date(await codiObj.condFi);
|
|
||||||
}
|
|
||||||
// const dataIni = codiObj.act_cond === "on" ? new Date(codiObj.periode_validesa_ini) : null;
|
|
||||||
// const dataFi = codiObj.act_cond === "on" ? new Date(codiObj.periode_validesa_fi) : null;
|
|
||||||
|
|
||||||
console.log("codiObj: ", codiObj);
|
|
||||||
console.log("ara: ", ara);
|
|
||||||
console.log("dataIni: ", dataIni);
|
|
||||||
console.log("dataFi: ", dataFi);
|
|
||||||
console.log(`codiObj.absCond`, codiObj.absCond);
|
|
||||||
|
|
||||||
try {
|
|
||||||
console.log(`APLICANT CODI "${codi}" sobre "${userId}".`); // Comprovant si ${Meteor.userId()} és Admin: `, esAdmin);
|
|
||||||
|
|
||||||
if ((codiObj.absCond === "cond" && (ara >= dataIni && ara <= dataFi)) || codiObj.absActiu) {
|
|
||||||
Roles.addUsersToRolesAsync(userId, codiObj.rol, codiObj.ambit);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// const codiObj = await CodisCollection.findOneAsync({codi});
|
|
||||||
|
|
||||||
console.log("-codi");
|
|
||||||
|
|
||||||
const userId = await Accounts.createUserAsync(uObj);
|
|
||||||
|
|
||||||
// const ara = new Date();
|
|
||||||
// let dataIni, dataFi;
|
|
||||||
|
|
||||||
// console.log("codiObj.periode_validesa_ini: ", await codiObj.periode_validesa_ini);
|
|
||||||
|
|
||||||
// if (codiObj.act_cond === "on") {
|
|
||||||
// dataIni = new Date(await codiObj.periode_validesa_ini);
|
|
||||||
// dataFi = new Date(await codiObj.periode_validesa_fi);
|
|
||||||
// }
|
|
||||||
// const dataIni = codiObj.act_cond === "on" ? new Date(codiObj.periode_validesa_ini) : null;
|
|
||||||
// const dataFi = codiObj.act_cond === "on" ? new Date(codiObj.periode_validesa_fi) : null;
|
|
||||||
|
|
||||||
// console.log("codiObj: ", codiObj);
|
|
||||||
// console.log("ara: ", ara);
|
|
||||||
// console.log("dataIni: ", dataIni);
|
|
||||||
// console.log("dataFi: ", dataFi);
|
|
||||||
// console.log(`codiObj.act_cond === "on"`, codiObj.act_cond === "on");
|
|
||||||
|
|
||||||
try {
|
|
||||||
// console.log(`APLICANT CODI "${codi}" sobre "${userId}".`); // Comprovant si ${Meteor.userId()} és Admin: `, esAdmin);
|
|
||||||
|
|
||||||
// if ((codiObj.act_cond==="on" && (ara >= dataIni && ara <= dataFi)) || codiObj.act_abs) {
|
|
||||||
Roles.addUsersToRolesAsync(userId, 'usuari', 'GENERAL');
|
|
||||||
// }
|
|
||||||
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Check if the username and email are valid
|
|
||||||
// if (!username || !email || !password) {
|
|
||||||
// throw new Meteor.Error('invalid-input', 'Please fill in all fields');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Check if the avatar is a valid file
|
|
||||||
// if (!avatar || !avatar.file) {
|
|
||||||
// throw new Meteor.Error('invalid-avatar', 'Please select a valid avatar image');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Upload the avatar to GridFS
|
|
||||||
// const avatarId = Avatars.insert(avatar.file, (err, fileObj) => {
|
|
||||||
// if (err) {
|
|
||||||
// throw new Meteor.Error('avatar-upload-failed', 'Failed to upload avatar');
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
console.log("-avatar-codi");
|
|
||||||
|
|
||||||
// Create the new user
|
|
||||||
const userId = Accounts.createUserAsync({
|
|
||||||
...uObj,
|
|
||||||
profile: {
|
|
||||||
avatar: null
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Return the new user's ID
|
|
||||||
return userId;
|
|
||||||
},
|
|
||||||
|
|
||||||
'usaCodiAmbUsuari': async function (userId, codi) {
|
'usaCodiAmbUsuari': async function (userId, codi) {
|
||||||
// const esAdmin = await Roles.userIsInRoleAsync(Meteor.userId(), "admin");
|
// const esAdmin = await Roles.userIsInRoleAsync(Meteor.userId(), "admin");
|
||||||
const codiObj = await CodisCollection.find({codi}).fetchAsync();
|
const codiObj = await CodisCollection.find({codi}).fetchAsync();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user