forked from jsnbuchanan/crowd-funder-for-time-pwa
Convert Vue components to use @Emit decorator instead of manual emits declarations
Replace manual emits declarations with proper @Emit decorator usage across components:
- ActivityListItem: Add @Emit methods for viewImage, loadClaim, confirmClaim
- ContactInputForm: Convert handleQRScan to use @Emit("qr-scan")
- ContactBulkActions: Add @Emit methods for toggle-all-selection, copy-selected
- ContactListHeader: Add @Emit methods for all 5 emitted events
- MembersList: Add @Emit("error") method for error handling
- LargeIdenticonModal: Add @Emit("close") method
- ContactListItem: Add @Emit methods for all 4 emitted events
Update all templates to call emit methods instead of direct $emit calls.
Fix TypeScript type issues with optional parameters.
Resolves Vue warning about undeclared emitted events.
Follows vue-facing-decorator best practices and improves code consistency.
This commit is contained in:
@@ -52,7 +52,7 @@
|
|||||||
<a
|
<a
|
||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
data-testid="circle-info-link"
|
data-testid="circle-info-link"
|
||||||
@click="$emit('loadClaim', record.jwtId)"
|
@click="emitLoadClaim(record.jwtId)"
|
||||||
>
|
>
|
||||||
<font-awesome icon="circle-info" class="fa-fw text-slate-500" />
|
<font-awesome icon="circle-info" class="fa-fw text-slate-500" />
|
||||||
</a>
|
</a>
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
class="block bg-slate-100/50 backdrop-blur-md px-6 py-4 cursor-pointer"
|
class="block bg-slate-100/50 backdrop-blur-md px-6 py-4 cursor-pointer"
|
||||||
@click="$emit('viewImage', record.image)"
|
@click="emitViewImage(record.image)"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
class="w-full h-auto max-w-lg max-h-96 object-contain mx-auto drop-shadow-md"
|
class="w-full h-auto max-w-lg max-h-96 object-contain mx-auto drop-shadow-md"
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
|
|
||||||
<!-- Description -->
|
<!-- Description -->
|
||||||
<p class="font-medium">
|
<p class="font-medium">
|
||||||
<a class="cursor-pointer" @click="$emit('loadClaim', record.jwtId)">
|
<a class="cursor-pointer" @click="emitLoadClaim(record.jwtId)">
|
||||||
{{ description }}
|
{{ description }}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
@@ -248,7 +248,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Prop, Vue } from "vue-facing-decorator";
|
import { Component, Prop, Vue, Emit } from "vue-facing-decorator";
|
||||||
import { GiveRecordWithContactInfo } from "@/interfaces/give";
|
import { GiveRecordWithContactInfo } from "@/interfaces/give";
|
||||||
import EntityIcon from "./EntityIcon.vue";
|
import EntityIcon from "./EntityIcon.vue";
|
||||||
import { isGiveClaimType, notifyWhyCannotConfirm } from "../libs/util";
|
import { isGiveClaimType, notifyWhyCannotConfirm } from "../libs/util";
|
||||||
@@ -340,7 +340,19 @@ export default class ActivityListItem extends Vue {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleConfirmClick() {
|
// Emit methods using @Emit decorator
|
||||||
|
@Emit("viewImage")
|
||||||
|
emitViewImage(imageUrl: string) {
|
||||||
|
return imageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Emit("loadClaim")
|
||||||
|
emitLoadClaim(jwtId: string) {
|
||||||
|
return jwtId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Emit("confirmClaim")
|
||||||
|
emitConfirmClaim() {
|
||||||
if (!this.canConfirm) {
|
if (!this.canConfirm) {
|
||||||
notifyWhyCannotConfirm(
|
notifyWhyCannotConfirm(
|
||||||
(msg, timeout) => this.notify.info(msg.text ?? "", timeout),
|
(msg, timeout) => this.notify.info(msg.text ?? "", timeout),
|
||||||
@@ -352,7 +364,11 @@ export default class ActivityListItem extends Vue {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$emit("confirmClaim", this.record);
|
return this.record;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleConfirmClick() {
|
||||||
|
this.emitConfirmClaim();
|
||||||
}
|
}
|
||||||
|
|
||||||
get friendlyDate(): string {
|
get friendlyDate(): string {
|
||||||
|
|||||||
@@ -6,13 +6,13 @@
|
|||||||
:checked="allContactsSelected"
|
:checked="allContactsSelected"
|
||||||
class="align-middle ml-2 h-6 w-6"
|
class="align-middle ml-2 h-6 w-6"
|
||||||
data-testId="contactCheckAllBottom"
|
data-testId="contactCheckAllBottom"
|
||||||
@click="$emit('toggle-all-selection')"
|
@click="emitToggleAllSelection"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
v-if="!showGiveNumbers"
|
v-if="!showGiveNumbers"
|
||||||
:class="copyButtonClass"
|
:class="copyButtonClass"
|
||||||
:disabled="copyButtonDisabled"
|
:disabled="copyButtonDisabled"
|
||||||
@click="$emit('copy-selected')"
|
@click="emitCopySelected"
|
||||||
>
|
>
|
||||||
Copy
|
Copy
|
||||||
</button>
|
</button>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Vue, Prop } from "vue-facing-decorator";
|
import { Component, Vue, Prop, Emit } from "vue-facing-decorator";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ContactBulkActions - Contact bulk actions component
|
* ContactBulkActions - Contact bulk actions component
|
||||||
@@ -38,5 +38,16 @@ export default class ContactBulkActions extends Vue {
|
|||||||
@Prop({ required: true }) allContactsSelected!: boolean;
|
@Prop({ required: true }) allContactsSelected!: boolean;
|
||||||
@Prop({ required: true }) copyButtonClass!: string;
|
@Prop({ required: true }) copyButtonClass!: string;
|
||||||
@Prop({ required: true }) copyButtonDisabled!: boolean;
|
@Prop({ required: true }) copyButtonDisabled!: boolean;
|
||||||
|
|
||||||
|
// Emit methods using @Emit decorator
|
||||||
|
@Emit("toggle-all-selection")
|
||||||
|
emitToggleAllSelection() {
|
||||||
|
// No parameters needed
|
||||||
|
}
|
||||||
|
|
||||||
|
@Emit("copy-selected")
|
||||||
|
emitCopySelected() {
|
||||||
|
// No parameters needed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Vue, Prop } from "vue-facing-decorator";
|
import { Component, Vue, Prop, Emit } from "vue-facing-decorator";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ContactInputForm - Contact input form component
|
* ContactInputForm - Contact input form component
|
||||||
@@ -165,9 +165,9 @@ export default class ContactInputForm extends Vue {
|
|||||||
* Handle QR scan button click
|
* Handle QR scan button click
|
||||||
* Emits qr-scan event for parent handling
|
* Emits qr-scan event for parent handling
|
||||||
*/
|
*/
|
||||||
|
@Emit("qr-scan")
|
||||||
private handleQRScan(): void {
|
private handleQRScan(): void {
|
||||||
console.log("[ContactInputForm] QR scan button clicked");
|
console.log("[ContactInputForm] QR scan button clicked");
|
||||||
this.$emit("qr-scan");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -8,21 +8,21 @@
|
|||||||
:checked="allContactsSelected"
|
:checked="allContactsSelected"
|
||||||
class="align-middle ml-2 h-6 w-6"
|
class="align-middle ml-2 h-6 w-6"
|
||||||
data-testId="contactCheckAllTop"
|
data-testId="contactCheckAllTop"
|
||||||
@click="$emit('toggle-all-selection')"
|
@click="emitToggleAllSelection"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
v-if="!showGiveNumbers"
|
v-if="!showGiveNumbers"
|
||||||
:class="copyButtonClass"
|
:class="copyButtonClass"
|
||||||
:disabled="copyButtonDisabled"
|
:disabled="copyButtonDisabled"
|
||||||
data-testId="copySelectedContactsButtonTop"
|
data-testId="copySelectedContactsButtonTop"
|
||||||
@click="$emit('copy-selected')"
|
@click="emitCopySelected"
|
||||||
>
|
>
|
||||||
Copy
|
Copy
|
||||||
</button>
|
</button>
|
||||||
<font-awesome
|
<font-awesome
|
||||||
icon="circle-info"
|
icon="circle-info"
|
||||||
class="text-2xl text-blue-500 ml-2"
|
class="text-2xl text-blue-500 ml-2"
|
||||||
@click="$emit('show-copy-info')"
|
@click="emitShowCopyInfo"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
v-if="showGiveNumbers"
|
v-if="showGiveNumbers"
|
||||||
class="text-md bg-gradient-to-b shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-3 py-1.5 rounded-md"
|
class="text-md bg-gradient-to-b shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-3 py-1.5 rounded-md"
|
||||||
:class="giveAmountsButtonClass"
|
:class="giveAmountsButtonClass"
|
||||||
@click="$emit('toggle-give-totals')"
|
@click="emitToggleGiveTotals"
|
||||||
>
|
>
|
||||||
{{ giveAmountsButtonText }}
|
{{ giveAmountsButtonText }}
|
||||||
<font-awesome icon="left-right" class="fa-fw" />
|
<font-awesome icon="left-right" class="fa-fw" />
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
class="text-md bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-3 py-1.5 rounded-md"
|
class="text-md bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-3 py-1.5 rounded-md"
|
||||||
@click="$emit('toggle-show-actions')"
|
@click="emitToggleShowActions"
|
||||||
>
|
>
|
||||||
{{ showActionsButtonText }}
|
{{ showActionsButtonText }}
|
||||||
</button>
|
</button>
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Vue, Prop } from "vue-facing-decorator";
|
import { Component, Vue, Prop, Emit } from "vue-facing-decorator";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ContactListHeader - Contact list header component
|
* ContactListHeader - Contact list header component
|
||||||
@@ -71,5 +71,31 @@ export default class ContactListHeader extends Vue {
|
|||||||
@Prop({ required: true }) giveAmountsButtonText!: string;
|
@Prop({ required: true }) giveAmountsButtonText!: string;
|
||||||
@Prop({ required: true }) showActionsButtonText!: string;
|
@Prop({ required: true }) showActionsButtonText!: string;
|
||||||
@Prop({ required: true }) giveAmountsButtonClass!: Record<string, boolean>;
|
@Prop({ required: true }) giveAmountsButtonClass!: Record<string, boolean>;
|
||||||
|
|
||||||
|
// Emit methods using @Emit decorator
|
||||||
|
@Emit("toggle-all-selection")
|
||||||
|
emitToggleAllSelection() {
|
||||||
|
// No parameters needed
|
||||||
|
}
|
||||||
|
|
||||||
|
@Emit("copy-selected")
|
||||||
|
emitCopySelected() {
|
||||||
|
// No parameters needed
|
||||||
|
}
|
||||||
|
|
||||||
|
@Emit("show-copy-info")
|
||||||
|
emitShowCopyInfo() {
|
||||||
|
// No parameters needed
|
||||||
|
}
|
||||||
|
|
||||||
|
@Emit("toggle-give-totals")
|
||||||
|
emitToggleGiveTotals() {
|
||||||
|
// No parameters needed
|
||||||
|
}
|
||||||
|
|
||||||
|
@Emit("toggle-show-actions")
|
||||||
|
emitToggleShowActions() {
|
||||||
|
// No parameters needed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -9,14 +9,14 @@
|
|||||||
:checked="isSelected"
|
:checked="isSelected"
|
||||||
class="ml-2 h-6 w-6 flex-shrink-0"
|
class="ml-2 h-6 w-6 flex-shrink-0"
|
||||||
data-testId="contactCheckOne"
|
data-testId="contactCheckOne"
|
||||||
@click="$emit('toggle-selection', contact.did)"
|
@click="emitToggleSelection(contact.did)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<EntityIcon
|
<EntityIcon
|
||||||
:contact="contact"
|
:contact="contact"
|
||||||
:icon-size="48"
|
:icon-size="48"
|
||||||
class="shrink-0 align-text-bottom border border-slate-300 rounded cursor-pointer overflow-hidden"
|
class="shrink-0 align-text-bottom border border-slate-300 rounded cursor-pointer overflow-hidden"
|
||||||
@click="$emit('show-identicon', contact)"
|
@click="emitShowIdenticon(contact)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="overflow-hidden">
|
<div class="overflow-hidden">
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
<button
|
<button
|
||||||
class="text-sm bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2.5 py-1.5 rounded-l-md"
|
class="text-sm bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2.5 py-1.5 rounded-l-md"
|
||||||
:title="getGiveDescriptionForContact(contact.did, true)"
|
:title="getGiveDescriptionForContact(contact.did, true)"
|
||||||
@click="$emit('show-gifted-dialog', contact.did, activeDid)"
|
@click="emitShowGiftedDialog(contact.did, activeDid)"
|
||||||
>
|
>
|
||||||
{{ getGiveAmountForContact(contact.did, true) }}
|
{{ getGiveAmountForContact(contact.did, true) }}
|
||||||
</button>
|
</button>
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
<button
|
<button
|
||||||
class="text-sm bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2.5 py-1.5 rounded-r-md border-l"
|
class="text-sm bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2.5 py-1.5 rounded-r-md border-l"
|
||||||
:title="getGiveDescriptionForContact(contact.did, false)"
|
:title="getGiveDescriptionForContact(contact.did, false)"
|
||||||
@click="$emit('show-gifted-dialog', activeDid, contact.did)"
|
@click="emitShowGiftedDialog(activeDid, contact.did)"
|
||||||
>
|
>
|
||||||
{{ getGiveAmountForContact(contact.did, false) }}
|
{{ getGiveAmountForContact(contact.did, false) }}
|
||||||
</button>
|
</button>
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
<button
|
<button
|
||||||
class="text-sm bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-1.5 rounded-md"
|
class="text-sm bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-1.5 rounded-md"
|
||||||
data-testId="offerButton"
|
data-testId="offerButton"
|
||||||
@click="$emit('open-offer-dialog', contact.did, contact.name)"
|
@click="emitOpenOfferDialog(contact.did, contact.name)"
|
||||||
>
|
>
|
||||||
Offer
|
Offer
|
||||||
</button>
|
</button>
|
||||||
@@ -102,7 +102,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Vue, Prop } from "vue-facing-decorator";
|
import { Component, Vue, Prop, Emit } from "vue-facing-decorator";
|
||||||
import EntityIcon from "./EntityIcon.vue";
|
import EntityIcon from "./EntityIcon.vue";
|
||||||
import { Contact } from "../db/tables/contacts";
|
import { Contact } from "../db/tables/contacts";
|
||||||
import { AppString } from "../constants/app";
|
import { AppString } from "../constants/app";
|
||||||
@@ -140,6 +140,27 @@ export default class ContactListItem extends Vue {
|
|||||||
// Constants
|
// Constants
|
||||||
AppString = AppString;
|
AppString = AppString;
|
||||||
|
|
||||||
|
// Emit methods using @Emit decorator
|
||||||
|
@Emit("toggle-selection")
|
||||||
|
emitToggleSelection(did: string) {
|
||||||
|
return did;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Emit("show-identicon")
|
||||||
|
emitShowIdenticon(contact: Contact) {
|
||||||
|
return contact;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Emit("show-gifted-dialog")
|
||||||
|
emitShowGiftedDialog(fromDid: string, toDid: string) {
|
||||||
|
return { fromDid, toDid };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Emit("open-offer-dialog")
|
||||||
|
emitOpenOfferDialog(did: string, name: string | undefined) {
|
||||||
|
return { did, name };
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format contact name with non-breaking spaces
|
* Format contact name with non-breaking spaces
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -55,10 +55,7 @@
|
|||||||
aria-label="Delete profile image"
|
aria-label="Delete profile image"
|
||||||
@click="deleteImage"
|
@click="deleteImage"
|
||||||
>
|
>
|
||||||
<font-awesome
|
<font-awesome icon="trash-can" aria-hidden="true" />
|
||||||
icon="trash-can"
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
<div v-else class="text-center">
|
<div v-else class="text-center">
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
<div class="flex-1 flex items-center justify-center p-2">
|
<div class="flex-1 flex items-center justify-center p-2">
|
||||||
<div class="w-full h-full flex items-center justify-center">
|
<div class="w-full h-full flex items-center justify-center">
|
||||||
<img
|
<img
|
||||||
:src="transformedImageUrl"
|
:src="imageUrl"
|
||||||
class="max-h-[calc(100vh-5rem)] w-full h-full object-contain"
|
class="max-h-[calc(100vh-5rem)] w-full h-full object-contain"
|
||||||
alt="expanded shared content"
|
alt="expanded shared content"
|
||||||
@click="close"
|
@click="close"
|
||||||
|
|||||||
@@ -7,14 +7,14 @@
|
|||||||
:contact="contact"
|
:contact="contact"
|
||||||
:icon-size="512"
|
:icon-size="512"
|
||||||
class="flex w-11/12 max-w-sm mx-auto mb-3 overflow-hidden bg-white rounded-lg shadow-lg"
|
class="flex w-11/12 max-w-sm mx-auto mb-3 overflow-hidden bg-white rounded-lg shadow-lg"
|
||||||
@click="$emit('close')"
|
@click="emitClose"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Vue, Prop } from "vue-facing-decorator";
|
import { Component, Vue, Prop, Emit } from "vue-facing-decorator";
|
||||||
import EntityIcon from "./EntityIcon.vue";
|
import EntityIcon from "./EntityIcon.vue";
|
||||||
import { Contact } from "../db/tables/contacts";
|
import { Contact } from "../db/tables/contacts";
|
||||||
|
|
||||||
@@ -34,5 +34,11 @@ import { Contact } from "../db/tables/contacts";
|
|||||||
})
|
})
|
||||||
export default class LargeIdenticonModal extends Vue {
|
export default class LargeIdenticonModal extends Vue {
|
||||||
@Prop({ required: true }) contact!: Contact | undefined;
|
@Prop({ required: true }) contact!: Contact | undefined;
|
||||||
|
|
||||||
|
// Emit methods using @Emit decorator
|
||||||
|
@Emit("close")
|
||||||
|
emitClose() {
|
||||||
|
// No parameters needed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -178,7 +178,7 @@
|
|||||||
// Validation: Passes lint checks and TypeScript compilation
|
// Validation: Passes lint checks and TypeScript compilation
|
||||||
// Navigation: Contacts → Chair Icon → Start/Join Meeting → Members List
|
// Navigation: Contacts → Chair Icon → Start/Join Meeting → Members List
|
||||||
|
|
||||||
import { Component, Vue, Prop } from "vue-facing-decorator";
|
import { Component, Vue, Prop, Emit } from "vue-facing-decorator";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
errorStringForLog,
|
errorStringForLog,
|
||||||
@@ -222,6 +222,12 @@ export default class MembersList extends Vue {
|
|||||||
@Prop({ required: true }) password!: string;
|
@Prop({ required: true }) password!: string;
|
||||||
@Prop({ default: false }) showOrganizerTools!: boolean;
|
@Prop({ default: false }) showOrganizerTools!: boolean;
|
||||||
|
|
||||||
|
// Emit methods using @Emit decorator
|
||||||
|
@Emit("error")
|
||||||
|
emitError(message: string) {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
decryptedMembers: DecryptedMember[] = [];
|
decryptedMembers: DecryptedMember[] = [];
|
||||||
firstName = "";
|
firstName = "";
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
@@ -262,10 +268,7 @@ export default class MembersList extends Vue {
|
|||||||
"Error fetching members: " + errorStringForLog(error),
|
"Error fetching members: " + errorStringForLog(error),
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
this.$emit(
|
this.emitError(serverMessageForUser(error) || "Failed to fetch members.");
|
||||||
"error",
|
|
||||||
serverMessageForUser(error) || "Failed to fetch members.",
|
|
||||||
);
|
|
||||||
} finally {
|
} finally {
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
}
|
}
|
||||||
@@ -478,8 +481,7 @@ export default class MembersList extends Vue {
|
|||||||
"Error toggling admission: " + errorStringForLog(error),
|
"Error toggling admission: " + errorStringForLog(error),
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
this.$emit(
|
this.emitError(
|
||||||
"error",
|
|
||||||
serverMessageForUser(error) ||
|
serverMessageForUser(error) ||
|
||||||
"Failed to update member admission status.",
|
"Failed to update member admission status.",
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1006,7 +1006,9 @@ export async function importFromMnemonic(
|
|||||||
|
|
||||||
// If settings weren't saved correctly, try individual updates
|
// If settings weren't saved correctly, try individual updates
|
||||||
if (firstName !== "User Zero" || isRegistered !== 1) {
|
if (firstName !== "User Zero" || isRegistered !== 1) {
|
||||||
logger.warn("[importFromMnemonic] Test User #0 settings not saved correctly, retrying with individual updates");
|
logger.warn(
|
||||||
|
"[importFromMnemonic] Test User #0 settings not saved correctly, retrying with individual updates",
|
||||||
|
);
|
||||||
|
|
||||||
await platformService.dbExec(
|
await platformService.dbExec(
|
||||||
"UPDATE settings SET firstName = ? WHERE accountDid = ?",
|
"UPDATE settings SET firstName = ? WHERE accountDid = ?",
|
||||||
@@ -1026,17 +1028,25 @@ export async function importFromMnemonic(
|
|||||||
|
|
||||||
if (retryResult?.values?.length) {
|
if (retryResult?.values?.length) {
|
||||||
const retrySettings = retryResult.values[0];
|
const retrySettings = retryResult.values[0];
|
||||||
logger.info("[importFromMnemonic] Test User #0 settings after retry", {
|
logger.info(
|
||||||
firstName: retrySettings[0],
|
"[importFromMnemonic] Test User #0 settings after retry",
|
||||||
isRegistered: retrySettings[1],
|
{
|
||||||
});
|
firstName: retrySettings[0],
|
||||||
|
isRegistered: retrySettings[1],
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.error("[importFromMnemonic] Failed to verify Test User #0 settings - no record found");
|
logger.error(
|
||||||
|
"[importFromMnemonic] Failed to verify Test User #0 settings - no record found",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("[importFromMnemonic] Error setting up Test User #0 settings:", error);
|
logger.error(
|
||||||
|
"[importFromMnemonic] Error setting up Test User #0 settings:",
|
||||||
|
error,
|
||||||
|
);
|
||||||
// Don't throw - allow the import to continue even if settings fail
|
// Don't throw - allow the import to continue even if settings fail
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,16 +3,18 @@
|
|||||||
<h2>PlatformServiceMixin Test</h2>
|
<h2>PlatformServiceMixin Test</h2>
|
||||||
<button @click="testInsert">Test Insert</button>
|
<button @click="testInsert">Test Insert</button>
|
||||||
<button @click="testUpdate">Test Update</button>
|
<button @click="testUpdate">Test Update</button>
|
||||||
<button
|
<button :class="primaryButtonClasses" @click="testUserZeroSettings">
|
||||||
:class="primaryButtonClasses"
|
|
||||||
@click="testUserZeroSettings"
|
|
||||||
>
|
|
||||||
Test User #0 Settings
|
Test User #0 Settings
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div v-if="userZeroTestResult" class="mt-4 p-4 border border-gray-300 rounded-md bg-gray-50">
|
<div
|
||||||
|
v-if="userZeroTestResult"
|
||||||
|
class="mt-4 p-4 border border-gray-300 rounded-md bg-gray-50"
|
||||||
|
>
|
||||||
<h4 class="font-semibold mb-2">User #0 Settings Test Result:</h4>
|
<h4 class="font-semibold mb-2">User #0 Settings Test Result:</h4>
|
||||||
<pre class="text-sm">{{ JSON.stringify(userZeroTestResult, null, 2) }}</pre>
|
<pre class="text-sm">{{
|
||||||
|
JSON.stringify(userZeroTestResult, null, 2)
|
||||||
|
}}</pre>
|
||||||
</div>
|
</div>
|
||||||
<pre>{{ result }}</pre>
|
<pre>{{ result }}</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -222,11 +222,18 @@ export const PlatformServiceMixin = {
|
|||||||
let value = row[index];
|
let value = row[index];
|
||||||
|
|
||||||
// Convert SQLite integer booleans to JavaScript booleans
|
// Convert SQLite integer booleans to JavaScript booleans
|
||||||
if (column === 'isRegistered' || column === 'finishedOnboarding' ||
|
if (
|
||||||
column === 'filterFeedByVisible' || column === 'filterFeedByNearby' ||
|
column === "isRegistered" ||
|
||||||
column === 'hideRegisterPromptOnNewContact' || column === 'showContactGivesInline' ||
|
column === "finishedOnboarding" ||
|
||||||
column === 'showGeneralAdvanced' || column === 'showShortcutBvc' ||
|
column === "filterFeedByVisible" ||
|
||||||
column === 'warnIfProdServer' || column === 'warnIfTestServer') {
|
column === "filterFeedByNearby" ||
|
||||||
|
column === "hideRegisterPromptOnNewContact" ||
|
||||||
|
column === "showContactGivesInline" ||
|
||||||
|
column === "showGeneralAdvanced" ||
|
||||||
|
column === "showShortcutBvc" ||
|
||||||
|
column === "warnIfProdServer" ||
|
||||||
|
column === "warnIfTestServer"
|
||||||
|
) {
|
||||||
if (value === 1) {
|
if (value === 1) {
|
||||||
value = true;
|
value = true;
|
||||||
} else if (value === 0) {
|
} else if (value === 0) {
|
||||||
@@ -1403,7 +1410,9 @@ export const PlatformServiceMixin = {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!result?.values?.length) {
|
if (!result?.values?.length) {
|
||||||
logger.warn(`[PlatformServiceMixin] No settings found for DID: ${did}`);
|
logger.warn(
|
||||||
|
`[PlatformServiceMixin] No settings found for DID: ${did}`,
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1413,7 +1422,9 @@ export const PlatformServiceMixin = {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!mappedResults.length) {
|
if (!mappedResults.length) {
|
||||||
logger.warn(`[PlatformServiceMixin] Failed to map settings for DID: ${did}`);
|
logger.warn(
|
||||||
|
`[PlatformServiceMixin] Failed to map settings for DID: ${did}`,
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1428,7 +1439,10 @@ export const PlatformServiceMixin = {
|
|||||||
|
|
||||||
return settings;
|
return settings;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`[PlatformServiceMixin] Error debugging settings for DID ${did}:`, error);
|
logger.error(
|
||||||
|
`[PlatformServiceMixin] Error debugging settings for DID ${did}:`,
|
||||||
|
error,
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1442,14 +1456,24 @@ export const PlatformServiceMixin = {
|
|||||||
async $debugMergedSettings(did: string): Promise<void> {
|
async $debugMergedSettings(did: string): Promise<void> {
|
||||||
try {
|
try {
|
||||||
// Get default settings
|
// Get default settings
|
||||||
const defaultSettings = await this.$getSettings(MASTER_SETTINGS_KEY, {});
|
const defaultSettings = await this.$getSettings(
|
||||||
logger.info(`[PlatformServiceMixin] Default settings:`, defaultSettings);
|
MASTER_SETTINGS_KEY,
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
logger.info(
|
||||||
|
`[PlatformServiceMixin] Default settings:`,
|
||||||
|
defaultSettings,
|
||||||
|
);
|
||||||
|
|
||||||
// Get DID-specific settings
|
// Get DID-specific settings
|
||||||
const didSettings = await this.$debugDidSettings(did);
|
const didSettings = await this.$debugDidSettings(did);
|
||||||
|
|
||||||
// Get merged settings
|
// Get merged settings
|
||||||
const mergedSettings = await this.$getMergedSettings(MASTER_SETTINGS_KEY, did, defaultSettings || {});
|
const mergedSettings = await this.$getMergedSettings(
|
||||||
|
MASTER_SETTINGS_KEY,
|
||||||
|
did,
|
||||||
|
defaultSettings || {},
|
||||||
|
);
|
||||||
|
|
||||||
logger.info(`[PlatformServiceMixin] Merged settings for ${did}:`, {
|
logger.info(`[PlatformServiceMixin] Merged settings for ${did}:`, {
|
||||||
defaultSettings,
|
defaultSettings,
|
||||||
@@ -1458,7 +1482,10 @@ export const PlatformServiceMixin = {
|
|||||||
isRegistered: mergedSettings.isRegistered,
|
isRegistered: mergedSettings.isRegistered,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`[PlatformServiceMixin] Error debugging merged settings for DID ${did}:`, error);
|
logger.error(
|
||||||
|
`[PlatformServiceMixin] Error debugging merged settings for DID ${did}:`,
|
||||||
|
error,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1415,7 +1415,8 @@ export default class AccountViewView extends Vue {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.limitsMessage = ACCOUNT_VIEW_CONSTANTS.LIMITS.ERROR_RETRIEVING_LIMITS;
|
this.limitsMessage =
|
||||||
|
ACCOUNT_VIEW_CONSTANTS.LIMITS.ERROR_RETRIEVING_LIMITS;
|
||||||
logger.error("Error retrieving limits: ", error);
|
logger.error("Error retrieving limits: ", error);
|
||||||
// this.notify.error(this.limitsMessage, TIMEOUTS.STANDARD);
|
// this.notify.error(this.limitsMessage, TIMEOUTS.STANDARD);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -1475,7 +1476,7 @@ export default class AccountViewView extends Vue {
|
|||||||
async deleteImage(): Promise<void> {
|
async deleteImage(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
// Extract the image ID from the full URL
|
// Extract the image ID from the full URL
|
||||||
const imageId = this.profileImageUrl?.split('/').pop();
|
const imageId = this.profileImageUrl?.split("/").pop();
|
||||||
if (!imageId) {
|
if (!imageId) {
|
||||||
this.notify.error("Invalid image URL");
|
this.notify.error("Invalid image URL");
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user