From 682a341e9abfafe45da273cccab67124a3597e61 Mon Sep 17 00:00:00 2001 From: Swapnil M Mane Date: Fri, 6 Dec 2024 16:04:29 +0530 Subject: [PATCH 1/3] docs: updated test AI plugin code, renamed the model --- .../src/DecorateContentEntryFormBind.tsx | 2 +- .../testPluginsAi/admin/src/SmartSeo.tsx | 2 +- .../extensions/testPluginsAi/api/package.json | 20 +++++++++---------- .../testPluginsAi/api/src/Article.ts | 9 +++------ 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/DecorateContentEntryFormBind.tsx b/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/DecorateContentEntryFormBind.tsx index 5c7e004..eae2c70 100644 --- a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/DecorateContentEntryFormBind.tsx +++ b/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/DecorateContentEntryFormBind.tsx @@ -24,7 +24,7 @@ export const DecorateContentEntryFormBind = useBind.createDecorator(baseHook => const { model } = useModel(); // Skip tracking for non-article models - if (model.modelId !== "article") { + if (model.modelId !== "article-smart-seo") { return baseHook(params); } diff --git a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/SmartSeo.tsx b/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/SmartSeo.tsx index b6cb9cf..f7a4a74 100644 --- a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/SmartSeo.tsx +++ b/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/SmartSeo.tsx @@ -120,7 +120,7 @@ export const SmartSeo = () => { name={"askAi"} before={"save"} element={} - modelIds={["article"]} + modelIds={["article-smart-seo"]} /> ); }; diff --git a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/package.json b/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/package.json index bec1dd7..12cecb0 100644 --- a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/package.json +++ b/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/package.json @@ -1,12 +1,12 @@ { - "name": "test-plugin-ai-api", - "main": "src/index.ts", - "keywords": [ - "webiny-extension", - "webiny-extension-type:api" - ], - "version": "1.0.0", - "dependencies": { - "@webiny/api-headless-cms": "5.41.1" - } + "name": "test-plugin-ai-api", + "main": "src/index.ts", + "keywords": [ + "webiny-extension", + "webiny-extension-type:api" + ], + "version": "1.0.0", + "dependencies": { + "@webiny/api-headless-cms": "5.41.1" + } } diff --git a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/src/Article.ts b/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/src/Article.ts index a313c05..5ec2f7f 100644 --- a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/src/Article.ts +++ b/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/src/Article.ts @@ -7,13 +7,10 @@ export const Article = () => { return [ // Defines a new Ungrouped content models group. createCmsModelPlugin({ - name: "Article", - modelId: "article", + name: "Article - Smart SEO", + modelId: "article-smart-seo", description: "Article content model for Smart SEO", - group: { - id: "673b06847c123c0002c9cfdc", - name: "Ungrouped AI 2" - }, + group: {id: "", name: ""}, fields: [ createModelField({ fieldId: "content", From 8890b4469915f5a68594e7be1c1229c841a3cad0 Mon Sep 17 00:00:00 2001 From: Swapnil M Mane Date: Wed, 11 Dec 2024 14:39:27 +0530 Subject: [PATCH 2/3] docs: restructured the smart-seo-open-ai plugin and added admin and api plugins (#170) Also added the code to create Article content model --- .../smartSeoOpenAi/{ => admin}/package.json | 2 +- .../src/DecorateContentEntryForm.tsx | 0 .../src/DecorateContentEntryFormBind.tsx | 0 .../{ => admin}/src/FieldTracker.tsx | 0 .../smartSeoOpenAi}/admin/src/SmartSeo.tsx | 2 +- .../{ => admin}/src/extractFromRichText.ts | 0 .../smartSeoOpenAi/{ => admin}/src/index.tsx | 0 .../smartSeoOpenAi/{ => admin}/tsconfig.json | 0 .../smartSeoOpenAi}/api/package.json | 2 +- .../smartSeoOpenAi}/api/src/Article.ts | 0 .../smartSeoOpenAi}/api/src/index.ts | 0 .../smartSeoOpenAi/api}/tsconfig.json | 0 .../src/DecorateContentEntryFormBind.tsx | 49 ------- .../smartSeoOpenAi/src/SmartSeo.tsx | 126 ------------------ headless-cms/smart-seo-open-ai/article.json | 1 - .../testPluginsAi/admin/package.json | 13 -- .../admin/src/DecorateContentEntryForm.tsx | 19 --- .../testPluginsAi/admin/src/FieldTracker.tsx | 69 ---------- .../admin/src/extractFromRichText.ts | 14 -- .../testPluginsAi/admin/src/index.tsx | 15 --- .../testPluginsAi/api/tsconfig.json | 4 - 21 files changed, 3 insertions(+), 313 deletions(-) rename headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/{ => admin}/package.json (84%) rename headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/{ => admin}/src/DecorateContentEntryForm.tsx (100%) rename headless-cms/{test-plugins-ai/5.41.x/extensions/testPluginsAi => smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi}/admin/src/DecorateContentEntryFormBind.tsx (100%) rename headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/{ => admin}/src/FieldTracker.tsx (100%) rename headless-cms/{test-plugins-ai/5.41.x/extensions/testPluginsAi => smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi}/admin/src/SmartSeo.tsx (98%) rename headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/{ => admin}/src/extractFromRichText.ts (100%) rename headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/{ => admin}/src/index.tsx (100%) rename headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/{ => admin}/tsconfig.json (100%) rename headless-cms/{test-plugins-ai/5.41.x/extensions/testPluginsAi => smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi}/api/package.json (84%) rename headless-cms/{test-plugins-ai/5.41.x/extensions/testPluginsAi => smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi}/api/src/Article.ts (100%) rename headless-cms/{test-plugins-ai/5.41.x/extensions/testPluginsAi => smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi}/api/src/index.ts (100%) rename headless-cms/{test-plugins-ai/5.41.x/extensions/testPluginsAi/admin => smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/api}/tsconfig.json (100%) delete mode 100644 headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/src/DecorateContentEntryFormBind.tsx delete mode 100644 headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/src/SmartSeo.tsx delete mode 100644 headless-cms/smart-seo-open-ai/article.json delete mode 100644 headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/package.json delete mode 100644 headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/DecorateContentEntryForm.tsx delete mode 100644 headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/FieldTracker.tsx delete mode 100644 headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/extractFromRichText.ts delete mode 100644 headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/index.tsx delete mode 100644 headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/tsconfig.json diff --git a/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/package.json b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/package.json similarity index 84% rename from headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/package.json rename to headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/package.json index 5f4b852..87b46d4 100644 --- a/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/package.json +++ b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/package.json @@ -1,5 +1,5 @@ { - "name": "smart-seo-open-ai", + "name": "smart-seo-open-ai-admin", "main": "src/index.tsx", "version": "1.0.0", "keywords": [ diff --git a/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/src/DecorateContentEntryForm.tsx b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/src/DecorateContentEntryForm.tsx similarity index 100% rename from headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/src/DecorateContentEntryForm.tsx rename to headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/src/DecorateContentEntryForm.tsx diff --git a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/DecorateContentEntryFormBind.tsx b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/src/DecorateContentEntryFormBind.tsx similarity index 100% rename from headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/DecorateContentEntryFormBind.tsx rename to headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/src/DecorateContentEntryFormBind.tsx diff --git a/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/src/FieldTracker.tsx b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/src/FieldTracker.tsx similarity index 100% rename from headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/src/FieldTracker.tsx rename to headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/src/FieldTracker.tsx diff --git a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/SmartSeo.tsx b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/src/SmartSeo.tsx similarity index 98% rename from headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/SmartSeo.tsx rename to headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/src/SmartSeo.tsx index f7a4a74..cb3f780 100644 --- a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/SmartSeo.tsx +++ b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/src/SmartSeo.tsx @@ -7,7 +7,7 @@ import { FieldWithValue, useFieldTracker } from "./FieldTracker"; import { extractRichTextHtml } from "./extractFromRichText"; import { useSnackbar } from "@webiny/app-admin"; -const OPENAI_API_KEY = String(process.env["REACT_APP_OPEN_AI_API_KEY"]); +const OPENAI_API_KEY = String(process.env["WEBINY_ADMIN_OPEN_AI_API_KEY"]); const openai = new OpenAI({ apiKey: OPENAI_API_KEY, dangerouslyAllowBrowser: true }); diff --git a/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/src/extractFromRichText.ts b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/src/extractFromRichText.ts similarity index 100% rename from headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/src/extractFromRichText.ts rename to headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/src/extractFromRichText.ts diff --git a/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/src/index.tsx b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/src/index.tsx similarity index 100% rename from headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/src/index.tsx rename to headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/src/index.tsx diff --git a/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/tsconfig.json b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/tsconfig.json similarity index 100% rename from headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/tsconfig.json rename to headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/admin/tsconfig.json diff --git a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/package.json b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/api/package.json similarity index 84% rename from headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/package.json rename to headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/api/package.json index 12cecb0..a6da1fd 100644 --- a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/package.json +++ b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/api/package.json @@ -1,5 +1,5 @@ { - "name": "test-plugin-ai-api", + "name": "smart-seo-open-ai-api", "main": "src/index.ts", "keywords": [ "webiny-extension", diff --git a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/src/Article.ts b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/api/src/Article.ts similarity index 100% rename from headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/src/Article.ts rename to headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/api/src/Article.ts diff --git a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/src/index.ts b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/api/src/index.ts similarity index 100% rename from headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/src/index.ts rename to headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/api/src/index.ts diff --git a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/tsconfig.json b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/api/tsconfig.json similarity index 100% rename from headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/tsconfig.json rename to headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/api/tsconfig.json diff --git a/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/src/DecorateContentEntryFormBind.tsx b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/src/DecorateContentEntryFormBind.tsx deleted file mode 100644 index 5c7e004..0000000 --- a/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/src/DecorateContentEntryFormBind.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import { useBind } from "@webiny/form"; -import { useModel, useModelField, useParentField } from "@webiny/app-headless-cms"; -import { useFieldTracker } from "./FieldTracker"; -import { useEffect } from "react"; - -/** - * Decorator `useBind` hook that integrates field tracking for models. - * In this example below we track rich-text fields and SEO-specific fields - * ("seoTitle", "seoDescription", "seoMetaTags") of article model. - * to trigger dynamic updates and interaction with external services. - * - * You can customise this decorator to track fields of other models or field types. - */ -export const DecorateContentEntryFormBind = useBind.createDecorator(baseHook => { - const seoFields = ["seoTitle", "seoDescription", "seoMetaTags"]; - - return params => { - try { - const { trackField } = useFieldTracker(); - - const { field } = useModelField(); - const parent = useParentField(); - - const { model } = useModel(); - - // Skip tracking for non-article models - if (model.modelId !== "article") { - return baseHook(params); - } - - const bind = baseHook(params); - - useEffect(() => { - // Track rich-text fields and SEO fields - if (field.type === "rich-text") { - trackField(field.label, field.type, params.name, bind.value, bind.onChange); - } - - if (seoFields.includes(field.fieldId) && !parent) { - trackField(field.label, field.fieldId, params.name, bind.value, bind.onChange); - } - }, [bind.value]); - - return bind; - } catch { - return baseHook(params); - } - }; -}); diff --git a/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/src/SmartSeo.tsx b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/src/SmartSeo.tsx deleted file mode 100644 index b6cb9cf..0000000 --- a/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/src/SmartSeo.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import React, { useState } from "react"; -import OpenAI from "openai"; -import { ReactComponent as MagicIcon } from "@material-design-icons/svg/round/school.svg"; -import { ContentEntryEditorConfig } from "@webiny/app-headless-cms"; -import { ButtonSecondary, ButtonIcon } from "@webiny/ui/Button"; -import { FieldWithValue, useFieldTracker } from "./FieldTracker"; -import { extractRichTextHtml } from "./extractFromRichText"; -import { useSnackbar } from "@webiny/app-admin"; - -const OPENAI_API_KEY = String(process.env["REACT_APP_OPEN_AI_API_KEY"]); - -const openai = new OpenAI({ apiKey: OPENAI_API_KEY, dangerouslyAllowBrowser: true }); - -const prompt = `You will be provided with one or more paragraphs of HTML, and you need to extract a SEO optimized page title, a page summary, and up to 5 keywords. Response should be returned as a plain JSON object, with "title" field for the page title, "description" field for page summary, and "keywords" field as an array of keywords.`; - -const { Actions } = ContentEntryEditorConfig; - -const populateSeoTitle = (fields: FieldWithValue[], value: string) => { - const field = fields.find(field => field.type === "seoTitle"); - if (!field) { - return; - } - - field.onChange(value); -}; - -const populateSeoDescription = (fields: FieldWithValue[], value: string) => { - const field = fields.find(field => field.type === "seoDescription"); - if (!field) { - return; - } - - field.onChange(value); -}; - -interface Tag { - tagName: string; - tagValue: string; -} - -const populateSeoKeywords = (fields: FieldWithValue[], keywords: string[]) => { - const field = fields.find(field => field.type === "seoMetaTags"); - if (!field) { - console.warn("no meta tags field!"); - return; - } - const tags: Tag[] = Array.isArray(field.value) ? field.value : []; - const tagsWithoutKeywords = tags.filter(tag => tag.tagName !== "keywords"); - - field.onChange([ - ...tagsWithoutKeywords, - { tagName: "keywords", tagValue: keywords.join(", ") } - ]); -}; - -/** - * A button component to trigger OpenAI's GPT model to generate SEO fields. - * Extracts rich-text content, sends it to GPT, and updates the form fields with the AI's suggestions. - */ -const GetSeoData = () => { - const { showSnackbar } = useSnackbar(); - const [loading, setLoading] = useState(false); - const { fields } = useFieldTracker(); - - const askChatGpt = async () => { - let response; - setLoading(true); - try { - response = await openai.chat.completions.create({ - model: "gpt-3.5-turbo", - messages: [ - { - role: "system", - content: prompt - }, - { - role: "user", - content: extractRichTextHtml(fields).join("\n") - } - ], - temperature: 0.5, - max_tokens: 128, - top_p: 1 - }); - } catch (e) { - console.log(e); - } - setLoading(false); - - console.log("ChatGPT response", response); - try { - // const seo = { - // title: "Node.js, Yarn, and AWS Setup Guide for Webiny", - // description: - // "Learn how to set up Node.js, yarn, and AWS account and user credentials for deploying Webiny. Make sure you have the required versions installed.", - // keywords: ["Node.js", "Yarn", "AWS", "Webiny", "setup"] - // }; - const seo = JSON.parse(response?.choices[0].message.content as string); - console.log("parsed response", seo); - populateSeoTitle(fields, seo.title); - populateSeoDescription(fields, seo.description); - populateSeoKeywords(fields, seo.keywords); - showSnackbar("Success! We've populated the SEO fields with the recommended values."); - } catch (e) { - console.log(e); - showSnackbar("We were unable to get a recommendation from AI at this point."); - } - }; - - return ( - askChatGpt()} disabled={loading}> - } /> AI-optimized SEO - - ); -}; - -export const SmartSeo = () => { - return ( - } - modelIds={["article"]} - /> - ); -}; diff --git a/headless-cms/smart-seo-open-ai/article.json b/headless-cms/smart-seo-open-ai/article.json deleted file mode 100644 index 11b4bd4..0000000 --- a/headless-cms/smart-seo-open-ai/article.json +++ /dev/null @@ -1 +0,0 @@ -{"groups":[{"id":"673b06847c123c0002c9cfdc","name":"Ungrouped","slug":"ungrouped","description":"A generic content model group","icon":"fas/star"}],"models":[{"modelId":"article","name":"Article","group":"673b06847c123c0002c9cfdc","singularApiName":"Article","pluralApiName":"Articles","fields":[{"multipleValues":false,"listValidation":[],"settings":{},"renderer":{"name":"text-input","settings":{}},"helpText":null,"predefinedValues":{"enabled":false,"values":[]},"label":"SEO - Title","type":"text","tags":[],"placeholderText":null,"id":"fatgp2e8","validation":[],"storageId":"text@fatgp2e8","fieldId":"seoTitle"},{"multipleValues":false,"listValidation":[],"settings":{},"renderer":{"name":"long-text-text-area","settings":{}},"helpText":null,"predefinedValues":{"enabled":false,"values":[]},"label":"SEO - Description","type":"long-text","tags":[],"placeholderText":null,"id":"hmm8rn13","validation":[],"storageId":"long-text@hmm8rn13","fieldId":"seoDescription"},{"multipleValues":false,"listValidation":[],"settings":{},"renderer":{"name":"lexical-text-input","settings":{}},"helpText":null,"predefinedValues":{"enabled":false,"values":[]},"label":"Content","type":"rich-text","tags":[],"placeholderText":null,"id":"fpdv3c7m","validation":[],"storageId":"rich-text@fpdv3c7m","fieldId":"content"},{"multipleValues":true,"listValidation":[],"settings":{"fields":[{"renderer":{"name":"text-input"},"label":"Tag Name","id":"5u81n61u","type":"text","validation":[],"fieldId":"tagName","storageId":"text@5u81n61u"},{"renderer":{"name":"text-input"},"label":"Tag Value","id":"4jhcwcq2","type":"text","validation":[],"fieldId":"tagValue","storageId":"text@4jhcwcq2"}],"layout":[["5u81n61u"],["4jhcwcq2"]]},"renderer":{"name":"objects","settings":{}},"helpText":null,"predefinedValues":{"enabled":false,"values":[]},"label":"SEO - Meta tags","type":"object","tags":[],"placeholderText":null,"id":"ttwf5mz2","validation":[],"storageId":"object@ttwf5mz2","fieldId":"seoMetaTags"}],"layout":[["fpdv3c7m"],["fatgp2e8"],["hmm8rn13"],["ttwf5mz2"]],"titleFieldId":"seoTitle","descriptionFieldId":"seoDescription","tags":["type:model"]}]} diff --git a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/package.json b/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/package.json deleted file mode 100644 index 7669830..0000000 --- a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "test-plugin-ai-admin", - "main": "src/index.tsx", - "version": "1.0.0", - "keywords": [ - "webiny-extension", - "webiny-extension-type:admin" - ], - "dependencies": { - "openai": "^4.33.0", - "react": "18.2.0" - } -} diff --git a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/DecorateContentEntryForm.tsx b/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/DecorateContentEntryForm.tsx deleted file mode 100644 index 4994de4..0000000 --- a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/DecorateContentEntryForm.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from "react"; -import { ContentEntryForm } from "@webiny/app-headless-cms/admin/components/ContentEntryForm/ContentEntryForm"; -import { FieldTracker } from "./FieldTracker"; - -/** - * Decorate the ContentEntryForm with a FieldTracker. - * FieldTracker monitors changes in form fields, enabling dynamic updates - * and interaction with external services like OpenAI for SEO recommendations. - */ -export const DecorateContentEntryForm = ContentEntryForm.createDecorator(Original => { - return function ContentEntryForm(props) { - return ( - // Use the FieldTracker component to track changes in the form fields - - - - ); - }; -}); diff --git a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/FieldTracker.tsx b/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/FieldTracker.tsx deleted file mode 100644 index dc6a3ce..0000000 --- a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/FieldTracker.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import React, { Dispatch, SetStateAction, useCallback, useMemo, useState } from "react"; - -interface FieldTrackerProps { - children: React.ReactNode; -} - -export interface FieldWithValue { - value: any; - path: string; - type: string; - label: string; - onChange: (value: any) => void; -} - -interface FieldTrackerContext { - fields: FieldWithValue[]; - setFields: Dispatch>; - trackField: ( - label: string, - type: string, - path: string, - value: any, - onChange: (value: any) => void - ) => void; -} - -/** - * Context and provider for tracking changes in content entry fields. - * Enables monitoring and managing form field state for dynamic behavior. - */ -const FieldTrackerContext = React.createContext(undefined); - -export const FieldTracker = ({ children }: FieldTrackerProps) => { - const [fields, setFields] = useState([]); - - const trackField = useCallback((label:string, type:string, path:string, value:any, onChange: any) => { - setFields(fields => { - const newValue: FieldWithValue = { - label, - type, - path, - value, - onChange - }; - - const index = fields.findIndex(trackedField => trackedField.path === path); - - if (index > -1) { - return [...fields.slice(0, index), newValue, ...fields.slice(index + 1)]; - } - - return [...fields, newValue]; - }); - }, []); - - const context = useMemo(() => ({ fields, setFields, trackField }), [fields]); - - return {children}; -}; - -export const useFieldTracker = () => { - const context = React.useContext(FieldTrackerContext); - - if (!context) { - throw new Error(`FieldTracker context is missing in the component hierarchy!`); - } - - return context; -}; diff --git a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/extractFromRichText.ts b/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/extractFromRichText.ts deleted file mode 100644 index 190108a..0000000 --- a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/extractFromRichText.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createLexicalStateTransformer } from "@webiny/lexical-converter"; -import { FieldWithValue } from "./FieldTracker"; - -const transformer = createLexicalStateTransformer(); - -/** - * Extracts HTML from rich-text (lexical content) fields. - * Filters fields of type "rich-text" and converts their content to HTML for further processing. We will pass this HTML content to OpenAI. - */ -export const extractRichTextHtml = (fields: FieldWithValue[]) => { - return fields - .filter(field => field.type === "rich-text" && !!field.value) - .map(field => transformer.toHtml(field.value)); -}; \ No newline at end of file diff --git a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/index.tsx b/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/index.tsx deleted file mode 100644 index b68e263..0000000 --- a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/admin/src/index.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from "react"; -import { ContentEntryEditorConfig } from "@webiny/app-headless-cms"; -import { DecorateContentEntryForm } from "./DecorateContentEntryForm"; -import { DecorateContentEntryFormBind} from "./DecorateContentEntryFormBind"; -import { SmartSeo } from "./SmartSeo"; - -export const Extension = () => { - return <>{/* Your code here. */} - - - - - - ; -}; diff --git a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/tsconfig.json b/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/tsconfig.json deleted file mode 100644 index 596e2cf..0000000 --- a/headless-cms/test-plugins-ai/5.41.x/extensions/testPluginsAi/api/tsconfig.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "include": ["src"] -} From 59f44c564e83e9c453819882209e8946b5069b79 Mon Sep 17 00:00:00 2001 From: Swapnil M Mane Date: Wed, 11 Dec 2024 14:49:56 +0530 Subject: [PATCH 3/3] chore: removed incorrect comment --- .../5.41.x/extensions/smartSeoOpenAi/api/src/Article.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/api/src/Article.ts b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/api/src/Article.ts index 5ec2f7f..f294bcd 100644 --- a/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/api/src/Article.ts +++ b/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/api/src/Article.ts @@ -5,7 +5,6 @@ import { export const Article = () => { return [ - // Defines a new Ungrouped content models group. createCmsModelPlugin({ name: "Article - Smart SEO", modelId: "article-smart-seo",