Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Activity tab in files sidebar #358

Merged
merged 2 commits into from
Aug 24, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions js/activitycollection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2015
*
* This file is licensed under the Affero General Public License version 3
* or later.
*
* See the COPYING-README file.
*
*/

(function() {

OCA.Activity = OCA.Activity || {};

/**
* @class OCA.Activity.ActivityCollection
* @classdesc
*
* Displays activity information for a given file
*
*/
var ActivityCollection = OC.Backbone.Collection.extend(
/** @lends OCA.Activity.ActivityCollection.prototype */ {

/**
* Id of the file for which to filter activities by
*
* @var int
*/
_objectId: null,

/**
* Type of the object to filter by
*
* @var string
*/
_objectType: null,

model: OCA.Activity.ActivityModel,

/**
* Sets the object id to filter by or null for all.
*
* @param {int} objectId file id or null
*/
setObjectId: function(objectId) {
this._objectId = objectId;
},

/**
* Sets the object type to filter by or null for all.
*
* @param {int} objectType file id or null
*/
setObjectType: function(objectType) {
this._objectType = objectType;
},

url: function() {
var query = {
page: 1,
filter: 'all'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filter: 'filter'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but only when objectid or objecttype are set ? or always ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all gives all, filter uses object id and type, see the following lines:
https://github.com/owncloud/activity/pull/363/files#diff-7842161f69cff3997d7b10126d8c368fR223

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this still needs updating?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scroll down

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we only set the filter if either objectId or objectType are set. Else we fetch all (could be used later in other views)

};
var url = OC.generateUrl('apps/activity/activities/fetch');
if (this._objectId) {
query.objectid = this._objectId;
query.filter = 'filter';
}
if (this._objectType) {
query.objecttype = this._objectType;
query.filter = 'filter';
}
url += '?' + OC.buildQueryString(query);
return url;
}
});

OCA.Activity.ActivityCollection = ActivityCollection;
})();

26 changes: 26 additions & 0 deletions js/activitymodel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2015
*
* This file is licensed under the Affero General Public License version 3
* or later.
*
* See the COPYING-README file.
*
*/

(function() {
/**
* @class OCA.Activity.ActivityModel
* @classdesc
*
* Displays activity information for a given file
*
*/
var ActivityModel = OC.Backbone.Model.extend(
/** @lends OCA.Activity.ActivityModel.prototype */ {
});

OCA.Activity = OCA.Activity || {};
OCA.Activity.ActivityModel = ActivityModel;
})();

161 changes: 161 additions & 0 deletions js/activitytabview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/*
* Copyright (c) 2015
*
* This file is licensed under the Affero General Public License version 3
* or later.
*
* See the COPYING-README file.
*
*/

