ai plugin modal
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "magico-pagebuilder",
|
"name": "magico-pagebuilder",
|
||||||
"version": "0.0.26",
|
"version": "0.0.27",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
111
src/components/AIModal.vue
Normal file
111
src/components/AIModal.vue
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
<template>
|
||||||
|
<MagicoModal v-model="modal" title="Generuj AI">
|
||||||
|
<div class="p-1">
|
||||||
|
<h5>O czym chcesz napisać?</h5>
|
||||||
|
<textarea
|
||||||
|
class="form-control mb-3"
|
||||||
|
rows="5"
|
||||||
|
v-model="text"
|
||||||
|
placeholder="Napisz krótki opis, aby AI mogło wygenerować treść."
|
||||||
|
></textarea>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Ilość znaków</label>
|
||||||
|
<select v-model="count" class="form-select">
|
||||||
|
<option value="500">500</option>
|
||||||
|
<option value="1000">1000</option>
|
||||||
|
<option value="2000">2000</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="text-center mt-3">
|
||||||
|
<button :disabled="loader" @click="generate" class="btn btn-primary">
|
||||||
|
<span class="spinner-border spinner-border-sm me-2" v-if="loader"></span>
|
||||||
|
Generuj
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</MagicoModal>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { onMounted, ref, watch } from 'vue'
|
||||||
|
const modal = ref(true)
|
||||||
|
import axios from 'axios';
|
||||||
|
import MagicoModal from './MagicoModal.vue'
|
||||||
|
// import axios from '@/api/sync-axios'
|
||||||
|
const props = defineProps({
|
||||||
|
product: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
type: Object,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
lang: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
callback: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const text = ref('')
|
||||||
|
const offer = ref({})
|
||||||
|
const loader = ref(false)
|
||||||
|
onMounted(() => {
|
||||||
|
offer.value = props.modelValue
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(newValue) => {
|
||||||
|
offer.value = newValue
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
const count = ref(500)
|
||||||
|
const emit = defineEmits(['offerGenerated', 'update:modelValue'])
|
||||||
|
function generate() {
|
||||||
|
const prompt = `Twoim zadaniem jest stworzenie opisu.
|
||||||
|
Do "content" wstaw tekst w formacie HTML, jako akapity dla edytora WYSIWYG na podstawie dostarczonej treści na maksymalnie ${count.value} znaków.
|
||||||
|
Odpowiedź wygeneruj w języku określanym przez kod kraju: pl.
|
||||||
|
Wynik zwróć jako czysty JSON bez dodatkowego formatowania, bez używania \`\`\`json i \`\`\`, bez używania \`\`\`html i \`\`\`:
|
||||||
|
{
|
||||||
|
"content": ""
|
||||||
|
}`
|
||||||
|
const query = `${text.value}`
|
||||||
|
loader.value = true
|
||||||
|
axios
|
||||||
|
.post(
|
||||||
|
'https://ai.magico.pro/api/v1/message',
|
||||||
|
{ prompt, query },
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: 'Bearer ' + localStorage.getItem('access_token')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then((response) => {
|
||||||
|
loader.value = false
|
||||||
|
modal.value = false // Close the modal after generation
|
||||||
|
// Handle the response, e.g., display the generated content
|
||||||
|
const jsonText = response.data.data.choices[0].message.content
|
||||||
|
const jsonData = JSON.parse(jsonText)
|
||||||
|
console.log('Generated Offer Data:', jsonData)
|
||||||
|
emit('update:modelValue', offer.value)
|
||||||
|
props.callback(jsonData)
|
||||||
|
// Assuming you want to do something with the generated data
|
||||||
|
// modal.value = false; // Close the modal after generation
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Błąd podczas generowania oferty:', error)
|
||||||
|
alert('Wystąpił błąd podczas generowania oferty.')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function setFeatureValue(featureName, value) {
|
||||||
|
const feature = offer.value.features.find((f) => f.feature_name === featureName)
|
||||||
|
if (feature) {
|
||||||
|
feature.feature_value = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -90,9 +90,7 @@ export default {
|
|||||||
text: '',
|
text: '',
|
||||||
name: 'core_section_textarea',
|
name: 'core_section_textarea',
|
||||||
vtinymce: Object.assign(tinymceConfig, {
|
vtinymce: Object.assign(tinymceConfig, {
|
||||||
setup: function (e) {
|
|
||||||
console.log(e)
|
|
||||||
},
|
|
||||||
file_picker_callback: (callback) => {
|
file_picker_callback: (callback) => {
|
||||||
if (this.$filechooser) {
|
if (this.$filechooser) {
|
||||||
this.$filechooser.open({
|
this.$filechooser.open({
|
||||||
|
|||||||
54
src/components/tinymce/ai.js
Normal file
54
src/components/tinymce/ai.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
export function addAI(editor) {
|
||||||
|
editor.ui.registry.addButton('ai_button', {
|
||||||
|
text: 'Wygeneruj treść AI',
|
||||||
|
onAction: async function () {
|
||||||
|
open({
|
||||||
|
callback: (data) => {
|
||||||
|
editor.setContent(data.content || '<p>Brak treści</p>')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// const count = 1000
|
||||||
|
// const lang = 'pl'
|
||||||
|
// const prompt = `Twoim zadaniem jest stworzenie nowego wpisu na stronę www na podstawie dostarczonej treści strony.
|
||||||
|
// Do "content" wstaw tekst w formacie HTML, jako akapity dla edytora WYSIWYG na podstawie dostarczonej treści na maksymalnie ${count} znaków.
|
||||||
|
// Metatagi wygeneruj na podstawie wygenerowanej przez ciebie treści.
|
||||||
|
// Odpowiedź wygeneruj w języku określanym przez kod kraju: "${lang}".
|
||||||
|
// Wynik zwróć jako czysty JSON bez dodatkowego formatowania, bez używania \`\`\`json i \`\`\`, bez używania \`\`\`html i \`\`\`:
|
||||||
|
// {
|
||||||
|
// "title": "",
|
||||||
|
// "page_title": "",
|
||||||
|
// "meta_description": "",
|
||||||
|
// "meta_keywords": "",
|
||||||
|
// "og_title": "",
|
||||||
|
// "og_description": "",
|
||||||
|
// "content": ""
|
||||||
|
// }`
|
||||||
|
|
||||||
|
// // Tu możesz wysłać zapytanie do swojego endpointa lub OpenAI
|
||||||
|
// const response = await fetch('/api/generate', {
|
||||||
|
// method: 'POST',
|
||||||
|
// headers: { 'Content-Type': 'application/json' },
|
||||||
|
// body: JSON.stringify({ prompt })
|
||||||
|
// })
|
||||||
|
|
||||||
|
// const data = await response.json()
|
||||||
|
// editor.setContent(data.content || '<p>Brak treści</p>')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
import { createApp, h } from 'vue'
|
||||||
|
import AIModal from '../AIModal.vue'
|
||||||
|
|
||||||
|
export function open(props = {}) {
|
||||||
|
const app = createApp({
|
||||||
|
render: () => h(AIModal, props)
|
||||||
|
})
|
||||||
|
|
||||||
|
const mountNode = document.createElement('div')
|
||||||
|
document.body.appendChild(mountNode)
|
||||||
|
app.mount(mountNode)
|
||||||
|
|
||||||
|
return app
|
||||||
|
}
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
|
import { addAI } from './ai'
|
||||||
export default {
|
export default {
|
||||||
autoresize_max_height: window.innerHeight - window.innerHeight / 4,
|
autoresize_max_height: window.innerHeight - window.innerHeight / 4,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
selector: "textarea.wysiwyg",
|
selector: 'textarea.wysiwyg',
|
||||||
language: "pl",
|
language: 'pl',
|
||||||
language_url: 'https://cdn.magico.pl/tinymce/langs/pl.js',
|
language_url: 'https://cdn.magico.pl/tinymce/langs/pl.js',
|
||||||
forced_root_block: "p",
|
forced_root_block: 'p',
|
||||||
entity_encoding: 'named',
|
entity_encoding: 'named',
|
||||||
entities: '160,nbsp,38,amp,60,lt,62,gt',
|
entities: '160,nbsp,38,amp,60,lt,62,gt',
|
||||||
valid_elements: '*[*]',
|
valid_elements: '*[*]',
|
||||||
@@ -19,6 +20,9 @@ export default {
|
|||||||
promotion: false,
|
promotion: false,
|
||||||
visualblocks_default_state: true,
|
visualblocks_default_state: true,
|
||||||
visualchars_default_state: false,
|
visualchars_default_state: false,
|
||||||
|
setup(editor) {
|
||||||
|
addAI(editor)
|
||||||
|
},
|
||||||
formats: {
|
formats: {
|
||||||
mainparagraph: {
|
mainparagraph: {
|
||||||
inline: 'span',
|
inline: 'span',
|
||||||
@@ -42,51 +46,69 @@ export default {
|
|||||||
classes: 'default_button_span'
|
classes: 'default_button_span'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
style_formats: [{
|
style_formats: [
|
||||||
|
{
|
||||||
title: 'Headers',
|
title: 'Headers',
|
||||||
items: [{
|
items: [
|
||||||
|
{
|
||||||
title: 'h1',
|
title: 'h1',
|
||||||
block: 'h1'
|
block: 'h1'
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
title: 'h2',
|
title: 'h2',
|
||||||
block: 'h2'
|
block: 'h2'
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
title: 'h3',
|
title: 'h3',
|
||||||
block: 'h3'
|
block: 'h3'
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
title: 'h4',
|
title: 'h4',
|
||||||
block: 'h4'
|
block: 'h4'
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
title: 'h5',
|
title: 'h5',
|
||||||
block: 'h5'
|
block: 'h5'
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
title: 'h6',
|
title: 'h6',
|
||||||
block: 'h6'
|
block: 'h6'
|
||||||
}]
|
}
|
||||||
}, {
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
title: 'Blocks',
|
title: 'Blocks',
|
||||||
items: [{
|
items: [
|
||||||
|
{
|
||||||
title: 'Główny akapit',
|
title: 'Główny akapit',
|
||||||
format: 'mainparagraph'
|
format: 'mainparagraph'
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
title: 'LinkURL - 1',
|
title: 'LinkURL - 1',
|
||||||
format: 'firstlink'
|
format: 'firstlink'
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
title: 'LinkURL - 2',
|
title: 'LinkURL - 2',
|
||||||
format: 'secondlink'
|
format: 'secondlink'
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
title: 'p',
|
title: 'p',
|
||||||
block: 'p'
|
block: 'p'
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
title: 'div',
|
title: 'div',
|
||||||
block: 'div'
|
block: 'div'
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
title: 'pre',
|
title: 'pre',
|
||||||
block: 'pre'
|
block: 'pre'
|
||||||
}]
|
}
|
||||||
}, {
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
title: 'Containers',
|
title: 'Containers',
|
||||||
items: [{
|
items: [
|
||||||
|
{
|
||||||
title: 'section',
|
title: 'section',
|
||||||
block: 'section',
|
block: 'section',
|
||||||
wrapper: true,
|
wrapper: true,
|
||||||
@@ -97,22 +119,23 @@ export default {
|
|||||||
title: 'blockquote',
|
title: 'blockquote',
|
||||||
block: 'blockquote',
|
block: 'blockquote',
|
||||||
wrapper: true
|
wrapper: true
|
||||||
},
|
}
|
||||||
//{ title: 'hgroup', block: 'hgroup', wrapper: true },
|
//{ title: 'hgroup', block: 'hgroup', wrapper: true },
|
||||||
//{ title: 'aside', block: 'aside', wrapper: true },
|
//{ title: 'aside', block: 'aside', wrapper: true },
|
||||||
//{ title: 'figure', block: 'figure', wrapper: true }
|
//{ title: 'figure', block: 'figure', wrapper: true }
|
||||||
]
|
]
|
||||||
}],
|
}
|
||||||
paste_word_valid_elements: "table,tr,td,th,b,link,strong,i,em,h1,h2, strong",
|
],
|
||||||
|
paste_word_valid_elements: 'table,tr,td,th,b,link,strong,i,em,h1,h2, strong',
|
||||||
valid_styles: {
|
valid_styles: {
|
||||||
'*': 'display, margin, float, margin-left, margin-right, margin-top, margin-bottom, padding-left, padding-right, padding-top, padding-bottom, text-decoration, border,font-size,color,background,background-color,line-height,text-align,list-style-type, border-radius',
|
'*': 'display, margin, float, margin-left, margin-right, margin-top, margin-bottom, padding-left, padding-right, padding-top, padding-bottom, text-decoration, border,font-size,color,background,background-color,line-height,text-align,list-style-type, border-radius'
|
||||||
},
|
},
|
||||||
plugins: ['autoresize', 'link', 'image', 'media', 'lists'],
|
plugins: ['autoresize', 'link', 'image', 'media', 'lists'],
|
||||||
removed_menuitems: 'newdocument',
|
removed_menuitems: 'newdocument',
|
||||||
toolbarxx: "undo redo | bold italic | bullist numlist outdent indent | alignleft aligncenter alignright alignjustify | link image forecolor backcolor",
|
toolbarxx:
|
||||||
toolbar1: 'undo redo | styles | bold italic | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | link image | media | forecolor backcolor',
|
'undo redo | bold italic | bullist numlist outdent indent | alignleft aligncenter alignright alignjustify | link image forecolor backcolor | ai_button',
|
||||||
|
toolbar1:
|
||||||
|
'undo redo | styles | bold italic | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | link image | media | forecolor backcolor ai_button',
|
||||||
toolbar2: '',
|
toolbar2: '',
|
||||||
menubar: true,
|
menubar: true
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user