Browse Source

Refactor ContactsView.vue to use notification constants

- Extracted all inline notification and danger messages to src/constants/notifications.ts
- Added 20+ new notification constants and 2 template functions for dynamic messages
- Replaced all notify and danger calls with references to new constants/templates
- Updated imports for notification constants/templates and removed unused imports
- Fixed all linter errors - all notification messages now use single source of truth
- All $notify calls now use constants (remaining 3 are complex modals requiring raw calls)
pull/142/head
Matthew Raymer 19 hours ago
parent
commit
af7a02bc5a
  1. 151
      src/constants/notifications.ts
  2. 137
      src/views/ContactsView.vue
  3. 175
      src/views/OnboardMeetingSetupView.vue

151
src/constants/notifications.ts

@ -123,6 +123,17 @@ export const NOTIFY_UNCONFIRMED_HOURS = {
message: "Would you like to confirm some of those hours?", message: "Would you like to confirm some of those hours?",
}; };
// Dynamic message template for unconfirmed hours (used in ContactsView.vue)
export const NOTIFY_UNCONFIRMED_HOURS_DYNAMIC = {
title: "Unconfirmed Hours",
// Template: "There {is/are} {count} unconfirmed {hour/hours} from them. Would you like to confirm some of those hours?"
getMessage: (count: number): string => {
const isAre = count === 1 ? "is" : "are";
const hours = count === 1 ? "hour" : "hours";
return `There ${isAre} ${count} unconfirmed ${hours} from them. Would you like to confirm some of those hours?`;
},
};
// Complex modal constants (for raw $notify calls with advanced features) // Complex modal constants (for raw $notify calls with advanced features)
// MembersList.vue complex modals // MembersList.vue complex modals
export const NOTIFY_ADD_CONTACT_FIRST = { export const NOTIFY_ADD_CONTACT_FIRST = {
@ -284,3 +295,143 @@ export const NOTIFY_PHOTO_PROCESSING_ERROR = {
title: "Processing Error", title: "Processing Error",
message: "Failed to process image. Please try again.", message: "Failed to process image. Please try again.",
}; };
// OnboardMeetingSetupView.vue constants
export const NOTIFY_MEETING_INVALID_TIME = {
title: "Invalid Time",
message: "Select a future time for the meeting expiration.",
};
export const NOTIFY_MEETING_NAME_REQUIRED = {
title: "Invalid Name",
message: "Please enter your name.",
};
export const NOTIFY_MEETING_PASSWORD_REQUIRED = {
title: "Invalid Password",
message: "Please enter a password.",
};
export const NOTIFY_MEETING_CREATED = {
title: "Success",
message: "Meeting created.",
};
export const NOTIFY_MEETING_DELETED = {
title: "Success",
message: "Meeting deleted successfully.",
};
export const NOTIFY_MEETING_LINK_COPIED = {
title: "Copied",
message: "The member link is copied to the clipboard.",
};
// ContactsView.vue extracted notification messages
export const NOTIFY_CONTACT_NO_INFO = {
title: "No Contact Info",
message: "There was no contact info to add. Try the other green buttons.",
};
export const NOTIFY_CONTACT_INVALID_URL = {
title: "Invalid URL",
message: "Invalid contact URL format.",
};
export const NOTIFY_CONTACTS_ADDED_CSV = {
title: "Contacts Added",
message: "Each contact was added. Nothing was sent to the server.",
};
export const NOTIFY_CONTACTS_ADD_ERROR = {
title: "Add Contacts Error",
message: "An error occurred. Some contacts may have been added.",
};
export const NOTIFY_CONTACT_INPUT_PARSE_ERROR = {
title: "Invalid Contact List",
message: "The input could not be parsed.",
};
export const NOTIFY_CONTACT_NO_CONTACT_FOUND = {
title: "No Contact Info",
message: "No contact info was found in that input.",
};
export const NOTIFY_CONTACT_NO_DID = {
title: "Incomplete Contact",
message: "Cannot add a contact without a DID.",
};
export const NOTIFY_CONTACT_INVALID_DID = {
title: "Invalid DID",
message: "The DID must begin with 'did:'",
};
export const NOTIFY_CONTACT_IMPORT_ERROR = {
title: "Contact Not Added",
message: "An error prevented this import.",
};
export const NOTIFY_CONTACT_IMPORT_CONFLICT = {
title: "Contact Not Added",
message:
"A contact with that DID is already in your contact list. Edit them directly below.",
};
export const NOTIFY_CONTACT_IMPORT_CONSTRAINT = {
title: "Contact Not Added",
message: "Check that the contact doesn't conflict with any you already have.",
};
export const NOTIFY_GIVES_LOAD_ERROR = {
title: "Gives Load Error",
message: "Got an error loading your gives.",
};
export const NOTIFY_CONTACT_SETTING_SAVE_ERROR = {
title: "Setting Save Error",
message:
"The setting may not have saved. Try again, maybe after restarting the app.",
};
export const NOTIFY_MEETING_STATUS_ERROR = {
title: "Meeting Error",
message: "There was an error checking your meeting status.",
};
export const NOTIFY_CONTACTS_ADDED_VISIBLE = {
title: "Contact Added",
message: "They were added, and your activity is visible to them.",
};
export const NOTIFY_CONTACTS_ADDED = {
title: "Contact Added",
message: "They were added.",
};
export const NOTIFY_CONTACT_INFO_COPY = {
title: "Info",
message: "Contact info will include name, ID, profile image, and public key.",
};
export const NOTIFY_CONTACTS_SELECT_TO_COPY = {
title: "Select Contacts",
message: "You must select contacts to copy.",
};
export const NOTIFY_CONTACT_LINK_COPIED = {
title: "Copied",
message: "contact link",
};
// Template for registration success message
export const getRegisterPersonSuccessMessage = (name?: string): string =>
`${name || "That unnamed person"} ${NOTIFY_REGISTER_PERSON_SUCCESS.message}`;
// Template for visibility success message
export const getVisibilitySuccessMessage = (
name?: string,
visible = true,
): string =>
`${name || "That user"} can ${visible ? "" : "not "}see your activity.`;

137
src/views/ContactsView.vue

@ -305,12 +305,31 @@ import {
NOTIFY_INVITE_ERROR, NOTIFY_INVITE_ERROR,
NOTIFY_ONBOARDING_CONFIRM, NOTIFY_ONBOARDING_CONFIRM,
NOTIFY_REGISTER_NOT_AVAILABLE, NOTIFY_REGISTER_NOT_AVAILABLE,
NOTIFY_REGISTER_PERSON_SUCCESS,
NOTIFY_REGISTER_PERSON_ERROR, NOTIFY_REGISTER_PERSON_ERROR,
NOTIFY_VISIBILITY_ERROR, NOTIFY_VISIBILITY_ERROR,
NOTIFY_UNCONFIRMED_HOURS, NOTIFY_UNCONFIRMED_HOURS_DYNAMIC,
NOTIFY_REGISTER_CONTACT, NOTIFY_REGISTER_CONTACT,
NOTIFY_ONBOARDING_MEETING, NOTIFY_ONBOARDING_MEETING,
NOTIFY_CONTACT_NO_INFO,
NOTIFY_CONTACT_INVALID_URL,
NOTIFY_CONTACTS_ADDED_CSV,
NOTIFY_CONTACTS_ADD_ERROR,
NOTIFY_CONTACT_INPUT_PARSE_ERROR,
NOTIFY_CONTACT_NO_CONTACT_FOUND,
NOTIFY_CONTACT_NO_DID,
NOTIFY_CONTACT_INVALID_DID,
NOTIFY_CONTACT_IMPORT_ERROR,
NOTIFY_CONTACT_IMPORT_CONFLICT,
NOTIFY_CONTACT_IMPORT_CONSTRAINT,
NOTIFY_GIVES_LOAD_ERROR,
NOTIFY_CONTACT_SETTING_SAVE_ERROR,
NOTIFY_MEETING_STATUS_ERROR,
NOTIFY_CONTACTS_ADDED,
NOTIFY_CONTACT_INFO_COPY,
NOTIFY_CONTACTS_SELECT_TO_COPY,
NOTIFY_CONTACT_LINK_COPIED,
getRegisterPersonSuccessMessage,
getVisibilitySuccessMessage,
} from "@/constants/notifications"; } from "@/constants/notifications";
@Component({ @Component({
@ -689,24 +708,24 @@ export default class ContactsView extends Vue {
} catch (error) { } catch (error) {
const fullError = "Error loading gives: " + errorStringForLog(error); const fullError = "Error loading gives: " + errorStringForLog(error);
this.$logAndConsole(fullError, true); this.$logAndConsole(fullError, true);
this.notify.error("Got an error loading your gives.", TIMEOUTS.STANDARD); this.notify.error(NOTIFY_GIVES_LOAD_ERROR.message, TIMEOUTS.STANDARD);
} }
} }
private async onClickNewContact(): Promise<void> { private async onClickNewContact(): Promise<void> {
const contactInput = this.contactInput.trim(); const contactInput = this.contactInput.trim();
if (!contactInput) { if (!contactInput) {
this.danger( this.notify.error(NOTIFY_CONTACT_NO_INFO.message, TIMEOUTS.STANDARD);
"There was no contact info to add. Try the other green buttons.",
"No Contact",
);
return; return;
} }
if (contactInput.includes(CONTACT_IMPORT_CONFIRM_URL_PATH_TIME_SAFARI)) { if (contactInput.includes(CONTACT_IMPORT_CONFIRM_URL_PATH_TIME_SAFARI)) {
const jwt = getContactJwtFromJwtUrl(contactInput); const jwt = getContactJwtFromJwtUrl(contactInput);
if (!jwt) { if (!jwt) {
this.danger("Invalid contact URL format.", "Invalid URL"); this.notify.error(
NOTIFY_CONTACT_INVALID_URL.message,
TIMEOUTS.STANDARD,
);
return; return;
} }
const { payload } = decodeEndorserJwt(jwt); const { payload } = decodeEndorserJwt(jwt);
@ -729,7 +748,10 @@ export default class ContactsView extends Vue {
) { ) {
const jwt = getContactJwtFromJwtUrl(contactInput); const jwt = getContactJwtFromJwtUrl(contactInput);
if (!jwt) { if (!jwt) {
this.danger("Invalid contact URL format.", "Invalid URL"); this.notify.error(
NOTIFY_CONTACT_INVALID_URL.message,
TIMEOUTS.STANDARD,
);
return; return;
} }
const { payload } = decodeEndorserJwt(jwt); const { payload } = decodeEndorserJwt(jwt);
@ -758,14 +780,17 @@ export default class ContactsView extends Vue {
try { try {
await Promise.all(lineAdded); await Promise.all(lineAdded);
this.notify.success( this.notify.success(
"Each contact was added. Nothing was sent to the server.", NOTIFY_CONTACTS_ADDED_CSV.message,
TIMEOUTS.STANDARD, // keeping it up so that the "visibility" message is seen TIMEOUTS.STANDARD,
); );
} catch (e) { } catch (e) {
const fullError = const fullError =
"Error adding contacts from CSV: " + errorStringForLog(e); NOTIFY_CONTACTS_ADD_ERROR.message + ": " + errorStringForLog(e);
this.$logAndConsole(fullError, true); this.$logAndConsole(fullError, true);
this.danger("An error occurred. Some contacts may have been added."); this.notify.error(
NOTIFY_CONTACT_INPUT_PARSE_ERROR.message,
TIMEOUTS.STANDARD,
);
} }
this.contacts = await this.$getAllContacts(); this.contacts = await this.$getAllContacts();
@ -828,14 +853,19 @@ export default class ContactsView extends Vue {
}); });
} catch (e) { } catch (e) {
const fullError = const fullError =
"Error adding contacts from array: " + errorStringForLog(e); NOTIFY_CONTACT_INPUT_PARSE_ERROR.message +
": " +
errorStringForLog(e);
this.$logAndConsole(fullError, true); this.$logAndConsole(fullError, true);
this.danger("The input could not be parsed.", "Invalid Contact List"); this.notify.error(
NOTIFY_CONTACT_NO_CONTACT_FOUND.message,
TIMEOUTS.STANDARD,
);
} }
return; return;
} }
this.danger("No contact info was found in that input.", "No Contact Info"); this.notify.error(NOTIFY_CONTACT_NO_INFO.message, TIMEOUTS.STANDARD);
} }
private async addContactFromEndorserMobileLine( private async addContactFromEndorserMobileLine(
@ -848,11 +878,11 @@ export default class ContactsView extends Vue {
private async addContact(newContact: Contact) { private async addContact(newContact: Contact) {
if (!newContact.did) { if (!newContact.did) {
this.danger("Cannot add a contact without a DID.", "Incomplete Contact"); this.notify.error(NOTIFY_CONTACT_NO_DID.message, TIMEOUTS.STANDARD);
return; return;
} }
if (!isDid(newContact.did)) { if (!isDid(newContact.did)) {
this.danger("The DID must begin with 'did:'", "Invalid DID"); this.notify.error(NOTIFY_CONTACT_INVALID_DID.message, TIMEOUTS.STANDARD);
return; return;
} }
@ -869,10 +899,9 @@ export default class ContactsView extends Vue {
if (this.activeDid) { if (this.activeDid) {
this.setVisibility(newContact, true, false); this.setVisibility(newContact, true, false);
newContact.seesMe = true; // didn't work inside setVisibility newContact.seesMe = true; // didn't work inside setVisibility
addedMessage = addedMessage = getVisibilitySuccessMessage(newContact.name || "");
"They were added, and your activity is visible to them.";
} else { } else {
addedMessage = "They were added."; addedMessage = NOTIFY_CONTACTS_ADDED.message;
} }
this.contactInput = ""; this.contactInput = "";
if (this.isRegistered) { if (this.isRegistered) {
@ -916,20 +945,22 @@ export default class ContactsView extends Vue {
}) })
.catch((err) => { .catch((err) => {
const fullError = const fullError =
"Error when adding contact to storage: " + errorStringForLog(err); NOTIFY_CONTACT_SETTING_SAVE_ERROR.message +
": " +
errorStringForLog(err);
this.$logAndConsole(fullError, true); this.$logAndConsole(fullError, true);
let message = "An error prevented this import."; let message = NOTIFY_CONTACT_IMPORT_ERROR.message;
if ( if (
err.message?.indexOf("Key already exists in the object store.") > -1 err.message?.indexOf("Key already exists in the object store.") > -1
) { ) {
message = message =
"A contact with that DID is already in your contact list. Edit them directly below."; NOTIFY_CONTACT_IMPORT_CONFLICT.message +
". Check that the contact doesn't conflict with any you already have.";
} }
if (err.name === "ConstraintError") { if (err.name === "ConstraintError") {
message += message += NOTIFY_CONTACT_IMPORT_CONSTRAINT.message;
" Check that the contact doesn't conflict with any you already have.";
} }
this.danger(message, "Contact Not Added", 5000); this.notify.error(message, TIMEOUTS.MODAL);
}); });
} }
@ -949,7 +980,9 @@ export default class ContactsView extends Vue {
await this.$updateContact(contact.did, { registered: true }); await this.$updateContact(contact.did, { registered: true });
this.notify.success( this.notify.success(
`${contact.name || "That unnamed person"} ${NOTIFY_REGISTER_PERSON_SUCCESS.message}`, getRegisterPersonSuccessMessage(
contact.name || "That unnamed person",
),
TIMEOUTS.STANDARD, TIMEOUTS.STANDARD,
); );
} else { } else {
@ -1003,7 +1036,7 @@ export default class ContactsView extends Vue {
//contact.seesMe = visibility; // why doesn't it affect the UI from here? //contact.seesMe = visibility; // why doesn't it affect the UI from here?
if (showSuccessAlert) { if (showSuccessAlert) {
this.notify.success( this.notify.success(
`${contact.name || "That user"} can ${visibility ? "" : "not "}see your activity.`, getVisibilitySuccessMessage(contact.name || ""),
TIMEOUTS.STANDARD, TIMEOUTS.STANDARD,
); );
} }
@ -1026,22 +1059,14 @@ export default class ContactsView extends Vue {
recipientDid === this.activeDid && recipientDid === this.activeDid &&
this.givenToMeUnconfirmed[giverDid] > 0 this.givenToMeUnconfirmed[giverDid] > 0
) { ) {
const isAre = this.givenToMeUnconfirmed[giverDid] == 1 ? "is" : "are"; const message = NOTIFY_UNCONFIRMED_HOURS_DYNAMIC.getMessage(
const hours = this.givenToMeUnconfirmed[giverDid] == 1 ? "hour" : "hours"; this.givenToMeUnconfirmed[giverDid],
const message = );
"There " +
isAre +
" " +
this.givenToMeUnconfirmed[giverDid] +
" unconfirmed " +
hours +
" from them." +
" Would you like to confirm some of those hours?";
this.$notify( this.$notify(
{ {
group: "modal", group: "modal",
type: "confirm", type: "confirm",
title: NOTIFY_UNCONFIRMED_HOURS.title, title: NOTIFY_UNCONFIRMED_HOURS_DYNAMIC.title,
text: message, text: message,
onNo: async () => { onNo: async () => {
this.showGiftedDialog(giverDid, recipientDid); this.showGiftedDialog(giverDid, recipientDid);
@ -1120,11 +1145,13 @@ export default class ContactsView extends Vue {
}); });
} catch (err) { } catch (err) {
const fullError = const fullError =
"Error updating contact-amounts setting: " + errorStringForLog(err); NOTIFY_CONTACT_SETTING_SAVE_ERROR.message +
": " +
errorStringForLog(err);
this.$logAndConsole(fullError, true); this.$logAndConsole(fullError, true);
this.notify.error( this.notify.error(
"The setting may not have saved. Try again, maybe after restarting the app.", NOTIFY_CONTACT_SETTING_SAVE_ERROR.message,
TIMEOUTS.LONG, TIMEOUTS.MODAL,
); );
} }
this.showGiveNumbers = newShowValue; this.showGiveNumbers = newShowValue;
@ -1167,7 +1194,10 @@ export default class ContactsView extends Vue {
private async copySelectedContacts() { private async copySelectedContacts() {
if (this.contactsSelected.length === 0) { if (this.contactsSelected.length === 0) {
this.danger("You must select contacts to copy."); this.notify.error(
NOTIFY_CONTACTS_SELECT_TO_COPY.message,
TIMEOUTS.STANDARD,
);
return; return;
} }
const selectedContactsFull = this.contacts.filter((c) => const selectedContactsFull = this.contacts.filter((c) =>
@ -1197,15 +1227,15 @@ export default class ContactsView extends Vue {
useClipboard() useClipboard()
.copy(contactsJwtUrl) .copy(contactsJwtUrl)
.then(() => { .then(() => {
this.notify.copied("contact link", TIMEOUTS.STANDARD); this.notify.success(
NOTIFY_CONTACT_LINK_COPIED.message,
TIMEOUTS.STANDARD,
);
}); });
} }
private showCopySelectionsInfo() { private showCopySelectionsInfo() {
this.notify.info( this.notify.info(NOTIFY_CONTACT_INFO_COPY.message, TIMEOUTS.LONG);
"Contact info will include name, ID, profile image, and public key.",
TIMEOUTS.LONG,
);
} }
private async showOnboardMeetingDialog() { private async showOnboardMeetingDialog() {
@ -1253,13 +1283,10 @@ export default class ContactsView extends Vue {
} }
} catch (error) { } catch (error) {
this.$logAndConsole( this.$logAndConsole(
"Error checking meeting status:" + errorStringForLog(error), NOTIFY_MEETING_STATUS_ERROR.message + ": " + errorStringForLog(error),
true, true,
); );
this.danger( this.notify.error(NOTIFY_MEETING_STATUS_ERROR.message, TIMEOUTS.MODAL);
"There was an error checking your meeting status.",
"Meeting Error",
);
} }
} }

175
src/views/OnboardMeetingSetupView.vue

@ -276,16 +276,23 @@ import { RouteLocationNormalizedLoaded, Router } from "vue-router";
import QuickNav from "../components/QuickNav.vue"; import QuickNav from "../components/QuickNav.vue";
import TopMessage from "../components/TopMessage.vue"; import TopMessage from "../components/TopMessage.vue";
import MembersList from "../components/MembersList.vue"; import MembersList from "../components/MembersList.vue";
import * as databaseUtil from "../db/databaseUtil";
import { logConsoleAndDb } from "../db/databaseUtil";
import { import {
errorStringForLog, errorStringForLog,
getHeaders, getHeaders,
serverMessageForUser, serverMessageForUser,
} from "../libs/endorserServer"; } from "../libs/endorserServer";
import { encryptMessage } from "../libs/crypto"; import { encryptMessage } from "../libs/crypto";
import { logger } from "../utils/logger";
import { APP_SERVER } from "@/constants/app"; import { APP_SERVER } from "@/constants/app";
import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin";
import { createNotifyHelpers, TIMEOUTS } from "@/utils/notify";
import {
NOTIFY_MEETING_INVALID_TIME,
NOTIFY_MEETING_NAME_REQUIRED,
NOTIFY_MEETING_PASSWORD_REQUIRED,
NOTIFY_MEETING_CREATED,
NOTIFY_MEETING_DELETED,
NOTIFY_MEETING_LINK_COPIED,
} from "@/constants/notifications";
interface ServerMeeting { interface ServerMeeting {
groupId: number; // from the server groupId: number; // from the server
name: string; // to & from the server name: string; // to & from the server
@ -309,6 +316,7 @@ interface MeetingSetupInputs {
TopMessage, TopMessage,
MembersList, MembersList,
}, },
mixins: [PlatformServiceMixin],
}) })
export default class OnboardMeetingView extends Vue { export default class OnboardMeetingView extends Vue {
$notify!: ( $notify!: (
@ -317,6 +325,7 @@ export default class OnboardMeetingView extends Vue {
) => void; ) => void;
$route!: RouteLocationNormalizedLoaded; $route!: RouteLocationNormalizedLoaded;
$router!: Router; $router!: Router;
notify!: ReturnType<typeof createNotifyHelpers>;
currentMeeting: ServerMeeting | null = null; currentMeeting: ServerMeeting | null = null;
newOrUpdatedMeetingInputs: MeetingSetupInputs | null = null; newOrUpdatedMeetingInputs: MeetingSetupInputs | null = null;
@ -334,11 +343,12 @@ export default class OnboardMeetingView extends Vue {
} }
async created() { async created() {
const settings = await databaseUtil.retrieveSettingsForActiveAccount(); this.notify = createNotifyHelpers(this.$notify as any);
this.activeDid = settings.activeDid || ""; const settings = await this.$getSettings("activeAccount");
this.apiServer = settings.apiServer || ""; this.activeDid = settings?.activeDid || "";
this.fullName = settings.firstName || ""; this.apiServer = settings?.apiServer || "";
this.isRegistered = !!settings.isRegistered; this.fullName = settings?.firstName || "";
this.isRegistered = !!settings?.isRegistered;
await this.fetchCurrentMeeting(); await this.fetchCurrentMeeting();
this.isLoading = false; this.isLoading = false;
@ -426,38 +436,20 @@ export default class OnboardMeetingView extends Vue {
const localExpiresAt = new Date(this.newOrUpdatedMeetingInputs.expiresAt); const localExpiresAt = new Date(this.newOrUpdatedMeetingInputs.expiresAt);
const now = new Date(); const now = new Date();
if (localExpiresAt <= now) { if (localExpiresAt <= now) {
this.$notify( this.notify.warning(NOTIFY_MEETING_INVALID_TIME.message, TIMEOUTS.LONG);
{
group: "alert",
type: "warning",
title: "Invalid Time",
text: "Select a future time for the meeting expiration.",
},
5000,
);
return; return;
} }
if (!this.newOrUpdatedMeetingInputs.userFullName) { if (!this.newOrUpdatedMeetingInputs.userFullName) {
this.$notify( this.notify.warning(
{ NOTIFY_MEETING_NAME_REQUIRED.message,
group: "alert", TIMEOUTS.LONG,
type: "warning",
title: "Invalid Name",
text: "Please enter your name.",
},
5000,
); );
return; return;
} }
if (!this.newOrUpdatedMeetingInputs.password) { if (!this.newOrUpdatedMeetingInputs.password) {
this.$notify( this.notify.warning(
{ NOTIFY_MEETING_PASSWORD_REQUIRED.message,
group: "alert", TIMEOUTS.LONG,
type: "warning",
title: "Invalid Password",
text: "Please enter a password.",
},
5000,
); );
return; return;
} }
@ -492,33 +484,19 @@ export default class OnboardMeetingView extends Vue {
}; };
this.newOrUpdatedMeetingInputs = null; this.newOrUpdatedMeetingInputs = null;
this.$notify( this.notify.success(NOTIFY_MEETING_CREATED.message, TIMEOUTS.STANDARD);
{
group: "alert",
type: "success",
title: "Success",
text: "Meeting created.",
},
3000,
);
} else { } else {
throw { response: response }; throw { response: response };
} }
} catch (error) { } catch (error) {
logConsoleAndDb( this.$logAndConsole(
"Error creating meeting: " + errorStringForLog(error), "Error creating meeting: " + errorStringForLog(error),
true, true,
); );
const errorMessage = serverMessageForUser(error); const errorMessage = serverMessageForUser(error);
this.$notify( this.notify.error(
{ errorMessage ||
group: "alert", "Failed to create meeting. Try reloading or submitting again.",
type: "danger",
title: "Error",
text:
errorMessage ||
"Failed to create meeting. Try reloading or submitting again.",
},
5000, 5000,
); );
} finally { } finally {
@ -560,25 +538,12 @@ export default class OnboardMeetingView extends Vue {
this.newOrUpdatedMeetingInputs = this.blankMeeting(); this.newOrUpdatedMeetingInputs = this.blankMeeting();
this.showDeleteConfirm = false; this.showDeleteConfirm = false;
this.$notify( this.notify.success(NOTIFY_MEETING_DELETED.message, TIMEOUTS.STANDARD);
{
group: "alert",
type: "success",
title: "Success",
text: "Meeting deleted successfully.",
},
3000,
);
} catch (error) { } catch (error) {
logger.error("Error deleting meeting:", error); this.$logError("Error deleting meeting: " + error);
this.$notify( this.notify.error(
{ serverMessageForUser(error) || "Failed to delete meeting.",
group: "alert", TIMEOUTS.LONG,
type: "danger",
title: "Error",
text: serverMessageForUser(error) || "Failed to delete meeting.",
},
5000,
); );
} finally { } finally {
this.isDeleting = false; this.isDeleting = false;
@ -597,7 +562,7 @@ export default class OnboardMeetingView extends Vue {
projectLink: this.currentMeeting.projectLink || "", projectLink: this.currentMeeting.projectLink || "",
}; };
} else { } else {
logger.error( this.$logError(
"There is no current meeting to edit. We should never get here.", "There is no current meeting to edit. We should never get here.",
); );
} }
@ -619,38 +584,20 @@ export default class OnboardMeetingView extends Vue {
const localExpiresAt = new Date(this.newOrUpdatedMeetingInputs.expiresAt); const localExpiresAt = new Date(this.newOrUpdatedMeetingInputs.expiresAt);
const now = new Date(); const now = new Date();
if (localExpiresAt <= now) { if (localExpiresAt <= now) {
this.$notify( this.notify.warning(NOTIFY_MEETING_INVALID_TIME.message, TIMEOUTS.LONG);
{
group: "alert",
type: "warning",
title: "Invalid Time",
text: "Select a future time for the meeting expiration.",
},
5000,
);
return; return;
} }
if (!this.newOrUpdatedMeetingInputs.userFullName) { if (!this.newOrUpdatedMeetingInputs.userFullName) {
this.$notify( this.notify.warning(
{ NOTIFY_MEETING_NAME_REQUIRED.message,
group: "alert", TIMEOUTS.LONG,
type: "warning",
title: "Invalid Name",
text: "Please enter your name.",
},
5000,
); );
return; return;
} }
if (!this.newOrUpdatedMeetingInputs.password) { if (!this.newOrUpdatedMeetingInputs.password) {
this.$notify( this.notify.warning(
{ NOTIFY_MEETING_PASSWORD_REQUIRED.message,
group: "alert", TIMEOUTS.LONG,
type: "warning",
title: "Invalid Password",
text: "Please enter a password.",
},
5000,
); );
return; return;
} }
@ -696,21 +643,15 @@ export default class OnboardMeetingView extends Vue {
throw { response: response }; throw { response: response };
} }
} catch (error) { } catch (error) {
logConsoleAndDb( this.$logAndConsole(
"Error updating meeting: " + errorStringForLog(error), "Error updating meeting: " + errorStringForLog(error),
true, true,
); );
const errorMessage = serverMessageForUser(error); const errorMessage = serverMessageForUser(error);
this.$notify( this.notify.error(
{ errorMessage ||
group: "alert", "Failed to update meeting. Try reloading or submitting again.",
type: "danger", TIMEOUTS.LONG,
title: "Error",
text:
errorMessage ||
"Failed to update meeting. Try reloading or submitting again.",
},
5000,
); );
} finally { } finally {
this.isLoading = false; this.isLoading = false;
@ -727,30 +668,14 @@ export default class OnboardMeetingView extends Vue {
} }
handleMembersError(message: string) { handleMembersError(message: string) {
this.$notify( this.notify.error(message, TIMEOUTS.LONG);
{
group: "alert",
type: "danger",
title: "Error",
text: message,
},
5000,
);
} }
copyMembersLinkToClipboard() { copyMembersLinkToClipboard() {
useClipboard() useClipboard()
.copy(this.onboardMeetingMembersLink()) .copy(this.onboardMeetingMembersLink())
.then(() => { .then(() => {
this.$notify( this.notify.info(NOTIFY_MEETING_LINK_COPIED.message, TIMEOUTS.LONG);
{
group: "alert",
type: "info",
title: "Copied",
text: "The member link is copied to the clipboard.",
},
5000,
);
}); });
} }
} }

Loading…
Cancel
Save