Commit 4a314fa8 by Mac Stephens

v0.8.5 fixes Deployed 0.8.8

parent 071af034
...@@ -20,7 +20,7 @@ type ...@@ -20,7 +20,7 @@ type
FUnauthorizedAccessProc: TUnauthorizedAccessProc; FUnauthorizedAccessProc: TUnauthorizedAccessProc;
public public
const clientVersion = '0.8.7'; const clientVersion = '0.8.8';
procedure InitApp(SuccessProc: TSuccessProc; procedure InitApp(SuccessProc: TSuccessProc;
UnauthorizedAccessProc: TUnauthorizedAccessProc); UnauthorizedAccessProc: TUnauthorizedAccessProc);
procedure SetClientConfig(Callback: TVersionCheckCallback); procedure SetClientConfig(Callback: TVersionCheckCallback);
......
...@@ -14,6 +14,7 @@ procedure ShowToast(const MessageText: string; const ToastType: string = 'succes ...@@ -14,6 +14,7 @@ procedure ShowToast(const MessageText: string; const ToastType: string = 'succes
procedure ShowConfirmationModal(msg, leftLabel, rightLabel: string; ConfirmProc: TProc<Boolean>); procedure ShowConfirmationModal(msg, leftLabel, rightLabel: string; ConfirmProc: TProc<Boolean>);
procedure ShowNotificationModal(msg: string); procedure ShowNotificationModal(msg: string);
procedure ShowAppDialog(const Msg: string; const Title: string = 'emT3 web app'; ReloadOnClose: Boolean = False; ButtonText: string = 'Close'); procedure ShowAppDialog(const Msg: string; const Title: string = 'emT3 web app'; ReloadOnClose: Boolean = False; ButtonText: string = 'Close');
function NormalizeDateValue(const Value: string): string;
implementation implementation
...@@ -281,5 +282,22 @@ begin ...@@ -281,5 +282,22 @@ begin
end; end;
function NormalizeDateValue(const Value: string): string;
var
normalizedValue: string;
begin
normalizedValue := Trim(Value);
if (normalizedValue = '') or
SameText(normalizedValue, '1899-12-30') or
SameText(normalizedValue, '12/30/1899') or
SameText(normalizedValue, '1899-12-30T00:00:00') or
SameText(normalizedValue, '1899-12-30 00:00:00') then
Result := ''
else
Result := normalizedValue;
end;
end. end.
...@@ -62,6 +62,9 @@ input[data-field="itemNum"] { ...@@ -62,6 +62,9 @@ input[data-field="itemNum"] {
top: 0; top: 0;
z-index: 2; z-index: 2;
background: var(--bs-body-bg); background: var(--bs-body-bg);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
} }
.tasks-vscroll thead th.th-resize { .tasks-vscroll thead th.th-resize {
...@@ -86,7 +89,155 @@ span.card { ...@@ -86,7 +89,155 @@ span.card {
user-select: none; user-select: none;
} }
. test-test {} .tasks-table {
table-layout: fixed;
}
.tasks-table th {
overflow: hidden;
}
.tasks-table td {
overflow: visible;
}
.nowrap-cell,
.wrap-cell {
overflow: visible;
}
.tasks-table .dropdown,
.task-dd-toggle,
.task-dd-label,
.cell-input,
.cell-textarea {
min-width: 0;
}
.dropdown-menu {
z-index: 1055;
}
.task-dd-toggle.status-cannot-duplicate {
--bs-btn-color: #41464b;
--bs-btn-bg: #e2e3e5;
--bs-btn-border-color: #c4c8cb;
--bs-btn-hover-color: #41464b;
--bs-btn-hover-bg: #d3d4d5;
--bs-btn-hover-border-color: #b9bcc0;
--bs-btn-active-color: #41464b;
--bs-btn-active-bg: #c6c7c8;
--bs-btn-active-border-color: #b9bcc0;
}
.task-dd-toggle.status-cannot-test {
--bs-btn-color: #842029;
--bs-btn-bg: #f8d7da;
--bs-btn-border-color: #f1aeb5;
--bs-btn-hover-color: #842029;
--bs-btn-hover-bg: #f1c2c7;
--bs-btn-hover-border-color: #ea9ca6;
--bs-btn-active-color: #842029;
--bs-btn-active-bg: #eaadb5;
--bs-btn-active-border-color: #e68592;
}
.task-dd-toggle.status-future-enhancement {
--bs-btn-color: #055160;
--bs-btn-bg: #cff4fc;
--bs-btn-border-color: #9eeaf9;
--bs-btn-hover-color: #055160;
--bs-btn-hover-bg: #b6effb;
--bs-btn-hover-border-color: #86e5f8;
--bs-btn-active-color: #055160;
--bs-btn-active-bg: #9eeaf9;
--bs-btn-active-border-color: #74dff6;
}
.task-dd-toggle.status-fixed-verified {
--bs-btn-color: #0f5132;
--bs-btn-bg: #d1e7dd;
--bs-btn-border-color: #a3cfbb;
--bs-btn-hover-color: #0f5132;
--bs-btn-hover-bg: #badbcc;
--bs-btn-hover-border-color: #8fc5a9;
--bs-btn-active-color: #0f5132;
--bs-btn-active-bg: #a3cfbb;
--bs-btn-active-border-color: #7db89d;
}
.task-dd-toggle.status-fixed {
--bs-btn-color: #146c43;
--bs-btn-bg: #d1e7dd;
--bs-btn-border-color: #a3cfbb;
--bs-btn-hover-color: #146c43;
--bs-btn-hover-bg: #badbcc;
--bs-btn-hover-border-color: #8fc5a9;
--bs-btn-active-color: #146c43;
--bs-btn-active-bg: #a3cfbb;
--bs-btn-active-border-color: #7db89d;
}
.task-dd-toggle.status-investigating {
--bs-btn-color: #664d03;
--bs-btn-bg: #fff3cd;
--bs-btn-border-color: #ffe69c;
--bs-btn-hover-color: #664d03;
--bs-btn-hover-bg: #ffecb5;
--bs-btn-hover-border-color: #ffdf7e;
--bs-btn-active-color: #664d03;
--bs-btn-active-bg: #ffe69c;
--bs-btn-active-border-color: #ffd966;
}
.task-dd-toggle.status-not-fixed {
--bs-btn-color: #842029;
--bs-btn-bg: #f8d7da;
--bs-btn-border-color: #f1aeb5;
--bs-btn-hover-color: #842029;
--bs-btn-hover-bg: #f1c2c7;
--bs-btn-hover-border-color: #ea9ca6;
--bs-btn-active-color: #842029;
--bs-btn-active-bg: #eaadb5;
--bs-btn-active-border-color: #e68592;
}
.task-dd-toggle.status-non-issue {
--bs-btn-color: #432874;
--bs-btn-bg: #e2d9f3;
--bs-btn-border-color: #cbbbe8;
--bs-btn-hover-color: #432874;
--bs-btn-hover-bg: #d6caee;
--bs-btn-hover-border-color: #bea9e2;
--bs-btn-active-color: #432874;
--bs-btn-active-bg: #cbbbe8;
--bs-btn-active-border-color: #b89ddd;
}
.task-dd-toggle.status-possibly-a-problem {
--bs-btn-color: #7a3e00;
--bs-btn-bg: #ffe5d0;
--bs-btn-border-color: #f7c79d;
--bs-btn-hover-color: #7a3e00;
--bs-btn-hover-bg: #ffd7b8;
--bs-btn-hover-border-color: #f2ba88;
--bs-btn-active-color: #7a3e00;
--bs-btn-active-bg: #f7c79d;
--bs-btn-active-border-color: #eeaf69;
}
.task-dd-toggle.status-default {
--bs-btn-color: #212529;
--bs-btn-bg: #f8f9fa;
--bs-btn-border-color: #dee2e6;
--bs-btn-hover-color: #212529;
--bs-btn-hover-bg: #e9ecef;
--bs-btn-hover-border-color: #ced4da;
--bs-btn-active-color: #212529;
--bs-btn-active-bg: #dee2e6;
--bs-btn-active-border-color: #ced4da;
}
...@@ -12,7 +12,8 @@ uses ...@@ -12,7 +12,8 @@ uses
View.Main in 'View.Main.pas' {FViewMain: TWebForm} {*.html}, View.Main in 'View.Main.pas' {FViewMain: TWebForm} {*.html},
Utils in 'Utils.pas', Utils in 'Utils.pas',
View.TaskItems in 'View.TaskItems.pas' {FTaskItems: TWebForm} {*.html}, View.TaskItems in 'View.TaskItems.pas' {FTaskItems: TWebForm} {*.html},
uNameManager in 'uNameManager.pas'; uNameOffCanvas in 'uNameOffCanvas.pas',
uDropdownHelpers in 'uDropdownHelpers.pas';
{$R *.res} {$R *.res}
......
...@@ -94,12 +94,12 @@ ...@@ -94,12 +94,12 @@
<DCC_RemoteDebug>false</DCC_RemoteDebug> <DCC_RemoteDebug>false</DCC_RemoteDebug>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale> <VerInfo_Locale>1033</VerInfo_Locale>
<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> <VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=0.8.8.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> <AppDPIAwarenessMode>PerMonitor</AppDPIAwarenessMode>
<VerInfo_MajorVer>0</VerInfo_MajorVer> <VerInfo_MajorVer>0</VerInfo_MajorVer>
<VerInfo_MinorVer>8</VerInfo_MinorVer> <VerInfo_MinorVer>8</VerInfo_MinorVer>
<VerInfo_Release>7</VerInfo_Release> <VerInfo_Release>8</VerInfo_Release>
<TMSWebBrowser>1</TMSWebBrowser> <TMSWebBrowser>5</TMSWebBrowser>
<TMSUseJSDebugger>2</TMSUseJSDebugger> <TMSUseJSDebugger>2</TMSUseJSDebugger>
<TMSWebSingleInstance>1</TMSWebSingleInstance> <TMSWebSingleInstance>1</TMSWebSingleInstance>
<TMSWebOutputPath>..\emT3XDataServer\bin\static</TMSWebOutputPath> <TMSWebOutputPath>..\emT3XDataServer\bin\static</TMSWebOutputPath>
...@@ -142,7 +142,8 @@ ...@@ -142,7 +142,8 @@
<FormType>dfm</FormType> <FormType>dfm</FormType>
<DesignClass>TWebForm</DesignClass> <DesignClass>TWebForm</DesignClass>
</DCCReference> </DCCReference>
<DCCReference Include="uNameManager.pas"/> <DCCReference Include="uNameOffCanvas.pas"/>
<DCCReference Include="uDropdownHelpers.pas"/>
<None Include="index.html"/> <None Include="index.html"/>
<None Include="css\app.css"/> <None Include="css\app.css"/>
<None Include="config\config.json"/> <None Include="config\config.json"/>
......
unit uDropdownHelpers;
interface
uses
System.SysUtils, System.Classes, JS, Web,
WEBLib.Graphics, WEBLib.Controls, WEBLib.Forms, WEBLib.Dialogs;
function GetTaskStatusClass(const AStatus: string): string;
procedure ClearTaskStatusClasses(const AElement: TJSHTMLElement);
procedure ApplyTaskStatusClass(const AElement: TJSHTMLElement; const AStatus: string);
function ExtractOptionNames(const SourceArray: TJSArray): TJSArray;
function ExtractCodeDescs(const SourceArray: TJSArray): TJSArray;
function ExtractAssignedOptionNames(const ResponseResult: TJSObject): TJSArray;
function ExtractReportedOptionNames(const ResponseResult: TJSObject): TJSArray;
function ExtractApplicationOptionNames(const ResponseResult: TJSObject): TJSArray;
function FindOptionIgnoreCase(const AItems: TJSArray; const AName: string): string;
function GetOptionsForField(const AFieldName: string; const AApplicationOptions, AReportedByOptions, AAssignedToOptions: TJSArray): TJSArray;
procedure FocusTrigger(const ATriggerId: string);
implementation
function GetTaskStatusClass(const AStatus: string): string;
var
statusText: string;
begin
statusText := Trim(AStatus);
if SameText(statusText, 'Cannot Duplicate') then
Result := 'status-cannot-duplicate'
else if SameText(statusText, 'Cannot Test') then
Result := 'status-cannot-test'
else if SameText(statusText, 'Future Enhancement') then
Result := 'status-future-enhancement'
else if SameText(statusText, 'Fixed - Verified') then
Result := 'status-fixed-verified'
else if SameText(statusText, 'Fixed') then
Result := 'status-fixed'
else if SameText(statusText, 'Investigating') then
Result := 'status-investigating'
else if SameText(statusText, 'Not Fixed') then
Result := 'status-not-fixed'
else if SameText(statusText, 'Non-Issue') then
Result := 'status-non-issue'
else if SameText(statusText, 'Possibly a Problem') then
Result := 'status-possibly-a-problem'
else
Result := 'status-default';
end;
procedure ClearTaskStatusClasses(const AElement: TJSHTMLElement);
begin
if not Assigned(AElement) then
Exit;
AElement.classList.remove('status-cannot-duplicate');
AElement.classList.remove('status-cannot-test');
AElement.classList.remove('status-future-enhancement');
AElement.classList.remove('status-fixed-verified');
AElement.classList.remove('status-fixed');
AElement.classList.remove('status-investigating');
AElement.classList.remove('status-not-fixed');
AElement.classList.remove('status-non-issue');
AElement.classList.remove('status-possibly-a-problem');
AElement.classList.remove('status-default');
end;
procedure ApplyTaskStatusClass(const AElement: TJSHTMLElement; const AStatus: string);
begin
if not Assigned(AElement) then
Exit;
ClearTaskStatusClasses(AElement);
AElement.classList.add(GetTaskStatusClass(AStatus));
end;
function ExtractOptionNames(const SourceArray: TJSArray): TJSArray;
var
i: Integer;
optionObj: TJSObject;
begin
Result := TJSArray.new;
if not Assigned(SourceArray) then
Exit;
for i := 0 to SourceArray.length - 1 do
begin
optionObj := TJSObject(SourceArray[i]);
if Assigned(optionObj) then
Result.push(string(optionObj['name']));
end;
end;
function ExtractCodeDescs(const SourceArray: TJSArray): TJSArray;
var
i: Integer;
optionObj: TJSObject;
begin
Result := TJSArray.new;
if not Assigned(SourceArray) then
Exit;
for i := 0 to SourceArray.length - 1 do
begin
optionObj := TJSObject(SourceArray[i]);
if Assigned(optionObj) then
Result.push(string(optionObj['codeDesc']));
end;
end;
function ExtractAssignedOptionNames(const ResponseResult: TJSObject): TJSArray;
begin
if not Assigned(ResponseResult) then
Exit(TJSArray.new);
Result := ExtractOptionNames(TJSArray(ResponseResult['assignedToOptions']));
end;
function ExtractReportedOptionNames(const ResponseResult: TJSObject): TJSArray;
begin
if not Assigned(ResponseResult) then
Exit(TJSArray.new);
Result := ExtractOptionNames(TJSArray(ResponseResult['reportedByOptions']));
end;
function ExtractApplicationOptionNames(const ResponseResult: TJSObject): TJSArray;
begin
if not Assigned(ResponseResult) then
Exit(TJSArray.new);
Result := ExtractOptionNames(TJSArray(ResponseResult['applicationOptions']));
end;
function 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;
function GetOptionsForField(const AFieldName: string; const AApplicationOptions, AReportedByOptions, AAssignedToOptions: TJSArray): TJSArray;
begin
if SameText(AFieldName, 'application') then
Result := AApplicationOptions
else if SameText(AFieldName, 'reportedBy') then
Result := AReportedByOptions
else if SameText(AFieldName, 'assignedTo') then
Result := AAssignedToOptions
else
Result := nil;
end;
procedure FocusTrigger(const ATriggerId: string);
var
el: TJSHTMLElement;
begin
if ATriggerId = '' then
Exit;
el := TJSHTMLElement(document.getElementById(ATriggerId));
if Assigned(el) then
el.focus;
end;
end.
unit uNameManager; unit uNameOffCanvas;
interface interface
...@@ -257,7 +257,7 @@ begin ...@@ -257,7 +257,7 @@ begin
Exit; Exit;
end; end;
if not (SameText(FCurrentField, 'assignedTo') or SameText(FCurrentField, 'application')) then if not (SameText(FCurrentField, 'assignedTo') or SameText(FCurrentField, 'application') or SameText(FCurrentField, 'reportedBy')) then
Exit; Exit;
if FCurrentEditName <> '' then if FCurrentEditName <> '' then
...@@ -356,7 +356,7 @@ begin ...@@ -356,7 +356,7 @@ begin
Event.preventDefault; Event.preventDefault;
Event.stopPropagation; Event.stopPropagation;
if not (SameText(FCurrentField, 'assignedTo') or SameText(FCurrentField, 'application')) then if not (SameText(FCurrentField, 'assignedTo') or SameText(FCurrentField, 'application') or SameText(FCurrentField, 'reportedBy')) then
Exit; Exit;
el := TJSHTMLElement(Event.currentTarget); el := TJSHTMLElement(Event.currentTarget);
...@@ -383,7 +383,7 @@ begin ...@@ -383,7 +383,7 @@ begin
Event.preventDefault; Event.preventDefault;
Event.stopPropagation; Event.stopPropagation;
if not (SameText(FCurrentField, 'assignedTo') or SameText(FCurrentField, 'application')) then if not (SameText(FCurrentField, 'assignedTo') or SameText(FCurrentField, 'application') or SameText(FCurrentField, 'reportedBy')) then
Exit; Exit;
el := TJSHTMLElement(Event.currentTarget); el := TJSHTMLElement(Event.currentTarget);
...@@ -401,7 +401,7 @@ procedure TNameManager.OpenManager(const AFieldName: string; const ARowIndex: In ...@@ -401,7 +401,7 @@ procedure TNameManager.OpenManager(const AFieldName: string; const ARowIndex: In
var var
titleEl: TJSHTMLElement; titleEl: TJSHTMLElement;
begin begin
if not (SameText(AFieldName, 'assignedTo') or SameText(AFieldName, 'application')) then if not (SameText(AFieldName, 'assignedTo') or SameText(AFieldName, 'application') or SameText(AFieldName, 'reportedBy')) then
Exit; Exit;
FCurrentField := AFieldName; FCurrentField := AFieldName;
...@@ -414,6 +414,8 @@ begin ...@@ -414,6 +414,8 @@ begin
begin begin
if SameText(AFieldName, 'application') then if SameText(AFieldName, 'application') then
titleEl.innerHTML := 'Manage Application' titleEl.innerHTML := 'Manage Application'
else if SameText(AFieldName, 'reportedBy') then
titleEl.innerHTML := 'Manage Reported By'
else else
titleEl.innerHTML := 'Manage Assigned To'; titleEl.innerHTML := 'Manage Assigned To';
end; end;
......
object ApiDatabase: TApiDatabase object ApiDatabase: TApiDatabase
OnCreate = DataModuleCreate OnCreate = DataModuleCreate
Height = 475 Height = 475
Width = 803 Width = 996
object ucETaskApi: TUniConnection object ucETaskApi: TUniConnection
AutoCommit = False AutoCommit = False
ProviderName = 'MySQL' ProviderName = 'MySQL'
...@@ -236,17 +236,17 @@ object ApiDatabase: TApiDatabase ...@@ -236,17 +236,17 @@ object ApiDatabase: TApiDatabase
'values (' 'values ('
' :TASK_ID,' ' :TASK_ID,'
' :ITEM_NUM,' ' :ITEM_NUM,'
' '#39#39',' ' null,'
' '#39#39',' ' null,'
' curdate(),' ' null,'
' curdate(),' ' null,'
' '#39#39',' ' null,'
' '#39#39',' ' null,'
' '#39#39',' ' null,'
' '#39#39',' ' null,'
' '#39#39',' ' null,'
' '#39#39',' ' null,'
' '#39#39 ' null'
')') ')')
Left = 536 Left = 536
Top = 282 Top = 282
...@@ -580,7 +580,8 @@ object ApiDatabase: TApiDatabase ...@@ -580,7 +580,8 @@ object ApiDatabase: TApiDatabase
object uqProjectReportedUsers: TUniQuery object uqProjectReportedUsers: TUniQuery
Connection = ucETaskApi Connection = ucETaskApi
SQL.Strings = ( SQL.Strings = (
'select distinct' 'select'
' min(tiu.TASK_ITEM_USER_ID) as TASK_ITEM_USER_ID,'
' tiu.NAME' ' tiu.NAME'
'from task_item_user tiu' 'from task_item_user tiu'
'join tasks project_tasks' 'join tasks project_tasks'
...@@ -589,6 +590,7 @@ object ApiDatabase: TApiDatabase ...@@ -589,6 +590,7 @@ object ApiDatabase: TApiDatabase
' on target_task.PROJECT_ID = project_tasks.PROJECT_ID' ' on target_task.PROJECT_ID = project_tasks.PROJECT_ID'
'where target_task.TASK_ID = :TASK_ID' 'where target_task.TASK_ID = :TASK_ID'
' and tiu.USER_TYPE = '#39'Reported'#39 ' and tiu.USER_TYPE = '#39'Reported'#39
'group by tiu.NAME'
'order by tiu.NAME') 'order by tiu.NAME')
Left = 58 Left = 58
Top = 256 Top = 256
...@@ -598,6 +600,11 @@ object ApiDatabase: TApiDatabase ...@@ -598,6 +600,11 @@ object ApiDatabase: TApiDatabase
Name = 'TASK_ID' Name = 'TASK_ID'
Value = nil Value = nil
end> end>
object uqProjectReportedUsersTASK_ITEM_USER_ID: TStringField
FieldName = 'TASK_ITEM_USER_ID'
ReadOnly = True
Size = 50
end
object uqProjectReportedUsersNAME: TStringField object uqProjectReportedUsersNAME: TStringField
FieldName = 'NAME' FieldName = 'NAME'
Required = True Required = True
...@@ -758,7 +765,7 @@ object ApiDatabase: TApiDatabase ...@@ -758,7 +765,7 @@ object ApiDatabase: TApiDatabase
Connection = ucETaskApi Connection = ucETaskApi
SQL.Strings = ( SQL.Strings = (
'update task_items' 'update task_items'
'set ASSIGNED_TO = '#39#39 'set ASSIGNED_TO = null'
'where TASK_ID = :TASK_ID' 'where TASK_ID = :TASK_ID'
' and lower(ASSIGNED_TO) = lower(:NAME)') ' and lower(ASSIGNED_TO) = lower(:NAME)')
Left = 388 Left = 388
...@@ -914,7 +921,7 @@ object ApiDatabase: TApiDatabase ...@@ -914,7 +921,7 @@ object ApiDatabase: TApiDatabase
'update task_items ti' 'update task_items ti'
'join tasks t' 'join tasks t'
' on t.TASK_ID = ti.TASK_ID' ' on t.TASK_ID = ti.TASK_ID'
'set ti.APPLICATION = '#39#39 'set ti.APPLICATION = null'
'where t.PROJECT_ID = :PROJECT_ID' 'where t.PROJECT_ID = :PROJECT_ID'
' and lower(ti.APPLICATION) = lower(:NAME)') ' and lower(ti.APPLICATION) = lower(:NAME)')
Left = 696 Left = 696
...@@ -931,4 +938,150 @@ object ApiDatabase: TApiDatabase ...@@ -931,4 +938,150 @@ object ApiDatabase: TApiDatabase
Value = nil Value = nil
end> end>
end end
object uqReportedInsert: TUniQuery
Connection = ucETaskApi
SQL.Strings = (
'insert into task_item_user ('
' TASK_ITEM_USER_ID,'
' TASK_ID,'
' USER_TYPE,'
' NAME'
')'
'values ('
' :TASK_ITEM_USER_ID,'
' :TASK_ID,'
' '#39'Reported'#39','
' :NAME'
')')
Left = 858
Top = 32
ParamData = <
item
DataType = ftUnknown
Name = 'TASK_ITEM_USER_ID'
Value = nil
end
item
DataType = ftUnknown
Name = 'TASK_ID'
Value = nil
end
item
DataType = ftUnknown
Name = 'NAME'
Value = nil
end>
end
object uqReportedRename: TUniQuery
Connection = ucETaskApi
SQL.Strings = (
'update task_item_user tiu'
'join tasks t'
' on t.TASK_ID = tiu.TASK_ID'
'join tasks target_task'
' on target_task.PROJECT_ID = t.PROJECT_ID'
'set tiu.NAME = :NEW_NAME'
'where target_task.TASK_ID = :TASK_ID'
' and tiu.USER_TYPE = '#39'Reported'#39
' and tiu.TASK_ITEM_USER_ID = :TASK_ITEM_USER_ID')
Left = 858
Top = 88
ParamData = <
item
DataType = ftUnknown
Name = 'NEW_NAME'
Value = nil
end
item
DataType = ftUnknown
Name = 'TASK_ID'
Value = nil
end
item
DataType = ftUnknown
Name = 'TASK_ITEM_USER_ID'
Value = nil
end>
end
object uqReportedDelete: TUniQuery
Connection = ucETaskApi
SQL.Strings = (
'delete tiu'
'from task_item_user tiu'
'join tasks t'
' on t.TASK_ID = tiu.TASK_ID'
'join tasks target_task'
' on target_task.PROJECT_ID = t.PROJECT_ID'
'where target_task.TASK_ID = :TASK_ID'
' and tiu.USER_TYPE = '#39'Reported'#39
' and tiu.TASK_ITEM_USER_ID = :TASK_ITEM_USER_ID')
Left = 858
Top = 144
ParamData = <
item
DataType = ftUnknown
Name = 'TASK_ID'
Value = nil
end
item
DataType = ftUnknown
Name = 'TASK_ITEM_USER_ID'
Value = nil
end>
end
object uqBlankTaskItemReportedBy: TUniQuery
Connection = ucETaskApi
SQL.Strings = (
'update task_items ti'
'join tasks t'
' on t.TASK_ID = ti.TASK_ID'
'join tasks target_task'
' on target_task.PROJECT_ID = t.PROJECT_ID'
'set ti.REPORTED_BY = null'
'where target_task.TASK_ID = :TASK_ID'
' and lower(ti.REPORTED_BY) = lower(:NAME)')
Left = 860
Top = 264
ParamData = <
item
DataType = ftUnknown
Name = 'TASK_ID'
Value = nil
end
item
DataType = ftUnknown
Name = 'NAME'
Value = nil
end>
end
object uqRenameTaskItemReportedBy: TUniQuery
Connection = ucETaskApi
SQL.Strings = (
'update task_items ti'
'join tasks t'
' on t.TASK_ID = ti.TASK_ID'
'join tasks target_task'
' on target_task.PROJECT_ID = t.PROJECT_ID'
'set ti.REPORTED_BY = :NEW_NAME'
'where target_task.TASK_ID = :TASK_ID'
' and lower(ti.REPORTED_BY) = lower(:OLD_NAME)')
Left = 858
Top = 202
ParamData = <
item
DataType = ftUnknown
Name = 'NEW_NAME'
Value = nil
end
item
DataType = ftUnknown
Name = 'TASK_ID'
Value = nil
end
item
DataType = ftUnknown
Name = 'OLD_NAME'
Value = nil
end>
end
end end
...@@ -68,7 +68,6 @@ type ...@@ -68,7 +68,6 @@ type
uqAssignedDelete: TUniQuery; uqAssignedDelete: TUniQuery;
uqRenameAssignedTo: TUniQuery; uqRenameAssignedTo: TUniQuery;
uqBlankAssignedTo: TUniQuery; uqBlankAssignedTo: TUniQuery;
uqProjectReportedUsersNAME: TStringField;
uqTaskAssignedUsersTASK_ITEM_USER_ID: TStringField; uqTaskAssignedUsersTASK_ITEM_USER_ID: TStringField;
uqTaskAssignedUsersTASK_ID: TStringField; uqTaskAssignedUsersTASK_ID: TStringField;
uqTaskAssignedUsersUSER_TYPE: TStringField; uqTaskAssignedUsersUSER_TYPE: TStringField;
...@@ -82,6 +81,13 @@ type ...@@ -82,6 +81,13 @@ type
uqProjectApplicationsTASK_ITEM_APPLICATION_ID: TIntegerField; uqProjectApplicationsTASK_ITEM_APPLICATION_ID: TIntegerField;
uqProjectApplicationsPROJECT_ID: TStringField; uqProjectApplicationsPROJECT_ID: TStringField;
uqProjectApplicationsNAME: TStringField; uqProjectApplicationsNAME: TStringField;
uqReportedInsert: TUniQuery;
uqReportedRename: TUniQuery;
uqReportedDelete: TUniQuery;
uqBlankTaskItemReportedBy: TUniQuery;
uqRenameTaskItemReportedBy: TUniQuery;
uqProjectReportedUsersTASK_ITEM_USER_ID: TStringField;
uqProjectReportedUsersNAME: TStringField;
procedure DataModuleCreate(Sender: TObject); procedure DataModuleCreate(Sender: TObject);
procedure uqUsersCalcFields(DataSet: TDataSet); procedure uqUsersCalcFields(DataSet: TDataSet);
private private
......
...@@ -76,6 +76,7 @@ type ...@@ -76,6 +76,7 @@ type
TTaskUserOptionsResponse = class TTaskUserOptionsResponse = class
public public
assignedToOptions: TList<TTaskUserOption>; assignedToOptions: TList<TTaskUserOption>;
reportedByOptions: TList<TTaskUserOption>;
constructor Create; constructor Create;
destructor Destroy; override; destructor Destroy; override;
end; end;
...@@ -105,21 +106,37 @@ type ...@@ -105,21 +106,37 @@ type
notes: string; notes: string;
end; end;
TTaskItemFieldSave = class
public
taskItemId: Integer;
fieldName: string;
value: string;
end;
type type
[ServiceContract, Model(API_MODEL)] [ServiceContract, Model(API_MODEL)]
IApiService = interface(IInvokable) IApiService = interface(IInvokable)
['{0EFB33D7-8C4C-4F3C-9BC3-8B4D444B5F69}'] ['{0EFB33D7-8C4C-4F3C-9BC3-8B4D444B5F69}']
function GetTaskItems(taskId: string): TTaskItemsResponse; function GetTaskItems(taskId: string): TTaskItemsResponse;
[HttpPost] function AddTaskRow(taskId: string; insertAfterItemNum: Integer): Boolean; [HttpPost] function AddTaskRow(taskId: string; insertAfterItemNum: Integer): Boolean;
[HttpPost] function SaveTaskRow(Item: TTaskRowSave): Boolean;
[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;
[HttpPost] function DeleteAssignedName(taskId: string; name: string): TTaskUserOptionsResponse; [HttpPost] function DeleteAssignedName(taskId: string; name: string): TTaskUserOptionsResponse;
[HttpPost] function AddReportedName(taskId: string; name: string): TTaskUserOptionsResponse;
[HttpPost]function RenameReportedName(taskId: string; oldName: string; newName: string): TTaskUserOptionsResponse;
[HttpPost]function DeleteReportedName(taskId: string; name: string): TTaskUserOptionsResponse;
[HttpPost] function AddApplicationName(taskId: string; name: string): TTaskApplicationOptionsResponse; [HttpPost] function AddApplicationName(taskId: string; name: string): TTaskApplicationOptionsResponse;
[HttpPost] function RenameApplicationName(taskId: string; oldName: string; newName: string): TTaskApplicationOptionsResponse; [HttpPost] function RenameApplicationName(taskId: string; oldName: string; newName: string): TTaskApplicationOptionsResponse;
[HttpPost] function DeleteApplicationName(taskId: string; name: string): TTaskApplicationOptionsResponse; [HttpPost] function DeleteApplicationName(taskId: string; name: string): TTaskApplicationOptionsResponse;
procedure MoveTaskRow(const taskId: Integer; const taskItemId: Integer; const newItemNum: Integer); procedure MoveTaskRow(const taskId: Integer; const taskItemId: Integer; const newItemNum: Integer);
function DeleteTaskRow(const taskId: Integer; const taskItemId: Integer): Boolean; function DeleteTaskRow(const taskId: Integer; const taskItemId: Integer): Boolean;
function SaveTaskItemField(const Item: TTaskItemFieldSave): Boolean;
end; end;
implementation implementation
...@@ -148,11 +165,13 @@ constructor TTaskUserOptionsResponse.Create; ...@@ -148,11 +165,13 @@ constructor TTaskUserOptionsResponse.Create;
begin begin
inherited; inherited;
assignedToOptions := TList<TTaskUserOption>.Create; assignedToOptions := TList<TTaskUserOption>.Create;
reportedByOptions := TList<TTaskUserOption>.Create;
end; end;
destructor TTaskUserOptionsResponse.Destroy; destructor TTaskUserOptionsResponse.Destroy;
begin begin
assignedToOptions.Free; assignedToOptions := TList<TTaskUserOption>.Create;
reportedByOptions := TList<TTaskUserOption>.Create;
inherited; inherited;
end; end;
......
[Settings] [Settings]
MemoLogLevel=4 MemoLogLevel=4
FileLogLevel=4 FileLogLevel=4
webClientVersion=0.8.7 webClientVersion=0.8.8
LogFileNum=155 LogFileNum=160
[Database] [Database]
Server=192.168.102.131 Server=192.168.102.131
......
...@@ -114,10 +114,10 @@ ...@@ -114,10 +114,10 @@
<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.8.7.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.8.0;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>8</VerInfo_MinorVer> <VerInfo_MinorVer>8</VerInfo_MinorVer>
<VerInfo_Release>7</VerInfo_Release> <VerInfo_Release>8</VerInfo_Release>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''"> <PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode> <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