Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement CSV export of maintenance events #371

Merged
merged 7 commits into from
Dec 12, 2024

Conversation

mitaligondaliya
Copy link
Contributor

What it Does

  • Closes FEATURE - CSV Export of Maintenance Events Only #343
  • Added a picker to allow users to choose between PDF and CSV export options.
  • Implemented functionality to generate a CSV file containing the maintenance events of selected vehicles.
  • Integrated ShareLink to enable sharing of the generated CSV file.

How I Tested

  • Run the application
  • Go to the dashboard and add a new maintenance event. This will enable the share button.
  • Tap the share button to proceed to the vehicle selection screen.
  • Select a vehicle, and a picker will appear.
  • Choose CSV as the export format.
  • See the result

Screenshot

Simulator.Screen.Recording.-.iPhone.16.Pro.-.2024-11-21.at.18.13.47.mov

@mikaelacaron
Copy link
Owner

awesome work!! I'll look at this PR over the weekend

Copy link
Owner

@mikaelacaron mikaelacaron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!!! Thanks for contributing!

You added more complexity in the csv than I would've just for exporting the bool in different ways and the date, I would've only done one option, and made it not as generic, but that's fine! It'll be more flexible in the future how you've written it

One small thing, that I'll make a new issue out of later is that the generateCSVFile function in CSVGeneratorView gets run multiple times, because the function is really called when the view body is evaluated, which can happen many times. A better way to implement this is to make that function trigger from a button tap. But no worries I'll add that as an issue later


import Foundation

internal extension BidirectionalCollection where Element == String {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't need to be marked internal cause it is by default

var newlineDelimited: String { joined(separator: "\r\n") }
}

public struct CSVColumn<Record> {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this shouldn't be public the "Shared" folder that this is in, is still all in a single project, so it's fine if it stays just internal

Same with like the whole file

struct ExportOptionsView: View {
@Environment(\.dismiss) var dismiss
@State private var selectedVehicle: Vehicle?
@State private var isShowingThumbnail = false
@State private var pdfDoc: PDFDocument?
@State private var showingErrorAlert = false
@State private var selectedOption: ExportOption?
@State private var showingExporter = false
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@State private var showingExporter = false
@State private var showingCSVGeneratorView = false

renaming this, and how the variable is used is this file, cause I think it feels more clear cause "showExporter" also feels like it would be used for the PDF, but it isn't

Button("Export") {
Menu(content: {
Picker("Export", selection: $selectedOption) {
ForEach(ExportOption.allCases, id: \.self) { option in
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ForEach(ExportOption.allCases, id: \.self) { option in
ForEach(ExportOption.allCases) { option in

The id: \.self isn't needed because ExportOption conforms to Identifiable

Also for the Menu I use multiple trailing closure syntax, as a personal preference

isShowingThumbnail = true
switch selectedOption {
case .pdf:
selectedOption = nil
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand why this is being set to nil, but it's not my favorite way to implement this, maybe we could set it to nil on the dismiss of the view that's shown?

but this works! so I'm not too worried about it


import Foundation

internal extension BidirectionalCollection where Element == String {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also moving this file to just the Dashboard folder, cause it doesn't fit being in the Dashboard > Views folder

let events: [MaintenanceEvent]
let vehicleName: String

func csvData() -> String {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moving the functions below the body, just as a personal preference thing

and they can be private, because they're only used in this view

private(set) var attribute: (Record) -> CSVEncodable

init(
_ header: String,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

personal preference, but I don't format this on multiple lines unless it's needed because the line is too long, or there's many parameters (which at that point usually it needs to be refactored for passing too many things

@mikaelacaron mikaelacaron merged commit 1d68c23 into mikaelacaron:dev Dec 12, 2024
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FEATURE - CSV Export of Maintenance Events Only
2 participants