Merge pull request #916 from sharelatex/revert-900-ja-show-last-modified

Revert "Record and show last modified by user for projects"
This commit is contained in:
James Allen 2018-09-13 14:01:36 +01:00 committed by GitHub
commit 14b77a2060
17 changed files with 344 additions and 410 deletions

View file

@ -7,7 +7,6 @@ HistoryManager = require "./HistoryManager"
ProjectDetailsHandler = require "../Project/ProjectDetailsHandler"
ProjectEntityUpdateHandler = require "../Project/ProjectEntityUpdateHandler"
RestoreManager = require "./RestoreManager"
ProjectUpdateHandler = require "../Project/ProjectUpdateHandler"
module.exports = HistoryController =
selectHistoryApi: (req, res, next = (error) ->) ->
@ -144,11 +143,3 @@ module.exports = HistoryController =
error = new Error("history api responded with non-success code: #{response.statusCode}")
logger.error err: error, "project-history api responded with non-success code: #{response.statusCode}"
callback(error)
setLastUpdated: (req, res, next) ->
{project_id} = req.params
{user_id, timestamp} = req.body
logger.log {project_id, user_id, timestamp}, 'updating last updated date'
ProjectUpdateHandler.markAsUpdated project_id, user_id, timestamp, (error) ->
return next(error) if error?
res.sendStatus 200

View file

@ -184,7 +184,7 @@ module.exports = ProjectController =
notifications: (cb)->
NotificationsHandler.getUserNotifications user_id, cb
projects: (cb)->
ProjectGetter.findAllUsersProjects user_id, 'name lastUpdated lastUpdatedBy publicAccesLevel archived owner_ref tokens', cb
ProjectGetter.findAllUsersProjects user_id, 'name lastUpdated publicAccesLevel archived owner_ref tokens', cb
v1Projects: (cb) ->
Modules.hooks.fire "findAllV1Projects", user_id, (error, projects = []) ->
if error? and error instanceof V1ConnectionError
@ -392,7 +392,6 @@ module.exports = ProjectController =
id: project._id
name: project.name
lastUpdated: project.lastUpdated
lastUpdatedBy: project.lastUpdatedBy
publicAccessLevel: project.publicAccesLevel
accessLevel: accessLevel
source: source
@ -431,8 +430,6 @@ module.exports = ProjectController =
for project in projects
if project.owner_ref?
users[project.owner_ref.toString()] = true
if project.lastUpdatedBy?
users[project.lastUpdatedBy] = true
jobs = []
for user_id, _ of users
@ -447,8 +444,6 @@ module.exports = ProjectController =
for project in projects
if project.owner_ref?
project.owner = users[project.owner_ref.toString()]
if project.lastUpdatedBy?
project.lastUpdatedBy = users[project.lastUpdatedBy.toString()]
callback null, projects
_buildWarningsList: (v1ProjectData = {}) ->

View file

@ -114,6 +114,8 @@ module.exports = ProjectEntityUpdateHandler = self =
logger.log {project_id, doc_id, modified}, "finished updating doc lines"
# path will only be present if the doc is not deleted
if modified && !isDeletedDoc
# Don't need to block for marking as updated
ProjectUpdateHandler.markAsUpdated project_id
TpdsUpdateSender.addDoc {project_id:project_id, path:path.fileSystem, doc_id:doc_id, project_name:project.name, rev:rev}, callback
else
callback()

View file

@ -2,25 +2,30 @@ Project = require('../../models/Project').Project
logger = require('logger-sharelatex')
module.exports =
markAsUpdated : (project_id, user_id, timestamp, callback)->
markAsUpdated : (project_id, callback)->
conditions = {_id:project_id}
update = {
lastUpdated: new Date(timestamp),
lastUpdatedBy: user_id
}
Project.update conditions, update, {}, callback
update = {lastUpdated:Date.now()}
Project.update conditions, update, {}, (err)->
if callback?
callback()
markAsOpened : (project_id, callback)->
conditions = {_id:project_id}
update = {lastOpened:Date.now()}
Project.update conditions, update, {}, callback
Project.update conditions, update, {}, (err)->
if callback?
callback()
markAsInactive: (project_id, callback)->
conditions = {_id:project_id}
update = {active:false}
Project.update conditions, update, {}, callback
Project.update conditions, update, {}, (err)->
if callback?
callback()
markAsActive: (project_id, callback)->
conditions = {_id:project_id}
update = {active:true}
Project.update conditions, update, {}, callback
Project.update conditions, update, {}, (err)->
if callback?
callback()

