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

Example invoice #57

Open
wants to merge 134 commits into
base: master
Choose a base branch
from
Open

Conversation

ltfschoen
Copy link
Contributor

@ltfschoen ltfschoen commented Apr 4, 2023

run with

cd examples/invoice/
cargo install --locked trunk
RUST_LOG=info trunk serve --address=127.0.0.1 --open
cargo test
  • invoice example incorporates code from the following examples todomvc, csv_editor, and qrcode
  • editable table, and can choose a 'main' file invoice.csv to populate the table, whose cells are then still editable
  • editable from_org_addr input field in the UI
  • edited fields are stored in local storage. if the user refreshes the page it loads the previously edited data from local storage instead of using mock data
  • uploading csv file also stores uploaded data in local storage
  • replace from_org_addr input field in the UI with multiple editable input fields with details like inv_date, from_org_addr, etc (from details.csv labels. so we can choose a 'details' file details.csv to populate those input fields in the UI, whose input fields are still then editable
  • edited values in the UI can be downloaded to a CSV file in a single-click by clicking "Save to CSV file", which generates an object URL that includes formatted CSV data that gets stored in the state and that data populates the href attribute of a hyperlink, and a script detects when it's populated an automatically clicks that hyperlink for the user to download the file. Then if you make changes directly in the CSV file and upload the file in the expected format it should automatically populate the fields in the UI
    • review Maciej comments in Discord thread with much simpler approach to saving to CSV file. See Discord thread "i finally updated the...". See commit 0383323
  • incorporate basic css. Moved to separate styles.css file
  • choosing .csv file that has a QR code column automatically populates the QR code image
  • style the choose file input for uploading CSV files
  • Fix broken code after updating from Kobold 0.7.0 to 0.8.0. See 7cfcfcb
  • currently when page first loads, if try to Save to CSV it doesn't work, because it only works if the obj_url isn't the placeholder or is defined. so it only works if click once to populate the local storage, and then you have to change one of the cells in the UI before you click the button a second time, then it will download
  • review how useful the wasm-bindgen JS integration is, where i have to put the JS files in the project root folder. Maciej showed much simpler code, perhaps i can approach this differently. See Discord thread "the only annoying thing..."
  • instead of view conditional with else that has Empty, try using condition.then(|| view! { ... }) https://doc.rust-lang.org/std/primitive.bool.html#method.then. See Discord thread "how to use Empty...". Update: did this to conditionally render the hint only when not already editing
  • Fix issue where if i edit the UI cells, then upload a CSV file, it updates local storage "source", but doesn't overwrite the UI cells. This was fixed in 0.8.1 and using update instead of update_silent again.
  • Refactor onload_details and onload_main into common method, or move common aspects into common function. See 1cc4c97. See Discord thread "how to change the onchange...". Update: This feature is only possible with nightly, might be possible in future
  • Note: On Brave/Chrome, cannot upload same file more than once since it uses onchange (until refresh or upload a different document), but the issue doesn't happen on Firefox - solved using this https://stackoverflow.com/a/48499451/3208553, in this commit daa517a
  • Try changing onchange to something else so if try upload same file twice in a row on Brave or Chrome, it updates
  • allow user to specify the table variant in the CSV file being uploaded (i.e. start of the CSV file would be #details,name,age\nluke,...., where there is a mapping from details to TableVariant::Details. so if they provide a valid one identified by prefix with # at the start, then it will store that value details as the Table's property variant value, otherwise it will error if invalid one is provided, or if it is not provided then TableVariant::Unknown will be stored (perhaps if loaded from mock data) unless they click the relevant button that triggers say onload_details, which manually overrides it with TableVariant::Details with get(state).table.variant = table_variant;
  • allow when saving to CSV file for it to be prefixed with the table variant if the Table's property variant value has a value other than TableVariant::Unknown, so if it was TableVariant::Details then it'd modify the string to be downloaded so it would be prefixed with #details, before anything else. See commit 8eb05e1
  • Fix the issue where we use variables and labels for the "details" table unnecessary, so currently in HeadDetails we use Editing::Cell { row, col } whereas in Head we just use (Editing::Column { col }. In the state for "details" table we're storing the variables in columns, the data in row[0], and the labels in row[1], but we want the variables removed, the labels to be instead in row[0] and data values in row[1]. In csv.rs we're pushing the table variant prefix on the variables in details, but we're pushing the table variant prefix on the labels in main because it doesn't have any variables. it's inconsistent but it still works, but need to remove variables and only keep labels. fixed in commit 8e1fd25
  • Add logo component that uses a url link for the logo. Refactor to make the logo component portable as a Kobold library component. Done in this commit e8dea20
  • validation saving CSV file for processing of rows and columns qty in the UI. if new columns added in UI with empty row data cells (e.g. "description,total,qr,aaa\neat,1,0x0,\nsleep,2,0x1,") then pad those values so do not get errors saving. See commit 79433ce
  • Refactor onload_common with Maciej feedback to pass function to the function as follows:
async fn onload_common(get: impl Fn(&mut State) -> &mut Content, state: Signal<State>, event: Event<InputElement>) {
    state.update(|state| get(state).filename = file.name());

and call with onload_common(|state| &mut state.main, state, event).await; to duplicate onload_common, so the closure will be inlined in the release build.
also replace

let onload_details = state.bind_async(|state, event: Event<InputElement>| async move {
    onload_common(...).await;
});

with the following as they should compile to the same code with optimizations on, which is an extra layer of a state machine for the compiler to chug through:

let onload_details = state.bind_async(|state, event: Event<InputElement>| {
    onload_common(...)
});
  • Input validation of CSV file uploaded (i.e. prevent user uploading the wrong CSV file for the table i.e. details instead of main). already does this in csv.rs InvalidRowLength. but also give option to specify the table variant
  • Add "remove row" feature to the "Main" table since it has multiple rows (uses button from todomvc example). see commits "remove row" in their description.
  • Add a "add row" feature (allowing adding rows between existing two existing rows not just appending to the end), so after populating the fields from a csv file the users can customise by further adding and removing fields (logic would only apply to the "Main" table that has multiple data rows)
  • upload multiple files at once with same button input file element (currently two separate input file elements). since all uploaded files will be tagged with #main, or #details, we know where they should go in the UI. error if try upload two files both with same variant..... would it be cooler if they were in same file, but that's not a very organised approach
  • add unit tests (in progress)
  • Replace Clawbird logo with Kobold logo, but need SVG support or convert it to png or jpg. Change example table info to more generic info
  • "Save All" button to save multiple files with same button at once (instead of a separate button for each table). they would be saved to the last filename that was used to upload the files and stored in Table filename. "Save As" button would allow the user to save the files individually (existing functionality)
  • Refactor common aspects. Since most of the code is from the other examples, there'd be lots of duplicate code across the kobold repo, so it might be worth considering how to avoid having to maintain those duplicates by having more customisations passed through props to more generic components.
  • add additional features to make it like a generic invoice people would use
  • try and see if can use QR code as receiver address to receive crypto
  • Optionally allow user to double click and edit the logo's url (since could do on mobile too)
  • Optionally refactor to try to make the # value into a const, but not sure how to use the const in a regex so would have to change that manually. also wouldn't mind creating a mapping from TableVariant to string by creating a FromTableVariant that extends String, and also the other way arround. Also think i need to have higher order Error enum since some errors might have shared usage across state.rs and csv.rs files . Draft commit with TODOs here 8eb05e1
  • Combine Head and HeadDetails into single component Head, and combine Cell with CellDetails into a single component Cell. Do this by using get: impl Fn(&mut State) -> &mut Content instead of state: ... technique
  • Maciej - what I want to do there in the future is make loaded files appear as tabs, and if the file fails to load it should show the error message in the tab instead of a table, not there yet
  • Propagate errors and information messages so they display in a Notifications component in the UI
  • N/A add save to pdf button - no necessary as can just print to PDF in browser anyway
  • N/A Add a logo upload button that stores base64 image in state and Local Storage, integrate into Kobold library Logo component, just by clicking the logo image it should allow the user to swap logos - pointless, since can easily upload to imgur or similar easily on mobile too, better just to double click edit url

Screenshot Preview (9 May 2023):

Screen Shot 2023-05-08 at 10 02 22 pm

Screenshot Preview (8 May 2023):

Screen Shot 2023-05-08 at 6 56 51 pm

ltfschoen added 21 commits May 4, 2023 06:28
@ltfschoen ltfschoen force-pushed the luke/invoice-debug branch from 0fc4ffc to ad96441 Compare May 8, 2023 23:19
@ltfschoen ltfschoen force-pushed the luke/invoice-debug branch from ad96441 to c29ba76 Compare May 8, 2023 23:21
@ltfschoen ltfschoen marked this pull request as ready for review May 18, 2023 01:16
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.

1 participant