forked from jsnbuchanan/crowd-funder-for-time-pwa
Complete QuickActionBvcEndView Enhanced Triple Migration Pattern (4 minutes)
- Replace retrieveAllAccountsMetadata with $getAllAccounts() mixin method - Standardize contact fetching to use $contacts() method - Extract long class strings to computed properties for maintainability - Add $getAllAccounts() method to PlatformServiceMixin for future migrations - Achieve 75% performance improvement over estimated time - Ready for human testing across all platforms
This commit is contained in:
@@ -592,6 +592,164 @@ get itemCoordinates() {
|
||||
- **Document computed properties**: Add JSDoc comments explaining purpose and return types
|
||||
- **Use descriptive names**: `userDisplayName` instead of `getName()`
|
||||
|
||||
## Component Extraction Patterns
|
||||
|
||||
### When to Extract Components
|
||||
|
||||
Extract components when you identify:
|
||||
- **Repeated UI patterns** used in multiple places
|
||||
- **Complex template sections** that could be simplified
|
||||
- **Form elements** with similar structure and behavior
|
||||
- **Layout patterns** that appear consistently
|
||||
- **Validation patterns** with repeated logic
|
||||
|
||||
### Component Extraction Examples
|
||||
|
||||
#### Form Input Extraction
|
||||
```typescript
|
||||
// Before: Repeated form input pattern
|
||||
<template>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Name</label>
|
||||
<input class="form-input" v-model="name" />
|
||||
<div class="error-message" v-if="nameError">{{ nameError }}</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Email</label>
|
||||
<input class="form-input" v-model="email" />
|
||||
<div class="error-message" v-if="emailError">{{ emailError }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
// After: Extracted FormInput component
|
||||
<template>
|
||||
<FormInput
|
||||
label="Name"
|
||||
v-model="name"
|
||||
:error="nameError"
|
||||
/>
|
||||
<FormInput
|
||||
label="Email"
|
||||
v-model="email"
|
||||
:error="emailError"
|
||||
/>
|
||||
</template>
|
||||
|
||||
// New FormInput.vue component
|
||||
<template>
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ label }}</label>
|
||||
<input
|
||||
class="form-input"
|
||||
:value="value"
|
||||
@input="$emit('input', $event.target.value)"
|
||||
/>
|
||||
<div class="error-message" v-if="error">{{ error }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Vue } from "vue-facing-decorator";
|
||||
|
||||
/**
|
||||
* Reusable form input component with label and error handling
|
||||
*/
|
||||
@Component
|
||||
export default class FormInput extends Vue {
|
||||
@Prop({ required: true }) label!: string;
|
||||
@Prop({ required: true }) value!: string;
|
||||
@Prop() error?: string;
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
#### Button Group Extraction
|
||||
```typescript
|
||||
// Before: Repeated button patterns
|
||||
<template>
|
||||
<div class="button-group">
|
||||
<button class="btn btn-primary" @click="save">Save</button>
|
||||
<button class="btn btn-secondary" @click="cancel">Cancel</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
// After: Extracted ButtonGroup component
|
||||
<template>
|
||||
<ButtonGroup
|
||||
:primary-action="{ text: 'Save', handler: save }"
|
||||
:secondary-action="{ text: 'Cancel', handler: cancel }"
|
||||
/>
|
||||
</template>
|
||||
|
||||
// New ButtonGroup.vue component
|
||||
<template>
|
||||
<div class="button-group">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
@click="primaryAction.handler"
|
||||
>
|
||||
{{ primaryAction.text }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-secondary"
|
||||
@click="secondaryAction.handler"
|
||||
>
|
||||
{{ secondaryAction.text }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Vue } from "vue-facing-decorator";
|
||||
|
||||
interface ButtonAction {
|
||||
text: string;
|
||||
handler: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reusable button group component for common action patterns
|
||||
*/
|
||||
@Component
|
||||
export default class ButtonGroup extends Vue {
|
||||
@Prop({ required: true }) primaryAction!: ButtonAction;
|
||||
@Prop({ required: true }) secondaryAction!: ButtonAction;
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
### Component Quality Standards
|
||||
|
||||
#### Single Responsibility
|
||||
- Each extracted component should have one clear purpose
|
||||
- Component name should clearly indicate its function
|
||||
- Props should be focused and relevant to the component's purpose
|
||||
|
||||
#### Reusability
|
||||
- Component should work in multiple contexts
|
||||
- Props should be flexible enough for different use cases
|
||||
- Events should provide appropriate communication with parent
|
||||
|
||||
#### Type Safety
|
||||
- All props should have proper TypeScript interfaces
|
||||
- Event emissions should be properly typed
|
||||
- Component should compile without type errors
|
||||
|
||||
#### Documentation
|
||||
- JSDoc comments explaining component purpose
|
||||
- Usage examples in comments
|
||||
- Clear prop descriptions and types
|
||||
|
||||
### Validation Checklist
|
||||
|
||||
After component extraction:
|
||||
- [ ] **No template duplication**: Extracted patterns don't appear elsewhere
|
||||
- [ ] **Proper component registration**: All components properly imported and registered
|
||||
- [ ] **Event handling works**: Parent components receive and handle events correctly
|
||||
- [ ] **Props validation**: All required props are provided with correct types
|
||||
- [ ] **Styling consistency**: Extracted components maintain visual consistency
|
||||
- [ ] **Functionality preserved**: All original functionality works with extracted components
|
||||
|
||||
## After Migration Checklist
|
||||
|
||||
⚠️ **CRITICAL**: Use `docs/migration-templates/COMPLETE_MIGRATION_CHECKLIST.md` for comprehensive validation
|
||||
@@ -621,6 +779,23 @@ get itemCoordinates() {
|
||||
- [ ] **Unused notification constants removed from imports but these can mean that notifications have been overlooked**
|
||||
- [ ] **Legacy wrapper functions removed (e.g., `danger()`, `success()`, etc.)**
|
||||
|
||||
### Phase 4: Template Streamlining (if applicable)
|
||||
- [ ] **All long class attributes (50+ characters) extracted to computed properties**
|
||||
- [ ] **Complex conditional logic moved to computed properties**
|
||||
- [ ] **Repeated expressions extracted to computed properties**
|
||||
- [ ] **Configuration objects moved to computed properties**
|
||||
- [ ] **All computed properties have JSDoc documentation**
|
||||
|
||||
### Phase 5: Component Extraction (if applicable)
|
||||
- [ ] **Reusable UI patterns identified and extracted to separate components**
|
||||
- [ ] **Form elements extracted to reusable components**
|
||||
- [ ] **Layout patterns extracted to reusable components**
|
||||
- [ ] **Validation patterns extracted to reusable components**
|
||||
- [ ] **All extracted components have clear props interfaces**
|
||||
- [ ] **All extracted components have proper event handling**
|
||||
- [ ] **All extracted components have JSDoc documentation**
|
||||
- [ ] **Parent components properly import and use extracted components**
|
||||
|
||||
### Final Validation
|
||||
- [ ] Error handling includes component name context
|
||||
- [ ] Component compiles without TypeScript errors
|
||||
|
||||
Reference in New Issue
Block a user