web/satellite: use modal instead of old create project view

Use newer modal instead of old create project view.
Also, created new composable to handle create project click.

Issue:
https://github.com/storj/storj/issues/6318

Change-Id: I50fce95924c5511c4a31e8f6e7ad271d3ff7081c
This commit is contained in:
Vitalii 2023-09-28 14:44:41 +03:00 committed by Storj Robot
parent 9d7ef17a26
commit 5295afb2da
15 changed files with 82 additions and 452 deletions

View File

@ -185,7 +185,6 @@ import {
Wallet, Wallet,
NativePaymentHistoryItem, NativePaymentHistoryItem,
} from '@/types/payments'; } from '@/types/payments';
import { RouteConfig } from '@/types/router';
import { AnalyticsErrorEventSource, AnalyticsEvent } from '@/utils/constants/analyticsEventNames'; import { AnalyticsErrorEventSource, AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
import { useNotify } from '@/utils/hooks'; import { useNotify } from '@/utils/hooks';
import { useUsersStore } from '@/store/modules/usersStore'; import { useUsersStore } from '@/store/modules/usersStore';
@ -196,6 +195,7 @@ import { useConfigStore } from '@/store/modules/configStore';
import { MODALS } from '@/utils/constants/appStatePopUps'; import { MODALS } from '@/utils/constants/appStatePopUps';
import { DEFAULT_PAGE_LIMIT } from '@/types/pagination'; import { DEFAULT_PAGE_LIMIT } from '@/types/pagination';
import { useAnalyticsStore } from '@/store/modules/analyticsStore'; import { useAnalyticsStore } from '@/store/modules/analyticsStore';
import { useCreateProjectClickHandler } from '@/composables/useCreateProjectClickHandler';
import VButton from '@/components/common/VButton.vue'; import VButton from '@/components/common/VButton.vue';
import VLoader from '@/components/common/VLoader.vue'; import VLoader from '@/components/common/VLoader.vue';
@ -233,12 +233,12 @@ const billingStore = useBillingStore();
const usersStore = useUsersStore(); const usersStore = useUsersStore();
const appStore = useAppStore(); const appStore = useAppStore();
const projectsStore = useProjectsStore(); const projectsStore = useProjectsStore();
const { handleCreateProjectClick } = useCreateProjectClickHandler();
const notify = useNotify(); const notify = useNotify();
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const emit = defineEmits(['toggleIsLoading', 'toggleIsLoaded', 'cancel']);
const showTransactions = ref<boolean>(false); const showTransactions = ref<boolean>(false);
const nativePayIsLoading = ref<boolean>(false); const nativePayIsLoading = ref<boolean>(false);
const deleteHover = ref<boolean>(false); const deleteHover = ref<boolean>(false);
@ -379,16 +379,12 @@ function closeAddPayment(): void {
} }
async function addCard(token: string): Promise<void> { async function addCard(token: string): Promise<void> {
emit('toggleIsLoading');
try { try {
await billingStore.addCreditCard(token); await billingStore.addCreditCard(token);
// We fetch User one more time to update their Paid Tier status. // We fetch User one more time to update their Paid Tier status.
await usersStore.getUser(); await usersStore.getUser();
} catch (error) { } catch (error) {
notify.notifyError(error, AnalyticsErrorEventSource.BILLING_PAYMENT_METHODS_TAB); notify.notifyError(error, AnalyticsErrorEventSource.BILLING_PAYMENT_METHODS_TAB);
emit('toggleIsLoading');
return; return;
} }
@ -397,22 +393,11 @@ async function addCard(token: string): Promise<void> {
await billingStore.getCreditCards(); await billingStore.getCreditCards();
} catch (error) { } catch (error) {
notify.notifyError(error, AnalyticsErrorEventSource.BILLING_PAYMENT_METHODS_TAB); notify.notifyError(error, AnalyticsErrorEventSource.BILLING_PAYMENT_METHODS_TAB);
emit('toggleIsLoading');
} }
emit('toggleIsLoading'); if (!userHasOwnProject.value) {
emit('toggleIsLoaded'); handleCreateProjectClick();
}
setTimeout(() => {
emit('cancel');
emit('toggleIsLoaded');
setTimeout(() => {
if (!userHasOwnProject.value) {
router.push(RouteConfig.CreateProject.path);
}
}, 500);
}, 2000);
} }
async function onConfirmAddStripe(): Promise<void> { async function onConfirmAddStripe(): Promise<void> {

View File

@ -9,7 +9,7 @@
<ProjectIcon /> <ProjectIcon />
<h1 class="modal__header__title">Get more projects</h1> <h1 class="modal__header__title">Get more projects</h1>
</div> </div>
<p v-if="!user.paidTier" class="modal__info"> <p v-if="!isPaidTier" class="modal__info">
Upgrade to Pro Account to create more projects and gain access to higher limits. Upgrade to Pro Account to create more projects and gain access to higher limits.
</p> </p>
<p v-else class="modal__info"> <p v-else class="modal__info">
@ -26,7 +26,7 @@
is-white is-white
/> />
<VButton <VButton
:label="buttonLabel()" :label="buttonLabel"
:on-press="onClick" :on-press="onClick"
width="100%" width="100%"
height="48px" height="48px"
@ -40,6 +40,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue';
import { MODALS } from '@/utils/constants/appStatePopUps'; import { MODALS } from '@/utils/constants/appStatePopUps';
import { useAppStore } from '@/store/modules/appStore'; import { useAppStore } from '@/store/modules/appStore';
import { useUsersStore } from '@/store/modules/usersStore'; import { useUsersStore } from '@/store/modules/usersStore';
@ -51,20 +53,15 @@ import ProjectIcon from '@/../static/images/common/blueBox.svg';
const appStore = useAppStore(); const appStore = useAppStore();
const userStore = useUsersStore(); const userStore = useUsersStore();
const user = userStore.state.user;
const isPaidTier = computed<boolean>(() => userStore.state.user.paidTier);
/** /**
* Button text logic depending on if the user is in the free or paid tier. * Returns button text label depending on if the user is in the free or paid tier.
*/ */
function buttonLabel(): string { const buttonLabel = computed<string>(() => {
let label = 'Upgrade -->'; return isPaidTier.value ? 'Request -->' : 'Upgrade -->';
});
if (user.paidTier) {
label = 'Request -->';
}
return label;
}
/** /**
* Holds on button click logic. * Holds on button click logic.
@ -72,7 +69,7 @@ function buttonLabel(): string {
* Redirects to upgrade modal or opens new tab to request increase project limits . * Redirects to upgrade modal or opens new tab to request increase project limits .
*/ */
function onClick(): void { function onClick(): void {
if (!user.paidTier) { if (!isPaidTier.value) {
appStore.updateActiveModal(MODALS.upgradeAccount); appStore.updateActiveModal(MODALS.upgradeAccount);
} else { } else {
appStore.removeActiveModal(); appStore.removeActiveModal();

View File

@ -228,6 +228,7 @@ import { useNotificationsStore } from '@/store/modules/notificationsStore';
import { useObjectBrowserStore } from '@/store/modules/objectBrowserStore'; import { useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
import { useConfigStore } from '@/store/modules/configStore'; import { useConfigStore } from '@/store/modules/configStore';
import { useAnalyticsStore } from '@/store/modules/analyticsStore'; import { useAnalyticsStore } from '@/store/modules/analyticsStore';
import { useCreateProjectClickHandler } from '@/composables/useCreateProjectClickHandler';
import ResourcesLinks from '@/components/navigation/ResourcesLinks.vue'; import ResourcesLinks from '@/components/navigation/ResourcesLinks.vue';
import QuickStartLinks from '@/components/navigation/QuickStartLinks.vue'; import QuickStartLinks from '@/components/navigation/QuickStartLinks.vue';
@ -282,6 +283,7 @@ const obStore = useObjectBrowserStore();
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const notify = useNotify(); const notify = useNotify();
const { handleCreateProjectClick } = useCreateProjectClickHandler();
const auth: AuthHttpApi = new AuthHttpApi(); const auth: AuthHttpApi = new AuthHttpApi();
@ -514,20 +516,7 @@ function onProjectsLinkClick(): void {
* Route to create project page. * Route to create project page.
*/ */
function onCreateLinkClick(): void { function onCreateLinkClick(): void {
if (route.name !== RouteConfig.CreateProject.name) { handleCreateProjectClick();
analyticsStore.eventTriggered(AnalyticsEvent.CREATE_NEW_CLICKED);
const user: User = usersStore.state.user;
const ownProjectsCount: number = projectsStore.projectsCount(user.id);
if (!user.paidTier || user.projectLimit === ownProjectsCount) {
appStore.updateActiveModal(MODALS.createProjectPrompt);
} else {
analyticsStore.pageVisit(RouteConfig.CreateProject.path);
appStore.updateActiveModal(MODALS.newCreateProject);
}
}
isProjectDropdownShown.value = false; isProjectDropdownShown.value = false;
} }

View File

@ -110,7 +110,6 @@ import { RouteConfig } from '@/types/router';
import { AnalyticsErrorEventSource, AnalyticsEvent } from '@/utils/constants/analyticsEventNames'; import { AnalyticsErrorEventSource, AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
import { LocalData } from '@/utils/localData'; import { LocalData } from '@/utils/localData';
import { Project } from '@/types/projects'; import { Project } from '@/types/projects';
import { User } from '@/types/users';
import { APP_STATE_DROPDOWNS, MODALS } from '@/utils/constants/appStatePopUps'; import { APP_STATE_DROPDOWNS, MODALS } from '@/utils/constants/appStatePopUps';
import { useNotify } from '@/utils/hooks'; import { useNotify } from '@/utils/hooks';
import { useUsersStore } from '@/store/modules/usersStore'; import { useUsersStore } from '@/store/modules/usersStore';
@ -122,6 +121,7 @@ import { useBucketsStore } from '@/store/modules/bucketsStore';
import { useProjectsStore } from '@/store/modules/projectsStore'; import { useProjectsStore } from '@/store/modules/projectsStore';
import { useConfigStore } from '@/store/modules/configStore'; import { useConfigStore } from '@/store/modules/configStore';
import { useAnalyticsStore } from '@/store/modules/analyticsStore'; import { useAnalyticsStore } from '@/store/modules/analyticsStore';
import { useCreateProjectClickHandler } from '@/composables/useCreateProjectClickHandler';
import VLoader from '@/components/common/VLoader.vue'; import VLoader from '@/components/common/VLoader.vue';
@ -142,9 +142,11 @@ const billingStore = useBillingStore();
const userStore = useUsersStore(); const userStore = useUsersStore();
const projectsStore = useProjectsStore(); const projectsStore = useProjectsStore();
const configStore = useConfigStore(); const configStore = useConfigStore();
const notify = useNotify(); const notify = useNotify();
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const { handleCreateProjectClick } = useCreateProjectClickHandler();
const FIRST_PAGE = 1; const FIRST_PAGE = 1;
@ -377,20 +379,7 @@ function onManagePassphraseClick(): void {
* Route to create project page. * Route to create project page.
*/ */
function onCreateLinkClick(): void { function onCreateLinkClick(): void {
if (route.name !== RouteConfig.CreateProject.name) { handleCreateProjectClick();
analyticsStore.eventTriggered(AnalyticsEvent.CREATE_NEW_CLICKED);
const user: User = userStore.state.user;
const ownProjectsCount: number = projectsStore.projectsCount(user.id);
if (user.projectLimit > ownProjectsCount) {
analyticsStore.pageVisit(RouteConfig.CreateProject.path);
appStore.updateActiveModal(MODALS.newCreateProject);
} else {
appStore.updateActiveModal(MODALS.createProjectPrompt);
}
}
closeDropdown(); closeDropdown();
} }
</script> </script>

View File

@ -46,13 +46,10 @@ import { useRoute, useRouter } from 'vue-router';
import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames'; import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
import { RouteConfig } from '@/types/router'; import { RouteConfig } from '@/types/router';
import { User } from '@/types/users';
import { AccessType } from '@/types/createAccessGrant'; import { AccessType } from '@/types/createAccessGrant';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { useUsersStore } from '@/store/modules/usersStore';
import { useAppStore } from '@/store/modules/appStore'; import { useAppStore } from '@/store/modules/appStore';
import { useProjectsStore } from '@/store/modules/projectsStore';
import { useAnalyticsStore } from '@/store/modules/analyticsStore'; import { useAnalyticsStore } from '@/store/modules/analyticsStore';
import { useCreateProjectClickHandler } from '@/composables/useCreateProjectClickHandler';
import NewProjectIcon from '@/../static/images/navigation/newProject.svg'; import NewProjectIcon from '@/../static/images/navigation/newProject.svg';
import CreateAGIcon from '@/../static/images/navigation/createAccessGrant.svg'; import CreateAGIcon from '@/../static/images/navigation/createAccessGrant.svg';
@ -62,11 +59,11 @@ import UploadInWebIcon from '@/../static/images/navigation/uploadInWeb.svg';
const analyticsStore = useAnalyticsStore(); const analyticsStore = useAnalyticsStore();
const appStore = useAppStore(); const appStore = useAppStore();
const usersStore = useUsersStore();
const projectsStore = useProjectsStore();
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const { handleCreateProjectClick } = useCreateProjectClickHandler();
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
closeDropdowns?: () => void; closeDropdowns?: () => void;
}>(), { }>(), {
@ -126,20 +123,7 @@ function navigateToCLIFlow(): void {
* Redirects to create access grant screen. * Redirects to create access grant screen.
*/ */
function navigateToNewProject(): void { function navigateToNewProject(): void {
if (route.name !== RouteConfig.CreateProject.name) { handleCreateProjectClick();
analyticsStore.eventTriggered(AnalyticsEvent.NEW_PROJECT_CLICKED);
const user: User = usersStore.state.user;
const ownProjectsCount: number = projectsStore.projectsCount(user.id);
if (!user.paidTier || user.projectLimit === ownProjectsCount) {
appStore.updateActiveModal(MODALS.createProjectPrompt);
} else {
analyticsStore.pageVisit(RouteConfig.CreateProject.path);
appStore.updateActiveModal(MODALS.newCreateProject);
}
}
props.closeDropdowns(); props.closeDropdowns();
} }
</script> </script>

View File

@ -1,238 +0,0 @@
// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
<template>
<div class="create-project">
<div class="create-project__container">
<div class="create-project__container__image-container">
<img
class="create-project__container__image-container__img"
src="@/../static/images/project/createProject.png"
alt="create project"
>
</div>
<h2 class="create-project__container__title" aria-roledescription="title">Create a Project</h2>
<VInput
label="Project Name"
additional-label="Up To 20 Characters"
placeholder="Enter Project Name"
class="full-input"
is-limit-shown
:current-limit="projectName.length"
:max-symbols="20"
:error="nameError"
@setData="setProjectName"
/>
<VInput
label="Description"
placeholder="Enter Project Description"
additional-label="Optional"
class="full-input"
is-multiline
height="100px"
is-limit-shown
:current-limit="description.length"
:max-symbols="100"
@setData="setProjectDescription"
/>
<div class="create-project__container__button-container">
<VButton
class="create-project__container__button-container__cancel"
label="Cancel"
width="210px"
height="48px"
:on-press="onCancelClick"
:is-transparent="true"
/>
<VButton
label="Create Project +"
width="210px"
height="48px"
:on-press="onCreateProjectClick"
:is-disabled="!projectName"
/>
</div>
<div v-if="isLoading" class="create-project__container__blur">
<VLoader class="create-project__container__blur__loader" width="50px" height="50px" />
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { RouteConfig } from '@/types/router';
import { ProjectFields } from '@/types/projects';
import { LocalData } from '@/utils/localData';
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
import { useNotify } from '@/utils/hooks';
import { useUsersStore } from '@/store/modules/usersStore';
import { useProjectsStore } from '@/store/modules/projectsStore';
import { useAnalyticsStore } from '@/store/modules/analyticsStore';
import VLoader from '@/components/common/VLoader.vue';
import VButton from '@/components/common/VButton.vue';
import VInput from '@/components/common/VInput.vue';
const analyticsStore = useAnalyticsStore();
const usersStore = useUsersStore();
const projectsStore = useProjectsStore();
const notify = useNotify();
const router = useRouter();
const description = ref<string>('');
const createdProjectId = ref<string>('');
const projectName = ref<string>('');
const nameError = ref<string>('');
const isLoading = ref<boolean>(false);
/**
* Sets project name from input value.
*/
function setProjectName(value: string): void {
projectName.value = value;
nameError.value = '';
}
/**
* Sets project description from input value.
*/
function setProjectDescription(value: string): void {
description.value = value;
}
/**
* Redirects to previous route.
*/
function onCancelClick(): void {
const PREVIOUS_ROUTE_NUMBER = -1;
router.go(PREVIOUS_ROUTE_NUMBER);
}
/**
* Creates project and refreshes store.
*/
async function onCreateProjectClick(): Promise<void> {
if (isLoading.value) return;
isLoading.value = true;
projectName.value = projectName.value.trim();
const project = new ProjectFields(
projectName.value,
description.value,
usersStore.state.user.id,
);
try {
project.checkName();
} catch (error) {
isLoading.value = false;
nameError.value = error.message;
analyticsStore.errorEventTriggered(AnalyticsErrorEventSource.CREATE_PROJECT_MODAL);
return;
}
try {
createdProjectId.value = await projectsStore.createProject(project);
} catch (error) {
notify.error(error.message, AnalyticsErrorEventSource.CREATE_PROJECT_MODAL);
isLoading.value = false;
return;
}
selectCreatedProject();
notify.success('Project created successfully!');
isLoading.value = false;
analyticsStore.pageVisit(RouteConfig.ProjectDashboard.path);
await router.push(RouteConfig.ProjectDashboard.path);
}
/**
* Selects just created project.
*/
function selectCreatedProject(): void {
projectsStore.selectProject(createdProjectId.value);
LocalData.setSelectedProjectId(createdProjectId.value);
}
</script>
<style scoped lang="scss">
.create-project {
width: 100%;
height: calc(100% - 140px);
padding: 70px 0;
font-family: 'font_regular', sans-serif;
&__container {
margin: 0 auto;
max-width: 440px;
padding: 70px 50px 55px;
background-color: #fff;
border-radius: 8px;
position: relative;
&__image-container {
width: 100%;
display: flex;
justify-content: center;
}
&__img {
max-width: 190px;
max-height: 130px;
}
&__title {
font-size: 28px;
line-height: 34px;
color: #384b65;
font-family: 'font_bold', sans-serif;
text-align: center;
margin: 15px 0 30px;
}
&__button-container {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 30px;
&__cancel {
margin-right: 20px;
}
}
&__blur {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background-color: rgb(229 229 229 / 20%);
border-radius: 8px;
z-index: 100;
&__loader {
width: 25px;
height: 25px;
position: absolute;
right: 40px;
top: 40px;
}
}
}
}
.full-input {
margin-top: 20px;
}
</style>

View File

@ -36,7 +36,7 @@
width="130px" width="130px"
height="40px" height="40px"
font-size="13px" font-size="13px"
:on-press="onCreateProjectClick" :on-press="handleCreateProjectClick"
:is-white="true" :is-white="true"
> >
<template #icon> <template #icon>
@ -193,6 +193,7 @@ import { centsToDollars } from '@/utils/strings';
import { User } from '@/types/users'; import { User } from '@/types/users';
import { ProjectRole } from '@/types/projectMembers'; import { ProjectRole } from '@/types/projectMembers';
import { useAnalyticsStore } from '@/store/modules/analyticsStore'; import { useAnalyticsStore } from '@/store/modules/analyticsStore';
import { useCreateProjectClickHandler } from '@/composables/useCreateProjectClickHandler';
import VLoader from '@/components/common/VLoader.vue'; import VLoader from '@/components/common/VLoader.vue';
import InfoContainer from '@/components/project/dashboard/InfoContainer.vue'; import InfoContainer from '@/components/project/dashboard/InfoContainer.vue';
@ -223,6 +224,8 @@ const usersStore = useUsersStore();
const projectsStore = useProjectsStore(); const projectsStore = useProjectsStore();
const pmStore = useProjectMembersStore(); const pmStore = useProjectMembersStore();
const agStore = useAccessGrantsStore(); const agStore = useAccessGrantsStore();
const { handleCreateProjectClick } = useCreateProjectClickHandler();
const notify = useNotify(); const notify = useNotify();
const router = useRouter(); const router = useRouter();
@ -400,14 +403,6 @@ function onInviteUsersClick(): void {
appStore.updateActiveModal(MODALS.addTeamMember); appStore.updateActiveModal(MODALS.addTeamMember);
} }
/**
* Holds on create project button click logic.
*/
function onCreateProjectClick(): void {
analyticsStore.pageVisit(RouteConfig.CreateProject.path);
router.push(RouteConfig.CreateProject.path);
}
/** /**
* toggleChartsDatePicker holds logic for toggling charts date picker. * toggleChartsDatePicker holds logic for toggling charts date picker.
*/ */

View File

@ -9,7 +9,7 @@
label="Create Project +" label="Create Project +"
width="203px" width="203px"
height="44px" height="44px"
:on-press="onCreateClick" :on-press="handleCreateProjectClick"
:is-disabled="areProjectsFetching" :is-disabled="areProjectsFetching"
/> />
</div> </div>
@ -52,18 +52,15 @@ import { useRouter } from 'vue-router';
import { RouteConfig } from '@/types/router'; import { RouteConfig } from '@/types/router';
import { Project, ProjectsPage } from '@/types/projects'; import { Project, ProjectsPage } from '@/types/projects';
import { LocalData } from '@/utils/localData'; import { LocalData } from '@/utils/localData';
import { User } from '@/types/users'; import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
import { AnalyticsErrorEventSource, AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { useNotify } from '@/utils/hooks'; import { useNotify } from '@/utils/hooks';
import { useUsersStore } from '@/store/modules/usersStore';
import { useProjectMembersStore } from '@/store/modules/projectMembersStore'; import { useProjectMembersStore } from '@/store/modules/projectMembersStore';
import { useBillingStore } from '@/store/modules/billingStore'; import { useBillingStore } from '@/store/modules/billingStore';
import { useAppStore } from '@/store/modules/appStore';
import { useAccessGrantsStore } from '@/store/modules/accessGrantsStore'; import { useAccessGrantsStore } from '@/store/modules/accessGrantsStore';
import { useBucketsStore } from '@/store/modules/bucketsStore'; import { useBucketsStore } from '@/store/modules/bucketsStore';
import { useProjectsStore } from '@/store/modules/projectsStore'; import { useProjectsStore } from '@/store/modules/projectsStore';
import { useAnalyticsStore } from '@/store/modules/analyticsStore'; import { useAnalyticsStore } from '@/store/modules/analyticsStore';
import { useCreateProjectClickHandler } from '@/composables/useCreateProjectClickHandler';
import ProjectsListItem from '@/components/projectsList/ProjectsListItem.vue'; import ProjectsListItem from '@/components/projectsList/ProjectsListItem.vue';
import VTable from '@/components/common/VTable.vue'; import VTable from '@/components/common/VTable.vue';
@ -74,12 +71,12 @@ const FIRST_PAGE = 1;
const analyticsStore = useAnalyticsStore(); const analyticsStore = useAnalyticsStore();
const bucketsStore = useBucketsStore(); const bucketsStore = useBucketsStore();
const appStore = useAppStore();
const agStore = useAccessGrantsStore(); const agStore = useAccessGrantsStore();
const pmStore = useProjectMembersStore(); const pmStore = useProjectMembersStore();
const billingStore = useBillingStore(); const billingStore = useBillingStore();
const usersStore = useUsersStore();
const projectsStore = useProjectsStore(); const projectsStore = useProjectsStore();
const { handleCreateProjectClick } = useCreateProjectClickHandler();
const notify = useNotify(); const notify = useNotify();
const router = useRouter(); const router = useRouter();
@ -108,23 +105,6 @@ async function onPageChange(page: number, limit: number): Promise<void> {
} }
} }
/**
* Redirects to create project page.
*/
function onCreateClick(): void {
analyticsStore.eventTriggered(AnalyticsEvent.NEW_PROJECT_CLICKED);
const user: User = usersStore.state.user;
const ownProjectsCount: number = projectsStore.projectsCount(user.id);
if (!user.paidTier || user.projectLimit === ownProjectsCount) {
appStore.updateActiveModal(MODALS.createProjectPrompt);
} else {
analyticsStore.pageVisit(RouteConfig.CreateProject.path);
appStore.updateActiveModal(MODALS.newCreateProject);
}
}
/** /**
* Fetches all project related information. * Fetches all project related information.
* @param project * @param project

View File

@ -0,0 +1,36 @@
// Copyright (C) 2023 Storj Labs, Inc.
// See LICENSE for copying information.
import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
import { User } from '@/types/users';
import { RouteConfig } from '@/types/router';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { useAnalyticsStore } from '@/store/modules/analyticsStore';
import { useUsersStore } from '@/store/modules/usersStore';
import { useProjectsStore } from '@/store/modules/projectsStore';
import { useAppStore } from '@/store/modules/appStore';
export function useCreateProjectClickHandler() {
const analyticsStore = useAnalyticsStore();
const userStore = useUsersStore();
const projectsStore = useProjectsStore();
const appStore = useAppStore();
function handleCreateProjectClick(): void {
analyticsStore.eventTriggered(AnalyticsEvent.CREATE_NEW_CLICKED);
const user: User = userStore.state.user;
const ownProjectsCount: number = projectsStore.projectsCount(user.id);
if (user.projectLimit > ownProjectsCount) {
analyticsStore.pageVisit(RouteConfig.CreateProject.path);
appStore.updateActiveModal(MODALS.newCreateProject);
} else {
appStore.updateActiveModal(MODALS.createProjectPrompt);
}
}
return {
handleCreateProjectClick,
};
}

View File

@ -26,7 +26,6 @@ import OnboardingTourArea from '@/components/onboardingTour/OnboardingTourArea.v
import PricingPlanStep from '@/components/onboardingTour/steps/PricingPlanStep.vue'; import PricingPlanStep from '@/components/onboardingTour/steps/PricingPlanStep.vue';
import OnbCLIStep from '@/components/onboardingTour/steps/CLIStep.vue'; import OnbCLIStep from '@/components/onboardingTour/steps/CLIStep.vue';
import OverviewStep from '@/components/onboardingTour/steps/OverviewStep.vue'; import OverviewStep from '@/components/onboardingTour/steps/OverviewStep.vue';
import CreateProject from '@/components/project/CreateProject.vue';
import EditProjectDetails from '@/components/project/EditProjectDetails.vue'; import EditProjectDetails from '@/components/project/EditProjectDetails.vue';
import ProjectDashboard from '@/components/project/dashboard/ProjectDashboard.vue'; import ProjectDashboard from '@/components/project/dashboard/ProjectDashboard.vue';
import ProjectsList from '@/components/projectsList/ProjectsList.vue'; import ProjectsList from '@/components/projectsList/ProjectsList.vue';
@ -248,11 +247,6 @@ export const router = createRouter({
}, },
], ],
}, },
{
path: RouteConfig.CreateProject.path,
name: RouteConfig.CreateProject.name,
component: CreateProject,
},
{ {
path: RouteConfig.EditProjectDetails.path, path: RouteConfig.EditProjectDetails.path,
name: RouteConfig.EditProjectDetails.name, name: RouteConfig.EditProjectDetails.name,

View File

@ -22,47 +22,20 @@
<VButton <VButton
class="empty-project-item__button" class="empty-project-item__button"
icon="addcircle" icon="addcircle"
:on-press="onCreateProjectClicked" :on-press="handleCreateProjectClick"
label="Create a Project" label="Create a Project"
/> />
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames'; import { useCreateProjectClickHandler } from '@/composables/useCreateProjectClickHandler';
import { User } from '@/types/users';
import { RouteConfig } from '@/types/router';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { useUsersStore } from '@/store/modules/usersStore';
import { useAppStore } from '@/store/modules/appStore';
import { useProjectsStore } from '@/store/modules/projectsStore';
import { useAnalyticsStore } from '@/store/modules/analyticsStore';
import VButton from '@/components/common/VButton.vue'; import VButton from '@/components/common/VButton.vue';
import BoxIcon from '@/../static/images/navigation/project.svg'; import BoxIcon from '@/../static/images/navigation/project.svg';
const analyticsStore = useAnalyticsStore(); const { handleCreateProjectClick } = useCreateProjectClickHandler();
const appStore = useAppStore();
const usersStore = useUsersStore();
const projectsStore = useProjectsStore();
/**
* Route to create project page.
*/
function onCreateProjectClicked(): void {
analyticsStore.eventTriggered(AnalyticsEvent.CREATE_NEW_CLICKED);
const user: User = usersStore.state.user;
const ownProjectsCount: number = projectsStore.projectsCount(user.id);
if (!user.paidTier && user.projectLimit === ownProjectsCount) {
appStore.updateActiveModal(MODALS.createProjectPrompt);
} else {
analyticsStore.pageVisit(RouteConfig.CreateProject.path);
appStore.updateActiveModal(MODALS.newCreateProject);
}
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@ -46,7 +46,7 @@
border-radius="8px" border-radius="8px"
font-size="12px" font-size="12px"
is-white is-white
:on-press="onCreateProjectClicked" :on-press="handleCreateProjectClick"
label="Create New Project" label="Create New Project"
/> />
@ -56,7 +56,7 @@
border-radius="8px" border-radius="8px"
font-size="12px" font-size="12px"
is-white is-white
:on-press="onCreateProjectClicked" :on-press="handleCreateProjectClick"
label="Create a Project" label="Create a Project"
/> />
</span> </span>
@ -85,21 +85,14 @@
import { computed, onMounted, ref } from 'vue'; import { computed, onMounted, ref } from 'vue';
import { Project, ProjectInvitation } from '@/types/projects'; import { Project, ProjectInvitation } from '@/types/projects';
import { RouteConfig } from '@/types/router'; import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
import {
AnalyticsErrorEventSource,
AnalyticsEvent,
} from '@/utils/constants/analyticsEventNames';
import { User } from '@/types/users';
import { MODALS } from '@/utils/constants/appStatePopUps';
import { useUsersStore } from '@/store/modules/usersStore';
import { useAppStore } from '@/store/modules/appStore'; import { useAppStore } from '@/store/modules/appStore';
import { useProjectsStore } from '@/store/modules/projectsStore'; import { useProjectsStore } from '@/store/modules/projectsStore';
import { useConfigStore } from '@/store/modules/configStore'; import { useConfigStore } from '@/store/modules/configStore';
import { useResize } from '@/composables/resize'; import { useResize } from '@/composables/resize';
import { useAnalyticsStore } from '@/store/modules/analyticsStore';
import { useBillingStore } from '@/store/modules/billingStore'; import { useBillingStore } from '@/store/modules/billingStore';
import { useNotify } from '@/utils/hooks'; import { useNotify } from '@/utils/hooks';
import { useCreateProjectClickHandler } from '@/composables/useCreateProjectClickHandler';
import EmptyProjectItem from '@/views/all-dashboard/components/EmptyProjectItem.vue'; import EmptyProjectItem from '@/views/all-dashboard/components/EmptyProjectItem.vue';
import ProjectItem from '@/views/all-dashboard/components/ProjectItem.vue'; import ProjectItem from '@/views/all-dashboard/components/ProjectItem.vue';
@ -116,10 +109,9 @@ import TableIcon from '@/../static/images/common/tableIcon.svg';
const billingStore = useBillingStore(); const billingStore = useBillingStore();
const appStore = useAppStore(); const appStore = useAppStore();
const configStore = useConfigStore(); const configStore = useConfigStore();
const usersStore = useUsersStore();
const projectsStore = useProjectsStore(); const projectsStore = useProjectsStore();
const analyticsStore = useAnalyticsStore();
const { handleCreateProjectClick } = useCreateProjectClickHandler();
const notify = useNotify(); const notify = useNotify();
const { isMobile } = useResize(); const { isMobile } = useResize();
@ -158,23 +150,6 @@ function onViewChangeClicked(view: string): void {
hasProjectTableViewConfigured.value = true; hasProjectTableViewConfigured.value = true;
} }
/**
* Route to create project page.
*/
function onCreateProjectClicked(): void {
analyticsStore.eventTriggered(AnalyticsEvent.CREATE_NEW_CLICKED);
const user: User = usersStore.state.user;
const ownProjectsCount: number = projectsStore.projectsCount(user.id);
if (user.projectLimit > ownProjectsCount) {
analyticsStore.pageVisit(RouteConfig.CreateProject.path);
appStore.updateActiveModal(MODALS.newCreateProject);
} else {
appStore.updateActiveModal(MODALS.createProjectPrompt);
}
}
onMounted(async () => { onMounted(async () => {
if (!configStore.state.config.nativeTokenPaymentsEnabled) { if (!configStore.state.config.nativeTokenPaymentsEnabled) {
return; return;

View File

@ -228,7 +228,7 @@ const reachedThresholds = computed((): LimitThresholdsReached => {
* Indicates if navigation sidebar is hidden. * Indicates if navigation sidebar is hidden.
*/ */
const isNavigationHidden = computed((): boolean => { const isNavigationHidden = computed((): boolean => {
return isOnboardingTour.value || isCreateProjectPage.value; return isOnboardingTour.value;
}); });
/* whether the paid tier banner should be shown */ /* whether the paid tier banner should be shown */
@ -290,13 +290,6 @@ const isProjectInvitationBannerShown = computed((): boolean => {
return !configStore.state.config.allProjectsDashboard; return !configStore.state.config.allProjectsDashboard;
}); });
/**
* Indicates if current route is create project page.
*/
const isCreateProjectPage = computed((): boolean => {
return route.name === RouteConfig.CreateProject.name;
});
/** /**
* Indicates if current route is the dashboard page. * Indicates if current route is the dashboard page.
*/ */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -1,22 +0,0 @@
// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
import { shallowMount } from '@vue/test-utils';
import CreateProject from '@/components/project/CreateProject.vue';
describe('CreateProject.vue', (): void => {
it('renders correctly', (): void => {
const wrapper = shallowMount(CreateProject);
expect(wrapper).toMatchSnapshot();
});
it('renders correctly with project name', async (): Promise<void> => {
const wrapper = shallowMount(CreateProject);
await wrapper.vm.setProjectName('testName');
expect(wrapper.findAll('.disabled').length).toBe(0);
});
});