Commit 44a9fed1 by Daniel Barker

Fix find button border on timeentries, add copy functionality to taskitems

parent 68ac3ea9
...@@ -58,6 +58,19 @@ object FTaskItems: TFTaskItems ...@@ -58,6 +58,19 @@ object FTaskItems: TFTaskItems
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
OnClick = btnInsertRowClick OnClick = btnInsertRowClick
end end
object btnCopyRow: TWebButton
Left = 78
Top = 210
Width = 96
Height = 25
Caption = 'Copy Row'
Enabled = False
ElementID = 'btn_copy_row'
ElementFont = efCSS
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnCopyRowClick
end
object btnTextColor: TWebButton object btnTextColor: TWebButton
Left = 282 Left = 282
Top = 197 Top = 197
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
<button id="btn_add_row" class="btn btn-sm btn-success text-nowrap">Add Row</button> <button id="btn_add_row" class="btn btn-sm btn-success text-nowrap">Add Row</button>
<button id="btn_insert_row" class="btn btn-sm btn-success text-nowrap">Insert Row</button> <button id="btn_insert_row" class="btn btn-sm btn-success text-nowrap">Insert Row</button>
<button id="btn_copy_row" class="btn btn-sm btn-primary text-nowrap" disabled>Copy Row</button>
<button id="btn_delete_row" class="btn btn-sm btn-danger text-nowrap">Delete Row</button> <button id="btn_delete_row" class="btn btn-sm btn-danger text-nowrap">Delete Row</button>
<button id="btn_reload" class="btn btn-sm btn-primary text-nowrap">Reload</button> <button id="btn_reload" class="btn btn-sm btn-primary text-nowrap">Reload</button>
</div> </div>
......
...@@ -31,6 +31,7 @@ type ...@@ -31,6 +31,7 @@ type
xdwdsTaskstaskItemId: TIntegerField; xdwdsTaskstaskItemId: TIntegerField;
btnDeleteRow: TWebButton; btnDeleteRow: TWebButton;
btnInsertRow: TWebButton; btnInsertRow: TWebButton;
btnCopyRow: TWebButton;
btnTextColor: TWebButton; btnTextColor: TWebButton;
btnFmtBold: TWebButton; btnFmtBold: TWebButton;
btnFmtItalic: TWebButton; btnFmtItalic: TWebButton;
...@@ -40,6 +41,7 @@ type ...@@ -40,6 +41,7 @@ type
procedure WebFormCreate(Sender: TObject); procedure WebFormCreate(Sender: TObject);
[async] procedure btnDeleteRowClick(Sender: TObject); [async] procedure btnDeleteRowClick(Sender: TObject);
[async] procedure btnInsertRowClick(Sender: TObject); [async] procedure btnInsertRowClick(Sender: TObject);
[async] procedure btnCopyRowClick(Sender: TObject);
procedure btnTextColorClick(Sender: TObject); procedure btnTextColorClick(Sender: TObject);
procedure btnFmtBoldClick(Sender: TObject); procedure btnFmtBoldClick(Sender: TObject);
procedure btnFmtItalicClick(Sender: TObject); procedure btnFmtItalicClick(Sender: TObject);
...@@ -61,6 +63,8 @@ type ...@@ -61,6 +63,8 @@ type
FActiveRichEditorId: string; FActiveRichEditorId: string;
FLastSelectionRange: JSValue; FLastSelectionRange: JSValue;
FNameManager: TNameManager; FNameManager: TNameManager;
FCopyingRow: Boolean;
[async] function CopyTaskRow: Boolean;
[async] procedure LoadTasks(const ATaskId: string); [async] procedure LoadTasks(const ATaskId: string);
procedure RenderTable; procedure RenderTable;
procedure BindTableEditors; procedure BindTableEditors;
...@@ -134,6 +138,8 @@ begin ...@@ -134,6 +138,8 @@ begin
FStatusOptions := TJSArray.new; FStatusOptions := TJSArray.new;
FSelectedTaskItemId := 0; FSelectedTaskItemId := 0;
FSelectedTaskId := 0; FSelectedTaskId := 0;
FCopyingRow := False;
btnCopyRow.Enabled := False;
FNameManager := TNameManager.Create( FNameManager := TNameManager.Create(
function(const AFieldName: string): TJSArray function(const AFieldName: string): TJSArray
...@@ -465,6 +471,53 @@ begin ...@@ -465,6 +471,53 @@ begin
end; end;
end; end;
[async] procedure TFTaskItems.btnCopyRowClick(Sender: TObject);
begin
if FCopyingRow or (FSelectedTaskItemId <= 0) then
Exit;
FCopyingRow := True;
btnCopyRow.Enabled := False;
Utils.ShowSpinner('spinner');
try
if await(CopyTaskRow) then
begin
CaptureTableScroll;
await(LoadTasks(FTaskId));
end;
finally
FCopyingRow := False;
btnCopyRow.Enabled := FSelectedTaskItemId > 0;
Utils.HideSpinner('spinner');
end;
end;
[async] function TFTaskItems.CopyTaskRow: Boolean;
var
response: TXDataClientResponse;
sourceTaskItemId: Integer;
begin
Result := False;
sourceTaskItemId := FSelectedTaskItemId;
try
response := await(xdwcTasks.RawInvokeAsync(
'ITaskItemService.CopyTaskRow', [FTaskId, sourceTaskItemId]));
console.log('CopyTaskRow: response=' + string(TJSJSON.stringify(response.Result)));
FSelectedTaskItemId := StrToIntDef(string(TJSObject(response.Result)['value']), 0);
FPendingFocusTaskItemId := FSelectedTaskItemId;
FPendingFocusField := 'application';
Result := True;
except
on E: EXDataClientRequestException do
begin
console.log('CopyTaskRow ERROR: ' + E.ErrorResult.ErrorMessage);
Utils.ShowErrorModal(E.ErrorResult.ErrorMessage);
end;
end;
end;
procedure TFTaskItems.RowClick(Event: TJSEvent); procedure TFTaskItems.RowClick(Event: TJSEvent);
var var
rowEl: TJSHTMLElement; rowEl: TJSHTMLElement;
...@@ -488,6 +541,7 @@ end; ...@@ -488,6 +541,7 @@ end;
procedure TFTaskItems.ApplySelectedRowState; procedure TFTaskItems.ApplySelectedRowState;
begin begin
btnCopyRow.Enabled := (FSelectedTaskItemId > 0) and not FCopyingRow;
asm asm
const selectedTaskItemId = this.FSelectedTaskItemId; const selectedTaskItemId = this.FSelectedTaskItemId;
document.querySelectorAll('.task-row-selectable').forEach(function(row){ document.querySelectorAll('.task-row-selectable').forEach(function(row){
......
...@@ -99,10 +99,10 @@ object FTimeEntries: TFTimeEntries ...@@ -99,10 +99,10 @@ object FTimeEntries: TFTimeEntries
OnClick = btnSearchRangeClick OnClick = btnSearchRangeClick
end end
object btnCopyEntry: TWebButton object btnCopyEntry: TWebButton
Left = 440 Left = 88
Top = 122 Top = 152
Width = 96 Width = 79
Height = 25 Height = 31
Caption = 'Copy' Caption = 'Copy'
ChildOrder = 7 ChildOrder = 7
ElementID = 'btn_copy_entry' ElementID = 'btn_copy_entry'
......
...@@ -459,7 +459,7 @@ var ...@@ -459,7 +459,7 @@ var
if AShowTaskPicker then if AShowTaskPicker then
begin begin
Result := Result + Result := Result +
'<button type="button" class="btn btn-outline-secondary time-task-picker-btn flex-shrink-0 text-nowrap" ' + '<button type="button" class="btn btn-outline-secondary time-task-picker-btn flex-shrink-0 text-nowrap ms-0" ' +
'data-idx="' + IntToStr(AIdx) + '" title="Find task">Find</button>' + 'data-idx="' + IntToStr(AIdx) + '" title="Find task">Find</button>' +
'</div>'; '</div>';
end; end;
......
...@@ -265,6 +265,60 @@ object ApiDatabase: TApiDatabase ...@@ -265,6 +265,60 @@ object ApiDatabase: TApiDatabase
Value = nil Value = nil
end> end>
end end
object uqCopyTaskItem: TUniQuery
Connection = ucETaskApi
SQL.Strings = (
'insert into task_items ('
' TASK_ID,'
' ITEM_NUM,'
' APPLICATION,'
' APP_VERSION,'
' TASK_DATE,'
' STATUS_DATE,'
' REPORTED_BY,'
' ASSIGNED_TO,'
' STATUS,'
' FIXED_VERSION,'
' FORM_SECTION,'
' ISSUE,'
' NOTES'
')'
'select'
' TASK_ID,'
' :ITEM_NUM,'
' APPLICATION,'
' APP_VERSION,'
' TASK_DATE,'
' STATUS_DATE,'
' REPORTED_BY,'
' ASSIGNED_TO,'
' STATUS,'
' FIXED_VERSION,'
' FORM_SECTION,'
' ISSUE,'
' NOTES'
'from task_items'
'where TASK_ID = :TASK_ID'
' and TASK_ITEM_ID = :TASK_ITEM_ID')
Left = 656
Top = 282
ParamData = <
item
DataType = ftInteger
Name = 'ITEM_NUM'
Value = nil
end
item
DataType = ftString
Name = 'TASK_ID'
Value = nil
end
item
DataType = ftInteger
Name = 'TASK_ITEM_ID'
Value = nil
end>
end
object uqTaskHeader: TUniQuery object uqTaskHeader: TUniQuery
Connection = ucETaskApi Connection = ucETaskApi
SQL.Strings = ( SQL.Strings = (
...@@ -565,7 +619,8 @@ object ApiDatabase: TApiDatabase ...@@ -565,7 +619,8 @@ object ApiDatabase: TApiDatabase
'update task_items' 'update task_items'
'set ITEM_NUM = ITEM_NUM + 1' 'set ITEM_NUM = ITEM_NUM + 1'
'where TASK_ID = :TASK_ID' 'where TASK_ID = :TASK_ID'
' and ITEM_NUM > :INSERT_AFTER_ITEM_NUM') ' and ITEM_NUM > :INSERT_AFTER_ITEM_NUM'
'order by ITEM_NUM desc')
Left = 538 Left = 538
Top = 76 Top = 76
ParamData = < ParamData = <
......
...@@ -19,6 +19,7 @@ type ...@@ -19,6 +19,7 @@ type
uqSaveTaskRow: TUniQuery; uqSaveTaskRow: TUniQuery;
uqTaskItems: TUniQuery; uqTaskItems: TUniQuery;
uqAddTaskRow: TUniQuery; uqAddTaskRow: TUniQuery;
uqCopyTaskItem: TUniQuery;
uqTaskItemsTASK_ID: TStringField; uqTaskItemsTASK_ID: TStringField;
uqTaskItemsITEM_NUM: TShortintField; uqTaskItemsITEM_NUM: TShortintField;
uqTaskItemsAPPLICATION: TStringField; uqTaskItemsAPPLICATION: TStringField;
......
...@@ -120,6 +120,7 @@ type ...@@ -120,6 +120,7 @@ type
[HttpGet] function GetTaskItems(taskId: string): TTaskItemsResponse; [HttpGet] function GetTaskItems(taskId: string): TTaskItemsResponse;
[HttpPost] function AddTaskRow(taskId: string; insertAfterItemNum: Integer): Boolean; [HttpPost] function AddTaskRow(taskId: string; insertAfterItemNum: Integer): Boolean;
[HttpPost] function CopyTaskRow(taskId: string; sourceTaskItemId: Integer): Integer;
[HttpPost] function AddAssignedName(taskId: string; name: string): TTaskUserOptionsResponse; [HttpPost] function AddAssignedName(taskId: string; name: string): TTaskUserOptionsResponse;
[HttpPost] function RenameAssignedName(taskId: string; oldName: string; newName: string): TTaskUserOptionsResponse; [HttpPost] function RenameAssignedName(taskId: string; oldName: string; newName: string): TTaskUserOptionsResponse;
......
...@@ -19,6 +19,7 @@ type ...@@ -19,6 +19,7 @@ type
function FindAssignedOptionId(const taskId, name: string): string; function FindAssignedOptionId(const taskId, name: string): string;
function FindAssignedOptionName(const taskId, name: string): string; function FindAssignedOptionName(const taskId, name: string): string;
function AddTaskRow(taskId: string; insertAfterItemNum: Integer): Boolean; function AddTaskRow(taskId: string; insertAfterItemNum: Integer): Boolean;
function CopyTaskRow(taskId: string; sourceTaskItemId: Integer): Integer;
function BuildAssignedOptionsResponse(const taskId: string): TTaskUserOptionsResponse; function BuildAssignedOptionsResponse(const taskId: string): TTaskUserOptionsResponse;
function AddAssignedName(taskId: string; name: string): TTaskUserOptionsResponse; function AddAssignedName(taskId: string; name: string): TTaskUserOptionsResponse;
function RenameAssignedName(taskId: string; oldName: string; newName: string): TTaskUserOptionsResponse; function RenameAssignedName(taskId: string; oldName: string; newName: string): TTaskUserOptionsResponse;
...@@ -272,6 +273,66 @@ begin ...@@ -272,6 +273,66 @@ begin
end; end;
function TTaskItemService.CopyTaskRow(taskId: string; sourceTaskItemId: Integer): Integer;
var
q: TUniQuery;
sourceItemNum: Integer;
begin
Logger.Log(4, Format('TaskItemService.CopyTaskRow - TASK_ID="%s" SOURCE_TASK_ITEM_ID="%d"', [taskId, sourceTaskItemId]));
apiDB.uqGetTaskRowPosition.Close;
apiDB.uqGetTaskRowPosition.ParamByName('TASK_ID').AsString := taskId;
apiDB.uqGetTaskRowPosition.ParamByName('TASK_ITEM_ID').AsInteger := sourceTaskItemId;
apiDB.uqGetTaskRowPosition.Open;
if apiDB.uqGetTaskRowPosition.IsEmpty then
begin
Logger.Log(2, Format('TaskItemService.CopyTaskRow - row not found TASK_ID="%s" TASK_ITEM_ID="%d"', [taskId, sourceTaskItemId]));
raise Exception.Create('Task row not found.');
end;
sourceItemNum := apiDB.uqGetTaskRowPositionITEM_NUM.AsInteger;
q := TUniQuery.Create(nil);
try
q.Connection := apiDB.ucETaskApi;
apiDB.ucETaskApi.StartTransaction;
try
apiDB.uqShiftTaskRowsForInsert.Close;
apiDB.uqShiftTaskRowsForInsert.ParamByName('TASK_ID').AsString := taskId;
apiDB.uqShiftTaskRowsForInsert.ParamByName('INSERT_AFTER_ITEM_NUM').AsInteger := sourceItemNum;
apiDB.uqShiftTaskRowsForInsert.ExecSQL;
apiDB.uqCopyTaskItem.Close;
apiDB.uqCopyTaskItem.ParamByName('TASK_ID').AsString := taskId;
apiDB.uqCopyTaskItem.ParamByName('TASK_ITEM_ID').AsInteger := sourceTaskItemId;
apiDB.uqCopyTaskItem.ParamByName('ITEM_NUM').AsInteger := sourceItemNum + 1;
apiDB.uqCopyTaskItem.ExecSQL;
if apiDB.uqCopyTaskItem.RowsAffected <> 1 then
raise Exception.Create('Unable to copy the selected task row.');
q.SQL.Text := 'select LAST_INSERT_ID() as TASK_ITEM_ID';
q.Open;
Result := q.FieldByName('TASK_ITEM_ID').AsInteger;
apiDB.ucETaskApi.Commit;
Logger.Log(4, Format('TaskItemService.CopyTaskRow - OK TASK_ID="%s" SOURCE_TASK_ITEM_ID="%d" TASK_ITEM_ID="%d" ITEM_NUM="%d"',
[taskId, sourceTaskItemId, Result, sourceItemNum + 1]));
except
on E: Exception do
begin
if apiDB.ucETaskApi.InTransaction then
apiDB.ucETaskApi.Rollback;
Logger.Log(2, 'TaskItemService.CopyTaskRow - ERROR: ' + E.Message);
raise;
end;
end;
finally
q.Free;
end;
end;
procedure TTaskItemService.MoveTaskRow(const taskId: Integer; const taskItemId: Integer; const newItemNum: Integer); procedure TTaskItemService.MoveTaskRow(const taskId: Integer; const taskItemId: Integer; const newItemNum: Integer);
var var
oldItemNum: Integer; oldItemNum: Integer;
......
...@@ -2,12 +2,14 @@ ...@@ -2,12 +2,14 @@
MemoLogLevel=4 MemoLogLevel=4
FileLogLevel=4 FileLogLevel=4
webClientVersion=0.9.3 webClientVersion=0.9.3
LogFileNum=245 LogFileNum=167
[Database] [Database]
Server=192.168.102.133 --Server=192.168.102.131
--Server=192.168.116.131 --Server=192.168.116.128
--Server=192.168.102.131
--Server=192.168.159.10 --Server=192.168.159.10
Server=192.168.90.129
Database=eTask Database=eTask
Username=root Username=root
Password=emsys01 Password=emsys01
......
...@@ -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.1;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.3;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>1</VerInfo_Build> <VerInfo_Build>3</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