Add view type switch (#424)

* Manage view_type through collection preset composition

* Move view type translation

* Add layout drawer detail component

* Use different icon for tabular

* Render view as section in browse sidebar

* Fix sticky header in table

* Sort return statement values 🤓

* Use viewtype picker on users

* Use layout picker on files

* Default to tabular view when invalid is set

* Render view type dynamically based on setting
This commit is contained in:
Rijk van Zanten
2020-04-16 16:53:45 -04:00
committed by GitHub
parent ce9c374876
commit 28a4ad5ec6
10 changed files with 107 additions and 26 deletions

View File

@@ -289,7 +289,7 @@ export default defineComponent({
padding-right: 0;
}
.fixed th {
.fixed {
position: sticky;
top: var(--v-table-sticky-offset-top);
z-index: 2;

View File

@@ -341,6 +341,10 @@ export default defineComponent({
}
::v-deep {
thead {
display: contents;
}
tr {
display: grid;
grid-template-columns: var(--grid-columns);

View File

@@ -50,6 +50,19 @@ export function useCollectionPreset(collection: Ref<string>) {
},
});
const viewType = computed({
get() {
return localPreset.value.view_type || 'tabular';
},
set(val) {
localPreset.value = {
...localPreset.value,
view_type: val,
};
savePreset(localPreset.value);
},
});
const filters = computed<Filter[]>({
get() {
return localPreset.value.filters || [];
@@ -63,5 +76,5 @@ export function useCollectionPreset(collection: Ref<string>) {
},
});
return { viewOptions, viewQuery, filters };
return { viewType, viewOptions, viewQuery, filters };
}

View File

@@ -222,6 +222,7 @@
"upload_file_indeterminate": "Uploading File | Uploading files {done}/{total}",
"upload_file_success": "File Uploaded | {count} Files Uploaded",
"upload_file_failed": "Couldn't Upload File | Couldn't Upload Files",
"view_type": "View As...",
"about_directus": "About Directus",
"activity_log": "Activity Log",
@@ -677,7 +678,6 @@
"values": "Values",
"version": "Version",
"version_and_updates": "Version and Updates",
"view_type": "View As...",
"visible_all_users": "Visible for all users",
"webhook_count": "No Webhooks | 1 Webhook | {count} Webhooks",
"weeks": {

View File

@@ -4,6 +4,6 @@ import TabularLayout from './tabular.vue';
export default defineLayout(({ i18n }) => ({
id: 'tabular',
name: i18n.t('layouts.tabular.tabular'),
icon: 'table',
icon: 'reorder',
component: TabularLayout,
}));

View File

@@ -8,6 +8,7 @@
</template>
<template #drawer>
<layout-drawer-detail v-model="viewType" />
<filter-drawer-detail v-model="filters" :collection="collection" />
<portal-target name="drawer" />
</template>
@@ -53,9 +54,10 @@
<collections-navigation />
</template>
<layout-tabular
<component
class="layout"
ref="layout"
:is="`layout-${viewType}`"
:collection="collection"
:selection.sync="selection"
:view-options.sync="viewOptions"
@@ -78,6 +80,7 @@ import CollectionsNotFound from '../not-found/';
import useCollection from '@/compositions/use-collection';
import useCollectionPreset from '@/compositions/use-collection-preset';
import FilterDrawerDetail from '@/views/private/components/filter-drawer-detail';
import LayoutDrawerDetail from '@/views/private/components/layout-drawer-detail';
const redirectIfNeeded: NavigationGuard = async (to, from, next) => {
const collectionsStore = useCollectionsStore();
@@ -115,7 +118,12 @@ export default defineComponent({
beforeRouteEnter: redirectIfNeeded,
beforeRouteUpdate: redirectIfNeeded,
name: 'collections-browse',
components: { CollectionsNavigation, CollectionsNotFound, FilterDrawerDetail },
components: {
CollectionsNavigation,
CollectionsNotFound,
FilterDrawerDetail,
LayoutDrawerDetail,
},
props: {
collection: {
type: String,
@@ -132,22 +140,23 @@ export default defineComponent({
const { selection } = useSelection();
const { info: currentCollection, primaryKeyField } = useCollection(collection);
const { addNewLink, batchLink, collectionsLink } = useLinks();
const { viewOptions, viewQuery, filters } = useCollectionPreset(collection);
const { viewType, viewOptions, viewQuery, filters } = useCollectionPreset(collection);
const { confirmDelete, deleting, batchDelete } = useBatchDelete();
return {
currentCollection,
addNewLink,
batchLink,
selection,
confirmDelete,
batchDelete,
batchLink,
collectionsLink,
confirmDelete,
currentCollection,
deleting,
filters,
layout,
selection,
viewOptions,
viewQuery,
collectionsLink,
filters,
viewType,
};
function useSelection() {

View File

@@ -7,6 +7,7 @@
</template>
<template #drawer>
<layout-drawer-detail v-model="viewType" />
<filter-drawer-detail v-model="filters" collection="directus_files" />
<portal-target name="drawer" />
</template>
@@ -52,9 +53,10 @@
<files-navigation />
</template>
<layout-tabular
<component
class="layout"
ref="layout"
:is="`layout-${viewType}`"
collection="directus_files"
:selection.sync="selection"
:view-options.sync="viewOptions"
@@ -74,6 +76,7 @@ import api from '@/api';
import { LayoutComponent } from '@/layouts/types';
import useCollectionPreset from '@/compositions/use-collection-preset';
import FilterDrawerDetail from '@/views/private/components/filter-drawer-detail';
import LayoutDrawerDetail from '@/views/private/components/layout-drawer-detail';
type Item = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -82,7 +85,7 @@ type Item = {
export default defineComponent({
name: 'files-browse',
components: { FilesNavigation, FilterDrawerDetail },
components: { FilesNavigation, FilterDrawerDetail, LayoutDrawerDetail },
props: {},
setup() {
const layout = ref<LayoutComponent>(null);
@@ -90,23 +93,26 @@ export default defineComponent({
const selection = ref<Item[]>([]);
const { viewOptions, viewQuery, filters } = useCollectionPreset(ref('directus_files'));
const { viewType, viewOptions, viewQuery, filters } = useCollectionPreset(
ref('directus_files')
);
const { addNewLink, batchLink } = useLinks();
const { confirmDelete, deleting, batchDelete } = useBatchDelete();
const { breadcrumb } = useBreadcrumb();
return {
addNewLink,
batchDelete,
batchLink,
selection,
breadcrumb,
confirmDelete,
batchDelete,
deleting,
filters,
layout,
selection,
viewOptions,
viewQuery,
filters,
viewType,
};
function useBatchDelete() {

View File

@@ -7,6 +7,7 @@
</template>
<template #drawer>
<layout-drawer-detail v-model="viewType" />
<filter-drawer-detail v-model="filters" collection="directus_users" />
<portal-target name="drawer" />
</template>
@@ -52,9 +53,10 @@
<users-navigation />
</template>
<layout-tabular
<component
class="layout"
ref="layout"
:is="`layout-${viewType}`"
collection="directus_users"
:selection.sync="selection"
:view-options.sync="viewOptions"
@@ -75,6 +77,7 @@ import api from '@/api';
import { LayoutComponent } from '@/layouts/types';
import useCollectionPreset from '@/compositions/use-collection-preset';
import FilterDrawerDetail from '@/views/private/components/filter-drawer-detail';
import LayoutDrawerDetail from '@/views/private/components/layout-drawer-detail';
type Item = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -83,7 +86,7 @@ type Item = {
export default defineComponent({
name: 'users-browse',
components: { UsersNavigation, FilterDrawerDetail },
components: { UsersNavigation, FilterDrawerDetail, LayoutDrawerDetail },
props: {
role: {
type: String,
@@ -96,7 +99,9 @@ export default defineComponent({
const selection = ref<Item[]>([]);
const { viewOptions, viewQuery, filters } = useCollectionPreset(ref('directus_users'));
const { viewType, viewOptions, viewQuery, filters } = useCollectionPreset(
ref('directus_users')
);
const { addNewLink, batchLink } = useLinks();
const { confirmDelete, deleting, batchDelete } = useBatchDelete();
const { breadcrumb } = useBreadcrumb();
@@ -129,18 +134,19 @@ export default defineComponent({
});
return {
_filters,
addNewLink,
batchDelete,
batchLink,
selection,
breadcrumb,
confirmDelete,
batchDelete,
deleting,
filters,
layout,
selection,
viewOptions,
viewQuery,
_filters,
filters,
viewType,
};
function useBatchDelete() {

View File

@@ -0,0 +1,4 @@
import LayoutDrawerDetail from './layout-drawer-detail.vue';
export { LayoutDrawerDetail };
export default LayoutDrawerDetail;

View File

@@ -0,0 +1,39 @@
<template>
<drawer-detail :icon="currentLayout.icon" :title="$t('view_type')">
<v-select :items="layouts" item-text="name" item-value="id" v-model="viewType" full-width />
</drawer-detail>
</template>
<script lang="ts">
import { defineComponent, computed } from '@vue/composition-api';
import layouts from '@/layouts';
export default defineComponent({
props: {
value: {
type: String,
required: true,
},
},
setup(props, { emit }) {
let currentLayout = layouts.find((layout) => layout.id === props.value);
// If for whatever reason the current layout doesn't exist, force reset it to tabular
if (currentLayout === undefined) {
currentLayout = layouts.find((layout) => layout.id === 'tabular');
emit('input', 'tabular');
}
const viewType = computed({
get() {
return props.value;
},
set(newType: string) {
emit('input', newType);
},
});
return { currentLayout, layouts, viewType };
},
});
</script>