@mixd-id/web-scaffold 0.2.240705 → 0.2.250801009
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/docs/components/Dashboard.md +56 -0
- package/log.txt +7 -0
- package/package.json +27 -19
- package/src/components/404.vue +61 -0
- package/src/components/AccountIcon.vue +19 -0
- package/src/components/Ahref.vue +1 -1
- package/src/components/Alert.vue +4 -13
- package/src/components/ArrayList.vue +49 -0
- package/src/components/Article.vue +24 -30
- package/src/components/Button.vue +79 -167
- package/src/components/Card.vue +235 -0
- package/src/components/Carousel.vue +61 -60
- package/src/components/Cart.vue +192 -0
- package/src/components/CartIcon.vue +89 -0
- package/src/components/ChartBar.vue +2 -3
- package/src/components/Checkbox.vue +20 -11
- package/src/components/Checkout.vue +373 -0
- package/src/components/CheckoutDelivery.vue +267 -0
- package/src/components/CodeEditor.vue +5 -16
- package/src/components/CollapsiblePanel.vue +70 -0
- package/src/components/ColorPicker.vue +8 -3
- package/src/components/ColorPicker2.vue +41 -19
- package/src/components/ColorPicker3.vue +100 -0
- package/src/components/Confirm.vue +9 -7
- package/src/components/ContextMenu.vue +122 -206
- package/src/components/ContextMenuItem.vue +53 -0
- package/src/components/Dashboard.vue +243 -0
- package/src/components/Dashboard2.vue +118 -0
- package/src/components/DashboardComponentSelector.vue +96 -0
- package/src/components/DashboardConfigs.vue +202 -0
- package/src/components/Datepicker.vue +102 -41
- package/src/components/DayTimeRange.vue +3 -2
- package/src/components/Dropdown.vue +7 -4
- package/src/components/Flex.vue +14 -40
- package/src/components/GHeatMaps.vue +2 -2
- package/src/components/Grid.vue +6 -6
- package/src/components/HTMLEditor.vue +27 -14
- package/src/components/Image.vue +62 -108
- package/src/components/ImagePreview.vue +14 -4
- package/src/components/ImageUploader.vue +114 -0
- package/src/components/ImportModal.vue +3 -3
- package/src/components/Link.vue +62 -6
- package/src/components/List.vue +524 -402
- package/src/components/ListContextMenu.vue +88 -0
- package/src/components/ListItem.vue +5 -3
- package/src/components/ListPage1.vue +14 -15
- package/src/components/ListView.vue +5 -6
- package/src/components/ListViewSettings.vue +2 -2
- package/src/components/LogViewerItem.vue +1 -1
- package/src/components/MarkdownEdit.vue +128 -0
- package/src/components/MarkdownPreview.vue +102 -0
- package/src/components/MenuItem1.vue +36 -0
- package/src/components/Modal.vue +95 -43
- package/src/components/MultiDropdown.vue +124 -0
- package/src/components/MultilineText.vue +1 -4
- package/src/components/OTPField.vue +11 -17
- package/src/components/ObjectTree.vue +1 -1
- package/src/components/PageBuilder.vue +3 -3
- package/src/components/Paragraph.vue +1 -2
- package/src/components/PresetSelectorFilterItem.vue +107 -95
- package/src/components/Radio.vue +1 -1
- package/src/components/SearchModal.vue +153 -0
- package/src/components/Slider.vue +1 -1
- package/src/components/Svg.vue +1 -1
- package/src/components/SvgEditor.vue +173 -0
- package/src/components/Switch.vue +4 -5
- package/src/components/Table.vue +2 -2
- package/src/components/TableView.vue +2 -3
- package/src/components/TableViewHead.vue +2 -2
- package/src/components/Tabs.vue +1 -1
- package/src/components/Testimonial.vue +2 -2
- package/src/components/Text.vue +7 -22
- package/src/components/TextEditor.vue +3 -3
- package/src/components/TextWithTag.vue +61 -30
- package/src/components/Textarea.vue +11 -16
- package/src/components/Textbox.vue +9 -19
- package/src/components/Timepicker.vue +25 -15
- package/src/components/Toast.vue +5 -3
- package/src/components/TreeMenu.vue +122 -0
- package/src/components/TreeView.vue +15 -10
- package/src/components/TreeView2.vue +38 -0
- package/src/components/TreeViewItem.vue +58 -29
- package/src/components/TreeViewItem2.vue +55 -0
- package/src/components/Uploader.vue +45 -0
- package/src/components/Video.vue +119 -0
- package/src/components/VirtualGrid.vue +24 -7
- package/src/components/VirtualTable.vue +363 -128
- package/src/configs/dashboard/data-table.js +9 -0
- package/src/configs/web-page-builder.js +118 -0
- package/src/directives/intersect.js +26 -0
- package/src/hooks/device.js +14 -0
- package/src/index.js +62 -107
- package/src/mixin/component.js +147 -67
- package/src/themes/default/index.js +83 -155
- package/src/utils/dashboard.js +22 -962
- package/src/utils/helpers.cjs +635 -0
- package/src/utils/helpers.js +91 -60
- package/src/utils/helpers.mjs +245 -12
- package/src/utils/importer.js +22 -3
- package/src/utils/list.mjs +1509 -0
- package/src/utils/preset-selector.cjs +1455 -0
- package/src/utils/preset-selector.js +489 -95
- package/src/utils/preset-selector.mjs +59 -20
- package/src/utils/queue.js +63 -0
- package/src/utils/web.mjs +120 -0
- package/src/utils/wss.js +37 -29
- package/src/utils/wss.mjs +24 -19
- package/src/widgets/AhrefSetting.vue +16 -13
- package/src/widgets/ArticleSetting.vue +15 -27
- package/src/widgets/BackgroundColorSetting.vue +153 -0
- package/src/widgets/BorderColorSetting.vue +57 -0
- package/src/widgets/BotEditor/BotEditorActions.vue +3 -2
- package/src/widgets/BotEditor/BotEditorSettings.vue +21 -0
- package/src/widgets/BotEditor.vue +35 -15
- package/src/widgets/ButtonSetting.vue +12 -13
- package/src/widgets/CarouselSetting.vue +33 -45
- package/src/widgets/CartSetting.vue +46 -0
- package/src/widgets/CheckoutSetting.vue +46 -0
- package/src/widgets/CollapsiblePanelSetting.vue +46 -0
- package/src/widgets/ColumnSelector.vue +29 -5
- package/src/widgets/ComponentSetting.vue +1 -1
- package/src/widgets/ComponentSetting2.vue +112 -234
- package/src/widgets/ComponentSetting3.vue +1 -1
- package/src/widgets/ContactForm.vue +3 -3
- package/src/widgets/ContactFormSetting.vue +41 -30
- package/src/widgets/Dashboard/BarChart.vue +47 -11
- package/src/widgets/Dashboard/BarChartSetting.vue +1 -1
- package/src/widgets/Dashboard/DataTable.vue +125 -0
- package/src/widgets/Dashboard/DataTableSetting.vue +243 -0
- package/src/widgets/Dashboard/DatasourceSelector.vue +1 -1
- package/src/widgets/Dashboard/Doughnut.vue +49 -7
- package/src/widgets/Dashboard/DoughnutSetting.vue +2 -2
- package/src/widgets/Dashboard/Metric.vue +78 -19
- package/src/widgets/Dashboard/MetricSetting.vue +81 -28
- package/src/widgets/Dashboard/Pie.vue +55 -6
- package/src/widgets/Dashboard/PieSetting.vue +1 -1
- package/src/widgets/Dashboard/PolarArea.vue +49 -7
- package/src/widgets/Dashboard/PolarAreaSetting.vue +1 -1
- package/src/widgets/Dashboard/SharingModal.vue +4 -5
- package/src/widgets/Dashboard/ViewSelector.vue +2 -2
- package/src/widgets/Dashboard/VirtualTableSetting.vue +121 -184
- package/src/widgets/{Dashboard.vue → Dashboard0.vue} +426 -343
- package/src/widgets/EmbeddedVideoSetting.vue +7 -5
- package/src/widgets/FAQ.vue +16 -3
- package/src/widgets/FAQSetting.vue +53 -47
- package/src/widgets/FeatureList.vue +3 -0
- package/src/widgets/FeatureListSetting.vue +112 -102
- package/src/widgets/FlexSetting.vue +83 -106
- package/src/widgets/GridSetting.vue +71 -196
- package/src/widgets/Header2.vue +34 -71
- package/src/widgets/Header2Setting.vue +95 -179
- package/src/widgets/HeaderSetting.vue +16 -18
- package/src/widgets/IconListSetting.vue +69 -65
- package/src/widgets/ImageSetting.vue +33 -60
- package/src/widgets/LinkSetting.vue +60 -37
- package/src/widgets/LinkSettingModal.vue +173 -0
- package/src/widgets/LogViewer.vue +1 -1
- package/src/widgets/MarginSetting.vue +2 -2
- package/src/widgets/MenuEditor.vue +1 -1
- package/src/widgets/MenuItem1Setting.vue +78 -0
- package/src/widgets/ModalSetting.vue +42 -44
- package/src/widgets/MultiValueSetting.vue +2 -2
- package/src/widgets/MultiValueSetting2.vue +78 -45
- package/src/widgets/OGSettingModal.vue +103 -0
- package/src/widgets/PaddingSetting.vue +2 -2
- package/src/widgets/ParagraphSetting.vue +16 -13
- package/src/widgets/PositionSetting.vue +209 -0
- package/src/widgets/PresetBar.vue +359 -210
- package/src/widgets/PresetBarPivot.vue +31 -19
- package/src/widgets/PresetSelector.vue +29 -17
- package/src/widgets/SearchModalSetting.vue +70 -0
- package/src/widgets/Share.vue +1 -2
- package/src/widgets/ShareSetting.vue +67 -60
- package/src/widgets/StyleSetting.vue +227 -116
- package/src/widgets/TestimonialSetting.vue +97 -88
- package/src/widgets/TextBlockSetting.vue +16 -13
- package/src/widgets/UserActionBuilder/UserActionConsole.vue +30 -10
- package/src/widgets/UserActionBuilder/UserActionOutput.vue +2 -2
- package/src/widgets/UserActionBuilder/UserActionOutputReply.vue +64 -87
- package/src/widgets/UserActionBuilder/UserActionProps.vue +3 -3
- package/src/widgets/UserActionBuilder.vue +4 -16
- package/src/widgets/WebComponentSelector.vue +15 -11
- package/src/widgets/WebLayoutSelector.vue +41 -270
- package/src/widgets/WebPageBuilder.vue +693 -704
- package/src/widgets/WebPageBuilder2.vue +7 -7
- package/src/widgets/WebPageBuilder4/ButtonSetting.vue +0 -8
- package/src/widgets/WebPageBuilder4/CarouselSetting.vue +63 -7
- package/src/widgets/WebPageBuilder4/FlexAlignSetting.vue +3 -3
- package/src/widgets/WebPageBuilder4/FlexSetting.vue +1 -10
- package/src/widgets/WebPageBuilder4/MultiValueSetting.vue +2 -2
- package/src/widgets/WebPageBuilder4/PropertySetting.vue +0 -7
- package/src/widgets/WebPageBuilder4/WebPageComponentSelector.vue +1 -7
- package/src/widgets/WebPageBuilder4.vue +289 -575
- package/src/widgets/WebPageSelector.vue +1 -1
- package/src/widgets/YoutubeVideoSetting.vue +16 -13
- package/tailwind.config.js +3 -35
- package/docs/schema/user-action.json +0 -266
- package/src/App.vue +0 -25
- package/src/components/SearchButton.vue +0 -57
- package/src/entry-client.js +0 -27
- package/src/entry-server.js +0 -73
- package/src/events/event.js +0 -2
- package/src/main.js +0 -29
- package/src/mixin/website.js +0 -121
- package/src/router.js +0 -57
- package/src/widgets/MobileMenu.vue +0 -182
- package/src/widgets/WebPageBuilder4/ActionSetting.vue +0 -158
- package/src/widgets/WebPageBuilder4/ColorSetting.vue +0 -63
- package/src/widgets/WebPageBuilder4/DataSetting.vue +0 -92
- package/src/widgets/WebPageBuilder4/FontSizeSetting.vue +0 -76
- package/src/widgets/WebPageBuilder4/LinkSetting.vue +0 -68
- package/src/widgets/WebPageBuilder4/MobileMenuSetting.vue +0 -106
- package/src/widgets/WebPageBuilder4/Setting.vue +0 -73
- package/src/widgets/WebPageBuilder4/StyleSetting.vue +0 -77
- package/src/widgets/WebPageBuilder4/SvgSetting.vue +0 -207
- package/src/widgets/WebPageBuilder4/TextTransformSetting.vue +0 -70
- package/src/widgets/WebPageBuilder4/WebPageDataEdit.vue +0 -121
- package/test.json +0 -22
- /package/src/widgets/{Header1.vue → Header0.vue} +0 -0
- /package/src/widgets/{Header1Setting.vue → Header0Setting.vue} +0 -0
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="flex-1 flex items-center justify-center" v-if="
|
|
2
|
+
<div class="flex-1 flex items-center justify-center" v-if="readyState === 2">
|
|
3
3
|
<svg class="animate-spin aspect-square w-[48px]" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>
|
|
4
4
|
</div>
|
|
5
5
|
<div :class="$style.comp" v-else-if="page">
|
|
6
6
|
|
|
7
7
|
<div class="flex-1 flex flex-col bg-base-400">
|
|
8
8
|
|
|
9
|
-
<div class="p-3 pr-5
|
|
10
|
-
<div class="flex-1 flex flex-row gap-4 items-center"
|
|
9
|
+
<div class="p-3 pr-5 flex justify-center gap-4 bg-base-400 border-b-[1px] border-border-50">
|
|
10
|
+
<div class="flex-1 flex flex-row gap-4 items-center"
|
|
11
|
+
@click.meta="log(page)"
|
|
12
|
+
@click.alt="log(layout)">
|
|
11
13
|
|
|
12
14
|
<button ref="close" class=" p-1"
|
|
13
15
|
@click="close">
|
|
@@ -23,27 +25,18 @@
|
|
|
23
25
|
<template #start>
|
|
24
26
|
<div class="flex flex-row items-center mr-2">
|
|
25
27
|
<button @click="reloadIframe" class="p-3">
|
|
26
|
-
<svg width="14" height="14" viewBox="0 0 24 24" class="fill-
|
|
28
|
+
<svg width="14" height="14" viewBox="0 0 24 24" class="fill-primary" xmlns="http://www.w3.org/2000/svg">
|
|
27
29
|
<path d="M3.75 12C3.75 7.44365 7.44365 3.75 12 3.75C14.7802 3.75 17.1982 5.12612 18.6816 7.24467L16.5022 7.23828C16.088 7.23707 15.7512 7.57187 15.75 7.98608C15.7488 8.4003 16.0836 8.73706 16.4978 8.73828L19.9491 8.74839C19.9817 8.75065 20.0147 8.75076 20.0477 8.74868L20.4978 8.75C20.6971 8.75058 20.8884 8.67182 21.0296 8.53111C21.1707 8.39039 21.25 8.19929 21.25 8L21.25 4C21.25 3.58579 20.9142 3.25 20.5 3.25C20.0858 3.25 19.75 3.58579 19.75 4L19.75 6.16237C17.9894 3.79113 15.2004 2.25 12 2.25C6.61522 2.25 2.25 6.61522 2.25 12C2.25 17.3848 6.61522 21.75 12 21.75C15.8354 21.75 19.0799 19.5367 20.6716 16.3338C20.856 15.9628 20.7047 15.5127 20.3338 15.3284C19.9628 15.144 19.5127 15.2953 19.3284 15.6662C17.9747 18.3902 15.2321 20.25 12 20.25C7.44365 20.25 3.75 16.5563 3.75 12Z"/>
|
|
28
30
|
</svg>
|
|
29
31
|
</button>
|
|
30
|
-
<select v-model="store.zoomLevel" :class="$style.zoomLevel" @change="resize()">
|
|
31
|
-
<optgroup label="Zoom Level">
|
|
32
|
-
<option value="fit">Fit</option>
|
|
33
|
-
<option value="125%">125%</option>
|
|
34
|
-
<option value="100%">100%</option>
|
|
35
|
-
<option value="75%">75%</option>
|
|
36
|
-
<option value="50%">50%</option>
|
|
37
|
-
</optgroup>
|
|
38
|
-
</select>
|
|
39
32
|
</div>
|
|
40
33
|
</template>
|
|
41
34
|
<template #end>
|
|
42
|
-
<div class="flex flex-row gap-
|
|
43
|
-
<CopyToClipboard :value="computedIframeSrc" @copied="toast($t('Copied'))">
|
|
35
|
+
<div class="flex flex-row gap-5 ml-3">
|
|
36
|
+
<CopyToClipboard :value="computedIframeSrc" @copied="toast($t('URL Copied'))">
|
|
44
37
|
<svg width="14" height="14" class="fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM352 32.491a15.88 15.88 0 0 1 7.431 4.195l51.882 51.883A15.885 15.885 0 0 1 415.508 96H352V32.491zM288 464c0 8.822-7.178 16-16 16H48c-8.822 0-16-7.178-16-16V144c0-8.822 7.178-16 16-16h80v240c0 26.51 21.49 48 48 48h112v48zm128-96c0 8.822-7.178 16-16 16H176c-8.822 0-16-7.178-16-16V48c0-8.822 7.178-16 16-16h144v72c0 13.2 10.8 24 24 24h72v240z"/></svg>
|
|
45
38
|
</CopyToClipboard>
|
|
46
|
-
<a type="button" class="w-[
|
|
39
|
+
<a type="button" class="w-[24px]" :href="computedIframeSrc" target="_blank">
|
|
47
40
|
<svg width="12" height="12" class="fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M497.6,0,334.4.17A14.4,14.4,0,0,0,320,14.57V47.88a14.4,14.4,0,0,0,14.69,14.4l73.63-2.72,2.06,2.06L131.52,340.49a12,12,0,0,0,0,17l23,23a12,12,0,0,0,17,0L450.38,101.62l2.06,2.06-2.72,73.63A14.4,14.4,0,0,0,464.12,192h33.31a14.4,14.4,0,0,0,14.4-14.4L512,14.4A14.4,14.4,0,0,0,497.6,0ZM432,288H416a16,16,0,0,0-16,16V458a6,6,0,0,1-6,6H54a6,6,0,0,1-6-6V118a6,6,0,0,1,6-6H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V304A16,16,0,0,0,432,288Z"/></svg>
|
|
48
41
|
</a>
|
|
49
42
|
</div>
|
|
@@ -51,9 +44,9 @@
|
|
|
51
44
|
</Textbox>
|
|
52
45
|
</div>
|
|
53
46
|
|
|
54
|
-
<Tabs :items="previewModes" v-model="store.previewMode" variant="button" @change="updateIframe" />
|
|
47
|
+
<Tabs :items="previewModes" v-model="store.previewMode" variant="button" @change="updateIframe" class="rounded-full" />
|
|
55
48
|
|
|
56
|
-
<div v-if="pageHistory" class="flex flex-row border-[1px] border-
|
|
49
|
+
<div v-if="pageHistory" class="flex flex-row border-[1px] border-border-200 bg-text-50 rounded-full overflow-hidden">
|
|
57
50
|
<button type="button" class="p-2 px-3 group"
|
|
58
51
|
:class="pageHistory.canUndo.value && pageHistory.history.value.length > 2 ? 'hover:bg-primary' : 'opacity-50 cursor-not-allowed'"
|
|
59
52
|
:disabled="!(pageHistory.canUndo.value && pageHistory.history.value.length > 2)"
|
|
@@ -76,27 +69,27 @@
|
|
|
76
69
|
class="w-[70px] rounded-full p-1"
|
|
77
70
|
:state="canSave ? 1 : -1"
|
|
78
71
|
@click="save">{{ $t('Save') }}</Button>
|
|
72
|
+
|
|
79
73
|
</div>
|
|
80
74
|
</div>
|
|
81
75
|
|
|
82
76
|
<div class="flex-1 flex flex-row">
|
|
83
77
|
|
|
84
|
-
<div class="flex flex-row
|
|
78
|
+
<div ref="leftPanel" class="flex flex-row"
|
|
85
79
|
:style="section1Style">
|
|
86
80
|
|
|
87
81
|
<div class="flex-1 flex flex-col overflow-y-auto">
|
|
88
82
|
|
|
89
|
-
<div class="flex flex-col
|
|
83
|
+
<div class="flex flex-col px-3 border-b-[1px] border-border-100 overflow-x-auto no-scrollbar pt-1">
|
|
90
84
|
<Tabs :items="tabItems"
|
|
91
|
-
class="pt-1"
|
|
92
85
|
v-model="store.tabIndex" />
|
|
93
86
|
</div>
|
|
94
87
|
|
|
95
|
-
<div v-if="store.tabIndex === 1" class="flex-1 overflow-y-auto flex flex-col gap-4 p-6"
|
|
88
|
+
<div v-if="store.tabIndex === 1" class="flex-1 overflow-y-auto flex flex-col gap-4 p-6">
|
|
96
89
|
|
|
97
90
|
<div class="flex flex-row gap-4" v-if="!page.isSystem">
|
|
98
91
|
<div class="flex flex-col gap-1">
|
|
99
|
-
<
|
|
92
|
+
<small class="text-text-400 w-[40px]">{{ $t('Status') }}</small>
|
|
100
93
|
<Dropdown v-model="page.status">
|
|
101
94
|
<option :value="-1">{{ $t('Disabled') }}</option>
|
|
102
95
|
<option :value="0">{{ $t('Draft') }}</option>
|
|
@@ -105,52 +98,55 @@
|
|
|
105
98
|
</div>
|
|
106
99
|
|
|
107
100
|
<div class="flex-1">
|
|
108
|
-
<
|
|
101
|
+
<small class="text-text-400">{{ $t('Path')}}</small>
|
|
109
102
|
<Textbox v-model="page.path" />
|
|
110
103
|
</div>
|
|
111
104
|
</div>
|
|
112
105
|
|
|
113
106
|
<div class="flex flex-col gap-1">
|
|
114
|
-
<
|
|
107
|
+
<small class="text-text-400">{{ $t('Title')}}</small>
|
|
115
108
|
<Textbox v-model="page.title" />
|
|
116
109
|
</div>
|
|
117
110
|
|
|
118
111
|
<div class="flex flex-col gap-1">
|
|
119
|
-
<
|
|
112
|
+
<small class="text-text-400">{{ $t('Description')}}</small>
|
|
120
113
|
<Textarea v-model="page.description" />
|
|
121
114
|
</div>
|
|
122
115
|
|
|
123
116
|
<div class="flex flex-col gap-1">
|
|
124
|
-
<
|
|
117
|
+
<small class="text-text-400">{{ $t('Keywords')}}</small>
|
|
125
118
|
<Textbox v-model="page.keywords" />
|
|
126
119
|
</div>
|
|
127
120
|
|
|
128
121
|
<div>
|
|
129
122
|
<div class="mb-1">
|
|
130
|
-
<
|
|
123
|
+
<small class="text-text-400">{{ $t('OG')}}</small>
|
|
131
124
|
</div>
|
|
132
|
-
<div class="flex flex-row gap-
|
|
133
|
-
@click="$refs.ogModal.open({ ...this.page.og })"
|
|
125
|
+
<div class="flex flex-row gap-2 bg-base-500 border-[1px] border-border-200 rounded-lg p-1 cursor-pointer"
|
|
126
|
+
@click="$refs.ogModal.open({ ...this.page.og }, og => page.og = og)"
|
|
134
127
|
v-if="page.og && Object.keys(page.og).length > 0">
|
|
135
128
|
<div>
|
|
136
|
-
<Image :src="
|
|
129
|
+
<Image :src="page.og.image" class="w-[40px] aspect-square bg-text-50" />
|
|
137
130
|
</div>
|
|
138
131
|
<div class="flex-1 flex flex-col">
|
|
139
|
-
<
|
|
140
|
-
|
|
141
|
-
|
|
132
|
+
<label class="text-sm text-ellipsis-nowrap">
|
|
133
|
+
{{ page.og.title }}
|
|
134
|
+
</label>
|
|
135
|
+
<small class="text-sm text-ellipsis-nowrap">
|
|
136
|
+
{{ page.og.description }}
|
|
137
|
+
</small>
|
|
142
138
|
</div>
|
|
143
139
|
</div>
|
|
144
|
-
<div v-else class="bg-base-500 p-2 text-center border-[1px] border-
|
|
145
|
-
@click="$refs.ogModal.open(
|
|
140
|
+
<div v-else class="bg-base-500 p-2 text-center border-[1px] border-border-100 rounded-lg cursor-pointer"
|
|
141
|
+
@click="$refs.ogModal.open(page.og, og => page.og = og)">
|
|
146
142
|
Set OG
|
|
147
143
|
</div>
|
|
148
144
|
</div>
|
|
149
145
|
|
|
150
146
|
<div>
|
|
151
147
|
<div class="flex flex-row gap-2 mb-1">
|
|
152
|
-
<
|
|
153
|
-
<button type="button" class="text-primary" @click="$refs.ldjsonModal.open({})">
|
|
148
|
+
<small class="flex-1 text-text-400">{{ $t('JSON-LD')}}</small>
|
|
149
|
+
<button type="button" class="text-primary text-sm" @click="$refs.ldjsonModal.open({})">
|
|
154
150
|
{{ $t('Add') }}
|
|
155
151
|
</button>
|
|
156
152
|
</div>
|
|
@@ -166,46 +162,97 @@
|
|
|
166
162
|
</div>
|
|
167
163
|
</template>
|
|
168
164
|
</ListItem>
|
|
169
|
-
<div v-else class="bg-base-500 p-2 text-center border-[1px] border-
|
|
165
|
+
<div v-else class="bg-base-500 p-2 text-center border-[1px] border-border-100 rounded-lg cursor-pointer text-text-300">
|
|
170
166
|
No JSON-LD set
|
|
171
167
|
</div>
|
|
172
168
|
</div>
|
|
173
169
|
|
|
174
170
|
<div>
|
|
175
|
-
<
|
|
176
|
-
<Dropdown v-model="page.noIndex" class="max-w-[
|
|
171
|
+
<small class="flex-1 text-text-400">{{ $t('No Index')}}</small>
|
|
172
|
+
<Dropdown v-model="page.noIndex" class="w-full max-w-[300px]">
|
|
177
173
|
<option value="none">None</option>
|
|
178
174
|
<option value="robots">All</option>
|
|
179
175
|
<option value="googlebot">Google Bot</option>
|
|
180
176
|
</Dropdown>
|
|
181
177
|
</div>
|
|
182
178
|
|
|
183
|
-
|
|
179
|
+
</div>
|
|
180
|
+
|
|
181
|
+
<div v-else-if="store.tabIndex === 2" class="flex-1 overflow-y-auto p-6 flex flex-col gap-6">
|
|
184
182
|
|
|
185
183
|
<div>
|
|
186
|
-
<
|
|
187
|
-
|
|
188
|
-
<
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
184
|
+
<div class="flex flex-row gap-1 items-end cursor-pointer">
|
|
185
|
+
<small class="flex-1 text-text-400 text-overflow-ellipsis">{{ $t('Components')}}</small>
|
|
186
|
+
<button type="button" class="text-primary text-sm flex flex-row items-center gap-1"
|
|
187
|
+
@click="openComponentSelector({ callback:(component) => page.components.push(component) })">
|
|
188
|
+
{{ $t('Add')}}
|
|
189
|
+
</button>
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
<div class="flex flex-col gap-10">
|
|
193
|
+
<TreeView class="mt-2"
|
|
194
|
+
v-model="page.components"
|
|
195
|
+
:selected-item="currentItem"
|
|
196
|
+
@add="(items) => openComponentSelector({ callback:(component) => items.push(component) })"
|
|
197
|
+
@duplicate="duplicate"
|
|
198
|
+
@change="pageHistory.commit()">
|
|
199
|
+
<template #default="{ item }">
|
|
200
|
+
<div class="flex-1 text-ellipsis whitespace-nowrap overflow-hidden"
|
|
201
|
+
:class="!item.props.enabled ? 'line-through' : ''"
|
|
202
|
+
@click="select(item.uid)">
|
|
203
|
+
{{ item.props.name ?? item.type }}
|
|
204
|
+
</div>
|
|
205
|
+
</template>
|
|
206
|
+
</TreeView>
|
|
207
|
+
</div>
|
|
208
|
+
</div>
|
|
209
|
+
|
|
210
|
+
</div>
|
|
211
|
+
|
|
212
|
+
<div v-else-if="store.tabIndex === 3" class="flex-1 overflow-y-auto p-6">
|
|
213
|
+
|
|
214
|
+
<div class="p-6 flex flex-col gap-2" v-if="Array.isArray(page.datasource) && page.datasource.length > 0">
|
|
215
|
+
<div v-for="(ds, index) in page.datasource"
|
|
216
|
+
class="p-3 border-[1px] border-border-50 rounded-lg flex flex-row items-start gap-2">
|
|
217
|
+
<div class="flex-1 flex flex-col" @click="$refs.webDatasourceSelector.open({ _index:index, ...ds })">
|
|
218
|
+
<label>{{ ds.name }}</label>
|
|
219
|
+
</div>
|
|
220
|
+
<button type="button"
|
|
221
|
+
@click="removeDatasource(index)">
|
|
222
|
+
<svg width="14" height="14" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z"/></svg>
|
|
223
|
+
</button>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
<div v-else>
|
|
227
|
+
<div class="p-6 text-center">
|
|
228
|
+
<small class="text-text-400">{{ $t('No Datasource')}}</small>
|
|
229
|
+
</div>
|
|
192
230
|
</div>
|
|
193
231
|
|
|
194
|
-
<div class="
|
|
232
|
+
<div class="text-center" v-if="useDatasource">
|
|
233
|
+
<button type="button" class="text-primary"
|
|
234
|
+
@click="$refs.webDatasourceSelector.create()">
|
|
235
|
+
Add Datasource
|
|
236
|
+
</button>
|
|
237
|
+
</div>
|
|
238
|
+
|
|
239
|
+
<WebDatasourceSelector ref="webDatasourceSelector"
|
|
240
|
+
@apply="addDatasource"
|
|
241
|
+
:use-datasource="useDatasource" />
|
|
195
242
|
|
|
196
243
|
</div>
|
|
197
244
|
|
|
198
|
-
<div v-else-if="store.tabIndex ===
|
|
245
|
+
<div v-else-if="store.tabIndex === 4" class="flex-1 overflow-y-auto flex flex-col">
|
|
199
246
|
|
|
200
|
-
<div>
|
|
201
|
-
<div class="flex flex-row gap-2"
|
|
202
|
-
<
|
|
203
|
-
<button type="button" class="text-primary" @click="store.layoutMode = !store.layoutMode">
|
|
204
|
-
{{ store.layoutMode ? 'Hide Layout' : '
|
|
247
|
+
<div class="p-6">
|
|
248
|
+
<div class="flex flex-row items-end gap-2">
|
|
249
|
+
<small class="flex-1 text-text-400">{{ $t('Layout')}}</small>
|
|
250
|
+
<button type="button" class="text-primary text-sm" @click="store.layoutMode = !store.layoutMode">
|
|
251
|
+
{{ store.layoutMode ? 'Hide Layout' : 'Edit Layout' }}
|
|
205
252
|
</button>
|
|
206
253
|
</div>
|
|
207
|
-
<div class="mt-
|
|
208
|
-
<div class="cursor-pointer bg-text-50 p-2 border-[1px] border-
|
|
254
|
+
<div class="mt-1">
|
|
255
|
+
<div class="cursor-pointer bg-text-50 p-2 border-[1px] border-border-200 flex flex-row items-center rounded-lg"
|
|
209
256
|
@click="(e) => $refs.layoutSelector.open(e.target)">
|
|
210
257
|
<div class="flex-1 pointer-events-none">
|
|
211
258
|
{{ layout ? (layout.name ?? layout.title) : 'None' }}
|
|
@@ -218,19 +265,21 @@
|
|
|
218
265
|
</div>
|
|
219
266
|
|
|
220
267
|
<ContextMenu ref="layoutSelector">
|
|
221
|
-
<div class="flex flex-col min-w-[260px] divide-y divide-
|
|
268
|
+
<div class="flex flex-col min-w-[260px] divide-y divide-border-50">
|
|
222
269
|
|
|
223
|
-
<div
|
|
270
|
+
<div @click="page.layoutId = null;" :class="appStyle.menuItem">None</div>
|
|
224
271
|
|
|
225
272
|
<div v-for="layout in layouts"
|
|
226
|
-
class="
|
|
273
|
+
:class="appStyle.menuItem"
|
|
227
274
|
@click="page.layoutId = layout.id;pageHistory.commit()">
|
|
228
275
|
{{ layout.name ?? layout.title }}
|
|
229
276
|
</div>
|
|
230
277
|
|
|
231
|
-
<div class="flex flex-row"
|
|
232
|
-
<
|
|
233
|
-
|
|
278
|
+
<div class="flex flex-row">
|
|
279
|
+
<button type="button" class="p-3 flex-1 cursor-pointer text-primary"
|
|
280
|
+
@click="$refs.webLayoutSelector.create({})">
|
|
281
|
+
Create New...
|
|
282
|
+
</button>
|
|
234
283
|
</div>
|
|
235
284
|
|
|
236
285
|
</div>
|
|
@@ -238,57 +287,26 @@
|
|
|
238
287
|
</div>
|
|
239
288
|
</div>
|
|
240
289
|
|
|
241
|
-
<div v-if="
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
@click="store.selectedComponent = [ 'style' ]">Edit Style</button>
|
|
246
|
-
</div>
|
|
247
|
-
|
|
248
|
-
<div v-if="store.layoutMode && layout" @click="currentArea = 'headers'">
|
|
249
|
-
<div class="flex flex-row gap-1 items-center cursor-pointer">
|
|
250
|
-
<svg v-if="!expanded['headers']" width="12" height="12" @click="expanded['headers'] = !expanded['headers']" class="fill-text" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 192 512"><path d="M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z"/></svg>
|
|
251
|
-
<svg v-else width="12" height="12" @click="expanded['headers'] = !expanded['headers']" class="fill-text" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"/></svg>
|
|
252
|
-
<strong class="flex-1 text-text-400 line-clamp-1" @click="expanded['headers'] = !expanded['headers']">{{ $t('Header')}}</strong>
|
|
253
|
-
<button type="button" class="text-primary flex flex-row items-center gap-1"
|
|
254
|
-
@click="openComponentSelector({ items:layout.headers, isLayout:true })">
|
|
255
|
-
<svg width="16" height="16" class="fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path d="M376 232H216V72c0-4.42-3.58-8-8-8h-32c-4.42 0-8 3.58-8 8v160H8c-4.42 0-8 3.58-8 8v32c0 4.42 3.58 8 8 8h160v160c0 4.42 3.58 8 8 8h32c4.42 0 8-3.58 8-8V280h160c4.42 0 8-3.58 8-8v-32c0-4.42-3.58-8-8-8z"/></svg>
|
|
256
|
-
{{ $t('Add')}}
|
|
257
|
-
</button>
|
|
258
|
-
</div>
|
|
259
|
-
<div v-if="expanded['headers']" class="flex flex-col gap-10">
|
|
260
|
-
<TreeView class="mt-2"
|
|
261
|
-
v-model="layoutHeaders"
|
|
262
|
-
:selected-item="currentItem"
|
|
263
|
-
@add="(items) => openComponentSelector({ items })">
|
|
264
|
-
<template #default="{ item }">
|
|
265
|
-
<div class="flex-1 text-ellipsis whitespace-nowrap overflow-hidden"
|
|
266
|
-
:class="!item.props.enabled ? 'line-through' : ''"
|
|
267
|
-
@click="select(item.uid)">
|
|
268
|
-
{{ item.name ?? item.type }}
|
|
269
|
-
</div>
|
|
270
|
-
</template>
|
|
271
|
-
</TreeView>
|
|
290
|
+
<div v-if="layout" class="flex flex-col gap-6 p-6 border-t-[1px] border-border-50">
|
|
291
|
+
<div>
|
|
292
|
+
<small class="text-text-400">Name</small>
|
|
293
|
+
<Textbox v-model="layout.title"/>
|
|
272
294
|
</div>
|
|
273
|
-
</div>
|
|
274
295
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
{{ $t('Add')}}
|
|
284
|
-
</button>
|
|
285
|
-
</div>
|
|
296
|
+
<div>
|
|
297
|
+
<div class="flex flex-row gap-1 items-end cursor-pointer">
|
|
298
|
+
<small class="flex-1 text-text-400 text-overflow-ellipsis">{{ $t('Headers')}}</small>
|
|
299
|
+
<button type="button" class="text-primary text-sm flex flex-row items-center gap-1"
|
|
300
|
+
@click="openComponentSelector({ callback:(component) => layout.headers.push(component) })">
|
|
301
|
+
{{ $t('Add')}}
|
|
302
|
+
</button>
|
|
303
|
+
</div>
|
|
286
304
|
|
|
287
|
-
<div v-if="expanded['components']" class="flex flex-col gap-10">
|
|
288
305
|
<TreeView class="mt-2"
|
|
289
|
-
v-model="
|
|
306
|
+
v-model="layout.headers"
|
|
290
307
|
:selected-item="currentItem"
|
|
291
|
-
@add="(items) => openComponentSelector({ items })"
|
|
308
|
+
@add="(items) => openComponentSelector({ callback:(component) => items.push(component) })"
|
|
309
|
+
@duplicate="duplicate"
|
|
292
310
|
@change="pageHistory.commit()">
|
|
293
311
|
<template #default="{ item }">
|
|
294
312
|
<div class="flex-1 text-ellipsis whitespace-nowrap overflow-hidden"
|
|
@@ -300,25 +318,21 @@
|
|
|
300
318
|
</TreeView>
|
|
301
319
|
</div>
|
|
302
320
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
@click="openComponentSelector({ items:layoutFooters, isLayout:true })">
|
|
312
|
-
<svg width="16" height="16" class="fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path d="M376 232H216V72c0-4.42-3.58-8-8-8h-32c-4.42 0-8 3.58-8 8v160H8c-4.42 0-8 3.58-8 8v32c0 4.42 3.58 8 8 8h160v160c0 4.42 3.58 8 8 8h32c4.42 0 8-3.58 8-8V280h160c4.42 0 8-3.58 8-8v-32c0-4.42-3.58-8-8-8z"/></svg>
|
|
313
|
-
{{ $t('Add')}}
|
|
314
|
-
</button>
|
|
315
|
-
</div>
|
|
321
|
+
<div>
|
|
322
|
+
<div class="flex flex-row gap-1 items-end cursor-pointer">
|
|
323
|
+
<small class="flex-1 text-text-400 text-overflow-ellipsis">{{ $t('Footers')}}</small>
|
|
324
|
+
<button type="button" class="text-primary text-sm flex flex-row items-center gap-1"
|
|
325
|
+
@click="openComponentSelector({ callback:(component) => layout.footers.push(component) })">
|
|
326
|
+
{{ $t('Add')}}
|
|
327
|
+
</button>
|
|
328
|
+
</div>
|
|
316
329
|
|
|
317
|
-
<div v-if="expanded['footers']" class="flex flex-col gap-10">
|
|
318
330
|
<TreeView class="mt-2"
|
|
319
|
-
v-model="
|
|
331
|
+
v-model="layout.footers"
|
|
320
332
|
:selected-item="currentItem"
|
|
321
|
-
@add="(items) => openComponentSelector({ items })"
|
|
333
|
+
@add="(items) => openComponentSelector({ callback:(component) => items.push(component) })"
|
|
334
|
+
@duplicate="duplicate"
|
|
335
|
+
@change="pageHistory.commit()">
|
|
322
336
|
<template #default="{ item }">
|
|
323
337
|
<div class="flex-1 text-ellipsis whitespace-nowrap overflow-hidden"
|
|
324
338
|
:class="!item.props.enabled ? 'line-through' : ''"
|
|
@@ -328,51 +342,17 @@
|
|
|
328
342
|
</template>
|
|
329
343
|
</TreeView>
|
|
330
344
|
</div>
|
|
331
|
-
</div>
|
|
332
345
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
@apply="addComponent"
|
|
341
|
-
dismissable="true"
|
|
342
|
-
@dismiss="$refs.webPageComponentSelector.close()" />
|
|
343
|
-
|
|
344
|
-
</div>
|
|
345
|
-
|
|
346
|
-
<div v-else-if="store.tabIndex === 3" class="flex-1 overflow-y-auto p-6" @click="currentArea = 'datasource'">
|
|
347
|
-
|
|
348
|
-
<div class="p-6 flex flex-col gap-2" v-if="Array.isArray(page.datasource) && page.datasource.length > 0">
|
|
349
|
-
<div v-for="(ds, index) in page.datasource"
|
|
350
|
-
class="p-3 border-[1px] border-text-50 rounded-lg flex flex-row items-start gap-2">
|
|
351
|
-
<div class="flex-1 flex flex-col" @click="$refs.webDatasourceSelector.open({ _index:index, ...ds })">
|
|
352
|
-
<label>{{ ds.name }}</label>
|
|
346
|
+
<div>
|
|
347
|
+
<div class="flex flex-row gap-1 items-end cursor-pointer">
|
|
348
|
+
<small class="flex-1 text-text-400 text-overflow-ellipsis">{{ $t('Styles')}}</small>
|
|
349
|
+
<button type="button" class="text-primary text-sm flex flex-row items-center gap-1"
|
|
350
|
+
@click="select('style')">
|
|
351
|
+
{{ $t('Edit Style')}}
|
|
352
|
+
</button>
|
|
353
353
|
</div>
|
|
354
|
-
<button type="button"
|
|
355
|
-
@click="removeDatasource(index)">
|
|
356
|
-
<svg width="14" height="14" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z"/></svg>
|
|
357
|
-
</button>
|
|
358
354
|
</div>
|
|
359
355
|
</div>
|
|
360
|
-
<div v-else>
|
|
361
|
-
<div class="p-6 text-center">
|
|
362
|
-
<label class="text-text-400">{{ $t('No Datasource')}}</label>
|
|
363
|
-
</div>
|
|
364
|
-
</div>
|
|
365
|
-
|
|
366
|
-
<div class="text-center" v-if="useDatasource">
|
|
367
|
-
<button type="button" class="text-primary"
|
|
368
|
-
@click="$refs.webDatasourceSelector.create()">
|
|
369
|
-
Add Datasource
|
|
370
|
-
</button>
|
|
371
|
-
</div>
|
|
372
|
-
|
|
373
|
-
<WebDatasourceSelector ref="webDatasourceSelector"
|
|
374
|
-
@apply="addDatasource"
|
|
375
|
-
:use-datasource="useDatasource" />
|
|
376
356
|
|
|
377
357
|
</div>
|
|
378
358
|
|
|
@@ -381,107 +361,41 @@
|
|
|
381
361
|
<div :class="$style.resize1"
|
|
382
362
|
@mousedown="(e) => $util.dragResize(e, resize1)"></div>
|
|
383
363
|
|
|
384
|
-
|
|
385
|
-
<template v-slot:head>
|
|
386
|
-
<div class="relative p-5">
|
|
387
|
-
<h3>{{ $t('Edit OG')}}</h3>
|
|
388
|
-
<div class="absolute top-0 right-0 p-2">
|
|
389
|
-
<button type="button" class="p-2" @click="$refs.ogModal.close()">
|
|
390
|
-
<svg width="24" height="24" viewBox="0 0 24 24" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg">
|
|
391
|
-
<path d="M6.53034 5.46965C6.23745 5.17676 5.76257 5.17676 5.46968 5.46965C5.17679 5.76255 5.17679 6.23742 5.46968 6.53031L10.9393 12L5.46967 17.4697C5.17678 17.7626 5.17678 18.2374 5.46967 18.5303C5.76256 18.8232 6.23744 18.8232 6.53033 18.5303L12 13.0606L17.4697 18.5303C17.7626 18.8232 18.2375 18.8232 18.5303 18.5303C18.8232 18.2374 18.8232 17.7626 18.5303 17.4697L13.0607 12L18.5303 6.53032C18.8232 6.23743 18.8232 5.76256 18.5303 5.46966C18.2374 5.17677 17.7626 5.17677 17.4697 5.46966L12 10.9393L6.53034 5.46965Z"/>
|
|
392
|
-
</svg>
|
|
393
|
-
</button>
|
|
394
|
-
</div>
|
|
395
|
-
</div>
|
|
396
|
-
</template>
|
|
397
|
-
<template v-slot:foot="{ context }">
|
|
398
|
-
<div class="p-5">
|
|
399
|
-
<Button type="button" class="w-[100px]"
|
|
400
|
-
@click="Object.assign(this.page.og, context);$refs.ogModal.close()">
|
|
401
|
-
OK
|
|
402
|
-
</Button>
|
|
403
|
-
</div>
|
|
404
|
-
</template>
|
|
405
|
-
<template #default="{ context }">
|
|
406
|
-
<div class="flex-1 p-5 flex flex-col gap-4">
|
|
407
|
-
<div class="flex flex-row gap-4">
|
|
408
|
-
<div>
|
|
409
|
-
<label class="text-text-400">Type</label>
|
|
410
|
-
<Dropdown v-model="context.type" class="mt-1 w-[120px]">
|
|
411
|
-
<option value="website">Website</option>
|
|
412
|
-
<option value="article">Article</option>
|
|
413
|
-
</Dropdown>
|
|
414
|
-
</div>
|
|
415
|
-
<div class="flex-1">
|
|
416
|
-
<label class="text-text-400">Title</label>
|
|
417
|
-
<Textbox v-model="context.title" class="mt-1" />
|
|
418
|
-
</div>
|
|
419
|
-
</div>
|
|
364
|
+
</div>
|
|
420
365
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
366
|
+
<div ref="preview" class="flex-1 relative" :class="previewClass">
|
|
367
|
+
|
|
368
|
+
<div class="flex flex-row gap-4 items-center p-2">
|
|
369
|
+
<select v-model="store.zoomLevel" :class="$style.zoomLevel">
|
|
370
|
+
<optgroup label="Zoom Level">
|
|
371
|
+
<option value="fit">Fit</option>
|
|
372
|
+
<option value="125%">125%</option>
|
|
373
|
+
<option value="100%">100%</option>
|
|
374
|
+
<option value="75%">75%</option>
|
|
375
|
+
<option value="50%">50%</option>
|
|
376
|
+
</optgroup>
|
|
377
|
+
</select>
|
|
425
378
|
|
|
426
|
-
|
|
427
|
-
<label class="text-text-400">Url</label>
|
|
428
|
-
<Textbox v-model="context.url" class="mt-1" />
|
|
429
|
-
</div>
|
|
379
|
+
<div class="flex-1"></div>
|
|
430
380
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
</div>
|
|
437
|
-
<div class="mt-1">
|
|
438
|
-
<Image ref="ogImage" :src="imageUrl(context)" class="w-[80px] aspect-square"
|
|
439
|
-
:editable="true"
|
|
440
|
-
@change="(base64, file) => { uploadImage(file).then((res) => context.imageUrl = res.name); }" />
|
|
441
|
-
</div>
|
|
442
|
-
</div>
|
|
443
|
-
</div>
|
|
444
|
-
</template>
|
|
445
|
-
</Modal>
|
|
446
|
-
|
|
447
|
-
<Modal ref="ldjsonModal" width="600" height="480">
|
|
448
|
-
<template v-slot:head>
|
|
449
|
-
<div class="relative p-5">
|
|
450
|
-
<h3>JSON-LD</h3>
|
|
451
|
-
<div class="absolute top-0 right-0 p-2">
|
|
452
|
-
<button type="button" class="p-2" @click="$refs.ldjsonModal.close()">
|
|
453
|
-
<svg width="24" height="24" viewBox="0 0 24 24" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg">
|
|
454
|
-
<path d="M6.53034 5.46965C6.23745 5.17676 5.76257 5.17676 5.46968 5.46965C5.17679 5.76255 5.17679 6.23742 5.46968 6.53031L10.9393 12L5.46967 17.4697C5.17678 17.7626 5.17678 18.2374 5.46967 18.5303C5.76256 18.8232 6.23744 18.8232 6.53033 18.5303L12 13.0606L17.4697 18.5303C17.7626 18.8232 18.2375 18.8232 18.5303 18.5303C18.8232 18.2374 18.8232 17.7626 18.5303 17.4697L13.0607 12L18.5303 6.53032C18.8232 6.23743 18.8232 5.76256 18.5303 5.46966C18.2374 5.17677 17.7626 5.17677 17.4697 5.46966L12 10.9393L6.53034 5.46965Z"/>
|
|
455
|
-
</svg>
|
|
381
|
+
<div class="flex flex-row border-[1px] border-border-200 divide-x divide-border-50" :class="$style.zoomLevel">
|
|
382
|
+
<Radio v-for="_type in viewTypes" :value="_type.value" v-model="store.viewType" :custom="true">
|
|
383
|
+
<template #default="">
|
|
384
|
+
<button v-if="_type.value === ''" type="button" class="w-[30px] flex items-center justify-center">
|
|
385
|
+
<svg width="14" height="14" :class="_type.value === store.viewType ? 'fill-primary' : 'fill-text'" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M320 0H64C37.5 0 16 21.5 16 48v416C16 490.5 37.5 512 64 512h256c26.5 0 48-21.5 48-48v-416C368 21.5 346.5 0 320 0zM240 447.1C240 456.8 232.8 464 224 464H159.1C151.2 464 144 456.8 144 448S151.2 432 160 432h64C232.8 432 240 439.2 240 447.1zM304 384h-224V64h224V384z"/></svg>
|
|
456
386
|
</button>
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
<div class="flex-1 p-5">
|
|
470
|
-
<Textarea v-model="context.code" rows="10" ></Textarea>
|
|
471
|
-
</div>
|
|
472
|
-
</template>
|
|
473
|
-
</Modal>
|
|
474
|
-
|
|
475
|
-
</div>
|
|
476
|
-
|
|
477
|
-
<div class="flex-1 bg-base-300 dark:bg-base-400 relative" :class="previewClass" ref="preview"
|
|
478
|
-
@click="currentArea = 'preview'">
|
|
479
|
-
<div class="flex flex-row p-2">
|
|
480
|
-
<select class="p-1 text-sm cursor-pointer bg-text-50 outline-none"
|
|
481
|
-
v-model="store.previewViewType"
|
|
482
|
-
@change="resize">
|
|
483
|
-
<option v-for="_type in previewViewTypes" :value="_type.value">{{ _type.text }}</option>
|
|
484
|
-
</select>
|
|
387
|
+
<button v-if="_type.value === 'md:'" type="button" class="w-[30px] flex items-center justify-center">
|
|
388
|
+
<svg width="14" height="14" :class="_type.value === store.viewType ? 'fill-primary' : 'fill-text'" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M384 .0001H64c-35.35 0-64 28.65-64 64v384c0 35.35 28.65 63.1 64 63.1h320c35.35 0 64-28.65 64-63.1v-384C448 28.65 419.3 .0001 384 .0001zM288 448c0 8.837-7.163 16-15.1 16H175.1c-8.837 0-15.1-7.163-15.1-16s7.163-16 15.1-16h96C280.8 432 288 439.2 288 448zM384 384H64v-320h320V384z"/></svg>
|
|
389
|
+
</button>
|
|
390
|
+
<button v-if="_type.value === 'xl:'" type="button" class="w-[30px] flex items-center justify-center">
|
|
391
|
+
<svg width="14" height="14" :class="_type.value === store.viewType ? 'fill-primary' : 'fill-text'" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M528 0h-480C21.5 0 0 21.5 0 48v320C0 394.5 21.5 416 48 416h192L224 464H152C138.8 464 128 474.8 128 488S138.8 512 152 512h272c13.25 0 24-10.75 24-24s-10.75-24-24-24H352L336 416h192c26.5 0 48-21.5 48-48v-320C576 21.5 554.5 0 528 0zM512 288H64V64h448V288z"/></svg>
|
|
392
|
+
</button>
|
|
393
|
+
<button v-if="_type.value === '2xl:'" type="button" class="w-[30px] flex items-center justify-center">
|
|
394
|
+
<svg width="14" height="14" :class="_type.value === store.viewType ? 'fill-primary' : 'fill-text'" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M512 448H127.1C110.3 448 96 462.3 96 479.1S110.3 512 127.1 512h384C529.7 512 544 497.7 544 480S529.7 448 512 448zM592 0h-544C21.5 0 0 21.5 0 48v320C0 394.5 21.5 416 48 416h544c26.5 0 48-21.5 48-48v-320C640 21.5 618.5 0 592 0zM576 352H64v-288h512V352z"/></svg>
|
|
395
|
+
</button>
|
|
396
|
+
</template>
|
|
397
|
+
</Radio>
|
|
398
|
+
</div>
|
|
485
399
|
</div>
|
|
486
400
|
|
|
487
401
|
<div class="p-6">
|
|
@@ -490,74 +404,97 @@
|
|
|
490
404
|
</div>
|
|
491
405
|
</div>
|
|
492
406
|
|
|
493
|
-
<div v-if="currentItem" class="flex flex-
|
|
494
|
-
|
|
495
|
-
:style="section3Style">
|
|
496
|
-
|
|
497
|
-
<div class="px-6 py-4 flex flex-row items-center gap-2">
|
|
498
|
-
<Textbox v-if="currentItem.type !== 'Style'"
|
|
499
|
-
v-model="currentItem.props.name"
|
|
500
|
-
:placeholder="currentItem.type"
|
|
501
|
-
class="bg-base-500 rounded-full flex-1"
|
|
502
|
-
item-class="p-0 px-2"
|
|
503
|
-
variant="minimal">
|
|
504
|
-
<template #start>
|
|
505
|
-
<div class="pl-3">
|
|
506
|
-
<Switch v-model="currentItem.props.enabled"/>
|
|
507
|
-
</div>
|
|
508
|
-
</template>
|
|
509
|
-
</Textbox>
|
|
407
|
+
<div v-if="currentItem" ref="rightPanel" class="flex flex-row"
|
|
408
|
+
:style="section3Style" @click.meta="log(currentItem)">
|
|
510
409
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
</div>
|
|
514
|
-
</div>
|
|
410
|
+
<div :class="$style.resize3"
|
|
411
|
+
@mousedown="(e) => $util.dragResize(e, resize3)"></div>
|
|
515
412
|
|
|
516
|
-
<div
|
|
517
|
-
|
|
518
|
-
<template #tab="{ item }">
|
|
519
|
-
<div v-if="item.value === ''" class="px-6 p-2 border-[1px] border-b-0 relative top-[1px] rounded-t-md overflow-hidden"
|
|
520
|
-
:class="store.viewType === item.value ? 'bg-base-400 border-text-50' : 'border-transparent'">
|
|
521
|
-
<div v-if="store.viewType === item.value" class="absolute top-0 left-0 right-0 h-[2px] bg-primary"></div>
|
|
522
|
-
Mobile
|
|
523
|
-
</div>
|
|
524
|
-
<div v-else-if="item.value === 'md:'" class="px-6 p-2 border-[1px] border-b-0 relative top-[1px] rounded-t-md overflow-hidden"
|
|
525
|
-
:class="store.viewType === item.value ? 'bg-base-400 border-text-50' : 'border-transparent'">
|
|
526
|
-
<div v-if="store.viewType === item.value" class="absolute top-0 left-0 right-0 h-[2px] bg-primary"></div>
|
|
527
|
-
Tablet
|
|
528
|
-
</div>
|
|
529
|
-
</template>
|
|
530
|
-
</Tabs>
|
|
531
|
-
</div>
|
|
413
|
+
<div class="flex-1 flex flex-col relative"
|
|
414
|
+
ref="rightPane">
|
|
532
415
|
|
|
533
|
-
|
|
416
|
+
<TransitionGroup name="openltr" tag="div" class="flex-1 flex flex-col">
|
|
534
417
|
|
|
535
|
-
|
|
536
|
-
@mousedown="(e) => $util.dragResize(e, resize3)"></div>
|
|
418
|
+
<div v-if="extRightPane === null" class="flex-1 flex flex-col divide-y divide-border-50 overflow-y-auto">
|
|
537
419
|
|
|
538
|
-
|
|
420
|
+
<div v-if="currentItem.type !== 'Style'" class="px-6 py-4 flex flex-row gap-5 items-start">
|
|
421
|
+
<div>
|
|
422
|
+
<small class="text-text-400">Enabled</small>
|
|
423
|
+
<Switch v-model="currentItem.props.enabled"/>
|
|
424
|
+
</div>
|
|
425
|
+
<div v-if="currentItem.type !== 'Style'" class="flex-1">
|
|
426
|
+
<small class="text-text-400">Name</small>
|
|
427
|
+
<Textbox v-model="currentItem.props.name"
|
|
428
|
+
:placeholder="currentItem.type"
|
|
429
|
+
class="bg-base-500 flex-1"
|
|
430
|
+
variant="minimal" />
|
|
431
|
+
</div>
|
|
432
|
+
<div v-else class="px-3">
|
|
433
|
+
<h4>Style</h4>
|
|
434
|
+
</div>
|
|
435
|
+
</div>
|
|
539
436
|
|
|
540
|
-
<div>
|
|
541
437
|
<component :is="`${currentItem.type}Setting`"
|
|
542
438
|
:item="currentItem"
|
|
543
439
|
:view-type="store.viewType"
|
|
440
|
+
:view-index="viewIndex"
|
|
544
441
|
:view-types="viewTypes"
|
|
545
442
|
ref="settingComponent"
|
|
546
443
|
@change="pageHistory.commit()"
|
|
547
444
|
@postMessageToIframe="onPostMessageToIframe"/>
|
|
445
|
+
|
|
446
|
+
<div class="p-6 py-4" v-if="debugMode">
|
|
447
|
+
<small class="text-text-400">Debug ID</small>
|
|
448
|
+
<Textbox v-model="currentItem.props.debugId" maxlength="5" />
|
|
449
|
+
</div>
|
|
450
|
+
|
|
451
|
+
<br />
|
|
452
|
+
<br />
|
|
453
|
+
<br />
|
|
454
|
+
|
|
548
455
|
</div>
|
|
549
456
|
|
|
550
|
-
<div class="
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
457
|
+
<div v-else-if="extRightPane?.type" class="flex-1 flex flex-col divide-y divide-border-50 overflow-y-auto">
|
|
458
|
+
|
|
459
|
+
<div class="px-6 py-4 flex flex-row gap-5 items-center">
|
|
460
|
+
<div class="flex flex-col">
|
|
461
|
+
<small class="text-text-400"> </small>
|
|
462
|
+
<button type="button" @click="extRightPane = null">
|
|
463
|
+
<svg width="14" height="14" class="fill-text" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M447.1 256C447.1 273.7 433.7 288 416 288H109.3l105.4 105.4c12.5 12.5 12.5 32.75 0 45.25C208.4 444.9 200.2 448 192 448s-16.38-3.125-22.62-9.375l-160-160c-12.5-12.5-12.5-32.75 0-45.25l160-160c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25L109.3 224H416C433.7 224 447.1 238.3 447.1 256z"/></svg>
|
|
464
|
+
</button>
|
|
465
|
+
</div>
|
|
466
|
+
<div>
|
|
467
|
+
<small class="text-text-400">Enabled</small>
|
|
468
|
+
<Switch v-model="extRightPane.props.enabled"/>
|
|
469
|
+
</div>
|
|
470
|
+
<div v-if="extRightPane.type !== 'Style'" class="flex-1">
|
|
471
|
+
<small class="text-text-400">Name</small>
|
|
472
|
+
<Textbox v-model="currentItem.props.name"
|
|
473
|
+
:placeholder="extRightPane.type"
|
|
474
|
+
class="bg-base-500 flex-1"
|
|
475
|
+
variant="minimal" />
|
|
476
|
+
</div>
|
|
477
|
+
<div v-else class="px-3">
|
|
478
|
+
<h4>Style</h4>
|
|
479
|
+
</div>
|
|
480
|
+
</div>
|
|
481
|
+
|
|
482
|
+
<component :is="`${extRightPane.type}Setting`"
|
|
483
|
+
:item="extRightPane"
|
|
484
|
+
:view-type="store.viewType"
|
|
485
|
+
:view-index="viewIndex"
|
|
486
|
+
:view-types="viewTypes"
|
|
487
|
+
ref="settingComponent"
|
|
488
|
+
@change="pageHistory.commit()"
|
|
489
|
+
@postMessageToIframe="onPostMessageToIframe"/>
|
|
490
|
+
|
|
491
|
+
<br />
|
|
492
|
+
<br />
|
|
493
|
+
<br />
|
|
555
494
|
|
|
556
|
-
<WebTemplateCreator :="useTemplateCreator"
|
|
557
|
-
ref="templateCreator"
|
|
558
|
-
@save="templateCreatorAfterSave" />
|
|
559
495
|
</div>
|
|
560
|
-
|
|
496
|
+
|
|
497
|
+
</TransitionGroup>
|
|
561
498
|
|
|
562
499
|
</div>
|
|
563
500
|
|
|
@@ -568,7 +505,44 @@
|
|
|
568
505
|
</div>
|
|
569
506
|
|
|
570
507
|
<div class="absolute">
|
|
571
|
-
<WebLayoutSelector ref="webLayoutSelector"
|
|
508
|
+
<WebLayoutSelector ref="webLayoutSelector" @apply="createLayout"/>
|
|
509
|
+
|
|
510
|
+
<WebComponentSelector ref="webPageComponentSelector"
|
|
511
|
+
:component-src="`${this.controller}.load-templates`"
|
|
512
|
+
:components="availableComponents"
|
|
513
|
+
@apply="addComponent"
|
|
514
|
+
dismissable="true"
|
|
515
|
+
@dismiss="$refs.webPageComponentSelector.close()" />
|
|
516
|
+
|
|
517
|
+
<OGSettingModal ref="ogModal" />
|
|
518
|
+
|
|
519
|
+
<Modal ref="ldjsonModal" width="600" height="480">
|
|
520
|
+
<template v-slot:head>
|
|
521
|
+
<div class="relative p-5">
|
|
522
|
+
<h3>JSON-LD</h3>
|
|
523
|
+
<div class="absolute top-0 right-0 p-2">
|
|
524
|
+
<button type="button" class="p-2" @click="$refs.ldjsonModal.close()">
|
|
525
|
+
<svg width="24" height="24" viewBox="0 0 24 24" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg">
|
|
526
|
+
<path d="M6.53034 5.46965C6.23745 5.17676 5.76257 5.17676 5.46968 5.46965C5.17679 5.76255 5.17679 6.23742 5.46968 6.53031L10.9393 12L5.46967 17.4697C5.17678 17.7626 5.17678 18.2374 5.46967 18.5303C5.76256 18.8232 6.23744 18.8232 6.53033 18.5303L12 13.0606L17.4697 18.5303C17.7626 18.8232 18.2375 18.8232 18.5303 18.5303C18.8232 18.2374 18.8232 17.7626 18.5303 17.4697L13.0607 12L18.5303 6.53032C18.8232 6.23743 18.8232 5.76256 18.5303 5.46966C18.2374 5.17677 17.7626 5.17677 17.4697 5.46966L12 10.9393L6.53034 5.46965Z"/>
|
|
527
|
+
</svg>
|
|
528
|
+
</button>
|
|
529
|
+
</div>
|
|
530
|
+
</div>
|
|
531
|
+
</template>
|
|
532
|
+
<template #foot="{ context }">
|
|
533
|
+
<div class="p-5">
|
|
534
|
+
<Button type="button" class="w-[100px]"
|
|
535
|
+
@click="saveLdjson(context)">
|
|
536
|
+
Save
|
|
537
|
+
</Button>
|
|
538
|
+
</div>
|
|
539
|
+
</template>
|
|
540
|
+
<template #default="{ context }">
|
|
541
|
+
<div class="flex-1 p-5">
|
|
542
|
+
<Textarea v-model="context.code" rows="10" ></Textarea>
|
|
543
|
+
</div>
|
|
544
|
+
</template>
|
|
545
|
+
</Modal>
|
|
572
546
|
</div>
|
|
573
547
|
|
|
574
548
|
</div>
|
|
@@ -578,14 +552,22 @@
|
|
|
578
552
|
|
|
579
553
|
import throttle from "lodash/throttle";
|
|
580
554
|
import md5 from "md5";
|
|
581
|
-
import {
|
|
555
|
+
import {createFormData, invokeAfterIdle} from "../utils/helpers.mjs";
|
|
582
556
|
import {ref} from 'vue'
|
|
583
557
|
import {useManualRefHistory} from "@vueuse/core";
|
|
584
558
|
import axios from "axios";
|
|
585
559
|
import {useRouter} from "vue-router";
|
|
560
|
+
import WebLayoutSelector from "./WebLayoutSelector.vue";
|
|
561
|
+
import WebComponentSelector from "./WebComponentSelector.vue";
|
|
562
|
+
import defaultConfig from "../configs/web-page-builder.js"
|
|
563
|
+
import OGSettingModal from "./OGSettingModal.vue";
|
|
564
|
+
|
|
565
|
+
const patchPageCache = {}
|
|
586
566
|
|
|
587
567
|
export default{
|
|
588
568
|
|
|
569
|
+
components: {OGSettingModal, WebComponentSelector, WebLayoutSelector},
|
|
570
|
+
|
|
589
571
|
setup(){
|
|
590
572
|
const page = ref({})
|
|
591
573
|
const pageHistory = useManualRefHistory(page, { clone:true })
|
|
@@ -598,78 +580,34 @@ export default{
|
|
|
598
580
|
|
|
599
581
|
props: {
|
|
600
582
|
|
|
601
|
-
/**
|
|
602
|
-
* Can add/remove layout
|
|
603
|
-
*/
|
|
604
583
|
canManageLayout: {
|
|
605
584
|
type: Boolean,
|
|
606
585
|
default: false
|
|
607
586
|
},
|
|
608
587
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
* @param {Array} components
|
|
612
|
-
* @param {String} components[]
|
|
613
|
-
*/
|
|
588
|
+
controller: String,
|
|
589
|
+
|
|
614
590
|
excludeComponents: {
|
|
615
591
|
type: Array,
|
|
616
592
|
default: []
|
|
617
593
|
},
|
|
618
594
|
|
|
619
|
-
/**
|
|
620
|
-
* Add more components
|
|
621
|
-
* @param {Array} components
|
|
622
|
-
* @param {String} components[]
|
|
623
|
-
*/
|
|
624
595
|
moreComponents: {
|
|
625
596
|
type: Array,
|
|
626
597
|
default: []
|
|
627
598
|
},
|
|
628
599
|
|
|
629
|
-
/**
|
|
630
|
-
* Persist web page builder state
|
|
631
|
-
*/
|
|
632
|
-
store: {
|
|
633
|
-
type: Object,
|
|
634
|
-
default: {
|
|
635
|
-
version: '0.0.999',
|
|
636
|
-
layoutMode: false,
|
|
637
|
-
selectedComponent: null, // [ 'uid|style', 'style|headers|components|footers' ]
|
|
638
|
-
tabIndex: 2,
|
|
639
|
-
viewType: '',
|
|
640
|
-
zoomLevel: 'fit',
|
|
641
|
-
width: [ 320, 320 ]
|
|
642
|
-
}
|
|
643
|
-
},
|
|
644
|
-
|
|
645
|
-
src:{
|
|
646
|
-
type: [ String, Array ],
|
|
647
|
-
default: 'page.open'
|
|
648
|
-
},
|
|
649
|
-
|
|
650
|
-
saveSrc:{
|
|
651
|
-
type: [ String, Array ],
|
|
652
|
-
default: 'page.save'
|
|
653
|
-
},
|
|
654
|
-
|
|
655
|
-
/**
|
|
656
|
-
* @param {Object} config
|
|
657
|
-
* @param {String} config.method
|
|
658
|
-
* @param {String} config.url
|
|
659
|
-
*/
|
|
660
600
|
uploadConfig: {
|
|
661
|
-
type: Object
|
|
662
|
-
required: true
|
|
601
|
+
type: Object
|
|
663
602
|
},
|
|
664
603
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
* @param {Object} config
|
|
668
|
-
* @param {String} config.url
|
|
669
|
-
*/
|
|
604
|
+
uploadImageFn: Function,
|
|
605
|
+
|
|
670
606
|
useDatasource: undefined,
|
|
671
607
|
|
|
672
|
-
useTemplateCreator: undefined
|
|
608
|
+
useTemplateCreator: undefined,
|
|
609
|
+
|
|
610
|
+
presetKey: String
|
|
673
611
|
|
|
674
612
|
},
|
|
675
613
|
|
|
@@ -708,27 +646,6 @@ export default{
|
|
|
708
646
|
this.loadDatasource()
|
|
709
647
|
},
|
|
710
648
|
|
|
711
|
-
cleanItem(item){
|
|
712
|
-
|
|
713
|
-
delete item.uid
|
|
714
|
-
delete item.enabled
|
|
715
|
-
|
|
716
|
-
if(item.props){
|
|
717
|
-
for(let key in item.props){
|
|
718
|
-
if(Array.isArray(item.props[key]) &&
|
|
719
|
-
(item.props[key].length === 0 || [ '[{},{}]', '[]', '["",""]', '[""]' ].includes(JSON.stringify(item.props[key])))){
|
|
720
|
-
delete item.props[key]
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
if(Array.isArray(item.items)){
|
|
726
|
-
for(let i in item.items){
|
|
727
|
-
this.cleanItem(item.items[i])
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
},
|
|
731
|
-
|
|
732
649
|
close(){
|
|
733
650
|
this.$emit('close')
|
|
734
651
|
},
|
|
@@ -760,7 +677,13 @@ export default{
|
|
|
760
677
|
return Array.isArray(component.props[key]) ? component.props[key].join(' ') : ''
|
|
761
678
|
})
|
|
762
679
|
.filter(_ => _)
|
|
763
|
-
.join(' ')
|
|
680
|
+
.join(' '),
|
|
681
|
+
|
|
682
|
+
style: this.styleClasses.reduce((res, cur) => {
|
|
683
|
+
if(Array.isArray(component.props[cur]))
|
|
684
|
+
res[cur] = component.props[cur]
|
|
685
|
+
return res
|
|
686
|
+
}, {})
|
|
764
687
|
}
|
|
765
688
|
|
|
766
689
|
for(let key in component.props){
|
|
@@ -783,40 +706,111 @@ export default{
|
|
|
783
706
|
instance.items = component.items.map((_) => this.createComponentInstance(_)).filter(_=>_)
|
|
784
707
|
}
|
|
785
708
|
|
|
709
|
+
if(Array.isArray(component.items2)){
|
|
710
|
+
instance.items2 = component.items2.map((_) => this.createComponentInstance(_)).filter(_=>_)
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
if(Array.isArray(component.items3)){
|
|
714
|
+
instance.items3 = component.items3.map((_) => this.createComponentInstance(_)).filter(_=>_)
|
|
715
|
+
}
|
|
716
|
+
|
|
786
717
|
if(component.props && Array.isArray(component.props.items)){
|
|
787
718
|
instance.items = component.props.items
|
|
788
719
|
}
|
|
789
720
|
|
|
721
|
+
if(component.slots){
|
|
722
|
+
const slots = {}
|
|
723
|
+
for(let key in component.slots){
|
|
724
|
+
slots[key] = component.slots[key].map((_) => this.createComponentInstance(_)).filter(_=>_)
|
|
725
|
+
}
|
|
726
|
+
instance.slots = slots
|
|
727
|
+
}
|
|
728
|
+
|
|
790
729
|
return instance
|
|
791
730
|
},
|
|
792
731
|
|
|
793
732
|
createLayout(layout){
|
|
794
|
-
this.
|
|
733
|
+
this.socket.send(`${this.controller}.create-layout`, layout)
|
|
734
|
+
.then(layout => {
|
|
735
|
+
this.loadLayouts()
|
|
736
|
+
this.page.layoutId = layout.id
|
|
737
|
+
this.$refs.webLayoutSelector.close()
|
|
738
|
+
})
|
|
739
|
+
.catch(err => this.alert(err))
|
|
795
740
|
},
|
|
796
741
|
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
742
|
+
createStyleSheet(styles){
|
|
743
|
+
|
|
744
|
+
const mediaQueries = {
|
|
745
|
+
'': '@media screen',
|
|
746
|
+
'md:': '@media screen and (min-width: 640px)',
|
|
747
|
+
}
|
|
800
748
|
|
|
801
|
-
const
|
|
802
|
-
|
|
749
|
+
const fontFamilies = {
|
|
750
|
+
'"Anton", sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Anton&display=swap');`,
|
|
751
|
+
'Dosis, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Dosis:wght@400;700&display=swap');`,
|
|
752
|
+
'Lato, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Lato:wght@400;700&display=swap');`,
|
|
753
|
+
'Merriweather, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Merriweather:wght@400;700&display=swap');`,
|
|
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');`,
|
|
766
|
+
}
|
|
803
767
|
|
|
804
|
-
|
|
805
|
-
|
|
768
|
+
let text = ''
|
|
769
|
+
const usedFonts = {}
|
|
770
|
+
for(let mediaKey in styles?.media){
|
|
771
|
+
const css = styles.media[mediaKey]
|
|
772
|
+
|
|
773
|
+
text += mediaQueries[mediaKey] + '{ '
|
|
774
|
+
for(let key in css){
|
|
775
|
+
text += key + '{ '
|
|
776
|
+
for(let selector in css[key]){
|
|
777
|
+
text += selector + ':' + css[key][selector] + ';'
|
|
778
|
+
|
|
779
|
+
if(selector === 'font-family' && fontFamilies[css[key][selector]]){
|
|
780
|
+
usedFonts[css[key][selector]] = fontFamilies[css[key][selector]]
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
text += '}'
|
|
784
|
+
}
|
|
785
|
+
text += '}\n'
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
return [
|
|
789
|
+
...Object.values(usedFonts),
|
|
790
|
+
text
|
|
791
|
+
]
|
|
792
|
+
.join("\n")
|
|
806
793
|
},
|
|
807
794
|
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
795
|
+
createInstances(){
|
|
796
|
+
if(!this.page.instances || typeof this.page.instances !== 'object' || Array.isArray(this.page.instances))
|
|
797
|
+
this.page.instances = {}
|
|
798
|
+
this.page.instances.components = (this.page.components ?? []).map((_) => this.createComponentInstance(_)).filter(_=>_)
|
|
811
799
|
|
|
812
|
-
this
|
|
813
|
-
|
|
814
|
-
|
|
800
|
+
if(this.layout){
|
|
801
|
+
if(!this.layout.instances || typeof this.layout.instances !== 'object' || Array.isArray(this.layout.instances))
|
|
802
|
+
this.layout.instances = {}
|
|
803
|
+
this.layout.instances.headers = (this.layout.headers ?? []).map((_) => this.createComponentInstance(_)).filter(_=>_)
|
|
804
|
+
this.layout.instances.footers = (this.layout.footers ?? []).map((_) => this.createComponentInstance(_)).filter(_=>_)
|
|
805
|
+
|
|
806
|
+
this.layout.instances.stylesheet = this.createStyleSheet(this.layout.styles)
|
|
807
|
+
}
|
|
815
808
|
},
|
|
816
809
|
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
this
|
|
810
|
+
duplicate(parent, item){
|
|
811
|
+
const newItem = JSON.parse(JSON.stringify(item))
|
|
812
|
+
this.setUid(newItem)
|
|
813
|
+
parent.push(newItem)
|
|
820
814
|
},
|
|
821
815
|
|
|
822
816
|
findCompByUid(uid, components){
|
|
@@ -893,7 +887,7 @@ export default{
|
|
|
893
887
|
},
|
|
894
888
|
|
|
895
889
|
listen(){
|
|
896
|
-
this.
|
|
890
|
+
this.socket.send(`${this.controller}.subscribe`, { name:'page' })
|
|
897
891
|
.then(() => {
|
|
898
892
|
|
|
899
893
|
})
|
|
@@ -901,11 +895,15 @@ export default{
|
|
|
901
895
|
},
|
|
902
896
|
|
|
903
897
|
async load(){
|
|
904
|
-
return this.
|
|
905
|
-
.then(({ page,
|
|
906
|
-
|
|
907
|
-
|
|
898
|
+
return this.socket.send(`${this.controller}.open`, { uid:this.$route.params.uid })
|
|
899
|
+
.then(({ page, host, previewHost, debugMode }) => {
|
|
900
|
+
|
|
901
|
+
this.patchPage(page)
|
|
902
|
+
|
|
903
|
+
if(page) Object.assign(this.page, page)
|
|
908
904
|
if(host) this.host = host
|
|
905
|
+
this.debugMode = debugMode ?? this.debugMode
|
|
906
|
+
if(previewHost) this.previewHost = previewHost
|
|
909
907
|
|
|
910
908
|
this.prevData = {
|
|
911
909
|
page: JSON.stringify(this.page),
|
|
@@ -914,27 +912,129 @@ export default{
|
|
|
914
912
|
|
|
915
913
|
this.pageHistory.commit()
|
|
916
914
|
|
|
917
|
-
this
|
|
918
|
-
this.resize()
|
|
919
|
-
this.iframeSrc = (this.host ?? import.meta.env.VITE_WEB_HOST) + '/' + (this.page.path ?? '') +
|
|
920
|
-
`?edit-mode=${this.store.previewMode}`
|
|
921
|
-
window.setTimeout(() => {
|
|
922
|
-
this.updateIframe()
|
|
923
|
-
}, 500)
|
|
924
|
-
})
|
|
915
|
+
host = this.host ?? import.meta.env.VITE_WEB_HOST
|
|
925
916
|
|
|
926
|
-
|
|
917
|
+
if(host){
|
|
918
|
+
this.$nextTick(() => {
|
|
919
|
+
this.resize()
|
|
927
920
|
|
|
921
|
+
if(this.previewHost){
|
|
922
|
+
this.iframeSrc = this.previewHost + `?edit-mode=${this.store.previewMode}`
|
|
923
|
+
}
|
|
924
|
+
else{
|
|
925
|
+
this.iframeSrc = host + '/' + (this.page.path ?? '') +
|
|
926
|
+
`?edit-mode=${this.store.previewMode}`
|
|
927
|
+
}
|
|
928
|
+
})
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
this.readyState = 1
|
|
928
932
|
})
|
|
929
933
|
.catch((err) => {
|
|
930
934
|
this.toast(err)
|
|
931
|
-
this
|
|
935
|
+
this.readyState = -1
|
|
936
|
+
console.error(err)
|
|
937
|
+
})
|
|
938
|
+
},
|
|
939
|
+
|
|
940
|
+
patchBgColors(bgColors){
|
|
941
|
+
if (!Array.isArray(bgColors)) return
|
|
942
|
+
|
|
943
|
+
for(let i = 0 ; i < bgColors.length ; i++){
|
|
944
|
+
let value = bgColors[i]
|
|
945
|
+
if(`${bgColors[i]}`.startsWith('bg-')){
|
|
946
|
+
if(patchPageCache[bgColors[i]]){
|
|
947
|
+
value = patchPageCache[bgColors[i]]
|
|
948
|
+
}
|
|
949
|
+
else{
|
|
950
|
+
const el = document.createElement('div')
|
|
951
|
+
el.classList.add(bgColors[i])
|
|
952
|
+
el.style.position = 'fixed'
|
|
953
|
+
el.style.top = '-100000px'
|
|
954
|
+
document.body.appendChild(el)
|
|
955
|
+
|
|
956
|
+
const rgbText = window.getComputedStyle(el)['background-color']
|
|
957
|
+
|
|
958
|
+
const rgb = rgbText.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*\d+)?\)/)
|
|
959
|
+
if(rgb){
|
|
960
|
+
value = `#${((1 << 24) + (parseInt(rgb[1]) << 16) +
|
|
961
|
+
(parseInt(rgb[2]) << 8) +
|
|
962
|
+
parseInt(rgb[3])).toString(16).slice(1)}`
|
|
963
|
+
}
|
|
964
|
+
document.body.removeChild(el)
|
|
965
|
+
|
|
966
|
+
patchPageCache[bgColors[i]] = value
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
bgColors[i] = value
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
},
|
|
973
|
+
|
|
974
|
+
patchBdColor(bdColor){
|
|
975
|
+
if (!Array.isArray(bdColor)) return
|
|
976
|
+
|
|
977
|
+
for(let i = 0 ; i < bdColor.length ; i++){
|
|
978
|
+
let value = bdColor[i]
|
|
979
|
+
if(`${bdColor[i]}`.startsWith('border-')){
|
|
980
|
+
if(patchPageCache[bdColor[i]]){
|
|
981
|
+
value = patchPageCache[bdColor[i]]
|
|
982
|
+
}
|
|
983
|
+
else{
|
|
984
|
+
const el = document.createElement('div')
|
|
985
|
+
el.classList.add(bdColor[i])
|
|
986
|
+
el.style.position = 'fixed'
|
|
987
|
+
el.style.borderStyle = "solid"
|
|
988
|
+
el.style.borderWidth = "5px"
|
|
989
|
+
el.style.width = '100px'
|
|
990
|
+
el.style.height = '100px'
|
|
991
|
+
el.style.top = '10px'
|
|
992
|
+
el.style.left = '10px'
|
|
993
|
+
document.body.appendChild(el)
|
|
994
|
+
|
|
995
|
+
const rgbText = window.getComputedStyle(el)['border-color']
|
|
996
|
+
const rgb = rgbText.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*\d+)?\)/)
|
|
997
|
+
if(rgb){
|
|
998
|
+
value = `#${((1 << 24) + (parseInt(rgb[1]) << 16) +
|
|
999
|
+
(parseInt(rgb[2]) << 8) +
|
|
1000
|
+
parseInt(rgb[3])).toString(16).slice(1)}`
|
|
1001
|
+
}
|
|
1002
|
+
document.body.removeChild(el)
|
|
1003
|
+
|
|
1004
|
+
patchPageCache[bdColor[i]] = value
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
bdColor[i] = value
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
},
|
|
1011
|
+
|
|
1012
|
+
patchPage(page){
|
|
1013
|
+
|
|
1014
|
+
const recursePatch = (components) => {
|
|
1015
|
+
for(let component of components){
|
|
1016
|
+
this.patchBgColors(component.props.bgColors)
|
|
1017
|
+
this.patchBdColor(component.props.bdColor)
|
|
1018
|
+
|
|
1019
|
+
if(Array.isArray(component.items)){
|
|
1020
|
+
recursePatch(component.items)
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
recursePatch(page.components)
|
|
1026
|
+
},
|
|
1027
|
+
|
|
1028
|
+
async loadLayouts(){
|
|
1029
|
+
this.socket.send(`${this.controller}.load-layouts`, {})
|
|
1030
|
+
.then(_ => {
|
|
1031
|
+
this.layouts = _
|
|
932
1032
|
})
|
|
933
1033
|
},
|
|
934
1034
|
|
|
935
1035
|
loadDatasource(){
|
|
936
1036
|
if(this.useDatasource && this.useDatasource[1]){
|
|
937
|
-
this.
|
|
1037
|
+
this.socket.send(this.useDatasource[1], this.page.datasource)
|
|
938
1038
|
.then((data) => {
|
|
939
1039
|
Object.assign(this.page, { data })
|
|
940
1040
|
this.updateIframe()
|
|
@@ -942,32 +1042,40 @@ export default{
|
|
|
942
1042
|
}
|
|
943
1043
|
},
|
|
944
1044
|
|
|
945
|
-
|
|
946
|
-
this.$
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
1045
|
+
loadPreset(){
|
|
1046
|
+
if(!Object.keys(this.$route.query).map(_ => _.toLowerCase()).includes('reset')){
|
|
1047
|
+
if(this.presetKey){
|
|
1048
|
+
return this.socket.send(this.presetSrc, { key:this.presetKey })
|
|
1049
|
+
.then(config => {
|
|
1050
|
+
if(config){
|
|
1051
|
+
Object.assign(this.config.params, config.params)
|
|
952
1052
|
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
1053
|
+
if(this.$route.query?.search)
|
|
1054
|
+
this.preset.search = this.$route.query.search
|
|
1055
|
+
}
|
|
1056
|
+
})
|
|
1057
|
+
}
|
|
1058
|
+
return new Promise(resolve => resolve())
|
|
1059
|
+
}
|
|
1060
|
+
else{
|
|
1061
|
+
return new Promise((resolve) => {
|
|
1062
|
+
const query = {}
|
|
1063
|
+
for(let key in this.$route.query){
|
|
1064
|
+
if(key.toLowerCase() !== 'reset')
|
|
1065
|
+
query[key] = this.$route.query[key]
|
|
1066
|
+
}
|
|
1067
|
+
this.$router.replace({
|
|
1068
|
+
...this.$route,
|
|
1069
|
+
query
|
|
958
1070
|
})
|
|
959
|
-
this.setUid(item)
|
|
960
1071
|
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
1072
|
+
resolve()
|
|
1073
|
+
})
|
|
1074
|
+
}
|
|
1075
|
+
},
|
|
964
1076
|
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
catch(e){
|
|
968
|
-
console.error(e)
|
|
969
|
-
}
|
|
970
|
-
})
|
|
1077
|
+
openComponentSelector(params, callback){
|
|
1078
|
+
this.$refs.webPageComponentSelector.open(params, callback)
|
|
971
1079
|
},
|
|
972
1080
|
|
|
973
1081
|
onHooks(model, event, items){
|
|
@@ -983,25 +1091,19 @@ export default{
|
|
|
983
1091
|
|
|
984
1092
|
onKeyDown(e){
|
|
985
1093
|
|
|
986
|
-
if(e.
|
|
987
|
-
this.copy()
|
|
988
|
-
}
|
|
989
|
-
else if(e.keyCode === 86 && (e.metaKey || e.ctrlKey)){
|
|
990
|
-
this.paste(e)
|
|
991
|
-
}
|
|
992
|
-
else if(e.altKey){
|
|
1094
|
+
if(e.altKey){
|
|
993
1095
|
if([ 49, 50, 51, 52 ].includes(e.keyCode)){
|
|
994
1096
|
if(e.keyCode === 49){
|
|
995
|
-
this.store.
|
|
1097
|
+
this.store.viewType = ''
|
|
996
1098
|
}
|
|
997
1099
|
else if(e.keyCode === 50){
|
|
998
|
-
this.store.
|
|
1100
|
+
this.store.viewType = 'md:'
|
|
999
1101
|
}
|
|
1000
1102
|
else if(e.keyCode === 51){
|
|
1001
|
-
this.store.
|
|
1103
|
+
this.store.viewType = 'xl:'
|
|
1002
1104
|
}
|
|
1003
1105
|
else if(e.keyCode === 52){
|
|
1004
|
-
this.store.
|
|
1106
|
+
this.store.viewType = '2xl:'
|
|
1005
1107
|
}
|
|
1006
1108
|
this.resize()
|
|
1007
1109
|
}
|
|
@@ -1049,11 +1151,26 @@ export default{
|
|
|
1049
1151
|
break
|
|
1050
1152
|
|
|
1051
1153
|
case 'component-click':
|
|
1052
|
-
|
|
1053
|
-
if(
|
|
1154
|
+
let component = this.findCompByUid(uid, this.page.components)
|
|
1155
|
+
if(component){
|
|
1156
|
+
this.store.tabIndex = 2
|
|
1054
1157
|
this.store.selectedComponent = [ uid ]
|
|
1158
|
+
return
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
component = this.findCompByUid(uid, this.layout.headers)
|
|
1162
|
+
if(!component)
|
|
1163
|
+
component = this.findCompByUid(uid, this.layout.footers)
|
|
1164
|
+
if(component){
|
|
1165
|
+
this.store.tabIndex = 4
|
|
1166
|
+
this.store.selectedComponent = [ uid ]
|
|
1167
|
+
return
|
|
1055
1168
|
}
|
|
1056
1169
|
break
|
|
1170
|
+
|
|
1171
|
+
case 'mounted':
|
|
1172
|
+
this.updateIframe()
|
|
1173
|
+
break
|
|
1057
1174
|
}
|
|
1058
1175
|
},
|
|
1059
1176
|
|
|
@@ -1072,6 +1189,10 @@ export default{
|
|
|
1072
1189
|
}
|
|
1073
1190
|
},
|
|
1074
1191
|
|
|
1192
|
+
openRightPane2(component){
|
|
1193
|
+
this.extRightPane = component
|
|
1194
|
+
},
|
|
1195
|
+
|
|
1075
1196
|
postIframe(data){
|
|
1076
1197
|
return new Promise((resolve, reject) => {
|
|
1077
1198
|
const handleResponse = (e) => {
|
|
@@ -1115,7 +1236,7 @@ export default{
|
|
|
1115
1236
|
|
|
1116
1237
|
resize(){
|
|
1117
1238
|
|
|
1118
|
-
const transformOrigin = this.
|
|
1239
|
+
const transformOrigin = this.store.viewType === '' ? 'center top' : '0 0'
|
|
1119
1240
|
|
|
1120
1241
|
switch(this.store.zoomLevel){
|
|
1121
1242
|
|
|
@@ -1125,7 +1246,7 @@ export default{
|
|
|
1125
1246
|
const previewHeight = this.$refs.preview.clientHeight - 70
|
|
1126
1247
|
|
|
1127
1248
|
let scale = 1
|
|
1128
|
-
switch(this.
|
|
1249
|
+
switch(this.store.viewType){
|
|
1129
1250
|
|
|
1130
1251
|
case 'md:':
|
|
1131
1252
|
scale = (previewWidth / 1024).toFixed(2)
|
|
@@ -1209,80 +1330,16 @@ export default{
|
|
|
1209
1330
|
},
|
|
1210
1331
|
|
|
1211
1332
|
resize3(w){
|
|
1212
|
-
if(this.store.width[1] - w >= 270){
|
|
1333
|
+
if(this.store.width[1] - w >= 270 && this.store.width[1] - w <= 480){
|
|
1213
1334
|
this.store.width[1] -= w
|
|
1214
1335
|
}
|
|
1215
1336
|
},
|
|
1216
1337
|
|
|
1217
|
-
createStyleSheet(styles){
|
|
1218
|
-
|
|
1219
|
-
const mediaQueries = {
|
|
1220
|
-
'': '@media screen',
|
|
1221
|
-
'md:': '@media screen and (min-width: 640px)',
|
|
1222
|
-
}
|
|
1223
|
-
|
|
1224
|
-
const fontFamilies = {
|
|
1225
|
-
'"Anton", sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Anton&display=swap');`,
|
|
1226
|
-
'Dosis, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Dosis:wght@400;700&display=swap');`,
|
|
1227
|
-
'Lato, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Lato:wght@400;700&display=swap');`,
|
|
1228
|
-
'Merriweather, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Merriweather:wght@400;700&display=swap');`,
|
|
1229
|
-
'Montserrat, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap');`,
|
|
1230
|
-
'"Noto Sans", sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;800&display=swap');`,
|
|
1231
|
-
'Oswald, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@400;700&display=swap');`,
|
|
1232
|
-
'Poppins, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap');`,
|
|
1233
|
-
'Raleway, sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Raleway:wght@400;700&display=swap');`,
|
|
1234
|
-
'"Roboto", sans-serif': `@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');`,
|
|
1235
|
-
'"Roboto Slab", serif': `@import url('https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@400;800&display=swap');`,
|
|
1236
|
-
'"Work Sans", serif': `@import url('https://fonts.googleapis.com/css2?family=Work+Sans:wght@400;700&display=swap');`,
|
|
1237
|
-
}
|
|
1238
|
-
|
|
1239
|
-
let text = ''
|
|
1240
|
-
const usedFonts = {}
|
|
1241
|
-
for(let mediaKey in styles.media){
|
|
1242
|
-
const css = styles.media[mediaKey]
|
|
1243
|
-
|
|
1244
|
-
text += mediaQueries[mediaKey] + '{ '
|
|
1245
|
-
for(let key in css){
|
|
1246
|
-
text += key + '{ '
|
|
1247
|
-
for(let selector in css[key]){
|
|
1248
|
-
text += selector + ':' + css[key][selector] + ';'
|
|
1249
|
-
|
|
1250
|
-
if(selector === 'font-family' && fontFamilies[css[key][selector]]){
|
|
1251
|
-
usedFonts[css[key][selector]] = fontFamilies[css[key][selector]]
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1254
|
-
text += '}'
|
|
1255
|
-
}
|
|
1256
|
-
text += '}\n'
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
|
-
return [
|
|
1260
|
-
...Object.values(usedFonts),
|
|
1261
|
-
text
|
|
1262
|
-
]
|
|
1263
|
-
.join("\n")
|
|
1264
|
-
},
|
|
1265
|
-
|
|
1266
|
-
createInstances(){
|
|
1267
|
-
if(!this.page.instances || typeof this.page.instances !== 'object' || Array.isArray(this.page.instances))
|
|
1268
|
-
this.page.instances = {}
|
|
1269
|
-
this.page.instances.components = (this.page.components ?? []).map((_) => this.createComponentInstance(_)).filter(_=>_)
|
|
1270
|
-
|
|
1271
|
-
if(this.layout){
|
|
1272
|
-
if(!this.layout.instances || typeof this.layout.instances !== 'object' || Array.isArray(this.layout.instances))
|
|
1273
|
-
this.layout.instances = {}
|
|
1274
|
-
this.layout.instances.headers = (this.layout.headers ?? []).map((_) => this.createComponentInstance(_)).filter(_=>_)
|
|
1275
|
-
this.layout.instances.footers = (this.layout.footers ?? []).map((_) => this.createComponentInstance(_)).filter(_=>_)
|
|
1276
|
-
|
|
1277
|
-
this.layout.instances.stylesheet = this.createStyleSheet(this.layout.styles)
|
|
1278
|
-
}
|
|
1279
|
-
},
|
|
1280
|
-
|
|
1281
1338
|
save(){
|
|
1282
1339
|
this.createInstances()
|
|
1283
1340
|
|
|
1284
1341
|
this.$refs.saveBtn.setState(2)
|
|
1285
|
-
this.
|
|
1342
|
+
this.socket.send(`${this.controller}.save`, { ...this.page, layout:this.layout })
|
|
1286
1343
|
.then((_) => {
|
|
1287
1344
|
this.prevData = {
|
|
1288
1345
|
page: JSON.stringify(this.page),
|
|
@@ -1290,8 +1347,8 @@ export default{
|
|
|
1290
1347
|
}
|
|
1291
1348
|
})
|
|
1292
1349
|
.catch((err) => {
|
|
1350
|
+
console.log('ERR', err)
|
|
1293
1351
|
this.toast(err)
|
|
1294
|
-
this.load()
|
|
1295
1352
|
})
|
|
1296
1353
|
.finally(_ => this.$refs.saveBtn.resetState())
|
|
1297
1354
|
},
|
|
@@ -1312,8 +1369,16 @@ export default{
|
|
|
1312
1369
|
this.$refs.ldjsonModal.close()
|
|
1313
1370
|
},
|
|
1314
1371
|
|
|
1372
|
+
savePreset: invokeAfterIdle(function() {
|
|
1373
|
+
if(this.presetKey) {
|
|
1374
|
+
this.socket.send(this.presetSrc,
|
|
1375
|
+
{key: this.presetKey, config: this.config})
|
|
1376
|
+
}
|
|
1377
|
+
}),
|
|
1378
|
+
|
|
1315
1379
|
select(uid){
|
|
1316
1380
|
this.store.selectedComponent = [ uid ]
|
|
1381
|
+
this.extRightPane = null
|
|
1317
1382
|
|
|
1318
1383
|
this.$refs.iframe.contentWindow.postMessage({
|
|
1319
1384
|
action: 'select',
|
|
@@ -1332,10 +1397,7 @@ export default{
|
|
|
1332
1397
|
},
|
|
1333
1398
|
|
|
1334
1399
|
stopListen(){
|
|
1335
|
-
this.
|
|
1336
|
-
.then(() => {
|
|
1337
|
-
|
|
1338
|
-
})
|
|
1400
|
+
this.socket.send(`${this.controller}.unsubscribe`, { name:'page' })
|
|
1339
1401
|
.catch((err) => this.toast(err))
|
|
1340
1402
|
},
|
|
1341
1403
|
|
|
@@ -1375,23 +1437,31 @@ export default{
|
|
|
1375
1437
|
|
|
1376
1438
|
async uploadImage(image, extra = {}, opt = {}){
|
|
1377
1439
|
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
.catch((err) => {
|
|
1391
|
-
this.$refs.image.value = ''
|
|
1392
|
-
this.$refs.imageModal.close()
|
|
1393
|
-
this.toast(err)
|
|
1440
|
+
if(typeof this.uploadImageFn === 'function'){
|
|
1441
|
+
return this.uploadImageFn(image, extra, opt)
|
|
1442
|
+
}
|
|
1443
|
+
else if(this.uploadConfig?.method){
|
|
1444
|
+
return axios({
|
|
1445
|
+
method: this.uploadConfig.method,
|
|
1446
|
+
url: this.uploadConfig.url,
|
|
1447
|
+
data: createFormData({ image, ...extra, ...(this.uploadConfig.data ?? {}) }),
|
|
1448
|
+
onUploadProgress: function (progressEvent) {
|
|
1449
|
+
if(opt.onUploadProgress)
|
|
1450
|
+
opt.onUploadProgress(progressEvent)
|
|
1451
|
+
},
|
|
1394
1452
|
})
|
|
1453
|
+
.then((res) => {
|
|
1454
|
+
return res.data
|
|
1455
|
+
})
|
|
1456
|
+
.catch((err) => {
|
|
1457
|
+
this.$refs.image.value = ''
|
|
1458
|
+
this.$refs.imageModal.close()
|
|
1459
|
+
this.toast(err)
|
|
1460
|
+
})
|
|
1461
|
+
}
|
|
1462
|
+
else{
|
|
1463
|
+
throw 'Unable to upload image'
|
|
1464
|
+
}
|
|
1395
1465
|
},
|
|
1396
1466
|
|
|
1397
1467
|
},
|
|
@@ -1399,13 +1469,13 @@ export default{
|
|
|
1399
1469
|
computed: {
|
|
1400
1470
|
|
|
1401
1471
|
componentStore(){
|
|
1402
|
-
if(this.store
|
|
1403
|
-
|
|
1404
|
-
this.store.components.compsetting = {}
|
|
1472
|
+
if(!this.store.components)
|
|
1473
|
+
this.store.components = {}
|
|
1405
1474
|
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1475
|
+
if(!this.store.components.compsetting)
|
|
1476
|
+
this.store.components.compsetting = {}
|
|
1477
|
+
|
|
1478
|
+
return this.store.components.compsetting
|
|
1409
1479
|
},
|
|
1410
1480
|
|
|
1411
1481
|
expanded(){
|
|
@@ -1430,14 +1500,8 @@ export default{
|
|
|
1430
1500
|
this.prevData.layout !== JSON.stringify(this.layout))
|
|
1431
1501
|
},
|
|
1432
1502
|
|
|
1433
|
-
computedPreviewViewType(){
|
|
1434
|
-
if(this.store.previewViewType === 'auto')
|
|
1435
|
-
return this.store.viewType
|
|
1436
|
-
return this.store.previewViewType
|
|
1437
|
-
},
|
|
1438
|
-
|
|
1439
1503
|
computedIframeSrc(){
|
|
1440
|
-
return this.iframeSrc
|
|
1504
|
+
return `${this.iframeSrc}`.substring(0, `${this.iframeSrc}`.indexOf('?'))
|
|
1441
1505
|
},
|
|
1442
1506
|
|
|
1443
1507
|
currentItem(){
|
|
@@ -1483,7 +1547,7 @@ export default{
|
|
|
1483
1547
|
iframeSize(){
|
|
1484
1548
|
|
|
1485
1549
|
let width, height
|
|
1486
|
-
switch(this.
|
|
1550
|
+
switch(this.store.viewType){
|
|
1487
1551
|
case '':
|
|
1488
1552
|
width = 390
|
|
1489
1553
|
height = 844
|
|
@@ -1517,24 +1581,6 @@ export default{
|
|
|
1517
1581
|
}
|
|
1518
1582
|
},
|
|
1519
1583
|
|
|
1520
|
-
layoutHeaders(){
|
|
1521
|
-
if(!this.layout) return []
|
|
1522
|
-
|
|
1523
|
-
if(!Array.isArray(this.layout.headers))
|
|
1524
|
-
this.layout.headers = []
|
|
1525
|
-
|
|
1526
|
-
return this.layout.headers
|
|
1527
|
-
},
|
|
1528
|
-
|
|
1529
|
-
layoutFooters(){
|
|
1530
|
-
if(!this.layout) return []
|
|
1531
|
-
|
|
1532
|
-
if(!Array.isArray(this.layout.footers))
|
|
1533
|
-
this.layout.footers = []
|
|
1534
|
-
|
|
1535
|
-
return this.layout.footers
|
|
1536
|
-
},
|
|
1537
|
-
|
|
1538
1584
|
previewClass(){
|
|
1539
1585
|
return {
|
|
1540
1586
|
'overflow-auto': this.store.zoomLevel !== 'fit',
|
|
@@ -1554,125 +1600,46 @@ export default{
|
|
|
1554
1600
|
}
|
|
1555
1601
|
},
|
|
1556
1602
|
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
return {
|
|
1561
|
-
components: [
|
|
1562
|
-
|
|
1563
|
-
{"type":"Flex","name":"3 Column Layout","group":"Layouts","thumbnailUrl":"/images/templates/3-column-layout1.png", "items":[{"type":"Flex","name":"Flex","group":"Components","items":[{"type":"Article","name":"Article","group":"Components","props":{"htmlText":"Left","padding":["p-6",""],"enabled":true,"direction":["flex-column"],"gap":["gap-2"],"name":"Dummy Text"}}],"props":{"direction":["flex-col"],"enabled":true,"width":["","md:w-2/12"],"name":"Left"}},{"type":"Flex","name":"Flex","group":"Components","items":[{"type":"Article","name":"Article","group":"Components","props":{"htmlText":"Middle","padding":["p-6",""],"enabled":true,"direction":["flex-column"],"gap":["gap-2"],"name":"Dummy Text"}}],"props":{"direction":["flex-col"],"enabled":true,"width":[null,"md:flex-1"],"name":"Middle"}},{"type":"Flex","name":"Flex","group":"Components","items":[{"type":"Article","name":"Article","group":"Components","props":{"htmlText":"Right","padding":["p-6",""],"enabled":true,"direction":["flex-column"],"gap":["gap-2"],"name":"Dummy Text"}}],"props":{"direction":["flex-col"],"enabled":true,"width":[null,"md:w-3/12"],"name":"RIght"}}],"props":{"direction":["flex-col","md:flex-row"],"gap":[null,"md:gap-4"],"enabled":true,"name":"3 Column Layout"}},
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
{"type":"Flex","name":"Thumbnails","group":"Sections","thumbnailUrl":"/images/templates/thumbnails.gif","items":[{"type":"Flex","name":"Flex","group":"Components","items":[{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Thumbnails","tagName":"h5","flex":["flex-1"]}},{"type":"Link","name":"Link","group":"Components","props":{"enabled":true,"textColor":["text-primary-500"],"direction":["flex-column"],"gap":["gap-2"],"text":"More Thumbnails"},"items":[]}],"props":{"direction":["flex-row"],"enabled":true,"flexAlign":["items-center"]}},{"type":"Flex","name":"Flex","group":"Components","items":[{"type":"Thumbnail","name":"Thumbnail","group":"Components","props":{"enabled":true,"width":["w-5/12"],"direction":["flex-column"],"gap":["gap-2"],"flex":["flex-0"]},"items":[]},{"type":"Thumbnail","name":"Thumbnail","group":"Components","props":{"enabled":true,"width":["w-5/12"],"direction":["flex-column"],"gap":["gap-2"],"flex":["flex-0"]},"items":[]},{"type":"Thumbnail","name":"Thumbnail","group":"Components","props":{"enabled":true,"width":["w-5/12"],"direction":["flex-column"],"gap":["gap-2"],"flex":["flex-0"]},"items":[]}],"props":{"direction":["flex-row"],"gap":["gap-4"],"enabled":true,"overflow":["overflow-x-scroll"],"width":["w-full"],"minWidth":["min-w-0"]}}],"props":{"direction":["flex-col"],"gap":["gap-2"],"enabled":true,"padding":["p-5",""],"name":"Thumbnails"}},
|
|
1567
|
-
|
|
1568
|
-
{"type":"Carousel","name":"Image Carousel","group":"Sections","thumbnailUrl":"/images/templates/carousel1.png","items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["/assets/web/banner1.jpg"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"],"bdRadius":["rounded-xl"],"aspectRatio":["aspect-[2/1]"],"bgColors":["bg-amber-300"]}},{"type":"Image","name":"Image","group":"Components","props":{"src":["/assets/web/banner1.jpg"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"],"bdRadius":["rounded-xl"],"aspectRatio":["aspect-[2/1]"],"bgColors":["bg-lime-300"]}},{"type":"Image","name":"Image","group":"Components","props":{"src":["/assets/web/banner1.jpg"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"],"bdRadius":["rounded-xl"],"aspectRatio":["aspect-[2/1]"],"bgColors":["bg-blue-300"]}}],"props":{"enabled":true,"containerGap":["gap-2"],"padding":["p-4",""],"direction":["flex-column"],"gap":["gap-2"],"useLegend":true}},
|
|
1569
|
-
|
|
1570
|
-
{"type":"Link","name":"Icon Link","group":"Sections","thumbnailUrl":"/images/templates/icon-link.png","props":{"enabled":true,"display":["flex"],"direction":["flex-col"],"gap":["gap-2"],"flexAlign":["items-center"],"name":"Icon Link"},"items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["059bae0eadf1b650f3acff7dd1e7433a.png"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"]}},{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","fontWeight":["font-normal"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Icon Link 1"}}]},
|
|
1571
|
-
|
|
1572
|
-
{"type":"Carousel","name":"Icon Link Carousel","group":"Sections","thumbnailUrl":"/images/templates/icon-link-carousel.gif", "items":[{"type":"Grid","name":"Grid","group":"Components","thumbnailUrl":"/images/templates/grid1.png","items":[{"type":"Link","name":"Icon Link","group":"Sections","props":{"enabled":true,"display":["flex"],"direction":["flex-col"],"gap":["gap-2"],"flexAlign":["items-center"],"name":"Icon Link"},"items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["059bae0eadf1b650f3acff7dd1e7433a.png"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"]}},{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Link 1","fontSize":["text-sm"]}}]},{"type":"Link","name":"Icon Link","group":"Sections","props":{"enabled":true,"display":["flex"],"direction":["flex-col"],"gap":["gap-2"],"flexAlign":["items-center"],"name":"Icon Link"},"items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["c7e8d12c0dcda3b9d3b2862559a8bc2e.png"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"]}},{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Link 2","fontSize":["text-sm"]}}]},{"type":"Link","name":"Icon Link","group":"Sections","props":{"enabled":true,"display":["flex"],"direction":["flex-col"],"gap":["gap-2"],"flexAlign":["items-center"],"name":"Icon Link"},"items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["47bcb782edfc426c8506664cc3b320e7.png"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"]}},{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Link 3","fontSize":["text-sm"]}}]},{"type":"Link","name":"Icon Link","group":"Sections","props":{"enabled":true,"display":["flex"],"direction":["flex-col"],"gap":["gap-2"],"flexAlign":["items-center"],"name":"Icon Link"},"items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["01e5a3e8f0e89562a7f6a5449be44614.png"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"]}},{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Link 4","fontSize":["text-sm"]}}]},{"type":"Link","name":"Icon Link","group":"Sections","props":{"enabled":true,"display":["flex"],"direction":["flex-col"],"gap":["gap-2"],"flexAlign":["items-center"],"name":"Icon Link"},"items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["7d7cc53e346aa5abf1f1ada463ed0e5c.png"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"]}},{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Link 5","fontSize":["text-sm"]}}]},{"type":"Link","name":"Icon Link","group":"Sections","props":{"enabled":true,"display":["flex"],"direction":["flex-col"],"gap":["gap-2"],"flexAlign":["items-center"],"name":"Icon Link"},"items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["4a1d1808e9f1be18f0ba18322647a11e.png"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"]}},{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Link 6","fontSize":["text-sm"]}}]},{"type":"Link","name":"Icon Link","group":"Sections","props":{"enabled":true,"display":["flex"],"direction":["flex-col"],"gap":["gap-2"],"flexAlign":["items-center"],"name":"Icon Link"},"items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["1b7f9673aeee9ebdf305658a54c63dc8.png"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"]}},{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Link 7","fontSize":["text-sm"]}}]},{"type":"Link","name":"Icon Link","group":"Sections","props":{"enabled":true,"display":["flex"],"direction":["flex-col"],"gap":["gap-2"],"flexAlign":["items-center"],"name":"Icon Link"},"items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["71828d52f682527cd500c1ba6c2a9ef0.png"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"]}},{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Link 8","fontSize":["text-sm"]}}]}],"gap":[],"props":{"columns":["grid-cols-4"],"gap":["gap-5"],"enabled":true,"direction":["flex-column"],"padding":["p-5",""]}},{"type":"Grid","name":"Grid","group":"Components","thumbnailUrl":"/images/templates/grid1.png","items":[{"type":"Link","name":"Icon Link","group":"Sections","props":{"enabled":true,"display":["flex"],"direction":["flex-col"],"gap":["gap-2"],"flexAlign":["items-center"],"name":"Icon Link"},"items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["71828d52f682527cd500c1ba6c2a9ef0.png"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"]}},{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Link 9","fontSize":["text-sm"]}}]},{"type":"Link","name":"Icon Link","group":"Sections","props":{"enabled":true,"display":["flex"],"direction":["flex-col"],"gap":["gap-2"],"flexAlign":["items-center"],"name":"Icon Link"},"items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["059bae0eadf1b650f3acff7dd1e7433a.png"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"]}},{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Link 10","fontSize":["text-sm"]}}]},{"type":"Link","name":"Icon Link","group":"Sections","props":{"enabled":true,"display":["flex"],"direction":["flex-col"],"gap":["gap-2"],"flexAlign":["items-center"],"name":"Icon Link"},"items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["4a1d1808e9f1be18f0ba18322647a11e.png"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"]}},{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Link 11","fontSize":["text-sm"]}}]},{"type":"Link","name":"Icon Link","group":"Sections","props":{"enabled":true,"display":["flex"],"direction":["flex-col"],"gap":["gap-2"],"flexAlign":["items-center"],"name":"Icon Link"},"items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["7d7cc53e346aa5abf1f1ada463ed0e5c.png"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"]}},{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Link 12","fontSize":["text-sm"]}}]},{"type":"Link","name":"Icon Link","group":"Sections","props":{"enabled":true,"display":["flex"],"direction":["flex-col"],"gap":["gap-2"],"flexAlign":["items-center"],"name":"Icon Link"},"items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["47bcb782edfc426c8506664cc3b320e7.png"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"]}},{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Link 13","fontSize":["text-sm"]}}]},{"type":"Link","name":"Icon Link","group":"Sections","props":{"enabled":true,"display":["flex"],"direction":["flex-col"],"gap":["gap-2"],"flexAlign":["items-center"],"name":"Icon Link"},"items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["c7e8d12c0dcda3b9d3b2862559a8bc2e.png"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"]}},{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Link 14","fontSize":["text-sm"]}}]},{"type":"Link","name":"Icon Link","group":"Sections","props":{"enabled":true,"display":["flex"],"direction":["flex-col"],"gap":["gap-2"],"flexAlign":["items-center"],"name":"Icon Link"},"items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["4a1d1808e9f1be18f0ba18322647a11e.png"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"]}},{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Link 15","fontSize":["text-sm"]}}]},{"type":"Link","name":"Icon Link","group":"Sections","props":{"enabled":true,"display":["flex"],"direction":["flex-col"],"gap":["gap-2"],"flexAlign":["items-center"],"name":"Icon Link"},"items":[{"type":"Image","name":"Image","group":"Components","props":{"src":["059bae0eadf1b650f3acff7dd1e7433a.png"],"enabled":true,"direction":["flex-column"],"gap":["gap-2"]}},{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","enabled":true,"direction":["flex-column"],"gap":["gap-2"],"text":"Link 16","fontSize":["text-sm"]}}]}],"gap":[],"props":{"columns":["grid-cols-4"],"gap":["gap-5"],"enabled":true,"direction":["flex-column"],"padding":["p-5",""]}}],"props":{"enabled":true,"containerGap":["gap-2"],"padding":["p-4",""],"direction":["flex-column"],"gap":["gap-2"],"useLegend":true,"bgColors":["bg-gray-200"],"name":"Icon Link Carousel"}},
|
|
1573
|
-
|
|
1574
|
-
{ type:'ContactForm', name:'Contact Form', group:'Widgets', thumbnailUrl:"/images/templates/contact-form1.png", props:{
|
|
1575
|
-
fields:[
|
|
1576
|
-
{ type:'name', label:'Nama', required:true },
|
|
1577
|
-
{ type:'mobileNumber', label:'Nomor HP', required:true },
|
|
1578
|
-
{ type:'remark', label:'Pertanyaan' },
|
|
1579
|
-
],
|
|
1580
|
-
title: 'Contact Us',
|
|
1581
|
-
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent gravida erat eget nisi',
|
|
1582
|
-
submitMethod: 'post',
|
|
1583
|
-
submitUrl: '/inquiry',
|
|
1584
|
-
onSubmit:[],
|
|
1585
|
-
}},
|
|
1586
|
-
|
|
1587
|
-
{ type:'IconList', name:'Icon List', group:'Widgets', props:{
|
|
1588
|
-
icons:[], columns:[ 'grid-cols-4' ],
|
|
1589
|
-
}},
|
|
1590
|
-
|
|
1591
|
-
{ type:'DataList', name:'Data List', group:'Widgets', props:{}, items:[] },
|
|
1592
|
-
|
|
1593
|
-
{ type:'FAQ', name:'FAQ', group:'Widgets', thumbnailUrl:"/images/templates/faq.gif", props:{ items:[] }},
|
|
1594
|
-
{ type:'FAQ', name:'FAQ', group:'Widgets', thumbnailUrl:"/images/templates/faq.gif", props:{ items:[] }},
|
|
1595
|
-
|
|
1596
|
-
{ type:'FeatureList', name:'Feature List', group:'Widgets', props:{ items:[], columns:[], variant:['variant1'] }},
|
|
1597
|
-
|
|
1598
|
-
{ type:'Review', name:'Review', group:'Widgets', props:{} },
|
|
1599
|
-
|
|
1600
|
-
{ type:'Share', name:'Share To', group:'Widgets', props:{ channels:[] }},
|
|
1601
|
-
|
|
1602
|
-
{ type:'Testimonial', name:'Testimonial', group:'Widgets', props:{} },
|
|
1603
|
-
|
|
1604
|
-
{ type:'Header', name:'Header', group:'Widgets', props:{}, items:[] },
|
|
1605
|
-
|
|
1606
|
-
{ type:'ThumbnailList', name:'Thumbnail List', group:'Widgets', props:{ items:[] } },
|
|
1607
|
-
|
|
1608
|
-
{ type:'ProductDetail', name:'Product Detail', props:{}, group:'Widgets' },
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
{"type":"Flex","name":"Section 1","group":"Components","items":[{"type":"TextBlock","name":"TextBlock","group":"Components","props":{"htmlText":"","fontSize":["text-4xl"],"enabled":true,"text":"Drive more revenue at lower costs\n","fontWeight":["font-semibold"]}},{"type":"Paragraph","name":"Paragraph","group":"Components","props":{"name":"Paragraph","enabled":true,"text":"Reach every customer on their own preferred channel with dynamic, omnichannel campaigns, using channel-responsive templates.","html":"Reach every customer on their own preferred channel with dynamic, omnichannel campaigns, using channel-responsive templates.","maxWidth":["max-w-lg"],"fontSize":["text-xl"]}},{"type":"Flex","name":"Flex","group":"Components","items":[{"type":"Button","name":"Button","group":"Components","props":{"name":"Button","text":"Start Now","enabled":true,"padding":["px-3 py-0"],"fontSize":["text-xl"]}},{"type":"Button","name":"Button","group":"Components","props":{"name":"Button","text":"Contact Sales","enabled":true,"variant":"outline","padding":["p-3"],"fontSize":["text-xl"]}}],"props":{"direction":["flex-row"],"gap":["gap-3"],"enabled":true}}],"props":{"direction":["flex-col"],"gap":["gap-4"],"enabled":true,"padding":["p-8"],"margin":["mx-auto"],"width":["w-full"],"maxWidth":["max-w-screen-xl"]}},
|
|
1612
|
-
|
|
1613
|
-
{"type":"Carousel","name":"Carousel","group":"Components","items":[],"props":{"enabled":true,"containerGap":["gap-2"],"padding":["p-4",""],"direction":["flex-column"],"gap":["gap-2"],"useLegend":true}},
|
|
1614
|
-
|
|
1615
|
-
{ type:'Link', name:'Link', group:'Components', props:{}, items:[] },
|
|
1616
|
-
|
|
1617
|
-
{ type:'Modal', name:'Modal', group:'Components', props:{}, items:[] },
|
|
1618
|
-
|
|
1619
|
-
{ type:'Thumbnail', name:'Thumbnail', group:'Components', props:{}, items:[] },
|
|
1620
|
-
|
|
1621
|
-
{ type:'Ahref', name:'Ahref', group:'Components', props:{ name:'Ahref', text:'Ahref' } },
|
|
1622
|
-
|
|
1623
|
-
{ type:'Paragraph', name:'Paragraph', group:'Components', thumbnailUrl:"/images/templates/paragraph1.png", props:{ name:'Paragraph' } },
|
|
1624
|
-
|
|
1625
|
-
{ type:'Button', name:'Button', group:'Components', props:{
|
|
1626
|
-
name:'Button', text:'Button'
|
|
1627
|
-
}},
|
|
1628
|
-
|
|
1629
|
-
{ type:'Flex', name:'Flex', group:'Components', items:[], props:{ direction: [ 'flex-row' ] }},
|
|
1630
|
-
|
|
1631
|
-
{ type:'Grid', name:'Grid', group:'Components', thumbnailUrl:"/images/templates/grid1.png", items:[], gap:[], props:{
|
|
1632
|
-
columns: [], gap: [],
|
|
1633
|
-
}},
|
|
1634
|
-
|
|
1635
|
-
{ type:'Image', name:'Image', group:'Components', props:{
|
|
1636
|
-
src:[],
|
|
1637
|
-
}},
|
|
1638
|
-
|
|
1639
|
-
{ type:'EmbeddedVideo', name:'Video', group:'Components', props:{
|
|
1640
|
-
src:[],
|
|
1641
|
-
}},
|
|
1642
|
-
|
|
1643
|
-
{ type:'Article', name:'Article', group:'Components', props:{
|
|
1644
|
-
htmlText:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed convallis odio at odio dapibus, " +
|
|
1645
|
-
"eget molestie risus semper. Aenean magna tellus, aliquet nec tristique eget, lacinia nec urna.",
|
|
1646
|
-
}},
|
|
1647
|
-
|
|
1648
|
-
{ type:'Table', name:'Table', group:'Components', props:{
|
|
1649
|
-
items: []
|
|
1650
|
-
}},
|
|
1651
|
-
|
|
1652
|
-
{ type:'TextBlock', name:'TextBlock', group:'Components', props:{
|
|
1653
|
-
htmlText:'',
|
|
1654
|
-
fontFamily:[], fontSize:[], fontWeight:[], textColor:[]
|
|
1655
|
-
}},
|
|
1656
|
-
|
|
1657
|
-
{ type:'Block', name:'Block', group:'Components', items:[], props:{}},
|
|
1603
|
+
store(){
|
|
1604
|
+
return this.config.params
|
|
1605
|
+
},
|
|
1658
1606
|
|
|
1659
|
-
|
|
1607
|
+
presetSrc(){
|
|
1608
|
+
return this.controller ?
|
|
1609
|
+
`${this.controller}.preset` :
|
|
1610
|
+
'user.preset'
|
|
1611
|
+
},
|
|
1660
1612
|
|
|
1661
|
-
|
|
1613
|
+
viewIndex(){
|
|
1614
|
+
return this.viewTypes.findIndex(_ => _.value === this.store.viewType)
|
|
1615
|
+
}
|
|
1662
1616
|
|
|
1663
|
-
|
|
1617
|
+
},
|
|
1664
1618
|
|
|
1665
|
-
|
|
1619
|
+
data(){
|
|
1620
|
+
return {
|
|
1621
|
+
components: defaultConfig.components,
|
|
1622
|
+
config: {
|
|
1623
|
+
params: {
|
|
1624
|
+
version: '0.0.999',
|
|
1625
|
+
layoutMode: false,
|
|
1626
|
+
selectedComponent: null, // [ 'uid|style', 'style|headers|components|footers' ]
|
|
1627
|
+
tabIndex: 2,
|
|
1628
|
+
viewType: '',
|
|
1629
|
+
zoomLevel: 'fit',
|
|
1630
|
+
width: [ 320, 320 ],
|
|
1631
|
+
previewMode: 1,
|
|
1632
|
+
}
|
|
1633
|
+
},
|
|
1666
1634
|
|
|
1667
|
-
currentArea: null,
|
|
1668
1635
|
currentComponentItems: null,
|
|
1669
1636
|
compClasses: [
|
|
1670
1637
|
'aspectRatio', 'position', 'left', 'top', 'right', 'bottom',
|
|
1671
1638
|
|
|
1672
|
-
'bdSize', '
|
|
1639
|
+
'bdSize', 'bdRadius', 'bdStyle',
|
|
1673
1640
|
'divideSize', 'divideColor', 'divideStyle',
|
|
1674
1641
|
'outlineWidth', 'outlineColor', 'outlineStyle',
|
|
1675
|
-
'
|
|
1642
|
+
'bgSize', 'bgPosition', 'bgRepeat',
|
|
1676
1643
|
'textAlign', 'verticalAlign',
|
|
1677
1644
|
'gap',
|
|
1678
1645
|
'padding', 'margin',
|
|
@@ -1700,7 +1667,11 @@ export default{
|
|
|
1700
1667
|
itemClasses: [
|
|
1701
1668
|
'itemMinWidth', 'itemRatio', 'itemVariant'
|
|
1702
1669
|
],
|
|
1670
|
+
styleClasses: [
|
|
1671
|
+
'bgColors', 'bgImages', 'bdColor'
|
|
1672
|
+
],
|
|
1703
1673
|
host: null,
|
|
1674
|
+
previewHost: null,
|
|
1704
1675
|
iframeStyle: {},
|
|
1705
1676
|
iframeSrc: '',
|
|
1706
1677
|
layouts: [],
|
|
@@ -1709,38 +1680,39 @@ export default{
|
|
|
1709
1680
|
{ text:"Design", value:1 },
|
|
1710
1681
|
{ text:"Preview", value:2 },
|
|
1711
1682
|
],
|
|
1712
|
-
|
|
1683
|
+
viewTypes: [
|
|
1713
1684
|
{ text:'Mobile', value:'' },
|
|
1714
1685
|
{ text:'Tablet', value:'md:' },
|
|
1715
|
-
{ text:'Desktop', value:'xl:' }
|
|
1716
|
-
{ text:'TV', value:'2xl:' },
|
|
1686
|
+
{ text:'Desktop', value:'xl:' }
|
|
1717
1687
|
],
|
|
1718
1688
|
routerBeforeEach: null,
|
|
1719
|
-
|
|
1689
|
+
readyState: 2,
|
|
1720
1690
|
tabItems: [
|
|
1721
1691
|
{ text:"Page Info", value:1 },
|
|
1692
|
+
{ text:"Layout", value:4 },
|
|
1722
1693
|
{ text:"Components", value:2 },
|
|
1723
|
-
{ text:"Datasource", value:3 }
|
|
1724
|
-
],
|
|
1725
|
-
viewTypes: [
|
|
1726
|
-
{ text:'Mobile', value:'' },
|
|
1727
|
-
{ text:'Tablet', value:'md:' },
|
|
1728
|
-
/*{ text:'Desktop', value:'xl:' },
|
|
1729
|
-
{ text:'TV', value:'2xl:' },*/
|
|
1694
|
+
/*{ text:"Datasource", value:3 },*/
|
|
1730
1695
|
],
|
|
1731
1696
|
stylesheets: [
|
|
1732
1697
|
'font-family'
|
|
1733
1698
|
],
|
|
1734
1699
|
updating: true,
|
|
1700
|
+
|
|
1701
|
+
extRightPane: null,
|
|
1702
|
+
debugMode: false,
|
|
1735
1703
|
}
|
|
1736
1704
|
},
|
|
1737
1705
|
|
|
1738
1706
|
emits: [ 'close', 'unmount' ],
|
|
1739
1707
|
|
|
1740
|
-
inject: [ 'alert', '
|
|
1708
|
+
inject: [ 'alert', 'appStyle', 'confirm', 'socket', 'toast' ],
|
|
1741
1709
|
|
|
1742
1710
|
mounted() {
|
|
1743
|
-
this.
|
|
1711
|
+
this.loadPreset()
|
|
1712
|
+
.then(_ => {
|
|
1713
|
+
this.loadLayouts()
|
|
1714
|
+
this.load()
|
|
1715
|
+
})
|
|
1744
1716
|
|
|
1745
1717
|
window.addEventListener('message', this.onMessage)
|
|
1746
1718
|
window.addEventListener('resize', this.onResize)
|
|
@@ -1780,11 +1752,23 @@ export default{
|
|
|
1780
1752
|
getPage: this.getPage,
|
|
1781
1753
|
uploadImage: this.uploadImage,
|
|
1782
1754
|
openComponentSelector: this.openComponentSelector,
|
|
1755
|
+
setUid: this.setUid,
|
|
1756
|
+
openRightPane2: this.openRightPane2,
|
|
1757
|
+
getRightPane: () => this.$refs.rightPane,
|
|
1758
|
+
pageHistory: this.pageHistory,
|
|
1759
|
+
duplicate: this.duplicate
|
|
1783
1760
|
}
|
|
1784
1761
|
},
|
|
1785
1762
|
|
|
1786
1763
|
watch: {
|
|
1787
1764
|
|
|
1765
|
+
config: {
|
|
1766
|
+
deep: true,
|
|
1767
|
+
handler(){
|
|
1768
|
+
this.savePreset()
|
|
1769
|
+
}
|
|
1770
|
+
},
|
|
1771
|
+
|
|
1788
1772
|
currentItem(){
|
|
1789
1773
|
this.$nextTick(() => this.resize())
|
|
1790
1774
|
},
|
|
@@ -1793,6 +1777,11 @@ export default{
|
|
|
1793
1777
|
if(to === 'fit'){
|
|
1794
1778
|
this.$refs.preview.scrollTop = 0
|
|
1795
1779
|
}
|
|
1780
|
+
this.resize()
|
|
1781
|
+
},
|
|
1782
|
+
|
|
1783
|
+
"store.viewType"(to){
|
|
1784
|
+
this.resize()
|
|
1796
1785
|
},
|
|
1797
1786
|
|
|
1798
1787
|
page: {
|
|
@@ -1820,20 +1809,20 @@ export default{
|
|
|
1820
1809
|
.comp{
|
|
1821
1810
|
@apply flex-1;
|
|
1822
1811
|
@apply hidden md:flex flex-row;
|
|
1823
|
-
@apply divide-x divide-
|
|
1812
|
+
@apply divide-x divide-border-50;
|
|
1824
1813
|
}
|
|
1825
1814
|
|
|
1826
1815
|
.resize1{
|
|
1827
|
-
@apply w-[3px] cursor-ew-resize;
|
|
1816
|
+
@apply w-[3px] cursor-ew-resize border-l-[1px] border-border-50;
|
|
1828
1817
|
}
|
|
1829
1818
|
|
|
1830
1819
|
.resize3{
|
|
1831
|
-
@apply w-[3px] cursor-ew-resize;
|
|
1820
|
+
@apply w-[3px] cursor-ew-resize border-r-[1px] border-border-50;
|
|
1832
1821
|
}
|
|
1833
1822
|
|
|
1834
1823
|
.zoomLevel{
|
|
1835
1824
|
@apply appearance-none bg-base-400 text-center outline-none h-[24px] rounded-md;
|
|
1836
|
-
@apply border-[1px] border-
|
|
1825
|
+
@apply border-[1px] border-border-200;
|
|
1837
1826
|
}
|
|
1838
1827
|
|
|
1839
1828
|
</style>
|