View file

@ -19,7 +19,6 @@ DeletedFileSchema = new Schema
ProjectSchema = new Schema
name : {type:String, default:'new project'}
lastUpdated : {type:Date, default: () -> new Date()}
lastUpdatedBy : {type:ObjectId, ref: 'User'}
lastOpened : {type:Date}
active : { type: Boolean, default: true }
owner_ref : {type:ObjectId, ref:'User'}

View file

@ -238,7 +238,6 @@ module.exports = class Router
webRouter.post '/project/:project_id/doc/:doc_id/restore', AuthorizationMiddlewear.ensureUserCanWriteProjectContent, HistoryController.restoreDocFromDeletedDoc
webRouter.post "/project/:project_id/restore_file", AuthorizationMiddlewear.ensureUserCanWriteProjectContent, HistoryController.restoreFileFromV2
privateApiRouter.post "/project/:Project_id/history/resync", AuthenticationController.httpAuth, HistoryController.resyncProjectHistory
privateApiRouter.post "/project/:project_id/last_updated", AuthenticationController.httpAuth, HistoryController.setLastUpdated
webRouter.get "/project/:Project_id/labels", AuthorizationMiddlewear.ensureUserCanReadProject, HistoryController.selectHistoryApi, HistoryController.ensureProjectHistoryEnabled, HistoryController.getLabels
webRouter.post "/project/:Project_id/labels", AuthorizationMiddlewear.ensureUserCanWriteProjectContent, HistoryController.selectHistoryApi, HistoryController.ensureProjectHistoryEnabled, HistoryController.createLabel

View file

