mirror of
https://github.com/wekan/wekan.git
synced 2026-01-24 18:26:10 +01:00
Multi-File Storage.
Thanks to mfilser ! Related https://github.com/wekan/wekan/pull/4484 Merge branch 'master' into upgrade-meteor
This commit is contained in:
commit
68e8155805
29 changed files with 921 additions and 276 deletions
|
|
@ -11,11 +11,6 @@ template(name="adminReports")
|
|||
i.fa.fa-chain-broken
|
||||
| {{_ 'broken-cards'}}
|
||||
|
||||
li
|
||||
a.js-report-files(data-id="report-orphaned-files")
|
||||
i.fa.fa-paperclip
|
||||
| {{_ 'orphanedFilesReportTitle'}}
|
||||
|
||||
li
|
||||
a.js-report-files(data-id="report-files")
|
||||
i.fa.fa-paperclip
|
||||
|
|
@ -43,8 +38,6 @@ template(name="adminReports")
|
|||
+brokenCardsReport
|
||||
else if showFilesReport.get
|
||||
+filesReport
|
||||
else if showOrphanedFilesReport.get
|
||||
+orphanedFilesReport
|
||||
else if showRulesReport.get
|
||||
+rulesReport
|
||||
else if showBoardsReport.get
|
||||
|
|
@ -64,7 +57,7 @@ template(name="brokenCardsReport")
|
|||
template(name="rulesReport")
|
||||
h1 {{_ 'rulesReportTitle'}}
|
||||
if resultsCount
|
||||
table.table
|
||||
table
|
||||
tr
|
||||
th Rule Title
|
||||
th Board Title
|
||||
|
|
@ -83,44 +76,23 @@ template(name="rulesReport")
|
|||
template(name="filesReport")
|
||||
h1 {{_ 'filesReportTitle'}}
|
||||
if resultsCount
|
||||
table.table
|
||||
table
|
||||
tr
|
||||
th Filename
|
||||
th.right Size (kB)
|
||||
th MIME Type
|
||||
th.center Usage
|
||||
th MD5 Sum
|
||||
th ID
|
||||
th Attachment ID
|
||||
th Board ID
|
||||
th Card ID
|
||||
|
||||
each att in results
|
||||
tr
|
||||
td {{ att.filename }}
|
||||
td.right {{fileSize att.length }}
|
||||
td {{ att.contentType }}
|
||||
td.center {{usageCount att._id.toHexString }}
|
||||
td {{ att.md5 }}
|
||||
td {{ att._id.toHexString }}
|
||||
else
|
||||
div {{_ 'no-results' }}
|
||||
|
||||
template(name="orphanedFilesReport")
|
||||
h1 {{_ 'orphanedFilesReportTitle'}}
|
||||
if resultsCount
|
||||
table.table
|
||||
tr
|
||||
th Filename
|
||||
th.right Size (kB)
|
||||
th MIME Type
|
||||
th MD5 Sum
|
||||
th ID
|
||||
|
||||
each att in results
|
||||
tr
|
||||
td {{ att.filename }}
|
||||
td.right {{fileSize att.length }}
|
||||
td {{ att.contentType }}
|
||||
td {{ att.md5 }}
|
||||
td {{ att._id.toHexString }}
|
||||
td {{ att.name }}
|
||||
td.right {{fileSize att.size }}
|
||||
td {{ att.type }}
|
||||
td {{ att._id }}
|
||||
td {{ att.meta.boardId }}
|
||||
td {{ att.meta.cardId }}
|
||||
else
|
||||
div {{_ 'no-results' }}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ BlazeComponent.extendComponent({
|
|||
{
|
||||
'click a.js-report-broken': this.switchMenu,
|
||||
'click a.js-report-files': this.switchMenu,
|
||||
'click a.js-report-orphaned-files': this.switchMenu,
|
||||
'click a.js-report-rules': this.switchMenu,
|
||||
'click a.js-report-cards': this.switchMenu,
|
||||
'click a.js-report-boards': this.switchMenu,
|
||||
|
|
@ -66,11 +65,6 @@ BlazeComponent.extendComponent({
|
|||
this.subscription = Meteor.subscribe('attachmentsList', () => {
|
||||
this.loading.set(false);
|
||||
});
|
||||
} else if ('report-orphaned-files' === targetID) {
|
||||
this.showOrphanedFilesReport.set(true);
|
||||
this.subscription = Meteor.subscribe('orphanedAttachments', () => {
|
||||
this.loading.set(false);
|
||||
});
|
||||
} else if ('report-rules' === targetID) {
|
||||
this.subscription = Meteor.subscribe('rulesReport', () => {
|
||||
this.showRulesReport.set(true);
|
||||
|
|
@ -104,8 +98,6 @@ class AdminReport extends BlazeComponent {
|
|||
|
||||
results() {
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('attachments:', AttachmentStorage.find());
|
||||
// console.log('attachments.count:', AttachmentStorage.find().count());
|
||||
return this.collection.find();
|
||||
}
|
||||
|
||||
|
|
@ -125,10 +117,6 @@ class AdminReport extends BlazeComponent {
|
|||
return Math.round(size / 1024);
|
||||
}
|
||||
|
||||
usageCount(key) {
|
||||
return Attachments.find({ 'copies.attachments.key': key }).count();
|
||||
}
|
||||
|
||||
abbreviate(text) {
|
||||
if (text.length > 30) {
|
||||
return `${text.substr(0, 29)}...`;
|
||||
|
|
@ -138,13 +126,9 @@ class AdminReport extends BlazeComponent {
|
|||
}
|
||||
|
||||
(class extends AdminReport {
|
||||
collection = AttachmentStorage;
|
||||
collection = Attachments;
|
||||
}.register('filesReport'));
|
||||
|
||||
(class extends AdminReport {
|
||||
collection = AttachmentStorage;
|
||||
}.register('orphanedFilesReport'));
|
||||
|
||||
(class extends AdminReport {
|
||||
collection = Rules;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
.admin-reports-content
|
||||
height: auto !important
|
||||
|
||||
84
client/components/settings/attachments.jade
Normal file
84
client/components/settings/attachments.jade
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
template(name="attachments")
|
||||
.setting-content.attachments-content
|
||||
unless currentUser.isAdmin
|
||||
| {{_ 'error-notAuthorized'}}
|
||||
else
|
||||
.content-body
|
||||
.side-menu
|
||||
ul
|
||||
li
|
||||
a.js-move-attachments(data-id="move-attachments")
|
||||
i.fa.fa-arrow-right
|
||||
| {{_ 'attachment-move'}}
|
||||
|
||||
.main-body
|
||||
if loading.get
|
||||
+spinner
|
||||
else if showMoveAttachments.get
|
||||
+moveAttachments
|
||||
|
||||
template(name="moveAttachments")
|
||||
.move-attachment-buttons
|
||||
.js-move-attachment
|
||||
button.js-move-all-attachments-to-fs {{_ 'move-all-attachments-to-fs'}}
|
||||
.js-move-attachment
|
||||
button.js-move-all-attachments-to-gridfs {{_ 'move-all-attachments-to-gridfs'}}
|
||||
|
||||
each board in getBoardsWithAttachments
|
||||
+moveBoardAttachments board
|
||||
|
||||
template(name="moveBoardAttachments")
|
||||
hr
|
||||
.board-description
|
||||
table
|
||||
tr
|
||||
th {{_ 'board'}} ID
|
||||
th {{_ 'board-title'}}
|
||||
tr
|
||||
td {{ _id }}
|
||||
td {{ title }}
|
||||
|
||||
.move-attachment-buttons
|
||||
.js-move-attachment
|
||||
button.js-move-all-attachments-of-board-to-fs {{_ 'move-all-attachments-of-board-to-fs'}}
|
||||
.js-move-attachment
|
||||
button.js-move-all-attachments-of-board-to-gridfs {{_ 'move-all-attachments-of-board-to-gridfs'}}
|
||||
|
||||
.board-attachments
|
||||
table
|
||||
tr
|
||||
th {{_ 'card'}}-Id
|
||||
th {{_ 'attachment'}}-Id
|
||||
th {{_ 'name'}}
|
||||
th {{_ 'path'}}
|
||||
th {{_ 'version-name'}}
|
||||
th {{_ 'size'}} (B)
|
||||
th GridFsFileId
|
||||
th {{_ 'storage'}}
|
||||
th {{_ 'action'}}
|
||||
|
||||
each attachment in attachments
|
||||
+moveAttachment attachment
|
||||
|
||||
template(name="moveAttachment")
|
||||
each version in flatVersion
|
||||
tr
|
||||
td {{ meta.cardId }}
|
||||
td {{ _id }}
|
||||
td {{ name }}
|
||||
td {{ version.path }}
|
||||
td {{ version.versionName }}
|
||||
td {{ version.size }}
|
||||
td {{ version.meta.gridFsFileId }}
|
||||
td {{ version.storageName }}
|
||||
td
|
||||
if $neq version.storageName "fs"
|
||||
button.js-move-storage-fs
|
||||
i.fa.fa-arrow-right
|
||||
| {{_ 'attachment-move-storage-fs'}}
|
||||
|
||||
if $neq version.storageName "gridfs"
|
||||
if version.storageName
|
||||
button.js-move-storage-gridfs
|
||||
i.fa.fa-arrow-right
|
||||
| {{_ 'attachment-move-storage-gridfs'}}
|
||||
123
client/components/settings/attachments.js
Normal file
123
client/components/settings/attachments.js
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
import Attachments, { fileStoreStrategyFactory } from '/models/attachments';
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
subscription: null,
|
||||
showMoveAttachments: new ReactiveVar(false),
|
||||
sessionId: null,
|
||||
|
||||
onCreated() {
|
||||
this.error = new ReactiveVar('');
|
||||
this.loading = new ReactiveVar(false);
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click a.js-move-attachments': this.switchMenu,
|
||||
},
|
||||
];
|
||||
},
|
||||
|
||||
switchMenu(event) {
|
||||
const target = $(event.target);
|
||||
if (!target.hasClass('active')) {
|
||||
this.loading.set(true);
|
||||
this.showMoveAttachments.set(false);
|
||||
if (this.subscription) {
|
||||
this.subscription.stop();
|
||||
}
|
||||
|
||||
$('.side-menu li.active').removeClass('active');
|
||||
target.parent().addClass('active');
|
||||
const targetID = target.data('id');
|
||||
|
||||
if ('move-attachments' === targetID) {
|
||||
this.showMoveAttachments.set(true);
|
||||
this.subscription = Meteor.subscribe('attachmentsList', () => {
|
||||
this.loading.set(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
}).register('attachments');
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
getBoardsWithAttachments() {
|
||||
this.attachments = Attachments.find().get();
|
||||
this.attachmentsByBoardId = _.chain(this.attachments)
|
||||
.groupBy(fileObj => fileObj.meta.boardId)
|
||||
.value();
|
||||
|
||||
const ret = Object.keys(this.attachmentsByBoardId)
|
||||
.map(boardId => {
|
||||
const boardAttachments = this.attachmentsByBoardId[boardId];
|
||||
|
||||
_.each(boardAttachments, _attachment => {
|
||||
_attachment.flatVersion = Object.keys(_attachment.versions)
|
||||
.map(_versionName => {
|
||||
const _version = Object.assign(_attachment.versions[_versionName], {"versionName": _versionName});
|
||||
_version.storageName = fileStoreStrategyFactory.getFileStrategy(_attachment, _versionName).getStorageName();
|
||||
return _version;
|
||||
});
|
||||
});
|
||||
const board = Boards.findOne(boardId);
|
||||
board.attachments = boardAttachments;
|
||||
return board;
|
||||
})
|
||||
return ret;
|
||||
},
|
||||
getBoardData(boardid) {
|
||||
const ret = Boards.findOne(boardId);
|
||||
return ret;
|
||||
},
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click button.js-move-all-attachments-to-fs'(event) {
|
||||
this.attachments.forEach(_attachment => {
|
||||
Meteor.call('moveAttachmentToStorage', _attachment._id, "fs");
|
||||
});
|
||||
},
|
||||
'click button.js-move-all-attachments-to-gridfs'(event) {
|
||||
this.attachments.forEach(_attachment => {
|
||||
Meteor.call('moveAttachmentToStorage', _attachment._id, "gridfs");
|
||||
});
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
}).register('moveAttachments');
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click button.js-move-all-attachments-of-board-to-fs'(event) {
|
||||
this.data().attachments.forEach(_attachment => {
|
||||
Meteor.call('moveAttachmentToStorage', _attachment._id, "fs");
|
||||
});
|
||||
},
|
||||
'click button.js-move-all-attachments-of-board-to-gridfs'(event) {
|
||||
this.data().attachments.forEach(_attachment => {
|
||||
Meteor.call('moveAttachmentToStorage', _attachment._id, "gridfs");
|
||||
});
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
}).register('moveBoardAttachments');
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click button.js-move-storage-fs'(event) {
|
||||
Meteor.call('moveAttachmentToStorage', this.data()._id, "fs");
|
||||
},
|
||||
'click button.js-move-storage-gridfs'(event) {
|
||||
Meteor.call('moveAttachmentToStorage', this.data()._id, "gridfs");
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
}).register('moveAttachment');
|
||||
8
client/components/settings/attachments.styl
Normal file
8
client/components/settings/attachments.styl
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
.move-attachment-buttons
|
||||
display: flex
|
||||
gap: 10px
|
||||
|
||||
.attachments-content
|
||||
hr
|
||||
height: 0px
|
||||
border: 1px solid black
|
||||
|
|
@ -2,8 +2,6 @@
|
|||
overflow: scroll;
|
||||
|
||||
table
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
color: #000;
|
||||
|
||||
td, th
|
||||
|
|
@ -22,14 +20,13 @@ table
|
|||
.ext-box-left
|
||||
display: flex;
|
||||
width: 100%
|
||||
gap: 10px
|
||||
|
||||
span
|
||||
vertical-align: center;
|
||||
line-height: 34px;
|
||||
margin-right: 10px;
|
||||
|
||||
input, button
|
||||
margin: 0 10px 0 0;
|
||||
padding: 0;
|
||||
|
||||
button
|
||||
|
|
|
|||
|
|
@ -7,11 +7,9 @@
|
|||
display: flex
|
||||
|
||||
.setting-content
|
||||
padding 30px
|
||||
color: #727479
|
||||
background: #dedede
|
||||
width 100%
|
||||
height calc(100% - 80px)
|
||||
position: absolute;
|
||||
|
||||
.content-title
|
||||
|
|
@ -21,6 +19,7 @@
|
|||
display flex
|
||||
padding-top 15px
|
||||
height 100%
|
||||
gap: 10px;
|
||||
|
||||
.side-menu
|
||||
background-color: #f7f7f7;
|
||||
|
|
@ -54,7 +53,6 @@
|
|||
margin-right: 20px
|
||||
|
||||
.main-body
|
||||
padding: 0.1em 1em
|
||||
-webkit-user-select: text // Safari 3.1+
|
||||
-moz-user-select: text // Firefox 2+
|
||||
-ms-user-select: text // IE 10+
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@ template(name="settingHeaderBar")
|
|||
i.fa(class="fa-list")
|
||||
span {{_ 'reports'}}
|
||||
|
||||
a.setting-header-btn.informations(href="{{pathFor 'attachments'}}")
|
||||
i.fa(class="fa-paperclip")
|
||||
span {{_ 'attachments'}}
|
||||
|
||||
a.setting-header-btn.informations(href="{{pathFor 'information'}}")
|
||||
i.fa(class="fa-info-circle")
|
||||
span {{_ 'info'}}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue