Compare commits

...

28 Commits

Author SHA1 Message Date
Hargata Softworks
79633dbe1d Merge pull request #799 from hargata/Hargata/796
Update configurator
2025-01-10 12:13:54 -07:00
DESKTOP-T0O5CDB\DESK-555BD
f325306e20 Update configurator 2025-01-10 12:13:34 -07:00
Hargata Softworks
4778656063 Merge pull request #798 from hargata/Hargata/796
fix mileage not included.
2025-01-10 11:02:35 -07:00
DESKTOP-T0O5CDB\DESK-555BD
f7e00523c2 fix mileage not included. 2025-01-10 11:01:24 -07:00
Hargata Softworks
bf3df7230b Merge pull request #797 from hargata/Hargata/796
Hargata/796
2025-01-10 10:03:51 -07:00
DESKTOP-T0O5CDB\DESK-555BD
c5182e0ed6 lol 2025-01-10 10:03:09 -07:00
DESKTOP-T0O5CDB\DESK-555BD
4081438cba Defer calculations if odometer not provided. 2025-01-10 10:01:16 -07:00
Hargata Softworks
b72fe2bf37 Merge pull request #793 from hargata/Hargata/warn.dir.diff
Warn when working directory differs from content path.
2025-01-09 10:02:49 -07:00
DESKTOP-T0O5CDB\DESK-555BD
4d9c687709 Warn when working directory differs from content path. 2025-01-09 10:02:14 -07:00
Hargata Softworks
792f295c45 Merge pull request #791 from hargata/Hargata/769
Fixed backup restoration for userConfig.json
2025-01-08 20:38:52 -07:00
DESKTOP-T0O5CDB\DESK-555BD
af28753558 use a static string instead. 2025-01-08 20:37:45 -07:00
DESKTOP-T0O5CDB\DESK-555BD
24fb663599 Fixed backup restoration for userConfig.json 2025-01-08 20:33:38 -07:00
Hargata Softworks
140506c9c3 Merge pull request #790 from hargata/Hargata/769
moved userConfig file into data folder.
2025-01-08 20:26:13 -07:00
DESKTOP-T0O5CDB\DESK-555BD
519f159c8c moved userConfig file into data folder. 2025-01-08 20:25:17 -07:00
Hargata Softworks
bb019cbcd9 Merge pull request #789 from hargata/Hargata/769
Fix gas record files attachment
2025-01-08 16:19:57 -07:00
DESKTOP-T0O5CDB\DESK-555BD
84219627ff Fix gas record files attachment 2025-01-08 16:18:36 -07:00
Hargata Softworks
f218e878c6 Merge pull request #788 from hargata/Hargata/769
Document Upload Endpoint
2025-01-08 15:55:30 -07:00
DESKTOP-T0O5CDB\DESK-555BD
520f47955b cleaned up usings. 2025-01-08 14:15:15 -07:00
DESKTOP-T0O5CDB\DESK-555BD
8110ee18f1 Create endpoint to upload documents and add ability to attach uploaded documents to records. 2025-01-08 14:14:23 -07:00
Hargata Softworks
55bf817310 Merge pull request #782 from hargata/Hargata/697
added API method that generates a calendar of reminders for the user.
2025-01-08 12:39:26 -07:00
DESKTOP-T0O5CDB\DESK-555BD
f2f55f8118 Restore favicon, previously was served up automatically by browser but now we want to link it explicitly. also brought back the security features for accessing static files. 2025-01-08 12:38:27 -07:00
DESKTOP-T0O5CDB\DESK-555BD
f48e7cd0d4 update Controller Action Name, 2025-01-08 11:11:29 -07:00
DESKTOP-T0O5CDB\DESK-555BD
c82e0c8b9b Use a MD5 hash to get exactly 16 bytes so the GUID is always valid and identical for the calendar event with same date and description. 2025-01-08 10:49:26 -07:00
DESKTOP-T0O5CDB\DESK-555BD
c72877e16b Merge branch 'main' into Hargata/697 2025-01-08 10:40:10 -07:00
Hargata Softworks
ccc9076397 Merge pull request #786 from hargata/Hargata/785
move files out of webrootpath.
2025-01-08 10:13:03 -07:00
DESKTOP-T0O5CDB\DESK-555BD
1c716ecf4a bump version 2025-01-08 10:12:42 -07:00
DESKTOP-T0O5CDB\DESK-555BD
2cc471b944 move files out of webrootpath. 2025-01-08 10:10:41 -07:00
DESKTOP-T0O5CDB\DESK-555BD
a6c450109a added API method that generates a calendar of reminders for the user. 2025-01-07 08:43:25 -07:00
13 changed files with 380 additions and 78 deletions

11
.gitignore vendored
View File

@@ -1,15 +1,6 @@
.vs/
bin/
obj/
wwwroot/images/
cartracker.db
data/cartracker.db
wwwroot/documents/
wwwroot/temp/
wwwroot/imports/
wwwroot/translations/
config/userConfig.json
data/
CarCareTracker.csproj.user
Properties/launchSettings.json
data/cartracker-log.db
data/widgets.html

View File

@@ -34,6 +34,7 @@ namespace CarCareTracker.Controllers
private readonly IFileHelper _fileHelper;
private readonly IMailHelper _mailHelper;
private readonly IConfigHelper _config;
private readonly IWebHostEnvironment _webEnv;
public APIController(IVehicleDataAccess dataAccess,
IGasHelper gasHelper,
IReminderHelper reminderHelper,
@@ -55,7 +56,8 @@ namespace CarCareTracker.Controllers
IConfigHelper config,
IUserLogic userLogic,
IVehicleLogic vehicleLogic,
IOdometerLogic odometerLogic)
IOdometerLogic odometerLogic,
IWebHostEnvironment webEnv)
{
_dataAccess = dataAccess;
_noteDataAccess = noteDataAccess;
@@ -79,6 +81,7 @@ namespace CarCareTracker.Controllers
_vehicleLogic = vehicleLogic;
_fileHelper = fileHelper;
_config = config;
_webEnv = webEnv;
}
public IActionResult Index()
{
@@ -163,7 +166,7 @@ namespace CarCareTracker.Controllers
return Json(response);
}
var vehicleRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId);
var result = vehicleRecords.Select(x => new GenericRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString(), ExtraFields = x.ExtraFields, Tags = string.Join(' ', x.Tags) });
var result = vehicleRecords.Select(x => new GenericRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString(), ExtraFields = x.ExtraFields, Files = x.Files, Tags = string.Join(' ', x.Tags) });
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
{
return Json(result, StaticHelper.GetInvariantOption());
@@ -206,6 +209,7 @@ namespace CarCareTracker.Controllers
Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes,
Cost = decimal.Parse(input.Cost),
ExtraFields = input.ExtraFields,
Files = input.Files,
Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList()
};
_serviceRecordDataAccess.SaveServiceRecordToVehicle(serviceRecord);
@@ -291,6 +295,7 @@ namespace CarCareTracker.Controllers
existingRecord.Description = input.Description;
existingRecord.Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes;
existingRecord.Cost = decimal.Parse(input.Cost);
existingRecord.Files = input.Files;
existingRecord.ExtraFields = input.ExtraFields;
existingRecord.Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList();
_serviceRecordDataAccess.SaveServiceRecordToVehicle(existingRecord);
@@ -322,7 +327,7 @@ namespace CarCareTracker.Controllers
return Json(response);
}
var vehicleRecords = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
var result = vehicleRecords.Select(x => new GenericRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString(), ExtraFields = x.ExtraFields, Tags = string.Join(' ', x.Tags) });
var result = vehicleRecords.Select(x => new GenericRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString(), ExtraFields = x.ExtraFields, Files = x.Files, Tags = string.Join(' ', x.Tags) });
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
{
return Json(result, StaticHelper.GetInvariantOption());
@@ -366,6 +371,7 @@ namespace CarCareTracker.Controllers
Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes,
Cost = decimal.Parse(input.Cost),
ExtraFields = input.ExtraFields,
Files = input.Files,
Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList()
};
_collisionRecordDataAccess.SaveCollisionRecordToVehicle(repairRecord);
@@ -453,6 +459,7 @@ namespace CarCareTracker.Controllers
existingRecord.Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes;
existingRecord.Cost = decimal.Parse(input.Cost);
existingRecord.ExtraFields = input.ExtraFields;
existingRecord.Files = input.Files;
existingRecord.Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList();
_collisionRecordDataAccess.SaveCollisionRecordToVehicle(existingRecord);
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGenericRecord(existingRecord, "repairrecord.update.api", User.Identity.Name));
@@ -484,7 +491,7 @@ namespace CarCareTracker.Controllers
return Json(response);
}
var vehicleRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
var result = vehicleRecords.Select(x => new GenericRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString(), ExtraFields = x.ExtraFields, Tags = string.Join(' ', x.Tags) });
var result = vehicleRecords.Select(x => new GenericRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString(), ExtraFields = x.ExtraFields, Files = x.Files, Tags = string.Join(' ', x.Tags) });
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
{
return Json(result, StaticHelper.GetInvariantOption());
@@ -528,6 +535,7 @@ namespace CarCareTracker.Controllers
Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes,
Cost = decimal.Parse(input.Cost),
ExtraFields = input.ExtraFields,
Files = input.Files,
Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList()
};
_upgradeRecordDataAccess.SaveUpgradeRecordToVehicle(upgradeRecord);
@@ -614,6 +622,7 @@ namespace CarCareTracker.Controllers
existingRecord.Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes;
existingRecord.Cost = decimal.Parse(input.Cost);
existingRecord.ExtraFields = input.ExtraFields;
existingRecord.Files = input.Files;
existingRecord.Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList();
_upgradeRecordDataAccess.SaveUpgradeRecordToVehicle(existingRecord);
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGenericRecord(existingRecord, "upgraderecord.update.api", User.Identity.Name));
@@ -644,7 +653,7 @@ namespace CarCareTracker.Controllers
Response.StatusCode = 400;
return Json(response);
}
var result = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId).Select(x => new TaxRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, ExtraFields = x.ExtraFields, Tags = string.Join(' ', x.Tags) });
var result = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId).Select(x => new TaxRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, ExtraFields = x.ExtraFields, Files = x.Files, Tags = string.Join(' ', x.Tags) });
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
{
return Json(result, StaticHelper.GetInvariantOption());
@@ -721,6 +730,7 @@ namespace CarCareTracker.Controllers
Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes,
Cost = decimal.Parse(input.Cost),
ExtraFields = input.ExtraFields,
Files = input.Files,
Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList()
};
_taxRecordDataAccess.SaveTaxRecordToVehicle(taxRecord);
@@ -790,6 +800,7 @@ namespace CarCareTracker.Controllers
existingRecord.Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes;
existingRecord.Cost = decimal.Parse(input.Cost);
existingRecord.ExtraFields = input.ExtraFields;
existingRecord.Files = input.Files;
existingRecord.Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList();
_taxRecordDataAccess.SaveTaxRecordToVehicle(existingRecord);
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromTaxRecord(existingRecord, "taxrecord.update.api", User.Identity.Name));
@@ -840,7 +851,7 @@ namespace CarCareTracker.Controllers
{
vehicleRecords = _odometerLogic.AutoConvertOdometerRecord(vehicleRecords);
}
var result = vehicleRecords.Select(x => new OdometerRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), InitialOdometer = x.InitialMileage.ToString(), Odometer = x.Mileage.ToString(), Notes = x.Notes, ExtraFields = x.ExtraFields, Tags = string.Join(' ', x.Tags) });
var result = vehicleRecords.Select(x => new OdometerRecordExportModel { Id = x.Id.ToString(), Date = x.Date.ToShortDateString(), InitialOdometer = x.InitialMileage.ToString(), Odometer = x.Mileage.ToString(), Notes = x.Notes, ExtraFields = x.ExtraFields, Files = x.Files, Tags = string.Join(' ', x.Tags) });
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
{
return Json(result, StaticHelper.GetInvariantOption());
@@ -881,6 +892,7 @@ namespace CarCareTracker.Controllers
InitialMileage = (string.IsNullOrWhiteSpace(input.InitialOdometer) || int.Parse(input.InitialOdometer) == default) ? _odometerLogic.GetLastOdometerRecordMileage(vehicleId, new List<OdometerRecord>()) : int.Parse(input.InitialOdometer),
Mileage = int.Parse(input.Odometer),
ExtraFields = input.ExtraFields,
Files = input.Files,
Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList()
};
_odometerRecordDataAccess.SaveOdometerRecordToVehicle(odometerRecord);
@@ -948,6 +960,7 @@ namespace CarCareTracker.Controllers
existingRecord.InitialMileage = int.Parse(input.InitialOdometer);
existingRecord.Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes;
existingRecord.ExtraFields = input.ExtraFields;
existingRecord.Files = input.Files;
existingRecord.Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList();
_odometerRecordDataAccess.SaveOdometerRecordToVehicle(existingRecord);
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromOdometerRecord(existingRecord, "odometerrecord.update.api", User.Identity.Name));
@@ -991,6 +1004,7 @@ namespace CarCareTracker.Controllers
MissedFuelUp = x.MissedFuelUp.ToString(),
Notes = x.Notes,
ExtraFields = x.ExtraFields,
Files = x.Files,
Tags = string.Join(' ', x.Tags)
});
if (_config.GetInvariantApi() || Request.Headers.ContainsKey("culture-invariant"))
@@ -1041,6 +1055,7 @@ namespace CarCareTracker.Controllers
Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes,
Cost = decimal.Parse(input.Cost),
ExtraFields = input.ExtraFields,
Files = input.Files,
Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList()
};
_gasRecordDataAccess.SaveGasRecordToVehicle(gasRecord);
@@ -1085,7 +1100,7 @@ namespace CarCareTracker.Controllers
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGasRecord(existingRecord, "gasrecord.delete.api", User.Identity.Name));
}
return Json(OperationResponse.Conditional(result, "Odometer Record Deleted"));
return Json(OperationResponse.Conditional(result, "Gas Record Deleted"));
}
[HttpPut]
[Route("/api/vehicle/gasrecords/update")]
@@ -1126,6 +1141,7 @@ namespace CarCareTracker.Controllers
existingRecord.Notes = string.IsNullOrWhiteSpace(input.Notes) ? "" : input.Notes;
existingRecord.Cost = decimal.Parse(input.Cost);
existingRecord.ExtraFields = input.ExtraFields;
existingRecord.Files = input.Files;
existingRecord.Tags = string.IsNullOrWhiteSpace(input.Tags) ? new List<string>() : input.Tags.Split(' ').Distinct().ToList();
_gasRecordDataAccess.SaveGasRecordToVehicle(existingRecord);
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGasRecord(existingRecord, "gasrecord.update.api", User.Identity.Name));
@@ -1166,6 +1182,51 @@ namespace CarCareTracker.Controllers
return Json(results);
}
}
[HttpGet]
[Route("/api/calendar")]
public IActionResult Calendar()
{
var vehiclesStored = _dataAccess.GetVehicles();
if (!User.IsInRole(nameof(UserData.IsRootUser)))
{
vehiclesStored = _userLogic.FilterUserVehicles(vehiclesStored, GetUserID());
}
var reminders = _vehicleLogic.GetReminders(vehiclesStored, true);
var calendarContent = StaticHelper.RemindersToCalendar(reminders);
return File(calendarContent, "text/calendar");
}
[HttpPost]
[Route("/api/documents/upload")]
public IActionResult UploadDocument(List<IFormFile> documents)
{
if (documents.Any())
{
List<UploadedFiles> uploadedFiles = new List<UploadedFiles>();
string uploadDirectory = "documents/";
string uploadPath = Path.Combine(_webEnv.ContentRootPath, "data", uploadDirectory);
if (!Directory.Exists(uploadPath))
Directory.CreateDirectory(uploadPath);
foreach (IFormFile document in documents)
{
string fileName = Guid.NewGuid() + Path.GetExtension(document.FileName);
string filePath = Path.Combine(uploadPath, fileName);
using (var stream = System.IO.File.Create(filePath))
{
document.CopyTo(stream);
}
uploadedFiles.Add(new UploadedFiles
{
Location = Path.Combine("/", uploadDirectory, fileName),
Name = Path.GetFileName(document.FileName)
});
}
return Json(uploadedFiles);
} else
{
Response.StatusCode = 400;
return Json(OperationResponse.Failed("No files to upload"));
}
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
[HttpGet]
[Route("/api/vehicle/reminders/send")]

View File

@@ -81,7 +81,7 @@ namespace CarCareTracker.Controllers
private string UploadFile(IFormFile fileToUpload)
{
string uploadDirectory = "temp/";
string uploadPath = Path.Combine(_webEnv.WebRootPath, uploadDirectory);
string uploadPath = Path.Combine(_webEnv.ContentRootPath, "data", uploadDirectory);
if (!Directory.Exists(uploadPath))
Directory.CreateDirectory(uploadPath);
string fileName = Guid.NewGuid() + Path.GetExtension(fileToUpload.FileName);
@@ -95,7 +95,7 @@ namespace CarCareTracker.Controllers
public IActionResult UploadCoordinates(List<string> coordinates)
{
string uploadDirectory = "temp/";
string uploadPath = Path.Combine(_webEnv.WebRootPath, uploadDirectory);
string uploadPath = Path.Combine(_webEnv.ContentRootPath, "data", uploadDirectory);
if (!Directory.Exists(uploadPath))
Directory.CreateDirectory(uploadPath);
string fileName = Guid.NewGuid() + ".csv";

View File

@@ -25,7 +25,7 @@ namespace CarCareTracker.Controllers
return Json(false);
}
string uploadDirectory = "temp/";
string uploadPath = Path.Combine(_webEnv.WebRootPath, uploadDirectory);
string uploadPath = Path.Combine(_webEnv.ContentRootPath, "data", uploadDirectory);
if (!Directory.Exists(uploadPath))
Directory.CreateDirectory(uploadPath);
var fileNameToExport = $"temp/{Guid.NewGuid()}.csv";

View File

@@ -34,7 +34,7 @@ namespace CarCareTracker.Helper
}
public List<string> GetLanguages()
{
var languagePath = Path.Combine(_webEnv.WebRootPath, "translations");
var languagePath = Path.Combine(_webEnv.ContentRootPath, "data", "translations");
var defaultList = new List<string>() { "en_US" };
if (Directory.Exists(languagePath))
{
@@ -72,7 +72,7 @@ namespace CarCareTracker.Helper
{
currentFilePath = currentFilePath.Substring(1);
}
string oldFilePath = Path.Combine(_webEnv.WebRootPath, currentFilePath);
string oldFilePath = currentFilePath.StartsWith("defaults/") ? Path.Combine(_webEnv.WebRootPath, currentFilePath) : Path.Combine(_webEnv.ContentRootPath, "data", currentFilePath);
if (File.Exists(oldFilePath))
{
return oldFilePath;
@@ -94,7 +94,7 @@ namespace CarCareTracker.Helper
}
try
{
var tempPath = Path.Combine(_webEnv.WebRootPath, $"temp/{Guid.NewGuid()}");
var tempPath = Path.Combine(_webEnv.ContentRootPath, "data", $"temp/{Guid.NewGuid()}");
if (!Directory.Exists(tempPath))
Directory.CreateDirectory(tempPath);
//extract zip file
@@ -105,10 +105,10 @@ namespace CarCareTracker.Helper
var translationPath = Path.Combine(tempPath, "translations");
var dataPath = Path.Combine(tempPath, StaticHelper.DbName);
var widgetPath = Path.Combine(tempPath, StaticHelper.AdditionalWidgetsPath);
var configPath = Path.Combine(tempPath, StaticHelper.UserConfigPath);
var configPath = Path.Combine(tempPath, StaticHelper.LegacyUserConfigPath);
if (Directory.Exists(imagePath))
{
var existingPath = Path.Combine(_webEnv.WebRootPath, "images");
var existingPath = Path.Combine(_webEnv.ContentRootPath, "data", "images");
if (!Directory.Exists(existingPath))
{
Directory.CreateDirectory(existingPath);
@@ -130,7 +130,7 @@ namespace CarCareTracker.Helper
}
if (Directory.Exists(documentPath))
{
var existingPath = Path.Combine(_webEnv.WebRootPath, "documents");
var existingPath = Path.Combine(_webEnv.ContentRootPath, "data", "documents");
if (!Directory.Exists(existingPath))
{
Directory.CreateDirectory(existingPath);
@@ -152,7 +152,7 @@ namespace CarCareTracker.Helper
}
if (Directory.Exists(translationPath))
{
var existingPath = Path.Combine(_webEnv.WebRootPath, "translations");
var existingPath = Path.Combine(_webEnv.ContentRootPath, "data", "translations");
if (!Directory.Exists(existingPath))
{
Directory.CreateDirectory(existingPath);
@@ -186,9 +186,9 @@ namespace CarCareTracker.Helper
if (File.Exists(configPath))
{
//check if config folder exists.
if (!Directory.Exists("config/"))
if (!Directory.Exists("data/config"))
{
Directory.CreateDirectory("config/");
Directory.CreateDirectory("data/config");
}
File.Move(configPath, StaticHelper.UserConfigPath, true);
}
@@ -203,7 +203,7 @@ namespace CarCareTracker.Helper
public string MakeAttachmentsExport(List<GenericReportModel> exportData)
{
var folderName = Guid.NewGuid();
var tempPath = Path.Combine(_webEnv.WebRootPath, $"temp/{folderName}");
var tempPath = Path.Combine(_webEnv.ContentRootPath, "data", $"temp/{folderName}");
if (!Directory.Exists(tempPath))
Directory.CreateDirectory(tempPath);
int fileIndex = 0;
@@ -227,10 +227,10 @@ namespace CarCareTracker.Helper
public string MakeBackup()
{
var folderName = $"db_backup_{DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss")}";
var tempPath = Path.Combine(_webEnv.WebRootPath, $"temp/{folderName}");
var imagePath = Path.Combine(_webEnv.WebRootPath, "images");
var documentPath = Path.Combine(_webEnv.WebRootPath, "documents");
var translationPath = Path.Combine(_webEnv.WebRootPath, "translations");
var tempPath = Path.Combine(_webEnv.ContentRootPath, "data", $"temp/{folderName}");
var imagePath = Path.Combine(_webEnv.ContentRootPath, "data", "images");
var documentPath = Path.Combine(_webEnv.ContentRootPath, "data", "documents");
var translationPath = Path.Combine(_webEnv.ContentRootPath, "data", "translations");
var dataPath = StaticHelper.DbName;
var widgetPath = StaticHelper.AdditionalWidgetsPath;
var configPath = StaticHelper.UserConfigPath;
@@ -301,8 +301,8 @@ namespace CarCareTracker.Helper
{
currentFilePath = currentFilePath.Substring(1);
}
string uploadPath = Path.Combine(_webEnv.WebRootPath, newFolder);
string oldFilePath = Path.Combine(_webEnv.WebRootPath, currentFilePath);
string uploadPath = Path.Combine(_webEnv.ContentRootPath, "data", newFolder);
string oldFilePath = Path.Combine(_webEnv.ContentRootPath, "data", currentFilePath);
if (!Directory.Exists(uploadPath))
Directory.CreateDirectory(uploadPath);
string newFileUploadPath = oldFilePath.Replace(tempPath, newFolder);
@@ -319,7 +319,7 @@ namespace CarCareTracker.Helper
{
currentFilePath = currentFilePath.Substring(1);
}
string filePath = Path.Combine(_webEnv.WebRootPath, currentFilePath);
string filePath = Path.Combine(_webEnv.ContentRootPath, "data", currentFilePath);
if (File.Exists(filePath))
{
File.Delete(filePath);

View File

@@ -76,7 +76,8 @@ namespace CarCareTracker.Helper
MissedFuelUp = currentObject.MissedFuelUp,
Notes = currentObject.Notes,
Tags = currentObject.Tags,
ExtraFields = currentObject.ExtraFields
ExtraFields = currentObject.ExtraFields,
Files = currentObject.Files
};
if (currentObject.MissedFuelUp)
{
@@ -86,9 +87,9 @@ namespace CarCareTracker.Helper
unFactoredConsumption = 0;
unFactoredMileage = 0;
}
else if (currentObject.IsFillToFull)
else if (currentObject.IsFillToFull && currentObject.Mileage != default)
{
//if user filled to full.
//if user filled to full and an odometer is provided, otherwise we will defer calculations
if (convertedConsumption > 0.00M && deltaMileage > 0)
{
try
@@ -130,10 +131,14 @@ namespace CarCareTracker.Helper
MissedFuelUp = currentObject.MissedFuelUp,
Notes = currentObject.Notes,
Tags = currentObject.Tags,
ExtraFields = currentObject.ExtraFields
ExtraFields = currentObject.ExtraFields,
Files = currentObject.Files
});
}
previousMileage = currentObject.Mileage;
if (currentObject.Mileage != default)
{
previousMileage = currentObject.Mileage;
}
}
return computedResults;
}

View File

@@ -1,6 +1,8 @@
using CarCareTracker.Models;
using CsvHelper;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
namespace CarCareTracker.Helper
@@ -10,9 +12,10 @@ namespace CarCareTracker.Helper
/// </summary>
public static class StaticHelper
{
public const string VersionNumber = "1.4.2";
public const string VersionNumber = "1.4.3";
public const string DbName = "data/cartracker.db";
public const string UserConfigPath = "config/userConfig.json";
public const string UserConfigPath = "data/config/userConfig.json";
public const string LegacyUserConfigPath = "config/userConfig.json";
public const string AdditionalWidgetsPath = "data/widgets.html";
public const string GenericErrorMessage = "An error occurred, please try again later";
public const string ReminderEmailTemplate = "defaults/reminderemailtemplate.txt";
@@ -240,7 +243,8 @@ namespace CarCareTracker.Helper
public static List<ExtraField> AddExtraFields(List<ExtraField> recordExtraFields, List<ExtraField> templateExtraFields)
{
if (!templateExtraFields.Any()) {
if (!templateExtraFields.Any())
{
return new List<ExtraField>();
}
if (!recordExtraFields.Any())
@@ -261,7 +265,7 @@ namespace CarCareTracker.Helper
extraField.IsRequired = templateExtraFields.Where(x => x.Name == extraField.Name).First().IsRequired;
}
//append extra fields
foreach(ExtraField extraField in templateExtraFields)
foreach (ExtraField extraField in templateExtraFields)
{
if (!recordFieldNames.Contains(extraField.Name))
{
@@ -309,7 +313,8 @@ namespace CarCareTracker.Helper
if (mailConfig != null && !string.IsNullOrWhiteSpace(mailConfig.EmailServer))
{
Console.WriteLine($"SMTP Configured for {mailConfig.EmailServer}");
} else
}
else
{
Console.WriteLine("SMTP Not Configured");
}
@@ -317,7 +322,94 @@ namespace CarCareTracker.Helper
Console.WriteLine($"Message Of The Day: {motd}");
if (string.IsNullOrWhiteSpace(CultureInfo.CurrentCulture.Name))
{
Console.WriteLine("No Locale or Culture Configured for LubeLogger, Check Environment Variables");
Console.WriteLine("WARNING: No Locale or Culture Configured for LubeLogger, Check Environment Variables");
}
//Create folders if they don't exist.
if (!Directory.Exists("data"))
{
Directory.CreateDirectory("data");
Console.WriteLine("Created data directory");
}
if (!Directory.Exists("data/images"))
{
Console.WriteLine("Created images directory");
Directory.CreateDirectory("data/images");
}
if (!Directory.Exists("data/documents"))
{
Directory.CreateDirectory("data/documents");
Console.WriteLine("Created documents directory");
}
if (!Directory.Exists("data/translations"))
{
Directory.CreateDirectory("data/translations");
Console.WriteLine("Created translations directory");
}
if (!Directory.Exists("data/temp"))
{
Directory.CreateDirectory("data/temp");
Console.WriteLine("Created translations directory");
}
if (!Directory.Exists("data/config"))
{
Directory.CreateDirectory("data/config");
Console.WriteLine("Created config directory");
}
}
public static void CheckMigration(string webRootPath, string webContentPath)
{
//check if current working directory differs from content root.
if (Directory.GetCurrentDirectory() != webContentPath)
{
Console.WriteLine("WARNING: The Working Directory differs from the Web Content Path");
Console.WriteLine($"Working Directory: {Directory.GetCurrentDirectory()}");
Console.WriteLine($"Web Content Path: {webContentPath}");
}
//migrates all user-uploaded files from webroot to new data folder
//images
var imagePath = Path.Combine(webRootPath, "images");
var docsPath = Path.Combine(webRootPath, "documents");
var translationPath = Path.Combine(webRootPath, "translations");
var tempPath = Path.Combine(webRootPath, "temp");
if (File.Exists(LegacyUserConfigPath))
{
File.Move(LegacyUserConfigPath, UserConfigPath, true);
}
if (Directory.Exists(imagePath))
{
foreach (string fileToMove in Directory.GetFiles(imagePath))
{
var newFilePath = $"data/images/{Path.GetFileName(fileToMove)}";
File.Move(fileToMove, newFilePath, true);
Console.WriteLine($"Migrated Image: {Path.GetFileName(fileToMove)}");
}
}
if (Directory.Exists(docsPath))
{
foreach (string fileToMove in Directory.GetFiles(docsPath))
{
var newFilePath = $"data/documents/{Path.GetFileName(fileToMove)}";
File.Move(fileToMove, newFilePath, true);
Console.WriteLine($"Migrated Document: {Path.GetFileName(fileToMove)}");
}
}
if (Directory.Exists(translationPath))
{
foreach (string fileToMove in Directory.GetFiles(translationPath))
{
var newFilePath = $"data/translations/{Path.GetFileName(fileToMove)}";
File.Move(fileToMove, newFilePath, true);
Console.WriteLine($"Migrated Translation: {Path.GetFileName(fileToMove)}");
}
}
if (Directory.Exists(tempPath))
{
foreach (string fileToMove in Directory.GetFiles(tempPath))
{
var newFilePath = $"data/temp/{Path.GetFileName(fileToMove)}";
File.Move(fileToMove, newFilePath, true);
Console.WriteLine($"Migrated Temp File: {Path.GetFileName(fileToMove)}");
}
}
}
public static async void NotifyAsync(string webhookURL, WebHookPayload webHookPayload)
@@ -332,7 +424,8 @@ namespace CarCareTracker.Helper
webhookURL = webhookURL.Replace("discord://", "https://"); //cleanurl
//format to discord
httpClient.PostAsJsonAsync(webhookURL, DiscordWebHook.FromWebHookPayload(webHookPayload));
} else
}
else
{
httpClient.PostAsJsonAsync(webhookURL, webHookPayload);
}
@@ -370,12 +463,14 @@ namespace CarCareTracker.Helper
if (vehicle.VehicleIdentifier == "LicensePlate")
{
return vehicle.LicensePlate;
} else
}
else
{
if (vehicle.ExtraFields.Any(x=>x.Name == vehicle.VehicleIdentifier))
if (vehicle.ExtraFields.Any(x => x.Name == vehicle.VehicleIdentifier))
{
return vehicle.ExtraFields?.FirstOrDefault(x=>x.Name == vehicle.VehicleIdentifier)?.Value;
} else
return vehicle.ExtraFields?.FirstOrDefault(x => x.Name == vehicle.VehicleIdentifier)?.Value;
}
else
{
return "N/A";
}
@@ -402,10 +497,11 @@ namespace CarCareTracker.Helper
//Translations
public static string GetTranslationDownloadPath(string continent, string name)
{
if (string.IsNullOrWhiteSpace(continent) || string.IsNullOrWhiteSpace(name)){
if (string.IsNullOrWhiteSpace(continent) || string.IsNullOrWhiteSpace(name))
{
return string.Empty;
}
else
}
else
{
switch (continent)
{
@@ -424,8 +520,9 @@ namespace CarCareTracker.Helper
if (string.IsNullOrWhiteSpace(name))
{
return string.Empty;
} else
{
}
else
{
try
{
string cleanedName = name.Contains("_") ? name.Replace("_", "-") : name;
@@ -438,7 +535,8 @@ namespace CarCareTracker.Helper
{
return displayName;
}
} catch (Exception ex)
}
catch (Exception ex)
{
return name;
}
@@ -609,7 +707,8 @@ namespace CarCareTracker.Helper
if (input == 0M.ToString("C2") && hideZero)
{
return "---";
} else
}
else
{
return string.IsNullOrWhiteSpace(decorations) ? input : $"{input}{decorations}";
}
@@ -669,5 +768,52 @@ namespace CarCareTracker.Helper
_csv.NextRecord();
}
}
public static byte[] RemindersToCalendar(List<ReminderRecordViewModel> reminders)
{
//converts reminders to iCal file
StringBuilder sb = new StringBuilder();
//start the calendar item
sb.AppendLine("BEGIN:VCALENDAR");
sb.AppendLine("VERSION:2.0");
sb.AppendLine("PRODID:lubelogger.com");
sb.AppendLine("CALSCALE:GREGORIAN");
sb.AppendLine("METHOD:PUBLISH");
//create events.
foreach(ReminderRecordViewModel reminder in reminders)
{
var dtStart = reminder.Date.Date.ToString("yyyyMMddTHHmm00");
var dtEnd = reminder.Date.Date.AddDays(1).AddMilliseconds(-1).ToString("yyyyMMddTHHmm00");
var calendarUID = new Guid(MD5.HashData(Encoding.UTF8.GetBytes($"{dtStart}_{reminder.Description}")));
sb.AppendLine("BEGIN:VEVENT");
sb.AppendLine("DTSTAMP:" + DateTime.Now.ToString("yyyyMMddTHHmm00"));
sb.AppendLine("UID:" + calendarUID);
sb.AppendLine("DTSTART:" + dtStart);
sb.AppendLine("DTEND:" + dtEnd);
sb.AppendLine($"SUMMARY:{reminder.Description}");
sb.AppendLine($"DESCRIPTION:{reminder.Description}");
switch (reminder.Urgency)
{
case ReminderUrgency.NotUrgent:
sb.AppendLine("PRIORITY:3");
break;
case ReminderUrgency.Urgent:
sb.AppendLine("PRIORITY:2");
break;
case ReminderUrgency.VeryUrgent:
sb.AppendLine("PRIORITY:1");
break;
case ReminderUrgency.PastDue:
sb.AppendLine("PRIORITY:1");
break;
}
sb.AppendLine("END:VEVENT");
}
//end calendar item
sb.AppendLine("END:VCALENDAR");
string calendarContent = sb.ToString();
return Encoding.UTF8.GetBytes(calendarContent);
}
}
}

View File

@@ -23,6 +23,7 @@
public string Notes { get; set; }
public List<string> Tags { get; set; } = new List<string>();
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
public bool IncludeInAverage { get { return MilesPerGallon > 0 || (!IsFillToFull && !MissedFuelUp); } }
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
public bool IncludeInAverage { get { return MilesPerGallon > 0 || (!IsFillToFull && !MissedFuelUp) || (Mileage == default && !MissedFuelUp); } }
}
}

View File

@@ -43,7 +43,7 @@ namespace CarCareTracker.Models
public string Cost { get; set; }
public string Notes { get; set; }
public string Tags { get; set; }
public List<ExtraField> ExtraFields { get; set; }
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
}
public class GenericRecordExportModel
{
@@ -58,7 +58,8 @@ namespace CarCareTracker.Models
[JsonConverter(typeof(FromDecimalOptional))]
public string Cost { get; set; }
public string Tags { get; set; }
public List<ExtraField> ExtraFields { get; set; }
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
}
public class OdometerRecordExportModel
{
@@ -72,7 +73,8 @@ namespace CarCareTracker.Models
public string Odometer { get; set; }
public string Notes { get; set; }
public string Tags { get; set; }
public List<ExtraField> ExtraFields { get; set; }
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
}
public class TaxRecordExportModel
{
@@ -85,7 +87,8 @@ namespace CarCareTracker.Models
[JsonConverter(typeof(FromDecimalOptional))]
public string Cost { get; set; }
public string Tags { get; set; }
public List<ExtraField> ExtraFields { get; set; }
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
}
public class GasRecordExportModel
{
@@ -107,7 +110,8 @@ namespace CarCareTracker.Models
public string MissedFuelUp { get; set; }
public string Notes { get; set; }
public string Tags { get; set; }
public List<ExtraField> ExtraFields { get; set; }
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
}
public class ReminderExportModel
{
@@ -130,6 +134,6 @@ namespace CarCareTracker.Models
public string Priority { get; set; }
public string Progress { get; set; }
public string Cost { get; set; }
public List<ExtraField> ExtraFields { get; set; }
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
}
}

View File

@@ -7,11 +7,14 @@ using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
//Print Messages
StaticHelper.InitMessage(builder.Configuration);
//Check Migration
StaticHelper.CheckMigration(builder.Environment.WebRootPath, builder.Environment.ContentRootPath);
// Add services to the container.
builder.Services.AddControllersWithViews();
@@ -75,15 +78,6 @@ builder.Services.AddSingleton<IUserLogic, UserLogic>();
builder.Services.AddSingleton<IOdometerLogic, OdometerLogic>();
builder.Services.AddSingleton<IVehicleLogic, VehicleLogic>();
if (!Directory.Exists("data"))
{
Directory.CreateDirectory("data");
}
if (!Directory.Exists("config"))
{
Directory.CreateDirectory("config");
}
//Additional JsonFile
builder.Configuration.AddJsonFile(StaticHelper.UserConfigPath, optional: true, reloadOnChange: true);
@@ -112,11 +106,55 @@ var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseExceptionHandler("/Home/Error");
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "data", "images")),
RequestPath = "/images",
OnPrepareResponse = ctx =>
{
if (ctx.Context.Request.Path.StartsWithSegments("/images") || ctx.Context.Request.Path.StartsWithSegments("/documents"))
if (ctx.Context.Request.Path.StartsWithSegments("/images"))
{
ctx.Context.Response.Headers.Add("Cache-Control", "no-store");
if (!ctx.Context.User.Identity.IsAuthenticated)
{
ctx.Context.Response.Redirect("/Login");
}
}
}
});
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "data", "documents")),
RequestPath = "/documents",
OnPrepareResponse = ctx =>
{
if (ctx.Context.Request.Path.StartsWithSegments("/documents"))
{
ctx.Context.Response.Headers.Add("Cache-Control", "no-store");
if (!ctx.Context.User.Identity.IsAuthenticated)
{
ctx.Context.Response.Redirect("/Login");
}
}
}
});
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "data", "translations")),
RequestPath = "/translations"
});
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "data", "temp")),
RequestPath = "/temp",
OnPrepareResponse = ctx =>
{
if (ctx.Context.Request.Path.StartsWithSegments("/temp"))
{
ctx.Context.Response.Headers.Add("Cache-Control", "no-store");
if (!ctx.Context.User.Identity.IsAuthenticated)

View File

@@ -118,6 +118,7 @@
notes - notes(optional)<br />
tags - tags separated by space(optional)<br />
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
}
</div>
</div>
@@ -140,6 +141,7 @@
notes - notes(optional)<br />
tags - tags separated by space(optional)<br />
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
}
</div>
</div>
@@ -192,6 +194,7 @@
notes - notes(optional)<br />
tags - tags separated by space(optional)<br />
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
}
</div>
</div>
@@ -215,6 +218,7 @@
notes - notes(optional)<br />
tags - tags separated by space(optional)<br />
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
}
</div>
</div>
@@ -267,6 +271,7 @@
notes - notes(optional)<br />
tags - tags separated by space(optional)<br />
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
}
</div>
</div>
@@ -290,6 +295,7 @@
notes - notes(optional)<br />
tags - tags separated by space(optional)<br />
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
}
</div>
</div>
@@ -342,6 +348,7 @@
notes - notes(optional)<br />
tags - tags separated by space(optional)<br />
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
}
</div>
</div>
@@ -365,6 +372,7 @@
notes - notes(optional)<br />
tags - tags separated by space(optional)<br />
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
}
</div>
</div>
@@ -430,6 +438,7 @@
notes - notes(optional)<br />
tags - tags separated by space(optional)<br />
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
}
</div>
</div>
@@ -452,6 +461,7 @@
notes - notes(optional)<br />
tags - tags separated by space(optional)<br />
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
}
</div>
</div>
@@ -510,6 +520,7 @@
notes - notes(optional)<br />
tags - tags separated by space(optional)<br />
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
}
</div>
</div>
@@ -535,6 +546,7 @@
notes - notes(optional)<br />
tags - tags separated by space(optional)<br />
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
files - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showAttachmentsInfo()">attachments(optional)</a><br />
}
</div>
</div>
@@ -566,6 +578,22 @@
vehicleId - Id of Vehicle
</div>
</div>
<div class="row api-method">
<div class="col-1">
<span class="badge bg-primary">POST</span>
</div>
<div class="col-5 copyable">
<code>/api/documents/upload</code>
</div>
<div class="col-3">
Upload Documents
</div>
<div class="col-3">
Body(form-data): {<br />
documents[] - Files to Upload<br />
}
</div>
</div>
@if (User.IsInRole(nameof(UserData.IsRootUser)))
{
<div class="row api-method">
@@ -624,4 +652,11 @@
icon: "info"
});
}
function showAttachmentsInfo(){
Swal.fire({
title: "Attaching Files",
html: "The Document Upload Endpoint will upload the files and provide a formatted output which you can pass into this method",
icon: "info"
});
}
</script>

