Example #1
0
		/// <summary>
		/// Displays the change list composition. This is called when the main table shows the details of one
		/// change list.
		/// </summary>
		/// <param name="cid"> Change Id. This is relative to the database, not source control. </param>
		/// <param name="userName"> User name. </param>
		private void DisplayChange(int cid, string userName)
		{
			var changeQuery = from ch in DataContext.ChangeLists where ch.Id == cid select ch;
			if (changeQuery.Count() != 1)
			{
				ErrorOut("Could not find this change in the system!");
				return;
			}

			HintsData.InChangeView = true;

			ChangeList changeList = changeQuery.Single();

			DisplayPageHeader("Change list " + changeList.CL);

			Table table = new Table();
			table.AppendCSSClass("CssChangeListDetail");

			ActivePage.Controls.Add(table);

			table.Rows.Add(GetChangeDescriptionRow("Date:", WrapTimeStamp(changeList.TimeStamp)));
			if (changeList.UserClient != null && changeList.UserClient != String.Empty)
				table.Rows.Add(GetChangeDescriptionRow("Client:", changeList.UserClient));
			var userRow = GetChangeDescriptionRow("User:"******"Status:", changeList.Stage == 0 ? "Pending" : "Submitted"));
			if (changeList.Description != null && changeList.Description != String.Empty)
				table.Rows.Add(GetChangeDescriptionRow("Description:", Server.HtmlEncode(changeList.Description)));
			table.Rows.Add(GetChangeDescriptionRow("Files:", ""));

			var latestReview = GetLatestUserReviewForChangeList(userName, cid);
			foreach (ChangeFile file in
				(from fl in DataContext.ChangeFiles where fl.ChangeListId == cid select fl))
			{
				var versions = GetVersionsAbstract(file.Id);
				bool hasTextBody = (from ver in versions where ver.HasTextBody select ver).Count() != 0;
				table.Rows.Add(GetChangeFileRow(file, versions.LastOrDefault(), hasTextBody, latestReview));
			}

			var attachments = (from ll in DataContext.Attachments 
							   where ll.ChangeListId == cid
							   orderby ll.TimeStamp
							   select ll);

			if (attachments.Count() > 0)
			{
				table.Rows.Add(GetChangeDescriptionRow("Links:", ""));

				foreach (Attachment a in attachments)
					AddAttachmentRow(table, a);
			}

			AddLabel("<h3>Review history</h3>");
			Table reviewResults = new Table();

			ActivePage.Controls.Add(reviewResults);

			reviewResults.AppendCSSClass("CssChangeListReviewHistory");

			var allReviewsQuery = from rr in DataContext.Reviews
								  where rr.ChangeListId == cid && rr.IsSubmitted
								  orderby rr.TimeStamp
								  select rr;

			foreach (Review review in allReviewsQuery)
			{
				TableRow row = new TableRow();
				reviewResults.Rows.Add(row);

				row.AppendCSSClass("CssTopAligned");

				TableCell dateCell = new TableCell();
				row.Cells.Add(dateCell);

				dateCell.AppendCSSClass("CssDate");
				dateCell.Text = WrapTimeStamp(review.TimeStamp);

				TableCell nameCell = new TableCell();
				row.Cells.Add(nameCell);

				nameCell.AppendCSSClass("CssName");
				nameCell.Text = review.UserName;

				TableCell verdictCell = new TableCell();
				row.Cells.Add(verdictCell);

				verdictCell.AppendCSSClass("CssScore");

				HyperLink reviewTarget = new HyperLink();
				verdictCell.Controls.Add(reviewTarget);

				if (review.OverallStatus == 0)
					HintsData.HaveNeedsWorkVotes = true;

				reviewTarget.Text = Malevich.Util.CommonUtils.ReviewStatusToString(review.OverallStatus);
				reviewTarget.NavigateUrl = Request.FilePath + "?rid=" + review.Id;

				if (review.CommentText != null)
				{
					TableCell abbreviatedCommentCell = new TableCell();
					row.Cells.Add(abbreviatedCommentCell);
					abbreviatedCommentCell.AppendCSSClass("CssComment");
					abbreviatedCommentCell.Text = AbbreviateToOneLine(review.CommentText, MaxReviewCommentLength);
				}
			}

			//Todo: modify stage logic, stage 1 is pending...
			if (changeList.Stage != 0)
			{
				HintsData.IsChangeInactive = true;

				AddLabel(String.Format("<br>This review has been {0}.", (changeList.Stage == 2 ? "closed" : "deleted")));
				return;
			}

			AddLabel("<h3>Vote so far</h3>");

			TableGen.Table reviewerVote = new TableGen.Table(2) { CssClass = "CssChangeListVoteHistory" };
			ActivePage.Controls.Add(reviewerVote);

			var reviewerQuery = from rv in DataContext.Reviewers where rv.ChangeListId == cid select rv;
			Reviewer[] reviewers = reviewerQuery.ToArray();
			bool iAmAReviewer = false;
			foreach (Reviewer reviewer in reviewers)
			{
				var row = reviewerVote.CreateRow();
				reviewerVote.AddItem(row);

				row[0].Text = reviewer.ReviewerAlias;

				if (userName.EqualsIgnoreCase(reviewer.ReviewerAlias))
				{
					DropDownList list = new DropDownList() { ID = "verdictlist" };
					row[1].Add(list);

					list.Items.Add(new ListItem() { Text = "Needs work" });				
					list.Items.Add(new ListItem() { Text = "LGTM with minor tweaks" });
					list.Items.Add(new ListItem() { Text = "LGTM" });
					list.Items.Add(new ListItem() { Text = "Non-scoring comment" });

					iAmAReviewer = true;
				}
				else if (!Page.IsPostBack)
				{
					Review review = GetLastReview(cid, reviewer.ReviewerAlias);
					if (review == null)
					{
						row[1].Text = "Have not looked";
					}
					else
					{
						row[1].Add(new HyperLink()
						{
							Text = Malevich.Util.CommonUtils.ReviewStatusToString(review.OverallStatus),
							NavigateUrl = Request.FilePath + "?rid=" + review.Id,
						});
					}
				}
			}

			bool iOwnTheChange = changeList.UserName.EqualsIgnoreCase(userName);
			if (!iAmAReviewer && !iOwnTheChange)
			{
				AddLabel("<br>");
				AddLink("I would like to review this change.", "?cid=" + changeList.Id + "&action=makemereviewer")
					.AppendCSSClass("button");
			}

			if (iOwnTheChange && changeList.Stage != 2 && /* 2 = closed */
				GetChangeListStatus(changeList) == ChangeListStatus.Closable)
			{
				AddLabel("<br>");
				AddLink("Close Review", "?cid=" + changeList.Id + "&action=close")
					.AppendCSSClass("button");
			}

			if (iOwnTheChange)
			{
				HintsData.IsChangeAuthor = true;
				AddLabel("<h3>My response</h3>");
			}
			else
			{
				HintsData.IsChangeReviewer = true;
				AddLabel("<h3>My comments</h3>");
			}

			TextBox commentTextBox = new TextBox();
			ActivePage.Controls.Add(commentTextBox);
			commentTextBox.TextMode = TextBoxMode.MultiLine;
			commentTextBox.AppendCSSClass("CssGeneralCommentInputBox");
			commentTextBox.ID = "reviewcommenttextbox";

			AddLabel("<br>");

			Button submitReviewButton =
				new Button() { ID = "submitreviewbutton", Text = "Submit", CssClass = "button" };
			ActivePage.Controls.Add(submitReviewButton.As(HtmlTextWriterTag.P));
			submitReviewButton.Click += new EventHandler(
				delegate(object sender, EventArgs e) { submitReview_Clicked(cid, sender, e); });

			AddLabel("<br>");

			int myReviewId = GetBaseReviewId(userName, cid);
			if (myReviewId == 0)
				return;

			DisplayReviewLineComments(myReviewId);
		}