Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
emT3web
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Mac Stephens
emT3web
Commits
0b6d8acf
Commit
0b6d8acf
authored
Aug 24, 2026
by
Mac Stephens
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update Time Entries routing, optional date login, row actions, and copy entry support
parent
074ca098
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
188 additions
and
53 deletions
+188
-53
Auth.Service.pas
emT3Web/Auth.Service.pas
+8
-1
View.Login.pas
emT3Web/View.Login.pas
+11
-3
View.Main.pas
emT3Web/View.Main.pas
+6
-1
View.TimeEntries.dfm
emT3Web/View.TimeEntries.dfm
+14
-0
View.TimeEntries.html
emT3Web/View.TimeEntries.html
+4
-10
View.TimeEntries.pas
emT3Web/View.TimeEntries.pas
+134
-35
emT3web.dpr
emT3Web/emT3web.dpr
+10
-2
emT3XDataServer.ini
emT3XDataServer/bin/emT3XDataServer.ini
+1
-1
No files found.
emT3Web/Auth.Service.pas
View file @
0b6d8acf
...
@@ -142,7 +142,13 @@ var
...
@@ -142,7 +142,13 @@ var
end
;
end
;
begin
begin
if
(
AUserName
=
''
)
or
(
ALoginType
=
''
)
or
(
ALoginValue
=
''
)
or
(
APassword
=
''
)
then
if
(
AUserName
=
''
)
or
(
ALoginType
=
''
)
or
(
APassword
=
''
)
then
begin
AError
(
'Please enter all required login fields.'
);
Exit
;
end
;
if
SameText
(
ALoginType
,
'task_items'
)
and
(
ALoginValue
=
''
)
then
begin
begin
AError
(
'Please enter all required login fields.'
);
AError
(
'Please enter all required login fields.'
);
Exit
;
Exit
;
...
@@ -166,6 +172,7 @@ procedure TAuthService.Logout;
...
@@ -166,6 +172,7 @@ procedure TAuthService.Logout;
begin
begin
DeleteToken
;
DeleteToken
;
DMConnection
.
currentTaskId
:=
''
;
DMConnection
.
currentTaskId
:=
''
;
DMConnection
.
currentTimeEntryDate
:=
''
;
end
;
end
;
procedure
TAuthService
.
SetToken
(
AToken
:
string
);
procedure
TAuthService
.
SetToken
(
AToken
:
string
);
...
...
emT3Web/View.Login.pas
View file @
0b6d8acf
...
@@ -51,10 +51,11 @@ procedure TFViewLogin.btnLoginClick(Sender: TObject);
...
@@ -51,10 +51,11 @@ procedure TFViewLogin.btnLoginClick(Sender: TObject);
var
var
timeEntriesParam
:
string
;
timeEntriesParam
:
string
;
newUrl
:
string
;
newUrl
:
string
;
isTimeEntriesMode
:
Boolean
;
procedure
LoginSuccess
;
procedure
LoginSuccess
;
begin
begin
if
SameText
(
timeEntriesParam
,
'true'
)
then
if
isTimeEntriesMode
then
begin
begin
DMConnection
.
currentTaskId
:=
''
;
DMConnection
.
currentTaskId
:=
''
;
DMConnection
.
currentTimeEntryDate
:=
edtDate
.
Text
;
DMConnection
.
currentTimeEntryDate
:=
edtDate
.
Text
;
...
@@ -79,8 +80,11 @@ var
...
@@ -79,8 +80,11 @@ var
begin
begin
timeEntriesParam
:=
Application
.
Parameters
.
Values
[
'time_entries'
];
timeEntriesParam
:=
Application
.
Parameters
.
Values
[
'time_entries'
];
isTimeEntriesMode
:=
SameText
(
timeEntriesParam
,
'true'
)
or
(
Application
.
Parameters
.
Values
[
'task_id'
]
=
''
);
if
SameText
(
timeEntriesParam
,
'true'
)
then
if
isTimeEntriesMode
then
begin
begin
AuthService
.
WebLogin
(
AuthService
.
WebLogin
(
edtUsername
.
Text
,
edtUsername
.
Text
,
...
@@ -149,16 +153,20 @@ end;
...
@@ -149,16 +153,20 @@ end;
procedure
TFViewLogin
.
WebFormCreate
(
Sender
:
TObject
);
procedure
TFViewLogin
.
WebFormCreate
(
Sender
:
TObject
);
var
var
timeEntriesParam
:
string
;
timeEntriesParam
:
string
;
isTimeEntriesMode
:
Boolean
;
begin
begin
console
.
log
(
'TFViewLogin.WebFormCreate FUserId='
+
FUserId
+
' FTaskId='
+
FTaskId
+
' FMessage='
+
FMessage
);
console
.
log
(
'TFViewLogin.WebFormCreate FUserId='
+
FUserId
+
' FTaskId='
+
FTaskId
+
' FMessage='
+
FMessage
);
timeEntriesParam
:=
Application
.
Parameters
.
Values
[
'time_entries'
];
timeEntriesParam
:=
Application
.
Parameters
.
Values
[
'time_entries'
];
isTimeEntriesMode
:=
SameText
(
timeEntriesParam
,
'true'
)
or
(
Application
.
Parameters
.
Values
[
'task_id'
]
=
''
);
edtUsername
.
Text
:=
FUserId
;
edtUsername
.
Text
:=
FUserId
;
edtTaskId
.
Text
:=
FTaskId
;
edtTaskId
.
Text
:=
FTaskId
;
edtDate
.
Text
:=
Application
.
Parameters
.
Values
[
'date'
];
edtDate
.
Text
:=
Application
.
Parameters
.
Values
[
'date'
];
if
SameText
(
timeEntriesParam
,
'true'
)
then
if
isTimeEntriesMode
then
begin
begin
WebLabel1
.
Caption
:=
'Time Entries Sign In'
;
WebLabel1
.
Caption
:=
'Time Entries Sign In'
;
TJSHTMLElement
(
document
.
getElementById
(
'view.login.taskid.group'
)).
classList
.
add
(
'd-none'
);
TJSHTMLElement
(
document
.
getElementById
(
'view.login.taskid.group'
)).
classList
.
add
(
'd-none'
);
...
...
emT3Web/View.Main.pas
View file @
0b6d8acf
...
@@ -43,12 +43,17 @@ uses
...
@@ -43,12 +43,17 @@ uses
procedure
TFViewMain
.
WebFormCreate
(
Sender
:
TObject
);
procedure
TFViewMain
.
WebFormCreate
(
Sender
:
TObject
);
var
var
userName
:
string
;
userName
:
string
;
isTimeEntriesMode
:
Boolean
;
begin
begin
userName
:=
JS
.
toString
(
AuthService
.
TokenPayload
.
Properties
[
'user_name'
]);
userName
:=
JS
.
toString
(
AuthService
.
TokenPayload
.
Properties
[
'user_name'
]);
lblUsername
.
Caption
:=
userName
;
lblUsername
.
Caption
:=
userName
;
lblVersion
.
Caption
:=
'v'
+
DMConnection
.
clientVersion
;
lblVersion
.
Caption
:=
'v'
+
DMConnection
.
clientVersion
;
if
SameText
(
Application
.
Parameters
.
Values
[
'time_entries'
],
'true'
)
then
isTimeEntriesMode
:=
SameText
(
Application
.
Parameters
.
Values
[
'time_entries'
],
'true'
)
or
(
Application
.
Parameters
.
Values
[
'task_id'
]
=
''
);
if
isTimeEntriesMode
then
begin
begin
lblAppTitle
.
Caption
:=
'Time Entries'
;
lblAppTitle
.
Caption
:=
'Time Entries'
;
ShowForm
(
TFTimeEntries
);
ShowForm
(
TFTimeEntries
);
...
...
emT3Web/View.TimeEntries.dfm
View file @
0b6d8acf
...
@@ -98,6 +98,20 @@ object FTimeEntries: TFTimeEntries
...
@@ -98,6 +98,20 @@ object FTimeEntries: TFTimeEntries
WidthPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnSearchRangeClick
OnClick = btnSearchRangeClick
end
end
object btnCopyEntry: TWebButton
Left = 440
Top = 122
Width = 96
Height = 25
Caption = 'Copy'
ChildOrder = 7
ElementID = 'btn_copy_entry'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnCopyEntryClick
end
object xdwcTimeEntries: TXDataWebClient
object xdwcTimeEntries: TXDataWebClient
Connection = DMConnection.ApiConnection
Connection = DMConnection.ApiConnection
Left = 460
Left = 460
...
...
emT3Web/View.TimeEntries.html
View file @
0b6d8acf
...
@@ -28,6 +28,10 @@
...
@@ -28,6 +28,10 @@
Add Entry
Add Entry
</button>
</button>
<button
id=
"btn_copy_entry"
class=
"btn btn-sm btn-primary text-nowrap"
disabled
>
Copy Entry
</button>
<button
id=
"btn_delete_entry"
class=
"btn btn-sm btn-danger text-nowrap"
disabled
>
<button
id=
"btn_delete_entry"
class=
"btn btn-sm btn-danger text-nowrap"
disabled
>
Delete Entry
Delete Entry
</button>
</button>
...
@@ -37,16 +41,6 @@
...
@@ -37,16 +41,6 @@
<div
id=
"lbl_validation_message"
class=
"alert alert-danger py-1 px-2 mb-2 invisible small"
style=
"min-height: 31px;"
></div>
<div
id=
"lbl_validation_message"
class=
"alert alert-danger py-1 px-2 mb-2 invisible small"
style=
"min-height: 31px;"
></div>
<div
id=
"time_entries_table_host"
class=
"flex-grow-1 min-h-0 overflow-auto"
></div>
<div
id=
"time_entries_table_host"
class=
"flex-grow-1 min-h-0 overflow-auto"
></div>
<div
id=
"time_new_entry_actions"
class=
"position-fixed d-none"
style=
"z-index: 1030;"
>
<div
class=
"bg-body border rounded shadow-sm p-2 d-flex gap-2"
>
<button
type=
"button"
id=
"btn_time_new_save"
class=
"btn btn-sm btn-success"
>
Save
</button>
<button
type=
"button"
id=
"btn_time_new_cancel"
class=
"btn btn-sm btn-outline-secondary"
>
Cancel
</button>
</div>
</div>
<div
class=
"offcanvas offcanvas-end"
tabindex=
"-1"
id=
"task_picker_offcanvas"
aria-labelledby=
"task_picker_title"
>
<div
class=
"offcanvas offcanvas-end"
tabindex=
"-1"
id=
"task_picker_offcanvas"
aria-labelledby=
"task_picker_title"
>
<div
class=
"offcanvas-header"
>
<div
class=
"offcanvas-header"
>
...
...
emT3Web/View.TimeEntries.pas
View file @
0b6d8acf
...
@@ -29,11 +29,13 @@ type
...
@@ -29,11 +29,13 @@ type
xdwdsTimeEntriesplaceDesc
:
TStringField
;
xdwdsTimeEntriesplaceDesc
:
TStringField
;
btnDeleteEntry
:
TWebButton
;
btnDeleteEntry
:
TWebButton
;
btnSearchRange
:
TWebButton
;
btnSearchRange
:
TWebButton
;
btnCopyEntry
:
TWebButton
;
procedure
WebFormCreate
(
Sender
:
TObject
);
procedure
WebFormCreate
(
Sender
:
TObject
);
procedure
btnAddEntryClick
(
Sender
:
TObject
);
procedure
btnAddEntryClick
(
Sender
:
TObject
);
procedure
btnDeleteEntryClick
(
Sender
:
TObject
);
procedure
btnDeleteEntryClick
(
Sender
:
TObject
);
procedure
edtWeekOfExit
(
Sender
:
TObject
);
procedure
edtWeekOfExit
(
Sender
:
TObject
);
[
async
]
procedure
btnSearchRangeClick
(
Sender
:
TObject
);
[
async
]
procedure
btnSearchRangeClick
(
Sender
:
TObject
);
procedure
btnCopyEntryClick
(
Sender
:
TObject
);
private
private
FUserId
:
string
;
FUserId
:
string
;
FUserName
:
string
;
FUserName
:
string
;
...
@@ -95,6 +97,7 @@ type
...
@@ -95,6 +97,7 @@ type
procedure
EditorBlur
(
Event
:
TJSEvent
);
procedure
EditorBlur
(
Event
:
TJSEvent
);
[
async
]
procedure
SaveField
(
AIndex
:
Integer
;
const
AFieldName
:
string
);
[
async
]
procedure
SaveField
(
AIndex
:
Integer
;
const
AFieldName
:
string
);
[
async
]
procedure
DeleteSelectedEntry
;
[
async
]
procedure
DeleteSelectedEntry
;
function
CopySelectedEntry
:
Boolean
;
public
public
end
;
end
;
...
@@ -134,8 +137,6 @@ begin
...
@@ -134,8 +137,6 @@ begin
document
.
addEventListener
(
'mousedown'
,
TJSEventHandler
(@
DocumentMouseDown
));
document
.
addEventListener
(
'mousedown'
,
TJSEventHandler
(@
DocumentMouseDown
));
BindNewEntryButtons
;
payload
:=
AuthService
.
TokenPayload
;
payload
:=
AuthService
.
TokenPayload
;
if
Assigned
(
payload
)
then
if
Assigned
(
payload
)
then
begin
begin
...
@@ -148,6 +149,7 @@ begin
...
@@ -148,6 +149,7 @@ begin
SetTimeEntriesLabel
(
FUserName
);
SetTimeEntriesLabel
(
FUserName
);
btnDeleteEntry
.
Enabled
:=
False
;
btnDeleteEntry
.
Enabled
:=
False
;
btnCopyEntry
.
Enabled
:=
False
;
anchorDate
:=
DMConnection
.
currentTimeEntryDate
;
anchorDate
:=
DMConnection
.
currentTimeEntryDate
;
...
@@ -335,6 +337,7 @@ begin
...
@@ -335,6 +337,7 @@ begin
HideRowValidationMessage
;
HideRowValidationMessage
;
SetTopControlsEnabled
(
True
);
SetTopControlsEnabled
(
True
);
btnDeleteEntry
.
Enabled
:=
False
;
btnDeleteEntry
.
Enabled
:=
False
;
btnCopyEntry
.
Enabled
:=
False
;
RenderTable
;
RenderTable
;
finally
finally
...
@@ -351,10 +354,6 @@ var
...
@@ -351,10 +354,6 @@ var
html
:
string
;
html
:
string
;
rowIdx
:
Integer
;
rowIdx
:
Integer
;
hoursText
:
string
;
hoursText
:
string
;
actionsEl
:
TJSHTMLElement
;
rowEl
:
TJSHTMLElement
;
rowRect
:
TJSObject
;
topPos
:
Integer
;
function
Th
(
const
s
:
string
):
string
;
function
Th
(
const
s
:
string
):
string
;
begin
begin
...
@@ -519,6 +518,21 @@ begin
...
@@ -519,6 +518,21 @@ begin
TdWrap
(
SummaryTextArea
(
'summary'
,
xdwdsTimeEntriessummary
.
AsString
,
rowIdx
))
+
TdWrap
(
SummaryTextArea
(
'summary'
,
xdwdsTimeEntriessummary
.
AsString
,
rowIdx
))
+
'</tr>'
;
'</tr>'
;
if
IsNewEntryRow
(
rowIdx
)
then
begin
html
:=
html
+
'<tr class="time-new-entry-actions-row">'
+
'<td colspan="7" class="p-0 border-0">'
+
'<div class="position-sticky d-flex justify-content-end py-1 pe-2" style="right:0; z-index:5; pointer-events:none;">'
+
'<div class="bg-body border rounded shadow-sm p-2 d-flex gap-2" style="pointer-events:auto;">'
+
'<button type="button" id="btn_time_new_save" class="btn btn-sm btn-success">Save</button>'
+
'<button type="button" id="btn_time_new_cancel" class="btn btn-sm btn-outline-secondary">Cancel</button>'
+
'</div>'
+
'</div>'
+
'</td>'
+
'</tr>'
;
end
;
xdwdsTimeEntries
.
Next
;
xdwdsTimeEntries
.
Next
;
Inc
(
rowIdx
);
Inc
(
rowIdx
);
end
;
end
;
...
@@ -527,35 +541,7 @@ begin
...
@@ -527,35 +541,7 @@ begin
SetTotalRowsLabel
(
rowIdx
);
SetTotalRowsLabel
(
rowIdx
);
host
.
innerHTML
:=
html
;
host
.
innerHTML
:=
html
;
actionsEl
:=
TJSHTMLElement
(
document
.
getElementById
(
'time_new_entry_actions'
));
BindNewEntryButtons
;
if
Assigned
(
actionsEl
)
then
begin
if
FAddingNewEntry
then
begin
rowEl
:=
TJSHTMLElement
(
document
.
querySelector
(
'tr[data-idx="'
+
IntToStr
(
FNewEntryRowIndex
)
+
'"]'
));
if
Assigned
(
rowEl
)
then
begin
actionsEl
.
classList
.
remove
(
'd-none'
);
rowRect
:=
TJSObject
(
rowEl
.
getBoundingClientRect
);
topPos
:=
Round
(
JS
.
toNumber
(
rowRect
[
'bottom'
])
-
2
);
actionsEl
.
setAttribute
(
'style'
,
'z-index: 1030; '
+
'right: 12px; '
+
'top: '
+
IntToStr
(
topPos
)
+
'px; '
+
'left: auto; '
+
'bottom: auto;'
);
end
else
actionsEl
.
classList
.
add
(
'd-none'
);
end
else
actionsEl
.
classList
.
add
(
'd-none'
);
end
;
BindTableEditors
;
BindTableEditors
;
EnableAutoGrowTextAreas
;
EnableAutoGrowTextAreas
;
...
@@ -664,6 +650,7 @@ begin
...
@@ -664,6 +650,7 @@ begin
HideRowValidationMessage
;
HideRowValidationMessage
;
SetTopControlsEnabled
(
True
);
SetTopControlsEnabled
(
True
);
btnDeleteEntry
.
Enabled
:=
False
;
btnDeleteEntry
.
Enabled
:=
False
;
btnCopyEntry
.
Enabled
:=
False
;
CaptureTableScroll
;
CaptureTableScroll
;
await
(
LoadTimeEntries
);
await
(
LoadTimeEntries
);
...
@@ -690,6 +677,7 @@ begin
...
@@ -690,6 +677,7 @@ begin
HideRowValidationMessage
;
HideRowValidationMessage
;
SetTopControlsEnabled
(
True
);
SetTopControlsEnabled
(
True
);
btnDeleteEntry
.
Enabled
:=
False
;
btnDeleteEntry
.
Enabled
:=
False
;
btnCopyEntry
.
Enabled
:=
False
;
RenderTable
;
RenderTable
;
end
;
end
;
...
@@ -760,6 +748,7 @@ begin
...
@@ -760,6 +748,7 @@ begin
FActiveRowIndex
:=
idx
;
FActiveRowIndex
:=
idx
;
btnDeleteEntry
.
Enabled
:=
not
IsNewEntryRow
(
idx
);
btnDeleteEntry
.
Enabled
:=
not
IsNewEntryRow
(
idx
);
btnCopyEntry
.
Enabled
:=
not
IsNewEntryRow
(
idx
);
GotoRowIndex
(
idx
);
GotoRowIndex
(
idx
);
if
xdwdsTimeEntries
.
Eof
then
if
xdwdsTimeEntries
.
Eof
then
...
@@ -826,6 +815,7 @@ begin
...
@@ -826,6 +815,7 @@ begin
FActiveRowIndex
:=
FNewEntryRowIndex
;
FActiveRowIndex
:=
FNewEntryRowIndex
;
btnDeleteEntry
.
Enabled
:=
False
;
btnDeleteEntry
.
Enabled
:=
False
;
btnCopyEntry
.
Enabled
:=
False
;
SetTopControlsEnabled
(
False
);
SetTopControlsEnabled
(
False
);
FBlockedRowIndex
:=
FNewEntryRowIndex
;
FBlockedRowIndex
:=
FNewEntryRowIndex
;
...
@@ -853,6 +843,7 @@ begin
...
@@ -853,6 +843,7 @@ begin
FActiveRowIndex
:=
idx
;
FActiveRowIndex
:=
idx
;
btnDeleteEntry
.
Enabled
:=
not
IsNewEntryRow
(
idx
);
btnDeleteEntry
.
Enabled
:=
not
IsNewEntryRow
(
idx
);
btnCopyEntry
.
Enabled
:=
not
IsNewEntryRow
(
idx
);
ApplyActiveRowState
;
ApplyActiveRowState
;
end
;
end
;
...
@@ -884,6 +875,7 @@ begin
...
@@ -884,6 +875,7 @@ begin
begin
begin
FActiveRowIndex
:=
idx
;
FActiveRowIndex
:=
idx
;
btnDeleteEntry
.
Enabled
:=
True
;
btnDeleteEntry
.
Enabled
:=
True
;
btnCopyEntry
.
Enabled
:=
True
;
ApplyRowValidation
(
idx
);
ApplyRowValidation
(
idx
);
ShowRowValidationMessage
(
idx
,
'Complete required fields before leaving this row.'
);
ShowRowValidationMessage
(
idx
,
'Complete required fields before leaving this row.'
);
SetTopControlsEnabled
(
False
);
SetTopControlsEnabled
(
False
);
...
@@ -934,6 +926,7 @@ begin
...
@@ -934,6 +926,7 @@ begin
FActiveRowIndex
:=
FNewEntryRowIndex
;
FActiveRowIndex
:=
FNewEntryRowIndex
;
btnDeleteEntry
.
Enabled
:=
False
;
btnDeleteEntry
.
Enabled
:=
False
;
btnCopyEntry
.
Enabled
:=
False
;
SetTopControlsEnabled
(
False
);
SetTopControlsEnabled
(
False
);
FBlockedRowIndex
:=
FNewEntryRowIndex
;
FBlockedRowIndex
:=
FNewEntryRowIndex
;
...
@@ -988,6 +981,7 @@ begin
...
@@ -988,6 +981,7 @@ begin
FActiveRowIndex
:=
idx
;
FActiveRowIndex
:=
idx
;
btnDeleteEntry
.
Enabled
:=
not
IsNewEntryRow
(
idx
);
btnDeleteEntry
.
Enabled
:=
not
IsNewEntryRow
(
idx
);
btnCopyEntry
.
Enabled
:=
not
IsNewEntryRow
(
idx
);
btn
:=
TJSHTMLElement
(
document
.
getElementById
(
triggerId
));
btn
:=
TJSHTMLElement
(
document
.
getElementById
(
triggerId
));
if
Assigned
(
btn
)
then
if
Assigned
(
btn
)
then
...
@@ -1076,6 +1070,7 @@ begin
...
@@ -1076,6 +1070,7 @@ begin
FActiveRowIndex
:=
idx
;
FActiveRowIndex
:=
idx
;
btnDeleteEntry
.
Enabled
:=
True
;
btnDeleteEntry
.
Enabled
:=
True
;
btnCopyEntry
.
Enabled
:=
True
;
SetTopControlsEnabled
(
True
);
SetTopControlsEnabled
(
True
);
ApplyActiveRowState
;
ApplyActiveRowState
;
...
@@ -1247,6 +1242,7 @@ begin
...
@@ -1247,6 +1242,7 @@ begin
FActiveRowIndex
:=
FNewEntryRowIndex
;
FActiveRowIndex
:=
FNewEntryRowIndex
;
btnDeleteEntry
.
Enabled
:=
False
;
btnDeleteEntry
.
Enabled
:=
False
;
btnCopyEntry
.
Enabled
:=
False
;
SetTopControlsEnabled
(
False
);
SetTopControlsEnabled
(
False
);
FBlockedRowIndex
:=
FNewEntryRowIndex
;
FBlockedRowIndex
:=
FNewEntryRowIndex
;
...
@@ -1399,6 +1395,7 @@ begin
...
@@ -1399,6 +1395,7 @@ begin
SetTopControlsEnabled
(
False
);
SetTopControlsEnabled
(
False
);
btnDeleteEntry
.
Enabled
:=
False
;
btnDeleteEntry
.
Enabled
:=
False
;
btnCopyEntry
.
Enabled
:=
False
;
HideRowValidationMessage
;
HideRowValidationMessage
;
CaptureTableScroll
;
CaptureTableScroll
;
...
@@ -1408,12 +1405,110 @@ begin
...
@@ -1408,12 +1405,110 @@ begin
end
;
end
;
function
TFTimeEntries
.
CopySelectedEntry
:
Boolean
;
var
taskDate
:
string
;
taskId
:
string
;
taskDisplay
:
string
;
hoursValue
:
Double
;
hasHours
:
Boolean
;
taskTime
:
string
;
place
:
string
;
placeDesc
:
string
;
category
:
string
;
categoryDesc
:
string
;
summary
:
string
;
begin
Result
:=
False
;
if
FAddingNewEntry
then
begin
Utils
.
ShowErrorModal
(
'Save or cancel the new entry before copying another entry.'
);
Exit
;
end
;
if
FActiveRowIndex
<
0
then
begin
Utils
.
ShowErrorModal
(
'Select a time entry to copy.'
);
Exit
;
end
;
if
(
FActiveRowIndex
>=
0
)
and
(
not
ValidateRow
(
FActiveRowIndex
))
then
begin
ApplyRowValidation
(
FActiveRowIndex
);
ShowRowValidationMessage
(
FActiveRowIndex
,
'Complete required fields before copying this entry.'
);
SetTopControlsEnabled
(
False
);
Exit
;
end
;
GotoRowIndex
(
FActiveRowIndex
);
if
xdwdsTimeEntries
.
Eof
then
Exit
;
taskDate
:=
xdwdsTimeEntriestaskDate
.
AsString
;
taskId
:=
xdwdsTimeEntriestaskId
.
AsString
;
taskDisplay
:=
xdwdsTimeEntriestaskDisplay
.
AsString
;
hasHours
:=
not
xdwdsTimeEntrieshours
.
IsNull
;
if
hasHours
then
hoursValue
:=
xdwdsTimeEntrieshours
.
AsFloat
else
hoursValue
:=
0
;
taskTime
:=
xdwdsTimeEntriestaskTime
.
AsString
;
place
:=
xdwdsTimeEntriesplace
.
AsString
;
placeDesc
:=
xdwdsTimeEntriesplaceDesc
.
AsString
;
category
:=
xdwdsTimeEntriescategory
.
AsString
;
categoryDesc
:=
xdwdsTimeEntriescategoryDesc
.
AsString
;
summary
:=
xdwdsTimeEntriessummary
.
AsString
;
xdwdsTimeEntries
.
Append
;
xdwdsTimeEntriesentryId
.
AsInteger
:=
0
;
xdwdsTimeEntriestaskDate
.
AsString
:=
taskDate
;
xdwdsTimeEntriestaskId
.
AsString
:=
taskId
;
xdwdsTimeEntriestaskDisplay
.
AsString
:=
taskDisplay
;
if
hasHours
then
xdwdsTimeEntrieshours
.
AsFloat
:=
hoursValue
else
xdwdsTimeEntrieshours
.
Clear
;
xdwdsTimeEntriestaskTime
.
AsString
:=
taskTime
;
xdwdsTimeEntriesplace
.
AsString
:=
place
;
xdwdsTimeEntriesplaceDesc
.
AsString
:=
placeDesc
;
xdwdsTimeEntriescategory
.
AsString
:=
category
;
xdwdsTimeEntriescategoryDesc
.
AsString
:=
categoryDesc
;
xdwdsTimeEntriessummary
.
AsString
:=
summary
;
xdwdsTimeEntries
.
Post
;
FAddingNewEntry
:=
True
;
FNewEntryRowIndex
:=
xdwdsTimeEntries
.
RecordCount
-
1
;
FActiveRowIndex
:=
FNewEntryRowIndex
;
SetTopControlsEnabled
(
False
);
btnDeleteEntry
.
Enabled
:=
False
;
btnCopyEntry
.
Enabled
:=
False
;
HideRowValidationMessage
;
CaptureTableScroll
;
RenderTable
;
Result
:=
True
;
end
;
procedure
TFTimeEntries
.
btnAddEntryClick
(
Sender
:
TObject
);
procedure
TFTimeEntries
.
btnAddEntryClick
(
Sender
:
TObject
);
begin
begin
BeginAddEntry
;
BeginAddEntry
;
end
;
end
;
procedure
TFTimeEntries
.
btnCopyEntryClick
(
Sender
:
TObject
);
begin
CopySelectedEntry
;
end
;
procedure
TFTimeEntries
.
btnDeleteEntryClick
(
Sender
:
TObject
);
procedure
TFTimeEntries
.
btnDeleteEntryClick
(
Sender
:
TObject
);
begin
begin
if
FActiveRowIndex
<
0
then
if
FActiveRowIndex
<
0
then
...
@@ -1514,6 +1609,7 @@ begin
...
@@ -1514,6 +1609,7 @@ begin
FActiveRowIndex
:=
FNewEntryRowIndex
;
FActiveRowIndex
:=
FNewEntryRowIndex
;
btnDeleteEntry
.
Enabled
:=
False
;
btnDeleteEntry
.
Enabled
:=
False
;
btnCopyEntry
.
Enabled
:=
False
;
SetTopControlsEnabled
(
False
);
SetTopControlsEnabled
(
False
);
FBlockedRowIndex
:=
FNewEntryRowIndex
;
FBlockedRowIndex
:=
FNewEntryRowIndex
;
...
@@ -1542,6 +1638,7 @@ begin
...
@@ -1542,6 +1638,7 @@ begin
FActiveRowIndex
:=
idx
;
FActiveRowIndex
:=
idx
;
btnDeleteEntry
.
Enabled
:=
not
IsNewEntryRow
(
idx
);
btnDeleteEntry
.
Enabled
:=
not
IsNewEntryRow
(
idx
);
btnCopyEntry
.
Enabled
:=
not
IsNewEntryRow
(
idx
);
if
not
Assigned
(
FTaskPickerOffCanvas
)
then
if
not
Assigned
(
FTaskPickerOffCanvas
)
then
FTaskPickerOffCanvas
:=
TTaskPickerOffCanvas
.
Create
(
xdwcTimeEntries
,
@
TaskPickerTaskSelected
);
FTaskPickerOffCanvas
:=
TTaskPickerOffCanvas
.
Create
(
xdwcTimeEntries
,
@
TaskPickerTaskSelected
);
...
@@ -1569,6 +1666,7 @@ begin
...
@@ -1569,6 +1666,7 @@ begin
FActiveRowIndex
:=
ARowIndex
;
FActiveRowIndex
:=
ARowIndex
;
btnDeleteEntry
.
Enabled
:=
not
IsNewEntryRow
(
ARowIndex
);
btnDeleteEntry
.
Enabled
:=
not
IsNewEntryRow
(
ARowIndex
);
btnCopyEntry
.
Enabled
:=
not
IsNewEntryRow
(
ARowIndex
);
CaptureTableScroll
;
CaptureTableScroll
;
RenderTable
;
RenderTable
;
...
@@ -1765,6 +1863,7 @@ begin
...
@@ -1765,6 +1863,7 @@ begin
HideRowValidationMessage
;
HideRowValidationMessage
;
SetTopControlsEnabled
(
True
);
SetTopControlsEnabled
(
True
);
btnDeleteEntry
.
Enabled
:=
False
;
btnDeleteEntry
.
Enabled
:=
False
;
btnCopyEntry
.
Enabled
:=
False
;
CaptureTableScroll
;
CaptureTableScroll
;
await
(
LoadTimeEntries
);
await
(
LoadTimeEntries
);
...
...
emT3Web/emT3web.dpr
View file @
0b6d8acf
...
@@ -80,10 +80,14 @@ var
...
@@ -80,10 +80,14 @@ var
taskIdParam: string;
taskIdParam: string;
codeParam: string;
codeParam: string;
timeEntriesParam: string;
timeEntriesParam: string;
isTimeEntriesMode: Boolean;
begin
begin
timeEntriesParam := Application.Parameters.Values['time_entries'];
timeEntriesParam := Application.Parameters.Values['time_entries'];
isTimeEntriesMode :=
SameText(timeEntriesParam, 'true') or
(Application.Parameters.Values['task_id'] = '');
if
SameText(timeEntriesParam, 'true')
then
if
isTimeEntriesMode
then
begin
begin
if AuthService.Authenticated and not AuthService.TokenExpired then
if AuthService.Authenticated and not AuthService.TokenExpired then
begin
begin
...
@@ -120,12 +124,16 @@ var
...
@@ -120,12 +124,16 @@ var
userIdParam: string;
userIdParam: string;
taskIdParam: string;
taskIdParam: string;
timeEntriesParam: string;
timeEntriesParam: string;
isTimeEntriesMode: Boolean;
begin
begin
AuthService.Logout;
AuthService.Logout;
timeEntriesParam := Application.Parameters.Values['time_entries'];
timeEntriesParam := Application.Parameters.Values['time_entries'];
isTimeEntriesMode :=
SameText(timeEntriesParam, 'true') or
(Application.Parameters.Values['task_id'] = '');
if
SameText(timeEntriesParam, 'true')
then
if
isTimeEntriesMode
then
begin
begin
DisplayLoginView('', '', AMsg);
DisplayLoginView('', '', AMsg);
Exit;
Exit;
...
...
emT3XDataServer/bin/emT3XDataServer.ini
View file @
0b6d8acf
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
MemoLogLevel
=
4
MemoLogLevel
=
4
FileLogLevel
=
4
FileLogLevel
=
4
webClientVersion
=
0.8.9
webClientVersion
=
0.8.9
LogFileNum
=
24
3
LogFileNum
=
24
4
[Database]
[Database]
Server
=
192.168.102.133
Server
=
192.168.102.133
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment