@tailor-cms/tce-preview-runtime 0.0.4 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,15 +1,18 @@
1
1
  {
2
2
  "name": "@tailor-cms/tce-preview-runtime",
3
- "version": "0.0.4",
3
+ "version": "0.0.15",
4
4
  "dependencies": {
5
5
  "@mdi/font": "^7.0.96",
6
6
  "@vitejs/plugin-vue": "^3.0.3",
7
7
  "@vueuse/core": "^9.1.1",
8
+ "ky": "^0.31.4",
9
+ "sort-object-keys": "^1.1.3",
8
10
  "split.js": "^1.6.4",
9
11
  "typescript": "^5.1.6",
10
- "vite-plugin-vuetify": "^1.0.2",
11
12
  "vite": "^3.0.7",
13
+ "vite-plugin-vuetify": "^1.0.2",
12
14
  "vue": "^3.2.37",
15
+ "vue-json-pretty": "^2.2.4",
13
16
  "vue-tsc": "^0.39.5",
14
17
  "vuetify": "^3.3.14"
15
18
  },
package/src/App.vue CHANGED
@@ -1,12 +1,37 @@
1
1
  <script setup lang="ts">
2
+ import { onMounted, ref } from 'vue';
3
+ import ky from 'ky';
4
+
2
5
  import AppBar from './components/AppBar.vue';
3
6
  import MainLayout from './components/MainLayout.vue';
7
+
8
+ const SERVER_HOST = `localhost:${import.meta.env.VITE_TCE_SERVER_PORT || 8030}`;
9
+ const api = ky.create({ prefixUrl: `http://${SERVER_HOST}` });
10
+ const ws = new WebSocket(`ws://${SERVER_HOST}`);
11
+
12
+ const element = ref({});
13
+ onMounted(async () => {
14
+ element.value = await getElement();
15
+ ws.addEventListener('message', (event) => {
16
+ element.value = JSON.parse(event.data);
17
+ });
18
+ });
19
+
20
+ async function getElement() {
21
+ try {
22
+ const response = await api('content-element').json();
23
+ return response || {};
24
+ } catch (error) {
25
+ console.log('Error on element get', error);
26
+ return { msg: 'Error upon retrieving element state' };
27
+ }
28
+ }
4
29
  </script>
5
30
 
6
31
  <template>
7
32
  <v-app>
8
33
  <AppBar />
9
- <MainLayout class="mt-14" />
34
+ <MainLayout :element="element" class="mt-14" />
10
35
  </v-app>
11
36
  </template>
12
37
 
@@ -1,23 +1,37 @@
1
1
  <script setup lang="ts">
2
- import { useToggle } from '@vueuse/core';
3
-
4
2
  import logoUrl from '../assets/logo.png';
5
- import { useDarkGlobal } from '../utils';
3
+ import { useGlobalState } from '../state';
6
4
 
7
- const isDark = useDarkGlobal();
8
- const toggleDark = useToggle(isDark);
5
+ const { isDark, toggleDark, showEdit, showDisplay, showBothComponents } =
6
+ useGlobalState();
9
7
  </script>
10
8
 
11
9
  <template>
12
- <v-app-bar :color="isDark ? 'blue-grey-darken-4' : 'grey-lighten-4'">
10
+ <v-app-bar :color="isDark ? 'blue-grey-darken-4' : 'grey-lighten-5'">
13
11
  <template #prepend>
14
- <v-app-bar-nav-icon>
15
- <img :src="logoUrl" alt="Tailor logo" width="32" />
12
+ <v-app-bar-nav-icon class="ml-3">
13
+ <v-avatar :color="isDark ? 'blue-grey-darken-4' : '#333'" size="48">
14
+ <img :src="logoUrl" alt="Tailor logo" width="30" />
15
+ </v-avatar>
16
16
  </v-app-bar-nav-icon>
17
17
  </template>
18
- <v-app-bar-title> Dev Kit </v-app-bar-title>
18
+ <v-app-bar-title class="ml-3 font-weight-bold">Dev Kit</v-app-bar-title>
19
19
  <v-spacer />
20
- <v-btn icon>
20
+ <v-btn-toggle class="mr-4" density="compact" borderless>
21
+ <v-btn @click="showEdit">
22
+ <span>Edit</span>
23
+ <v-icon end>mdi-pencil</v-icon>
24
+ </v-btn>
25
+ <v-btn @click="showDisplay">
26
+ <span>Preview</span>
27
+ <v-icon end>mdi-fullscreen</v-icon>
28
+ </v-btn>
29
+ <v-btn @click="showBothComponents">
30
+ <span>Both</span>
31
+ <v-icon end>mdi-math-norm-box</v-icon>
32
+ </v-btn>
33
+ </v-btn-toggle>
34
+ <v-btn href="https://github.com/tailor-cms/t-xt" icon>
21
35
  <v-icon>mdi-github</v-icon>
22
36
  </v-btn>
23
37
  <v-btn icon @click.prevent="toggleDark()">
@@ -1,42 +1,89 @@
1
1
  <script setup lang="ts">
2
+ import 'vue-json-pretty/lib/styles.css';
3
+
4
+ import * as sortObject from 'sort-object-keys';
2
5
  import { onMounted, ref, watch } from 'vue';
3
6
  import Split from 'split.js';
7
+ import VueJsonPretty from 'vue-json-pretty';
4
8
 
5
- import { useDarkGlobal } from '../utils';
6
- const isDark = useDarkGlobal();
7
- const iframe = ref<HTMLIFrameElement>();
9
+ const SERVER_PROP_ORDER = [
10
+ 'id',
11
+ 'uid',
12
+ 'type',
13
+ 'position',
14
+ 'data',
15
+ 'meta',
16
+ 'refs',
17
+ 'contentId',
18
+ 'contentSignature',
19
+ 'linked',
20
+ 'detached',
21
+ 'createdAt',
22
+ 'updatedAt',
23
+ 'deletedAt',
24
+ ];
8
25
 
9
- watch(isDark, (value) => {
10
- iframe.value?.contentWindow?.postMessage(
11
- `theme-${value ? 'dark' : 'light'}`,
12
- '*',
13
- );
14
- });
26
+ import { PANELS, useGlobalState } from '../state';
27
+
28
+ const LIGHT_BACKGROUND = '#ECEFF1';
29
+ const DARK_BACKGROUND = '#CFD8DC';
30
+
31
+ const props = defineProps<{ element: any }>();
32
+ const { isDark, splitJs } = useGlobalState();
33
+ const backgroundColor = ref('');
15
34
 
16
- onMounted(() => Split(['#splitA', '#splitB']));
35
+ watch(
36
+ isDark,
37
+ (value) => {
38
+ backgroundColor.value = value ? DARK_BACKGROUND : LIGHT_BACKGROUND;
39
+ },
40
+ { immediate: true },
41
+ );
42
+
43
+ onMounted(() => {
44
+ // Component preview split
45
+ splitJs.value = Split([`#${PANELS.EDIT}`, `#${PANELS.DISPLAY}`], {
46
+ minSize: [0, 0],
47
+ });
48
+ // Client/server vertical split
49
+ Split([`#panelTop`, `#panelBottom`], {
50
+ direction: 'vertical',
51
+ sizes: [70, 30],
52
+ });
53
+ });
17
54
  </script>
18
55
 
19
56
  <template>
20
- <main>
21
- <div class="d-flex flex-row h-100">
22
- <iframe
23
- id="splitA"
24
- ref="iframe"
25
- class="w-full p-4"
26
- frameBorder="0"
27
- sandbox="allow-scripts"
28
- src="http://localhost:8010"
29
- title="Edit component container"
30
- ></iframe>
31
- <iframe
32
- id="splitB"
33
- ref="iframe"
34
- class="w-full p-4"
35
- frameBorder="0"
36
- sandbox="allow-scripts"
37
- src="http://localhost:8020"
38
- title="Display component container"
39
- ></iframe>
57
+ <main :class="{ 'dark-theme': isDark }">
58
+ <div id="panelTop" class="d-flex">
59
+ <div class="d-flex flex-grow-1">
60
+ <iframe
61
+ :id="PANELS.EDIT"
62
+ :style="{ backgroundColor }"
63
+ frameBorder="0"
64
+ sandbox="allow-scripts"
65
+ src="http://localhost:8010"
66
+ title="Edit component container"
67
+ >
68
+ </iframe>
69
+ <iframe
70
+ :id="PANELS.DISPLAY"
71
+ :style="{ backgroundColor }"
72
+ frameBorder="0"
73
+ sandbox="allow-scripts"
74
+ src="http://localhost:8020"
75
+ title="Display component container"
76
+ >
77
+ </iframe>
78
+ </div>
79
+ </div>
80
+ <div id="panelBottom" :style="{ backgroundColor }">
81
+ <v-tabs density="compact" hide-slider>
82
+ <v-tab>Server state</v-tab>
83
+ </v-tabs>
84
+ <div class="pa-5">
85
+ <VueJsonPretty :data="sortObject(props.element, SERVER_PROP_ORDER)" />
86
+ </div>
40
87
  </div>
41
88
  </main>
42
89
  </template>
@@ -51,8 +98,21 @@ main {
51
98
  }
52
99
 
53
100
  .gutter.gutter-horizontal {
54
- background-color: #333;
55
- background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==');
56
101
  cursor: col-resize;
102
+ background-color: #fff;
103
+ background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==');
104
+ }
105
+
106
+ .gutter.gutter-vertical {
107
+ cursor: row-resize !important;
108
+ background-color: #fff;
109
+ background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==');
110
+ }
111
+
112
+ .dark-theme {
113
+ .gutter.gutter-horizontal,
114
+ .gutter.gutter-vertical {
115
+ background-color: #333;
116
+ }
57
117
  }
58
118
  </style>
@@ -0,0 +1 @@
1
+ export * from './preview';
@@ -0,0 +1,40 @@
1
+ import { createGlobalState, useToggle } from '@vueuse/core';
2
+ import { ref } from 'vue';
3
+
4
+ export const PANELS = {
5
+ EDIT: 'editPanel',
6
+ DISPLAY: 'displayPanel',
7
+ STATE: 'statePanel',
8
+ };
9
+
10
+ export const useGlobalState = createGlobalState(() => {
11
+ // Control color scheme
12
+ const isDark = ref(false);
13
+ const toggleDark = useToggle(isDark);
14
+
15
+ // Control panels
16
+ const visiblePanels = ref(['EDIT', 'DISPLAY', 'STATE']);
17
+ const splitJs = ref();
18
+ const showEdit = () => {
19
+ visiblePanels.value = [PANELS.EDIT];
20
+ if (splitJs.value) splitJs.value?.setSizes([100, 0]);
21
+ };
22
+ const showDisplay = () => {
23
+ visiblePanels.value = [PANELS.DISPLAY];
24
+ if (splitJs.value) splitJs.value?.setSizes([0, 100]);
25
+ };
26
+ const showBothComponents = () => {
27
+ visiblePanels.value = [PANELS.EDIT, PANELS.DISPLAY];
28
+ if (splitJs.value) splitJs.value?.setSizes([50, 50]);
29
+ };
30
+
31
+ return {
32
+ isDark,
33
+ toggleDark,
34
+ visiblePanels,
35
+ splitJs,
36
+ showEdit,
37
+ showDisplay,
38
+ showBothComponents,
39
+ };
40
+ });
@@ -1,3 +0,0 @@
1
- import { createGlobalState, useDark } from '@vueuse/core';
2
-
3
- export const useDarkGlobal = createGlobalState(() => useDark());
@@ -1 +0,0 @@
1
- export * from './helpers';