@mixd-id/web-scaffold 0.2.250801009 → 0.2.250801010
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/components/Button.vue +6 -4
- package/src/components/Card.vue +29 -7
- package/src/components/ColorPicker.vue +4 -2
- package/src/components/List.vue +5 -1
- package/src/components/ListItem.vue +1 -1
- package/src/components/OTPField.vue +30 -10
- package/src/components/Textarea.vue +6 -7
- package/src/mixin/component.js +4 -0
- package/src/themes/default/index.js +35 -4
- package/src/utils/wss.js +1 -7
- package/src/widgets/ComponentSetting2.vue +33 -2
- package/src/widgets/Header2.vue +1 -1
- package/src/widgets/ImageSetting.vue +1 -1
- package/src/widgets/StyleSetting.vue +295 -191
- package/src/widgets/WebComponentSelector.vue +3 -3
- package/src/widgets/WebPageBuilder.vue +403 -80
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
<div class="flex-1 flex flex-col bg-base-400">
|
|
8
8
|
|
|
9
|
-
<div class="p-3 pr-5 flex justify-center gap-4
|
|
9
|
+
<div class="p-3 pr-5 flex justify-center gap-4 border-b-[1px] border-border-50">
|
|
10
10
|
<div class="flex-1 flex flex-row gap-4 items-center"
|
|
11
11
|
@click.meta="log(page)"
|
|
12
12
|
@click.alt="log(layout)">
|
|
@@ -356,6 +356,82 @@
|
|
|
356
356
|
|
|
357
357
|
</div>
|
|
358
358
|
|
|
359
|
+
<div v-else-if="store.tabIndex === 7" class="flex-1 flex flex-col">
|
|
360
|
+
<div class="flex flex-row justify-end p-4">
|
|
361
|
+
<button type="button" @click="newChat()">
|
|
362
|
+
<svg width="19" height="19" class="fill-primary hover:fill-primary-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256C397.4 512 512 397.4 512 256S397.4 0 256 0zM352 280H280V352c0 13.2-10.8 24-23.1 24C242.8 376 232 365.2 232 352V280H160C146.8 280 136 269.2 136 256c0-13.2 10.8-24 24-24H232V160c0-13.2 10.8-24 24-24C269.2 136 280 146.8 280 160v72h72C365.2 232 376 242.8 376 256C376 269.2 365.2 280 352 280z"/></svg>
|
|
363
|
+
</button>
|
|
364
|
+
</div>
|
|
365
|
+
<div class="flex-1 overflow-y-auto">
|
|
366
|
+
|
|
367
|
+
<div class="flex flex-col gap-4 p-4">
|
|
368
|
+
|
|
369
|
+
<div v-for="message in chat.messages"
|
|
370
|
+
:class="$style.chat + ' ' + (message.direction === 1 ? $style.chatIn : $style.chatOut)">
|
|
371
|
+
|
|
372
|
+
<p>{{ message.body }}</p>
|
|
373
|
+
|
|
374
|
+
<div v-if="message.direction !== 1" class="flex text-text-300 flex-row items-center gap-2 self-stretch pl-3">
|
|
375
|
+
<small class="text-xs text-text-300">{{ message.llmOutputTokenCount }} token</small>
|
|
376
|
+
•
|
|
377
|
+
<small class="text-xs text-text-300">{{ message.llmEllapsedMs }} ms</small>
|
|
378
|
+
<div class="flex-1"></div>
|
|
379
|
+
<button type="button" class="text-xs group hover:text-primary" v-if="(message.attachments ?? [])[0]" @click="chatSet(message.attachments[0])">
|
|
380
|
+
<svg width="9" height="9" class="inline fill-text-300 group-hover:fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M176 480C148.6 480 128 457.6 128 432v-352c0-25.38 20.4-47.98 48.01-47.98c8.686 0 17.35 2.352 25.02 7.031l288 176C503.3 223.8 512 239.3 512 256s-8.703 32.23-22.97 40.95l-288 176C193.4 477.6 184.7 480 176 480z"/></svg>
|
|
381
|
+
Apply
|
|
382
|
+
</button>
|
|
383
|
+
</div>
|
|
384
|
+
</div>
|
|
385
|
+
|
|
386
|
+
</div>
|
|
387
|
+
|
|
388
|
+
<pre class="text-xs break-all whitespace-pre-wrap">
|
|
389
|
+
|
|
390
|
+
</pre>
|
|
391
|
+
|
|
392
|
+
</div>
|
|
393
|
+
<div class="p-2">
|
|
394
|
+
<div class="flex flex-col gap-2">
|
|
395
|
+
<div class="flex flex-row gap-2 items-start">
|
|
396
|
+
<div class="w-[22px]"></div>
|
|
397
|
+
<div class="flex-1 flex flex-row flex-wrap gap-2">
|
|
398
|
+
<div v-for="(attachment, idx) in chat.attachments">
|
|
399
|
+
<Image :src="attachment.image"
|
|
400
|
+
@click="chat.attachments.splice(idx, 1)"
|
|
401
|
+
class="w-[48px] h-[48px] border-[1px] rounded-lg border-border-200" />
|
|
402
|
+
</div>
|
|
403
|
+
</div>
|
|
404
|
+
</div>
|
|
405
|
+
|
|
406
|
+
<div class="flex flex-row items-start gap-2">
|
|
407
|
+
<div class="pt-1">
|
|
408
|
+
<Button variant="minimal" class="p-0 mt-1" type="button" @click="$refs.chatFile.click()">
|
|
409
|
+
<svg width="19" height="19" class="fill-primary hover:fill-primary-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256C397.4 512 512 397.4 512 256S397.4 0 256 0zM352 280H280V352c0 13.2-10.8 24-23.1 24C242.8 376 232 365.2 232 352V280H160C146.8 280 136 269.2 136 256c0-13.2 10.8-24 24-24H232V160c0-13.2 10.8-24 24-24C269.2 136 280 146.8 280 160v72h72C365.2 232 376 242.8 376 256C376 269.2 365.2 280 352 280z"/></svg>
|
|
410
|
+
</Button>
|
|
411
|
+
<input type="file" accept="image/*" multiple ref="chatFile" class="hidden" @change="onChatUpload" />
|
|
412
|
+
</div>
|
|
413
|
+
<div class="flex-1">
|
|
414
|
+
<Textarea v-model="chat.input" rows="5" class="max-h-[60vh]">
|
|
415
|
+
<template #end>
|
|
416
|
+
<div class="p-2">
|
|
417
|
+
<Button ref="chatBtn" variant="minimal" class="p-0" type="button" @click="chatApply">
|
|
418
|
+
<svg width="19" height="19" class="fill-primary hover:fill-primary-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM372.5 276.5l-144 88C224.7 366.8 220.3 368 216 368c-13.69 0-24-11.2-24-24V168C192 155.3 202.2 144 216 144c4.344 0 8.678 1.176 12.51 3.516l144 88C379.6 239.9 384 247.6 384 256C384 264.4 379.6 272.1 372.5 276.5z"/></svg>
|
|
419
|
+
</Button>
|
|
420
|
+
</div>
|
|
421
|
+
</template>
|
|
422
|
+
</Textarea>
|
|
423
|
+
</div>
|
|
424
|
+
</div>
|
|
425
|
+
|
|
426
|
+
<div class="flex flex-row justify-end px-3 gap-2 text-text-300 text-xs">
|
|
427
|
+
<div class="text-text-300">{{ totalChatTokens }} tokens</div>
|
|
428
|
+
•
|
|
429
|
+
<div class="text-text-300">{{ chat.model }}</div>
|
|
430
|
+
</div>
|
|
431
|
+
</div>
|
|
432
|
+
</div>
|
|
433
|
+
</div>
|
|
434
|
+
|
|
359
435
|
</div>
|
|
360
436
|
|
|
361
437
|
<div :class="$style.resize1"
|
|
@@ -564,6 +640,107 @@ import OGSettingModal from "./OGSettingModal.vue";
|
|
|
564
640
|
|
|
565
641
|
const patchPageCache = {}
|
|
566
642
|
|
|
643
|
+
const fontFamilies = {
|
|
644
|
+
'"Anton", sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Anton&display=swap');`,
|
|
645
|
+
'Dosis, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Dosis:wght@400;700&display=swap');`,
|
|
646
|
+
'Lato, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Lato:wght@400;700&display=swap');`,
|
|
647
|
+
'Merriweather, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Merriweather:wght@400;700&display=swap');`,
|
|
648
|
+
'Montserrat, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap');`,
|
|
649
|
+
'"Noto Sans", sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;800&display=swap');`,
|
|
650
|
+
'Oswald, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@400;700&display=swap');`,
|
|
651
|
+
'Oxygen, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Oxygen:wght@400;700&display=swap');`,
|
|
652
|
+
'Poppins, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap');`,
|
|
653
|
+
'Quantico, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Quantico:wght@400;700&display=swap"');`,
|
|
654
|
+
'Raleway, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Raleway:wght@400;700&display=swap');`,
|
|
655
|
+
'"Reddit Sans", sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Reddit+Sans:wght@400;700&display=swap');`,
|
|
656
|
+
'"Roboto", sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');`,
|
|
657
|
+
'"Roboto Slab", serif': `@import url('https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@400;800&display=swap');`,
|
|
658
|
+
'Volkhov, serif': `@import url('https://fonts.googleapis.com/css2?family=Volkhov:wght@400;700&display=swap');`,
|
|
659
|
+
'"Work Sans", serif': `@import url('https://fonts.googleapis.com/css2?family=Work+Sans:wght@400;700&display=swap');`,
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
const defaultMedia = {
|
|
663
|
+
":root": {
|
|
664
|
+
"--spacing-1": [],
|
|
665
|
+
"--spacing-2": [],
|
|
666
|
+
"--spacing-3": [],
|
|
667
|
+
"--spacing-4": [],
|
|
668
|
+
"--spacing-5": [],
|
|
669
|
+
"--spacing-6": [],
|
|
670
|
+
"--spacing-7": [],
|
|
671
|
+
"--spacing-8": [],
|
|
672
|
+
"--spacing-9": [],
|
|
673
|
+
"--spacing-10": [],
|
|
674
|
+
"--spacing-11": [],
|
|
675
|
+
"--spacing-12": []
|
|
676
|
+
},
|
|
677
|
+
"*": {
|
|
678
|
+
"font-family": [ "Poppins, sans-serif" ]
|
|
679
|
+
},
|
|
680
|
+
"html, .html": {
|
|
681
|
+
"font-size": [],
|
|
682
|
+
"--base-300": [ "rgb(235, 235, 235)" ],
|
|
683
|
+
"--base-400": [ "rgb(245, 245, 245)" ],
|
|
684
|
+
"--base-500": [ "rgb(255, 255, 255)" ],
|
|
685
|
+
"--primary-100": [],
|
|
686
|
+
"--primary-200": [],
|
|
687
|
+
"--primary-300": [],
|
|
688
|
+
"--primary-400": [],
|
|
689
|
+
"--primary-500": [ "rgb(0, 0, 0)" ],
|
|
690
|
+
"--primary-600": [ "rgb(15, 15, 15)" ],
|
|
691
|
+
"--primary-700": [],
|
|
692
|
+
"--primary-800": [],
|
|
693
|
+
"--primary-900": [],
|
|
694
|
+
"--secondary-100": [],
|
|
695
|
+
"--secondary-200": [],
|
|
696
|
+
"--secondary-300": [],
|
|
697
|
+
"--secondary-400": [],
|
|
698
|
+
"--secondary-500": [],
|
|
699
|
+
"--secondary-600": [],
|
|
700
|
+
"--secondary-700": [],
|
|
701
|
+
"--secondary-800": [],
|
|
702
|
+
"--secondary-900": [],
|
|
703
|
+
"--text-100": [],
|
|
704
|
+
"--text-200": [],
|
|
705
|
+
"--text-300": [],
|
|
706
|
+
"--text-400": [],
|
|
707
|
+
"--text-500": [ "rgb(33, 33, 33)" ],
|
|
708
|
+
"--text-600": [],
|
|
709
|
+
"--text-700": [],
|
|
710
|
+
"--text-800": [],
|
|
711
|
+
"--text-900": []
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
function collectFontImports(styles) {
|
|
716
|
+
const usedFonts = new Set()
|
|
717
|
+
const media = styles?.media || {}
|
|
718
|
+
|
|
719
|
+
for (const selector in media) {
|
|
720
|
+
const rules = media[selector]
|
|
721
|
+
if (!rules || !rules['font-family']) continue
|
|
722
|
+
|
|
723
|
+
const values = rules['font-family']
|
|
724
|
+
if (!Array.isArray(values)) continue
|
|
725
|
+
|
|
726
|
+
for (const val of values) {
|
|
727
|
+
if (!val) continue
|
|
728
|
+
if (fontFamilies[val]) {
|
|
729
|
+
usedFonts.add(val)
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
return Array.from(usedFonts)
|
|
735
|
+
.map(font => fontFamilies[font])
|
|
736
|
+
.join('\n')
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
function indent(str, spaces = 2) {
|
|
740
|
+
const pad = ' '.repeat(spaces)
|
|
741
|
+
return str.split('\n').map(line => pad + line).join('\n')
|
|
742
|
+
}
|
|
743
|
+
|
|
567
744
|
export default{
|
|
568
745
|
|
|
569
746
|
components: {OGSettingModal, WebComponentSelector, WebLayoutSelector},
|
|
@@ -730,7 +907,7 @@ export default{
|
|
|
730
907
|
},
|
|
731
908
|
|
|
732
909
|
createLayout(layout){
|
|
733
|
-
this.
|
|
910
|
+
this.useSocket().send(`${this.controller}.create-layout`, layout)
|
|
734
911
|
.then(layout => {
|
|
735
912
|
this.loadLayouts()
|
|
736
913
|
this.page.layoutId = layout.id
|
|
@@ -739,57 +916,78 @@ export default{
|
|
|
739
916
|
.catch(err => this.alert(err))
|
|
740
917
|
},
|
|
741
918
|
|
|
742
|
-
createStyleSheet(styles
|
|
919
|
+
createStyleSheet(styles, breakpoints = {
|
|
920
|
+
md: '768px',
|
|
921
|
+
lg: '1024px',
|
|
922
|
+
xl: '1280px'
|
|
923
|
+
}){
|
|
924
|
+
const mediaBuckets = {
|
|
925
|
+
base: [],
|
|
926
|
+
md: [],
|
|
927
|
+
lg: [],
|
|
928
|
+
xl: []
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
const media = styles?.media || {}
|
|
932
|
+
|
|
933
|
+
for (const selector in media) {
|
|
934
|
+
const rules = media[selector]
|
|
935
|
+
if (!rules || Object.keys(rules).length === 0) continue
|
|
936
|
+
|
|
937
|
+
const ruleSets = {
|
|
938
|
+
base: [],
|
|
939
|
+
md: [],
|
|
940
|
+
lg: [],
|
|
941
|
+
xl: []
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
for (const prop in rules) {
|
|
945
|
+
const values = rules[prop]
|
|
946
|
+
if (!Array.isArray(values)) continue
|
|
947
|
+
|
|
948
|
+
if (values[0] !== undefined) ruleSets.base.push(`${prop}: ${values[0]};`)
|
|
949
|
+
if (values[1] !== undefined) ruleSets.md.push(`${prop}: ${values[1]};`)
|
|
950
|
+
if (values[2] !== undefined) ruleSets.lg.push(`${prop}: ${values[2]};`)
|
|
951
|
+
if (values[3] !== undefined) ruleSets.xl.push(`${prop}: ${values[3]};`)
|
|
952
|
+
}
|
|
743
953
|
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
954
|
+
for (const size in ruleSets) {
|
|
955
|
+
if (ruleSets[size].length === 0) continue
|
|
956
|
+
mediaBuckets[size].push(
|
|
957
|
+
`${selector} {\n ${ruleSets[size].join('\n ')}\n}`
|
|
958
|
+
)
|
|
959
|
+
}
|
|
747
960
|
}
|
|
748
961
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
'Montserrat, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap');`,
|
|
755
|
-
'"Noto Sans", sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;800&display=swap');`,
|
|
756
|
-
'Oswald, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@400;700&display=swap');`,
|
|
757
|
-
'Oxygen, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Oxygen:wght@400;700&display=swap');`,
|
|
758
|
-
'Poppins, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap');`,
|
|
759
|
-
'Quantico, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Quantico:wght@400;700&display=swap"');`,
|
|
760
|
-
'Raleway, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Raleway:wght@400;700&display=swap');`,
|
|
761
|
-
'"Reddit Sans", sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Reddit+Sans:wght@400;700&display=swap');`,
|
|
762
|
-
'"Roboto", sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');`,
|
|
763
|
-
'"Roboto Slab", serif': `@import url('https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@400;800&display=swap');`,
|
|
764
|
-
'Volkhov, serif': `@import url('https://fonts.googleapis.com/css2?family=Volkhov:wght@400;700&display=swap');`,
|
|
765
|
-
'"Work Sans", serif': `@import url('https://fonts.googleapis.com/css2?family=Work+Sans:wght@400;700&display=swap');`,
|
|
962
|
+
let css = ''
|
|
963
|
+
|
|
964
|
+
const fontImports = collectFontImports(styles, fontFamilies)
|
|
965
|
+
if (fontImports) {
|
|
966
|
+
css += fontImports + '\n\n'
|
|
766
967
|
}
|
|
767
968
|
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
969
|
+
const mediaImports = styles?.imports || []
|
|
970
|
+
if (Array.isArray(mediaImports)) {
|
|
971
|
+
css += mediaImports.join('\n') + '\n\n'
|
|
972
|
+
}
|
|
772
973
|
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
for(let selector in css[key]){
|
|
777
|
-
text += selector + ':' + css[key][selector] + ';'
|
|
974
|
+
if (mediaBuckets.base.length) {
|
|
975
|
+
css += mediaBuckets.base.join('\n\n') + '\n\n'
|
|
976
|
+
}
|
|
778
977
|
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
text += '}'
|
|
784
|
-
}
|
|
785
|
-
text += '}\n'
|
|
978
|
+
if (mediaBuckets.md.length) {
|
|
979
|
+
css += `@media (min-width: ${breakpoints.md}) {\n${indent(mediaBuckets.md.join('\n\n'))}\n}\n\n`
|
|
786
980
|
}
|
|
787
981
|
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
982
|
+
if (mediaBuckets.lg.length) {
|
|
983
|
+
css += `@media (min-width: ${breakpoints.lg}) {\n${indent(mediaBuckets.lg.join('\n\n'))}\n}\n\n`
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
if (mediaBuckets.xl.length) {
|
|
987
|
+
css += `@media (min-width: ${breakpoints.xl}) {\n${indent(mediaBuckets.xl.join('\n\n'))}\n}\n\n`
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
return css.trim()
|
|
793
991
|
},
|
|
794
992
|
|
|
795
993
|
createInstances(){
|
|
@@ -887,7 +1085,7 @@ export default{
|
|
|
887
1085
|
},
|
|
888
1086
|
|
|
889
1087
|
listen(){
|
|
890
|
-
this.
|
|
1088
|
+
this.useSocket().send(`${this.controller}.subscribe`, { name:'page' })
|
|
891
1089
|
.then(() => {
|
|
892
1090
|
|
|
893
1091
|
})
|
|
@@ -895,16 +1093,17 @@ export default{
|
|
|
895
1093
|
},
|
|
896
1094
|
|
|
897
1095
|
async load(){
|
|
898
|
-
return this.
|
|
899
|
-
.then(({ page,
|
|
1096
|
+
return this.useSocket().send(`${this.controller}.open`, { uid:this.$route.params.uid })
|
|
1097
|
+
.then(({ page, previewHost, debugMode, useChat }) => {
|
|
900
1098
|
|
|
901
1099
|
this.patchPage(page)
|
|
902
1100
|
|
|
903
1101
|
if(page) Object.assign(this.page, page)
|
|
904
|
-
if(host) this.host = host
|
|
905
1102
|
this.debugMode = debugMode ?? this.debugMode
|
|
906
1103
|
if(previewHost) this.previewHost = previewHost
|
|
907
1104
|
|
|
1105
|
+
this.useChat = useChat ?? this.useChat
|
|
1106
|
+
|
|
908
1107
|
this.prevData = {
|
|
909
1108
|
page: JSON.stringify(this.page),
|
|
910
1109
|
layout: JSON.stringify(this.layout)
|
|
@@ -912,21 +1111,11 @@ export default{
|
|
|
912
1111
|
|
|
913
1112
|
this.pageHistory.commit()
|
|
914
1113
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
if(host){
|
|
918
|
-
this.$nextTick(() => {
|
|
919
|
-
this.resize()
|
|
1114
|
+
this.$nextTick(() => {
|
|
1115
|
+
this.resize()
|
|
920
1116
|
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
}
|
|
924
|
-
else{
|
|
925
|
-
this.iframeSrc = host + '/' + (this.page.path ?? '') +
|
|
926
|
-
`?edit-mode=${this.store.previewMode}`
|
|
927
|
-
}
|
|
928
|
-
})
|
|
929
|
-
}
|
|
1117
|
+
this.iframeSrc = this.previewHost + `?edit-mode=${this.store.previewMode}`
|
|
1118
|
+
})
|
|
930
1119
|
|
|
931
1120
|
this.readyState = 1
|
|
932
1121
|
})
|
|
@@ -1026,7 +1215,7 @@ export default{
|
|
|
1026
1215
|
},
|
|
1027
1216
|
|
|
1028
1217
|
async loadLayouts(){
|
|
1029
|
-
this.
|
|
1218
|
+
this.useSocket().send(`${this.controller}.load-layouts`, {})
|
|
1030
1219
|
.then(_ => {
|
|
1031
1220
|
this.layouts = _
|
|
1032
1221
|
})
|
|
@@ -1034,7 +1223,7 @@ export default{
|
|
|
1034
1223
|
|
|
1035
1224
|
loadDatasource(){
|
|
1036
1225
|
if(this.useDatasource && this.useDatasource[1]){
|
|
1037
|
-
this.
|
|
1226
|
+
this.useSocket().send(this.useDatasource[1], this.page.datasource)
|
|
1038
1227
|
.then((data) => {
|
|
1039
1228
|
Object.assign(this.page, { data })
|
|
1040
1229
|
this.updateIframe()
|
|
@@ -1045,7 +1234,7 @@ export default{
|
|
|
1045
1234
|
loadPreset(){
|
|
1046
1235
|
if(!Object.keys(this.$route.query).map(_ => _.toLowerCase()).includes('reset')){
|
|
1047
1236
|
if(this.presetKey){
|
|
1048
|
-
return this.
|
|
1237
|
+
return this.useSocket().send(this.presetSrc, { key:this.presetKey })
|
|
1049
1238
|
.then(config => {
|
|
1050
1239
|
if(config){
|
|
1051
1240
|
Object.assign(this.config.params, config.params)
|
|
@@ -1339,7 +1528,7 @@ export default{
|
|
|
1339
1528
|
this.createInstances()
|
|
1340
1529
|
|
|
1341
1530
|
this.$refs.saveBtn.setState(2)
|
|
1342
|
-
this.
|
|
1531
|
+
this.useSocket().send(`${this.controller}.save`, { ...this.page, layout:this.layout })
|
|
1343
1532
|
.then((_) => {
|
|
1344
1533
|
this.prevData = {
|
|
1345
1534
|
page: JSON.stringify(this.page),
|
|
@@ -1371,7 +1560,7 @@ export default{
|
|
|
1371
1560
|
|
|
1372
1561
|
savePreset: invokeAfterIdle(function() {
|
|
1373
1562
|
if(this.presetKey) {
|
|
1374
|
-
this.
|
|
1563
|
+
this.useSocket().send(this.presetSrc,
|
|
1375
1564
|
{key: this.presetKey, config: this.config})
|
|
1376
1565
|
}
|
|
1377
1566
|
}),
|
|
@@ -1397,7 +1586,7 @@ export default{
|
|
|
1397
1586
|
},
|
|
1398
1587
|
|
|
1399
1588
|
stopListen(){
|
|
1400
|
-
this.
|
|
1589
|
+
this.useSocket().send(`${this.controller}.unsubscribe`, { name:'page' })
|
|
1401
1590
|
.catch((err) => this.toast(err))
|
|
1402
1591
|
},
|
|
1403
1592
|
|
|
@@ -1464,6 +1653,97 @@ export default{
|
|
|
1464
1653
|
}
|
|
1465
1654
|
},
|
|
1466
1655
|
|
|
1656
|
+
chatApply(){
|
|
1657
|
+
|
|
1658
|
+
this.$refs.chatBtn.setState(2)
|
|
1659
|
+
return this.useSocket()
|
|
1660
|
+
.send(`${this.controller}.chat`, {
|
|
1661
|
+
key: this.chat.key,
|
|
1662
|
+
prompt: this.chat.input,
|
|
1663
|
+
attachments: this.chat.attachments,
|
|
1664
|
+
pageId: this.page.id,
|
|
1665
|
+
input: {
|
|
1666
|
+
components: this.page.components,
|
|
1667
|
+
styles: this.layout?.styles ?? {}
|
|
1668
|
+
}
|
|
1669
|
+
})
|
|
1670
|
+
.catch(err => this.alert(err))
|
|
1671
|
+
.then(res => {
|
|
1672
|
+
for(let message of res.messages){
|
|
1673
|
+
try{
|
|
1674
|
+
for(let attachment of (message.attachments ?? [])){
|
|
1675
|
+
if(attachment.type === 'page'){
|
|
1676
|
+
this.chatSet(attachment)
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
if(message.model) this.chat.model = message.model
|
|
1681
|
+
|
|
1682
|
+
this.chat.messages.push(message)
|
|
1683
|
+
}
|
|
1684
|
+
catch(e){
|
|
1685
|
+
console.error(e)
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
this.chat.input = ''
|
|
1690
|
+
this.chat.attachments = []
|
|
1691
|
+
})
|
|
1692
|
+
.finally(_ => this.$refs.chatBtn?.resetState())
|
|
1693
|
+
},
|
|
1694
|
+
|
|
1695
|
+
onChatUpload(e){
|
|
1696
|
+
for(let file of e.target.files){
|
|
1697
|
+
this.chat.attachments.push({
|
|
1698
|
+
type: "image",
|
|
1699
|
+
image: file
|
|
1700
|
+
})
|
|
1701
|
+
}
|
|
1702
|
+
},
|
|
1703
|
+
|
|
1704
|
+
chatSet(obj){
|
|
1705
|
+
|
|
1706
|
+
if(obj?.styles?.media && this.layout){
|
|
1707
|
+
Object.assign(this.layout, {
|
|
1708
|
+
styles: {
|
|
1709
|
+
media: this.createMedia(obj.styles.media),
|
|
1710
|
+
imports: obj.styles.imports
|
|
1711
|
+
}
|
|
1712
|
+
})
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
if((obj?.components ?? []).length > 0){
|
|
1716
|
+
Object.assign(this.page, {
|
|
1717
|
+
components: obj.components
|
|
1718
|
+
})
|
|
1719
|
+
}
|
|
1720
|
+
},
|
|
1721
|
+
|
|
1722
|
+
createMedia(obj){
|
|
1723
|
+
|
|
1724
|
+
const newMedia = JSON.parse(JSON.stringify(defaultMedia))
|
|
1725
|
+
|
|
1726
|
+
for(let selector in obj){
|
|
1727
|
+
if(!newMedia[selector]){
|
|
1728
|
+
newMedia[selector] = {}
|
|
1729
|
+
}
|
|
1730
|
+
for(let prop in obj[selector]){
|
|
1731
|
+
newMedia[selector][prop] = obj[selector][prop]
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1735
|
+
return newMedia
|
|
1736
|
+
},
|
|
1737
|
+
|
|
1738
|
+
newChat(){
|
|
1739
|
+
this.config.params.chat = {
|
|
1740
|
+
key: md5('web-page-chat-' + new Date().getTime()),
|
|
1741
|
+
input: '',
|
|
1742
|
+
attachments: [],
|
|
1743
|
+
messages: []
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1467
1747
|
},
|
|
1468
1748
|
|
|
1469
1749
|
computed: {
|
|
@@ -1501,7 +1781,7 @@ export default{
|
|
|
1501
1781
|
},
|
|
1502
1782
|
|
|
1503
1783
|
computedIframeSrc(){
|
|
1504
|
-
return
|
|
1784
|
+
return this.page.app.hosts[0].name + this.page.path
|
|
1505
1785
|
},
|
|
1506
1786
|
|
|
1507
1787
|
currentItem(){
|
|
@@ -1604,6 +1884,17 @@ export default{
|
|
|
1604
1884
|
return this.config.params
|
|
1605
1885
|
},
|
|
1606
1886
|
|
|
1887
|
+
tabItems(){
|
|
1888
|
+
return [
|
|
1889
|
+
{ text:"Page Info", value:1 },
|
|
1890
|
+
{ text:"Layout", value:4 },
|
|
1891
|
+
{ text:"Components", value:2 },
|
|
1892
|
+
this.useChat ? { text:"Chat", value:7 } : null,
|
|
1893
|
+
/*{ text:"Datasource", value:3 },*/
|
|
1894
|
+
]
|
|
1895
|
+
.filter(_ => _)
|
|
1896
|
+
},
|
|
1897
|
+
|
|
1607
1898
|
presetSrc(){
|
|
1608
1899
|
return this.controller ?
|
|
1609
1900
|
`${this.controller}.preset` :
|
|
@@ -1612,6 +1903,20 @@ export default{
|
|
|
1612
1903
|
|
|
1613
1904
|
viewIndex(){
|
|
1614
1905
|
return this.viewTypes.findIndex(_ => _.value === this.store.viewType)
|
|
1906
|
+
},
|
|
1907
|
+
|
|
1908
|
+
chat(){
|
|
1909
|
+
if(!this.config.params.chat)
|
|
1910
|
+
this.newChat()
|
|
1911
|
+
return this.config.params.chat
|
|
1912
|
+
},
|
|
1913
|
+
|
|
1914
|
+
totalChatTokens(){
|
|
1915
|
+
let total = 0
|
|
1916
|
+
for(let message of this.chat.messages){
|
|
1917
|
+
total += message.llmOutputTokenCount ?? 0
|
|
1918
|
+
}
|
|
1919
|
+
return total
|
|
1615
1920
|
}
|
|
1616
1921
|
|
|
1617
1922
|
},
|
|
@@ -1654,6 +1959,8 @@ export default{
|
|
|
1654
1959
|
'flexDirection',
|
|
1655
1960
|
'zIndex',
|
|
1656
1961
|
|
|
1962
|
+
'backdropBlur',
|
|
1963
|
+
|
|
1657
1964
|
'autoFlow', 'alignItems', 'justifyContent',
|
|
1658
1965
|
'letterSpacing', 'lineClamp',
|
|
1659
1966
|
|
|
@@ -1665,12 +1972,11 @@ export default{
|
|
|
1665
1972
|
'containerVariant', 'containerGridColumn', 'containerGap'
|
|
1666
1973
|
],
|
|
1667
1974
|
itemClasses: [
|
|
1668
|
-
'itemMinWidth', 'itemRatio', 'itemVariant'
|
|
1975
|
+
'itemMinWidth', 'itemRatio', 'itemVariant', 'objectFit'
|
|
1669
1976
|
],
|
|
1670
1977
|
styleClasses: [
|
|
1671
1978
|
'bgColors', 'bgImages', 'bdColor'
|
|
1672
1979
|
],
|
|
1673
|
-
host: null,
|
|
1674
1980
|
previewHost: null,
|
|
1675
1981
|
iframeStyle: {},
|
|
1676
1982
|
iframeSrc: '',
|
|
@@ -1687,12 +1993,6 @@ export default{
|
|
|
1687
1993
|
],
|
|
1688
1994
|
routerBeforeEach: null,
|
|
1689
1995
|
readyState: 2,
|
|
1690
|
-
tabItems: [
|
|
1691
|
-
{ text:"Page Info", value:1 },
|
|
1692
|
-
{ text:"Layout", value:4 },
|
|
1693
|
-
{ text:"Components", value:2 },
|
|
1694
|
-
/*{ text:"Datasource", value:3 },*/
|
|
1695
|
-
],
|
|
1696
1996
|
stylesheets: [
|
|
1697
1997
|
'font-family'
|
|
1698
1998
|
],
|
|
@@ -1700,12 +2000,14 @@ export default{
|
|
|
1700
2000
|
|
|
1701
2001
|
extRightPane: null,
|
|
1702
2002
|
debugMode: false,
|
|
2003
|
+
|
|
2004
|
+
useChat: false
|
|
1703
2005
|
}
|
|
1704
2006
|
},
|
|
1705
2007
|
|
|
1706
2008
|
emits: [ 'close', 'unmount' ],
|
|
1707
2009
|
|
|
1708
|
-
inject: [ 'alert', 'appStyle', 'confirm', '
|
|
2010
|
+
inject: [ 'alert', 'appStyle', 'confirm', 'useSocket', 'toast' ],
|
|
1709
2011
|
|
|
1710
2012
|
mounted() {
|
|
1711
2013
|
this.loadPreset()
|
|
@@ -1729,7 +2031,7 @@ export default{
|
|
|
1729
2031
|
})
|
|
1730
2032
|
|
|
1731
2033
|
this.listen()
|
|
1732
|
-
this.
|
|
2034
|
+
this.useSocket().onAny(this.onHooks)
|
|
1733
2035
|
},
|
|
1734
2036
|
|
|
1735
2037
|
unmounted() {
|
|
@@ -1739,7 +2041,7 @@ export default{
|
|
|
1739
2041
|
window.removeEventListener('beforeunload', this.onUnload)
|
|
1740
2042
|
this.routerBeforeEach()
|
|
1741
2043
|
this.stopListen()
|
|
1742
|
-
this.
|
|
2044
|
+
this.useSocket().offAny(this.onHooks)
|
|
1743
2045
|
this.$emit('unmount', { uid:this.page.uid })
|
|
1744
2046
|
},
|
|
1745
2047
|
|
|
@@ -1825,6 +2127,27 @@ export default{
|
|
|
1825
2127
|
@apply border-[1px] border-border-200;
|
|
1826
2128
|
}
|
|
1827
2129
|
|
|
2130
|
+
.chat{
|
|
2131
|
+
@apply max-w-[80%] flex flex-col;
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2134
|
+
.chatIn{
|
|
2135
|
+
@apply self-start;
|
|
2136
|
+
}
|
|
2137
|
+
.chatIn p{
|
|
2138
|
+
@apply bg-border-100 p-3 rounded-lg;
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
.chatOut{
|
|
2142
|
+
@apply self-end flex flex-col items-end;
|
|
2143
|
+
}
|
|
2144
|
+
.chatOut p{
|
|
2145
|
+
@apply bg-primary-100 p-3 rounded-lg;
|
|
2146
|
+
}
|
|
2147
|
+
.chatOut button{
|
|
2148
|
+
@apply p-0 px-2 text-sm mt-1 rounded-sm;
|
|
2149
|
+
}
|
|
2150
|
+
|
|
1828
2151
|
</style>
|
|
1829
2152
|
|
|
1830
2153
|
<style>
|