Skip to content

Commit b7f80dd

Browse files
committed
- do not show previews for fields that are hidden because of conditions
- user avatar loading indefinitely - copy button for typescript section - show uploading bottom sheet when uploading - remove show additional infos in File Manager
1 parent b34f0cb commit b7f80dd

15 files changed

Lines changed: 176 additions & 57 deletions

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "@json.ms/www",
33
"private": true,
44
"type": "module",
5-
"version": "1.3.3",
5+
"version": "1.3.4",
66
"scripts": {
77
"dev": "vite --host",
88
"build": "run-p type-check \"build-only {@}\" --",

src/components/FileFieldItem.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ const onRemoveFile = (file: IFile) => {
110110
<VideoPlayer
111111
v-else-if="isVideo(file)"
112112
:src="src"
113+
:type="file.meta.type"
113114
:aspect-ratio="(file.meta.width || 1) / (file.meta.height || 1)"
114115
:style="{ float: 'left', width: thumbnailSize(file).width + 'px', height: thumbnailSize(file).height + 'px' }"
115116
controls

src/components/FileManager.vue

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,13 @@ const upload = async (fileList: FileList, type: 'remote' | 'local') => {
221221
}))
222222
}
223223
}
224+
globalStore.showBottomSheet('Uploading file(s)...', null, 'mdi-upload', true);
224225
return Promise.all(promises)
225226
.catch(globalStore.catchError)
226-
.finally(() => uploading.value = false);
227+
.finally(() => {
228+
globalStore.hideBottomSheet();
229+
uploading.value = false
230+
});
227231
}
228232
229233
const remove = () => {
@@ -464,7 +468,9 @@ watch(() => globalStore.fileManager.visible, () => {
464468
<VideoPlayer
465469
v-else-if="item.meta.type?.startsWith('video')"
466470
:src="blobFileList[item.path || 'unknown'] || (serverSettings.publicUrl + item.path)"
471+
:type="item.meta.type"
467472
:aspect-ratio="(item.meta.width || 1) / (item.meta.height || 1)"
473+
controls
468474
/>
469475
<v-sheet v-else>
470476
<v-responsive :aspect-ratio="16 / 9" class="d-flex align-center justify-center text-center">
@@ -568,12 +574,12 @@ watch(() => globalStore.fileManager.visible, () => {
568574
</v-list-item>
569575
</v-list>
570576
</v-menu>
571-
<v-checkbox
572-
v-if="!smAndDown"
573-
v-model="showInfo"
574-
label="Show additional info"
575-
hide-details
576-
/>
577+
<!-- <v-checkbox-->
578+
<!-- v-if="!smAndDown"-->
579+
<!-- v-model="showInfo"-->
580+
<!-- label="Show additional info"-->
581+
<!-- hide-details-->
582+
<!-- />-->
577583
<v-spacer />
578584
<v-btn
579585
v-if="canSelect"

src/components/IntroductionDialog.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const close = () => {
2727
src="https://www.youtube.com/embed/QbzHaJ3GeJM?si=HsQLg2_cXyt97vv1"
2828
title="JSON.ms Youtube Presentation"
2929
frameborder="0"
30-
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
30+
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
3131
referrerpolicy="strict-origin-when-cross-origin"
3232
allowfullscreen
3333
/>

src/components/JSONms.vue

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -99,19 +99,23 @@ const showActionBar = computed((): boolean => {
9999
return ['data'].includes((tab.value || '').toString());
100100
});
101101
102-
const bottomSheetData = ref<{
103-
text: string,
104-
icon?: string,
105-
color?: string,
106-
loading?: boolean,
107-
}>({
108-
text: '',
109-
});
110102
const showBottomSheet = computed((): boolean => {
111-
return downloading.value || userDataLoading.value || structureStates.value.saved;
103+
return globalStore.bottomSheet.visible || structureStates.value.saved;
104+
});
105+
watch(() => downloading.value, () => {
106+
if (downloading.value) {
107+
globalStore.showBottomSheet('Downloading files and generating ZIP file. Please wait...', null, null, true)
108+
} else {
109+
globalStore.hideBottomSheet();
110+
}
111+
});
112+
watch(() => userDataLoading.value, () => {
113+
if (userDataLoading.value) {
114+
globalStore.showBottomSheet('Fetching user data. Please wait...', null, null, true)
115+
} else {
116+
globalStore.hideBottomSheet();
117+
}
112118
});
113-
watch(() => downloading.value, () => bottomSheetData.value = { text: 'Downloading files and generating ZIP file. Please wait...', loading: true });
114-
watch(() => userDataLoading.value, () => bottomSheetData.value = { text: 'Fetching user data. Please wait...', loading: true });
115119
116120
const showEditor = computed({
117121
get(): boolean {
@@ -168,7 +172,7 @@ const onSaveStructure = () => {
168172
if (canSaveStructure.value) {
169173
modelStore.structure.content = modelStore.temporaryContent || modelStore.structure.content;
170174
saveStructure().then(() => {
171-
bottomSheetData.value = { text: 'Structure saved!', color: 'success', icon: 'mdi-check' };
175+
globalStore.showBottomSheet('Structure saved!', 'success', 'mdi-check');
172176
syncToFolder(modelStore.structure, ['structure', 'default', 'typings', 'settings', 'index']);
173177
const newModel = modelStore.structure;
174178
globalStore.addStructure(newModel);
@@ -395,7 +399,7 @@ if (globalStore.session.loggedIn) {
395399
disable-resize-watcher
396400
disable-route-watcher
397401
>
398-
<v-card class="w-100 fill-height d-flex flex-column" theme="dark" tile flat>
402+
<v-card class="w-100 fill-height d-flex flex-column" theme="dark" :style="{ left: showEditor ? 0 : '-1px' }" tile flat>
399403
<StructureEditor
400404
ref="structureEditor"
401405
v-model="structure"
@@ -540,11 +544,11 @@ if (globalStore.session.loggedIn) {
540544
>
541545
<v-card theme="dark" style="margin: 0 auto">
542546
<template #prepend>
543-
<v-progress-circular v-if="bottomSheetData.loading" color="primary" indeterminate class="mr-4" />
544-
<v-icon v-else-if="bottomSheetData.icon" :color="bottomSheetData.color" :icon="bottomSheetData.icon" />
547+
<v-progress-circular v-if="globalStore.bottomSheet.loading" color="primary" indeterminate class="mr-4" />
548+
<v-icon v-else-if="globalStore.bottomSheet.icon" :color="globalStore.bottomSheet.color" :icon="globalStore.bottomSheet.icon" />
545549
</template>
546550
<template #item>
547-
{{ bottomSheetData.text }}
551+
{{ globalStore.bottomSheet.text }}
548552
</template>
549553
</v-card>
550554
</v-bottom-sheet>

src/components/SessionPanel.vue

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
22
import { useGlobalStore } from '@/stores/global';
3-
import { ref } from 'vue';
3+
import {computed, ref} from 'vue';
44
import { Services } from '@/services';
55
import {useModelStore} from '@/stores/model';
66
@@ -42,31 +42,38 @@ const logout = () => {
4242
})
4343
})
4444
}
45+
46+
const userInitials = computed((): string => {
47+
return globalStore.session.user?.name.trim().split(' ')
48+
.map(part => part.substring(0, 1))
49+
.join('').substring(0, 2) || '?';
50+
})
4551
</script>
4652

4753
<template>
4854
<v-menu>
4955
<template #activator="{ props }">
5056
<v-btn v-bind="props" :icon="dense" height="40">
5157
<template v-if="globalStore.session.loggedIn">
52-
<v-avatar size="32" color="primary">
53-
<v-img
54-
v-if="globalStore.session.user?.avatar"
55-
:src="globalStore.session.user?.avatar"
56-
alt="Avatar"
57-
>
58-
<template #placeholder>
59-
<div class="d-flex align-center justify-center fill-height">
60-
<v-progress-circular
61-
color="surface"
62-
indeterminate
63-
size="16"
64-
width="1"
65-
/>
66-
</div>
67-
</template>
68-
</v-img>
69-
<strong v-else>{{ globalStore.session.user?.name.substring(0, 1) }}</strong>
58+
<v-avatar size="32" color="secondary">
59+
<!-- <v-img-->
60+
<!-- v-if="globalStore.session.user?.avatar"-->
61+
<!-- :src="globalStore.session.user?.avatar"-->
62+
<!-- alt="Avatar"-->
63+
<!-- >-->
64+
<!-- <template #placeholder>-->
65+
<!-- <div class="d-flex align-center justify-center fill-height">-->
66+
<!-- <v-progress-circular-->
67+
<!-- color="surface"-->
68+
<!-- indeterminate-->
69+
<!-- size="16"-->
70+
<!-- width="1"-->
71+
<!-- />-->
72+
<!-- </div>-->
73+
<!-- </template>-->
74+
<!-- </v-img>-->
75+
<!-- <strong v-else>{{ globalStore.session.user?.name.substring(0, 1) }}</strong>-->
76+
<strong>{{ userInitials }}</strong>
7077
</v-avatar>
7178
<strong v-if="showUsername" class="ml-3">{{ globalStore.session.user?.name }}</strong>
7279
</template>

src/components/SitePreview.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ defineExpose({
236236
:user-data="userData"
237237
class="fill-height"
238238
columns
239+
show-tabs
239240
@save="onSaveStructureContent"
240241
@create="onCreateStructure"
241242
@change="onStructureContentChange"

src/components/StructureEditor.vue

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ import {useTypings} from "@/composables/typings";
1313
import {useModelStore} from "@/stores/model";
1414
import {useSyncing} from "@/composables/syncing";
1515
import {LineCounter, parseDocument} from "yaml";
16+
import {copyToClipboard} from "@/utils";
1617
// import yaml from 'js-yaml';
1718
1819
const emit = defineEmits(['save', 'create', 'change', 'focus', 'blur']);
1920
const structure = defineModel<IStructure>({ required: true });
20-
const { columns = false, userData } = defineProps<{
21+
const { columns = false, showTabs = false, userData } = defineProps<{
2122
columns?: boolean,
23+
showTabs?: boolean,
2224
structureData: IStructureData,
2325
userData: any
2426
}>();
@@ -42,6 +44,8 @@ const blueprintEditorTypings: Ref<VAceEditorInstance | null> = ref(null);
4244
const blueprintEditorDefault: Ref<VAceEditorInstance | null> = ref(null);
4345
const blueprintTypings = ref('')
4446
const blueprintDefault = ref('')
47+
const disableTypings = ref(false)
48+
const disableDefaultObjects = ref(false)
4549
const blueprintLanguage = ref<'typescript'>('typescript')
4650
4751
const sectionMenu = ref(false);
@@ -79,8 +83,8 @@ const sections = ref([{
7983
disabled: () => false,
8084
}, {
8185
key: 'blueprints',
82-
icon: 'mdi-ruler-square',
83-
title: "Blueprints",
86+
icon: 'mdi-language-typescript',
87+
title: "Typescript",
8488
subtitle: "TypeScript types and default data",
8589
disabledSubtitle: (): string => 'Must be logged in',
8690
disabled: () => false
@@ -194,6 +198,22 @@ const onBlur = () => {
194198
emit('blur');
195199
}
196200
201+
const copy = (content: string, type: 'typings' | 'defaults') => {
202+
switch (type) {
203+
case 'typings': disableTypings.value = true; break;
204+
case 'defaults': disableDefaultObjects.value = true; break;
205+
}
206+
copyToClipboard(content);
207+
globalStore.showBottomSheet('Copied to clipboard!', null, 'mdi-clipboard-check-outline');
208+
setTimeout(() => {
209+
globalStore.hideBottomSheet();
210+
switch (type) {
211+
case 'typings': disableTypings.value = false; break;
212+
case 'defaults': disableDefaultObjects.value = false; break;
213+
}
214+
}, 1000);
215+
}
216+
197217
const printAnnotations = (content: string) => {
198218
const instance = structureEditor.value?.getAceInstance();
199219
if (instance) {
@@ -526,7 +546,16 @@ watch(() => globalStore.userSettings.data, () => {
526546
/>
527547
<div v-else class="d-flex flex-column">
528548
<div v-if="globalStore.uiConfig.structure_menu" class="d-flex align-center pa-1" style="gap: 1rem">
529-
<v-menu v-model="sectionMenu" contained :close-on-content-click="false">
549+
<v-tabs v-if="showTabs" density="compact">
550+
<v-tab
551+
v-for="section in filteredSections"
552+
:key="section.key"
553+
:prepend-icon="section.disabled() ? 'mdi-alert' : section.icon"
554+
:text="section.title"
555+
@click="setSection(section)"
556+
/>
557+
</v-tabs>
558+
<v-menu v-else v-model="sectionMenu" contained :close-on-content-click="false">
530559
<template #activator="{ props }">
531560
<v-btn v-bind="props">
532561
<v-icon :icon="selectedSection?.icon" start />
@@ -700,11 +729,19 @@ watch(() => globalStore.userSettings.data, () => {
700729
}]"
701730
>
702731
<div v-if="globalStore.userSettings.data.blueprintsIncludeTypings" class="d-flex flex-column" style="flex: 1">
703-
<v-alert tile class="py-4 text-caption">
732+
<div class="d-flex justify-space-between bg-sheet pa-2 text-caption">
704733
<div class="text-truncate">
705734
<strong>Readonly:</strong> Typings are generated automatically.
706735
</div>
707-
</v-alert>
736+
<v-btn
737+
:disabled="disableTypings"
738+
size="x-small"
739+
variant="tonal"
740+
@click="() => copy(blueprintTypings, 'typings')"
741+
>
742+
Copy
743+
</v-btn>
744+
</div>
708745
<v-ace-editor
709746
ref="blueprintEditorTypings"
710747
v-model:value="blueprintTypings"
@@ -716,11 +753,19 @@ watch(() => globalStore.userSettings.data, () => {
716753
/>
717754
</div>
718755
<div class="d-flex flex-column" style="flex: 1">
719-
<v-alert tile class="py-4 text-caption">
756+
<div class="d-flex justify-space-between bg-sheet pa-2 text-caption">
720757
<div class="text-truncate">
721758
<strong>Readonly:</strong> Default objects are generated automatically.
722759
</div>
723-
</v-alert>
760+
<v-btn
761+
:disabled="disableDefaultObjects"
762+
size="x-small"
763+
variant="tonal"
764+
@click="() => copy(blueprintDefault, 'defaults')"
765+
>
766+
Copy
767+
</v-btn>
768+
</div>
724769
<v-ace-editor
725770
ref="blueprintEditorDefault"
726771
v-model:value="blueprintDefault"

src/components/Toolbar.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ watch(() => currentRoute.params.locale, () => {
152152
<template #prepend>
153153
<v-tooltip
154154
v-if="globalStore.uiConfig.toolbar_menu"
155-
text="Sections (CTRL+Q)"
155+
text="Sections (ALT+Q)"
156156
location="bottom"
157157
>
158158
<template #activator="{ props }">

src/components/VideoPlayer.vue

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
import {ref} from "vue";
33
44
const src = defineModel<string>('src', { required: true });
5+
const { type } = defineProps<{
6+
type?: string,
7+
}>();
58
69
const hasError = ref(false);
710
const onError = () => {
@@ -21,11 +24,18 @@ const onError = () => {
2124
</div>
2225
<video
2326
v-else
27+
v-bind="$attrs"
2428
:src="src"
2529
width="100%"
2630
disablePictureInPicture
2731
@error="onError"
28-
/>
32+
>
33+
<source
34+
:src="src"
35+
:type="type"
36+
>
37+
Your browser does not support the video tag.
38+
</video>
2939
</v-responsive>
3040
</template>
3141

0 commit comments

Comments
 (0)