2023-09-25 23:55:28 +02:00
|
|
|
unit WebSiteControllerU;
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
|
|
|
MVCFramework, System.Diagnostics, JsonDataObjects, MVCFramework.Commons, MVCFramework.HTMX;
|
|
|
|
|
|
|
|
type
|
|
|
|
|
|
|
|
[MVCPath('/people')]
|
|
|
|
TWebSiteController = class(TMVCController)
|
|
|
|
protected
|
|
|
|
function GeneratePeopleListAsCSV: String;
|
2023-11-01 23:12:56 +01:00
|
|
|
procedure OnBeforeAction(AContext: TWebContext; const AActionName: string; var AHandled: Boolean); override;
|
2023-09-25 23:55:28 +02:00
|
|
|
public
|
|
|
|
[MVCPath]
|
|
|
|
[MVCHTTPMethods([httpGET])]
|
|
|
|
function PeopleList: String;
|
|
|
|
|
|
|
|
[MVCPath('/search')]
|
|
|
|
[MVCHTTPMethods([httpGET])]
|
|
|
|
function PeopleSearch(const [MVCFromQueryString('q', '')] SearchText: String): String;
|
|
|
|
|
|
|
|
[MVCPath('/exports/csv')]
|
|
|
|
[MVCHTTPMethods([httpGET])]
|
|
|
|
function ExportPeopleListAsCSV_API: String;
|
|
|
|
|
|
|
|
[MVCPath]
|
|
|
|
[MVCHTTPMethods([httpPOST])]
|
|
|
|
[MVCConsumes(TMVCMediaType.APPLICATION_FORM_URLENCODED)]
|
2023-11-04 11:51:52 +01:00
|
|
|
procedure SavePerson(
|
|
|
|
const [MVCFromContentField('first_name')] FirstName: String;
|
|
|
|
const [MVCFromContentField('last_name')] LastName: String;
|
|
|
|
const [MVCFromContentField('age', 0)] Age: Integer;
|
2023-11-04 16:58:37 +01:00
|
|
|
const [MVCFromContentField('items')] Devices: TArray<String>
|
2023-11-04 11:51:52 +01:00
|
|
|
);
|
2023-09-25 23:55:28 +02:00
|
|
|
|
|
|
|
[MVCPath('/delete/($guid)')]
|
|
|
|
[MVCHTTPMethods([httpDELETE])]
|
|
|
|
procedure DeletePerson(const guid: string);
|
|
|
|
|
|
|
|
[MVCPath('/new')]
|
|
|
|
[MVCHTTPMethods([httpGET])]
|
|
|
|
[MVCProduces(TMVCMediaType.TEXT_HTML)]
|
2023-11-04 11:51:52 +01:00
|
|
|
function NewPerson: String;
|
2023-09-25 23:55:28 +02:00
|
|
|
|
2023-09-26 19:29:03 +02:00
|
|
|
[MVCPath('/modal/fordelete/($guid)')]
|
|
|
|
[MVCHTTPMethods([httpGET])]
|
|
|
|
[MVCProduces(TMVCMediaType.TEXT_HTML)]
|
|
|
|
function ShowModalForDelete(guid: string): String;
|
|
|
|
|
|
|
|
|
2023-09-25 23:55:28 +02:00
|
|
|
[MVCPath('/edit/($guid)')]
|
|
|
|
[MVCHTTPMethods([httpGET])]
|
|
|
|
[MVCProduces(TMVCMediaType.TEXT_HTML)]
|
|
|
|
function EditPerson(guid: string): String;
|
|
|
|
|
|
|
|
[MVCPath]
|
|
|
|
[MVCHTTPMethods([httpGET])]
|
|
|
|
[MVCProduces(TMVCMediaType.TEXT_HTML)]
|
|
|
|
procedure Index;
|
|
|
|
|
2023-09-26 19:29:03 +02:00
|
|
|
[MVCPath('/modal')]
|
|
|
|
[MVCHTTPMethods([httpGET])]
|
|
|
|
[MVCProduces(TMVCMediaType.TEXT_HTML)]
|
|
|
|
function ShowModal: String;
|
|
|
|
|
2023-09-25 23:55:28 +02:00
|
|
|
[MVCPath('/mustacheshowcase')]
|
|
|
|
[MVCHTTPMethods([httpGET])]
|
|
|
|
[MVCProduces(TMVCMediaType.TEXT_HTML)]
|
2023-11-04 11:51:52 +01:00
|
|
|
function MustacheTemplateShowCase: String;
|
2023-09-25 23:55:28 +02:00
|
|
|
end;
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
{ TWebSiteController }
|
|
|
|
|
|
|
|
uses DAL, System.SysUtils, Web.HTTPApp;
|
|
|
|
|
|
|
|
procedure TWebSiteController.DeletePerson(const guid: string);
|
|
|
|
var
|
|
|
|
LDAL: IPeopleDAL;
|
|
|
|
begin
|
|
|
|
LDAL := TServicesFactory.GetPeopleDAL;
|
|
|
|
LDAL.DeleteByGUID(GUID);
|
2024-07-28 23:28:29 +02:00
|
|
|
Context.Response.HXSetLocation('/people');
|
2023-09-25 23:55:28 +02:00
|
|
|
RenderStatusMessage(HTTP_STATUS.OK);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TWebSiteController.EditPerson(guid: string): String;
|
|
|
|
var
|
|
|
|
LDAL: IPeopleDAL;
|
|
|
|
lPerson: TPerson;
|
|
|
|
lDevices: TDeviceList;
|
|
|
|
lItem: TDevice;
|
|
|
|
begin
|
|
|
|
LDAL := TServicesFactory.GetPeopleDAL;
|
|
|
|
lPerson := LDAL.GetPersonByGUID(guid);
|
|
|
|
try
|
|
|
|
lDevices := LDAL.GetDevicesList;
|
|
|
|
try
|
|
|
|
ViewData['person'] := lPerson;
|
|
|
|
for lItem in lDevices do
|
|
|
|
begin
|
|
|
|
lItem.Selected := lPerson.Items.Contains(lItem.DeviceName);
|
|
|
|
end;
|
|
|
|
ViewData['deviceslist'] := lDevices;
|
2023-11-04 11:51:52 +01:00
|
|
|
Result := Page(['editperson']);
|
2023-09-25 23:55:28 +02:00
|
|
|
finally
|
|
|
|
lDevices.Free;
|
|
|
|
end;
|
|
|
|
finally
|
|
|
|
lPerson.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TWebSiteController.ExportPeopleListAsCSV_API: String;
|
|
|
|
begin
|
|
|
|
ContentType := TMVCMediaType.TEXT_CSV;
|
|
|
|
Context.Response.CustomHeaders.Values['Content-Disposition'] := 'attachment; filename=people.csv';
|
|
|
|
Result := GeneratePeopleListAsCSV;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TWebSiteController.GeneratePeopleListAsCSV: String;
|
|
|
|
var
|
|
|
|
LDAL: IPeopleDAL;
|
|
|
|
lPeople: TPeople;
|
|
|
|
begin
|
|
|
|
LDAL := TServicesFactory.GetPeopleDAL;
|
|
|
|
lPeople := LDAL.GetPeople;
|
|
|
|
try
|
|
|
|
ViewData['people'] := lPeople;
|
|
|
|
Result := GetRenderedView(['people_header.csv', 'people_list.csv']);
|
|
|
|
finally
|
|
|
|
lPeople.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TWebSiteController.Index;
|
|
|
|
begin
|
|
|
|
Redirect('/people');
|
|
|
|
end;
|
|
|
|
|
2023-11-04 11:51:52 +01:00
|
|
|
function TWebSiteController.MustacheTemplateShowCase: String;
|
2023-09-25 23:55:28 +02:00
|
|
|
var
|
|
|
|
LDAL: IPeopleDAL;
|
|
|
|
lPeople, lPeople2: TPeople;
|
|
|
|
lMyObj: TMyObj;
|
|
|
|
begin
|
|
|
|
LDAL := TServicesFactory.GetPeopleDAL;
|
|
|
|
lPeople := LDAL.GetPeople;
|
|
|
|
try
|
|
|
|
lPeople2 := TPeople.Create;
|
|
|
|
try
|
|
|
|
lMyObj := TMyObj.Create;
|
|
|
|
try
|
|
|
|
lMyObj.RawHTML := '<h1>This is</h1>Raw<br><span>HTML</span>';
|
|
|
|
ViewData['people'] := lPeople;
|
|
|
|
ViewData['people2'] := lPeople2;
|
|
|
|
ViewData['myobj'] := lMyObj;
|
2023-11-04 11:51:52 +01:00
|
|
|
Result := PageFragment(['showcase']); //it is not a "fragment" but we don't need standard headers/footer
|
2023-09-25 23:55:28 +02:00
|
|
|
finally
|
|
|
|
lMyObj.Free;
|
|
|
|
end;
|
|
|
|
finally
|
|
|
|
lPeople2.Free;
|
|
|
|
end;
|
|
|
|
finally
|
|
|
|
lPeople.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2023-11-04 11:51:52 +01:00
|
|
|
function TWebSiteController.NewPerson: String;
|
2023-09-25 23:55:28 +02:00
|
|
|
var
|
|
|
|
LDAL: IPeopleDAL;
|
|
|
|
lDevices: TDeviceList;
|
|
|
|
begin
|
|
|
|
LDAL := TServicesFactory.GetPeopleDAL;
|
|
|
|
lDevices := LDAL.GetDevicesList;
|
|
|
|
try
|
|
|
|
ViewData['deviceslist'] := lDevices;
|
2023-11-04 11:51:52 +01:00
|
|
|
Result := Page(['editperson']);
|
2023-09-25 23:55:28 +02:00
|
|
|
finally
|
|
|
|
lDevices.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2023-11-01 23:12:56 +01:00
|
|
|
procedure TWebSiteController.OnBeforeAction(AContext: TWebContext;
|
|
|
|
const AActionName: string; var AHandled: Boolean);
|
|
|
|
begin
|
|
|
|
inherited;
|
|
|
|
SetPagesCommonHeaders(['header']);
|
|
|
|
SetPagesCommonFooters(['footer']);
|
|
|
|
end;
|
|
|
|
|
2023-09-25 23:55:28 +02:00
|
|
|
function TWebSiteController.PeopleList: String;
|
|
|
|
var
|
|
|
|
LDAL: IPeopleDAL;
|
|
|
|
lPeople: TPeople;
|
|
|
|
begin
|
|
|
|
LDAL := TServicesFactory.GetPeopleDAL;
|
|
|
|
lPeople := LDAL.GetPeople;
|
|
|
|
try
|
|
|
|
ViewData['people'] := lPeople;
|
2023-11-01 23:12:56 +01:00
|
|
|
Result := Page(['people_list_search', 'people_list', 'people_list_bottom']);
|
2023-09-25 23:55:28 +02:00
|
|
|
finally
|
|
|
|
lPeople.Free;
|
|
|
|
end;
|
|
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TWebSiteController.PeopleSearch(const SearchText: String): String;
|
|
|
|
var
|
|
|
|
LDAL: IPeopleDAL;
|
|
|
|
lPeople: TPeople;
|
|
|
|
begin
|
|
|
|
LDAL := TServicesFactory.GetPeopleDAL;
|
|
|
|
|
|
|
|
lPeople := LDAL.GetPeople(SearchText);
|
|
|
|
try
|
|
|
|
ViewData['people'] := lPeople;
|
2023-11-01 23:12:56 +01:00
|
|
|
if Context.Request.IsHTMX then
|
2023-09-25 23:55:28 +02:00
|
|
|
begin
|
2023-11-01 23:12:56 +01:00
|
|
|
Result := PageFragment(['people_list']);
|
2023-09-25 23:55:28 +02:00
|
|
|
if SearchText.IsEmpty then
|
2023-10-06 10:46:14 +02:00
|
|
|
Context.Response.HXSetPushUrl('/people/search')
|
2023-09-25 23:55:28 +02:00
|
|
|
else
|
2023-10-06 10:46:14 +02:00
|
|
|
Context.Response.HXSetPushUrl('/people/search?q=' + SearchText);
|
2023-09-25 23:55:28 +02:00
|
|
|
end
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
var lJSON := TJSONObject.Create;
|
|
|
|
try
|
|
|
|
lJSON.S['q'] := SearchText;
|
2023-11-01 23:12:56 +01:00
|
|
|
Result := Page(['people_list_search', 'people_list', 'people_list_bottom'], lJSON);
|
2023-09-25 23:55:28 +02:00
|
|
|
finally
|
|
|
|
lJSON.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
finally
|
|
|
|
lPeople.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2023-11-04 11:51:52 +01:00
|
|
|
procedure TWebSiteController.SavePerson(
|
|
|
|
const FirstName: String;
|
|
|
|
const LastName: String;
|
|
|
|
const Age: Integer;
|
2023-11-04 16:58:37 +01:00
|
|
|
const Devices: TArray<String>);
|
2023-09-25 23:55:28 +02:00
|
|
|
var
|
|
|
|
LPeopleDAL: IPeopleDAL;
|
|
|
|
begin
|
2023-11-04 11:51:52 +01:00
|
|
|
if FirstName.IsEmpty or LastName.IsEmpty or (Age <= 0) then
|
2023-09-25 23:55:28 +02:00
|
|
|
begin
|
|
|
|
{ TODO -oDaniele -cGeneral : Show how to properly render an exception }
|
|
|
|
raise EMVCException.Create('Invalid data', 'First name, last name and age are not optional', 0);
|
|
|
|
end;
|
|
|
|
|
|
|
|
LPeopleDAL := TServicesFactory.GetPeopleDAL;
|
2023-11-04 16:58:37 +01:00
|
|
|
LPeopleDAL.AddPerson(FirstName, LastName, Age, Devices);
|
2023-10-06 10:46:14 +02:00
|
|
|
Context.Response.HXSetRedirect('/people');
|
2023-09-25 23:55:28 +02:00
|
|
|
end;
|
|
|
|
|
2023-09-26 19:29:03 +02:00
|
|
|
function TWebSiteController.ShowModal: String;
|
|
|
|
begin
|
|
|
|
var lJSON := StrToJSONObject('{"message":"Do you really want to delete row?", "title":"Bootstrap Modal Dialog"}');
|
|
|
|
try
|
2023-11-04 11:51:52 +01:00
|
|
|
Result := PageFragment(['modal'], lJSON);
|
2023-09-26 19:29:03 +02:00
|
|
|
finally
|
|
|
|
lJSON.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TWebSiteController.ShowModalForDelete(guid: string): String;
|
|
|
|
begin
|
|
|
|
var lJSON := TJsonObject.Create;
|
|
|
|
try
|
|
|
|
lJSON.S['title'] := 'Bootstrap Modal Dialog';
|
|
|
|
lJSON.S['message'] := 'Do you really want to delete row?';
|
|
|
|
lJSON.S['guid'] := guid;
|
2023-11-04 11:51:52 +01:00
|
|
|
Result := PageFragment(['modal'], lJSON);
|
2023-09-26 19:29:03 +02:00
|
|
|
finally
|
|
|
|
lJSON.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2023-09-25 23:55:28 +02:00
|
|
|
end.
|