Skip to content

Commit

Permalink
feat(view): ✨ extend implementation to tgl view <span> clients
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesNZL committed May 16, 2023
1 parent db659d2 commit 59a0c5c
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 101 deletions.
125 changes: 57 additions & 68 deletions src/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,95 +27,77 @@ internal enum ViewSpanKeys
Month,
Year,
}
internal static readonly Dictionary<Settings.ViewSpanKeys, ViewSpanCommandArgument> ViewSpanArguments = new Dictionary<Settings.ViewSpanKeys, ViewSpanCommandArgument>
internal static readonly List<ViewSpanCommandArgument> ViewSpanArguments = new List<ViewSpanCommandArgument>
{
new ViewSpanCommandArgument
{
Settings.ViewSpanKeys.Day,
new ViewSpanCommandArgument
{
Argument = "day",
Interpolation = "today",
Score = 400,
// Today
Start = now => now,
End = now => now
}
Argument = "day",
Interpolation = "today",
Score = 400,
// Today
Start = now => now,
End = now => now,
},
new ViewSpanCommandArgument
{
Settings.ViewSpanKeys.Week,
new ViewSpanCommandArgument
{
Argument = "week",
Interpolation = "this week",
Score = 300,
// Monday of the current week
Start = now => now.AddDays(-(int)now.DayOfWeek + 1),
// Sunday of the current week
End = now => now.AddDays(-(int)now.DayOfWeek + 7)
}
Argument = "week",
Interpolation = "this week",
Score = 300,
// Monday of the current week
Start = now => now.AddDays(-(int)now.DayOfWeek + 1),
// Sunday of the current week
End = now => now.AddDays(-(int)now.DayOfWeek + 7),
},
new ViewSpanCommandArgument
{
Settings.ViewSpanKeys.Month,
new ViewSpanCommandArgument
{
Argument = "month",
Interpolation = "this month",
Score = 200,
// First day of the current month
Start = now => new DateTimeOffset(now.Year, now.Month, 1, 0, 0, 0, now.Offset),
// Last day of the current month
End = now => new DateTimeOffset(now.Year, now.Month, DateTime.DaysInMonth(now.Year, now.Month), 0, 0, 0, now.Offset)
}
Argument = "month",
Interpolation = "this month",
Score = 200,
// First day of the current month
Start = now => new DateTimeOffset(now.Year, now.Month, 1, 0, 0, 0, now.Offset),
// Last day of the current month
End = now => new DateTimeOffset(now.Year, now.Month, DateTime.DaysInMonth(now.Year, now.Month), 0, 0, 0, now.Offset),
},
new ViewSpanCommandArgument
{
Settings.ViewSpanKeys.Year,
new ViewSpanCommandArgument
{
Argument = "year",
Interpolation = "this year",
Score = 100,
// First day of the current year
Start = now => new DateTimeOffset(now.Year, now.Month, 1, 0, 0, 0, now.Offset),
// Last day of the current year
End = now => new DateTimeOffset(now.Year, 12, 31, 0, 0, 0, now.Offset)
}
Argument = "year",
Interpolation = "this year",
Score = 100,
// First day of the current year
Start = now => new DateTimeOffset(now.Year, now.Month, 1, 0, 0, 0, now.Offset),
// Last day of the current year
End = now => new DateTimeOffset(now.Year, 12, 31, 0, 0, 0, now.Offset),
},
};

internal enum ViewGroupingKeys
public enum ViewGroupingKeys
{
Entries,
Projects,
Clients,
Entries,
}
internal static readonly Dictionary<Settings.ViewGroupingKeys, CommandArgument> ViewGroupingArguments = new Dictionary<Settings.ViewGroupingKeys, CommandArgument>
internal static readonly List<ViewGroupingCommandArgument> ViewGroupingArguments = new List<ViewGroupingCommandArgument>
{
new ViewGroupingCommandArgument
{
Settings.ViewGroupingKeys.Projects,
new CommandArgument
{
Argument = "projects",
Interpolation = "View tracked time grouped by project",
Score = 300
}
Argument = "projects",
Interpolation = "View tracked time grouped by project",
Score = 300,
Grouping = Settings.ViewGroupingKeys.Projects,
},
new ViewGroupingCommandArgument
{
Settings.ViewGroupingKeys.Clients,
new CommandArgument
{
Argument = "clients",
Interpolation = "View tracked time grouped by client",
Score = 200
}
Argument = "clients",
Interpolation = "View tracked time grouped by client",
Score = 200,
Grouping = Settings.ViewGroupingKeys.Clients,
},
new ViewGroupingCommandArgument
{
Settings.ViewGroupingKeys.Entries,
new CommandArgument
{
Argument = "entries",
Interpolation = "View tracked time entries",
Score = 100
}
Argument = "entries",
Interpolation = "View tracked time entries",
Score = 100,
Grouping = Settings.ViewGroupingKeys.Entries,
},
};

