Feature flags seeds, queries and hooks (#2769)

* seed is working

* allow graphql to retrieve feature flag data

* create useIsFeatureEnabled hook

* hook is working

* Update icons.ts
This commit is contained in:
bosiraphael
2023-11-29 16:40:44 +01:00
committed by GitHub
parent d855a42eca
commit 04c7c1a334
12 changed files with 174 additions and 17 deletions

View File

@ -88,6 +88,30 @@ export type CursorPaging = {
last?: InputMaybe<Scalars['Int']>;
};
export type FeatureFlag = {
__typename?: 'FeatureFlag';
id: Scalars['ID'];
key: Scalars['String'];
value: Scalars['Boolean'];
workspaceId: Scalars['String'];
};
export type FeatureFlagFilter = {
and?: InputMaybe<Array<FeatureFlagFilter>>;
id?: InputMaybe<IdFilterComparison>;
or?: InputMaybe<Array<FeatureFlagFilter>>;
};
export type FeatureFlagSort = {
direction: SortDirection;
field: FeatureFlagSortFields;
nulls?: InputMaybe<SortNulls>;
};
export enum FeatureFlagSortFields {
Id = 'id'
}
export type FieldConnection = {
__typename?: 'FieldConnection';
/** Array of edges. */
@ -387,6 +411,18 @@ export enum RelationMetadataType {
OneToOne = 'ONE_TO_ONE'
}
/** Sort Directions */
export enum SortDirection {
Asc = 'ASC',
Desc = 'DESC'
}
/** Sort Nulls Options */
export enum SortNulls {
NullsFirst = 'NULLS_FIRST',
NullsLast = 'NULLS_LAST'
}
export type Support = {
__typename?: 'Support';
supportDriver: Scalars['String'];
@ -466,12 +502,19 @@ export type Workspace = {
deletedAt?: Maybe<Scalars['DateTime']>;
displayName?: Maybe<Scalars['String']>;
domainName?: Maybe<Scalars['String']>;
featureFlags?: Maybe<Array<FeatureFlag>>;
id: Scalars['ID'];
inviteHash?: Maybe<Scalars['String']>;
logo?: Maybe<Scalars['String']>;
updatedAt: Scalars['DateTime'];
};
export type WorkspaceFeatureFlagsArgs = {
filter?: FeatureFlagFilter;
sorting?: Array<FeatureFlagSort>;
};
export type WorkspaceEdge = {
__typename?: 'WorkspaceEdge';
/** Cursor for this node. */
@ -671,7 +714,7 @@ export type UploadProfilePictureMutation = { __typename?: 'Mutation', uploadProf
export type GetCurrentUserQueryVariables = Exact<{ [key: string]: never; }>;
export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember: { __typename?: 'UserWorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'UserWorkspaceMemberName', firstName: string, lastName: string } }, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean } } };
export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember: { __typename?: 'UserWorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'UserWorkspaceMemberName', firstName: string, lastName: string } }, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null } } };
export type DeleteCurrentWorkspaceMutationVariables = Exact<{ [key: string]: never; }>;
@ -1204,6 +1247,12 @@ export const GetCurrentUserDocument = gql`
domainName
inviteHash
allowImpersonation
featureFlags {
id
key
value
workspaceId
}
}
}
}

View File

@ -4,7 +4,12 @@ import { Workspace } from '~/generated/graphql';
export type CurrentWorkspace = Pick<
Workspace,
'id' | 'inviteHash' | 'logo' | 'displayName' | 'allowImpersonation'
| 'id'
| 'inviteHash'
| 'logo'
| 'displayName'
| 'allowImpersonation'
| 'featureFlags'
>;
export const currentWorkspaceState = atom<CurrentWorkspace | null>({

View File

@ -26,6 +26,12 @@ export const GET_CURRENT_USER = gql`
domainName
inviteHash
allowImpersonation
featureFlags {
id
key
value
workspaceId
}
}
}
}

View File

@ -0,0 +1,17 @@
import { useRecoilValue } from 'recoil';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
export const useIsFeatureEnabled = (featureKey: string): boolean => {
const currentWorkspace = useRecoilValue(currentWorkspaceState);
const featureFlag = currentWorkspace?.featureFlags?.find(
(flag) => flag.key === featureKey,
);
if (!featureFlag) {
return false;
}
return featureFlag.value;
};

View File

@ -20,6 +20,7 @@ import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer'
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
import { View } from '@/views/types/View';
import { ViewType } from '@/views/types/ViewType';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { FieldMetadataType } from '~/generated-metadata/graphql';
export const SettingsObjectNewFieldStep2 = () => {
@ -37,6 +38,10 @@ export const SettingsObjectNewFieldStep2 = () => {
findActiveObjectMetadataItemBySlug(objectSlug);
const { createMetadataField } = useFieldMetadataItem();
const isRelationFieldTypeEnabled = useIsFeatureEnabled(
'IS_RELATION_FIELD_TYPE_ENABLED',
);
const {
formValues,
handleFormChange,
@ -177,6 +182,22 @@ export const SettingsObjectNewFieldStep2 = () => {
}
};
const excludedFieldTypes = [
FieldMetadataType.Currency,
FieldMetadataType.Email,
FieldMetadataType.Enum,
FieldMetadataType.Numeric,
FieldMetadataType.FullName,
FieldMetadataType.Link,
FieldMetadataType.Phone,
FieldMetadataType.Probability,
FieldMetadataType.Uuid,
];
if (!isRelationFieldTypeEnabled) {
excludedFieldTypes.push(FieldMetadataType.Relation);
}
return (
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
<SettingsPageContainer>
@ -204,18 +225,7 @@ export const SettingsObjectNewFieldStep2 = () => {
onChange={handleFormChange}
/>
<SettingsObjectFieldTypeSelectSection
excludedFieldTypes={[
FieldMetadataType.Currency,
FieldMetadataType.Email,
FieldMetadataType.Enum,
FieldMetadataType.Numeric,
FieldMetadataType.FullName,
FieldMetadataType.Link,
FieldMetadataType.Phone,
FieldMetadataType.Probability,
FieldMetadataType.Relation,
FieldMetadataType.Uuid,
]}
excludedFieldTypes={excludedFieldTypes}
fieldMetadata={{
icon: formValues.icon,
label: formValues.label || 'Employees',