Merge change 10667
* changes: File review status tracking.
This commit is contained in:
@@ -106,4 +106,5 @@ public interface ChangeConstants extends Constants {
|
||||
String pagedChangeListNext();
|
||||
|
||||
String reply();
|
||||
String reviewed();
|
||||
}
|
||||
|
||||
@@ -87,3 +87,4 @@ prevPatchLinkIcon = ⇦
|
||||
nextPatchLinkIcon = ⇨
|
||||
|
||||
reply = Reply
|
||||
reviewed = Reviewed
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
package com.google.gerrit.client.changes;
|
||||
|
||||
import com.google.gerrit.client.Gerrit;
|
||||
import com.google.gerrit.client.patches.PatchScreen;
|
||||
import com.google.gerrit.client.reviewdb.Patch;
|
||||
import com.google.gerrit.client.reviewdb.PatchSet;
|
||||
@@ -249,33 +250,46 @@ public class PatchTable extends Composite {
|
||||
void appendHeader(final SafeHtmlBuilder m) {
|
||||
m.openTr();
|
||||
|
||||
// Cursor
|
||||
m.openTd();
|
||||
m.addStyleName(S_ICON_HEADER);
|
||||
m.addStyleName("LeftMostCell");
|
||||
m.nbsp();
|
||||
m.closeTd();
|
||||
|
||||
// Mode
|
||||
m.openTd();
|
||||
m.setStyleName(S_ICON_HEADER);
|
||||
m.nbsp();
|
||||
m.closeTd();
|
||||
|
||||
// "File path"
|
||||
m.openTd();
|
||||
m.setStyleName(S_DATA_HEADER);
|
||||
m.append(Util.C.patchTableColumnName());
|
||||
m.closeTd();
|
||||
|
||||
// "Comments"
|
||||
m.openTd();
|
||||
m.setStyleName(S_DATA_HEADER);
|
||||
m.append(Util.C.patchTableColumnComments());
|
||||
m.closeTd();
|
||||
|
||||
// "Diff"
|
||||
m.openTd();
|
||||
m.setStyleName(S_DATA_HEADER);
|
||||
m.setAttribute("colspan", 3);
|
||||
m.append(Util.C.patchTableColumnDiff());
|
||||
m.closeTd();
|
||||
|
||||
// "Reviewed"
|
||||
if (Gerrit.isSignedIn()) {
|
||||
m.openTd();
|
||||
m.setStyleName(S_ICON_HEADER);
|
||||
m.append(Util.C.reviewed());
|
||||
m.closeTd();
|
||||
}
|
||||
|
||||
m.closeTr();
|
||||
}
|
||||
|
||||
@@ -350,6 +364,18 @@ public class PatchTable extends Composite {
|
||||
openlink(m, 1);
|
||||
m.closeTd();
|
||||
|
||||
// Green check mark if the user is logged in and they reviewed that file
|
||||
if (Gerrit.isSignedIn()) {
|
||||
m.openTd();
|
||||
m.setStyleName(S_DATA_CELL);
|
||||
if (p.isReviewedByCurrentUser()) {
|
||||
m.append(SafeHtml.asis(Gerrit.ICONS.greenCheck().getHTML()));
|
||||
} else {
|
||||
m.nbsp();
|
||||
}
|
||||
m.closeTd();
|
||||
}
|
||||
|
||||
m.closeTr();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,14 +15,20 @@
|
||||
package com.google.gerrit.client.data;
|
||||
|
||||
import com.google.gerrit.client.reviewdb.Account;
|
||||
import com.google.gerrit.client.reviewdb.AccountPatchReview;
|
||||
import com.google.gerrit.client.reviewdb.AccountPatchReviewAccess;
|
||||
import com.google.gerrit.client.reviewdb.Patch;
|
||||
import com.google.gerrit.client.reviewdb.PatchLineComment;
|
||||
import com.google.gerrit.client.reviewdb.PatchSet;
|
||||
import com.google.gerrit.client.reviewdb.PatchSetInfo;
|
||||
import com.google.gerrit.client.reviewdb.ReviewDb;
|
||||
import com.google.gerrit.client.reviewdb.Patch.Key;
|
||||
import com.google.gerrit.client.reviewdb.PatchSet.Id;
|
||||
import com.google.gerrit.client.rpc.Common;
|
||||
import com.google.gwtorm.client.OrmException;
|
||||
import com.google.gwtorm.client.ResultSet;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -35,9 +41,10 @@ public class PatchSetDetail {
|
||||
}
|
||||
|
||||
public void load(final ReviewDb db, final PatchSet ps) throws OrmException {
|
||||
PatchSet.Id patchSetKey = ps.getId();
|
||||
patchSet = ps;
|
||||
info = db.patchSetInfo().get(patchSet.getId());
|
||||
patches = db.patches().byPatchSet(patchSet.getId()).toList();
|
||||
info = db.patchSetInfo().get(patchSetKey);
|
||||
patches = db.patches().byPatchSet(patchSetKey).toList();
|
||||
|
||||
final Account.Id me = Common.getAccountId();
|
||||
if (me != null) {
|
||||
@@ -46,7 +53,7 @@ public class PatchSetDetail {
|
||||
// quickly locate where they have pending drafts, and review them.
|
||||
//
|
||||
final List<PatchLineComment> comments =
|
||||
db.patchComments().draft(ps.getId(), me).toList();
|
||||
db.patchComments().draft(patchSetKey, me).toList();
|
||||
if (!comments.isEmpty()) {
|
||||
final Map<Patch.Key, Patch> byKey = db.patches().toMap(patches);
|
||||
for (final PatchLineComment c : comments) {
|
||||
@@ -56,6 +63,18 @@ public class PatchSetDetail {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get all the reviewed patches in one query
|
||||
ResultSet<AccountPatchReview> reviews = db.accountPatchReviews().byReviewer(me, patchSetKey);
|
||||
HashSet<Patch.Key> reviewedPatches = new HashSet<Patch.Key>();
|
||||
for (AccountPatchReview review : reviews) {
|
||||
reviewedPatches.add(review.getKey().getPatchKey());
|
||||
}
|
||||
|
||||
// Initialize the reviewed status of each patch
|
||||
for (Patch p : patches) {
|
||||
if (reviewedPatches.contains(p.getKey())) p.setReviewedByCurrentUser(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,4 +54,6 @@ public interface PatchConstants extends Constants {
|
||||
|
||||
String previousFileHelp();
|
||||
String nextFileHelp();
|
||||
|
||||
String reviewed();
|
||||
}
|
||||
|
||||
@@ -35,3 +35,5 @@ whitespaceIGNORE_ALL_SPACE=All
|
||||
|
||||
previousFileHelp = Previous file
|
||||
nextFileHelp = Next file
|
||||
|
||||
reviewed = Reviewed
|
||||
|
||||
@@ -16,11 +16,13 @@ package com.google.gerrit.client.patches;
|
||||
|
||||
import com.google.gerrit.client.data.PatchScript;
|
||||
import com.google.gerrit.client.data.PatchScriptSettings;
|
||||
import com.google.gerrit.client.reviewdb.Account;
|
||||
import com.google.gerrit.client.reviewdb.ApprovalCategoryValue;
|
||||
import com.google.gerrit.client.reviewdb.Change;
|
||||
import com.google.gerrit.client.reviewdb.Patch;
|
||||
import com.google.gerrit.client.reviewdb.PatchLineComment;
|
||||
import com.google.gerrit.client.reviewdb.PatchSet;
|
||||
import com.google.gerrit.client.reviewdb.Patch.Key;
|
||||
import com.google.gerrit.client.rpc.SignInRequired;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwtjsonrpc.client.RemoteJsonService;
|
||||
@@ -55,4 +57,10 @@ public interface PatchDetailService extends RemoteJsonService {
|
||||
@SignInRequired
|
||||
void abandonChange(PatchSet.Id patchSetId, String message,
|
||||
AsyncCallback<VoidResult> callback);
|
||||
|
||||
/**
|
||||
* Update the reviewed status for the patch.
|
||||
*/
|
||||
@SignInRequired
|
||||
void setReviewedByCurrentUser(Key patchKey, boolean reviewed, AsyncCallback<VoidResult> callback);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ import com.google.gwt.event.logical.shared.ValueChangeEvent;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeHandler;
|
||||
import com.google.gwt.event.shared.HandlerRegistration;
|
||||
import com.google.gwt.user.client.History;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.CheckBox;
|
||||
import com.google.gwt.user.client.ui.DisclosurePanel;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
@@ -55,6 +56,7 @@ import com.google.gwtexpui.globalkey.client.KeyCommand;
|
||||
import com.google.gwtexpui.globalkey.client.KeyCommandSet;
|
||||
import com.google.gwtexpui.safehtml.client.SafeHtml;
|
||||
import com.google.gwtjsonrpc.client.RemoteJsonException;
|
||||
import com.google.gwtjsonrpc.client.VoidResult;
|
||||
|
||||
public abstract class PatchScreen extends Screen {
|
||||
public static class SideBySide extends PatchScreen {
|
||||
@@ -236,7 +238,7 @@ public abstract class PatchScreen extends Screen {
|
||||
}
|
||||
|
||||
private void initDisplayControls() {
|
||||
final Grid displayControls = new Grid(0, 4);
|
||||
final Grid displayControls = new Grid(0, 5);
|
||||
displayControls.setStyleName("gerrit-PatchScreen-DisplayControls");
|
||||
add(displayControls);
|
||||
|
||||
@@ -244,8 +246,13 @@ public abstract class PatchScreen extends Screen {
|
||||
createContext(displayControls, 0, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the contextual widgets for this patch: "Show full files" and "Keep unreviewed"
|
||||
*/
|
||||
private void createContext(final Grid parent, final int row, final int col) {
|
||||
parent.resizeRows(row + 1);
|
||||
|
||||
// Show full files
|
||||
final CheckBox cb = new CheckBox(PatchUtil.C.showFullFiles());
|
||||
cb.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
||||
@Override
|
||||
@@ -261,6 +268,38 @@ public abstract class PatchScreen extends Screen {
|
||||
}
|
||||
});
|
||||
parent.setWidget(row, col + 1, cb);
|
||||
|
||||
// "Reviewed" check box
|
||||
if (Gerrit.isSignedIn()) {
|
||||
final CheckBox ku = new CheckBox(PatchUtil.C.reviewed());
|
||||
ku.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<Boolean> event) {
|
||||
setReviewedByCurrentUser(event.getValue());
|
||||
}
|
||||
});
|
||||
// Checked by default
|
||||
ku.setValue(true);
|
||||
parent.setWidget(row, col + 2, ku);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setReviewedByCurrentUser(boolean reviewed) {
|
||||
PatchUtil.DETAIL_SVC.setReviewedByCurrentUser(patchKey, reviewed,
|
||||
new AsyncCallback<VoidResult>() {
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable arg0) {
|
||||
// nop
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(VoidResult result) {
|
||||
// nop
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void createIgnoreWhitespace(final Grid parent, final int row,
|
||||
@@ -344,6 +383,11 @@ public abstract class PatchScreen extends Screen {
|
||||
script = null;
|
||||
comments = null;
|
||||
|
||||
// Mark this file reviewed as soon we display the diff screen
|
||||
if (Gerrit.isSignedIn() && isFirst) {
|
||||
setReviewedByCurrentUser(true /* reviewed */);
|
||||
}
|
||||
|
||||
PatchUtil.DETAIL_SVC.patchScript(patchKey, idSideA, idSideB,
|
||||
scriptSettings, new GerritCallback<PatchScript>() {
|
||||
public void onSuccess(final PatchScript result) {
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
// Copyright (C) 2009 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.client.reviewdb;
|
||||
|
||||
import com.google.gwtorm.client.Column;
|
||||
import com.google.gwtorm.client.CompoundKey;
|
||||
|
||||
/**
|
||||
* An entity that keeps track of what user reviewed what patches.
|
||||
*/
|
||||
public final class AccountPatchReview {
|
||||
|
||||
public static class Key extends CompoundKey<Account.Id> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Column
|
||||
protected Account.Id accountId;
|
||||
|
||||
@Column(name = Column.NONE)
|
||||
protected Patch.Key patchKey;
|
||||
|
||||
protected Key() {
|
||||
accountId = new Account.Id();
|
||||
patchKey = new Patch.Key();
|
||||
}
|
||||
|
||||
public Key(final Patch.Key p, final Account.Id a) {
|
||||
patchKey = p;
|
||||
accountId = a;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account.Id getParentKey() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public Patch.Key getPatchKey() {
|
||||
return patchKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.google.gwtorm.client.Key<?>[] members() {
|
||||
return new com.google.gwtorm.client.Key<?>[] {patchKey};
|
||||
}
|
||||
}
|
||||
|
||||
@Column(name = Column.NONE)
|
||||
protected AccountPatchReview.Key key;
|
||||
|
||||
protected AccountPatchReview() {
|
||||
}
|
||||
|
||||
public AccountPatchReview(final Patch.Key k, final Account.Id a) {
|
||||
key = new AccountPatchReview.Key(k, a);
|
||||
}
|
||||
|
||||
public AccountPatchReview.Key getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (C) 2009 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.client.reviewdb;
|
||||
|
||||
import com.google.gwtorm.client.Access;
|
||||
import com.google.gwtorm.client.OrmException;
|
||||
import com.google.gwtorm.client.PrimaryKey;
|
||||
import com.google.gwtorm.client.Query;
|
||||
import com.google.gwtorm.client.ResultSet;
|
||||
|
||||
public interface AccountPatchReviewAccess
|
||||
extends Access<AccountPatchReview, AccountPatchReview.Key> {
|
||||
@PrimaryKey("key")
|
||||
AccountPatchReview get(AccountPatchReview.Key id) throws OrmException;
|
||||
|
||||
@Query("WHERE key.accountId = ? AND key.patchKey.patchSetId = ?")
|
||||
ResultSet<AccountPatchReview> byReviewer(Account.Id who, PatchSet.Id ps) throws OrmException;
|
||||
|
||||
}
|
||||
@@ -201,6 +201,9 @@ public final class Patch {
|
||||
@Column(notNull = false)
|
||||
protected String sourceFileName;
|
||||
|
||||
/** True if this patch has been reviewed by the current logged in user */
|
||||
private boolean reviewedByCurrentUser;
|
||||
|
||||
protected Patch() {
|
||||
}
|
||||
|
||||
@@ -258,6 +261,14 @@ public final class Patch {
|
||||
sourceFileName = n;
|
||||
}
|
||||
|
||||
public boolean isReviewedByCurrentUser() {
|
||||
return reviewedByCurrentUser;
|
||||
}
|
||||
|
||||
public void setReviewedByCurrentUser(boolean r) {
|
||||
reviewedByCurrentUser = r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[Patch " + getKey().toString() + "]";
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
package com.google.gerrit.server.patch;
|
||||
|
||||
import com.google.gerrit.client.Gerrit;
|
||||
import com.google.gerrit.client.data.ApprovalType;
|
||||
import com.google.gerrit.client.data.PatchScript;
|
||||
import com.google.gerrit.client.data.PatchScriptSettings;
|
||||
@@ -21,6 +22,7 @@ import com.google.gerrit.client.data.ProjectCache;
|
||||
import com.google.gerrit.client.patches.CommentDetail;
|
||||
import com.google.gerrit.client.patches.PatchDetailService;
|
||||
import com.google.gerrit.client.reviewdb.Account;
|
||||
import com.google.gerrit.client.reviewdb.AccountPatchReview;
|
||||
import com.google.gerrit.client.reviewdb.ApprovalCategory;
|
||||
import com.google.gerrit.client.reviewdb.ApprovalCategoryValue;
|
||||
import com.google.gerrit.client.reviewdb.Change;
|
||||
@@ -33,6 +35,7 @@ import com.google.gerrit.client.reviewdb.PatchSetInfo;
|
||||
import com.google.gerrit.client.reviewdb.Project;
|
||||
import com.google.gerrit.client.reviewdb.ReviewDb;
|
||||
import com.google.gerrit.client.reviewdb.Account.Id;
|
||||
import com.google.gerrit.client.reviewdb.Patch.Key;
|
||||
import com.google.gerrit.client.rpc.BaseServiceImplementation;
|
||||
import com.google.gerrit.client.rpc.Common;
|
||||
import com.google.gerrit.client.rpc.NoSuchAccountException;
|
||||
@@ -185,6 +188,28 @@ public class PatchDetailServiceImpl extends BaseServiceImplementation implements
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the reviewed status for the file by user @code{account}
|
||||
*/
|
||||
public void setReviewedByCurrentUser(final Key patchKey, final boolean reviewed,
|
||||
AsyncCallback<VoidResult> callback) {
|
||||
run(callback, new Action<VoidResult>() {
|
||||
public VoidResult run(ReviewDb db) throws OrmException {
|
||||
Account.Id account = Common.getAccountId();
|
||||
AccountPatchReview.Key key = new AccountPatchReview.Key(patchKey, account);
|
||||
AccountPatchReview apr = db.accountPatchReviews().get(key);
|
||||
if (apr == null && reviewed) {
|
||||
db.accountPatchReviews().
|
||||
insert(Collections.singleton(new AccountPatchReview(patchKey, account)));
|
||||
} else if (apr != null && !reviewed) {
|
||||
db.accountPatchReviews().delete(Collections.singleton(apr));
|
||||
}
|
||||
return VoidResult.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private static class PublishResult {
|
||||
Change change;
|
||||
PatchSet patchSet;
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
-- Upgrade: schema_version 14 to 15
|
||||
--
|
||||
ALTER TABLE patch_comments ADD parent_uuid VARCHAR(40);
|
||||
|
||||
UPDATE schema_version SET version_nbr = 15;
|
||||
13
src/main/webapp/WEB-INF/sql/upgrade014_015_mysql.sql
Normal file
13
src/main/webapp/WEB-INF/sql/upgrade014_015_mysql.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
-- Upgrade: schema_version 14 to 15
|
||||
--
|
||||
ALTER TABLE patch_comments ADD parent_uuid VARCHAR(40);
|
||||
|
||||
CREATE TABLE account_patch_reviews
|
||||
(account_id INTEGER NOT NULL DEFAULT(0),
|
||||
change_id INTEGER NOT NULL DEFAULT(0),
|
||||
patch_set_id INTEGER NOT NULL DEFAULT(0),
|
||||
file_name VARCHAR(255) NOT NULL DEFAULT(''),
|
||||
PRIMARY KEY (account_id, change_id, patch_set_id, file_name)
|
||||
);
|
||||
|
||||
UPDATE schema_version SET version_nbr = 15;
|
||||
15
src/main/webapp/WEB-INF/sql/upgrade014_015_postgres.sql
Normal file
15
src/main/webapp/WEB-INF/sql/upgrade014_015_postgres.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
-- Upgrade: schema_version 14 to 15
|
||||
--
|
||||
ALTER TABLE patch_comments ADD parent_uuid VARCHAR(40);
|
||||
|
||||
CREATE TABLE account_patch_reviews
|
||||
(account_id INTEGER NOT NULL DEFAULT(0),
|
||||
change_id INTEGER NOT NULL DEFAULT(0),
|
||||
patch_set_id INTEGER NOT NULL DEFAULT(0),
|
||||
file_name VARCHAR(255) NOT NULL DEFAULT(''),
|
||||
PRIMARY KEY (account_id, change_id, patch_set_id, file_name)
|
||||
);
|
||||
|
||||
ALTER_TABLE account_patch_reviews OWNER TO gerrit2;
|
||||
|
||||
UPDATE schema_version SET version_nbr = 15;
|
||||
Reference in New Issue
Block a user