Commit 071af034 by Mac Stephens

Refactor dropdown to use project wide server backed management and reuse the…

Refactor dropdown to use project wide server backed management and reuse the name manager for application/assigned flows. Deployed 0.8.7
parent 8c9083aa
......@@ -20,7 +20,7 @@ type
FUnauthorizedAccessProc: TUnauthorizedAccessProc;
public
const clientVersion = '0.8.6';
const clientVersion = '0.8.7';
procedure InitApp(SuccessProc: TSuccessProc;
UnauthorizedAccessProc: TUnauthorizedAccessProc);
procedure SetClientConfig(Callback: TVersionCheckCallback);
......
......@@ -36,6 +36,7 @@ type
[async] procedure btnDeleteRowClick(Sender: TObject);
private
FTaskId: string;
FApplicationOptions: TJSArray;
FReportedByOptions: TJSArray;
FAssignedToOptions: TJSArray;
FStatusOptions: TJSArray;
......@@ -81,10 +82,14 @@ type
[async] function RenameAssignedName(const AOldName, ANewName: string): TJSArray;
[async] function DeleteAssignedName(const AName: string): TJSArray;
function ExtractAssignedOptionNames(const ResponseResult: TJSObject): TJSArray;
[async] procedure HandleAddAssignedName(const ARowIndex: Integer; const ANewName: string);
[async] procedure HandleRenameAssignedName(const AOldName, ANewName: string);
[async] procedure HandleDeleteAssignedName(const AName: string);
function FindAssignedOptionIgnoreCase(const AItems: TJSArray; const AName: string): string;
[async] function AddApplicationName(const AName: string): TJSArray;
[async] function RenameApplicationName(const AOldName, ANewName: string): TJSArray;
[async] function DeleteApplicationName(const AName: string): TJSArray;
function ExtractApplicationOptionNames(const ResponseResult: TJSObject): TJSArray;
[async] procedure HandleAddManagedName(const AFieldName: string; const ARowIndex: Integer; const ANewName: string);
[async] procedure HandleRenameManagedName(const AFieldName, AOldName, ANewName: string);
[async] procedure HandleDeleteManagedName(const AFieldName, AName: string);
function FindOptionIgnoreCase(const AItems: TJSArray; const AName: string): string;
public
end;
......@@ -103,6 +108,7 @@ procedure TFTaskItems.WebFormCreate(Sender: TObject);
begin
console.log('TFTaskItems.WebFormCreate fired');
FTaskId := Application.Parameters.Values['task_id'];
FApplicationOptions := TJSArray.new;
FReportedByOptions := TJSArray.new;
FAssignedToOptions := TJSArray.new;
FStatusOptions := TJSArray.new;
......@@ -118,17 +124,17 @@ begin
begin
FocusTrigger(ATriggerId);
end,
procedure(const ARowIndex: Integer; const ANewName: string)
procedure(const AFieldName: string; const ARowIndex: Integer; const ANewName: string)
begin
HandleAddAssignedName(ARowIndex, ANewName);
HandleAddManagedName(AFieldName, ARowIndex, ANewName);
end,
procedure(const AOldName, ANewName: string)
procedure(const AFieldName, AOldName, ANewName: string)
begin
HandleRenameAssignedName(AOldName, ANewName);
HandleRenameManagedName(AFieldName, AOldName, ANewName);
end,
procedure(const AName: string)
procedure(const AFieldName, AName: string)
begin
HandleDeleteAssignedName(AName);
HandleDeleteManagedName(AFieldName, AName);
end
);
......@@ -575,6 +581,7 @@ begin
rowCount := StrToIntDef(string(resultObj['count']), 0);
SetTotalRowsLabel(rowCount);
FApplicationOptions := ExtractOptionNames(TJSArray(resultObj['applicationOptions']));
FReportedByOptions := ExtractOptionNames(TJSArray(resultObj['reportedByOptions']));
FAssignedToOptions := ExtractOptionNames(TJSArray(resultObj['assignedToOptions']));
FStatusOptions := ExtractCodeDescs(TJSArray(resultObj['statusOptions']));
......@@ -789,7 +796,7 @@ begin
html := html +
'<tr class="task-row-selectable" data-task-item-id="' + IntToStr(xdwdsTaskstaskItemId.AsInteger) + '" data-task-id="' + xdwdsTaskstaskId.AsString + '" data-item-num="' + IntToStr(xdwdsTasksitemNum.AsInteger) + '">' +
TdNowrap(ItemNumInput(xdwdsTasksitemNum.AsInteger, rowIdx)) +
TdNowrap(TextInput('application', xdwdsTasksapplication.AsString, rowIdx, 180)) +
TdNowrap(SelectList('application', xdwdsTasksapplication.AsString, rowIdx, FApplicationOptions, True)) +
TdNowrap(TextInput('version', xdwdsTasksversion.AsString, rowIdx, 80)) +
TdNowrap(DateInput('taskDate', xdwdsTaskstaskDate.AsString, rowIdx, 110)) +
TdNowrap(SelectList('reportedBy', xdwdsTasksreportedBy.AsString, rowIdx, FReportedByOptions, False)) +
......@@ -1050,7 +1057,9 @@ end;
function TFTaskItems.GetOptionsForField(const AFieldName: string): TJSArray;
begin
if SameText(AFieldName, 'reportedBy') then
if SameText(AFieldName, 'application') then
Result := FApplicationOptions
else if SameText(AFieldName, 'reportedBy') then
Result := FReportedByOptions
else if SameText(AFieldName, 'assignedTo') then
Result := FAssignedToOptions
......@@ -1138,7 +1147,7 @@ begin
if (idx < 0) or (fieldName = '') then
Exit;
if not SameText(fieldName, 'assignedTo') then
if not (SameText(fieldName, 'assignedTo') or SameText(fieldName, 'application')) then
Exit;
FNameManager.OpenManager(fieldName, idx, triggerId);
......@@ -1235,6 +1244,14 @@ begin
end;
function TFTaskItems.ExtractApplicationOptionNames(const ResponseResult: TJSObject): TJSArray;
begin
if not Assigned(ResponseResult) then
Exit(TJSArray.new);
Result := ExtractOptionNames(TJSArray(ResponseResult['applicationOptions']));
end;
function TFTaskItems.ExtractAssignedOptionNames(const ResponseResult: TJSObject): TJSArray;
begin
if not Assigned(ResponseResult) then
......@@ -1243,6 +1260,24 @@ begin
Result := ExtractOptionNames(TJSArray(ResponseResult['assignedToOptions']));
end;
function TFTaskItems.FindOptionIgnoreCase(const AItems: TJSArray; const AName: string): string;
var
i: Integer;
itemText: string;
begin
Result := '';
if not Assigned(AItems) then
Exit;
for i := 0 to AItems.length - 1 do
begin
itemText := string(AItems[i]);
if SameText(itemText, Trim(AName)) then
Exit(itemText);
end;
end;
[async] function TFTaskItems.AddAssignedName(const AName: string): TJSArray;
var
response: TXDataClientResponse;
......@@ -1321,36 +1356,28 @@ begin
end;
end;
function TFTaskItems.FindAssignedOptionIgnoreCase(const AItems: TJSArray; const AName: string): string;
var
i: Integer;
itemText: string;
begin
Result := '';
if not Assigned(AItems) then
Exit;
for i := 0 to AItems.length - 1 do
begin
itemText := string(AItems[i]);
if SameText(itemText, Trim(AName)) then
Exit(itemText);
end;
end;
[async] procedure TFTaskItems.HandleAddAssignedName(const ARowIndex: Integer; const ANewName: string);
[async] procedure TFTaskItems.HandleAddManagedName(const AFieldName: string; const ARowIndex: Integer; const ANewName: string);
var
newOptions: TJSArray;
resolvedName: string;
begin
newOptions := await(AddAssignedName(ANewName));
if SameText(AFieldName, 'application') then
newOptions := await(AddApplicationName(ANewName))
else if SameText(AFieldName, 'assignedTo') then
newOptions := await(AddAssignedName(ANewName))
else
Exit;
if not Assigned(newOptions) then
Exit;
FAssignedToOptions := newOptions;
resolvedName := FindAssignedOptionIgnoreCase(FAssignedToOptions, ANewName);
if SameText(AFieldName, 'application') then
FApplicationOptions := newOptions
else
FAssignedToOptions := newOptions;
resolvedName := FindOptionIgnoreCase(newOptions, ANewName);
if resolvedName = '' then
resolvedName := Trim(ANewName);
......@@ -1362,39 +1389,137 @@ begin
Exit;
xdwdsTasks.Edit;
xdwdsTasksassignedTo.AsString := resolvedName;
xdwdsTasks.FieldByName(AFieldName).AsString := resolvedName;
xdwdsTasks.Post;
RenderTable;
await(SaveRow(ARowIndex));
end;
[async] procedure TFTaskItems.HandleRenameAssignedName(const AOldName, ANewName: string);
[async] procedure TFTaskItems.HandleRenameManagedName(const AFieldName, AOldName, ANewName: string);
var
newOptions: TJSArray;
begin
newOptions := await(RenameAssignedName(AOldName, ANewName));
if SameText(AFieldName, 'application') then
newOptions := await(RenameApplicationName(AOldName, ANewName))
else if SameText(AFieldName, 'assignedTo') then
newOptions := await(RenameAssignedName(AOldName, ANewName))
else
Exit;
if not Assigned(newOptions) then
Exit;
FAssignedToOptions := newOptions;
if SameText(AFieldName, 'application') then
FApplicationOptions := newOptions
else
FAssignedToOptions := newOptions;
CaptureTableScroll;
LoadTasks(FTaskId);
end;
[async] procedure TFTaskItems.HandleDeleteAssignedName(const AName: string);
[async] procedure TFTaskItems.HandleDeleteManagedName(const AFieldName, AName: string);
var
newOptions: TJSArray;
begin
newOptions := await(DeleteAssignedName(AName));
if SameText(AFieldName, 'application') then
newOptions := await(DeleteApplicationName(AName))
else if SameText(AFieldName, 'assignedTo') then
newOptions := await(DeleteAssignedName(AName))
else
Exit;
if not Assigned(newOptions) then
Exit;
FAssignedToOptions := newOptions;
if SameText(AFieldName, 'application') then
FApplicationOptions := newOptions
else
FAssignedToOptions := newOptions;
CaptureTableScroll;
LoadTasks(FTaskId);
end;
[async] function TFTaskItems.AddApplicationName(const AName: string): TJSArray;
var
response: TXDataClientResponse;
resultObj: TJSObject;
begin
Result := nil;
try
response := await(xdwcTasks.RawInvokeAsync(
'IApiService.AddApplicationName',
[FTaskId, Trim(AName)]
));
resultObj := TJSObject(response.Result);
Result := ExtractApplicationOptionNames(resultObj);
FApplicationOptions := Result;
except
on E: EXDataClientRequestException do
begin
console.log('AddApplicationName ERROR: ' + E.ErrorResult.ErrorMessage);
Utils.ShowErrorModal(E.ErrorResult.ErrorMessage);
Exit;
end;
end;
end;
[async] function TFTaskItems.RenameApplicationName(const AOldName, ANewName: string): TJSArray;
var
response: TXDataClientResponse;
resultObj: TJSObject;
begin
Result := nil;
try
response := await(xdwcTasks.RawInvokeAsync(
'IApiService.RenameApplicationName',
[FTaskId, Trim(AOldName), Trim(ANewName)]
));
resultObj := TJSObject(response.Result);
Result := ExtractApplicationOptionNames(resultObj);
FApplicationOptions := Result;
except
on E: EXDataClientRequestException do
begin
console.log('RenameApplicationName ERROR: ' + E.ErrorResult.ErrorMessage);
Utils.ShowErrorModal(E.ErrorResult.ErrorMessage);
Exit;
end;
end;
end;
[async] function TFTaskItems.DeleteApplicationName(const AName: string): TJSArray;
var
response: TXDataClientResponse;
resultObj: TJSObject;
begin
Result := nil;
try
response := await(xdwcTasks.RawInvokeAsync(
'IApiService.DeleteApplicationName',
[FTaskId, Trim(AName)]
));
resultObj := TJSObject(response.Result);
Result := ExtractApplicationOptionNames(resultObj);
FApplicationOptions := Result;
except
on E: EXDataClientRequestException do
begin
console.log('DeleteApplicationName ERROR: ' + E.ErrorResult.ErrorMessage);
Utils.ShowErrorModal(E.ErrorResult.ErrorMessage);
Exit;
end;
end;
end;
......
......@@ -94,13 +94,13 @@
<DCC_RemoteDebug>false</DCC_RemoteDebug>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=0.8.6.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=0.9.8.0;Comments=;LastCompiledTime=2018/08/27 15:18:29</VerInfo_Keys>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=0.8.7.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=0.9.8.0;Comments=;LastCompiledTime=2018/08/27 15:18:29</VerInfo_Keys>
<AppDPIAwarenessMode>PerMonitor</AppDPIAwarenessMode>
<VerInfo_MajorVer>0</VerInfo_MajorVer>
<VerInfo_MinorVer>8</VerInfo_MinorVer>
<VerInfo_Release>6</VerInfo_Release>
<TMSUseJSDebugger>2</TMSUseJSDebugger>
<VerInfo_Release>7</VerInfo_Release>
<TMSWebBrowser>1</TMSWebBrowser>
<TMSUseJSDebugger>2</TMSUseJSDebugger>
<TMSWebSingleInstance>1</TMSWebSingleInstance>
<TMSWebOutputPath>..\emT3XDataServer\bin\static</TMSWebOutputPath>
</PropertyGroup>
......
......@@ -8,9 +8,9 @@ uses
type
TGetOptionsEvent = reference to function(const AFieldName: string): TJSArray;
TFocusTriggerEvent = reference to procedure(const ATriggerId: string);
TAddAssignedNameEvent = reference to procedure(const ARowIndex: Integer; const ANewName: string);
TRenameAssignedNameEvent = reference to procedure(const AOldName, ANewName: string);
TDeleteAssignedNameEvent = reference to procedure(const AName: string);
TAddManagedNameEvent = reference to procedure(const AFieldName: string; const ARowIndex: Integer; const ANewName: string);
TRenameManagedNameEvent = reference to procedure(const AFieldName, AOldName, ANewName: string);
TDeleteManagedNameEvent = reference to procedure(const AFieldName, AName: string);
TNameManager = class
private
......@@ -20,9 +20,9 @@ type
FCurrentEditName: string;
FGetOptions: TGetOptionsEvent;
FFocusTrigger: TFocusTriggerEvent;
FAddAssignedName: TAddAssignedNameEvent;
FRenameAssignedName: TRenameAssignedNameEvent;
FDeleteAssignedName: TDeleteAssignedNameEvent;
FAddManagedName: TAddManagedNameEvent;
FRenameManagedName: TRenameManagedNameEvent;
FDeleteManagedName: TDeleteManagedNameEvent;
procedure AddAnotherClick(Event: TJSEvent);
procedure SaveClick(Event: TJSEvent);
procedure NameInputKeyDown(Event: TJSEvent);
......@@ -40,9 +40,9 @@ type
constructor Create(
const AGetOptions: TGetOptionsEvent;
const AFocusTrigger: TFocusTriggerEvent;
const AAddAssignedName: TAddAssignedNameEvent;
const ARenameAssignedName: TRenameAssignedNameEvent;
const ADeleteAssignedName: TDeleteAssignedNameEvent
const AAddManagedName: TAddManagedNameEvent;
const ARenameManagedName: TRenameManagedNameEvent;
const ADeleteManagedName: TDeleteManagedNameEvent
);
procedure BindControls;
......@@ -70,17 +70,17 @@ end;
constructor TNameManager.Create(
const AGetOptions: TGetOptionsEvent;
const AFocusTrigger: TFocusTriggerEvent;
const AAddAssignedName: TAddAssignedNameEvent;
const ARenameAssignedName: TRenameAssignedNameEvent;
const ADeleteAssignedName: TDeleteAssignedNameEvent
const AAddManagedName: TAddManagedNameEvent;
const ARenameManagedName: TRenameManagedNameEvent;
const ADeleteManagedName: TDeleteManagedNameEvent
);
begin
inherited Create;
FGetOptions := AGetOptions;
FFocusTrigger := AFocusTrigger;
FAddAssignedName := AAddAssignedName;
FRenameAssignedName := ARenameAssignedName;
FDeleteAssignedName := ADeleteAssignedName;
FAddManagedName := AAddManagedName;
FRenameManagedName := ARenameManagedName;
FDeleteManagedName := ADeleteManagedName;
FCurrentField := '';
FCurrentRowIndex := -1;
FCurrentTriggerId := '';
......@@ -257,18 +257,18 @@ begin
Exit;
end;
if not SameText(FCurrentField, 'assignedTo') then
if not (SameText(FCurrentField, 'assignedTo') or SameText(FCurrentField, 'application')) then
Exit;
if FCurrentEditName <> '' then
begin
if Assigned(FRenameAssignedName) then
FRenameAssignedName(FCurrentEditName, newName);
if Assigned(FRenameManagedName) then
FRenameManagedName(FCurrentField, FCurrentEditName, newName);
end
else
begin
if Assigned(FAddAssignedName) then
FAddAssignedName(FCurrentRowIndex, newName);
if Assigned(FAddManagedName) then
FAddManagedName(FCurrentField, FCurrentRowIndex, newName);
end;
CloseManager;
......@@ -356,7 +356,7 @@ begin
Event.preventDefault;
Event.stopPropagation;
if not SameText(FCurrentField, 'assignedTo') then
if not (SameText(FCurrentField, 'assignedTo') or SameText(FCurrentField, 'application')) then
Exit;
el := TJSHTMLElement(Event.currentTarget);
......@@ -383,7 +383,7 @@ begin
Event.preventDefault;
Event.stopPropagation;
if not SameText(FCurrentField, 'assignedTo') then
if not (SameText(FCurrentField, 'assignedTo') or SameText(FCurrentField, 'application')) then
Exit;
el := TJSHTMLElement(Event.currentTarget);
......@@ -391,8 +391,8 @@ begin
if nameToDelete = '' then
Exit;
if Assigned(FDeleteAssignedName) then
FDeleteAssignedName(nameToDelete);
if Assigned(FDeleteManagedName) then
FDeleteManagedName(FCurrentField, nameToDelete);
CloseManager;
end;
......@@ -401,7 +401,7 @@ procedure TNameManager.OpenManager(const AFieldName: string; const ARowIndex: In
var
titleEl: TJSHTMLElement;
begin
if not SameText(AFieldName, 'assignedTo') then
if not (SameText(AFieldName, 'assignedTo') or SameText(AFieldName, 'application')) then
Exit;
FCurrentField := AFieldName;
......@@ -411,7 +411,12 @@ begin
titleEl := GetElement('nm_title');
if Assigned(titleEl) then
titleEl.innerHTML := 'Manage Assigned To';
begin
if SameText(AFieldName, 'application') then
titleEl.innerHTML := 'Manage Application'
else
titleEl.innerHTML := 'Manage Assigned To';
end;
ResetInputArea;
RenderExistingList;
......
object ApiDatabase: TApiDatabase
OnCreate = DataModuleCreate
Height = 453
Width = 641
Height = 475
Width = 803
object ucETaskApi: TUniConnection
AutoCommit = False
ProviderName = 'MySQL'
Database = 'eTask'
LoginPrompt = False
Left = 255
Top = 379
Left = 267
Top = 395
end
object MySQLUniProvider1: TMySQLUniProvider
Left = 354
Top = 378
Left = 416
Top = 398
end
object uqUsers: TUniQuery
Connection = ucETaskApi
......@@ -775,4 +775,160 @@ object ApiDatabase: TApiDatabase
Value = nil
end>
end
object uqProjectApplications: TUniQuery
Connection = ucETaskApi
SQL.Strings = (
'select distinct'
' tia.TASK_ITEM_APPLICATION_ID,'
' tia.PROJECT_ID,'
' tia.NAME'
'from task_item_application tia'
'join tasks target_task'
' on target_task.PROJECT_ID = tia.PROJECT_ID'
'where target_task.TASK_ID = :TASK_ID'
'order by tia.NAME')
Left = 58
Top = 314
ParamData = <
item
DataType = ftUnknown
Name = 'TASK_ID'
Value = nil
end>
object uqProjectApplicationsTASK_ITEM_APPLICATION_ID: TIntegerField
FieldName = 'TASK_ITEM_APPLICATION_ID'
end
object uqProjectApplicationsPROJECT_ID: TStringField
FieldName = 'PROJECT_ID'
Required = True
Size = 7
end
object uqProjectApplicationsNAME: TStringField
FieldName = 'NAME'
Required = True
Size = 255
end
end
object uqApplicationInsert: TUniQuery
Connection = ucETaskApi
SQL.Strings = (
'insert into task_item_application ('
' PROJECT_ID,'
' NAME'
')'
'values ('
' :PROJECT_ID,'
' :NAME'
')')
Left = 700
Top = 28
ParamData = <
item
DataType = ftUnknown
Name = 'PROJECT_ID'
Value = nil
end
item
DataType = ftUnknown
Name = 'NAME'
Value = nil
end>
end
object uqApplicationRename: TUniQuery
Connection = ucETaskApi
SQL.Strings = (
'update task_item_application'
'set NAME = :NEW_NAME'
'where TASK_ITEM_APPLICATION_ID = :TASK_ITEM_APPLICATION_ID'
' and PROJECT_ID = :PROJECT_ID')
Left = 700
Top = 82
ParamData = <
item
DataType = ftUnknown
Name = 'NEW_NAME'
Value = nil
end
item
DataType = ftUnknown
Name = 'TASK_ITEM_APPLICATION_ID'
Value = nil
end
item
DataType = ftUnknown
Name = 'PROJECT_ID'
Value = nil
end>
end
object uqApplicationDelete: TUniQuery
Connection = ucETaskApi
SQL.Strings = (
'delete from task_item_application'
'where TASK_ITEM_APPLICATION_ID = :TASK_ITEM_APPLICATION_ID'
' and PROJECT_ID = :PROJECT_ID')
Left = 700
Top = 136
ParamData = <
item
DataType = ftUnknown
Name = 'TASK_ITEM_APPLICATION_ID'
Value = nil
end
item
DataType = ftUnknown
Name = 'PROJECT_ID'
Value = nil
end>
end
object uqRenameTaskItemApplication: TUniQuery
Connection = ucETaskApi
SQL.Strings = (
'update task_items ti'
'join tasks t'
' on t.TASK_ID = ti.TASK_ID'
'set ti.APPLICATION = :NEW_NAME'
'where t.PROJECT_ID = :PROJECT_ID'
' and lower(ti.APPLICATION) = lower(:OLD_NAME)')
Left = 698
Top = 188
ParamData = <
item
DataType = ftUnknown
Name = 'NEW_NAME'
Value = nil
end
item
DataType = ftUnknown
Name = 'PROJECT_ID'
Value = nil
end
item
DataType = ftUnknown
Name = 'OLD_NAME'
Value = nil
end>
end
object uqBlankTaskItemApplication: TUniQuery
Connection = ucETaskApi
SQL.Strings = (
'update task_items ti'
'join tasks t'
' on t.TASK_ID = ti.TASK_ID'
'set ti.APPLICATION = '#39#39
'where t.PROJECT_ID = :PROJECT_ID'
' and lower(ti.APPLICATION) = lower(:NAME)')
Left = 696
Top = 244
ParamData = <
item
DataType = ftUnknown
Name = 'PROJECT_ID'
Value = nil
end
item
DataType = ftUnknown
Name = 'NAME'
Value = nil
end>
end
end
......@@ -73,6 +73,15 @@ type
uqTaskAssignedUsersTASK_ID: TStringField;
uqTaskAssignedUsersUSER_TYPE: TStringField;
uqTaskAssignedUsersNAME: TStringField;
uqProjectApplications: TUniQuery;
uqApplicationInsert: TUniQuery;
uqApplicationRename: TUniQuery;
uqApplicationDelete: TUniQuery;
uqRenameTaskItemApplication: TUniQuery;
uqBlankTaskItemApplication: TUniQuery;
uqProjectApplicationsTASK_ITEM_APPLICATION_ID: TIntegerField;
uqProjectApplicationsPROJECT_ID: TStringField;
uqProjectApplicationsNAME: TStringField;
procedure DataModuleCreate(Sender: TObject);
procedure uqUsersCalcFields(DataSet: TDataSet);
private
......
......@@ -48,7 +48,11 @@ type
name: string;
end;
type
TTaskApplicationOption = class
public
name: string;
end;
TTaskItemCode = class
public
code: string;
......@@ -61,6 +65,7 @@ type
count: integer;
task: TTaskHeader;
items: TList<TTaskItem>;
applicationOptions: TList<TTaskApplicationOption>;
reportedByOptions: TList<TTaskUserOption>;
assignedToOptions: TList<TTaskUserOption>;
statusOptions: TList<TTaskItemCode>;
......@@ -75,6 +80,13 @@ type
destructor Destroy; override;
end;
TTaskApplicationOptionsResponse = class
public
applicationOptions: TList<TTaskApplicationOption>;
constructor Create;
destructor Destroy; override;
end;
TTaskRowSave = class
public
taskItemId: integer;
......@@ -93,9 +105,6 @@ type
notes: string;
end;
type
[ServiceContract, Model(API_MODEL)]
IApiService = interface(IInvokable)
......@@ -106,6 +115,9 @@ type
[HttpPost] function AddAssignedName(taskId: string; name: string): TTaskUserOptionsResponse;
[HttpPost] function RenameAssignedName(taskId: string; oldName: string; newName: string): TTaskUserOptionsResponse;
[HttpPost] function DeleteAssignedName(taskId: string; name: string): TTaskUserOptionsResponse;
[HttpPost] function AddApplicationName(taskId: string; name: string): TTaskApplicationOptionsResponse;
[HttpPost] function RenameApplicationName(taskId: string; oldName: string; newName: string): TTaskApplicationOptionsResponse;
[HttpPost] function DeleteApplicationName(taskId: string; name: string): TTaskApplicationOptionsResponse;
procedure MoveTaskRow(const taskId: Integer; const taskItemId: Integer; const newItemNum: Integer);
function DeleteTaskRow(const taskId: Integer; const taskItemId: Integer): Boolean;
end;
......@@ -116,6 +128,7 @@ constructor TTaskItemsResponse.Create;
begin
inherited;
items := TList<TTaskItem>.Create;
applicationOptions := TList<TTaskApplicationOption>.Create;
reportedByOptions := TList<TTaskUserOption>.Create;
assignedToOptions := TList<TTaskUserOption>.Create;
statusOptions := TList<TTaskItemCode>.Create;
......@@ -124,6 +137,7 @@ end;
destructor TTaskItemsResponse.Destroy;
begin
items.Free;
applicationOptions.Free;
reportedByOptions.Free;
assignedToOptions.Free;
statusOptions.Free;
......@@ -142,6 +156,18 @@ begin
inherited;
end;
constructor TTaskApplicationOptionsResponse.Create;
begin
inherited;
applicationOptions := TList<TTaskApplicationOption>.Create;
end;
destructor TTaskApplicationOptionsResponse.Destroy;
begin
applicationOptions.Free;
inherited;
end;
initialization
RegisterServiceType(TypeInfo(IApiService));
......
......@@ -30,6 +30,13 @@ type
function DeleteAssignedName(taskId: string; name: string): TTaskUserOptionsResponse;
procedure MoveTaskRow(const taskId: Integer; const taskItemId: Integer; const newItemNum: Integer);
function DeleteTaskRow(const taskId, taskItemId: Integer): Boolean;
function FindProjectId(const taskId: string): string;
function FindApplicationId(const taskId, name: string): Integer;
function FindApplicationName(const taskId, name: string): string;
function BuildApplicationOptionsResponse(const taskId: string): TTaskApplicationOptionsResponse;
function AddApplicationName(taskId: string; name: string): TTaskApplicationOptionsResponse;
function RenameApplicationName(taskId: string; oldName: string; newName: string): TTaskApplicationOptionsResponse;
function DeleteApplicationName(taskId: string; name: string): TTaskApplicationOptionsResponse;
public
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
......@@ -58,6 +65,7 @@ var
taskHeader: TTaskHeader;
taskUserOption: TTaskUserOption;
taskItemCode: TTaskItemCode;
taskApplicationOption: TTaskApplicationOption;
item: TTaskItem;
begin
Logger.Log(4, Format('ApiService.GetTaskItems - TASK_ID="%s"', [taskId]));
......@@ -93,6 +101,21 @@ begin
Result.task := taskHeader;
apiDB.uqProjectApplications.Close;
apiDB.uqProjectApplications.ParamByName('TASK_ID').AsString := taskId;
apiDB.uqProjectApplications.Open;
while not apiDB.uqProjectApplications.Eof do
begin
taskApplicationOption := TTaskApplicationOption.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add(taskApplicationOption);
taskApplicationOption.name := apiDB.uqProjectApplicationsNAME.AsString;
Result.applicationOptions.Add(taskApplicationOption);
apiDB.uqProjectApplications.Next;
end;
apiDB.uqProjectReportedUsers.Close;
apiDB.uqProjectReportedUsers.ParamByName('TASK_ID').AsString := taskId;
apiDB.uqProjectReportedUsers.Open;
......@@ -687,6 +710,230 @@ begin
end;
end;
function TApiService.FindProjectId(const taskId: string): string;
begin
Result := '';
apiDB.uqTaskHeader.Close;
apiDB.uqTaskHeader.ParamByName('TASK_ID').AsString := taskId;
apiDB.uqTaskHeader.Open;
if not apiDB.uqTaskHeader.IsEmpty then
Result := apiDB.uqTaskHeaderPROJECT_ID.AsString;
end;
function TApiService.FindApplicationId(const taskId, name: string): Integer;
begin
Result := 0;
apiDB.uqProjectApplications.Close;
apiDB.uqProjectApplications.ParamByName('TASK_ID').AsString := taskId;
apiDB.uqProjectApplications.Open;
while not apiDB.uqProjectApplications.Eof do
begin
if SameText(Trim(apiDB.uqProjectApplicationsNAME.AsString), Trim(name)) then
begin
Result := apiDB.uqProjectApplicationsTASK_ITEM_APPLICATION_ID.AsInteger;
Exit;
end;
apiDB.uqProjectApplications.Next;
end;
end;
function TApiService.FindApplicationName(const taskId, name: string): string;
begin
Result := '';
apiDB.uqProjectApplications.Close;
apiDB.uqProjectApplications.ParamByName('TASK_ID').AsString := taskId;
apiDB.uqProjectApplications.Open;
while not apiDB.uqProjectApplications.Eof do
begin
if SameText(Trim(apiDB.uqProjectApplicationsNAME.AsString), Trim(name)) then
begin
Result := apiDB.uqProjectApplicationsNAME.AsString;
Exit;
end;
apiDB.uqProjectApplications.Next;
end;
end;
function TApiService.BuildApplicationOptionsResponse(const taskId: string): TTaskApplicationOptionsResponse;
var
taskApplicationOption: TTaskApplicationOption;
begin
Result := TTaskApplicationOptionsResponse.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
apiDB.uqProjectApplications.Close;
apiDB.uqProjectApplications.ParamByName('TASK_ID').AsString := taskId;
apiDB.uqProjectApplications.Open;
while not apiDB.uqProjectApplications.Eof do
begin
taskApplicationOption := TTaskApplicationOption.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add(taskApplicationOption);
taskApplicationOption.name := apiDB.uqProjectApplicationsNAME.AsString;
Result.applicationOptions.Add(taskApplicationOption);
apiDB.uqProjectApplications.Next;
end;
end;
function TApiService.AddApplicationName(taskId: string; name: string): TTaskApplicationOptionsResponse;
var
projectId: string;
newName: string;
existingName: string;
begin
newName := Trim(name);
if newName = '' then
raise Exception.Create('Application name cannot be blank.');
projectId := FindProjectId(taskId);
if projectId = '' then
raise Exception.Create('Project not found for task.');
existingName := FindApplicationName(taskId, newName);
if existingName = '' then
begin
apiDB.uqApplicationInsert.Connection.StartTransaction;
try
apiDB.uqApplicationInsert.Close;
apiDB.uqApplicationInsert.ParamByName('PROJECT_ID').AsString := projectId;
apiDB.uqApplicationInsert.ParamByName('NAME').AsString := newName;
apiDB.uqApplicationInsert.ExecSQL;
apiDB.uqApplicationInsert.Connection.Commit;
except
on E: Exception do
begin
if apiDB.uqApplicationInsert.Connection.InTransaction then
apiDB.uqApplicationInsert.Connection.Rollback;
raise;
end;
end;
end;
Result := BuildApplicationOptionsResponse(taskId);
end;
function TApiService.RenameApplicationName(taskId: string; oldName: string; newName: string): TTaskApplicationOptionsResponse;
var
projectId: string;
oldApplicationId: Integer;
existingApplicationId: Integer;
trimmedOldName: string;
trimmedNewName: string;
begin
trimmedOldName := Trim(oldName);
trimmedNewName := Trim(newName);
if trimmedOldName = '' then
raise Exception.Create('Old application name cannot be blank.');
if trimmedNewName = '' then
raise Exception.Create('New application name cannot be blank.');
projectId := FindProjectId(taskId);
if projectId = '' then
raise Exception.Create('Project not found for task.');
oldApplicationId := FindApplicationId(taskId, trimmedOldName);
if oldApplicationId = 0 then
raise Exception.Create('Application name not found.');
existingApplicationId := FindApplicationId(taskId, trimmedNewName);
apiDB.uqApplicationRename.Connection.StartTransaction;
try
apiDB.uqRenameTaskItemApplication.Close;
apiDB.uqRenameTaskItemApplication.ParamByName('PROJECT_ID').AsString := projectId;
apiDB.uqRenameTaskItemApplication.ParamByName('OLD_NAME').AsString := trimmedOldName;
apiDB.uqRenameTaskItemApplication.ParamByName('NEW_NAME').AsString := trimmedNewName;
apiDB.uqRenameTaskItemApplication.ExecSQL;
if (existingApplicationId <> 0) and (existingApplicationId <> oldApplicationId) then
begin
apiDB.uqApplicationDelete.Close;
apiDB.uqApplicationDelete.ParamByName('TASK_ITEM_APPLICATION_ID').AsInteger := oldApplicationId;
apiDB.uqApplicationDelete.ParamByName('PROJECT_ID').AsString := projectId;
apiDB.uqApplicationDelete.ExecSQL;
end
else
begin
apiDB.uqApplicationRename.Close;
apiDB.uqApplicationRename.ParamByName('TASK_ITEM_APPLICATION_ID').AsInteger := oldApplicationId;
apiDB.uqApplicationRename.ParamByName('PROJECT_ID').AsString := projectId;
apiDB.uqApplicationRename.ParamByName('NEW_NAME').AsString := trimmedNewName;
apiDB.uqApplicationRename.ExecSQL;
end;
apiDB.uqApplicationRename.Connection.Commit;
except
on E: Exception do
begin
if apiDB.uqApplicationRename.Connection.InTransaction then
apiDB.uqApplicationRename.Connection.Rollback;
raise;
end;
end;
Result := BuildApplicationOptionsResponse(taskId);
end;
function TApiService.DeleteApplicationName(taskId: string; name: string): TTaskApplicationOptionsResponse;
var
projectId: string;
applicationId: Integer;
applicationName: string;
begin
projectId := FindProjectId(taskId);
if projectId = '' then
raise Exception.Create('Project not found for task.');
applicationId := FindApplicationId(taskId, name);
applicationName := FindApplicationName(taskId, name);
if applicationId = 0 then
raise Exception.Create('Application name not found.');
apiDB.uqApplicationDelete.Connection.StartTransaction;
try
apiDB.uqBlankTaskItemApplication.Close;
apiDB.uqBlankTaskItemApplication.ParamByName('PROJECT_ID').AsString := projectId;
apiDB.uqBlankTaskItemApplication.ParamByName('NAME').AsString := applicationName;
apiDB.uqBlankTaskItemApplication.ExecSQL;
apiDB.uqApplicationDelete.Close;
apiDB.uqApplicationDelete.ParamByName('TASK_ITEM_APPLICATION_ID').AsInteger := applicationId;
apiDB.uqApplicationDelete.ParamByName('PROJECT_ID').AsString := projectId;
apiDB.uqApplicationDelete.ExecSQL;
apiDB.uqApplicationDelete.Connection.Commit;
except
on E: Exception do
begin
if apiDB.uqApplicationDelete.Connection.InTransaction then
apiDB.uqApplicationDelete.Connection.Rollback;
raise;
end;
end;
Result := BuildApplicationOptionsResponse(taskId);
end;
initialization
RegisterServiceType(TypeInfo(IApiService));
RegisterServiceType(TApiService);
......
[Settings]
MemoLogLevel=4
FileLogLevel=4
webClientVersion=0.8.6
LogFileNum=152
webClientVersion=0.8.7
LogFileNum=155
[Database]
Server=192.168.116.131
Server=192.168.102.131
--Server=192.168.116.128
--Server=192.168.102.131
--Server=192.168.159.10
......
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{2A3028D9-BC39-4625-9BA5-0338012E2824}</ProjectGuid>
<ProjectVersion>20.4</ProjectVersion>
......@@ -114,10 +114,10 @@
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_ExeOutput>.\bin</DCC_ExeOutput>
<DCC_UnitSearchPath>C:\RADTOOLS\FastMM4;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_Keys>CompanyName=EM Systems;FileDescription=$(MSBuildProjectName);FileVersion=0.8.6.0;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.8.7.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=0.9.11;Comments=</VerInfo_Keys>
<VerInfo_MajorVer>0</VerInfo_MajorVer>
<VerInfo_MinorVer>8</VerInfo_MinorVer>
<VerInfo_Release>6</VerInfo_Release>
<VerInfo_Release>7</VerInfo_Release>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
......
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