diff --git a/packages/client-core/src/admin/components/settings/tabs/features.tsx b/packages/client-core/src/admin/components/settings/tabs/features.tsx index 1fe56a24a5..a34f3aa6ce 100644 --- a/packages/client-core/src/admin/components/settings/tabs/features.tsx +++ b/packages/client-core/src/admin/components/settings/tabs/features.tsx @@ -28,17 +28,22 @@ import React, { forwardRef, useEffect } from 'react' import { useTranslation } from 'react-i18next' import { HiMinus, HiPlusSmall } from 'react-icons/hi2' -import { - FeatureFlag, - FeatureFlagSettingType, - featureFlagSettingPath -} from '@etherealengine/common/src/schema.type.module' +import { FeatureFlagSettingType, featureFlagSettingPath } from '@etherealengine/common/src/schema.type.module' import { useFind } from '@etherealengine/spatial/src/common/functions/FeathersHooks' import Accordion from '@etherealengine/ui/src/primitives/tailwind/Accordion' import { useHookstate } from '@hookstate/core' const defaultProps = ['id', 'flagName', 'flagValue', 'createdAt', 'updatedAt'] +const defaultTypes = [ + 'ir.client.menu.social', + 'ir.client.menu.emote', + 'ir.client.menu.avaturn', + 'ir.client.menu.readyPlayerMe' +] as const + +type FeatureFlag = (typeof defaultTypes)[number] + const FeaturesTab = forwardRef(({ open }: { open: boolean }, ref: React.MutableRefObject) => { const { t } = useTranslation() const displayedFeatures = useHookstate([]) @@ -46,13 +51,6 @@ const FeaturesTab = forwardRef(({ open }: { open: boolean }, ref: React.MutableR const featureFlagSettings = useFind(featureFlagSettingPath) useEffect(() => { - const defaultTypes = [ - 'ir.client.menu.social', - 'ir.client.menu.emote', - 'ir.client.menu.avaturn', - 'ir.client.menu.readyPlayerMe' - ] - if (featureFlagSettings.status === 'success') { const missingTypes = defaultTypes.filter( (type) => diff --git a/packages/common/src/schemas/setting/feature-flag-setting.schema.ts b/packages/common/src/schemas/setting/feature-flag-setting.schema.ts index 0ead322f6c..80d7b77606 100644 --- a/packages/common/src/schemas/setting/feature-flag-setting.schema.ts +++ b/packages/common/src/schemas/setting/feature-flag-setting.schema.ts @@ -25,11 +25,9 @@ Ethereal Engine. All Rights Reserved. // For more information about this file see https://dove.feathersjs.com/guides/cli/service.schemas.html import type { Static } from '@feathersjs/typebox' -import { getValidator, querySyntax, StringEnum, Type } from '@feathersjs/typebox' +import { getValidator, querySyntax, Type } from '@feathersjs/typebox' import { dataValidator, queryValidator } from '../validators' -export type FeatureFlag = FeatureFlagSettingType['flagName'] - export const featureFlagSettingPath = 'feature-flag-setting' export const featureFlagSettingMethods = ['find', 'get', 'create', 'patch', 'remove'] as const @@ -40,15 +38,7 @@ export const featureFlagSettingSchema = Type.Object( id: Type.String({ format: 'uuid' }), - flagName: StringEnum([ - 'ir.client.menu.social', - 'ir.client.menu.emote', - 'ir.client.menu.avaturn', - 'ir.client.menu.readyPlayerMe', - 'ir.mt.menu.myDomains', - 'ir.mt.project.storage', - 'ir.mt.project.version' - ]), + flagName: Type.String(), flagValue: Type.Boolean(), createdAt: Type.String({ format: 'date-time' }), updatedAt: Type.String({ format: 'date-time' }) diff --git a/packages/engine/src/FeatureFlagsState.tsx b/packages/engine/src/FeatureFlagsState.tsx index 819788d368..2e4140d594 100644 --- a/packages/engine/src/FeatureFlagsState.tsx +++ b/packages/engine/src/FeatureFlagsState.tsx @@ -23,21 +23,21 @@ All portions of the code written by the Ethereal Engine team are Copyright © 20 Ethereal Engine. All Rights Reserved. */ -import { FeatureFlag, featureFlagSettingPath } from '@etherealengine/common/src/schema.type.module' +import { featureFlagSettingPath } from '@etherealengine/common/src/schema.type.module' import { defineState, getMutableState, useHookstate } from '@etherealengine/hyperflux/functions/StateFunctions' import { useFind } from '@etherealengine/spatial/src/common/functions/FeathersHooks' import { useEffect } from 'react' export const FeatureFlagsState = defineState({ name: 'ee.engine.FeatureFlagsState', - initial: {} as Record, - enabled(flagName: FeatureFlag) { + initial: {} as Record, + enabled(flagName: FlagName) { const state = getMutableState(FeatureFlagsState)[flagName].value return typeof state === 'boolean' ? state : true }, - useEnabled(flagName: FeatureFlag) { + useEnabled(flagName: FlagName) { const state = useHookstate(getMutableState(FeatureFlagsState)[flagName]).value - return typeof state === 'boolean' ? state : typeof state === 'number' && state === 0 ? false : true + return typeof state === 'boolean' ? state : true }, reactor: () => { const featureFlagQuery = useFind(featureFlagSettingPath) diff --git a/packages/server-core/src/setting/feature-flag-setting/feature-flag-setting.resolvers.ts b/packages/server-core/src/setting/feature-flag-setting/feature-flag-setting.resolvers.ts index f17ed6e10a..8f4aba465f 100644 --- a/packages/server-core/src/setting/feature-flag-setting/feature-flag-setting.resolvers.ts +++ b/packages/server-core/src/setting/feature-flag-setting/feature-flag-setting.resolvers.ts @@ -40,7 +40,9 @@ export const featureFlagSettingResolver = resolve fromDateTimeSql(featureFlagSettings.updatedAt)) }) -export const featureFlagSettingExternalResolver = resolve({}) +export const featureFlagSettingExternalResolver = resolve({ + flagValue: async (_, setting) => !!setting.flagValue +}) export const featureFlagSettingDataResolver = resolve({ id: async () => {