diff --git a/memory-bank/implementation-checklist.md b/memory-bank/implementation-checklist.md index fccb517d..569b7d48 100644 --- a/memory-bank/implementation-checklist.md +++ b/memory-bank/implementation-checklist.md @@ -29,6 +29,22 @@ - [x] Verified all imports and dependencies are correctly resolved - [x] Build completed with no compilation errors +### ✅ Feature Toggle Movement +- **Task**: Move FeatureCard toggle from AssetMeta component to main asset information area next to language selector +- **Status**: COMPLETED +- **Details**: + - Removed FeatureCard component from AssetMeta.js + - Added feature toggle functionality directly to ComposeAsset.js + - Integrated toggle next to language selector in the main badge area + - Added proper state management (isFeatured, featureLoading) + - Added handleToggleFeature function with API integration + - Added proper initialization when asset loads + - Maintained same functionality and styling as original FeatureCard +- **Files Modified**: + - `src/app/views/media/components/AssetMeta.js` - Removed FeatureCard component and its usage + - `src/app/views/media/components/ComposeAsset.js` - Added feature toggle functionality and UI +- **Location**: The toggle now appears in the flex container next to the language badge at: `Grid item xs={12} sm={8} > div.flex > div (after language selector)` + ## 📋 Implementation Details ### Navigation Structure: @@ -66,4 +82,10 @@ The implementation is now complete and ready for testing. The new navigation str 3. Perform bulk operations on both types of data 4. Filter and search within each section independently -All code follows the existing patterns and conventions used throughout the application. \ No newline at end of file +All code follows the existing patterns and conventions used throughout the application. + +## Notes +- Both files pass syntax validation +- Feature toggle maintains same API integration and toast notifications +- Uses appropriate Material-UI components (Switch, FormControlLabel, Tooltip) +- Properly integrated with existing state management \ No newline at end of file diff --git a/src/app/views/media/components/AssetMeta.js b/src/app/views/media/components/AssetMeta.js index 494666aa..af69a95a 100644 --- a/src/app/views/media/components/AssetMeta.js +++ b/src/app/views/media/components/AssetMeta.js @@ -900,55 +900,12 @@ const TestCard = ({ asset, onAction }) => ; -const FeatureCard = ({ asset, onChange }) => { - const [isFeatured, setIsFeatured] = useState(asset.feature || false); - const [loading, setLoading] = useState(false); - - const handleToggleFeature = async () => { - setLoading(true); - try { - const updatedAsset = await API.registry().updateAsset(asset.slug, { feature: !isFeatured }); - - if (updatedAsset.status === 200) { - setIsFeatured(!isFeatured); - onChange({ feature: !isFeatured }); - toast.success(`Asset ${!isFeatured ? "marked as featured" : "removed from featured"} successfully!`); - } else { - toast.error("Error updating feature status."); - } - } catch (error) { - toast.error("Failed to update feature status."); - } - setLoading(false); - }; - - return ( - -

Feature Asset

- - - } - label={isFeatured ? "Featured" : "Not Featured"} - /> - -
- ); -}; - const AssetMeta = ({ asset, onAction, onChange }) => { const classes = useStyles(); return ( <> onAction(action)} onChange={a => onChange(a)} /> - onChange(a)} /> onAction(action)} onChange={a => onChange(a)} /> onChange(a)} /> onChange(a)} onAction={(action) => onAction(action)} /> diff --git a/src/app/views/media/components/ComposeAsset.js b/src/app/views/media/components/ComposeAsset.js index 5e5f984d..a370f77b 100644 --- a/src/app/views/media/components/ComposeAsset.js +++ b/src/app/views/media/components/ComposeAsset.js @@ -10,6 +10,9 @@ import { TextField, Card, MenuItem, + Switch, + FormControlLabel, + Tooltip, } from "@material-ui/core"; import { Base64 } from "js-base64"; import { Breadcrumb } from "matx"; @@ -189,6 +192,8 @@ const ComposeAsset = () => { now.toISOString().replace("Z", "").padEnd(23, "0") + "Z"; const [dirty, setDirty] = useState(false); + const [isFeatured, setIsFeatured] = useState(false); + const [featureLoading, setFeatureLoading] = useState(false); const handleMarkdownChange = () => { if (asset.updated_at != asset.last_synched_at) { @@ -196,6 +201,23 @@ const ComposeAsset = () => { } }; + const handleToggleFeature = async () => { + setFeatureLoading(true); + try { + const resp = await bc.registry().updateAsset(asset.slug, { feature: !isFeatured }); + + if (resp.status === 200) { + setIsFeatured(!isFeatured); + setAsset({ ...asset, feature: !isFeatured }); + toast.success(`Asset ${!isFeatured ? "marked as featured" : "removed from featured"} successfully!`); + } else { + toast.error("Error updating feature status."); + } + } catch (error) { + toast.error("Failed to update feature status."); + } + setFeatureLoading(false); + }; const partialUpdateAsset = async (_slug, newAsset) => { if (isCreating) { @@ -232,6 +254,7 @@ const ComposeAsset = () => { const resp = await bc.registry().getAsset(asset_slug); if (resp.status >= 200 && resp.status < 300) { setAsset({ ...resp.data, lang: resp.data.lang || "us" }); + setIsFeatured(resp.data.feature || false); } else throw Error("Asset could not be retrieved"); await getAssetContent(asset_slug); @@ -548,6 +571,26 @@ const ComposeAsset = () => { `Uknown language ${asset.lang}` )} +
+ + + } + label={ + + {isFeatured ? "Featured" : "Not Featured"} + + } + /> + +
{errors["asset_type"] && ( {errors["asset_type"]}