satellite/{web, console}: feature flag for new access grant flow
Added a feature flag for new create access grant flow. Also added some initial setup. Change-Id: I7f738181c8a83f5a724f9e562427445cae146b6f
This commit is contained in:
parent
38275bd710
commit
65e3cfb9c6
@ -92,6 +92,7 @@ type Config struct {
|
||||
PathwayOverviewEnabled bool `help:"indicates if the overview onboarding step should render with pathways" default:"true"`
|
||||
NewProjectDashboard bool `help:"indicates if new project dashboard should be used" default:"true"`
|
||||
NewBillingScreen bool `help:"indicates if new billing screens should be used" default:"true"`
|
||||
NewAccessGrantFlow bool `help:"indicates if new access grant flow should be used" default:"false"`
|
||||
GeneratedAPIEnabled bool `help:"indicates if generated console api should be used" default:"false"`
|
||||
OptionalSignupSuccessURL string `help:"optional url to external registration success page" default:""`
|
||||
HomepageURL string `help:"url link to storj.io homepage" default:"https://www.storj.io"`
|
||||
@ -457,6 +458,7 @@ func (server *Server) appHandler(w http.ResponseWriter, r *http.Request) {
|
||||
DefaultPaidStorageLimit memory.Size
|
||||
DefaultPaidBandwidthLimit memory.Size
|
||||
NewBillingScreen bool
|
||||
NewAccessGrantFlow bool
|
||||
InactivityTimerEnabled bool
|
||||
InactivityTimerDuration int
|
||||
InactivityTimerViewerEnabled bool
|
||||
@ -507,6 +509,7 @@ func (server *Server) appHandler(w http.ResponseWriter, r *http.Request) {
|
||||
data.PasswordMinimumLength = console.PasswordMinimumLength
|
||||
data.PasswordMaximumLength = console.PasswordMaximumLength
|
||||
data.ABTestingEnabled = server.config.ABTesting.Enabled
|
||||
data.NewAccessGrantFlow = server.config.NewAccessGrantFlow
|
||||
|
||||
templates, err := server.loadTemplates()
|
||||
if err != nil || templates.index == nil {
|
||||
|
3
scripts/testdata/satellite-config.yaml.lock
vendored
3
scripts/testdata/satellite-config.yaml.lock
vendored
@ -244,6 +244,9 @@ compensation.withheld-percents: 75,75,75,50,50,50,25,25,25,0,0,0,0,0,0
|
||||
# indicates if storj native token payments system is enabled
|
||||
# console.native-token-payments-enabled: false
|
||||
|
||||
# indicates if new access grant flow should be used
|
||||
# console.new-access-grant-flow: false
|
||||
|
||||
# indicates if new billing screens should be used
|
||||
# console.new-billing-screen: true
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
<meta name="default-paid-storage-limit" content="{{ .DefaultPaidStorageLimit }}">
|
||||
<meta name="default-paid-bandwidth-limit" content="{{ .DefaultPaidBandwidthLimit }}">
|
||||
<meta name="new-billing-screen" content="{{ .NewBillingScreen }}">
|
||||
<meta name="new-access-grant-flow" content="{{ .NewAccessGrantFlow }}">
|
||||
<meta name="inactivity-timer-enabled" content="{{ .InactivityTimerEnabled }}">
|
||||
<meta name="inactivity-timer-duration" content="{{ .InactivityTimerDuration }}">
|
||||
<meta name="inactivity-timer-viewer-enabled" content="{{ .InactivityTimerViewerEnabled }}">
|
||||
|
@ -14,6 +14,7 @@ import { Component, Vue } from 'vue-property-decorator';
|
||||
|
||||
import { PartneredSatellite } from '@/types/common';
|
||||
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
|
||||
import { APP_STATE_MUTATIONS } from '@/store/mutationConstants';
|
||||
import { MetaUtils } from '@/utils/meta';
|
||||
|
||||
import NotificationArea from '@/components/notifications/NotificationArea.vue';
|
||||
@ -40,6 +41,7 @@ export default class App extends Vue {
|
||||
const couponCodeBillingUIEnabled = MetaUtils.getMetaContent('coupon-code-billing-ui-enabled');
|
||||
const couponCodeSignupUIEnabled = MetaUtils.getMetaContent('coupon-code-signup-ui-enabled');
|
||||
const isNewProjectDashboard = MetaUtils.getMetaContent('new-project-dashboard');
|
||||
const isNewAccessGrantFlow = MetaUtils.getMetaContent('new-access-grant-flow');
|
||||
|
||||
if (satelliteName) {
|
||||
this.$store.dispatch(APP_STATE_ACTIONS.SET_SATELLITE_NAME, satelliteName);
|
||||
@ -72,6 +74,10 @@ export default class App extends Vue {
|
||||
this.$store.dispatch(APP_STATE_ACTIONS.SET_PROJECT_DASHBOARD_STATUS, isNewProjectDashboard === 'true');
|
||||
}
|
||||
|
||||
if (isNewAccessGrantFlow) {
|
||||
this.$store.commit(APP_STATE_MUTATIONS.SET_ACCESS_GRANT_FLOW_STATUS, isNewAccessGrantFlow === 'true');
|
||||
}
|
||||
|
||||
this.fixViewportHeight();
|
||||
}
|
||||
|
||||
|
@ -168,6 +168,7 @@ import { ACCESS_GRANTS_ACTIONS } from '@/store/modules/accessGrants';
|
||||
import { AccessGrant } from '@/types/accessGrants';
|
||||
import { AnalyticsHttpApi } from '@/api/analytics';
|
||||
import { AnalyticsErrorEventSource, AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
|
||||
import { AccessType } from '@/types/createAccessGrant';
|
||||
|
||||
import AccessGrantsItem from '@/components/accessGrants/AccessGrantsItem.vue';
|
||||
import ConfirmDeletePopup from '@/components/accessGrants/ConfirmDeletePopup.vue';
|
||||
@ -342,6 +343,16 @@ export default class AccessGrants extends Vue {
|
||||
*/
|
||||
public accessGrantClick(): void {
|
||||
this.analytics.eventTriggered(AnalyticsEvent.CREATE_ACCESS_GRANT_CLICKED);
|
||||
|
||||
if (this.isNewAccessGrantFlow) {
|
||||
this.trackPageVisit(RouteConfig.AccessGrants.with(RouteConfig.NewCreateAccessModal).path);
|
||||
this.$router.push({
|
||||
name: RouteConfig.NewCreateAccessModal.name,
|
||||
params: { accessType: AccessType.AccessGrant },
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.trackPageVisit(RouteConfig.AccessGrants.with(RouteConfig.CreateAccessModal).path);
|
||||
this.$router.push({
|
||||
name: RouteConfig.AccessGrants.with(RouteConfig.CreateAccessModal).name,
|
||||
@ -354,6 +365,16 @@ export default class AccessGrants extends Vue {
|
||||
*/
|
||||
public s3Click(): void {
|
||||
this.analytics.eventTriggered(AnalyticsEvent.CREATE_S3_CREDENTIALS_CLICKED);
|
||||
|
||||
if (this.isNewAccessGrantFlow) {
|
||||
this.trackPageVisit(RouteConfig.AccessGrants.with(RouteConfig.NewCreateAccessModal).path);
|
||||
this.$router.push({
|
||||
name: RouteConfig.NewCreateAccessModal.name,
|
||||
params: { accessType: AccessType.S3 },
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.trackPageVisit(RouteConfig.AccessGrants.with(RouteConfig.CreateAccessModal).path);
|
||||
this.$router.push({
|
||||
name: RouteConfig.AccessGrants.with(RouteConfig.CreateAccessModal).name,
|
||||
@ -366,6 +387,16 @@ export default class AccessGrants extends Vue {
|
||||
*/
|
||||
public cliClick(): void {
|
||||
this.analytics.eventTriggered(AnalyticsEvent.CREATE_KEYS_FOR_CLI_CLICKED);
|
||||
|
||||
if (this.isNewAccessGrantFlow) {
|
||||
this.trackPageVisit(RouteConfig.AccessGrants.with(RouteConfig.NewCreateAccessModal).path);
|
||||
this.$router.push({
|
||||
name: RouteConfig.NewCreateAccessModal.name,
|
||||
params: { accessType: AccessType.APIKey },
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.trackPageVisit(RouteConfig.AccessGrants.with(RouteConfig.CreateAccessModal).path);
|
||||
this.$router.push({
|
||||
name: RouteConfig.AccessGrants.with(RouteConfig.CreateAccessModal).name,
|
||||
@ -379,6 +410,13 @@ export default class AccessGrants extends Vue {
|
||||
public trackPageVisit(link: string): void {
|
||||
this.analytics.pageVisit(link);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if new access grant flow should be used.
|
||||
*/
|
||||
private get isNewAccessGrantFlow(): boolean {
|
||||
return this.$store.state.appStateModule.isNewAccessGrantFlow;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
|
@ -0,0 +1,24 @@
|
||||
// Copyright (C) 2023 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
<template>
|
||||
<VModal :on-close="closeModal">
|
||||
<template #content />
|
||||
</VModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from '@/utils/hooks';
|
||||
import { RouteConfig } from '@/router';
|
||||
|
||||
import VModal from '@/components/common/VModal.vue';
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
/**
|
||||
* Closes create access grant flow.
|
||||
*/
|
||||
function closeModal(): void {
|
||||
router.push(RouteConfig.AccessGrants.path);
|
||||
}
|
||||
</script>
|
@ -49,6 +49,7 @@ import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
|
||||
import { RouteConfig } from '@/router';
|
||||
import { APP_STATE_MUTATIONS } from '@/store/mutationConstants';
|
||||
import { User } from '@/types/users';
|
||||
import { AccessType } from '@/types/createAccessGrant';
|
||||
|
||||
import NewProjectIcon from '@/../static/images/navigation/newProject.svg';
|
||||
import CreateAGIcon from '@/../static/images/navigation/createAccessGrant.svg';
|
||||
@ -78,6 +79,16 @@ export default class QuickStartLinks extends Vue {
|
||||
public navigateToCreateAG(): void {
|
||||
this.analytics.eventTriggered(AnalyticsEvent.CREATE_AN_ACCESS_GRANT_CLICKED);
|
||||
this.closeDropdowns();
|
||||
|
||||
if (this.isNewAccessGrantFlow) {
|
||||
this.analytics.pageVisit(RouteConfig.AccessGrants.with(RouteConfig.NewCreateAccessModal).path);
|
||||
this.$router.push({
|
||||
name: RouteConfig.NewCreateAccessModal.name,
|
||||
params: { accessType: AccessType.AccessGrant },
|
||||
}).catch(() => {return;});
|
||||
return;
|
||||
}
|
||||
|
||||
this.analytics.pageVisit(RouteConfig.AccessGrants.with(RouteConfig.CreateAccessModal).path);
|
||||
this.$router.push({
|
||||
name: RouteConfig.AccessGrants.with(RouteConfig.CreateAccessModal).name,
|
||||
@ -91,6 +102,16 @@ export default class QuickStartLinks extends Vue {
|
||||
public navigateToAccessGrantS3(): void {
|
||||
this.analytics.eventTriggered(AnalyticsEvent.CREATE_S3_CREDENTIALS_CLICKED);
|
||||
this.closeDropdowns();
|
||||
|
||||
if (this.isNewAccessGrantFlow) {
|
||||
this.analytics.pageVisit(RouteConfig.AccessGrants.with(RouteConfig.NewCreateAccessModal).path);
|
||||
this.$router.push({
|
||||
name: RouteConfig.NewCreateAccessModal.name,
|
||||
params: { accessType: AccessType.S3 },
|
||||
}).catch(() => {return;});
|
||||
return;
|
||||
}
|
||||
|
||||
this.analytics.pageVisit(RouteConfig.AccessGrants.with(RouteConfig.CreateAccessModal).path);
|
||||
this.$router.push({
|
||||
name: RouteConfig.AccessGrants.with(RouteConfig.CreateAccessModal).name,
|
||||
@ -139,6 +160,13 @@ export default class QuickStartLinks extends Vue {
|
||||
|
||||
this.closeDropdowns();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if new access grant flow should be used.
|
||||
*/
|
||||
private get isNewAccessGrantFlow(): boolean {
|
||||
return this.$store.state.appStateModule.isNewAccessGrantFlow;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -9,6 +9,7 @@ import { MetaUtils } from '@/utils/meta';
|
||||
|
||||
import AccessGrants from '@/components/accessGrants/AccessGrants.vue';
|
||||
import CreateAccessModal from '@/components/accessGrants/CreateAccessModal.vue';
|
||||
import CreateAccessGrantFlow from '@/components/accessGrants/newCreateFlow/CreateAccessGrantFlow.vue';
|
||||
import AccountArea from '@/components/account/AccountArea.vue';
|
||||
import AccountBilling from '@/components/account/billing/BillingArea.vue';
|
||||
import BillingOverview from '@/components/account/billing/billingTabs/Overview.vue';
|
||||
@ -92,6 +93,7 @@ export abstract class RouteConfig {
|
||||
|
||||
// access grant child paths
|
||||
public static CreateAccessModal = new NavigationLink('create-access-modal', 'Create Access Modal');
|
||||
public static NewCreateAccessModal = new NavigationLink('new-create-access-modal', 'New Create Access Modal');
|
||||
|
||||
// onboarding tour child paths
|
||||
public static OverviewStep = new NavigationLink('overview', 'Onboarding Overview');
|
||||
@ -352,6 +354,11 @@ export const router = new Router({
|
||||
name: RouteConfig.CreateAccessModal.name,
|
||||
component: CreateAccessModal,
|
||||
},
|
||||
{
|
||||
path: RouteConfig.NewCreateAccessModal.path,
|
||||
name: RouteConfig.NewCreateAccessModal.name,
|
||||
component: CreateAccessGrantFlow,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -70,6 +70,7 @@ class State {
|
||||
public couponCodeBillingUIEnabled = false,
|
||||
public couponCodeSignupUIEnabled = false,
|
||||
public isNewProjectDashboard = false,
|
||||
public isNewAccessGrantFlow = false,
|
||||
){}
|
||||
}
|
||||
|
||||
@ -271,6 +272,9 @@ export const appStateModule = {
|
||||
[APP_STATE_MUTATIONS.SET_PROJECT_DASHBOARD_STATUS](state: State, isNewProjectDashboard: boolean): void {
|
||||
state.isNewProjectDashboard = isNewProjectDashboard;
|
||||
},
|
||||
[APP_STATE_MUTATIONS.SET_ACCESS_GRANT_FLOW_STATUS](state: State, isNewAccessGrantFlow: boolean): void {
|
||||
state.isNewAccessGrantFlow = isNewAccessGrantFlow;
|
||||
},
|
||||
[APP_STATE_MUTATIONS.SET_ONB_AG_NAME_STEP_BACK_ROUTE](state: State, backRoute: string): void {
|
||||
state.appState.onbAGStepBackRoute = backRoute;
|
||||
},
|
||||
|
@ -62,6 +62,7 @@ export const APP_STATE_MUTATIONS = {
|
||||
SET_COUPON_CODE_BILLING_UI_STATUS: 'SET_COUPON_CODE_BILLING_UI_STATUS',
|
||||
SET_COUPON_CODE_SIGNUP_UI_STATUS: 'SET_COUPON_CODE_SIGNUP_UI_STATUS',
|
||||
SET_PROJECT_DASHBOARD_STATUS: 'SET_PROJECT_DASHBOARD_STATUS',
|
||||
SET_ACCESS_GRANT_FLOW_STATUS: 'SET_ACCESS_GRANT_FLOW_STATUS',
|
||||
SET_ONB_AG_NAME_STEP_BACK_ROUTE: 'SET_ONB_AG_NAME_STEP_BACK_ROUTE',
|
||||
SET_ONB_API_KEY_STEP_BACK_ROUTE: 'SET_ONB_API_KEY_STEP_BACK_ROUTE',
|
||||
SET_ONB_API_KEY: 'SET_ONB_API_KEY',
|
||||
|
8
web/satellite/src/types/createAccessGrant.ts
Normal file
8
web/satellite/src/types/createAccessGrant.ts
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright (C) 2023 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
export enum AccessType {
|
||||
APIKey = 'apikey',
|
||||
S3 = 's3',
|
||||
AccessGrant = 'accessGrant',
|
||||
}
|
Loading…
Reference in New Issue
Block a user