Skip to content

Commit 2af2a98

Browse files
committed
fix(desk): filters & hide columns not working
1 parent 7a45795 commit 2af2a98

File tree

13 files changed

+611
-187
lines changed

13 files changed

+611
-187
lines changed

packages/core/entities/view-common.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export interface ViewColumn extends Partial<Column> {
1515
}
1616

1717
export default class ViewCommon extends View {
18+
public search = ''
1819
public filters: ViewFilter[] = []
1920
public columns: ViewColumn[] = []
2021
}

packages/desktop/i18n/en-US.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export default {
7575
loadingEntity: 'Loading {0}',
7676
table: 'Table',
7777
gallery: 'Gallery',
78+
loading: 'Loading',
7879
errors: {
7980
unknown: 'Unknown error',
8081
workspaceNotFound: '@:workspace not found: {0}',
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
<script setup lang="ts">
2+
import { computed, ref, watch, onMounted } from 'vue'
3+
4+
import Column, { ColumnType } from '@core/entities/column'
5+
6+
import { useStore as useCollectionStore } from '@/modules/collection/store'
7+
import { useStore } from '@/modules/collection-column/store'
8+
9+
import MEditor from '@/modules/monaco/components/MEditor.vue'
10+
import { useNonReactive } from '@/composables/utils'
11+
import { useI18n } from 'vue-i18n'
12+
13+
import { lib as libScriptColumn } from '@/modules/monaco/libs/column-script'
14+
15+
// Props & emits
16+
const props = defineProps({
17+
collectionId: {
18+
type: String,
19+
required: true,
20+
},
21+
columnId: {
22+
type: String,
23+
required: true,
24+
},
25+
})
26+
27+
// column
28+
const store = useStore()
29+
30+
const column = computed(() => store.get(props.collectionId, props.columnId))
31+
const loading = computed(() => store.isLoading(props.collectionId))
32+
33+
onMounted(async () => {
34+
if (!column.value) {
35+
await store.set(props.collectionId)
36+
}
37+
})
38+
39+
// form
40+
const tm = useI18n()
41+
42+
const payload = ref<Column>({
43+
id: '',
44+
label: '',
45+
field: '',
46+
type: ColumnType.text,
47+
content: '',
48+
options: undefined,
49+
collectionId: undefined,
50+
displayField: undefined,
51+
})
52+
53+
const types = Object.values(ColumnType).map((v) => ({
54+
label: tm.t(v),
55+
value: v,
56+
}))
57+
58+
async function submit() {
59+
if (!column.value) return
60+
61+
Object.keys(payload.value).forEach((key) => {
62+
column.value![key] = payload.value[key]
63+
})
64+
65+
dialog.value = false
66+
}
67+
68+
// icons
69+
const icons: Record<Column['type'], any> = {
70+
text: 'font',
71+
number: 'hashtag',
72+
select: 'fa-regular fa-square-caret-down',
73+
relation: 'arrow-up',
74+
script: 'code',
75+
entry: 'file',
76+
}
77+
78+
// dialog
79+
const dialog = ref(false)
80+
81+
watch(dialog, (value) => {
82+
if (!value) return
83+
84+
if (column.value) {
85+
payload.value = useNonReactive(column.value)
86+
}
87+
})
88+
89+
async function deleteColumn() {
90+
await store.destroy(props.collectionId, props.columnId)
91+
92+
dialog.value = false
93+
}
94+
95+
// collections
96+
const collectionStore = useCollectionStore()
97+
98+
// relation selected collection options
99+
100+
const relation = computed(() => {
101+
const { collectionId } = payload.value
102+
103+
if (!collectionId) return null
104+
105+
const collection = collectionStore.collections.find((c) => c.id === collectionId)
106+
107+
if (!collection) return null
108+
109+
return collection
110+
})
111+
</script>
112+
<template>
113+
<div
114+
v-if="loading"
115+
class="text-t-secondary text-sm overflow-hidden animate-pulse"
116+
v-bind="$attrs"
117+
>
118+
{{ $t('loading') }}...
119+
</div>
120+
121+
<div v-else-if="!column" class="text-t-secondary text-sm overflow-hidden" v-bind="$attrs">
122+
<is-icon name="triangle-exclamation" class="mr-2 text-xs" />
123+
{{ $t('errors.unknown') }}
124+
</div>
125+
126+
<v-dialog v-else v-model="dialog">
127+
<template #activator="{ attrs }">
128+
<div
129+
class="cursor-pointer text-t-secondary text-sm flex items-center overflow-hidden"
130+
v-bind="{ ...attrs, ...$attrs }"
131+
>
132+
<fa-icon :icon="icons[column.type] || 'font'" class="mr-2 text-xs" />
133+
134+
{{ column.label }}
135+
</div>
136+
</template>
137+
138+
<v-card width="500" color="b-secondary">
139+
<v-card-head class="px-4">
140+
<v-card-title>
141+
{{ $t('editEntity', [$t('column')]) }}
142+
</v-card-title>
143+
<v-btn text color="danger" class="ml-auto" @click="deleteColumn">
144+
<is-icon name="trash" />
145+
</v-btn>
146+
</v-card-head>
147+
148+
<v-card-content>
149+
<w-form class="w-full" @submit="submit">
150+
<div class="mb-4">
151+
<is-input v-model="payload.label" label="Label" />
152+
</div>
153+
154+
<div class="mb-4">
155+
<is-select
156+
v-model="payload.type"
157+
label="Type"
158+
:options="types"
159+
label-key="label"
160+
value-key="value"
161+
card:color="b-primary"
162+
/>
163+
</div>
164+
165+
<div class="mb-4">
166+
<is-input v-model="payload.field" label="Field" />
167+
</div>
168+
169+
<div v-if="payload.type === 'select'" class="mb-4">
170+
<is-input
171+
v-model="payload.options"
172+
label="Options (separate by comma)"
173+
placeholder="item-01,item-02"
174+
/>
175+
</div>
176+
177+
<template v-if="payload.type === 'relation'">
178+
<div class="mb-4">
179+
<is-select
180+
v-model="payload.collectionId"
181+
label="Collection"
182+
:options="collectionStore.collections"
183+
label-key="name"
184+
value-key="id"
185+
card:color="b-primary"
186+
/>
187+
</div>
188+
189+
<div v-if="payload.collectionId" class="mb-4">
190+
<is-select
191+
v-model="payload.displayField"
192+
label="Collection display field"
193+
:options="relation ? relation.columns : []"
194+
label-key="label"
195+
value-key="field"
196+
card:color="b-primary"
197+
/>
198+
</div>
199+
</template>
200+
201+
<is-drawer v-if="payload.type === 'script'" width="800">
202+
<template #activator="{ attrs }">
203+
<is-input
204+
v-bind="attrs"
205+
:model-value="$t('editEntity', [$t('script')])"
206+
:label="$t('content')"
207+
readonly
208+
class="cursor-pointer mb-4"
209+
input:class="cursor-pointer max-w-[calc(100%_-_32px)]"
210+
>
211+
<template #append>
212+
<is-icon name="code" class="ml-auto" />
213+
</template>
214+
</is-input>
215+
</template>
216+
217+
<v-card color="b-secondary" class="h-full">
218+
<m-editor
219+
v-model="payload.content"
220+
:libs="libScriptColumn.mount(store.all(collectionId))"
221+
/>
222+
</v-card>
223+
</is-drawer>
224+
225+
<div v-if="payload.type === 'entry'" class="mb-4">
226+
<is-input
227+
v-model="payload.filename"
228+
:label="$t('filename')"
229+
placeholder="thumbnail.jpg"
230+
/>
231+
</div>
232+
233+
<div>
234+
<v-btn type="submit" class="w-full">{{ $t('save') }}</v-btn>
235+
</div>
236+
</w-form>
237+
</v-card-content>
238+
</v-card>
239+
</v-dialog>
240+
</template>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { useNonReactive } from '@/composables/utils'
2+
import pick from 'lodash/pick'
3+
4+
import { ViewColumn } from '@core/entities/view-common'
5+
import Column from '@core/entities/column'
6+
7+
export function withView<T = ViewColumn>(columns: Column[], viewColumns: ViewColumn[] = []) {
8+
const result: any[] = useNonReactive(columns)
9+
10+
result.forEach((c) => {
11+
const vColumn = viewColumns.find((vc) => vc.id === c.id)
12+
13+
if (vColumn) {
14+
Object.assign(c, useNonReactive(vColumn))
15+
}
16+
})
17+
18+
result.sort((a, b) => {
19+
const aIndex = viewColumns.findIndex((s) => s.id === a.id)
20+
const bIndex = viewColumns.findIndex((s) => s.id === b.id)
21+
22+
if (aIndex === -1 || bIndex === -1) return 0
23+
24+
return aIndex - bIndex
25+
})
26+
27+
return result as (Column & T)[]
28+
}
29+
30+
export function withoutOnlyView<T = ViewColumn>(columns: (Column & T)[]): T[] {
31+
if (!columns[0]) return []
32+
33+
const cKeys = Object.keys(new Column({}))
34+
const keys = Object.keys(columns[0]).filter((k) => k === 'id' || !cKeys.includes(k))
35+
36+
return useNonReactive(columns).map((c) => pick(c, keys)) as T[]
37+
}

0 commit comments

Comments
 (0)