@ -1,6 +1,8 @@
td.selectProject
- var titleClasses = settings.overleaf ? "col-xs-6 col-sm-4 col-md-6" : "col-xs-6"
- var lastUpdatedClasses = settings.overleaf ? " col-xs-4 col-sm-3 col-md-2" : "col-xs-4"
div(class=titleClasses)
input.select-item(
ng-if="!project.isV1Project",
select-individual,
type="checkbox",
ng-disabled="shouldDisableCheckbox(project)",
@ -8,26 +10,7 @@ td.selectProject
stop-propagation="click"
aria-label=translate('select_project') + " '{{ project.name }}'"
)
span.v1-badge(
ng-if="project.isV1Project",
aria-label=translate("v1_badge")
tooltip-template="'v1ProjectTooltipTemplate'"
tooltip-append-to-body="true"
)
td.projectName
span(ng-if="project.isV1Project")
if settings.overleaf && settings.overleaf.host
button.btn.btn-link.projectName(
ng-click="openV1ImportModal(project)"
stop-propagation="click"
ng-show="project.accessLevel == 'owner'"
) {{project.name}}
a.projectName(
href=settings.overleaf.host + "/{{project.id}}"
target="_blank"
ng-hide="project.accessLevel == 'owner'"
) {{project.name}}
span(ng-if="!project.isV1Project")
span
a.projectName(
ng-href="{{projectLink(project)}}"
stop-propagation="click"
@ -48,8 +31,8 @@ td.projectName
ng-click="removeProjectFromTag(project, tag)"
) ×
td
span.owner {{userDisplayName(project.owner)}}
.col-xs-2
span.owner {{ownerName()}}
span(ng-if="isLinkSharingProject(project)")
|  
i.fa.fa-link.small(
@ -58,18 +41,16 @@ td
tooltip-append-to-body="true"
)
td
span.last-modified(tooltip="{{project.lastUpdated | formatDate}}")
| {{project.lastUpdated | fromNowDate}}
span(ng-if='project.lastUpdatedBy')
|
| #{translate('by')}
|
| {{userDisplayName(project.lastUpdatedBy)}}
div(class=lastUpdatedClasses)
if settings.overleaf
span.last-modified(tooltip="{{project.lastUpdated | formatDate}}") {{project.lastUpdated | fromNowDate}}
else
span.last-modified {{project.lastUpdated | formatDate}}
td.text-right
if settings.overleaf
.hidden-xs.col-sm-3.col-md-2.action-btn-row
div(
ng-if="!project.isTableActionInflight && !project.isV1Project"
ng-if="!project.isTableActionInflight"
)
button.btn.btn-link.action-btn(
tooltip=translate('copy'),

View file

@ -123,43 +123,53 @@
.col-xs-12
.card.card-thin.project-list-card
.table-wrapper(max-height="projectListHeight - 25",)
table.table.table-hover.project-list(
ul.list-unstyled.project-list.structured-list(
select-all-list,
ng-if="projects.length > 0",
max-height="projectListHeight - 25",
ng-cloak
)
thead
tr
th.selectProject
li.container-fluid
.row
- var titleClasses = settings.overleaf ? " col-xs-6 col-sm-4 col-md-6" : "col-xs-6"
- var lastUpdatedClasses = settings.overleaf ? " col-xs-4 col-sm-3 col-md-2" : "col-xs-4"
div(class=titleClasses)
input.select-all(
select-all,
type="checkbox"
aria-label=translate('select_all_projects')
)
th.projectName
span.header.clickable(ng-click="changePredicate('name')") #{translate("title")}
i.tablesort.fa(ng-class="getSortIconClass('name')")
th
.col-xs-2
span.header.clickable(ng-click="changePredicate('accessLevel')") #{translate("owner")}
i.tablesort.fa(ng-class="getSortIconClass('accessLevel')")
th
div(class=lastUpdatedClasses)
span.header.clickable(ng-click="changePredicate('lastUpdated')") #{translate("last_modified")}
i.tablesort.fa(ng-class="getSortIconClass('lastUpdated')")
if settings.overleaf
th.text-right
.hidden-xs.col-sm-3.col-md-2.action-btn-row-header
span.header #{translate("actions")}
tbody
tr.project_entry(
li.project_entry.container-fluid(
ng-repeat="project in visibleProjects | orderBy:predicate:reverse",
ng-controller="ProjectListItemController"
)
.row(
ng-if="!project.isV1Project"
select-row
)
include ./item
tr(
.row(
ng-if="project.isV1Project"
)
include ./v1-item
li(
ng-if="visibleProjects.length == 0",
ng-cloak
)
td(colspan=5).text-center
.row
.col-xs-12.text-centered
small #{translate("no_projects")}
div.welcome.text-centered(ng-if="projects.length == 0", ng-cloak)

View file

@ -0,0 +1,25 @@
.col-xs-6.col-sm-4.col-md-6
.select-item
span.v1-badge(
aria-label=translate("v1_badge")
tooltip-template="'v1ProjectTooltipTemplate'"
tooltip-append-to-body="true"
)
span
if settings.overleaf && settings.overleaf.host
button.btn.btn-link.projectName(
ng-click="openV1ImportModal(project)"
stop-propagation="click"
ng-show="project.accessLevel == 'owner'"
) {{project.name}}
a.projectName(
href=settings.overleaf.host + "/{{project.id}}"
target="_blank"
ng-hide="project.accessLevel == 'owner'"
) {{project.name}}
.col-xs-2
span.owner {{ownerName()}}
.col-xs-4.col-sm-3.col-md-2
span.last-modified(tooltip="{{project.lastUpdated | formatDate}}") {{project.lastUpdated | fromNowDate}}

View file

@ -485,11 +485,11 @@ define [
$scope.isLinkSharingProject = (project) ->
return project.source == 'token'
$scope.userDisplayName = (user) ->
if user? and user._id == window.user_id
$scope.ownerName = () ->
if $scope.project.accessLevel == "owner"
return "You"
else if user?
return [user.first_name, user.last_name].filter((n) -> n?).join(" ")
else if $scope.project.owner?
return [$scope.project.owner.first_name, $scope.project.owner.last_name].filter((n) -> n?).join(" ")
else
return "None"

View file

@ -314,38 +314,8 @@ ul.structured-list {
padding: 0 (@line-height-computed / 4);
}
.table-wrapper {
overflow: scroll;
}
table.project-list {
margin: 0;
width: 100%;
th when (@is-overleaf = true) {
font-weight: 600;
}
th when (@is-overleaf = false) {
text-transform: uppercase;
font-weight: normal;
}
// thead > tr > th {
// padding-top: @line-height-computed / 8;
// }
td {
@media (min-width: @screen-md-min) {
white-space: nowrap;
}
&.projectName {
white-space: normal;
width: 50%;
}
&.selectProject {
width: 1%;
}
ul.project-list {
li {
.last-modified when (@is-overleaf = false) {
font-size: .8rem;
}
@ -355,13 +325,12 @@ table.project-list {
.owner when (@is-overleaf = false) {
margin-right: 0;
}
a.projectName, button.projectName {
.projectName {
margin-right: @line-height-computed / 4;
padding: 0;
vertical-align: inherit;
white-space: normal;
text-align: left;
color: @structured-list-link-color;
}
.tag-label {
@ -400,7 +369,6 @@ table.project-list {
.v1-badge {
margin-left: -4px;
margin-right: -4px;
}
.action-btn-row-header, .action-btn-row {

View file

@ -34,7 +34,7 @@ th {
// Bottom align for column headings
> thead > tr > th {
vertical-align: bottom;
border-bottom: 1px solid @table-border-color;
border-bottom: 2px solid @table-border-color;
}
// Remove top border from thead by default
> caption + thead,

View file

@ -110,7 +110,7 @@
//## Customizes the `.table` component with basic values, each used across all table variations.
//** Padding for `<th>`s and `<td>`s.
@table-cell-padding: @line-height-computed / 4;
@table-cell-padding: 8px;
//** Padding for cells in `.table-condensed`.
@table-condensed-cell-padding: 5px;

View file

@ -1,42 +0,0 @@
expect = require("chai").expect
async = require("async")
User = require "./helpers/User"
request = require "./helpers/request"
settings = require "settings-sharelatex"
Project = require("../../../app/js/models/Project").Project
markAsUpdated = (project_id, user_id, timestamp, callback) ->
request.post {
url: "/project/#{project_id}/last_updated"
json: {
user_id,
timestamp
}
auth:
user: settings.apis.web.user
pass: settings.apis.web.pass
sendImmediately: true
jar: false
}, callback
describe "ProjectLastUpdated", ->
before (done) ->
@timeout(90000)
@owner = new User()
@timestamp = Date.now()
@user_id = "abcdef1234567890abcdef12"
async.series [
(cb) => @owner.login cb
(cb) => @owner.createProject "private-project", (error, @project_id) => cb(error)
], done
describe "with user_id and timestamp", ->
it 'should update the project', (done) ->
markAsUpdated @project_id, @user_id, @timestamp, (error, response, body) =>
return done(error) if error?
expect(response.statusCode).to.equal 200
Project.findOne _id: @project_id, (error, project) =>
return done(error) if error?
expect(project.lastUpdated.getTime()).to.equal @timestamp
expect(project.lastUpdatedBy.toString()).to.equal @user_id
done()

View file

@ -23,7 +23,6 @@ describe "HistoryController", ->
"../Project/ProjectDetailsHandler": @ProjectDetailsHandler = {}
"../Project/ProjectEntityUpdateHandler": @ProjectEntityUpdateHandler = {}
"./RestoreManager": @RestoreManager = {}
"../Project/ProjectUpdateHandler": @ProjectUpdateHandler = {}
@settings.apis =
trackchanges:
enabled: false

View file

@ -190,6 +190,11 @@ describe 'ProjectEntityUpdateHandler', ->
.calledWith(project_id, doc_id, @docLines, @version, @ranges)
.should.equal true
it "should mark the project as updated", ->
@ProjectUpdater.markAsUpdated
.calledWith(project_id)
.should.equal true
it "should send the doc the to the TPDS", ->
@TpdsUpdateSender.addDoc
.calledWith({

View file

@ -16,15 +16,12 @@ describe 'ProjectUpdateHandler', ->
describe 'marking a project as recently updated', ->
it 'should send an update to mongo', (done)->
project_id = "project_id"
user_id = "mock_user_id"
timestamp = Date.now()
@handler.markAsUpdated project_id, user_id, timestamp, (err)=>
@ProjectModel.update.calledWith({
_id: project_id,
}, {
lastUpdated: new Date(timestamp),
lastUpdatedBy: user_id
}).should.equal true
@handler.markAsUpdated project_id, (err)=>
args = @ProjectModel.update.args[0]
args[0]._id.should.equal project_id
date = args[1].lastUpdated+""
now = Date.now()+""
date.substring(0,5).should.equal now.substring(0,5)
done()
describe "markAsOpened", ->