diff --git a/core/database/scripts/autobuild/db_00020.sql b/core/database/scripts/autobuild/db_00020.sql index 18a5ba8e..0e6697e9 100644 --- a/core/database/scripts/autobuild/db_00020.sql +++ b/core/database/scripts/autobuild/db_00020.sql @@ -11,6 +11,10 @@ ALTER TABLE rolemember ENGINE = InnoDB; -- content analytics ALTER TABLE useractivity ADD COLUMN `metadata` VARCHAR(1000) NOT NULL DEFAULT '' AFTER `activitytype`; +-- new role for viewing content analytics +ALTER TABLE account ADD COLUMN `analytics` BOOL NOT NULL DEFAULT 0 AFTER `users`; +UPDATE account SET analytics=1 WHERE admin=1; + -- content likes/feedback -- DROP TABLE IF EXISTS `vote`; @@ -31,6 +35,6 @@ ALTER TABLE useractivity ADD COLUMN `metadata` VARCHAR(1000) NOT NULL DEFAULT '' -- DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci -- ENGINE = InnoDB; --- CREATE INDEX idx_vote_1 ON vaote(orgid,documentid); +-- CREATE INDEX idx_vote_1 ON vote(orgid,documentid); -- deprecations diff --git a/domain/account/mysql/store.go b/domain/account/mysql/store.go index ead299c8..469540ab 100644 --- a/domain/account/mysql/store.go +++ b/domain/account/mysql/store.go @@ -33,8 +33,8 @@ func (s Scope) Add(ctx domain.RequestContext, account account.Account) (err erro account.Created = time.Now().UTC() account.Revised = time.Now().UTC() - _, err = ctx.Transaction.Exec("INSERT INTO account (refid, orgid, userid, admin, editor, users, active, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", - account.RefID, account.OrgID, account.UserID, account.Admin, account.Editor, account.Users, account.Active, account.Created, account.Revised) + _, err = ctx.Transaction.Exec("INSERT INTO account (refid, orgid, userid, admin, editor, users, analytics, active, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + account.RefID, account.OrgID, account.UserID, account.Admin, account.Editor, account.Users, account.Analytics, account.Active, account.Created, account.Revised) if err != nil { err = errors.Wrap(err, "unable to execute insert for account") @@ -46,7 +46,7 @@ func (s Scope) Add(ctx domain.RequestContext, account account.Account) (err erro // GetUserAccount returns the database account record corresponding to the given userID, using the client's current organizaion. func (s Scope) GetUserAccount(ctx domain.RequestContext, userID string) (account account.Account, err error) { err = s.Runtime.Db.Get(&account, ` - SELECT a.id, a.refid, a.orgid, a.userid, a.editor, a.admin, a.users, a.active, a.created, a.revised, + SELECT a.id, a.refid, a.orgid, a.userid, a.editor, a.admin, a.users, a.analytics, a.active, a.created, a.revised, b.company, b.title, b.message, b.domain FROM account a, organization b WHERE b.refid=a.orgid AND a.orgid=? AND a.userid=?`, ctx.OrgID, userID) @@ -61,8 +61,8 @@ func (s Scope) GetUserAccount(ctx domain.RequestContext, userID string) (account // GetUserAccounts returns a slice of database account records, for all organizations that the userID is a member of, in organization title order. func (s Scope) GetUserAccounts(ctx domain.RequestContext, userID string) (t []account.Account, err error) { err = s.Runtime.Db.Select(&t, ` - SELECT a.id, a.refid, a.orgid, a.userid, a.editor, a.admin, a.users, a.active, a.created, a.revised, - b.company, b.title, b.message, b.domain + SELECT a.id, a.refid, a.orgid, a.userid, a.editor, a.admin, a.users, a.analytics, a.active, a.created, a.revised, + b.company, b.title, b.message, b.domain FROM account a, organization b WHERE a.userid=? AND a.orgid=b.refid AND a.active=1 ORDER BY b.title`, userID) @@ -76,7 +76,7 @@ func (s Scope) GetUserAccounts(ctx domain.RequestContext, userID string) (t []ac // GetAccountsByOrg returns a slice of database account records, for all users in the client's organization. func (s Scope) GetAccountsByOrg(ctx domain.RequestContext) (t []account.Account, err error) { err = s.Runtime.Db.Select(&t, - `SELECT a.id, a.refid, a.orgid, a.userid, a.editor, a.admin, a.users, a.active, a.created, a.revised, + `SELECT a.id, a.refid, a.orgid, a.userid, a.editor, a.admin, a.users, a.analytics, a.active, a.created, a.revised, b.company, b.title, b.message, b.domain FROM account a, organization b WHERE a.orgid=b.refid AND a.orgid=? AND a.active=1`, ctx.OrgID) @@ -109,7 +109,7 @@ func (s Scope) CountOrgAccounts(ctx domain.RequestContext) (c int) { func (s Scope) UpdateAccount(ctx domain.RequestContext, account account.Account) (err error) { account.Revised = time.Now().UTC() - _, err = ctx.Transaction.NamedExec("UPDATE account SET userid=:userid, admin=:admin, editor=:editor, users=:users, active=:active, revised=:revised WHERE orgid=:orgid AND refid=:refid", &account) + _, err = ctx.Transaction.NamedExec("UPDATE account SET userid=:userid, admin=:admin, editor=:editor, users=:users, analytics=:analytics, active=:active, revised=:revised WHERE orgid=:orgid AND refid=:refid", &account) if err != sql.ErrNoRows && err != nil { err = errors.Wrap(err, fmt.Sprintf("execute update for account %s", account.RefID)) diff --git a/domain/context.go b/domain/context.go index 04473457..967a7a2b 100644 --- a/domain/context.go +++ b/domain/context.go @@ -29,6 +29,7 @@ type RequestContext struct { Guest bool Editor bool Global bool + Analytics bool UserID string OrgID string OrgName string diff --git a/domain/user/endpoint.go b/domain/user/endpoint.go index 465a540a..daaf087c 100644 --- a/domain/user/endpoint.go +++ b/domain/user/endpoint.go @@ -162,6 +162,7 @@ func (h *Handler) Add(w http.ResponseWriter, r *http.Request) { a.Editor = true a.Admin = false a.Active = true + a.Analytics = false err = h.Store.Account.Add(ctx, a) if err != nil { @@ -481,6 +482,7 @@ func (h *Handler) Update(w http.ResponseWriter, r *http.Request) { a.Admin = u.Admin a.Active = u.Active a.Users = u.ViewUsers + a.Analytics = u.Analytics err = h.Store.Account.UpdateAccount(ctx, a) if err != nil { @@ -799,6 +801,7 @@ func (h *Handler) BulkImport(w http.ResponseWriter, r *http.Request) { a.Editor = true a.Admin = false a.Active = true + a.Analytics = false err = h.Store.Account.Add(ctx, a) if err != nil { diff --git a/domain/user/mysql/store.go b/domain/user/mysql/store.go index 41f6df07..691cb6a9 100644 --- a/domain/user/mysql/store.go +++ b/domain/user/mysql/store.go @@ -114,7 +114,7 @@ func (s Scope) GetActiveUsersForOrganization(ctx domain.RequestContext) (u []use err = s.Runtime.Db.Select(&u, `SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.lastversion, u.created, u.revised, - u.global, a.active, a.editor, a.admin, a.users as viewusers + u.global, a.active, a.editor, a.admin, a.users as viewusers, a.analytics FROM user u, account a WHERE u.refid=a.userid AND a.orgid=? AND a.active=1 ORDER BY u.firstname,u.lastname`, @@ -143,7 +143,7 @@ func (s Scope) GetUsersForOrganization(ctx domain.RequestContext, filter string) err = s.Runtime.Db.Select(&u, `SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.lastversion, u.created, u.revised, - u.global, a.active, a.editor, a.admin, a.users as viewusers + u.global, a.active, a.editor, a.admin, a.users as viewusers, a.analytics FROM user u, account a WHERE u.refid=a.userid AND a.orgid=? `+likeQuery+ `ORDER BY u.firstname, u.lastname LIMIT 100`, ctx.OrgID) @@ -165,7 +165,7 @@ func (s Scope) GetSpaceUsers(ctx domain.RequestContext, spaceID string) (u []use err = s.Runtime.Db.Select(&u, ` SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.created, u.lastversion, u.revised, u.global, - a.active, a.users AS viewusers, a.editor, a.admin + a.active, a.users AS viewusers, a.editor, a.admin, a.analytics FROM user u, account a WHERE a.orgid=? AND u.refid = a.userid AND a.active=1 AND u.refid IN ( SELECT whoid from permission WHERE orgid=? AND who='user' AND scope='object' AND location='space' AND refid=? UNION ALL @@ -194,7 +194,7 @@ func (s Scope) GetUsersForSpaces(ctx domain.RequestContext, spaces []string) (u query, args, err := sqlx.In(` SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.lastversion, u.created, u.revised, u.global, - a.active, a.users AS viewusers, a.editor, a.admin + a.active, a.users AS viewusers, a.editor, a.admin, a.analytics FROM user u, account a WHERE a.orgid=? AND u.refid = a.userid AND a.active=1 AND u.refid IN ( SELECT whoid from permission WHERE orgid=? AND who='user' AND scope='object' AND location='space' AND refid IN(?) UNION ALL @@ -295,7 +295,7 @@ func (s Scope) MatchUsers(ctx domain.RequestContext, text string, maxMatches int err = s.Runtime.Db.Select(&u, `SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.lastversion, u.created, u.revised, - u.global, a.active, a.editor, a.admin, a.users as viewusers + u.global, a.active, a.editor, a.admin, a.users as viewusers, a.analytics FROM user u, account a WHERE a.orgid=? AND u.refid=a.userid AND a.active=1 `+likeQuery+ `ORDER BY u.firstname,u.lastname LIMIT `+strconv.Itoa(maxMatches), diff --git a/domain/user/user.go b/domain/user/user.go index 9bc938a9..aaebe442 100644 --- a/domain/user/user.go +++ b/domain/user/user.go @@ -40,6 +40,7 @@ func AttachUserAccounts(ctx domain.RequestContext, s domain.Store, orgID string, u.Admin = false u.Active = false u.ViewUsers = false + u.Analytics = false for _, account := range u.Accounts { if account.OrgID == orgID { @@ -47,6 +48,7 @@ func AttachUserAccounts(ctx domain.RequestContext, s domain.Store, orgID string, u.Editor = account.Editor u.Active = account.Active u.ViewUsers = account.Users + u.Analytics = account.Analytics break } } diff --git a/gui/app/components/customize/user-list.js b/gui/app/components/customize/user-list.js index b1a53f12..94b336cd 100644 --- a/gui/app/components/customize/user-list.js +++ b/gui/app/components/customize/user-list.js @@ -27,7 +27,7 @@ export default Component.extend(AuthProvider, ModalMixin, { init() { this._super(...arguments); this.password = {}; - this.selectedUsers = []; + this.selectedUsers = []; }, didReceiveAttrs() { @@ -91,6 +91,13 @@ export default Component.extend(AuthProvider, ModalMixin, { cb(user); }, + toggleAnalytics(id) { + let user = this.users.findBy("id", id); + user.set('analytics', !user.get('analytics')); + let cb = this.get('onSave'); + cb(user); + }, + toggleUsers(id) { let user = this.users.findBy("id", id); user.set('viewUsers', !user.get('viewUsers')); @@ -208,7 +215,7 @@ export default Component.extend(AuthProvider, ModalMixin, { this.get('groupSvc').leave(groupId, userId).then(() => { this.filterUsers(); - }); + }); }, onJoinGroup(groupId) { @@ -222,7 +229,7 @@ export default Component.extend(AuthProvider, ModalMixin, { this.get('groupSvc').join(groupId, userId).then(() => { this.filterUsers(); - }); - } + }); + } } }); diff --git a/gui/app/models/user.js b/gui/app/models/user.js index e4b4d8ac..ff56d7e9 100644 --- a/gui/app/models/user.js +++ b/gui/app/models/user.js @@ -22,6 +22,7 @@ export default Model.extend({ editor: attr('boolean', { defaultValue: false }), admin: attr('boolean', { defaultValue: false }), viewUsers: attr('boolean', { defaultValue: false }), + analytics: attr('boolean', { defaultValue: false }), global: attr('boolean', { defaultValue: false }), accounts: attr(), groups: attr(), diff --git a/gui/app/services/document.js b/gui/app/services/document.js index fc7bc826..cddcc2f2 100644 --- a/gui/app/services/document.js +++ b/gui/app/services/document.js @@ -386,6 +386,8 @@ export default Service.extend({ let userHasChangeAwaitingReview = false; let userHasChangeRejected = false; + if (is.null(source) || is.undefined(source)) source = ""; + return this.get('ajax').request(`fetch/page/${documentId}?source=${source}`, { method: 'GET' }).then((response) => { diff --git a/gui/app/templates/components/customize/user-list.hbs b/gui/app/templates/components/customize/user-list.hbs index cc796be2..9d9b65d6 100644 --- a/gui/app/templates/components/customize/user-list.hbs +++ b/gui/app/templates/components/customize/user-list.hbs @@ -1,5 +1,5 @@