11/**
2- * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
2+ * Copyright (c) 2025-2026 , WSO2 LLC. (https://www.wso2.com).
33 *
44 * WSO2 LLC. licenses this file to you under the Apache License,
55 * Version 2.0 (the "License"); you may not use this file except
@@ -34,84 +34,16 @@ import ListItemText from "@oxygen-ui/react/ListItemText";
3434import Stack from "@oxygen-ui/react/Stack" ;
3535import Switch from "@oxygen-ui/react/Switch" ;
3636import Typography from "@oxygen-ui/react/Typography" ;
37- import { useRequiredScopes } from "@wso2is/access-control" ;
38- import { updateCDSConfig } from "@wso2is/admin.cds.v1/api/config" ;
39- import useCDSConfig from "@wso2is/admin.cds.v1/hooks/use-config" ;
40- import useFeatureGate from "@wso2is/admin.feature-gate.v1/hooks/use-feature-gate" ;
41- import { AlertLevels , FeatureAccessConfigInterface , IdentifiableComponentInterface } from "@wso2is/core/models" ;
42- import { addAlert } from "@wso2is/core/store" ;
43- import React , { ChangeEvent , FunctionComponent , ReactElement , useEffect , useMemo , useState } from "react" ;
37+ import { IdentifiableComponentInterface } from "@wso2is/core/models" ;
38+ import React , { ChangeEvent , FunctionComponent , ReactElement } from "react" ;
4439import { useTranslation } from "react-i18next" ;
45- import { useDispatch , useSelector } from "react-redux" ;
46- import NewCDSFeatureImage from "../../assets/illustrations/preview-features/new-cds-feature.png" ;
47- import { AppConstants } from "../../constants/app-constants" ;
48- import { history } from "../../helpers/history" ;
49- import { AppState } from "../../store" ;
50- import "./feature-preview-modal.scss" ;
51-
52- /** Added or removed as a system application when CDS is toggled. */
53- const CDS_CONSOLE_APP :string = "CONSOLE" ;
40+ import { PreviewFeaturesListInterface , usePreviewFeatures } from "../../hooks/use-preview-features" ;
5441
5542interface FeaturePreviewModalPropsInterface extends IdentifiableComponentInterface {
5643 open : boolean ;
5744 onClose : ( ) => void ;
5845}
5946
60- /**
61- * Preview features list interface.
62- */
63- interface PreviewFeaturesListInterface {
64- /**
65- * Feature action.
66- */
67- action ?: string ;
68-
69- /**
70- * Feature name.
71- */
72- name : string ;
73-
74- /**
75- * React component to be rendered
76- */
77- component ?: ReactElement ;
78-
79- /**
80- * Feature description.
81- */
82- description : string ;
83-
84- /**
85- * Feature id.
86- */
87- id : string ;
88-
89- /**
90- * Feature image.
91- */
92- image ?: string ;
93-
94- /**
95- * Whether the feature is enabled
96- */
97- enabled ?: boolean ;
98-
99- /**
100- * Feature value.
101- */
102- value : string ;
103-
104- /**
105- * Required scopes to access the feature. If not provided, the feature will be accessible to all users.
106- */
107- requiredScopes ?: string [ ] ;
108-
109- message ?: {
110- type : "info" | "warning" | "error" ;
111- content : string ;
112- } ;
113- }
114-
11547/**
11648 * Feature preview modal component.
11749 *
@@ -123,129 +55,19 @@ const FeaturePreviewModal: FunctionComponent<FeaturePreviewModalPropsInterface>
12355 onClose,
12456 open
12557} : FeaturePreviewModalPropsInterface ) : ReactElement => {
126-
12758 const { t } = useTranslation ( ) ;
128- const dispatch : any = useDispatch ( ) ;
129- const { selectedPreviewFeatureToShow } = useFeatureGate ( ) ;
130-
131- const cdsFeatureConfig : FeatureAccessConfigInterface = useSelector (
132- ( state : AppState ) => state ?. config ?. ui ?. features ?. customerDataService
133- ) ;
134-
13559 const {
136- data : cdsConfig ,
137- mutate : mutateCDSConfig
138- } = useCDSConfig ( open && ( cdsFeatureConfig ?. enabled ?? false ) ) ;
139-
140- const hasCDSScopes : boolean = useRequiredScopes (
141- cdsFeatureConfig ?. scopes ?. update
142- ) ;
143-
144-
145- const previewFeaturesList : PreviewFeaturesListInterface [ ] = useMemo ( ( ) => ( [
146- {
147- action : t ( "customerDataService:common.featurePreview.action" ) ,
148- description : t ( "customerDataService:common.featurePreview.description" ) ,
149- enabled : cdsConfig ?. cds_enabled ,
150- id : "customer-data-service" ,
151- image : NewCDSFeatureImage ,
152- message : {
153- content : t ( "customerDataService:common.featurePreview.message" ) ,
154- type : "warning" as const
155- } ,
156- name : t ( "customerDataService:common.featurePreview.name" ) ,
157- requiredScopes : cdsFeatureConfig ?. scopes ?. update ,
158- value : "CDS.Enable"
159- }
160- ] . filter ( Boolean ) ) , [ cdsConfig , cdsFeatureConfig , t ] ) ;
161-
162- const accessibleFeatures : PreviewFeaturesListInterface [ ] = useMemo ( ( ) => (
163- previewFeaturesList . filter ( ( feature : PreviewFeaturesListInterface ) => {
164- if ( feature . id === "customer-data-service" ) {
165- return hasCDSScopes && ! ! cdsFeatureConfig ?. enabled ;
166- }
167-
168- return true ;
169- } )
170- ) , [ previewFeaturesList , hasCDSScopes , cdsFeatureConfig ?. enabled ] ) ;
171-
172- const [ selectedFeatureIndex , setSelectedFeatureIndex ] = useState ( 0 ) ;
173-
174- const selected : PreviewFeaturesListInterface = useMemo (
175- ( ) => accessibleFeatures [ selectedFeatureIndex ] ,
176- [ selectedFeatureIndex , accessibleFeatures ]
177- ) ;
178-
179- useEffect ( ( ) => {
180- const activePreviewFeatureIndex : number = accessibleFeatures . findIndex (
181- ( feature : PreviewFeaturesListInterface ) => feature ?. id === selectedPreviewFeatureToShow
182- ) ;
183-
184- setSelectedFeatureIndex ( activePreviewFeatureIndex > 0 ? activePreviewFeatureIndex : 0 ) ;
185- } , [ selectedPreviewFeatureToShow ] ) ;
186-
187- const handleClose = ( ) => {
60+ accessibleFeatures,
61+ handlePageRedirection,
62+ handleToggleChange,
63+ selected,
64+ setSelectedFeatureIndex
65+ } = usePreviewFeatures ( ) ;
66+
67+ const handleClose : ( ) => void = ( ) : void => {
18868 onClose ( ) ;
18969 } ;
19070
191- const handlePageRedirection = ( actionId : string ) => {
192- switch ( actionId ) {
193- case "customer-data-service" :
194- return history . push ( AppConstants . getPaths ( ) . get ( "PROFILES" ) ) ;
195- default :
196- return ;
197- }
198- } ;
199-
200- const handleToggleChange = async ( e : ChangeEvent < HTMLInputElement > , actionId : string ) => {
201- const isChecked : boolean = e . target . checked ;
202-
203- switch ( actionId ) {
204- case "customer-data-service" :
205- await handleCDSToggle ( isChecked ) ;
206-
207- break ;
208-
209- default :
210- break ;
211- }
212- } ;
213-
214- /**
215- * Handles CDS enable/disable via PATCH.
216- *
217- * Enabling → set cds_enabled: true; if system_applications is empty, seed it with ["CONSOLE"].
218- * Disabling → set cds_enabled: false; remove "CONSOLE" from system_applications (leave others intact).
219- */
220- const handleCDSToggle = async ( enable : boolean ) : Promise < void > => {
221- const currentApps : string [ ] = cdsConfig ?. system_applications ?? [ ] ;
222-
223- let nextApps : string [ ] ;
224-
225- if ( enable ) {
226- nextApps = currentApps . length === 0
227- ? [ CDS_CONSOLE_APP ]
228- : currentApps ;
229- } else {
230- nextApps = currentApps . filter ( ( app : string ) => app !== CDS_CONSOLE_APP ) ;
231- }
232-
233- try {
234- await updateCDSConfig ( {
235- cds_enabled : enable ,
236- system_applications : nextApps
237- } ) ;
238-
239- mutateCDSConfig ( ) ;
240- } catch ( error ) {
241- dispatch ( addAlert ( {
242- description : t ( "customerDataService:common.featurePreview.updateError" ) ,
243- level : AlertLevels . ERROR ,
244- message : t ( "common:error" )
245- } ) ) ;
246- }
247- } ;
248-
24971 return (
25072 < Dialog
25173 onClose = { handleClose }
0 commit comments