protected override TimeRecordBase Clone() { var rec = new WorkItemTimeRecord(); rec.StartRevision = StartRevision; rec.EndRevision = EndRevision; rec.Item = Item; rec.StartTime = StartTime; rec.EndTime = EndTime; return(rec); }
protected override TimeRecordBase Clone() { var rec = new WorkItemTimeRecord(); rec.StartRevision = StartRevision; rec.EndRevision = EndRevision; rec.Item = Item; rec.StartTime = StartTime; rec.EndTime = EndTime; return rec; }
internal void Munge(List<WorkItemTimeRecord> records) { if (!records.All(x => records.First().Item == x.Item)) { throw new InvalidOperationException("Records are not all from the same work item & cannot be munged"); } var earliest = records.OrderBy(x => x.StartTime).First(); var latest = records.OrderBy(x => x.EndTime).Last(); var newRecord = new WorkItemTimeRecord() { StartTime = earliest.StartTime, StartRevision = earliest.StartRevision, EndTime = latest.EndTime, EndRevision = latest.EndRevision, Item = earliest.Item }; records.ForEach(x => { TimeRecords.Remove(x); }); TimeRecords.Add(newRecord); TimeRecords = new ObservableCollection<TimeRecordBase>(TimeRecords.OrderBy(x => x.StartTime)); //TODO persist munges and load them in the refresh method }
private async System.Threading.Tasks.Task RefreshAsync() { try { // Set our busy flag and clear the previous data this.IsBusy = true; this.TimeRecords.Clear(); var timeRecords = new List<TimeRecordBase>(); // Make the server call asynchronously to avoid blocking the UI await System.Threading.Tasks.Task.Run(() => { ITeamFoundationContext context = this.CurrentContext; if (context != null && context.HasCollection && context.HasTeamProject) { TeamFoundationIdentity user; context.TeamProjectCollection.GetAuthenticatedIdentity(out user); var userName = user.DisplayName; WorkItemStore wis = context.TeamProjectCollection.GetService<WorkItemStore>(); if (wis != null) { WorkItemCollection wic = wis.Query("SELECT [System.Id], [System.Title], [System.State] FROM WorkItems WHERE [System.WorkItemType] <> '' AND [System.State] <> '' AND [System.ChangedDate] > @Today - " + Days + " AND [System.AssignedTo] EVER @Me ORDER BY [System.Id]"); foreach (WorkItem wi in wic) { if (!Properties.Settings.Default.TimekeeperSettings.IsIncluded(wi)) { continue; } var predicates = new WorkItemFilteringPredicates(userName, wi, Days); var innerTimeRecords = new List<TimeRecordBase>(); var revs = wi.Revisions.Cast<Revision>() .Where(predicates.ChangedInLastXDays) .WhereAny(predicates.ShouldStart, predicates.ShouldStop) .Select(revision => new StateEvent() { Timestamp = Convert.ToDateTime(revision.Fields["Changed Date"].Value), Activate = predicates.ShouldStart(revision), Item = revision.WorkItem, Reason = (string)revision.Fields["System.Reason"].Value, Revision = wi.Revisions.IndexOf(revision) }) .OrderBy(revision => revision.Timestamp).ToList(); WorkItemTimeRecord current = null; foreach (var rev in revs) { if (rev.Activate) { current = new WorkItemTimeRecord() { Item = rev.Item, StartTime = rev.Timestamp, StartRevision = rev.Revision }; } else if (current != null && current.EndTime == DateTime.MaxValue) { current.EndTime = rev.Timestamp; current.EndRevision = rev.Revision; innerTimeRecords.AddRange(current.SplitToRecordPerDay()); current = null; } } if (current != null && current.EndTime == DateTime.MaxValue) { current.EndTime = DateTime.Now; current.EndRevision = -1; innerTimeRecords.AddRange(current.SplitToRecordPerDay()); } timeRecords.AddRange(innerTimeRecords); } timeRecords = timeRecords .Where(x => x.Duration > TimeSpan.FromMinutes(MinimumTimeSpan)) .Where(x => _showExported || !x.IsExported) .Where(x => _showIgnored || !x.IsIgnored) .OrderBy(x => x.StartTime) .ToList(); } } }); // Now back on the UI thread, update the bound collection and section title this.TimeRecords = new ObservableCollection<TimeRecordBase>(timeRecords); } catch (Exception ex) { this.ShowNotification(ex.Message, NotificationType.Error); } finally { // Always clear our busy flag when done this.IsBusy = false; } }