Skip to content

Commit ac434c2

Browse files
committed
feat(desk): v-gallery loading mode
1 parent 3e781ac commit ac434c2

File tree

5 files changed

+78
-48
lines changed

5 files changed

+78
-48
lines changed

packages/core/entities/view-gallery.ts

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,6 @@ export interface ViewGallerySize {
55
height: number | string
66
}
77

8-
export interface ViewGallerySizes {
9-
sm: ViewGallerySize
10-
md: ViewGallerySize
11-
lg: ViewGallerySize
12-
}
13-
148
export interface ViewGalleryThumbnail {
159
key?: string
1610
position?: string
@@ -20,24 +14,7 @@ export interface ViewGalleryThumbnail {
2014
export default class ViewGallery extends View {
2115
public readonly component = 'gallery'
2216

23-
public thumbnail: ViewGalleryThumbnail = {
24-
key: '',
25-
position: '',
26-
fit: '',
27-
}
17+
public thumbnail?: ViewGalleryThumbnail
2818

29-
public sizes: Record<string, ViewGallerySize> = {
30-
sm: {
31-
width: 200,
32-
height: 'auto',
33-
},
34-
md: {
35-
width: 282,
36-
height: 'auto',
37-
},
38-
lg: {
39-
width: 200,
40-
height: 'auto',
41-
},
42-
}
19+
public sizes?: Record<'sm' | 'md' | 'lg', ViewGallerySize>
4320
}

packages/desktop/components/v-gallery.vue

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ const props = defineProps({
2424
type: [String, Number],
2525
default: 20,
2626
},
27+
loading: {
28+
type: Boolean,
29+
default: false,
30+
},
31+
itemKey: {
32+
type: String,
33+
default: '',
34+
},
2735
})
2836
2937
// bindings
@@ -82,9 +90,26 @@ const visibleItems = computed(() => props.items.slice(0, pagination.value.limit)
8290
</script>
8391

8492
<template>
85-
<div ref="rootRef" class="flex flex-wrap gap-4">
93+
<div
94+
ref="rootRef"
95+
class="flex flex-wrap gap-4 relative"
96+
:class="loading ? 'animate-pulse' : ''"
97+
>
98+
<div v-if="loading" class="absolute top-0 left-0 h-[1px] w-full bg-accent animate-pulse" />
99+
100+
<v-card
101+
v-else-if="!items.length"
102+
width="100%"
103+
height="100"
104+
:color="color"
105+
class="flex items-center justify-center"
106+
>
107+
{{ $t('noEntity', [$t('item', 2)]) }}
108+
</v-card>
109+
86110
<slot
87111
v-for="(item, index) in visibleItems"
112+
:key="item[itemKey]"
88113
name="item"
89114
:size="size"
90115
:index="index"
@@ -94,7 +119,6 @@ const visibleItems = computed(() => props.items.slice(0, pagination.value.limit)
94119
:item="item"
95120
>
96121
<v-card
97-
:key="index"
98122
:width="size.width"
99123
:height="size.height"
100124
class="overflow-auto"
@@ -109,16 +133,6 @@ const visibleItems = computed(() => props.items.slice(0, pagination.value.limit)
109133
</v-card>
110134
</slot>
111135

112-
<v-card
113-
v-if="!items.length"
114-
width="100%"
115-
height="100"
116-
:color="color"
117-
class="flex items-center justify-center"
118-
>
119-
{{ $t('noEntity', [$t('item', 2)]) }}
120-
</v-card>
121-
122136
<slot
123137
name="append-body"
124138
:size="size"

packages/desktop/i18n/en-US.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export default {
7171
heightEntity: 'Height {0}',
7272
position: 'Position',
7373
fit: 'Fit',
74+
loadingEntity: 'Loading {0}',
7475
errors: {
7576
workspaceNotFound: '@:workspace not found: {0}',
7677
collectionNotFound: '@:collection not found: {1}',

packages/desktop/modules/collection/components/CGallery.vue

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,39 @@ const columns = computed({
8484
},
8585
})
8686
87+
// thumbnail
88+
89+
const thumbnail = computed(() => {
90+
if (view.value.thumbnail) return view.value.thumbnail
91+
92+
return {
93+
key: '',
94+
position: '',
95+
fit: '',
96+
}
97+
})
98+
99+
// sizes
100+
101+
const sizes = computed(() => {
102+
if (view.value.sizes) return view.value.sizes
103+
104+
return {
105+
sm: {
106+
width: 200,
107+
height: 'auto',
108+
},
109+
md: {
110+
width: 282,
111+
height: 'auto',
112+
},
113+
lg: {
114+
width: 200,
115+
height: 'auto',
116+
},
117+
}
118+
})
119+
87120
// count visible columns
88121
89122
const visibleColumns = computed(() => view.value.columns.filter((c) => !c.hide).length)
@@ -213,7 +246,8 @@ const updateItem = debounce(store.item.update, 500)
213246
:columns="columns"
214247
v-bind="bindings.gallery"
215248
:loading="loading"
216-
:sizes="view.sizes"
249+
:sizes="sizes"
250+
item-key="id"
217251
>
218252
<template #item="data">
219253
<v-card
@@ -224,17 +258,21 @@ const updateItem = debounce(store.item.update, 500)
224258
v-bind="data.bindings.card"
225259
>
226260
<e-img
227-
v-if="view.thumbnail.key"
228-
:src="data.item[view.thumbnail.key]"
261+
v-if="thumbnail.key"
262+
:src="data.item[thumbnail.key]"
229263
:height="`calc(100% - ${visibleColumns * 48}px)`"
230-
:fit="view.thumbnail.fit"
231-
:position="view.thumbnail.position"
264+
:fit="thumbnail.fit"
265+
:position="thumbnail.position"
232266
width="100%"
233267
class="object-cover"
234268
/>
235269

236-
<template v-for="(c, cIndex) in data.columns" :key="cIndex">
237-
<is-list-item v-if="!c.hide" size="px-1 py-1">
270+
<template v-for="c in data.columns" :key="`${c.id}-${data.item.id}`">
271+
<is-list-item
272+
v-if="!c.hide"
273+
:id="`${c.id}-${data.item.id}`"
274+
size="px-1 py-1"
275+
>
238276
<i-value
239277
:model-value="data.item[c.field]"
240278
:column="c"

packages/desktop/modules/item/components/IValue.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,24 @@ import template from 'lodash/template'
44
55
import uuid from 'uuid-random'
66
7-
import { CollectionColumn } from '@core/entities/collection'
7+
import Column from '@core/entities/column'
88
import Item from '@core/entities/item'
9+
import DirectoryEntry from '@core/entities/directory-entry'
910
import ExecuteScriptDTO from '@core/use-cases/execute-script/execute-script.dto'
1011
1112
import SOutput from '@/modules/script/components/SOutput.vue'
1213
import EEntryIcon from '@/modules/entry/components/EEntryIcon.vue'
1314
1415
import { useVModel } from 'vue-wind/composables/v-model'
1516
import { useStore } from '../store'
16-
import DirectoryEntry from '@/../core/entities/directory-entry'
1717
1818
const props = defineProps({
1919
modelValue: {
2020
type: [String, Number, Object] as PropType<any>,
2121
default: null,
2222
},
2323
column: {
24-
type: Object as () => CollectionColumn,
24+
type: Object as () => Column,
2525
required: true,
2626
},
2727
item: {
@@ -213,5 +213,5 @@ function upload() {
213213
</div>
214214
</template>
215215

216-
<is-input v-else v-model="model" flat />
216+
<is-input v-else-if="typeof model === 'string'" v-model="model" flat />
217217
</template>

0 commit comments

Comments
 (0)