(function() {
var TEMPLATE =
'<div>' +
'{{#if loading}}' +
'<div class="loading" style="height: 50px"></div>' +
'{{end}}' +
'{{else}}' +
'<ul>' +
'{{#each activities}}' +
' <li class="activity box">' +
' <div class="activity-icon {{typeIconClass}}"></div>' +
' <div class="activitysubject">{{{subject}}}</div>' +
' <span class="activitytime has-tooltip" title="{{formattedDateTooltip}}">{{formattedDate}}</span>' +
' <div class="activitymessage">{{{message}}}</div>' +
' {{#if previews}}' +
' <div class="previews">' +
' {{#each previews}}' +
' <img class="preview {{previewClass}}" src="{{source}}" alt="" />' +
' {{/each}}' +
' </div>' +
' {{/if}}' +
' </li>' +
'{{else}}' +
' <li class="empty">{{emptyMessage}}</li>' +
'{{/each}}' +
'</ul>' +
'{{/if}}' +
'</div>';

/**
* Format an activity model for display
*
* @param {OCA.Activity.ActivityModel} activity
* @return {Object}
*/
function formatActivity(activity) {
var output = {
subject: activity.get('subjectformatted').markup.trimmed,
formattedDate: activity.get('relativeDateTimestamp'),
formattedDateTooltip: activity.get('readableDateTimestamp'),
message: activity.get('messageformatted').markup.trimmed
};

if (activity.has('typeicon')) {
output.typeIconClass = activity.get('typeicon') + ' svg';
}
if (activity.has('previews')) {
output.previews = _.map(activity.get('previews'), function(data) {
return {
previewClass: data.isMimeTypeIcon ? 'preview-mimetype-icon': '',
source: data.source
};
});
}
return output;
}

/**
* @class OCA.Activity.ActivityTabView
* @classdesc
*
* Displays activity information for a given file
*
*/
var ActivityTabView = OCA.Files.DetailTabView.extend(
/** @lends OCA.Activity.ActivityTabView.prototype */ {
id: 'activityTabView',
className: 'activityTabView tab',

_loading: false,

initialize: function() {
this.collection = new OCA.Activity.ActivityCollection();
this.collection.setObjectType('files');
this.collection.on('request', this._onRequest, this);
this.collection.on('sync', this._onEndRequest, this);
this.collection.on('update', this._onChange, this);
this.collection.on('error', this._onError, this);
},

template: function(data) {
if (!this._template) {
this._template = Handlebars.compile(TEMPLATE);
}
return this._template(data);
},

get$: function() {
return this.$el;
},

getLabel: function() {
return t('activity', 'Activities');
},

setFileInfo: function(fileInfo) {
this._fileInfo = fileInfo;
if (this._fileInfo) {
this.collection.setObjectId(this._fileInfo.get('id'));
this.collection.fetch();
} else {
this.collection.reset();
}
},

_onError: function() {
OC.Notification.showTemporary(t('activity', 'Error loading activities'));
},

_onRequest: function() {
this._loading = true;
this.render();
},

_onEndRequest: function() {
this._loading = false;
// empty result ?
if (!this.collection.length) {
// render now as there will be no update event
this.render();
}
},

_onChange: function() {
this._loading = false;
this.render();
},

/**
* Renders this details view
*/
render: function() {
if (this._fileInfo) {
this.$el.html(this.template({
loading: this._loading,
activities: this.collection.map(formatActivity),
emptyMessage: t('activity', 'No activities')
}));
this.$el.find('.has-tooltip').tooltip({
placement: 'bottom'
});
} else {
// TODO: render placeholder text?
}
}
});

OCA.Activity = OCA.Activity || {};
OCA.Activity.ActivityTabView = ActivityTabView;
})();

22 changes: 22 additions & 0 deletions js/filesplugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2015
*
* This file is licensed under the Affero General Public License version 3
* or later.
*
* See the COPYING-README file.
*
*/

(function(OCA) {

var FilesPlugin = {
attach: function(fileList) {
fileList.registerTabView(new OCA.Activity.ActivityTabView());
}
};

OC.Plugins.register('OCA.Files.FileList', FilesPlugin);

})(OCA);

14 changes: 14 additions & 0 deletions lib/fileshooksstatic.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ public static function register() {
Util::connectHook('OC_Filesystem', 'delete', 'OCA\Activity\FilesHooksStatic', 'fileDelete');
Util::connectHook('\OCA\Files_Trashbin\Trashbin', 'post_restore', 'OCA\Activity\FilesHooksStatic', 'fileRestore');
Util::connectHook('OCP\Share', 'post_shared', 'OCA\Activity\FilesHooksStatic', 'share');

$eventDispatcher = \OC::$server->getEventDispatcher();
$eventDispatcher->addListener('OCA\Files::loadAdditionalScripts', ['OCA\Activity\FilesHooksStatic', 'onLoadFilesAppScripts']);
}

/**
Expand Down Expand Up @@ -87,4 +90,15 @@ public static function fileRestore($params) {
public static function share($params) {
self::getHooks()->share($params);
}

/**
* Load additional scripts when the files app is visible
*/
public static function onLoadFilesAppScripts() {
\OCP\Util::addStyle('activity', 'style');
\OCP\Util::addScript('activity', 'activitymodel');
\OCP\Util::addScript('activity', 'activitycollection');
\OCP\Util::addScript('activity', 'activitytabview');
\OCP\Util::addScript('activity', 'filesplugin');
}
}
34 changes: 34 additions & 0 deletions tests/js/activitycollectionSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2015
*
* This file is licensed under the Affero General Public License version 3
* or later.
*
* See the COPYING-README file.
*
*/
describe('ActivityCollection', function() {
var ActivityCollection = OCA.Activity.ActivityCollection;

describe('query url', function() {
it('does not filter by default', function() {
var col = new ActivityCollection();
expect(col.url())
.toEqual(
OC.generateUrl('apps/activity/activities/fetch') +
'?page=1&filter=all'
);
});
it('filters by id and type when specified', function() {
var col = new ActivityCollection();
col.setObjectType('files');
col.setObjectId(512);
expect(col.url())
.toEqual(
OC.generateUrl('apps/activity/activities/fetch') +
'?page=1&filter=filter&objectid=512&objecttype=files'
);
});
});
});

Loading