View File

@@ -34,6 +34,7 @@
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<title>@ViewData["Title"] - LubeLogger</title>
<link rel="icon" type="image/x-icon" href="~/favicon.ico">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap-icons.css" />
<link rel="stylesheet" href="~/lib/bootstrap-datepicker/css/bootstrap-datepicker.min.css" />

View File

@@ -49,9 +49,13 @@
<input type="text" id="inputFileExtensions" class="form-control">
<small class="text-body-secondary">Blank for default, * for all files</small>
</div>
<div class="form-check form-switch">
<input class="form-check-input"type="checkbox" role="switch" id="inputCustomWidgets">
<label class="form-check-label" for="inputCustomWidgets">Custom Widgets</label>
</div>
</div>
<div class="col-6">
<div class="form-group">
<div class="form-group">
<label for="inputCustomLogo">Custom Logo URL</label>
<input type="text" id="inputCustomLogo" class="form-control">
<small class="text-body-secondary">Default size: 204x48</small>
@@ -66,6 +70,10 @@
<input type="text" id="inputWebHook" class="form-control">
<small class="text-body-secondary">URL to WebHook Consumer</small>
</div>
<div class="form-check form-switch">
<input class="form-check-input"type="checkbox" role="switch" id="inputInvariantAPI">
<label class="form-check-label" for="inputInvariantAPI">Invariant API</label>
</div>
</div>
</div>
</div>
@@ -262,6 +270,12 @@ function generateConfig(){
if ($("#inputPostgres").val().trim() != ''){
windowConfig["POSTGRES_CONNECTION"]=$("#inputPostgres").val();
}
if ($("#inputCustomWidgets").is(":checked")){
windowConfig["LUBELOGGER_CUSTOM_WIDGETS"]=$('#inputCustomWidgets').is(':checked');
}
if ($("#inputInvariantAPI").is(":checked")){
windowConfig["LUBELOGGER_INVARIANT_API"]=$('#inputInvariantAPI').is(':checked');
}
if ($('#inputSmtpServer').val().trim() != ''){
windowConfig["MailConfig"] = {
EmailServer: $("#inputSmtpServer").val(),
@@ -327,6 +341,12 @@ function generateConfig(){
if ($("#inputPostgres").val().trim() != ''){
dockerConfig.push(`POSTGRES_CONNECTION="${$('#inputPostgres').val()}"`);
}
if ($("#inputCustomWidgets").is(":checked")){
dockerConfig.push(`LUBELOGGER_CUSTOM_WIDGETS="${$('#inputCustomWidgets').is(':checked')}"`);
}
if ($("#inputInvariantAPI").is(":checked")){
dockerConfig.push(`LUBELOGGER_INVARIANT_API="${$('#inputInvariantAPI').is(':checked')}"`);
}
if ($('#inputSmtpServer').val().trim() != ''){
dockerConfig.push(`MailConfig__EmailServer="${$('#inputSmtpServer').val()}"`);
dockerConfig.push(`MailConfig__EmailFrom="${$('#inputSmtpFrom').val()}"`);