@tailor-cms/tce-preview-runtime 0.5.0 → 0.5.2
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/CHANGELOG.md +13 -0
- package/package.json +16 -14
- package/src/App.vue +3 -3
- package/src/components/AppBar.vue +34 -34
- package/src/components/BottomPanel.vue +14 -14
- package/src/components/MainLayout.vue +17 -38
- package/src/components/MutationList.vue +8 -8
- package/src/components/SplashLoader.vue +21 -53
- package/vite.config.ts +0 -4
package/CHANGELOG.md
ADDED
package/package.json
CHANGED
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailor-cms/tce-preview-runtime",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"dependencies": {
|
|
5
6
|
"@lukeed/uuid": "^2.0.1",
|
|
6
|
-
"@mdi/font": "7.
|
|
7
|
-
"@vitejs/plugin-vue": "
|
|
8
|
-
"@vueuse/core": "
|
|
9
|
-
"date-fns": "^
|
|
10
|
-
"ky": "1.
|
|
7
|
+
"@mdi/font": "7.4.47",
|
|
8
|
+
"@vitejs/plugin-vue": "5.2.1",
|
|
9
|
+
"@vueuse/core": "12.5.0",
|
|
10
|
+
"date-fns": "^4.1.0",
|
|
11
|
+
"ky": "1.7.4",
|
|
11
12
|
"lodash": "^4.17.21",
|
|
12
|
-
"sass": "1.
|
|
13
|
+
"sass": "1.84.0",
|
|
13
14
|
"split.js": "1.6.5",
|
|
14
15
|
"stringify-object": "^5.0.0",
|
|
15
|
-
"typescript": "5.
|
|
16
|
-
"universal-cookie": "^
|
|
17
|
-
"vite": "
|
|
18
|
-
"vite-plugin-vuetify": "1.0
|
|
19
|
-
"vue": "3.
|
|
20
|
-
"vue-tsc": "
|
|
21
|
-
"vuetify": "3.
|
|
16
|
+
"typescript": "5.7.3",
|
|
17
|
+
"universal-cookie": "^7.2.2",
|
|
18
|
+
"vite": "6.1.0",
|
|
19
|
+
"vite-plugin-vuetify": "2.1.0",
|
|
20
|
+
"vue": "3.5.13",
|
|
21
|
+
"vue-tsc": "2.2.0",
|
|
22
|
+
"vuetify": "3.7.11"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
25
|
+
"@types/stringify-object": "^4.0.5",
|
|
24
26
|
"@tailor-cms/eslint-config": "0.0.2"
|
|
25
27
|
},
|
|
26
28
|
"publishConfig": {
|
package/src/App.vue
CHANGED
|
@@ -14,13 +14,13 @@ const appUrl = new URL(window.location.href);
|
|
|
14
14
|
const apiPrefix = '/tce-server';
|
|
15
15
|
const api = ky.create({ prefixUrl: apiPrefix });
|
|
16
16
|
const wsProtocol = appUrl.protocol === 'http:' ? 'ws:' : 'wss:';
|
|
17
|
-
const ws = new WebSocket(`${wsProtocol}//${appUrl.host}${apiPrefix}`);
|
|
18
17
|
|
|
19
18
|
const element = ref<ContentElement>();
|
|
20
19
|
const userState = ref({});
|
|
21
20
|
|
|
22
21
|
onMounted(async () => {
|
|
23
22
|
await getElement();
|
|
23
|
+
const ws = new WebSocket(`${wsProtocol}//${appUrl.host}${apiPrefix}`);
|
|
24
24
|
ws.addEventListener('message', (message) => {
|
|
25
25
|
const event = JSON.parse(message.data);
|
|
26
26
|
const elementUid = element.value?.uid;
|
|
@@ -70,7 +70,7 @@ async function resetState() {
|
|
|
70
70
|
</script>
|
|
71
71
|
|
|
72
72
|
<template>
|
|
73
|
-
<
|
|
73
|
+
<VApp>
|
|
74
74
|
<AppBar />
|
|
75
75
|
<MainLayout
|
|
76
76
|
:element="element"
|
|
@@ -79,7 +79,7 @@ async function resetState() {
|
|
|
79
79
|
@reset-element="resetElement"
|
|
80
80
|
@reset-state="resetState"
|
|
81
81
|
/>
|
|
82
|
-
</
|
|
82
|
+
</VApp>
|
|
83
83
|
</template>
|
|
84
84
|
|
|
85
85
|
<style>
|
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import logoUrl from '../assets/logo.png';
|
|
3
|
-
import { useGlobalState } from '../state';
|
|
4
|
-
import { version } from './../../package.json';
|
|
5
|
-
|
|
6
|
-
const { showEdit, showDisplay, showBothComponents } = useGlobalState();
|
|
7
|
-
</script>
|
|
8
|
-
|
|
9
1
|
<template>
|
|
10
|
-
<
|
|
2
|
+
<VAppBar color="blue-grey-darken-4" elevation="6">
|
|
11
3
|
<template #prepend>
|
|
12
|
-
<
|
|
4
|
+
<VAppBarNavIcon class="ml-2">
|
|
13
5
|
<img :src="logoUrl" alt="Tailor logo" width="36" />
|
|
14
|
-
</
|
|
6
|
+
</VAppBarNavIcon>
|
|
15
7
|
</template>
|
|
16
|
-
<
|
|
8
|
+
<VAppBarTitle class="ml-2">
|
|
17
9
|
Content Element Kit
|
|
18
|
-
<
|
|
10
|
+
<VChip
|
|
19
11
|
class="ml-3 mb-1 text-body-2"
|
|
20
12
|
color="#23F48B"
|
|
21
13
|
density="compact"
|
|
22
14
|
variant="tonal"
|
|
23
15
|
>
|
|
24
16
|
{{ version }}
|
|
25
|
-
</
|
|
26
|
-
</
|
|
27
|
-
<
|
|
28
|
-
<
|
|
29
|
-
<
|
|
17
|
+
</VChip>
|
|
18
|
+
</VAppBarTitle>
|
|
19
|
+
<VSpacer />
|
|
20
|
+
<VBtnToggle class="mr-4" density="compact">
|
|
21
|
+
<VBtn @click="showEdit">
|
|
30
22
|
<span>Authoring</span>
|
|
31
|
-
<
|
|
32
|
-
</
|
|
33
|
-
<
|
|
23
|
+
<VIcon end>mdi-pencil</VIcon>
|
|
24
|
+
</VBtn>
|
|
25
|
+
<VBtn @click="showDisplay">
|
|
34
26
|
<span>End-user</span>
|
|
35
|
-
<
|
|
36
|
-
</
|
|
37
|
-
<
|
|
27
|
+
<VIcon end>mdi-fullscreen</VIcon>
|
|
28
|
+
</VBtn>
|
|
29
|
+
<VBtn @click="showBothComponents">
|
|
38
30
|
<span>Both</span>
|
|
39
|
-
<
|
|
40
|
-
</
|
|
41
|
-
</
|
|
42
|
-
<
|
|
43
|
-
<
|
|
44
|
-
</
|
|
45
|
-
<
|
|
46
|
-
<
|
|
47
|
-
</
|
|
48
|
-
</
|
|
31
|
+
<VIcon end>mdi-math-norm-box</VIcon>
|
|
32
|
+
</VBtn>
|
|
33
|
+
</VBtnToggle>
|
|
34
|
+
<VBtn href="https://github.com/tailor-cms/tce-template" icon>
|
|
35
|
+
<VIcon>mdi-github</VIcon>
|
|
36
|
+
</VBtn>
|
|
37
|
+
<VBtn href="https://tailor-cms.github.io/xt/" icon>
|
|
38
|
+
<VIcon>mdi-book-outline</VIcon>
|
|
39
|
+
</VBtn>
|
|
40
|
+
</VAppBar>
|
|
49
41
|
</template>
|
|
42
|
+
|
|
43
|
+
<script setup lang="ts">
|
|
44
|
+
import logoUrl from '../assets/logo.png';
|
|
45
|
+
import { useGlobalState } from '../state';
|
|
46
|
+
import { version } from './../../package.json';
|
|
47
|
+
|
|
48
|
+
const { showEdit, showDisplay, showBothComponents } = useGlobalState();
|
|
49
|
+
</script>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div v-show="isLoaded">
|
|
3
|
-
<
|
|
4
|
-
<
|
|
3
|
+
<VTabs v-model="state.selectedTab">
|
|
4
|
+
<VTab :value="1">
|
|
5
5
|
<VChip append-icon="mdi-pen" class="mr-2" color="indigo" size="small">
|
|
6
6
|
{{ state.elementHistory.length }}
|
|
7
7
|
</VChip>
|
|
8
8
|
Authoring history
|
|
9
|
-
</
|
|
10
|
-
<
|
|
9
|
+
</VTab>
|
|
10
|
+
<VTab :value="2">
|
|
11
11
|
<VChip
|
|
12
12
|
append-icon="mdi-account"
|
|
13
13
|
class="mr-2"
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
{{ state.userInteractions.length }}
|
|
18
18
|
</VChip>
|
|
19
19
|
End-User state history
|
|
20
|
-
</
|
|
21
|
-
</
|
|
20
|
+
</VTab>
|
|
21
|
+
</VTabs>
|
|
22
22
|
<div class="pa-6">
|
|
23
|
-
<
|
|
24
|
-
<
|
|
23
|
+
<VWindow v-model="state.selectedTab">
|
|
24
|
+
<VWindowItem :value="1">
|
|
25
25
|
<VBtn
|
|
26
26
|
class="mb-4"
|
|
27
|
-
color="
|
|
27
|
+
color="indigoDarken4"
|
|
28
28
|
variant="tonal"
|
|
29
29
|
@click="$emit('resetElement')"
|
|
30
30
|
>
|
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
Reset content element
|
|
33
33
|
</VBtn>
|
|
34
34
|
<MutationList :changes="state.elementHistory" />
|
|
35
|
-
</
|
|
36
|
-
<
|
|
35
|
+
</VWindowItem>
|
|
36
|
+
<VWindowItem :value="2">
|
|
37
37
|
<VBtn
|
|
38
38
|
class="mb-4"
|
|
39
|
-
color="
|
|
39
|
+
color="indigoDarken4"
|
|
40
40
|
variant="tonal"
|
|
41
41
|
@click="$emit('resetState')"
|
|
42
42
|
>
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
Reset state context
|
|
45
45
|
</VBtn>
|
|
46
46
|
<MutationList :changes="state.userInteractions" />
|
|
47
|
-
</
|
|
48
|
-
</
|
|
47
|
+
</VWindowItem>
|
|
48
|
+
</VWindow>
|
|
49
49
|
</div>
|
|
50
50
|
</div>
|
|
51
51
|
</template>
|
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<main :class="{ 'dark-theme': isDark }">
|
|
3
|
+
<SplashLoader :is-visible="!isLoaded" />
|
|
4
|
+
<PreviewPanel id="panelTop" :is-loaded="isLoaded" />
|
|
5
|
+
<BottomPanel
|
|
6
|
+
id="panelBottom"
|
|
7
|
+
:element="props.element"
|
|
8
|
+
:is-loaded="isLoaded"
|
|
9
|
+
:user-state="props.userState"
|
|
10
|
+
class="preview-panel-bottom"
|
|
11
|
+
@reset-element="$emit('resetElement')"
|
|
12
|
+
@reset-state="$emit('resetState')"
|
|
13
|
+
/>
|
|
14
|
+
</main>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
1
17
|
<script setup lang="ts">
|
|
2
18
|
import { onMounted, ref } from 'vue';
|
|
3
19
|
import Split from 'split.js';
|
|
@@ -13,53 +29,16 @@ const props = defineProps<{ element: any; userState: any }>();
|
|
|
13
29
|
const { isDark } = useGlobalState();
|
|
14
30
|
const isLoaded = ref(false);
|
|
15
31
|
|
|
16
|
-
const runtimeId = import.meta.env.VITE_RUNTIME_ID;
|
|
17
|
-
const bootRegistry = JSON.parse(
|
|
18
|
-
localStorage.getItem('element-kit-boot') || '{}',
|
|
19
|
-
);
|
|
20
|
-
const isFirstBoot = !bootRegistry[runtimeId];
|
|
21
|
-
if (isFirstBoot) {
|
|
22
|
-
localStorage.setItem(
|
|
23
|
-
'element-kit-boot',
|
|
24
|
-
JSON.stringify({
|
|
25
|
-
...bootRegistry,
|
|
26
|
-
[runtimeId]: true,
|
|
27
|
-
}),
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
32
|
onMounted(() => {
|
|
32
33
|
// Client/server vertical split
|
|
33
34
|
Split([`#panelTop`, `#panelBottom`], {
|
|
34
35
|
direction: 'vertical',
|
|
35
36
|
sizes: [70, 30],
|
|
36
37
|
});
|
|
37
|
-
setTimeout(
|
|
38
|
-
() => {
|
|
39
|
-
isLoaded.value = true;
|
|
40
|
-
if (isFirstBoot) document.location.reload();
|
|
41
|
-
},
|
|
42
|
-
isFirstBoot ? 25000 : 5000,
|
|
43
|
-
);
|
|
38
|
+
setTimeout(() => { isLoaded.value = true; }, 5000);
|
|
44
39
|
});
|
|
45
40
|
</script>
|
|
46
41
|
|
|
47
|
-
<template>
|
|
48
|
-
<main :class="{ 'dark-theme': isDark }">
|
|
49
|
-
<SplashLoader :is-first-boot="isFirstBoot" :is-visible="!isLoaded" />
|
|
50
|
-
<PreviewPanel id="panelTop" :is-loaded="isLoaded" />
|
|
51
|
-
<BottomPanel
|
|
52
|
-
id="panelBottom"
|
|
53
|
-
:element="props.element"
|
|
54
|
-
:is-loaded="isLoaded"
|
|
55
|
-
:user-state="props.userState"
|
|
56
|
-
class="preview-panel-bottom"
|
|
57
|
-
@reset-element="$emit('resetElement')"
|
|
58
|
-
@reset-state="$emit('resetState')"
|
|
59
|
-
/>
|
|
60
|
-
</main>
|
|
61
|
-
</template>
|
|
62
|
-
|
|
63
42
|
<style>
|
|
64
43
|
main {
|
|
65
44
|
height: calc(100vh - var(--nav-height));
|
|
@@ -2,23 +2,23 @@
|
|
|
2
2
|
<VDataIterator :items="changes" :items-per-page="50" expand-on-click>
|
|
3
3
|
<template #default="{ items, isExpanded, toggleExpand }">
|
|
4
4
|
<template v-for="(item, index) in items" :key="item.raw.id">
|
|
5
|
-
<
|
|
5
|
+
<VCard
|
|
6
6
|
:disabled="index === 0"
|
|
7
7
|
:ripple="false"
|
|
8
8
|
class="mb-1"
|
|
9
|
-
@click="toggleExpand(item)"
|
|
9
|
+
@click="toggleExpand(item as any)"
|
|
10
10
|
>
|
|
11
|
-
<
|
|
11
|
+
<VCardTitle class="d-flex align-center">
|
|
12
12
|
<v-icon color="orange-darken-3" icon="mdi-update" size="18" start />
|
|
13
13
|
<div class="text-body-1">{{ item.raw.title }}</div>
|
|
14
|
-
</
|
|
15
|
-
<
|
|
16
|
-
v-show="isExpanded(item) || index === 0"
|
|
14
|
+
</VCardTitle>
|
|
15
|
+
<VCardText
|
|
16
|
+
v-show="isExpanded(item as any) || index === 0"
|
|
17
17
|
class="text-indigo-darken-4 bg-blue-grey-lighten-5 py-2 ma-3"
|
|
18
18
|
>
|
|
19
19
|
<pre>{{ stringifyObject(item.raw.data, { indent: ' ' }) }}</pre>
|
|
20
|
-
</
|
|
21
|
-
</
|
|
20
|
+
</VCardText>
|
|
21
|
+
</VCard>
|
|
22
22
|
</template>
|
|
23
23
|
</template>
|
|
24
24
|
</VDataIterator>
|
|
@@ -7,11 +7,6 @@
|
|
|
7
7
|
</div>
|
|
8
8
|
<div class="splash-loader__text text-body-1">
|
|
9
9
|
<div>Booting Content Element Kit....</div>
|
|
10
|
-
<v-progress-linear
|
|
11
|
-
v-if="isFirstBoot"
|
|
12
|
-
:model-value="progress"
|
|
13
|
-
class="my-3"
|
|
14
|
-
/>
|
|
15
10
|
<div class="font-weight-bold">Beta preview v{{ version }}</div>
|
|
16
11
|
</div>
|
|
17
12
|
</div>
|
|
@@ -19,57 +14,30 @@
|
|
|
19
14
|
</transition>
|
|
20
15
|
</template>
|
|
21
16
|
|
|
22
|
-
<script lang="ts">
|
|
17
|
+
<script lang="ts" setup>
|
|
18
|
+
import { onMounted } from 'vue';
|
|
19
|
+
|
|
23
20
|
import logoUrl from '../assets/logo.png';
|
|
24
21
|
import { version } from './../../package.json';
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
backgroundColor: {
|
|
45
|
-
type: String,
|
|
46
|
-
default: '#fff',
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
data: () => ({
|
|
50
|
-
interval: 0,
|
|
51
|
-
progress: 0,
|
|
52
|
-
}),
|
|
53
|
-
computed: {
|
|
54
|
-
version: () => version,
|
|
55
|
-
},
|
|
56
|
-
mounted() {
|
|
57
|
-
this.setColor();
|
|
58
|
-
if (!this.isFirstBoot) return;
|
|
59
|
-
this.interval = setInterval(() => {
|
|
60
|
-
this.progress += 1;
|
|
61
|
-
if (this.progress === 100) clearInterval(this.interval);
|
|
62
|
-
}, 200);
|
|
63
|
-
},
|
|
64
|
-
beforeUnmount() {
|
|
65
|
-
clearInterval(this.interval);
|
|
66
|
-
},
|
|
67
|
-
methods: {
|
|
68
|
-
setColor() {
|
|
69
|
-
document.documentElement.style.setProperty('--splash-color', this.color);
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
};
|
|
23
|
+
interface Props {
|
|
24
|
+
isVisible: boolean;
|
|
25
|
+
logo?: string;
|
|
26
|
+
color?: string;
|
|
27
|
+
backgroundColor?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
31
|
+
isVisible: true,
|
|
32
|
+
logo: logoUrl,
|
|
33
|
+
color: '#00bfa5',
|
|
34
|
+
backgroundColor: '#fff',
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
onMounted(() => {
|
|
38
|
+
const color = props.color || '#00bfa5';
|
|
39
|
+
document.documentElement.style.setProperty('--splash-color', color);
|
|
40
|
+
});
|
|
73
41
|
</script>
|
|
74
42
|
|
|
75
43
|
<style lang="scss" scoped>
|
package/vite.config.ts
CHANGED