Merge change 10667

* changes:
  File review status tracking.
This commit is contained in:
Android Code Review
2009-07-15 16:30:51 -07:00
15 changed files with 274 additions and 9 deletions

View File

@@ -106,4 +106,5 @@ public interface ChangeConstants extends Constants {
String pagedChangeListNext();
String reply();
String reviewed();
}

View File

@@ -87,3 +87,4 @@ prevPatchLinkIcon = ⇦
nextPatchLinkIcon = ⇨
reply = Reply
reviewed = Reviewed

View File

@@ -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();
}

View File

@@ -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);
}
}
}

View File

@@ -54,4 +54,6 @@ public interface PatchConstants extends Constants {
String previousFileHelp();
String nextFileHelp();
String reviewed();
}

View File

@@ -35,3 +35,5 @@ whitespaceIGNORE_ALL_SPACE=All
previousFileHelp = Previous file
nextFileHelp = Next file
reviewed = Reviewed

View File

@@ -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);
}

View File

@@ -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) {

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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() + "]";

View File

@@ -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;

View File

@@ -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;

View 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;

View 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;