web/satellite: notification plugin (#3352)

This commit is contained in:
Nikolay Yurchenko 2019-10-28 19:33:06 +02:00 committed by Vitalii Shpital
parent 016be4525a
commit fef0c51c18
30 changed files with 133 additions and 97 deletions

View File

@ -72,7 +72,7 @@ import ChangePasswordIcon from '@/../static/images/account/changePasswordPopup/c
import CloseCrossIcon from '@/../static/images/common/closeCross.svg';
import { AuthApi } from '@/api/auth';
import { APP_STATE_ACTIONS, NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
import { validatePassword } from '@/utils/validation';
@Component({
@ -137,12 +137,12 @@ export default class ChangePasswordPopup extends Vue {
try {
await this.auth.changePassword(this.oldPassword, this.newPassword);
} catch (error) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, error.message);
await this.$notify.error(error.message);
return;
}
this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, 'Password successfully changed!');
await this.$notify.success('Password successfully changed!');
this.$store.dispatch(APP_STATE_ACTIONS.TOGGLE_CHANGE_PASSWORD_POPUP);
}

View File

@ -54,7 +54,7 @@ import CloseCrossIcon from '@/../static/images/common/closeCross.svg';
import { AuthApi } from '@/api/auth';
import { RouteConfig } from '@/router';
import { AuthToken } from '@/utils/authToken';
import { APP_STATE_ACTIONS, NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
import { validatePassword } from '@/utils/validation';
@Component({
@ -93,7 +93,7 @@ export default class DeleteAccountPopup extends Vue {
try {
await this.auth.delete(this.password);
await this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, 'Account was successfully deleted');
await this.$notify.success('Account was successfully deleted');
AuthToken.remove();
@ -101,7 +101,7 @@ export default class DeleteAccountPopup extends Vue {
await this.$store.dispatch(APP_STATE_ACTIONS.TOGGLE_DEL_ACCOUNT);
await this.$router.push(RouteConfig.Login.path);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, error.message);
await this.$notify.error(error.message);
this.isLoading = false;
}
}

View File

@ -63,7 +63,7 @@ import CloseCrossIcon from '@/../static/images/common/closeCross.svg';
import { USER_ACTIONS } from '@/store/modules/users';
import { UpdatedUser } from '@/types/users';
import { APP_STATE_ACTIONS, NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
@Component({
components: {
@ -97,12 +97,12 @@ export default class EditProfilePopup extends Vue {
try {
await this.$store.dispatch(USER_ACTIONS.UPDATE, this.userInfo);
} catch (error) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, error.message);
await this.$notify.error(error.message);
return;
}
this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, 'Account info successfully updated!');
await this.$notify.success('Account info successfully updated!');
this.$store.dispatch(APP_STATE_ACTIONS.TOGGLE_EDIT_PROFILE_POPUP);
}

View File

@ -15,8 +15,6 @@
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import { NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
// StripeInput encapsulates Stripe add card addition logic
@Component
export default class StripeInput extends Vue {
@ -29,9 +27,9 @@ export default class StripeInput extends Vue {
// Stripe library
private stripe: any;
public mounted(): void {
public async mounted(): Promise<void> {
if (!window['Stripe']) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, 'Stripe library not loaded');
await this.$notify.error('Stripe library not loaded');
return;
}
@ -39,7 +37,7 @@ export default class StripeInput extends Vue {
this.stripe = window['Stripe'](process.env.VUE_APP_STRIPE_PUBLIC_KEY);
if (!this.stripe) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, 'Unable to initialize stripe');
await this.$notify.error('Unable to initialize stripe');
return;
}
@ -47,7 +45,7 @@ export default class StripeInput extends Vue {
const elements = this.stripe.elements();
if (!elements) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, 'Unable to instantiate elements');
await this.$notify.error('Unable to instantiate elements');
return;
}
@ -55,7 +53,7 @@ export default class StripeInput extends Vue {
this.cardElement = elements.create('card');
if (!this.cardElement) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, 'Unable to create card');
await this.$notify.error('Unable to create card');
return;
}
@ -77,7 +75,7 @@ export default class StripeInput extends Vue {
}
if (result.token.card.funding === 'prepaid') {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, 'Prepaid cards are not supported');
await this.$notify.error('Prepaid cards are not supported');
return;
}

View File

@ -122,7 +122,7 @@ import EmptySearchResultIcon from '@/../static/images/common/emptySearchResult.s
import { ApiKey, ApiKeyOrderBy } from '@/types/apiKeys';
import { SortDirection } from '@/types/common';
import { API_KEYS_ACTIONS, NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
import { API_KEYS_ACTIONS } from '@/utils/constants/actionNames';
import { EMPTY_STATE_IMAGES } from '@/utils/constants/emptyStatesImages';
import ApiKeysCopyPopup from './ApiKeysCopyPopup.vue';
@ -218,9 +218,9 @@ export default class ApiKeysArea extends Vue {
public async onDelete(): Promise<void> {
try {
await this.$store.dispatch(DELETE);
this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, `API keys deleted successfully`);
await this.$notify.success(`API keys deleted successfully`);
} catch (error) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, error.message);
await this.$notify.error(error.message);
}
try {
@ -336,7 +336,7 @@ export default class ApiKeysArea extends Vue {
}
public async notifyFetchError(error: Error): Promise<void> {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch API keys. ${error.message}`);
await this.$notify.error(`Unable to fetch API keys. ${error.message}`);
}
}
</script>

View File

@ -54,8 +54,8 @@ export default class ApiKeysCopyPopup extends Vue {
this.$emit('closePopup');
}
public onCopyClick(): void {
this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, 'Key saved to clipboard');
public async onCopyClick(): Promise<void> {
await this.$notify.success('Key saved to clipboard');
this.isCopiedButtonShown = true;
}
}

View File

@ -34,7 +34,7 @@ import VButton from '@/components/common/VButton.vue';
import CloseCrossIcon from '@/../static/images/common/closeCross.svg';
import { ApiKey } from '@/types/apiKeys';
import { API_KEYS_ACTIONS, NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
import { API_KEYS_ACTIONS } from '@/utils/constants/actionNames';
const CREATE = API_KEYS_ACTIONS.CREATE;
@ -84,21 +84,21 @@ export default class ApiKeysCreationPopup extends Vue {
try {
createdApiKey = await this.$store.dispatch(CREATE, this.name);
} catch (error) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, error.message);
await this.$notify.error(error.message);
this.isLoading = false;
return;
}
this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, 'Successfully created new api key');
await this.$notify.success('Successfully created new api key');
this.key = createdApiKey.secret;
this.isLoading = false;
this.name = '';
try {
this.$store.dispatch(API_KEYS_ACTIONS.FETCH, this.FIRST_PAGE);
await this.$store.dispatch(API_KEYS_ACTIONS.FETCH, this.FIRST_PAGE);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch API keys. ${error.message}`);
await this.$notify.error(`Unable to fetch API keys. ${error.message}`);
}
this.$emit('closePopup');

View File

@ -11,7 +11,7 @@
/>
</div>
<div class="sort-header-container__date-item" @click="onHeaderItemClick(ApiKeyOrderBy.CREATED_AT)">
<p class="sort-header-container__date-item__title">Created</p>
<p class="sort-header-container__date-item__title creation-date">Created</p>
<VerticalArrows
:is-active="areApiKeysSortedByDate"
:direction="getSortDirection"
@ -110,7 +110,7 @@ export default class SortApiKeysHeader extends Vue {
color: #2a2a32;
}
&:nth-child(1) {
.creation-date {
margin-left: 0;
}
}

View File

@ -83,7 +83,6 @@ import NotificationIcon from '@/../static/images/buckets/notification.svg';
import { BUCKET_ACTIONS } from '@/store/modules/buckets';
import { Bucket } from '@/types/buckets';
import { NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
import { EMPTY_STATE_IMAGES } from '@/utils/constants/emptyStatesImages';
const {
@ -156,7 +155,7 @@ export default class BucketArea extends Vue {
try {
await this.$store.dispatch(FETCH, 1);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch buckets: ${error.message}`);
await this.$notify.error(`Unable to fetch buckets: ${error.message}`);
}
}
@ -164,7 +163,7 @@ export default class BucketArea extends Vue {
try {
await this.$store.dispatch(FETCH, page);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch buckets: ${error.message}`);
await this.$notify.error(`Unable to fetch buckets: ${error.message}`);
}
}
}

View File

@ -14,7 +14,7 @@ import RegistrationSuccessIcon from '@/../static/images/register/registerSuccess
import { AuthApi } from '@/api/auth';
import { RouteConfig } from '@/router';
import { getUserId } from '@/utils/consoleLocalStorage';
import { APP_STATE_ACTIONS, NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
@Component({
components: {
@ -47,7 +47,7 @@ export default class RegistrationSuccessPopup extends Vue {
try {
await this.auth.resendEmail(userId);
} catch (error) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, 'could not send email ');
await this.$notify.error('Could not send email ');
}
this.startResendEmailCountdown();

View File

@ -29,7 +29,7 @@ import HideIcon from '@/../static/images/common/BlueHide.svg';
import { PROJECTS_ACTIONS } from '@/store/modules/projects';
import { Project } from '@/types/projects';
import { APP_STATE_ACTIONS, NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
import ProjectSelectionDropdown from './ProjectSelectionDropdown.vue';
@ -45,7 +45,7 @@ export default class ProjectSelectionArea extends Vue {
try {
await this.$store.dispatch(PROJECTS_ACTIONS.FETCH);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, error.message);
await this.$notify.error(error.message);
}
await this.$store.dispatch(APP_STATE_ACTIONS.TOGGLE_PROJECTS);

View File

@ -29,7 +29,6 @@ import { Project } from '@/types/projects';
import {
API_KEYS_ACTIONS,
APP_STATE_ACTIONS,
NOTIFICATION_ACTIONS,
PM_ACTIONS,
} from '@/utils/constants/actionNames';
@ -49,25 +48,25 @@ export default class ProjectSelectionDropdown extends Vue {
try {
await this.$store.dispatch(PROJECT_USAGE_ACTIONS.FETCH_CURRENT_ROLLUP);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch project usage. ${error.message}`);
await this.$notify.error(`Unable to fetch project usage. ${error.message}`);
}
try {
await this.$store.dispatch(PM_ACTIONS.FETCH, this.FIRST_PAGE);
} catch (error) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch project members. ${error.message}`);
await this.$notify.error(`Unable to fetch project members. ${error.message}`);
}
try {
await this.$store.dispatch(API_KEYS_ACTIONS.FETCH, this.FIRST_PAGE);
} catch (error) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch api keys. ${error.message}`);
await this.$notify.error(`Unable to fetch api keys. ${error.message}`);
}
try {
await this.$store.dispatch(BUCKET_ACTIONS.FETCH, this.FIRST_PAGE);
} catch (error) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, 'Unable to fetch buckets: ' + error.message);
await this.$notify.error('Unable to fetch buckets: ' + error.message);
}
}

View File

@ -64,7 +64,6 @@ import { PROJECT_USAGE_ACTIONS } from '@/store/modules/usage';
import {
API_KEYS_ACTIONS,
APP_STATE_ACTIONS,
NOTIFICATION_ACTIONS,
PM_ACTIONS,
} from '@/utils/constants/actionNames';
@ -99,11 +98,11 @@ export default class DeleteProjectPopup extends Vue {
try {
await this.$store.dispatch(PROJECTS_ACTIONS.DELETE, this.$store.getters.selectedProject.id);
this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, 'Project was successfully deleted');
await this.$notify.success('Project was successfully deleted');
await this.selectProject();
} catch (e) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, e.message);
await this.$notify.error(e.message);
}
this.isLoading = false;

View File

@ -68,7 +68,6 @@ import { CreateProjectModel, Project } from '@/types/projects';
import {
API_KEYS_ACTIONS,
APP_STATE_ACTIONS,
NOTIFICATION_ACTIONS,
PM_ACTIONS,
} from '@/utils/constants/actionNames';
@ -118,7 +117,7 @@ export default class NewProjectPopup extends Vue {
this.createdProjectId = project.id;
} catch (e) {
this.isLoading = false;
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, e.message);
await this.$notify.error(e.message);
this.$store.dispatch(APP_STATE_ACTIONS.TOGGLE_NEW_PROJ);
return;
@ -129,7 +128,7 @@ export default class NewProjectPopup extends Vue {
try {
await this.fetchProjectMembers();
} catch (e) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, e.message);
await this.$notify.error(e.message);
}
this.clearApiKeys();
@ -204,8 +203,8 @@ export default class NewProjectPopup extends Vue {
this.$store.dispatch(BUCKET_ACTIONS.CLEAR);
}
private notifySuccess(message: string): void {
this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, message);
private async notifySuccess(message: string): Promise<void> {
await this.$notify.success(message);
}
}
</script>

View File

@ -66,7 +66,7 @@ import EditIcon from '@/../static/images/project/edit.svg';
import { RouteConfig } from '@/router';
import { PROJECTS_ACTIONS } from '@/store/modules/projects';
import { UpdateProjectModel } from '@/types/projects';
import { APP_STATE_ACTIONS, NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
@Component({
components: {
@ -85,7 +85,7 @@ export default class ProjectDetailsArea extends Vue {
try {
await this.$store.dispatch(PROJECTS_ACTIONS.FETCH);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, error.message);
await this.$notify.error(error.message);
}
}
@ -118,13 +118,13 @@ export default class ProjectDetailsArea extends Vue {
new UpdateProjectModel(this.$store.getters.selectedProject.id, this.newDescription),
);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to update project description. ${error.message}`);
await this.$notify.error(`Unable to update project description. ${error.message}`);
return;
}
this.toggleEditing();
await this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, 'Project updated successfully!');
await this.$notify.success('Project updated successfully!');
}
public toggleDeleteDialog(): void {
@ -261,6 +261,7 @@ export default class ProjectDetailsArea extends Vue {
.project-details-svg {
cursor: pointer;
min-width: 40px;
&:hover {

View File

@ -66,7 +66,6 @@ import DownloadReportIcon from '@/../static/images/project/downloadReport.svg';
import { RouteConfig } from '@/router';
import { PROJECT_USAGE_ACTIONS } from '@/store/modules/usage';
import { DateRange } from '@/types/usage';
import { NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
import { toUnixTimestamp } from '@/utils/time';
@Component({
@ -120,7 +119,7 @@ export default class UsageReport extends Vue {
try {
await this.$store.dispatch(PROJECT_USAGE_ACTIONS.FETCH_CURRENT_ROLLUP);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch project usage. ${error.message}`);
await this.$notify.error(`Unable to fetch project usage. ${error.message}`);
}
}
@ -128,7 +127,7 @@ export default class UsageReport extends Vue {
try {
await this.$store.dispatch(PROJECT_USAGE_ACTIONS.FETCH_CURRENT_ROLLUP, this.dateRange);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, error.message);
await this.$notify.error(error.message);
}
const buttons = [...(document as any).querySelectorAll('.usage-report-container__options-area__option')];
@ -150,7 +149,7 @@ export default class UsageReport extends Vue {
try {
await this.$store.dispatch(PROJECT_USAGE_ACTIONS.FETCH_CURRENT_ROLLUP);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch project usage. ${error.message}`);
await this.$notify.error(`Unable to fetch project usage. ${error.message}`);
}
}
@ -160,7 +159,7 @@ export default class UsageReport extends Vue {
try {
await this.$store.dispatch(PROJECT_USAGE_ACTIONS.FETCH_PREVIOUS_ROLLUP);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch project usage. ${error.message}`);
await this.$notify.error(`Unable to fetch project usage. ${error.message}`);
}
}
@ -206,7 +205,7 @@ export default class UsageReport extends Vue {
try {
await this.$store.dispatch(PROJECT_USAGE_ACTIONS.FETCH, dateRange);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch project usage. ${error.message}`);
await this.$notify.error(`Unable to fetch project usage. ${error.message}`);
}
}

View File

@ -25,7 +25,6 @@ import { Component, Vue } from 'vue-property-decorator';
import { CREDIT_USAGE_ACTIONS } from '@/store/modules/credits';
import { CreditUsage } from '@/types/credits';
import { NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
class CreditDescription {
public title: string;
@ -61,7 +60,7 @@ export default class ReferralStats extends Vue {
try {
await this.$store.dispatch(CREDIT_USAGE_ACTIONS.FETCH);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, 'Unable to fetch credit usage: ' + error.message);
await this.$notify.error('Unable to fetch credit usage: ' + error.message);
}
}

View File

@ -85,7 +85,7 @@ import DeleteFieldIcon from '@/../static/images/team/deleteField.svg';
import { RouteConfig } from '@/router';
import { EmailInput } from '@/types/EmailInput';
import { APP_STATE_ACTIONS, NOTIFICATION_ACTIONS, PM_ACTIONS } from '@/utils/constants/actionNames';
import { APP_STATE_ACTIONS, PM_ACTIONS } from '@/utils/constants/actionNames';
import { validateEmail } from '@/utils/validation';
@Component({
@ -158,7 +158,7 @@ export default class AddUserPopup extends Vue {
}
if (emailArray.includes(this.$store.state.usersModule.email)) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Error during adding project members. You can't add yourself to the project`);
await this.$notify.error(`Error during adding project members. You can't add yourself to the project`);
this.isLoading = false;
return;
@ -167,19 +167,19 @@ export default class AddUserPopup extends Vue {
try {
await this.$store.dispatch(PM_ACTIONS.ADD, emailArray);
} catch (error) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Error during adding project members. ${error.message}`);
await this.$notify.error(`Error during adding project members. ${error.message}`);
this.isLoading = false;
return;
}
this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, 'Members successfully added to project!');
await this.$notify.success('Members successfully added to project!');
this.$store.dispatch(PM_ACTIONS.SET_SEARCH_QUERY, '');
try {
await this.$store.dispatch(PM_ACTIONS.FETCH, this.FIRST_PAGE);
} catch (error) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch project members. ${error.message}`);
await this.$notify.error(`Unable to fetch project members. ${error.message}`);
}
this.$store.dispatch(APP_STATE_ACTIONS.TOGGLE_TEAM_MEMBERS);

View File

@ -73,7 +73,7 @@ import VHeader from '@/components/common/VHeader.vue';
import AddUserPopup from '@/components/team/AddUserPopup.vue';
import { ProjectMemberHeaderState } from '@/types/projectMembers';
import { APP_STATE_ACTIONS, NOTIFICATION_ACTIONS, PM_ACTIONS } from '@/utils/constants/actionNames';
import { APP_STATE_ACTIONS, PM_ACTIONS } from '@/utils/constants/actionNames';
declare interface ClearSearch {
clearSearch(): void;
@ -128,24 +128,24 @@ export default class HeaderArea extends Vue {
try {
await this.$store.dispatch(PM_ACTIONS.DELETE);
} catch (error) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Error while deleting users from projectMembers. ${error.message}`);
await this.$notify.error(`Error while deleting users from projectMembers. ${error.message}`);
return;
}
this.$emit('onSuccessAction');
this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, 'Members was successfully removed from project');
await this.$notify.success('Members was successfully removed from project');
this.isDeleteClicked = false;
this.$refs.headerComponent.clearSearch();
}
public async processSearchQuery(search: string): Promise<void> {
this.$store.dispatch(PM_ACTIONS.SET_SEARCH_QUERY, search);
await this.$store.dispatch(PM_ACTIONS.SET_SEARCH_QUERY, search);
try {
await this.$store.dispatch(PM_ACTIONS.FETCH, this.FIRST_PAGE);
} catch (error) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch project members. ${error.message}`);
await this.$notify.error(`Unable to fetch project members. ${error.message}`);
}
}

View File

@ -47,7 +47,7 @@ import EmptySearchResultIcon from '@/../static/images/common/emptySearchResult.s
import { SortDirection } from '@/types/common';
import { ProjectMember, ProjectMemberHeaderState, ProjectMemberOrderBy } from '@/types/projectMembers';
import { NOTIFICATION_ACTIONS, PM_ACTIONS } from '@/utils/constants/actionNames';
import { PM_ACTIONS } from '@/utils/constants/actionNames';
const {
FETCH,
@ -138,7 +138,7 @@ export default class ProjectMembersArea extends Vue {
try {
await this.$store.dispatch(FETCH, index);
} catch (error) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch project members. ${error.message}`);
this.$notify.error(`Unable to fetch project members. ${error.message}`);
}
}
@ -148,7 +148,7 @@ export default class ProjectMembersArea extends Vue {
try {
await this.$store.dispatch(FETCH, this.FIRST_PAGE);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch project members. ${error.message}`);
await this.$notify.error(`Unable to fetch project members. ${error.message}`);
}
this.resetPaginator();

View File

@ -4,6 +4,8 @@
import Vue, { VNode } from 'vue';
import { DirectiveBinding } from 'vue/types/options';
import { NotificatorPlugin } from '@/utils/plugins/notificator';
import App from './App.vue';
import { router } from './router';
import { store } from './store';
@ -12,6 +14,10 @@ Vue.config.devtools = true;
Vue.config.performance = true;
Vue.config.productionTip = false;
const notificator = new NotificatorPlugin();
Vue.use(notificator);
let clickOutsideEvent: EventListener;
Vue.directive('click-outside', {

View File

@ -3,8 +3,11 @@
import Vue from 'vue';
import { Notificator } from '@/utils/plugins/notificator';
declare module 'vue/types/vue' {
interface Vue {
$segment: any; // define real typings here if you want
$notify: Notificator;
}
}

View File

@ -0,0 +1,31 @@
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
import { store } from '@/store';
import { NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
export class Notificator {
public constructor(private store) {}
public async success(message: string) {
await this.store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, message);
}
public async error(message: string) {
await this.store.dispatch(NOTIFICATION_ACTIONS.ERROR, message);
}
public async notify(message: string) {
await this.store.dispatch(NOTIFICATION_ACTIONS.NOTIFY, message);
}
public async warning(message: string) {
await this.store.dispatch(NOTIFICATION_ACTIONS.WARNING, message);
}
}
export class NotificatorPlugin {
public install(Vue) {
Vue.prototype.$notify = new Notificator(store);
}
}

View File

@ -36,9 +36,7 @@ import { AuthToken } from '@/utils/authToken';
import {
API_KEYS_ACTIONS,
APP_STATE_ACTIONS,
NOTIFICATION_ACTIONS,
PM_ACTIONS,
PROJECT_PAYMENT_METHODS_ACTIONS,
} from '@/utils/constants/actionNames';
import { AppState } from '@/utils/constants/appStateEnum';
@ -61,7 +59,7 @@ export default class DashboardArea extends Vue {
await this.$store.dispatch(USER_ACTIONS.GET);
} catch (error) {
await this.$store.dispatch(APP_STATE_ACTIONS.CHANGE_STATE, AppState.ERROR);
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, error.message);
await this.$notify.error(error.message);
AuthToken.remove();
await this.$router.push(RouteConfig.Login.path);
@ -80,7 +78,7 @@ export default class DashboardArea extends Vue {
// return;
// }
//
// await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, error.message);
// await this.$notify.error(error.message);
// }
let projects: Project[] = [];
@ -88,7 +86,7 @@ export default class DashboardArea extends Vue {
try {
projects = await this.$store.dispatch(PROJECTS_ACTIONS.FETCH);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, error.message);
await this.$notify.error(error.message);
return;
}
@ -113,25 +111,25 @@ export default class DashboardArea extends Vue {
try {
await this.$store.dispatch(PM_ACTIONS.FETCH, 1);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch project members. ${error.message}`);
await this.$notify.error(`Unable to fetch project members. ${error.message}`);
}
try {
await this.$store.dispatch(API_KEYS_ACTIONS.FETCH, 1);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch api keys. ${error.message}`);
await this.$notify.error(`Unable to fetch api keys. ${error.message}`);
}
try {
await this.$store.dispatch(PROJECT_USAGE_ACTIONS.FETCH_CURRENT_ROLLUP);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch project usage. ${error.message}`);
await this.$notify.error(`Unable to fetch project usage. ${error.message}`);
}
try {
await this.$store.dispatch(BUCKET_ACTIONS.FETCH, 1);
} catch (error) {
await this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Unable to fetch buckets. ${error.message}`);
await this.$notify.error(`Unable to fetch buckets. ${error.message}`);
}
await this.$store.dispatch(APP_STATE_ACTIONS.CHANGE_STATE, AppState.LOADED);

View File

@ -13,7 +13,6 @@ import LogoIcon from '@/../static/images/Logo.svg';
import { AuthApi } from '@/api/auth';
import { RouteConfig } from '@/router';
import { NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
import { LOADING_CLASSES } from '@/utils/constants/classConstants';
import { validateEmail } from '@/utils/validation';
@ -45,9 +44,9 @@ export default class ForgotPassword extends Vue {
try {
await this.auth.forgotPassword(this.email);
this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, 'Please look for instructions at your email');
await this.$notify.success('Please look for instructions at your email');
} catch (error) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, error.message);
await this.$notify.error(error.message);
}
}

View File

@ -15,7 +15,7 @@ import LoadingLogoIcon from '@/../static/images/LogoWhite.svg';
import { AuthApi } from '@/api/auth';
import { RouteConfig } from '@/router';
import { AuthToken } from '@/utils/authToken';
import { APP_STATE_ACTIONS, NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
import { AppState } from '@/utils/constants/appStateEnum';
import { LOADING_CLASSES } from '@/utils/constants/classConstants';
import { validateEmail, validatePassword } from '@/utils/validation';
@ -78,7 +78,7 @@ export default class Login extends Vue {
try {
this.authToken = await this.auth.token(this.email, this.password);
} catch (error) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, error.message);
await this.$notify.error(error.message);
this.isLoading = false;
return;

View File

@ -18,7 +18,7 @@ import { AuthApi } from '@/api/auth';
import { RouteConfig } from '@/router';
import { User } from '@/types/users';
import { setUserId } from '@/utils/consoleLocalStorage';
import { APP_STATE_ACTIONS, NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
import { LOADING_CLASSES } from '@/utils/constants/classConstants';
import { validateEmail, validatePassword } from '@/utils/validation';
@ -55,7 +55,7 @@ export default class RegisterArea extends Vue {
private readonly auth: AuthApi = new AuthApi();
mounted(): void {
async mounted(): Promise<void> {
if (this.$route.query.token) {
this.secret = this.$route.query.token.toString();
}
@ -65,7 +65,7 @@ export default class RegisterArea extends Vue {
try {
decoded = atob(ids);
} catch (error) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, 'Invalid Referral URL');
await this.$notify.error('Invalid Referral URL');
this.loadingClassName = LOADING_CLASSES.LOADING_OVERLAY;
return;
@ -169,7 +169,7 @@ export default class RegisterArea extends Vue {
(registrationSuccessPopupRef as any).startResendEmailCountdown();
}
} catch (error) {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, error.message);
await this.$notify.error(error.message);
this.loadingClassName = LOADING_CLASSES.LOADING_OVERLAY;
this.isLoading = false;
}

View File

@ -8,10 +8,13 @@ import ApiKeysCopyPopup from '@/components/apiKeys/ApiKeysCopyPopup.vue';
import { ApiKeysApiGql } from '@/api/apiKeys';
import { makeApiKeysModule } from '@/store/modules/apiKeys';
import { makeNotificationsModule } from '@/store/modules/notifications';
import { NotificatorPlugin } from '@/utils/plugins/notificator';
import { createLocalVue, mount } from '@vue/test-utils';
const localVue = createLocalVue();
localVue.use(Vuex);
const notificationPlugin = new NotificatorPlugin();
localVue.use(notificationPlugin);
const apiKeysApi = new ApiKeysApiGql();
const apiKeysModule = makeApiKeysModule(apiKeysApi);
const notificationsModule = makeNotificationsModule();
@ -40,13 +43,13 @@ describe('ApiKeysCopyPopup', () => {
expect(wrapper.emitted()).toEqual({'closePopup': [[]]});
});
it('function onCopyClick works correctly', () => {
it('function onCopyClick works correctly', async () => {
const wrapper = mount(ApiKeysCopyPopup, {
store,
localVue,
});
wrapper.vm.onCopyClick();
await wrapper.vm.onCopyClick();
expect(wrapper.vm.$data.isCopiedButtonShown).toBe(true);
});

View File

@ -13,10 +13,13 @@ import { makeProjectsModule } from '@/store/modules/projects';
import { ApiKey } from '@/types/apiKeys';
import { Project } from '@/types/projects';
import { API_KEYS_ACTIONS } from '@/utils/constants/actionNames';
import { NotificatorPlugin } from '@/utils/plugins/notificator';
import { createLocalVue, mount } from '@vue/test-utils';
const localVue = createLocalVue();
localVue.use(Vuex);
const notificationPlugin = new NotificatorPlugin();
localVue.use(notificationPlugin);
const apiKeysApi = new ApiKeysApiGql();
const apiKeysModule = makeApiKeysModule(apiKeysApi);
const projectsApi = new ProjectsApiGql();
@ -95,7 +98,7 @@ describe('ApiKeysCreationPopup', () => {
wrapper.vm.$data.isLoading = false;
wrapper.vm.$data.name = 'testName';
wrapper.vm.onNextClick();
await wrapper.vm.onNextClick();
const result = await store.dispatch(CREATE, 'testName');

View File

@ -11,7 +11,7 @@ exports[`SortingHeader.vue should render correctly 1`] = `
</svg></div>
</div>
<div class="sort-header-container__date-item">
<p class="sort-header-container__date-item__title">Created</p>
<p class="sort-header-container__date-item__title creation-date">Created</p>
<div class="container"><svg width="9" height="6" viewBox="0 0 9 6" fill="none" xmlns="http://www.w3.org/2000/svg" class="">
<path d="M4.73684 5.70565e-07L9 6L-9.53674e-07 6L4.73684 5.70565e-07Z" fill="#354049" class="arrow-svg-path"></path>
</svg> <svg width="9" height="6" viewBox="0 0 9 6" fill="none" xmlns="http://www.w3.org/2000/svg" class="">