Commit 33f30507 by Daniel Barker

Save and Cancel buttons now persist when editing a rows date

parent e3026c77
...@@ -85,9 +85,13 @@ ...@@ -85,9 +85,13 @@
Cancel Cancel
</button> </button>
<button type="button" class="btn btn-primary btn-sm" id="btn_task_picker_save" disabled> <button type="button" class="btn btn-outline-success btn-sm" id="btn_task_picker_save" disabled>
Save Save
</button> </button>
<button type="button" class="btn btn-primary btn-sm" id="btn_task_picker_select" disabled>
Select
</button>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -50,3 +50,17 @@ ...@@ -50,3 +50,17 @@
border-color: var(--bs-danger) !important; border-color: var(--bs-danger) !important;
padding-right: calc(1.5em + .75rem); padding-right: calc(1.5em + .75rem);
} }
.time-row-saved > td {
animation: time-row-saved-flash 900ms ease-out;
}
@keyframes time-row-saved-flash {
from {
box-shadow: inset 0 0 0 999px rgba(25, 135, 84, 0.25);
}
to {
box-shadow: inset 0 0 0 999px rgba(25, 135, 84, 0);
}
}
\ No newline at end of file
...@@ -1342,7 +1342,7 @@ object ApiDatabase: TApiDatabase ...@@ -1342,7 +1342,7 @@ object ApiDatabase: TApiDatabase
SQL.Strings = ( SQL.Strings = (
'select distinct' 'select distinct'
' t.TASK_ID,' ' t.TASK_ID,'
' c.NAME as CUSTOMER_NAME,' ' c.SHORT_NAME as CUSTOMER_NAME,'
' p.NAME as PROJECT_NAME,' ' p.NAME as PROJECT_NAME,'
' t.TASK_NUM_1,' ' t.TASK_NUM_1,'
' t.TASK_NUM_2,' ' t.TASK_NUM_2,'
......
...@@ -73,7 +73,6 @@ type ...@@ -73,7 +73,6 @@ type
value: string; value: string;
end; end;
type
TTaskPickerOption = class TTaskPickerOption = class
public public
value: string; value: string;
...@@ -88,6 +87,13 @@ type ...@@ -88,6 +87,13 @@ type
destructor Destroy; override; destructor Destroy; override;
end; end;
TTaskPickerTaskContext = class
public
taskId: string;
projectId: string;
customerId: string;
end;
[ServiceContract, Model(API_MODEL)] [ServiceContract, Model(API_MODEL)]
ITimeEntryService = interface(IInvokable) ITimeEntryService = interface(IInvokable)
['{B18BCD1E-B19A-4D25-BBA9-50A24FC4C690}'] ['{B18BCD1E-B19A-4D25-BBA9-50A24FC4C690}']
...@@ -97,9 +103,11 @@ type ...@@ -97,9 +103,11 @@ type
[HttpPost] function SaveTimeEntryField(Item: TTimeEntryFieldSave): Boolean; [HttpPost] function SaveTimeEntryField(Item: TTimeEntryFieldSave): Boolean;
[HttpPost] function DeleteTimeEntry(userId: string; entryId: Integer): Boolean; [HttpPost] function DeleteTimeEntry(userId: string; entryId: Integer): Boolean;
[HttpPost] function AddTaskToFocus(userId, taskId: string): Boolean; [HttpPost] function AddTaskToFocus(userId, taskId: string): Boolean;
[HttpPost] function RemoveTaskFromFocus(userId, taskId: string): Boolean;
function GetTaskPickerCustomers: TTaskPickerOptionsResponse; function GetTaskPickerCustomers: TTaskPickerOptionsResponse;
function GetTaskPickerProjects(customerId: string): TTaskPickerOptionsResponse; function GetTaskPickerProjects(customerId: string): TTaskPickerOptionsResponse;
function GetTaskPickerTasks(projectId: string): TTaskPickerOptionsResponse; function GetTaskPickerTasks(projectId: string): TTaskPickerOptionsResponse;
function GetTaskPickerTaskContext(taskId: string): TTaskPickerTaskContext;
end; end;
implementation implementation
......
...@@ -37,8 +37,10 @@ type ...@@ -37,8 +37,10 @@ type
function GetTaskPickerCustomers: TTaskPickerOptionsResponse; function GetTaskPickerCustomers: TTaskPickerOptionsResponse;
function GetTaskPickerProjects(customerId: string): TTaskPickerOptionsResponse; function GetTaskPickerProjects(customerId: string): TTaskPickerOptionsResponse;
function GetTaskPickerTasks(projectId: string): TTaskPickerOptionsResponse; function GetTaskPickerTasks(projectId: string): TTaskPickerOptionsResponse;
function GetTaskPickerTaskContext(taskId: string): TTaskPickerTaskContext;
function DeleteTimeEntry(userId: string; entryId: Integer): Boolean; function DeleteTimeEntry(userId: string; entryId: Integer): Boolean;
function AddTaskToFocus(userId, taskId: string): Boolean; function AddTaskToFocus(userId, taskId: string): Boolean;
function RemoveTaskFromFocus(userId, taskId: string): Boolean;
end; end;
implementation implementation
...@@ -213,7 +215,7 @@ begin ...@@ -213,7 +215,7 @@ begin
' ti.CATEGORY, ' + ' ti.CATEGORY, ' +
' cat.CODE_DESC as CATEGORY_DESC, ' + ' cat.CODE_DESC as CATEGORY_DESC, ' +
' ti.SUMMARY, ' + ' ti.SUMMARY, ' +
' c.NAME as CUSTOMER_NAME, ' + ' c.SHORT_NAME as CUSTOMER_NAME, ' +
' p.NAME as PROJECT_NAME, ' + ' p.NAME as PROJECT_NAME, ' +
' t.TASK_NUM_1, ' + ' t.TASK_NUM_1, ' +
' t.TASK_NUM_2, ' + ' t.TASK_NUM_2, ' +
...@@ -293,7 +295,7 @@ begin ...@@ -293,7 +295,7 @@ begin
tasksQuery.SQL.Text := tasksQuery.SQL.Text :=
'select distinct ' + 'select distinct ' +
' t.TASK_ID, ' + ' t.TASK_ID, ' +
' c.NAME as CUSTOMER_NAME, ' + ' c.SHORT_NAME as CUSTOMER_NAME, ' +
' p.NAME as PROJECT_NAME, ' + ' p.NAME as PROJECT_NAME, ' +
' t.TASK_NUM_1, ' + ' t.TASK_NUM_1, ' +
' t.TASK_NUM_2, ' + ' t.TASK_NUM_2, ' +
...@@ -308,7 +310,7 @@ begin ...@@ -308,7 +310,7 @@ begin
'join customers c on c.CUSTOMER_ID = p.CUSTOMER_ID ' + 'join customers c on c.CUSTOMER_ID = p.CUSTOMER_ID ' +
'where tau.USER_ID = :USER_ID ' + 'where tau.USER_ID = :USER_ID ' +
' and upper(trim(coalesce(tau.FOCUSED_TASK, ''''))) = ''T'' ' + ' and upper(trim(coalesce(tau.FOCUSED_TASK, ''''))) = ''T'' ' +
'order by c.NAME, p.NAME, t.TASK_NUM_1, t.TASK_NUM_2, t.TASK_NUM_3, t.TASK_NUM_4, t.TASK_NUM_5, t.TASK_NUM_6'; 'order by c.SHORT_NAME, p.NAME, t.TASK_NUM_1, t.TASK_NUM_2, t.TASK_NUM_3, t.TASK_NUM_4, t.TASK_NUM_5, t.TASK_NUM_6';
tasksQuery.ParamByName('USER_ID').AsString := userId; tasksQuery.ParamByName('USER_ID').AsString := userId;
tasksQuery.Open; tasksQuery.Open;
...@@ -850,6 +852,39 @@ begin ...@@ -850,6 +852,39 @@ begin
end; end;
function TTimeEntryService.GetTaskPickerTaskContext(taskId: string): TTaskPickerTaskContext;
var
q: TUniQuery;
begin
Logger.Log(4, Format('TimeEntryService.GetTaskPickerTaskContext - TASK_ID="%s"', [taskId]));
Result := TTaskPickerTaskContext.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
Result.taskId := taskId;
// Read-only lookup; an unknown task returns blank ids so the picker opens empty
q := TUniQuery.Create(nil);
try
q.Connection := apiDB.ucETaskApi;
q.SQL.Text :=
'select t.PROJECT_ID, p.CUSTOMER_ID ' +
'from tasks t ' +
'join project p on p.PROJECT_ID = t.PROJECT_ID ' +
'where t.TASK_ID = :TASK_ID';
q.ParamByName('TASK_ID').AsString := taskId;
q.Open;
if not q.Eof then
begin
Result.projectId := FieldText(q, 'PROJECT_ID');
Result.customerId := FieldText(q, 'CUSTOMER_ID');
end;
finally
q.Free;
end;
end;
function TTimeEntryService.DeleteTimeEntry(userId: string; entryId: Integer): Boolean; function TTimeEntryService.DeleteTimeEntry(userId: string; entryId: Integer): Boolean;
var var
q: TUniQuery; q: TUniQuery;
...@@ -952,6 +987,47 @@ begin ...@@ -952,6 +987,47 @@ begin
end; end;
end; end;
function TTimeEntryService.RemoveTaskFromFocus(userId, taskId: string): Boolean;
var
q: TUniQuery;
begin
Logger.Log(4, Format(
'TimeEntryService.RemoveTaskFromFocus - USER_ID="%s" TASK_ID="%s"',
[userId, taskId]
));
// Only clears the flag; the task_assigned_user row is kept and never inserted here
q := TUniQuery.Create(nil);
try
q.Connection := apiDB.ucETaskApi;
q.Connection.StartTransaction;
try
q.SQL.Text :=
'update task_assigned_user ' +
'set FOCUSED_TASK = ''F'' ' +
'where USER_ID = :USER_ID and TASK_ID = :TASK_ID';
q.ParamByName('USER_ID').AsString := userId;
q.ParamByName('TASK_ID').AsString := taskId;
q.ExecSQL;
q.Connection.Commit;
Result := True;
except
on E: Exception do
begin
if q.Connection.InTransaction then
q.Connection.Rollback;
Logger.Log(2, 'TimeEntryService.RemoveTaskFromFocus - ERROR: ' + E.Message);
raise;
end;
end;
finally
q.Free;
end;
end;
initialization initialization
RegisterServiceType(TTimeEntryService); RegisterServiceType(TTimeEntryService);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
MemoLogLevel=5 MemoLogLevel=5
FileLogLevel=5 FileLogLevel=5
webClientVersion=0.9.3 webClientVersion=0.9.3
LogFileNum=208 LogFileNum=218
[Database] [Database]
--Server=192.168.102.131 --Server=192.168.102.131
......
...@@ -114,11 +114,11 @@ ...@@ -114,11 +114,11 @@
<VerInfo_Locale>1033</VerInfo_Locale> <VerInfo_Locale>1033</VerInfo_Locale>
<DCC_ExeOutput>.\bin</DCC_ExeOutput> <DCC_ExeOutput>.\bin</DCC_ExeOutput>
<DCC_UnitSearchPath>C:\RADTOOLS\FastMM4;$(DCC_UnitSearchPath)</DCC_UnitSearchPath> <DCC_UnitSearchPath>C:\RADTOOLS\FastMM4;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_Keys>CompanyName=EM Systems;FileDescription=$(MSBuildProjectName);FileVersion=0.9.3.18;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=0.9.11;Comments=</VerInfo_Keys> <VerInfo_Keys>CompanyName=EM Systems;FileDescription=$(MSBuildProjectName);FileVersion=0.9.3.25;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=0.9.11;Comments=</VerInfo_Keys>
<VerInfo_MajorVer>0</VerInfo_MajorVer> <VerInfo_MajorVer>0</VerInfo_MajorVer>
<VerInfo_MinorVer>9</VerInfo_MinorVer> <VerInfo_MinorVer>9</VerInfo_MinorVer>
<VerInfo_AutoIncVersion>true</VerInfo_AutoIncVersion> <VerInfo_AutoIncVersion>true</VerInfo_AutoIncVersion>
<VerInfo_Build>18</VerInfo_Build> <VerInfo_Build>25</VerInfo_Build>
<VerInfo_Release>3</VerInfo_Release> <VerInfo_Release>3</VerInfo_Release>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''"> <PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment