Continued development

This commit is contained in:
c0d3.m0nk3y 2026-05-13 17:38:02 -04:00
parent 44864437a2
commit 8e0006cefe
16 changed files with 251 additions and 1152 deletions

View File

@ -35,11 +35,13 @@ namespace trakker.Data
p.status, p.status,
l.display AS status_name, l.display AS status_name,
p.hourly_rate, p.hourly_rate,
IFNULL(a.amount, 0.0) AS actuals,
p.notes, p.notes,
p.created_at, p.created_at,
p.updated_at p.updated_at
FROM projects p FROM projects p
LEFT JOIN clients c ON p.client_id = c.client_id LEFT JOIN clients c ON p.client_id = c.client_id
LEFT JOIN (SELECT project_id, SUM(hourly_rate * actual_hours) AS amount FROM tasks GROUP BY project_id) a ON p.project_id = a.project_id
JOIN (SELECT value, display FROM lov WHERE source = 'project.status') l ON p.status = l.value JOIN (SELECT value, display FROM lov WHERE source = 'project.status') l ON p.status = l.value
WHERE WHERE
{whereClause} {whereClause}
@ -72,6 +74,7 @@ namespace trakker.Data
var _var13 = reader.GetOrdinal("notes"); var _var13 = reader.GetOrdinal("notes");
var _var14 = reader.GetOrdinal("created_at"); var _var14 = reader.GetOrdinal("created_at");
var _var15 = reader.GetOrdinal("updated_at"); var _var15 = reader.GetOrdinal("updated_at");
var _var16 = reader.GetOrdinal("actuals");
while (reader.Read()) while (reader.Read())
{ {
results.Add(new Project results.Add(new Project
@ -91,6 +94,7 @@ namespace trakker.Data
Notes = reader.GetString(_var13), Notes = reader.GetString(_var13),
CreatedAt = reader.GetDateTime(_var14), CreatedAt = reader.GetDateTime(_var14),
UpdatedAt = reader.GetDateTime(_var15), UpdatedAt = reader.GetDateTime(_var15),
Actuals = reader.IsDBNull(_var16) ? null : reader.GetDecimal(_var16)
}); });
} }

View File

@ -32,6 +32,30 @@ namespace trakker.Data
break; break;
} }
//string sql = $@"
// SELECT
// task_id,
// project_id,
// title,
// description,
// status,
// status_name,
// priority,
// priority_name,
// due_date,
// estimated_hours,
// actual_hours,
// hourly_rate,
// amount,
// parent_task_id,
// created_at,
// updated_at
// FROM
// v$task_hierarchy
// WHERE
// {whereClause}
//";
string sql = $@" string sql = $@"
WITH RECURSIVE TaskHierarchy AS ( WITH RECURSIVE TaskHierarchy AS (
-- Anchor: starting task(s) -- Anchor: starting task(s)

View File

@ -28,6 +28,7 @@
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ClientForm));
groupBoxNewClient = new GroupBox(); groupBoxNewClient = new GroupBox();
tableLayoutPanel1 = new TableLayoutPanel(); tableLayoutPanel1 = new TableLayoutPanel();
tableLayoutPanel2 = new TableLayoutPanel(); tableLayoutPanel2 = new TableLayoutPanel();
@ -348,6 +349,7 @@
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1128, 665); ClientSize = new Size(1128, 665);
Controls.Add(groupBoxNewClient); Controls.Add(groupBoxNewClient);
Icon = (Icon)resources.GetObject("$this.Icon");
Name = "ClientForm"; Name = "ClientForm";
groupBoxNewClient.ResumeLayout(false); groupBoxNewClient.ResumeLayout(false);
tableLayoutPanel1.ResumeLayout(false); tableLayoutPanel1.ResumeLayout(false);

View File

@ -117,4 +117,39 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
rze0hMIAAAAASUVORK5CYII=
</value>
</data>
</root> </root>

View File

@ -29,6 +29,7 @@
private void InitializeComponent() private void InitializeComponent()
{ {
components = new System.ComponentModel.Container(); components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
MainForm_MenuStrip = new MenuStrip(); MainForm_MenuStrip = new MenuStrip();
fileToolStripMenuItem = new ToolStripMenuItem(); fileToolStripMenuItem = new ToolStripMenuItem();
MainForm_Exit_MenuItem = new ToolStripMenuItem(); MainForm_Exit_MenuItem = new ToolStripMenuItem();
@ -407,6 +408,7 @@
Controls.Add(tabControlMainForm); Controls.Add(tabControlMainForm);
Controls.Add(MainForm_StatusStrip); Controls.Add(MainForm_StatusStrip);
Controls.Add(MainForm_MenuStrip); Controls.Add(MainForm_MenuStrip);
Icon = (Icon)resources.GetObject("$this.Icon");
MainMenuStrip = MainForm_MenuStrip; MainMenuStrip = MainForm_MenuStrip;
Name = "MainForm"; Name = "MainForm";
Text = "MainForm"; Text = "MainForm";

View File

@ -36,10 +36,11 @@ namespace trakker
Cache = SqliteCacheMode.Shared Cache = SqliteCacheMode.Shared
}.ToString(); }.ToString();
Text = "Project Trakker - v[n.n.n] / pragmattica.com";
tabControlMainForm.TabPages[0].Text = " Home "; tabControlMainForm.TabPages[0].Text = " Home ";
tabControlMainForm.TabPages[1].Text = " Clients "; tabControlMainForm.TabPages[1].Text = " Clients ";
tabControlMainForm.TabPages[2].Text = " Projects "; tabControlMainForm.TabPages[2].Text = " Projects ";
tabControlMainForm.TabPages[3].Text = " Tasks "; tabControlMainForm.TabPages[3].Text = " Work Items ";
_ctrl = new Services.MainCtrl(this, connectionString); _ctrl = new Services.MainCtrl(this, connectionString);
} }
@ -235,6 +236,19 @@ namespace trakker
textColumn.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight; textColumn.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
dataGridViewProjects.Columns.Add(textColumn); dataGridViewProjects.Columns.Add(textColumn);
} }
{
var textColumn = new DataGridViewTextBoxColumn
{
AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill,
DataPropertyName = "Actuals",
Name = "Actuals",
Visible = true,
};
textColumn.DefaultCellStyle.Format = "$#,##0.00";
textColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
textColumn.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
dataGridViewProjects.Columns.Add(textColumn);
}
{ {
var textColumn = new DataGridViewTextBoxColumn var textColumn = new DataGridViewTextBoxColumn
{ {
@ -486,7 +500,7 @@ namespace trakker
MessageBox.Show("Cannot comment on root node", "Add Comment", MessageBoxButtons.OK, MessageBoxIcon.Warning); MessageBox.Show("Cannot comment on root node", "Add Comment", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return; return;
} }
TextAreaForm textAreaForm = new TextAreaForm("Add / Edit Comment"); TextAreaForm textAreaForm = new TextAreaForm("Add Comment");
DialogResult result = textAreaForm.ShowDialog(this); DialogResult result = textAreaForm.ShowDialog(this);
if (result == DialogResult.OK) if (result == DialogResult.OK)
{ {

View File

@ -129,4 +129,39 @@
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>162</value> <value>162</value>
</metadata> </metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
rze0hMIAAAAASUVORK5CYII=
</value>
</data>
</root> </root>

View File

@ -28,6 +28,7 @@
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProjectForm));
groupBoxNewClient = new GroupBox(); groupBoxNewClient = new GroupBox();
tableLayoutPanel1 = new TableLayoutPanel(); tableLayoutPanel1 = new TableLayoutPanel();
tableLayoutPanel2 = new TableLayoutPanel(); tableLayoutPanel2 = new TableLayoutPanel();
@ -386,6 +387,7 @@
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1144, 660); ClientSize = new Size(1144, 660);
Controls.Add(groupBoxNewClient); Controls.Add(groupBoxNewClient);
Icon = (Icon)resources.GetObject("$this.Icon");
Name = "ProjectForm"; Name = "ProjectForm";
Text = "ProjectForm"; Text = "ProjectForm";
groupBoxNewClient.ResumeLayout(false); groupBoxNewClient.ResumeLayout(false);

View File

@ -117,4 +117,39 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
rze0hMIAAAAASUVORK5CYII=
</value>
</data>
</root> </root>

View File

@ -28,6 +28,7 @@
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TaskForm));
groupBoxNewTask = new GroupBox(); groupBoxNewTask = new GroupBox();
tableLayoutPanel1 = new TableLayoutPanel(); tableLayoutPanel1 = new TableLayoutPanel();
tableLayoutPanel3 = new TableLayoutPanel(); tableLayoutPanel3 = new TableLayoutPanel();
@ -363,6 +364,7 @@
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1181, 372); ClientSize = new Size(1181, 372);
Controls.Add(groupBoxNewTask); Controls.Add(groupBoxNewTask);
Icon = (Icon)resources.GetObject("$this.Icon");
Name = "TaskForm"; Name = "TaskForm";
Text = "TaskForm"; Text = "TaskForm";
groupBoxNewTask.ResumeLayout(false); groupBoxNewTask.ResumeLayout(false);

View File

@ -117,4 +117,39 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
rze0hMIAAAAASUVORK5CYII=
</value>
</data>
</root> </root>

View File

