forked from trent_larson/crowd-funder-for-time-pwa
docs: add comprehensive JSDoc documentation to views
Changes: - Add detailed JSDoc headers to ContactImportView - Add component-level documentation to ProjectViewView - Document state management and data flow - Add security considerations and usage examples - Improve test script documentation and organization - Add interface documentation for deep linking This improves code maintainability by documenting component architecture, workflows and integration points.
This commit is contained in:
@@ -142,6 +142,37 @@ import { AppString, NotificationIface } from "../constants/app";
|
||||
import { db } from "../db/index";
|
||||
import { Contact, ContactMethod } from "../db/tables/contacts";
|
||||
|
||||
/**
|
||||
* Contact Edit View Component
|
||||
* @author Matthew Raymer
|
||||
*
|
||||
* This component provides a full-featured contact editing interface with support for:
|
||||
* - Basic contact information (name, notes)
|
||||
* - Multiple contact methods with type selection
|
||||
* - Data validation and persistence
|
||||
*
|
||||
* Workflow:
|
||||
* 1. Component loads with DID from route params
|
||||
* 2. Fetches existing contact data from IndexedDB
|
||||
* 3. Presents editable form with current values
|
||||
* 4. Validates and saves updates back to database
|
||||
*
|
||||
* Contact Method Types:
|
||||
* - CELL: Mobile phone numbers
|
||||
* - EMAIL: Email addresses
|
||||
* - WHATSAPP: WhatsApp contact info
|
||||
*
|
||||
* State Management:
|
||||
* - Maintains separate state for form fields to prevent direct mutation
|
||||
* - Handles array cloning for contact methods to prevent reference issues
|
||||
* - Manages dropdown state for method type selection
|
||||
*
|
||||
* Navigation:
|
||||
* - Back button returns to previous view
|
||||
* - Save redirects to contact detail view
|
||||
* - Cancel returns to previous view
|
||||
* - Invalid DID redirects to contacts list
|
||||
*/
|
||||
@Component({
|
||||
components: {
|
||||
QuickNav,
|
||||
@@ -149,22 +180,44 @@ import { Contact, ContactMethod } from "../db/tables/contacts";
|
||||
},
|
||||
})
|
||||
export default class ContactEditView extends Vue {
|
||||
/** Notification function injected by Vue */
|
||||
$notify!: (notification: NotificationIface, timeout?: number) => void;
|
||||
/** Current route instance */
|
||||
$route!: RouteLocationNormalizedLoaded;
|
||||
/** Router instance for navigation */
|
||||
$router!: Router;
|
||||
|
||||
/** Current contact data */
|
||||
contact: Contact = {
|
||||
did: "",
|
||||
name: "",
|
||||
notes: "",
|
||||
};
|
||||
/** Editable contact name field */
|
||||
contactName = "";
|
||||
/** Editable contact notes field */
|
||||
contactNotes = "";
|
||||
/** Array of editable contact methods */
|
||||
contactMethods: Array<ContactMethod> = [];
|
||||
/** Currently open dropdown index, null if none open */
|
||||
dropdownIndex: number | null = null;
|
||||
|
||||
/** App string constants */
|
||||
AppString = AppString;
|
||||
|
||||
/**
|
||||
* Component lifecycle hook that initializes the contact edit form
|
||||
*
|
||||
* Workflow:
|
||||
* 1. Extracts DID from route parameters
|
||||
* 2. Queries database for existing contact
|
||||
* 3. Populates form fields with contact data
|
||||
* 4. Handles missing contact error case
|
||||
*
|
||||
* @throws Will not throw but redirects on error
|
||||
* @emits Notification on contact not found
|
||||
* @emits Router navigation on error
|
||||
*/
|
||||
async created() {
|
||||
const contactDid = this.$route.params.did;
|
||||
const contact = await db.contacts.get(contactDid || "");
|
||||
@@ -185,29 +238,75 @@ export default class ContactEditView extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new empty contact method to the methods array
|
||||
*
|
||||
* Creates a new method object with empty fields for:
|
||||
* - label: Custom label for the method
|
||||
* - type: Communication type (CELL, EMAIL, WHATSAPP)
|
||||
* - value: The contact information value
|
||||
*/
|
||||
addContactMethod() {
|
||||
this.contactMethods.push({ label: "", type: "", value: "" });
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a contact method at the specified index
|
||||
*
|
||||
* @param index The array index of the method to remove
|
||||
*/
|
||||
removeContactMethod(index: number) {
|
||||
this.contactMethods.splice(index, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the type selection dropdown for a contact method
|
||||
*
|
||||
* If the clicked dropdown is already open, closes it.
|
||||
* If another dropdown is open, closes it and opens the clicked one.
|
||||
*
|
||||
* @param index The array index of the method whose dropdown to toggle
|
||||
*/
|
||||
toggleDropdown(index: number) {
|
||||
this.dropdownIndex = this.dropdownIndex === index ? null : index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type for a contact method and closes the dropdown
|
||||
*
|
||||
* @param index The array index of the method to update
|
||||
* @param type The new type value (CELL, EMAIL, WHATSAPP)
|
||||
*/
|
||||
setMethodType(index: number, type: string) {
|
||||
this.contactMethods[index].type = type;
|
||||
this.dropdownIndex = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the edited contact information to the database
|
||||
*
|
||||
* Workflow:
|
||||
* 1. Clones contact methods array to prevent reference issues
|
||||
* 2. Normalizes method types to uppercase
|
||||
* 3. Checks for changes in method types
|
||||
* 4. Updates database with new values
|
||||
* 5. Notifies user of success
|
||||
* 6. Redirects to contact detail view
|
||||
*
|
||||
* @throws Will not throw but notifies on validation errors
|
||||
* @emits Notification on type changes or success
|
||||
* @emits Router navigation on success
|
||||
*/
|
||||
async saveEdit() {
|
||||
// without this conversion, "Failed to execute 'put' on 'IDBObjectStore': [object Array] could not be cloned."
|
||||
const contactMethodsObj = JSON.parse(JSON.stringify(this.contactMethods));
|
||||
|
||||
// Normalize method types to uppercase
|
||||
const contactMethods = contactMethodsObj.map((method: ContactMethod) =>
|
||||
R.set(R.lensProp("type"), method.type.toUpperCase(), method),
|
||||
);
|
||||
|
||||
// Check for type changes
|
||||
if (!R.equals(contactMethodsObj, contactMethods)) {
|
||||
this.contactMethods = contactMethods;
|
||||
this.$notify(
|
||||
@@ -221,11 +320,15 @@ export default class ContactEditView extends Vue {
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Save to database
|
||||
await db.contacts.update(this.contact.did, {
|
||||
name: this.contactName,
|
||||
notes: this.contactNotes,
|
||||
contactMethods: contactMethods,
|
||||
});
|
||||
|
||||
// Notify success and redirect
|
||||
this.$notify({
|
||||
group: "alert",
|
||||
type: "success",
|
||||
|
||||
Reference in New Issue
Block a user