Commit 5647a1d3 by Cam Hayes

Merge branch 'master' into cam3

parents 102303cd 956385b8
......@@ -4,6 +4,7 @@ kgOrdersClient/__recovery/
kgOrdersClient/TMSWeb/
kgOrdersClient/Win32/
kgOrdersClient/css/__history/
kgOrdersClient/css/__recovery/
kgOrdersClient/config/__history/
kgOrdersServer/__history
kgOrdersServer/__recovery
......
......@@ -135,7 +135,7 @@ implementation
{$R *.dfm}
uses View.Main, View.Customers, View.SelectCustomer;
uses View.Main, View.Customers, View.SelectCustomer, Utils;
procedure TFViewAddCustomer.Clear();
// Clears the shipping address fields.
......@@ -184,9 +184,7 @@ begin
xdwdsShipTo.Close;
xdwdsShipTo.SetJSONData(notification['ADDRESS']);
xdwdsShipTo.Open;
asm
endSpinner();
end;
Utils.HideSpinner('spinner');
end;
procedure TFViewAddCustomer.SendAddressToServer;
......@@ -547,8 +545,8 @@ begin
var confirmationModal = new bootstrap.Modal(document.getElementById('confirmation_modal'), {
keyboard: false });
confirmationModal.hide();
startSpinner();
end;
Utils.ShowSpinner('spinner');
//delCustomer();
tmrReturn.Enabled := true;
end
......@@ -558,8 +556,8 @@ begin
var confirmationModal = new bootstrap.Modal(document.getElementById('confirmation_modal'), {
keyboard: false });
confirmationModal.hide();
startSpinner();
end;
Utils.ShowSpinner('spinner');
delAddress();
end;
end;
......@@ -715,9 +713,7 @@ procedure TFViewAddCustomer.tmrReturnTimer(Sender: TObject);
// Timer to returnto the customer page because it takes slightly too long to
// Delete customers causing ghost customers to show up.
begin
asm
endSpinner();
end;
Utils.HideSpinner('spinner');
tmrReturn.Enabled := false;
FViewMain.ViewCustomerList('Success:Customer Successfully Deleted');
end;
......
......@@ -19,7 +19,7 @@ type
FUnauthorizedAccessProc: TUnauthorizedAccessProc;
public
const clientVersion = '0.9.2';
const clientVersion = '0.9.4';
procedure InitApp(SuccessProc: TSuccessProc;
UnauthorizedAccessProc: TUnauthorizedAccessProc);
procedure SetClientConfig(Callback: TVersionCheckCallback);
......
unit Utils;
interface
uses
System.Classes, SysUtils, JS, Web, WEBLib.Forms, WEBLib.Toast, DateUtils;
procedure ShowStatusMessage(const AMessage, AClass: string; const AElementId: string);
procedure HideStatusMessage(const AElementId: string);
procedure ShowSpinner(SpinnerID: string);
procedure HideSpinner(SpinnerID: string);
function CalculateAge(DateOfBirth: TDateTime): Integer;
function FormatPhoneNumber(PhoneNumber: string): string;
procedure ApplyReportTitle(CurrentReportType: string);
// function FormatDollarValue(ValueStr: string): string;
implementation
procedure ShowStatusMessage(const AMessage, AClass: string; const AElementId: string);
var
StatusMessage: TJSHTMLElement;
begin
StatusMessage := TJSHTMLElement(document.getElementById(AElementId));
if Assigned(StatusMessage) then
begin
if AMessage = '' then
begin
StatusMessage.style.setProperty('display', 'none');
StatusMessage.className := '';
StatusMessage.innerHTML := '';
end
else
begin
StatusMessage.innerHTML := AMessage;
StatusMessage.className := 'alert ' + AClass;
StatusMessage.style.setProperty('display', 'block');
end
end
else
console.log('Error: Status message element not found');
end;
procedure HideStatusMessage(const AElementId: string);
var
StatusMessage: TJSHTMLElement;
begin
StatusMessage := TJSHTMLElement(document.getElementById(AElementId));
if Assigned(StatusMessage) then
begin
StatusMessage.style.setProperty('display', 'none');
StatusMessage.className := '';
StatusMessage.innerHTML := '';
end
else
console.log('Error: Status message element not found');
end;
procedure ShowSpinner(SpinnerID: string);
var
SpinnerElement: TJSHTMLElement;
begin
SpinnerElement := TJSHTMLElement(document.getElementById(SpinnerID));
if Assigned(SpinnerElement) then
begin
SpinnerElement.classList.remove('d-none');
SpinnerElement.classList.add('d-block');
end;
end;
procedure HideSpinner(SpinnerID: string);
var
SpinnerElement: TJSHTMLElement;
begin
SpinnerElement := TJSHTMLElement(document.getElementById(SpinnerID));
if Assigned(SpinnerElement) then
begin
SpinnerElement.classList.remove('d-block');
SpinnerElement.classList.add('d-none');
end;
end;
function CalculateAge(DateOfBirth: TDateTime): Integer;
var
Today, BirthDate: TJSDate;
Year, Month, Day, BirthYear, BirthMonth, BirthDay: NativeInt;
DOBString: string;
begin
Today := TJSDate.New;
Year := Today.FullYear;
Month := Today.Month + 1;
Day := Today.Date;
// Formats the DateOfBirth as an ISO 8601 date string
DOBString := FormatDateTime('yyyy-mm-dd', DateOfBirth);
BirthDate := TJSDate.New(DOBString);
if BirthDate = nil then
begin
Exit(0); // Exit the function with an age of 0 if the date creation fails
end;
BirthYear := BirthDate.FullYear;
BirthMonth := BirthDate.Month + 1;
BirthDay := BirthDate.Date;
Result := Year - BirthYear;
if (Month < BirthMonth) or ((Month = BirthMonth) and (Day < BirthDay)) then
Dec(Result);
end;
function FormatPhoneNumber(PhoneNumber: string): string;
var
Digits: string;
begin
Digits := PhoneNumber.Replace('(', '').Replace(')', '').Replace('-', '').Replace(' ', '');
case Length(Digits) of
7: Result := Format('%s-%s', [Copy(Digits, 1, 3), Copy(Digits, 4, 4)]);
10: Result := Format('(%s) %s-%s', [Copy(Digits, 1, 3), Copy(Digits, 4, 3), Copy(Digits, 7, 4)]);
else
// If the number does not have 7 or 10 digits, whatever they typed is returned
Result := PhoneNumber;
end;
end;
procedure ApplyReportTitle(CurrentReportType: string);
var
CrimeTitleElement: TJSHTMLElement;
begin
CrimeTitleElement := TJSHTMLElement(document.getElementById('crime_title'));
if Assigned(CrimeTitleElement) then
CrimeTitleElement.innerText := CurrentReportType
else
Console.Log('Element with ID "crime_title" not found.');
end;
// Used html number input type to restrict the input instead of this function
// function FormatDollarValue(ValueStr: string): string;
// var
// i: Integer;
// begin
// Result := ''; // Initialize the result
// // Filter out any characters that are not digits or decimal point
// for i := 1 to Length(ValueStr) do
// begin
// if (Pos(ValueStr[i], '0123456789.') > 0) then
// begin
// Result := Result + ValueStr[i];
// end;
// end;
// end;
end.
......@@ -61,7 +61,7 @@ var
implementation
uses
XData.Model.Classes, View.Main, View.SelectCustomer;
XData.Model.Classes, View.Main, View.SelectCustomer, Utils;
{$R *.dfm}
......@@ -124,9 +124,7 @@ var
begin
if PageNumber > 0 then
begin
asm
startSpinner();
end;
Utils.ShowSpinner('spinner');
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetCustomers', [searchOptions]));
customerList := TJSObject(xdcResponse.Result);
......@@ -135,9 +133,7 @@ begin
xdwdsCustomers.SetJsonData(customerList['data']);
xdwdsCustomers.Open;
asm
endSpinner();
end;
Utils.HideSpinner('spinner');
customerListLength := integer(customerList['count']);
TotalPages := ( (customerListLength + PageSize - 1) div PageSize);
......
......@@ -78,7 +78,8 @@ Windows,
View.Main,
View.Users,
VCL.Dialogs,
ConnectionModule;
ConnectionModule,
Utils;
procedure TFViewEditUser.btnCancelClick(Sender: TObject);
// Cancels the edit or addition
......@@ -99,9 +100,7 @@ begin
else
AddUser();
WebTimer1.Enabled := true;
asm
startSpinner();
end;
Utils.ShowSpinner('spinner');
end;
function TFViewEditUser.AddUser(): string;
......@@ -216,9 +215,7 @@ end;
procedure TFViewEditUser.WebTimer1Timer(Sender: TObject);
begin
WebTimer1.Enabled := False;
asm
endSpinner();
end;
Utils.HideSpinner('spinner');
if (not Info.Contains('Failure')) then
begin
FViewMain.ShowUserForm(Info);
......@@ -339,9 +336,16 @@ begin
end;
}
asm
var confirmationModal = new bootstrap.Modal(document.getElementById('confirmation_modal'), {
keyboard: false });
confirmationModal.show();
var modal = document.getElementById('confirmation_modal');
// ensure the modal is directly under <body>
if (modal && modal.parentNode !== document.body) {
document.body.appendChild(modal);
}
var bsModal = new bootstrap.Modal(modal, {
keyboard: false
});
bsModal.show();
end;
end;
......
......@@ -55,7 +55,7 @@ implementation
uses
JS, XData.Model.Classes,
ConnectionModule, Auth.Service;
ConnectionModule, Auth.Service, Utils;
{$R *.dfm}
......@@ -119,6 +119,7 @@ begin
// Appends new rows to the table body
TJSHTMLElement(document.getElementById('tblPhoneGrid').getElementsByTagName('tbody')[0]).appendChild(NewRow);
Utils.HideSpinner('spinner');
end;
procedure TFViewItems.GeneratePagination(TotalPages: Integer);
......@@ -304,18 +305,14 @@ begin
console.log('correct');
if PageNumber > 0 then
begin
asm
startSpinner();
end;
Utils.ShowSpinner('spinner');
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetItems',
[searchOptions]));
itemList := TJSObject(xdcResponse.Result);
data := TJSArray(itemList['data']);
itemListLength := integer(itemList['count']);
ClearTable();
asm
setTimeout(endSpinner, 2000);
end;
Utils.HideSpinner('Spinner');
for i := 0 to data.Length - 1 do
begin
item := TJSObject(data[i]);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -62,3 +62,13 @@
</div>
</div>
<div id="spinner" class="position-absolute top-50 start-50 translate-middle d-none">
<div class="lds-roller">
<div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div>
</div>
</div>
......@@ -50,8 +50,7 @@ type
{ Public declarations }
class procedure Display(LogoutProc: TLogoutProc);
procedure ShowForm( AFormClass: TWebFormClass );
procedure EditUser( Mode, Username, Password, Name, Status, Email,
Access, Rights, Perspective, QB: string);
procedure EditUser( Mode, Username, Password, Name, Status, Email, Access, Rights, Perspective, QB: string);
procedure ViewOrderEntryCorrugated(orderInfo, customerInfo, mode, info: string);
procedure ViewOrderEntryWeb(orderInfo, customerInfo, mode, info: string);
procedure ViewOrderEntryCuttingDie(orderInfo, customerInfo, mode, info: string);
......
......@@ -223,19 +223,19 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
Text = ''
OnChange = dtpMountDueChange
end
object WebButton1: TWebButton
object btnAddColor: TWebButton
Left = 658
Top = 150
Width = 96
Height = 25
Caption = '+'
Caption = 'Add Color'
ChildOrder = 59
ElementID = 'btnaddcolor'
ElementPosition = epRelative
HeightPercent = 100.000000000000000000
Role = 'null'
WidthPercent = 100.000000000000000000
OnClick = WebButton1Click
OnClick = btnAddColorClick
end
object dtpApprovedDate: TWebDateTimePicker
Left = 662
......
<nav class="navbar navbar-expand navbar-light bg-light sticky-top" style="z-index: 100;">
<nav class="navbar navbar-expand navbar-light bg-light border-light sticky-top" style="z-index: 100;">
<div class="container-fluid ps-0">
<div id="view.login.message" class="alert alert-danger"
style="padding: 0.25rem 0.5rem; font-size: 0.875rem; line-height: 1.5; display: flex; align-items: center; margin: 0 0 0 60px; height: 32px; width: 400px;">
......@@ -268,13 +268,24 @@
</div>
<h4 class="custom-h4 mt-3">Colors</h4>
<hr class="custom-hr">
<div class="row">
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Colors:</label>
<button id="btnaddcolor" class="btn btn-primary btn-sm float-end">+</button>
<div id="additionalFields" class="row mt-3"></div>
</div>
<div class="row align-items-center">
<!-- placeholders for the 4 dynamic input columns to center the Add Color button the dynamically created Remove button -->
<div class="col-sm"></div>
<div class="col-sm"></div>
<div class="col-sm"></div>
<div class="col-sm"></div>
<div class="col-auto d-flex justify-content-center">
<!-- Delphi-generated TWebButton stays here -->
<button id="btnaddcolor" class="btn btn-primary btn-sm me-3">
Add Color
</button>
</div>
</div>
<!-- your existing container for the dynamic rows -->
<div id="additionalFields" class="row mt-3"></div>
<h4 class="custom-h4 mt-3">Proofing</h4>
<hr class="custom-hr">
<div class="row">
......
......@@ -28,7 +28,7 @@ type
WebLabel4: TWebLabel;
WebLabel5: TWebLabel;
WebLabel6: TWebLabel;
WebButton1: TWebButton;
btnAddColor: TWebButton;
WebLabel7: TWebLabel;
dtpApprovedDate: TWebDateTimePicker;
WebLabel8: TWebLabel;
......@@ -210,7 +210,7 @@ type
[async] procedure getOrder(Order_ID: string);
[async] procedure getCustomer(customerID: string);
procedure tmrScrollTopTimer(Sender: TObject);
procedure WebButton1Click(Sender: TObject);
procedure btnAddColorClick(Sender: TObject);
procedure addColorRow(num, Color, LPI, Size: string);
procedure btnSaveClick(Sender: TObject);
[async] procedure AddCorrugatedOrder(orderJSON: TJSONObject);
......@@ -264,7 +264,7 @@ implementation
{$R *.dfm}
uses
View.Home, View.Main, View.AddOrder, View.AddAddress;
View.Home, View.Main, View.AddOrder, View.AddAddress, Utils;
procedure TFOrderEntryCorrugated.sendOrderToServer();
// This can be improved. I was struggling to get the checkboxes to work with
......@@ -499,9 +499,16 @@ begin
document.getElementById('btn_confirm_cancel').innerText := 'Cancel';
document.getElementById('btn_confirm_delete').innerText := 'Delete';
asm
var confirmationModal = new bootstrap.Modal(document.getElementById('confirmation_modal'), {
keyboard: false });
confirmationModal.show();
var modal = document.getElementById('confirmation_modal');
// ensure the modal lives directly under <body>
if (modal && modal.parentNode !== document.body) {
document.body.appendChild(modal);
}
var bsModal = new bootstrap.Modal(modal, {
keyboard: false
});
bsModal.show();
end;
end;
......@@ -532,11 +539,18 @@ begin
end
else
begin
Utils.ShowSpinner('spinner');
asm
var confirmationModal = new bootstrap.Modal(document.getElementById('confirmation_modal'), {
keyboard: false });
confirmationModal.hide();
startSpinner();
var modal = document.getElementById('confirmation_modal');
// ensure the modal lives directly under <body>
if (modal && modal.parentNode !== document.body) {
document.body.appendChild(modal);
}
var bsModal = new bootstrap.Modal(modal, {
keyboard: false
});
bsModal.hide();
end;
delOrder();
tmrReturn.Enabled := true;
......@@ -640,10 +654,10 @@ begin
});
const removeButtonCol = document.createElement('div');
removeButtonCol.className = 'col-auto d-flex align-items-center';
removeButtonCol.className = 'col-auto d-flex align-items-center mt-3';
const removeButton = document.createElement('button');
removeButton.className = 'btn btn-danger btn-sm';
removeButton.className = 'btn btn-danger btn-sm mt-1';
removeButton.textContent = 'Remove';
removeButton.addEventListener('click', function() {
container.removeChild(newRow);
......@@ -656,7 +670,7 @@ begin
end;
end;
procedure TFOrderEntryCorrugated.WebButton1Click(Sender: TObject);
procedure TFOrderEntryCorrugated.btnAddColorClick(Sender: TObject);
begin
addColorRow('','','','');
end;
......@@ -771,9 +785,16 @@ begin
document.getElementById('btn_confirm_cancel').innerText := 'No';
document.getElementById('btn_confirm_delete').innerText := 'Yes';
asm
var confirmationModal = new bootstrap.Modal(document.getElementById('confirmation_modal'), {
keyboard: false });
confirmationModal.show();
var modal = document.getElementById('confirmation_modal');
// ensure the modal is directly under <body>
if (modal && modal.parentNode !== document.body) {
document.body.appendChild(modal);
}
var bsModal = new bootstrap.Modal(modal, {
keyboard: false
});
bsModal.show();
end;
end;
......@@ -1060,9 +1081,7 @@ end;
procedure TFOrderEntryCorrugated.tmrReturnTimer(Sender: TObject);
begin
asm
endSpinner();
end;
Utils.HideSpinner('spinner');
tmrReturn.Enabled := false;
FViewMain.ViewOrders('Success: Order Successfully Deleted');
end;
......
......@@ -125,7 +125,7 @@ implementation
{$R *.dfm}
uses
View.Home, View.Main, View.AddOrder, View.AddAddress;
View.Home, View.Main, View.AddOrder, View.AddAddress, Utils;
procedure TFOrderEntryCuttingDie.WebButton2Click(Sender: TObject);
begin
......@@ -329,9 +329,16 @@ end;
procedure TFOrderEntryCuttingDie.btnDeleteClick(Sender: TObject);
begin
asm
var confirmationModal = new bootstrap.Modal(document.getElementById('confirmation_modal'), {
keyboard: false });
confirmationModal.show();
var modal = document.getElementById('confirmation_modal');
// ensure the modal is directly under <body>
if (modal && modal.parentNode !== document.body) {
document.body.appendChild(modal);
}
var bsModal = new bootstrap.Modal(modal, {
keyboard: false
});
bsModal.show();
end;
end;
procedure TFOrderEntryCuttingDie.btnEditClick(Sender: TObject);
......@@ -366,11 +373,18 @@ begin
end
else
begin
Utils.ShowSpinner('spinner');
asm
var confirmationModal = new bootstrap.Modal(document.getElementById('confirmation_modal'), {
keyboard: false });
confirmationModal.hide();
startSpinner();
var modal = document.getElementById('confirmation_modal');
// ensure the modal lives directly under <body>
if (modal && modal.parentNode !== document.body) {
document.body.appendChild(modal);
}
var bsModal = new bootstrap.Modal(modal, {
keyboard: false
});
bsModal.hide();
end;
delOrder();
tmrReturn.Enabled := true;
......@@ -474,9 +488,16 @@ begin
document.getElementById('btn_confirm_cancel').innerText := 'No';
document.getElementById('btn_confirm_delete').innerText := 'Yes';
asm
var confirmationModal = new bootstrap.Modal(document.getElementById('confirmation_modal'), {
keyboard: false });
confirmationModal.show();
var modal = document.getElementById('confirmation_modal');
// ensure the modal is directly under <body>
if (modal && modal.parentNode !== document.body) {
document.body.appendChild(modal);
}
var bsModal = new bootstrap.Modal(modal, {
keyboard: false
});
bsModal.show();
end;
end;
......@@ -639,9 +660,7 @@ end;
procedure TFOrderEntryCuttingDie.tmrReturnTimer(Sender: TObject);
begin
asm
endSpinner();
end;
Utils.HideSpinner('spinner');
tmrReturn.Enabled := false;
FViewMain.ViewOrders('Success: Order Successfully Deleted');
end;
......
......@@ -260,7 +260,7 @@ implementation
{$R *.dfm}
uses
View.Home, View.Main, View.AddOrder, View.AddAddress;
View.Home, View.Main, View.AddOrder, View.AddAddress, Utils;
procedure TFOrderEntryWeb.WebButton2Click(Sender: TObject);
begin
......@@ -419,9 +419,16 @@ end;
procedure TFOrderEntryWeb.btnDeleteClick(Sender: TObject);
begin
asm
var confirmationModal = new bootstrap.Modal(document.getElementById('confirmation_modal'), {
keyboard: false });
confirmationModal.show();
var modal = document.getElementById('confirmation_modal');
// ensure the modal is directly under <body>
if (modal && modal.parentNode !== document.body) {
document.body.appendChild(modal);
}
var bsModal = new bootstrap.Modal(modal, {
keyboard: false
});
bsModal.show();
end;
end;
......@@ -565,11 +572,18 @@ begin
end
else
begin
Utils.ShowSpinner('spinner');
asm
var confirmationModal = new bootstrap.Modal(document.getElementById('confirmation_modal'), {
keyboard: false });
confirmationModal.hide();
startSpinner();
var modal = document.getElementById('confirmation_modal');
// ensure the modal is directly under <body>
if (modal && modal.parentNode !== document.body) {
document.body.appendChild(modal);
}
var bsModal = new bootstrap.Modal(modal, {
keyboard: false
});
bsModal.hide();
end;
delOrder();
tmrReturn.Enabled := true;
......@@ -731,9 +745,16 @@ begin
document.getElementById('btn_confirm_cancel').innerText := 'No';
document.getElementById('btn_confirm_delete').innerText := 'Yes';
asm
var confirmationModal = new bootstrap.Modal(document.getElementById('confirmation_modal'), {
keyboard: false });
confirmationModal.show();
var modal = document.getElementById('confirmation_modal');
// ensure the modal is directly under <body>
if (modal && modal.parentNode !== document.body) {
document.body.appendChild(modal);
}
var bsModal = new bootstrap.Modal(modal, {
keyboard: false
});
bsModal.show();
end;
end;
......@@ -983,9 +1004,7 @@ end;
procedure TFOrderEntryWeb.tmrReturnTimer(Sender: TObject);
begin
asm
endSpinner();
end;
Utils.HideSpinner('spinner');
tmrReturn.Enabled := false;
FViewMain.ViewOrders('Success: Order Successfully Deleted');
end;
......
......@@ -98,7 +98,7 @@ object FViewOrders: TFViewOrders
BorderColor = clSilver
ChildOrder = 11
ElementFont = efCSS
ElementHeaderClassName = 'thead-light sticky-top bg-light'
ElementHeaderClassName = 'thead-light sticky-top bg-light border-light'
ElementPosition = epRelative
ElementTableClassName = 'table table-striped table-hover table-bordered text-sm'
Footer.ButtonActiveElementClassName = 'btn btn-primary'
......@@ -192,8 +192,10 @@ object FViewOrders: TFViewOrders
Title = 'Price'
end
item
ElementClassName = 'text-nowrap'
DataField = 'qbRefNum'
Title = 'QB Ref Num'
TitleElementClassName = 'min-w-80'
end
item
DataField = 'colors'
......@@ -235,7 +237,9 @@ object FViewOrders: TFViewOrders
ItemIndex = -1
LookupValues = <
item
Value = 'o.ORDER_ID DESC'
Value =
'COALESCE(cpo.staff_fields_order_date, wpo.staff_fields_order_dat' +
'e, cdo.staff_fields_order_date) DESC'
DisplayText = 'ID'
end
item
......
......@@ -49,7 +49,7 @@
<!-- Table Section -->
<div id="order_table_section" class="overflow-auto mt-2"
style="max-height: calc(100vh - 250px); padding-bottom: 0; width: 100%;">
<table id="tblPhoneGrid" class="table table-striped table-bordered" style="width: 100%;">
<table id="tblPhoneGrid" class="table table-striped table-bordered border-light" style="width: 100%;">
<thead class="sticky-top thead-light">
<tr style="font-size: 0.875rem;">
<!-- Table headers are dynamically generated -->
......@@ -71,3 +71,6 @@
</div>
</div>
......@@ -123,15 +123,29 @@ var
implementation
uses
XData.Model.Classes, View.Main, View.AddOrder, View.Search, View.SetStatus;
XData.Model.Classes, View.Main, View.AddOrder, View.Search, View.SetStatus, Utils;
{$R *.dfm}
class function TFViewOrders.CreateForm(AElementID, Info: string): TWebForm;
var
localInfo: string;
begin
localInfo := info;
Application.CreateForm(TFViewOrders, AElementID, Result,
procedure(AForm: TObject)
begin
with TFViewOrders(AForm) do
begin
TFViewOrders(AForm).info := LocalInfo;
end;
end
);
end;
procedure TFViewOrders.btnPDFClick(Sender: TObject);
begin
asm
startSpinner();
end;
Utils.ShowSpinner('spinner');
GenerateReportPDF;
end;
......@@ -152,8 +166,8 @@ begin
// Open the PDF in a new browser tab without needing a different form
// This method is much faster too, even for large datasets
window.open(pdfURL, '_blank');
asm
endSpinner();
begin
Utils.HideSpinner('Spinner');
end;
end;
......@@ -176,6 +190,7 @@ var
today: TDateTime;
params: TStringList;
begin
Utils.ShowSpinner('spinner');
DMConnection.ApiConnection.Connected := True;
PageNumber := 1;
TotalPages := 1; // Initial total pages
......@@ -200,7 +215,7 @@ begin
wcbPageSize.Text := '500';
PageSize := 500;
wlcbOrderBy.DisplayText := 'Order Date';
OrderBy := 'o.ORDER_DATE DESC';
OrderBy := 'COALESCE(cpo.staff_fields_order_date, wpo.staff_fields_order_date, cdo.staff_fields_order_date) DESC';
end
else
begin
......@@ -258,22 +273,6 @@ begin
getOrders(generateSearchOptions());
end;
class function TFViewOrders.CreateForm(AElementID, Info: string): TWebForm;
var
localInfo: string;
begin
localInfo := info;
Application.CreateForm(TFViewOrders, AElementID, Result,
procedure(AForm: TObject)
begin
with TFViewOrders(AForm) do
begin
TFViewOrders(AForm).info := LocalInfo;
end;
end
);
end;
procedure TFViewOrders.ShowAddOrderForm();
// displays the add order pop-up so the user can choose a customer
......@@ -397,9 +396,7 @@ begin
begin
if newform.confirm then
begin
asm
startSpinner();
end;
Utils.ShowSpinner('spinner');
StatusJSON := TJSONObject.Create;
StatusJSON.AddPair('ORDER_ID', OrderID);
StatusJSON.AddPair('date', DateTimeToStr(newform.dtpDate.Date));
......@@ -423,9 +420,7 @@ end;
procedure TFViewOrders.tmrReturnTimer(Sender: TObject);
begin
asm
endSpinner();
end;
Utils.HideSpinner('spinner');
tmrReturn.Enabled := false;
getOrders(fViewMain.search);
end;
......@@ -669,11 +664,9 @@ var
orderListLength: integer;
TotalPages: integer;
begin
Utils.ShowSpinner('spinner');
if PageNumber > 0 then
begin
asm
startSpinner();
end;
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetOrders', [searchOptions]));
orderList := TJSObject(xdcResponse.Result);
......@@ -682,10 +675,6 @@ begin
xdwdsOrders.SetJsonData(orderList['data']);
xdwdsOrders.Open;
asm
endSpinner();
end;
orderListLength := integer(orderList['count']);
TotalPages := ( (orderListLength + PageSize - 1) div PageSize);
......@@ -708,6 +697,7 @@ begin
// Optional: Continue using pagination if needed
GeneratePagination(TotalPages);
Utils.HideSpinner('spinner');
end;
end;
......
......@@ -167,7 +167,7 @@ begin
if params.values['null2'] <> '' then
begin
cbNull1.Checked := StrToBool(params.Values['null2']);
cbNull2.Checked := StrToBool(params.Values['null2']);
if StrToBool(params.Values['null2']) then
begin
dtpStartDate2.Visible := false;
......@@ -200,6 +200,10 @@ begin
dtpStartDate2.Date := 0;
dtpEndDate2.Date := 0;
cbNull2.Checked := false;
dtpStartDate1.Visible := true;
dtpStartDate2.Visible := true;
dtpEndDate1.Visible := true;
dtpEndDate2.Visible := true;
end;
procedure TFSearch.btnConfirmClick(Sender: TObject);
......
......@@ -62,7 +62,7 @@ implementation
{$R *.dfm}
uses View.Main;
uses View.Main, Utils;
procedure TFSelectCustomer.WebFormCreate(Sender: TObject);
begin
......@@ -75,9 +75,7 @@ end;
procedure TFSelectCustomer.WebFormShow(Sender: TObject);
begin
asm
startSpinner();
end;
Utils.ShowSpinner('spinner');
getCustomers();
end;
......@@ -112,9 +110,7 @@ begin
// Manually populate the grid
PopulateGridManually;
asm
endSpinner();
end;
Utils.HideSpinner('spinner');
end;
procedure TFSelectCustomer.PopulateGridManually;
......@@ -192,16 +188,14 @@ begin
CustomerJSON.AddPair('name', xdwdsCustomers.FieldByName('CompanyName').AsString);
CustomerJSON.AddPair('mode', 'ADD');
asm
startSpinner()
end;
Utils.ShowSpinner('spinner');
Response := await(XDataWebClient1.RawInvokeAsync('ILookupService.ImportQBCustomer',
[customerJSON.ToString]));
notification := TJSObject(Response.Result);
asm
endSpinner();
end;
Utils.HideSpinner('spinner');
FViewMain.ViewAddCustomer(string(notification['CustomerID']), string(notification['status']));
Close();
......
......@@ -165,6 +165,7 @@ is-invalid .form-check-input {
.table tbody tr:hover {
background-color: #d1e7fd; /* Light blue color for hover effect */
cursor: pointer;
margin-top: 5px;
}
.form-input{
......@@ -179,6 +180,19 @@ is-invalid .form-check-input {
transition: background-color 0.3s ease;
}
.table thead th{
border: 2px;
background-color: #e6e6e6;
}
.table thead {
border-color: #e6e6e6;
}
.min-w-80 {
min-width: 80px;
}
.table {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
border-radius: 5px;
......@@ -341,6 +355,18 @@ is-invalid .form-check-input {
box-sizing: border-box !important; /* Prevent borders from affecting dimensions */
}
#tblPhoneGrid {
--bs-table-bg: #fff;
--bs-table-border-color: #dee2e6; /* or whatever border tone you like */
}
/* and make sure the table collapses borders so there are no gaps */
#tblPhoneGrid {
border-collapse: collapse !important;
}
......
.lds-roller {
display: inline-block;
position: relative;
width: 80px;
height: 80px;
}
.lds-roller div {
animation: lds-roller 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
transform-origin: 40px 40px;
}
.lds-roller div:after {
content: " ";
display: block;
position: absolute;
width: 10px;
height: 10px;
border-radius: 50%;
background: #204d74;
margin: -5px 0 0 -5px;
}
.lds-roller div:nth-child(1) {
animation-delay: -0.036s;
}
.lds-roller div:nth-child(1):after {
top: 63px;
left: 63px;
}
.lds-roller div:nth-child(2) {
animation-delay: -0.072s;
}
.lds-roller div:nth-child(2):after {
top: 68px;
left: 56px;
}
.lds-roller div:nth-child(3) {
animation-delay: -0.108s;
}
.lds-roller div:nth-child(3):after {
top: 71px;
left: 48px;
}
.lds-roller div:nth-child(4) {
animation-delay: -0.144s;
}
.lds-roller div:nth-child(4):after {
top: 72px;
left: 40px;
}
.lds-roller div:nth-child(5) {
animation-delay: -0.18s;
}
.lds-roller div:nth-child(5):after {
top: 71px;
left: 32px;
}
.lds-roller div:nth-child(6) {
animation-delay: -0.216s;
}
.lds-roller div:nth-child(6):after {
top: 68px;
left: 24px;
}
.lds-roller div:nth-child(7) {
animation-delay: -0.252s;
}
.lds-roller div:nth-child(7):after {
top: 63px;
left: 17px;
}
.lds-roller div:nth-child(8) {
animation-delay: -0.288s;
}
.lds-roller div:nth-child(8):after {
top: 56px;
left: 12px;
}
@keyframes lds-roller {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<html><head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<noscript>Your browser does not support JavaScript!</noscript>
<link rel="icon" href="data:;base64,=">
<title>Web KG Orders</title>
<link href="css/app.css" rel="stylesheet" type="text/css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/2.3.1/css/flag-icon.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.0/css/all.min.css" rel="stylesheet">
<link crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js" type="text/javascript"></script>
<script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>
<script type="text/javascript" src="$(ProjectName).js"></script>
<script>
function startSpinner() {
//window.scrollTo(0, 0);
document.body.style.setProperty('--spinner-top', window.scrollY+'px');
$(".hide-scene").addClass("scene");
}
function endSpinner() {
$(".hide-scene").removeClass("scene");
}
</script>
<title>EM Systems webKGOrders App</title>
<script type="text/javascript" src="$(ProjectName).js"></script>
<style>
/*-----svg loader styles-------*/
:root {
--spinner-top: 0px; }
.hide-scene {
display:none;
}
.scene {
position: absolute;
z-index: 9999999;
top: var(--spinner-top);
width: 100%;
height: 100%;
perspective: 600;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
align-items: center;
justify-content: center;
}
.scene svg {
width: 165px;
height: 165px;
/* background-color: lavender; */
}
@keyframes arrow-spin {
50% {
transform: rotateY(360deg);
}
}
/*-------------------------------------------*/
</style>
</head>
<body>
</body>
<script type="text/javascript">
rtl.run();
</script>
<div class="hide-scene">
<svg
version="1.1"
id="dc-spinner"
xmlns="http://www.w3.org/2000/svg"
x="0px" y="0px"
width:"38"
height:"38"
viewBox="0 0 38 38"
preserveAspectRatio="xMinYMin meet">
<circle cx="20" cy="20" r="16" fill="#D3D3D3"></circle>
<text x="55%" y="54%" font-family="Monaco" font-size="2px" text-anchor="middle" dy=".3em" style="letter-spacing:0.6">PROCESSING
<animate
attributeName="opacity"
values="0;1;0" dur="1.8s"
repeatCount="indefinite"/>
</text>
<path fill="#373a42" d="M20,35c-8.271,0-15-6.729-15-15S11.729,5,20,5s15,6.729,15,15S28.271,35,20,35z M20,5.203
C11.841,5.203,5.203,11.841,5.203,20c0,8.159,6.638,14.797,14.797,14.797S34.797,28.159,34.797,20
C34.797,11.841,28.159,5.203,20,5.203z">
</path>
<path fill="#373a42" d="M20,33.125c-7.237,0-13.125-5.888-13.125-13.125S12.763,6.875,20,6.875S33.125,12.763,33.125,20
S27.237,33.125,20,33.125z M20,7.078C12.875,7.078,7.078,12.875,7.078,20c0,7.125,5.797,12.922,12.922,12.922
S32.922,27.125,32.922,20C32.922,12.875,27.125,7.078,20,7.078z">
</path>
<path fill="#2AA198" stroke="#2AA198" stroke-width="0.6027" stroke-miterlimit="10" d="M5.203,20
c0-8.159,6.638-14.797,14.797-14.797V5C11.729,5,5,11.729,5,20s6.729,15,15,15v-0.203C11.841,34.797,5.203,28.159,5.203,20z">
<animateTransform
attributeName="transform"
type="rotate"
from="0 20 20"
to="360 20 20"
calcMode="spline"
keySplines="0.4, 0, 0.2, 1"
keyTimes="0;1"
dur="2s"
repeatCount="indefinite" />
</path>
<path fill="#859900" stroke="#859900" stroke-width="0.2027" stroke-miterlimit="10" d="M7.078,20
c0-7.125,5.797-12.922,12.922-12.922V6.875C12.763,6.875,6.875,12.763,6.875,20S12.763,33.125,20,33.125v-0.203
C12.875,32.922,7.078,27.125,7.078,20z">
<animateTransform
attributeName="transform"
type="rotate"
from="0 20 20"
to="360 20 20"
dur="1.8s"
repeatCount="indefinite" />
</path>
</svg>
</div>
</html>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta content="width=device-width, initial-scale=1" name="viewport"/>
<noscript>Your browser does not support JavaScript!</noscript>
<link href="data:;base64,=" rel="icon"/>
<title>Web KG Orders</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/2.3.1/css/flag-icon.min.css" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.0/css/all.min.css" rel="stylesheet"/>
<link crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js" type="text/javascript"></script>
<script crossorigin="anonymous" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" src="https://code.jquery.com/jquery-3.7.1.js"></script>
<script src="$(ProjectName).js" type="text/javascript"></script>
<title>EM Systems webKGOrders App</title>
<link href="css/app.css" rel="stylesheet" type="text/css"/>
<link href="css/spinner.css" rel="stylesheet" type="text/css">
<script src="$(ProjectName).js" type="text/javascript"></script>
<body>
</body>
<script type="text/javascript">rtl.run();</script>
</html>
......@@ -28,7 +28,8 @@ uses
View.Customers in 'View.Customers.pas' {FViewCustomers: TWebForm} {*.html},
AddCustomer in 'AddCustomer.pas' {FViewAddCustomer: TWebForm} {*.html},
View.AddAddress in 'View.AddAddress.pas' {FViewAddAddress: TWebForm} {*.html},
View.SelectCustomer in 'View.SelectCustomer.pas' {FSelectCustomer: TWebForm} {*.html};
View.SelectCustomer in 'View.SelectCustomer.pas' {FSelectCustomer: TWebForm} {*.html},
Utils in 'Utils.pas';
{$R *.res}
......
......@@ -5,7 +5,7 @@
<FrameworkType>VCL</FrameworkType>
<MainSource>webKGOrders.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Config Condition="'$(Config)'==''">Release</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Application</AppType>
......@@ -107,7 +107,6 @@
<TMSWebDefines>RELEASE</TMSWebDefines>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<VerInfo_Build>8</VerInfo_Build>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.8;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;LastCompiledTime=2018/08/22 16:25:56</VerInfo_Keys>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
......@@ -206,9 +205,11 @@
<FormType>dfm</FormType>
<DesignClass>TWebForm</DesignClass>
</DCCReference>
<DCCReference Include="Utils.pas"/>
<None Include="index.html"/>
<None Include="css\app.css"/>
<None Include="config\config.json"/>
<None Include="css\spinner.css"/>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
......@@ -245,6 +246,12 @@
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="Win32\Release\webKGOrders.exe" Configuration="Release" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>webKGOrders.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="config\config.json" Configuration="Debug" Class="ProjectFile"/>
<DeployFile LocalName="config\config.json" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
......@@ -252,6 +259,12 @@
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="config\config.json" Configuration="Release" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="css\app.css" Configuration="Debug" Class="ProjectFile"/>
<DeployFile LocalName="css\app.css" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
......@@ -259,6 +272,18 @@
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="css\app.css" Configuration="Release" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="css\spinner.css" Configuration="Release" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="index.html" Configuration="Debug" Class="ProjectFile"/>
<DeployFile LocalName="index.html" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
......@@ -266,6 +291,12 @@
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="index.html" Configuration="Release" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="template\bootstrap\bootstrap.min.css" Configuration="Debug" Class="ProjectFile"/>
<DeployFile LocalName="template\bootstrap\bootstrap.min.js" Configuration="Debug" Class="ProjectFile"/>
<DeployFile LocalName="template\bootstrap\dataTables.bootstrap.css" Configuration="Debug" Class="ProjectFile"/>
......
......@@ -116,8 +116,8 @@
<DCC_UnitSearchPath>C:\RADTOOLS\FastMM4;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_MajorVer>0</VerInfo_MajorVer>
<VerInfo_MinorVer>9</VerInfo_MinorVer>
<VerInfo_Release>2</VerInfo_Release>
<VerInfo_Keys>CompanyName=EM Systems;FileDescription=$(MSBuildProjectName);FileVersion=0.9.2.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Release>4</VerInfo_Release>
<VerInfo_Keys>CompanyName=EM Systems;FileDescription=$(MSBuildProjectName);FileVersion=0.9.4.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=0.9.4.0;Comments=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
......@@ -130,6 +130,12 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
<DCC_UnitSearchPath>C:\RADTOOLS\FastMM4;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_MajorVer>0</VerInfo_MajorVer>
<VerInfo_MinorVer>9</VerInfo_MinorVer>
<VerInfo_Release>2</VerInfo_Release>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win64)'!=''">
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
......
[Settings]
MemoLogLevel=3
FileLogLevel=5
webClientVersion=0.9.2
webClientVersion=0.9.4
LogFileNum=661
[Database]
Server=192.168.159.131
--Server=192.168.102.130
--Server=192.168.159.131
Server=192.168.102.130
--Server=192.168.75.133
Database=kg_order_entry
Username=root
......
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