Expand All @@ -141,4 +123,11 @@ public class ViewSpanCommandArgument : CommandArgument
public Func<DateTimeOffset, DateTimeOffset> End { get; init; }
#nullable enable
}

public class ViewGroupingCommandArgument : CommandArgument
{
#nullable disable
public Settings.ViewGroupingKeys Grouping { get; init; }
#nullable enable
}
}
16 changes: 11 additions & 5 deletions src/Toggl/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,17 +122,23 @@ public void UpdateToken(string token)
* Reports API
*/

public async Task<SummaryTimeEntry?> GetSummaryTimeEntries(long workspaceId, long userId, DateTimeOffset start, DateTimeOffset? end)
public async Task<SummaryTimeEntry?> GetSummaryTimeEntries(long workspaceId, long userId, Settings.ViewGroupingKeys reportGrouping, DateTimeOffset start, DateTimeOffset? end)
{
(string grouping, string sub_grouping) = (reportGrouping) switch
{
Settings.ViewGroupingKeys.Projects => ("projects", "time_entries"),
Settings.ViewGroupingKeys.Clients => ("clients", "projects"),
Settings.ViewGroupingKeys.Entries => ("projects", "time_entries"),
_ => ("projects", "time_entries"),
};

return await this._reportsApi.Post<SummaryTimeEntry>($"workspace/{workspaceId}/summary/time_entries", new
{
user_ids = new long[] { userId },
start_date = start.ToString("yyyy-MM-dd"),
end_date = end?.ToString("yyyy-MM-dd"),
grouping = "projects",
sub_grouping = "time_entries",
// grouping = "clients",
// sub_grouping = "projects",
grouping,
sub_grouping,
});
}
}
Expand Down
84 changes: 56 additions & 28 deletions src/TogglTrack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1361,9 +1361,9 @@ internal async ValueTask<List<Result>> RequestViewReports(CancellationToken toke
/*
* Report span selection --- tgl view [day | week | month | year]
*/
if (query.SearchTerms.Length == ArgumentIndices.Span || !Settings.ViewSpanArguments.Values.ToList().Exists(span => span.Argument == query.SearchTerms[ArgumentIndices.Span]))
if (query.SearchTerms.Length == ArgumentIndices.Span || !Settings.ViewSpanArguments.Exists(span => span.Argument == query.SearchTerms[ArgumentIndices.Span]))
{
var spans = Settings.ViewSpanArguments.Values.ToList().ConvertAll(span =>
var spans = Settings.ViewSpanArguments.ConvertAll(span =>
{
return new Result
{
Expand Down Expand Up @@ -1392,9 +1392,9 @@ internal async ValueTask<List<Result>> RequestViewReports(CancellationToken toke
/*
* Report groupinging selection --- tgl view [duration] [projects | clients | entries]
*/
if (query.SearchTerms.Length == ArgumentIndices.Grouping || !Settings.ViewGroupingArguments.Values.ToList().Exists(grouping => grouping.Argument == query.SearchTerms[ArgumentIndices.Grouping]))
if (query.SearchTerms.Length == ArgumentIndices.Grouping || !Settings.ViewGroupingArguments.Exists(grouping => grouping.Argument == query.SearchTerms[ArgumentIndices.Grouping]))
{
var groupings = Settings.ViewGroupingArguments.Values.ToList().ConvertAll(grouping =>
var groupings = Settings.ViewGroupingArguments.ConvertAll(grouping =>
{
return new Result
{
Expand Down Expand Up @@ -1423,9 +1423,10 @@ internal async ValueTask<List<Result>> RequestViewReports(CancellationToken toke
string spanArgument = query.SearchTerms[ArgumentIndices.Span];
string groupingArgument = query.SearchTerms[ArgumentIndices.Grouping];

var spanConfiguration = Settings.ViewSpanArguments.Values.ToList().Find(span => span.Argument == spanArgument);
var spanConfiguration = Settings.ViewSpanArguments.Find(span => span.Argument == spanArgument);
var groupingConfiguration = Settings.ViewGroupingArguments.Find(grouping => grouping.Argument == groupingArgument);

if (spanConfiguration is null)
if ((spanConfiguration is null) || (groupingConfiguration is null))
{
return this.NotifyUnknownError();
}
Expand All @@ -1437,8 +1438,7 @@ internal async ValueTask<List<Result>> RequestViewReports(CancellationToken toke

// TODO: do I want to cache this?
// ^ would need to cache the params too
// TODO: it is just the "grouping" and "sub_grouping" inside that need to change
var timeEntries = await this._client.GetSummaryTimeEntries(me.default_workspace_id, me.id, start, end);
var timeEntries = await this._client.GetSummaryTimeEntries(me.default_workspace_id, me.id, groupingConfiguration.Grouping, start, end);

var total = TimeSpan.FromSeconds(timeEntries?.groups?.Sum(group => group.seconds) ?? 0);

Expand All @@ -1457,29 +1457,57 @@ internal async ValueTask<List<Result>> RequestViewReports(CancellationToken toke
return results;
}

// ! TODO: this is just a single test case
// TODO: is there *any* nice way to make this a switch case?
if (groupingArgument == Settings.ViewGroupingArguments[Settings.ViewGroupingKeys.Projects].Argument)
switch (groupingConfiguration.Grouping)
{
results.AddRange(
timeEntries.groups.ConvertAll(group =>
{
var project = me.projects?.Find(project => project.id == group.id);
var elapsed = TimeSpan.FromSeconds(group.seconds);
case (Settings.ViewGroupingKeys.Projects):
{
results.AddRange(
timeEntries.groups.ConvertAll(group =>
{
var project = me.projects?.Find(project => project.id == group.id);
var elapsed = TimeSpan.FromSeconds(group.seconds);
return new Result
return new Result
{
Title = project?.name ?? "No Project",
SubTitle = $"{((project?.client_id is not null) ? $"{me.clients?.Find(client => client.id == project.client_id)?.name} | " : string.Empty)}{elapsed.Humanize(maxUnit: Humanizer.Localisation.TimeUnit.Hour)} ({(int)elapsed.TotalHours}:{elapsed.ToString(@"mm\:ss")})",
IcoPath = (project?.color is not null)
? new ColourIcon(this._context, project.color, "view.png").GetColourIcon()
: "view.png",
// AutoCompleteText =
Score = (int)group.seconds,
// Action = c =>
};
})
);
break;
}
case (Settings.ViewGroupingKeys.Clients):
{
results.AddRange(
timeEntries.groups.ConvertAll(group =>
{
Title = project?.name ?? "No Project",
SubTitle = $"{((project?.client_id is not null) ? $"{me.clients?.Find(client => client.id == project.client_id)?.name} | " : string.Empty)}{elapsed.Humanize(maxUnit: Humanizer.Localisation.TimeUnit.Hour)} ({(int)elapsed.TotalHours}:{elapsed.ToString(@"mm\:ss")})",
IcoPath = (project?.color is not null)
? new ColourIcon(this._context, project.color, "view.png").GetColourIcon()
: "view.png",
// AutoCompleteText =
Score = (int)group.seconds,
// Action = c =>
};
})
);
var client = me.clients?.Find(client => client.id == group.id);
var elapsed = TimeSpan.FromSeconds(group.seconds);
return new Result
{
Title = client?.name ?? "No Client",
SubTitle = $"{elapsed.Humanize(maxUnit: Humanizer.Localisation.TimeUnit.Hour)} ({(int)elapsed.TotalHours}:{elapsed.ToString(@"mm\:ss")})",
// TODO: colour based on highest-tracked project
IcoPath = "view.png",
// AutoCompleteText =
Score = (int)group.seconds,
// Action = c =>
};
})
);
break;
}
case (Settings.ViewGroupingKeys.Entries):
{
break;
}
}

return results;
Expand Down

0 comments on commit 59a0c5c

Please sign in to comment.