diff --git a/app/app/components/document/sidebar-view-activity.js b/app/app/components/document/sidebar-view-activity.js index 84b78a0b..3a7d4b7b 100644 --- a/app/app/components/document/sidebar-view-activity.js +++ b/app/app/components/document/sidebar-view-activity.js @@ -13,64 +13,12 @@ import Ember from 'ember'; export default Ember.Component.extend({ documentService: Ember.inject.service('document'), - appMeta: Ember.inject.service(), - sortedItems: [], didReceiveAttrs() { this._super(...arguments); - this.get('documentService').getMeta(this.get('document.id')).then((activity) => { + this.get('documentService').getActivity(this.get('document.id')).then((activity) => { this.set('activity', activity); - - let editors = this.get('activity.editors'); - let viewers = this.get('activity.viewers'); - let pages = this.get('pages'); - let sorted = []; - - if (is.null(editors)) { - editors = []; - } - - if (is.null(viewers)) { - viewers = []; - } - - viewers.forEach((item) => { - Ember.set(item, 'changeLabel', "viewed"); - Ember.set(item, "viewed", true); - sorted.pushObject({ date: item.created, item: item }); - }); - - editors.forEach(function (item) { - Ember.set(item, "added", item.action === "add-page"); - Ember.set(item, "changed", item.action === "update-page"); - Ember.set(item, "deleted", item.action === "remove-page"); - - let page = pages.findBy('id', item.pageId); - let title = ""; - - if (item.deleted || is.undefined(page)) { - title = "removed section"; - } else { - if (item.added) { - title = "added " + page.get('title'); - } - - if (item.changed) { - title = "changed " + page.get('title'); - } - } - - Ember.set(item, 'changeLabel', title); - - let exists = sorted.findBy('item.pageId', item.pageId); - - if (is.undefined(exists)) { - sorted.pushObject({ date: item.created, item: item }); - } - }); - - this.set('sortedItems', _.sortBy(sorted, 'date').reverse()); }); } }); diff --git a/app/app/models/document-activity.js b/app/app/models/document-activity.js new file mode 100644 index 00000000..5ac51820 --- /dev/null +++ b/app/app/models/document-activity.js @@ -0,0 +1,103 @@ +// Copyright 2016 Documize Inc. . All rights reserved. +// +// This software (Documize Community Edition) is licensed under +// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html +// +// You can operate outside the AGPL restrictions by purchasing +// Documize Enterprise Edition and obtaining a commercial license +// by contacting . +// +// https://documize.com + +import Model from 'ember-data/model'; +import attr from 'ember-data/attr'; +import Ember from 'ember'; +import constants from '../utils/constants'; + +export default Model.extend({ + orgId: attr('string'), + folderId: attr('string'), + documentId: attr('string'), + userId: attr('string'), + firstname: attr('string'), + lastname: attr('string'), + activityType: attr('number'), + created: attr(), + + activityLabel: Ember.computed('activityType', function() { + let label = ''; + + switch (this.get('activityType')) { + case constants.UserActivityType.Created: + label = 'Added'; + break; + case constants.UserActivityType.Read: + label = 'Viewed'; + break; + case constants.UserActivityType.Edited: + label = 'Edited'; + break; + case constants.UserActivityType.Deleted: + label = 'Deleted'; + break; + case constants.UserActivityType.Archived: + label = 'Archived'; + break; + case constants.UserActivityType.Approved: + label = 'Approved'; + break; + case constants.UserActivityType.Reverted: + label = 'Reverted'; + break; + case constants.UserActivityType.PublishedTemplate: + label = 'Published Template'; + break; + case constants.UserActivityType.PublishedBlock: + label = 'Published Block'; + break; + default: + break; + } + + return label; + }), + + activityColor: Ember.computed('activityType', function() { + let color = ''; + + switch (this.get('activityType')) { + case constants.UserActivityType.Created: + color = 'color-blue'; + break; + case constants.UserActivityType.Read: + color = 'color-black'; + break; + case constants.UserActivityType.Edited: + color = 'color-green'; + break; + case constants.UserActivityType.Deleted: + color = 'color-red'; + break; + case constants.UserActivityType.Archived: + color = 'color-gray'; + break; + case constants.UserActivityType.Approved: + color = 'color-green'; + break; + case constants.UserActivityType.Reverted: + color = 'color-red'; + break; + case constants.UserActivityType.PublishedTemplate: + color = 'color-blue'; + break; + case constants.UserActivityType.PublishedBlock: + color = 'color-blue'; + break; + default: + break; + } + + return color; + }) + +}); diff --git a/app/app/services/document.js b/app/app/services/document.js index ae6f9b69..67a677f5 100644 --- a/app/app/services/document.js +++ b/app/app/services/document.js @@ -208,12 +208,19 @@ export default Ember.Service.extend({ }, // document meta referes to number of views, edits, approvals, etc. - getMeta(documentId) { - return this.get('ajax').request(`documents/${documentId}/meta`, { + getActivity(documentId) { + return this.get('ajax').request(`documents/${documentId}/activity`, { method: "GET" }).then((response) => { - return response; + let data = []; + data = response.map((obj) => { + let data = this.get('store').normalize('documentActivity', obj); + return this.get('store').push(data); + }); + + return data; }).catch(() => { + return []; }); }, diff --git a/app/app/templates/components/document/sidebar-view-activity.hbs b/app/app/templates/components/document/sidebar-view-activity.hbs index 46c47293..448da2a9 100644 --- a/app/app/templates/components/document/sidebar-view-activity.hbs +++ b/app/app/templates/components/document/sidebar-view-activity.hbs @@ -2,26 +2,13 @@
Activity
    - {{#each sortedItems as |e|}} + {{#each activity as |a|}}
  • -
    {{user-initials e.item.firstname e.item.lastname}}
    -
    -
    {{e.item.firstname}} {{e.item.lastname}}, {{time-ago e.date}}
    -
    - {{#if e.item.deleted}} -
    {{e.item.changeLabel}}
    - {{/if}} - {{#if e.item.changed}} -
    {{e.item.changeLabel}}
    - {{/if}} - {{#if e.item.added}} -
    {{e.item.changeLabel}}
    - {{/if}} - {{#if e.item.viewed}} -
    {{e.item.changeLabel}}
    - {{/if}} +
    {{user-initials a.firstname a.lastname}}
    +
    {{a.firstname}} {{a.lastname}}
    +
    {{a.activityLabel}}, {{time-ago a.created}}
  • {{/each}}
diff --git a/app/app/utils/constants.js b/app/app/utils/constants.js index 7af13a01..d7f5e0b5 100644 --- a/app/app/utils/constants.js +++ b/app/app/utils/constants.js @@ -26,5 +26,18 @@ export default { Feedback: 2, Contribute: 3, Approve: 4 - } + }, + + UserActivityType: { + Created: 1, + Read: 2, + Edited: 3, + Deleted: 4, + Archived: 5, + Approved: 6, + Reverted: 7, + PublishedTemplate: 8, + PublishedBlock: 9, + Feedback: 10 + } }; diff --git a/core/api/endpoint/document_endpoint.go b/core/api/endpoint/document_endpoint.go index cc061ce5..c1482243 100644 --- a/core/api/endpoint/document_endpoint.go +++ b/core/api/endpoint/document_endpoint.go @@ -26,6 +26,7 @@ import ( "github.com/documize/community/core/log" "github.com/documize/community/core/utility" + "github.com/documize/community/core/api/util" "github.com/gorilla/mux" ) @@ -126,39 +127,25 @@ func GetDocument(w http.ResponseWriter, r *http.Request) { writeSuccessBytes(w, json) } -// GetDocumentMeta is an endpoint returning the metadata for a document. -func GetDocumentMeta(w http.ResponseWriter, r *http.Request) { - method := "GetDocumentMeta" +// GetDocumentActivity is an endpoint returning the activity logs for specified document. +func GetDocumentActivity(w http.ResponseWriter, r *http.Request) { + method := "GetDocumentActivity" p := request.GetPersister(r) - params := mux.Vars(r) - id := params["documentID"] + id := params["documentID"] if len(id) == 0 { writeMissingDataError(w, method, "documentID") return } - meta, err := p.GetDocumentMeta(id) - - if err == sql.ErrNoRows { - writeNotFoundError(w, method, id) - return - } - - if err != nil { + a, err := p.GetDocumentActivity(id) + if err != nil && err != sql.ErrNoRows { writeGeneralSQLError(w, method, err) return } - json, err := json.Marshal(meta) - - if err != nil { - writeJSONMarshalError(w, method, "document", err) - return - } - - writeSuccessBytes(w, json) + util.WriteJSON(w, a) } // GetDocumentLinks is an endpoint returning the links for a document. diff --git a/core/api/endpoint/models/models.go b/core/api/endpoint/models/models.go index 71c638ce..054e3a41 100644 --- a/core/api/endpoint/models/models.go +++ b/core/api/endpoint/models/models.go @@ -16,6 +16,7 @@ package models import ( "github.com/documize/community/core/api/entity" + "time" ) // PageSequenceRequestModel details a page ID and its sequence within the document. @@ -66,3 +67,16 @@ type PageModel struct { Page entity.Page `json:"page"` Meta entity.PageMeta `json:"meta"` } + +// DocumentActivity represents an activity taken against a document. +type DocumentActivity struct { + ID int `json:"id"` + OrgID string `json:"orgId"` + LabelID string `json:"folderId"` + DocumentID string `json:"documentId"` + UserID string `json:"userId"` + Firstname string `json:"firstname"` + Lastname string `json:"lastname"` + ActivityType int `json:"activityType"` + Created time.Time `json:"created"` +} diff --git a/core/api/endpoint/router.go b/core/api/endpoint/router.go index 50d2e668..93fc40dc 100644 --- a/core/api/endpoint/router.go +++ b/core/api/endpoint/router.go @@ -155,7 +155,7 @@ func init() { log.IfErr(Add(RoutePrefixPrivate, "documents/{documentID}", []string{"GET", "OPTIONS"}, nil, GetDocument)) log.IfErr(Add(RoutePrefixPrivate, "documents/{documentID}", []string{"PUT", "OPTIONS"}, nil, UpdateDocument)) log.IfErr(Add(RoutePrefixPrivate, "documents/{documentID}", []string{"DELETE", "OPTIONS"}, nil, DeleteDocument)) - log.IfErr(Add(RoutePrefixPrivate, "documents/{documentID}/meta", []string{"GET", "OPTIONS"}, nil, GetDocumentMeta)) + log.IfErr(Add(RoutePrefixPrivate, "documents/{documentID}/activity", []string{"GET", "OPTIONS"}, nil, GetDocumentActivity)) // Document Page log.IfErr(Add(RoutePrefixPrivate, "documents/{documentID}/pages/level", []string{"POST", "OPTIONS"}, nil, ChangeDocumentPageLevel)) diff --git a/core/api/request/activity.go b/core/api/request/activity.go index 530766f0..bf111492 100644 --- a/core/api/request/activity.go +++ b/core/api/request/activity.go @@ -12,8 +12,11 @@ package request import ( + "database/sql" + "fmt" "time" + "github.com/documize/community/core/api/endpoint/models" "github.com/documize/community/core/api/entity" "github.com/documize/community/core/log" "github.com/documize/community/core/utility" @@ -42,3 +45,27 @@ func (p *Persister) RecordUserActivity(activity entity.UserActivity) (err error) return } + +// GetDocumentActivity returns the metadata for a specified document. +func (p *Persister) GetDocumentActivity(id string) (a []models.DocumentActivity, err error) { + s := `SELECT a.id, a.created, a.orgid, IFNULL(a.userid, '') AS userid, a.labelid, a.sourceid as documentid, a.activitytype, + IFNULL(u.firstname, 'Anonymous') AS firstname, IFNULL(u.lastname, 'Viewer') AS lastname + FROM useractivity a + LEFT JOIN user u ON a.userid=u.refid + WHERE a.orgid=? AND a.sourceid=? AND a.sourcetype=2 + AND a.userid != '0' AND a.userid != '' + ORDER BY a.created DESC` + + err = Db.Select(&a, s, p.Context.OrgID, id) + + if len(a) == 0 { + a = []models.DocumentActivity{} + } + + if err != nil && err != sql.ErrNoRows { + log.Error(fmt.Sprintf("Unable to execute GetDocumentActivity %s", id), err) + return + } + + return +}