💩(chat) add frontend feature flags (#29)
* 💩(chat) add frontend feature flags This introduce the use of feature flags: - flags can be globally enabled or disabled from the backend - when dynamic, it queries Posthog to get the value * ✨(chat) add frontend feature flags disable buttons for feature flags --------- Co-authored-by: Eléonore Voisin <elevoisin@gmail.com>
This commit is contained in:
+2
-1
@@ -8,10 +8,11 @@ and this project adheres to
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
- 🎨(front) change list attachment in chat
|
||||
- ✅(chat) add frontend feature flags #29
|
||||
|
||||
### Changed
|
||||
|
||||
- 🎨(front) change list attachment in chat
|
||||
- 🎨(front) move emplacement for attachment
|
||||
- 🎨(ui) retour ui sources files
|
||||
- ✨(ui) fix retour global ui
|
||||
|
||||
@@ -11,9 +11,20 @@ interface ThemeCustomization {
|
||||
translations?: Resource;
|
||||
}
|
||||
|
||||
export enum FeatureFlagState {
|
||||
ENABLED = 'enabled',
|
||||
DISABLED = 'disabled',
|
||||
DYNAMIC = 'dynamic',
|
||||
}
|
||||
|
||||
interface FeatureFlags {
|
||||
[key: string]: FeatureFlagState;
|
||||
}
|
||||
|
||||
export interface ConfigResponse {
|
||||
CRISP_WEBSITE_ID?: string;
|
||||
ENVIRONMENT: string;
|
||||
FEATURE_FLAGS: FeatureFlags;
|
||||
FRONTEND_CSS_URL?: string;
|
||||
FRONTEND_HOMEPAGE_FEATURE_ENABLED?: boolean;
|
||||
FRONTEND_THEME?: Theme;
|
||||
|
||||
@@ -3,6 +3,8 @@ import React, { useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Box, Icon, Text } from '@/components';
|
||||
import { FeatureFlagState, useConfig } from '@/core';
|
||||
import { useAnalytics } from '@/libs';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
import { AttachmentList } from './AttachmentList';
|
||||
@@ -44,6 +46,10 @@ export const InputChat = ({
|
||||
const [isDragActive, setIsDragActive] = useState(false);
|
||||
const { isDesktop, isMobile } = useResponsiveStore();
|
||||
const [currentSuggestionIndex, setCurrentSuggestionIndex] = useState(0);
|
||||
const { data: conf } = useConfig();
|
||||
const { isFeatureFlagActivated } = useAnalytics();
|
||||
const [fileUploadEnabled, setFileUploadEnabled] = useState(false);
|
||||
const [webSearchEnabled, setWebSearchEnabled] = useState(false);
|
||||
const [isResetting, setIsResetting] = useState(false);
|
||||
|
||||
const suggestions = [
|
||||
@@ -53,6 +59,29 @@ export const InputChat = ({
|
||||
t('Find recent news about...'),
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
if (!conf?.FEATURE_FLAGS) {
|
||||
setWebSearchEnabled(false);
|
||||
setFileUploadEnabled(false);
|
||||
return;
|
||||
}
|
||||
const isFeatureEnabled = (featureKey: string): boolean => {
|
||||
const configValue = conf.FEATURE_FLAGS[featureKey];
|
||||
if (!configValue) {
|
||||
return false;
|
||||
} else if (configValue === FeatureFlagState.DISABLED) {
|
||||
return false;
|
||||
} else if (configValue === FeatureFlagState.ENABLED) {
|
||||
return true;
|
||||
} else {
|
||||
return isFeatureFlagActivated(featureKey);
|
||||
}
|
||||
};
|
||||
|
||||
setWebSearchEnabled(isFeatureEnabled('web-search'));
|
||||
setFileUploadEnabled(isFeatureEnabled('document-upload'));
|
||||
}, [conf, isFeatureFlagActivated]);
|
||||
|
||||
useEffect(() => {
|
||||
if (messagesLength === 0) {
|
||||
const interval = setInterval(() => {
|
||||
@@ -140,7 +169,7 @@ export const InputChat = ({
|
||||
onSubmit={handleSubmit}
|
||||
onDragOver={(e) => {
|
||||
e.preventDefault();
|
||||
setIsDragActive(true);
|
||||
setIsDragActive(fileUploadEnabled);
|
||||
}}
|
||||
onDragLeave={(e) => {
|
||||
e.preventDefault();
|
||||
@@ -149,6 +178,9 @@ export const InputChat = ({
|
||||
onDrop={(e) => {
|
||||
e.preventDefault();
|
||||
setIsDragActive(false);
|
||||
if (!fileUploadEnabled) {
|
||||
return;
|
||||
}
|
||||
if (e.dataTransfer.files?.length) {
|
||||
setFiles((prev) => {
|
||||
const dt = new DataTransfer();
|
||||
@@ -337,6 +369,7 @@ export const InputChat = ({
|
||||
<Button
|
||||
size="small"
|
||||
type="button"
|
||||
disabled={!fileUploadEnabled}
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
aria-label={t('Add attach file')}
|
||||
className="c__button--neutral attach-file-button"
|
||||
@@ -355,6 +388,7 @@ export const InputChat = ({
|
||||
</Text>
|
||||
)}
|
||||
</Button>
|
||||
|
||||
{onToggleWebSearch && (
|
||||
<Box
|
||||
$margin={{ left: '4px' }}
|
||||
@@ -382,6 +416,7 @@ export const InputChat = ({
|
||||
<Button
|
||||
size="small"
|
||||
type="button"
|
||||
disabled={!webSearchEnabled}
|
||||
onClick={onToggleWebSearch}
|
||||
aria-label={t('Research on the web')}
|
||||
className="c__button--neutral research-web-button"
|
||||
|
||||
@@ -97,6 +97,13 @@ nextjs-portal {
|
||||
padding: 9px !important;
|
||||
}
|
||||
|
||||
.c__button--neutral.research-web-button:disabled,
|
||||
.c__button--neutral.attach-file-button:disabled {
|
||||
background-color: inherit !important;
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
|
||||
.c__button--neutral.action-chat-button .action-chat-button-icon,
|
||||
.c__button--neutral.research-web-button .c__button__icon span,
|
||||
.c__button--neutral.attach-file-button .c__button__icon span {
|
||||
|
||||
Reference in New Issue
Block a user