@ -32,14 +32,14 @@
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TextAreaForm)); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TextAreaForm));
TextEdit_TableLayoutPanel1 = new TableLayoutPanel(); TextEdit_TableLayoutPanel1 = new TableLayoutPanel();
Content_RichTextBox = new RichTextBox(); Content_RichTextBox = new RichTextBox();
TextEdit_ContextMenuStrip = new ContextMenuStrip(components);
copyToClipboardToolStripMenuItem = new ToolStripMenuItem();
TextEdit_TableLayoutPanel2 = new TableLayoutPanel(); TextEdit_TableLayoutPanel2 = new TableLayoutPanel();
Okay_Button = new Button(); Okay_Button = new Button();
Cancel_Button = new Button(); Cancel_Button = new Button();
TextEdit_ContextMenuStrip = new ContextMenuStrip(components);
copyToClipboardToolStripMenuItem = new ToolStripMenuItem();
TextEdit_TableLayoutPanel1.SuspendLayout(); TextEdit_TableLayoutPanel1.SuspendLayout();
TextEdit_TableLayoutPanel2.SuspendLayout();
TextEdit_ContextMenuStrip.SuspendLayout(); TextEdit_ContextMenuStrip.SuspendLayout();
TextEdit_TableLayoutPanel2.SuspendLayout();
SuspendLayout(); SuspendLayout();
// //
// TextEdit_TableLayoutPanel1 // TextEdit_TableLayoutPanel1
@ -69,6 +69,20 @@
Content_RichTextBox.Text = ""; Content_RichTextBox.Text = "";
Content_RichTextBox.LinkClicked += Content_RichTextBox_LinkClicked; Content_RichTextBox.LinkClicked += Content_RichTextBox_LinkClicked;
// //
// TextEdit_ContextMenuStrip
//
TextEdit_ContextMenuStrip.ImageScalingSize = new Size(32, 32);
TextEdit_ContextMenuStrip.Items.AddRange(new ToolStripItem[] { copyToClipboardToolStripMenuItem });
TextEdit_ContextMenuStrip.Name = "TextEdit_ContextMenuStrip";
TextEdit_ContextMenuStrip.Size = new Size(283, 42);
//
// copyToClipboardToolStripMenuItem
//
copyToClipboardToolStripMenuItem.Name = "copyToClipboardToolStripMenuItem";
copyToClipboardToolStripMenuItem.Size = new Size(282, 38);
copyToClipboardToolStripMenuItem.Text = "Copy to Clipboard";
copyToClipboardToolStripMenuItem.Click += copyToClipboardToolStripMenuItem_Click;
//
// TextEdit_TableLayoutPanel2 // TextEdit_TableLayoutPanel2
// //
TextEdit_TableLayoutPanel2.ColumnCount = 3; TextEdit_TableLayoutPanel2.ColumnCount = 3;
@ -105,32 +119,18 @@
Cancel_Button.Text = "Cancel"; Cancel_Button.Text = "Cancel";
Cancel_Button.UseVisualStyleBackColor = true; Cancel_Button.UseVisualStyleBackColor = true;
// //
// TextEdit_ContextMenuStrip // TextAreaForm
//
TextEdit_ContextMenuStrip.ImageScalingSize = new Size(32, 32);
TextEdit_ContextMenuStrip.Items.AddRange(new ToolStripItem[] { copyToClipboardToolStripMenuItem });
TextEdit_ContextMenuStrip.Name = "TextEdit_ContextMenuStrip";
TextEdit_ContextMenuStrip.Size = new Size(283, 42);
//
// copyToClipboardToolStripMenuItem
//
copyToClipboardToolStripMenuItem.Name = "copyToClipboardToolStripMenuItem";
copyToClipboardToolStripMenuItem.Size = new Size(282, 38);
copyToClipboardToolStripMenuItem.Text = "Copy to Clipboard";
copyToClipboardToolStripMenuItem.Click += copyToClipboardToolStripMenuItem_Click;
//
// TextEdit
// //
AutoScaleDimensions = new SizeF(13F, 32F); AutoScaleDimensions = new SizeF(13F, 32F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1206, 777); ClientSize = new Size(1206, 777);
Controls.Add(TextEdit_TableLayoutPanel1); Controls.Add(TextEdit_TableLayoutPanel1);
Icon = (Icon)resources.GetObject("$this.Icon"); Icon = (Icon)resources.GetObject("$this.Icon");
Name = "TextEdit"; Name = "TextAreaForm";
Text = "Edit"; Text = "Edit";
TextEdit_TableLayoutPanel1.ResumeLayout(false); TextEdit_TableLayoutPanel1.ResumeLayout(false);
TextEdit_TableLayoutPanel2.ResumeLayout(false);
TextEdit_ContextMenuStrip.ResumeLayout(false); TextEdit_ContextMenuStrip.ResumeLayout(false);
TextEdit_TableLayoutPanel2.ResumeLayout(false);
ResumeLayout(false); ResumeLayout(false);
} }

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,8 @@ namespace trakker.Models
public decimal? HourlyRate { get; set; } public decimal? HourlyRate { get; set; }
public decimal? Actuals { get; set; }
public string? Notes { get; set; } = string.Empty; public string? Notes { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

BIN
Resources/pragmattica.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -6,8 +6,13 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<ApplicationIcon>Resources\pragmattica.ico</ApplicationIcon>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<Content Include="Resources\pragmattica.ico" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="10.0.7" /> <PackageReference Include="Microsoft.Data.Sqlite.Core" Version="10.0.7" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.2" /> <PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.2" />