mirror of
https://github.com/directus/directus.git
synced 2026-01-26 09:58:03 -05:00
script[setup]: modules/content (#18442)
This commit is contained in:
@@ -5,27 +5,17 @@
|
||||
<v-list-item-content><v-text-overflow :text="name" :highlight="search" /></v-list-item-content>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
icon: {
|
||||
type: String,
|
||||
default: 'label',
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: 'var(--foreground-normal)',
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
search: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
});
|
||||
<script setup lang="ts">
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
name: string;
|
||||
search?: string;
|
||||
icon?: string;
|
||||
color?: string;
|
||||
}>(),
|
||||
{
|
||||
icon: 'label',
|
||||
color: 'var(--foreground-normal)',
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
@@ -57,8 +57,8 @@
|
||||
</v-menu>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType, computed } from 'vue';
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { Collection } from '@/types/collections';
|
||||
import { Preset } from '@directus/types';
|
||||
import { useUserStore } from '@/stores/user';
|
||||
@@ -69,95 +69,70 @@ import NavigationBookmark from './navigation-bookmark.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { orderBy } from 'lodash';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'NavigationItem',
|
||||
components: { NavigationItemContent, NavigationBookmark },
|
||||
props: {
|
||||
collection: {
|
||||
type: Object as PropType<Collection>,
|
||||
required: true,
|
||||
},
|
||||
showHidden: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
search: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const { t } = useI18n();
|
||||
const props = defineProps<{
|
||||
collection: Collection;
|
||||
showHidden?: boolean;
|
||||
search?: string;
|
||||
}>();
|
||||
|
||||
const { isAdmin } = useUserStore();
|
||||
const collectionsStore = useCollectionsStore();
|
||||
const presetsStore = usePresetsStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
const childCollections = computed(() => getChildCollections(props.collection));
|
||||
const { isAdmin } = useUserStore();
|
||||
const collectionsStore = useCollectionsStore();
|
||||
const presetsStore = usePresetsStore();
|
||||
|
||||
const childBookmarks = computed(() => getChildBookmarks(props.collection));
|
||||
const childCollections = computed(() => getChildCollections(props.collection));
|
||||
|
||||
const isGroup = computed(() => childCollections.value.length > 0 || childBookmarks.value.length > 0);
|
||||
const childBookmarks = computed(() => getChildBookmarks(props.collection));
|
||||
|
||||
const to = computed(() => (props.collection.schema ? `/content/${props.collection.collection}` : ''));
|
||||
const isGroup = computed(() => childCollections.value.length > 0 || childBookmarks.value.length > 0);
|
||||
|
||||
const matchesSearch = computed(() => {
|
||||
if (!props.search || props.search.length < 3) return true;
|
||||
const to = computed(() => (props.collection.schema ? `/content/${props.collection.collection}` : ''));
|
||||
|
||||
const searchQuery = props.search.toLowerCase();
|
||||
const matchesSearch = computed(() => {
|
||||
if (!props.search || props.search.length < 3) return true;
|
||||
|
||||
return matchesSearch(props.collection) || childrenMatchSearch(childCollections.value, childBookmarks.value);
|
||||
const searchQuery = props.search.toLowerCase();
|
||||
|
||||
function childrenMatchSearch(collections: Collection[], bookmarks: Preset[]): boolean {
|
||||
return (
|
||||
collections.some((collection) => {
|
||||
const childCollections = getChildCollections(collection);
|
||||
const childBookmarks = getChildBookmarks(collection);
|
||||
return matchesSearch(props.collection) || childrenMatchSearch(childCollections.value, childBookmarks.value);
|
||||
|
||||
return matchesSearch(collection) || childrenMatchSearch(childCollections, childBookmarks);
|
||||
}) || bookmarks.some((bookmark) => bookmarkMatchesSearch(bookmark))
|
||||
);
|
||||
}
|
||||
function childrenMatchSearch(collections: Collection[], bookmarks: Preset[]): boolean {
|
||||
return (
|
||||
collections.some((collection) => {
|
||||
const childCollections = getChildCollections(collection);
|
||||
const childBookmarks = getChildBookmarks(collection);
|
||||
|
||||
function matchesSearch(collection: Collection) {
|
||||
return collection.collection.includes(searchQuery) || collection.name.toLowerCase().includes(searchQuery);
|
||||
}
|
||||
return matchesSearch(collection) || childrenMatchSearch(childCollections, childBookmarks);
|
||||
}) || bookmarks.some((bookmark) => bookmarkMatchesSearch(bookmark))
|
||||
);
|
||||
}
|
||||
|
||||
function bookmarkMatchesSearch(bookmark: Preset) {
|
||||
return bookmark.bookmark?.toLowerCase().includes(searchQuery);
|
||||
}
|
||||
});
|
||||
function matchesSearch(collection: Collection) {
|
||||
return collection.collection.includes(searchQuery) || collection.name.toLowerCase().includes(searchQuery);
|
||||
}
|
||||
|
||||
const hasContextMenu = computed(() => isAdmin && props.collection.type === 'table');
|
||||
|
||||
return {
|
||||
childCollections,
|
||||
childBookmarks,
|
||||
isGroup,
|
||||
to,
|
||||
matchesSearch,
|
||||
isAdmin,
|
||||
t,
|
||||
hasContextMenu,
|
||||
};
|
||||
|
||||
function getChildCollections(collection: Collection) {
|
||||
let collections = collectionsStore.collections.filter(
|
||||
(childCollection) => childCollection.meta?.group === collection.collection
|
||||
);
|
||||
|
||||
if (props.showHidden === false) {
|
||||
collections = collections.filter((collection) => collection.meta?.hidden !== true);
|
||||
}
|
||||
|
||||
return orderBy(collections, ['meta.sort', 'collection']);
|
||||
}
|
||||
|
||||
function getChildBookmarks(collection: Collection) {
|
||||
return presetsStore.bookmarks.filter((bookmark) => bookmark.collection === collection.collection);
|
||||
}
|
||||
},
|
||||
function bookmarkMatchesSearch(bookmark: Preset) {
|
||||
return bookmark.bookmark?.toLowerCase().includes(searchQuery);
|
||||
}
|
||||
});
|
||||
|
||||
const hasContextMenu = computed(() => isAdmin && props.collection.type === 'table');
|
||||
|
||||
function getChildCollections(collection: Collection) {
|
||||
let collections = collectionsStore.collections.filter(
|
||||
(childCollection) => childCollection.meta?.group === collection.collection
|
||||
);
|
||||
|
||||
if (props.showHidden === false) {
|
||||
collections = collections.filter((collection) => collection.meta?.hidden !== true);
|
||||
}
|
||||
|
||||
return orderBy(collections, ['meta.sort', 'collection']);
|
||||
}
|
||||
|
||||
function getChildBookmarks(collection: Collection) {
|
||||
return presetsStore.bookmarks.filter((bookmark) => bookmark.collection === collection.collection);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -36,60 +36,42 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { defineComponent, computed, ref, toRefs } from 'vue';
|
||||
import { useNavigation } from '../composables/use-navigation';
|
||||
<script setup lang="ts">
|
||||
import { useCollectionsStore } from '@/stores/collections';
|
||||
import { orderBy, isNil } from 'lodash';
|
||||
import { isNil, orderBy } from 'lodash';
|
||||
import { computed, ref, toRefs } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useNavigation } from '../composables/use-navigation';
|
||||
import NavigationItem from './navigation-item.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: { NavigationItem },
|
||||
props: {
|
||||
currentCollection: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const { t } = useI18n();
|
||||
const { currentCollection } = toRefs(props);
|
||||
const { activeGroups, showHidden } = useNavigation(currentCollection);
|
||||
const props = defineProps<{
|
||||
currentCollection?: string;
|
||||
}>();
|
||||
|
||||
const search = ref('');
|
||||
const { t } = useI18n();
|
||||
const { currentCollection } = toRefs(props);
|
||||
const { activeGroups, showHidden } = useNavigation(currentCollection);
|
||||
|
||||
const collectionsStore = useCollectionsStore();
|
||||
const search = ref('');
|
||||
|
||||
const rootItems = computed(() => {
|
||||
const shownCollections = showHidden.value ? collectionsStore.allCollections : collectionsStore.visibleCollections;
|
||||
return orderBy(
|
||||
shownCollections.filter((collection) => {
|
||||
return isNil(collection?.meta?.group);
|
||||
}),
|
||||
['meta.sort', 'collection']
|
||||
);
|
||||
});
|
||||
const collectionsStore = useCollectionsStore();
|
||||
|
||||
const dense = computed(() => collectionsStore.visibleCollections.length > 5);
|
||||
const showSearch = computed(() => collectionsStore.visibleCollections.length > 20);
|
||||
|
||||
const hasHiddenCollections = computed(
|
||||
() => collectionsStore.allCollections.length > collectionsStore.visibleCollections.length
|
||||
);
|
||||
|
||||
return {
|
||||
t,
|
||||
activeGroups,
|
||||
showHidden,
|
||||
rootItems,
|
||||
dense,
|
||||
search,
|
||||
showSearch,
|
||||
hasHiddenCollections,
|
||||
};
|
||||
},
|
||||
const rootItems = computed(() => {
|
||||
const shownCollections = showHidden.value ? collectionsStore.allCollections : collectionsStore.visibleCollections;
|
||||
return orderBy(
|
||||
shownCollections.filter((collection) => {
|
||||
return isNil(collection?.meta?.group);
|
||||
}),
|
||||
['meta.sort', 'collection']
|
||||
);
|
||||
});
|
||||
|
||||
const dense = computed(() => collectionsStore.visibleCollections.length > 5);
|
||||
const showSearch = computed(() => collectionsStore.visibleCollections.length > 20);
|
||||
|
||||
const hasHiddenCollections = computed(
|
||||
() => collectionsStore.allCollections.length > collectionsStore.visibleCollections.length
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<component
|
||||
:is="isSingleton ? 'item-route' : 'collection-route'"
|
||||
:is="isSingleton ? ItemRoute : CollectionRoute"
|
||||
:collection="collection"
|
||||
:bookmark="bookmark"
|
||||
:archive="archive"
|
||||
@@ -8,56 +8,38 @@
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed, watch } from 'vue';
|
||||
<script setup lang="ts">
|
||||
import { computed, watch } from 'vue';
|
||||
import CollectionRoute from './collection.vue';
|
||||
import ItemRoute from './item.vue';
|
||||
import { useCollectionsStore } from '@/stores/collections';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useLocalStorage } from '@/composables/use-local-storage';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
CollectionRoute,
|
||||
ItemRoute,
|
||||
},
|
||||
props: {
|
||||
collection: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
bookmark: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
archive: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const route = useRoute();
|
||||
const props = defineProps<{
|
||||
collection: string;
|
||||
bookmark?: string;
|
||||
archive?: string;
|
||||
}>();
|
||||
|
||||
const { data } = useLocalStorage('last-accessed-collection');
|
||||
const route = useRoute();
|
||||
|
||||
const collectionsStore = useCollectionsStore();
|
||||
const { data } = useLocalStorage('last-accessed-collection');
|
||||
|
||||
const isSingleton = computed(() => {
|
||||
const collectionInfo = collectionsStore.getCollection(props.collection);
|
||||
return !!collectionInfo?.meta?.singleton === true;
|
||||
});
|
||||
const collectionsStore = useCollectionsStore();
|
||||
|
||||
watch(
|
||||
() => route.params,
|
||||
(newParams) => {
|
||||
if (newParams.collection && data.value !== newParams.collection) {
|
||||
data.value = newParams.collection;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
return { isSingleton };
|
||||
},
|
||||
const isSingleton = computed(() => {
|
||||
const collectionInfo = collectionsStore.getCollection(props.collection);
|
||||
return !!collectionInfo?.meta?.singleton === true;
|
||||
});
|
||||
|
||||
watch(
|
||||
() => route.params,
|
||||
(newParams) => {
|
||||
if (newParams.collection && data.value !== newParams.collection) {
|
||||
data.value = newParams.collection;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
@@ -270,410 +270,337 @@
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { defineComponent, computed, ref, watch, toRefs } from 'vue';
|
||||
import ContentNavigation from '../components/navigation.vue';
|
||||
<script setup lang="ts">
|
||||
import api from '@/api';
|
||||
import ContentNotFound from './not-found.vue';
|
||||
import { useCollection, useLayout } from '@directus/composables';
|
||||
import { useExtension } from '@/composables/use-extension';
|
||||
import { usePreset } from '@/composables/use-preset';
|
||||
import LayoutSidebarDetail from '@/views/private/components/layout-sidebar-detail.vue';
|
||||
import ArchiveSidebarDetail from '@/views/private/components/archive-sidebar-detail.vue';
|
||||
import RefreshSidebarDetail from '@/views/private/components/refresh-sidebar-detail.vue';
|
||||
import ExportSidebarDetail from '@/views/private/components/export-sidebar-detail.vue';
|
||||
import FlowSidebarDetail from '@/views/private/components/flow-sidebar-detail.vue';
|
||||
import SearchInput from '@/views/private/components/search-input.vue';
|
||||
import BookmarkAdd from '@/views/private/components/bookmark-add.vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { usePermissionsStore } from '@/stores/permissions';
|
||||
import { useUserStore } from '@/stores/user';
|
||||
import DrawerBatch from '@/views/private/components/drawer-batch.vue';
|
||||
import { unexpectedError } from '@/utils/unexpected-error';
|
||||
import { mergeFilters } from '@directus/utils';
|
||||
import ArchiveSidebarDetail from '@/views/private/components/archive-sidebar-detail.vue';
|
||||
import BookmarkAdd from '@/views/private/components/bookmark-add.vue';
|
||||
import DrawerBatch from '@/views/private/components/drawer-batch.vue';
|
||||
import ExportSidebarDetail from '@/views/private/components/export-sidebar-detail.vue';
|
||||
import FlowSidebarDetail from '@/views/private/components/flow-sidebar-detail.vue';
|
||||
import LayoutSidebarDetail from '@/views/private/components/layout-sidebar-detail.vue';
|
||||
import RefreshSidebarDetail from '@/views/private/components/refresh-sidebar-detail.vue';
|
||||
import SearchInput from '@/views/private/components/search-input.vue';
|
||||
import { useCollection, useLayout } from '@directus/composables';
|
||||
import { Filter } from '@directus/types';
|
||||
import { useExtension } from '@/composables/use-extension';
|
||||
import { mergeFilters } from '@directus/utils';
|
||||
import { computed, ref, toRefs, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRouter } from 'vue-router';
|
||||
import ContentNavigation from '../components/navigation.vue';
|
||||
import ContentNotFound from './not-found.vue';
|
||||
|
||||
type Item = {
|
||||
[field: string]: any;
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ContentCollection',
|
||||
components: {
|
||||
ContentNavigation,
|
||||
ContentNotFound,
|
||||
LayoutSidebarDetail,
|
||||
SearchInput,
|
||||
BookmarkAdd,
|
||||
DrawerBatch,
|
||||
ArchiveSidebarDetail,
|
||||
RefreshSidebarDetail,
|
||||
ExportSidebarDetail,
|
||||
FlowSidebarDetail,
|
||||
const props = defineProps<{
|
||||
collection: string;
|
||||
bookmark?: string;
|
||||
archive?: string;
|
||||
}>();
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const userStore = useUserStore();
|
||||
const permissionsStore = usePermissionsStore();
|
||||
const layoutRef = ref();
|
||||
|
||||
const { collection } = toRefs(props);
|
||||
const bookmarkID = computed(() => (props.bookmark ? +props.bookmark : null));
|
||||
|
||||
const { selection } = useSelection();
|
||||
const { info: currentCollection } = useCollection(collection);
|
||||
const { addNewLink, currentCollectionLink } = useLinks();
|
||||
const { breadcrumb } = useBreadcrumb();
|
||||
|
||||
const {
|
||||
layout,
|
||||
layoutOptions,
|
||||
layoutQuery,
|
||||
filter,
|
||||
search,
|
||||
savePreset,
|
||||
bookmarkExists,
|
||||
saveCurrentAsBookmark,
|
||||
bookmarkTitle,
|
||||
resetPreset,
|
||||
bookmarkSaved,
|
||||
bookmarkIsMine,
|
||||
refreshInterval,
|
||||
busy: bookmarkSaving,
|
||||
clearLocalSave,
|
||||
} = usePreset(collection, bookmarkID);
|
||||
|
||||
const { layoutWrapper } = useLayout(layout);
|
||||
|
||||
const {
|
||||
confirmDelete,
|
||||
deleting,
|
||||
batchDelete,
|
||||
confirmArchive,
|
||||
archiveItems,
|
||||
archiving,
|
||||
error: deleteError,
|
||||
batchEditActive,
|
||||
} = useBatch();
|
||||
|
||||
const { bookmarkDialogActive, creatingBookmark, createBookmark } = useBookmarks();
|
||||
|
||||
const currentLayout = useExtension('layout', layout);
|
||||
|
||||
watch(
|
||||
collection,
|
||||
() => {
|
||||
if (layout.value === null) {
|
||||
layout.value = 'tabular';
|
||||
}
|
||||
},
|
||||
props: {
|
||||
collection: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
bookmark: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
archive: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const { t } = useI18n();
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
const router = useRouter();
|
||||
const { batchEditAllowed, batchArchiveAllowed, batchDeleteAllowed, createAllowed } = usePermissions();
|
||||
|
||||
const userStore = useUserStore();
|
||||
const permissionsStore = usePermissionsStore();
|
||||
const layoutRef = ref();
|
||||
const hasArchive = computed(
|
||||
() =>
|
||||
currentCollection.value &&
|
||||
currentCollection.value.meta?.archive_field &&
|
||||
currentCollection.value.meta?.archive_app_filter
|
||||
);
|
||||
|
||||
const { collection } = toRefs(props);
|
||||
const bookmarkID = computed(() => (props.bookmark ? +props.bookmark : null));
|
||||
const archiveFilter = computed<Filter | null>(() => {
|
||||
if (!currentCollection.value?.meta) return null;
|
||||
if (!currentCollection.value?.meta?.archive_app_filter) return null;
|
||||
|
||||
const { selection } = useSelection();
|
||||
const { info: currentCollection } = useCollection(collection);
|
||||
const { addNewLink, currentCollectionLink } = useLinks();
|
||||
const { breadcrumb } = useBreadcrumb();
|
||||
const field = currentCollection.value.meta.archive_field;
|
||||
|
||||
const {
|
||||
layout,
|
||||
layoutOptions,
|
||||
layoutQuery,
|
||||
filter,
|
||||
search,
|
||||
savePreset,
|
||||
bookmarkExists,
|
||||
saveCurrentAsBookmark,
|
||||
bookmarkTitle,
|
||||
resetPreset,
|
||||
bookmarkSaved,
|
||||
bookmarkIsMine,
|
||||
refreshInterval,
|
||||
busy: bookmarkSaving,
|
||||
clearLocalSave,
|
||||
} = usePreset(collection, bookmarkID);
|
||||
if (!field) return null;
|
||||
|
||||
const { layoutWrapper } = useLayout(layout);
|
||||
|
||||
const {
|
||||
confirmDelete,
|
||||
deleting,
|
||||
batchDelete,
|
||||
confirmArchive,
|
||||
archiveItems,
|
||||
archiving,
|
||||
error: deleteError,
|
||||
batchEditActive,
|
||||
} = useBatch();
|
||||
|
||||
const { bookmarkDialogActive, creatingBookmark, createBookmark } = useBookmarks();
|
||||
|
||||
const currentLayout = useExtension('layout', layout);
|
||||
|
||||
watch(
|
||||
collection,
|
||||
() => {
|
||||
if (layout.value === null) {
|
||||
layout.value = 'tabular';
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
const { batchEditAllowed, batchArchiveAllowed, batchDeleteAllowed, createAllowed } = usePermissions();
|
||||
|
||||
const hasArchive = computed(
|
||||
() =>
|
||||
currentCollection.value &&
|
||||
currentCollection.value.meta?.archive_field &&
|
||||
currentCollection.value.meta?.archive_app_filter
|
||||
);
|
||||
|
||||
const archiveFilter = computed<Filter | null>(() => {
|
||||
if (!currentCollection.value?.meta) return null;
|
||||
if (!currentCollection.value?.meta?.archive_app_filter) return null;
|
||||
|
||||
const field = currentCollection.value.meta.archive_field;
|
||||
|
||||
if (!field) return null;
|
||||
|
||||
let archiveValue: any = currentCollection.value.meta.archive_value;
|
||||
if (archiveValue === 'true') archiveValue = true;
|
||||
if (archiveValue === 'false') archiveValue = false;
|
||||
|
||||
if (props.archive === 'all') {
|
||||
return null;
|
||||
} else if (props.archive === 'archived') {
|
||||
return {
|
||||
[field]: {
|
||||
_eq: archiveValue,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
[field]: {
|
||||
_neq: archiveValue,
|
||||
},
|
||||
};
|
||||
}
|
||||
});
|
||||
let archiveValue: any = currentCollection.value.meta.archive_value;
|
||||
if (archiveValue === 'true') archiveValue = true;
|
||||
if (archiveValue === 'false') archiveValue = false;
|
||||
|
||||
if (props.archive === 'all') {
|
||||
return null;
|
||||
} else if (props.archive === 'archived') {
|
||||
return {
|
||||
t,
|
||||
addNewLink,
|
||||
batchDelete,
|
||||
batchEditActive,
|
||||
confirmDelete,
|
||||
currentCollection,
|
||||
deleting,
|
||||
filter,
|
||||
layoutRef,
|
||||
layoutWrapper,
|
||||
selection,
|
||||
layoutOptions,
|
||||
layoutQuery,
|
||||
layout,
|
||||
search,
|
||||
savePreset,
|
||||
bookmarkExists,
|
||||
currentCollectionLink,
|
||||
bookmarkDialogActive,
|
||||
creatingBookmark,
|
||||
createBookmark,
|
||||
bookmarkTitle,
|
||||
breadcrumb,
|
||||
clearFilters,
|
||||
confirmArchive,
|
||||
archiveItems,
|
||||
archiving,
|
||||
batchEditAllowed,
|
||||
batchArchiveAllowed,
|
||||
batchDeleteAllowed,
|
||||
deleteError,
|
||||
createAllowed,
|
||||
resetPreset,
|
||||
bookmarkSaved,
|
||||
bookmarkIsMine,
|
||||
bookmarkSaving,
|
||||
clearLocalSave,
|
||||
batchRefresh,
|
||||
refresh,
|
||||
refreshInterval,
|
||||
currentLayout,
|
||||
hasArchive,
|
||||
archiveFilter,
|
||||
mergeFilters,
|
||||
download,
|
||||
[field]: {
|
||||
_eq: archiveValue,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
[field]: {
|
||||
_neq: archiveValue,
|
||||
},
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
async function refresh() {
|
||||
await layoutRef.value?.state?.refresh?.();
|
||||
}
|
||||
async function refresh() {
|
||||
await layoutRef.value?.state?.refresh?.();
|
||||
}
|
||||
|
||||
async function download() {
|
||||
await layoutRef.value?.state?.download?.();
|
||||
}
|
||||
async function download() {
|
||||
await layoutRef.value?.state?.download?.();
|
||||
}
|
||||
|
||||
async function batchRefresh() {
|
||||
selection.value = [];
|
||||
await refresh();
|
||||
}
|
||||
|
||||
function useBreadcrumb() {
|
||||
const breadcrumb = computed(() => [
|
||||
{
|
||||
name: currentCollection.value?.name,
|
||||
to: `/content/${props.collection}`,
|
||||
},
|
||||
]);
|
||||
|
||||
return { breadcrumb };
|
||||
}
|
||||
|
||||
function useSelection() {
|
||||
const selection = ref<Item[]>([]);
|
||||
|
||||
// Whenever the collection we're working on changes, we have to clear the selection
|
||||
watch(
|
||||
() => props.collection,
|
||||
() => (selection.value = [])
|
||||
);
|
||||
|
||||
return { selection };
|
||||
}
|
||||
|
||||
function useBatch() {
|
||||
const confirmDelete = ref(false);
|
||||
const deleting = ref(false);
|
||||
|
||||
const batchEditActive = ref(false);
|
||||
|
||||
const confirmArchive = ref(false);
|
||||
const archiving = ref(false);
|
||||
|
||||
const error = ref<any>(null);
|
||||
|
||||
return { batchEditActive, confirmDelete, deleting, batchDelete, confirmArchive, archiving, archiveItems, error };
|
||||
|
||||
async function batchDelete() {
|
||||
deleting.value = true;
|
||||
|
||||
const batchPrimaryKeys = selection.value;
|
||||
|
||||
try {
|
||||
await api.delete(`/items/${props.collection}`, {
|
||||
data: batchPrimaryKeys,
|
||||
});
|
||||
|
||||
async function batchRefresh() {
|
||||
selection.value = [];
|
||||
await refresh();
|
||||
}
|
||||
|
||||
function useBreadcrumb() {
|
||||
const breadcrumb = computed(() => [
|
||||
{
|
||||
name: currentCollection.value?.name,
|
||||
to: `/content/${props.collection}`,
|
||||
confirmDelete.value = false;
|
||||
} catch (err: any) {
|
||||
error.value = err;
|
||||
} finally {
|
||||
deleting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function archiveItems() {
|
||||
if (!currentCollection.value?.meta?.archive_field) return;
|
||||
|
||||
archiving.value = true;
|
||||
|
||||
let archiveValue: any = currentCollection.value.meta.archive_value;
|
||||
if (archiveValue === 'true') archiveValue = true;
|
||||
if (archiveValue === 'false') archiveValue = false;
|
||||
|
||||
try {
|
||||
await api.patch(`/items/${props.collection}`, {
|
||||
keys: selection.value,
|
||||
data: {
|
||||
[currentCollection.value.meta.archive_field]: archiveValue,
|
||||
},
|
||||
]);
|
||||
|
||||
return { breadcrumb };
|
||||
}
|
||||
|
||||
function useSelection() {
|
||||
const selection = ref<Item[]>([]);
|
||||
|
||||
// Whenever the collection we're working on changes, we have to clear the selection
|
||||
watch(
|
||||
() => props.collection,
|
||||
() => (selection.value = [])
|
||||
);
|
||||
|
||||
return { selection };
|
||||
}
|
||||
|
||||
function useBatch() {
|
||||
const confirmDelete = ref(false);
|
||||
const deleting = ref(false);
|
||||
|
||||
const batchEditActive = ref(false);
|
||||
|
||||
const confirmArchive = ref(false);
|
||||
const archiving = ref(false);
|
||||
|
||||
const error = ref<any>(null);
|
||||
|
||||
return { batchEditActive, confirmDelete, deleting, batchDelete, confirmArchive, archiving, archiveItems, error };
|
||||
|
||||
async function batchDelete() {
|
||||
deleting.value = true;
|
||||
|
||||
const batchPrimaryKeys = selection.value;
|
||||
|
||||
try {
|
||||
await api.delete(`/items/${props.collection}`, {
|
||||
data: batchPrimaryKeys,
|
||||
});
|
||||
|
||||
selection.value = [];
|
||||
await refresh();
|
||||
|
||||
confirmDelete.value = false;
|
||||
} catch (err: any) {
|
||||
error.value = err;
|
||||
} finally {
|
||||
deleting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function archiveItems() {
|
||||
if (!currentCollection.value?.meta?.archive_field) return;
|
||||
|
||||
archiving.value = true;
|
||||
|
||||
let archiveValue: any = currentCollection.value.meta.archive_value;
|
||||
if (archiveValue === 'true') archiveValue = true;
|
||||
if (archiveValue === 'false') archiveValue = false;
|
||||
|
||||
try {
|
||||
await api.patch(`/items/${props.collection}`, {
|
||||
keys: selection.value,
|
||||
data: {
|
||||
[currentCollection.value.meta.archive_field]: archiveValue,
|
||||
},
|
||||
});
|
||||
|
||||
selection.value = [];
|
||||
await refresh();
|
||||
|
||||
confirmArchive.value = false;
|
||||
} catch (err: any) {
|
||||
error.value = err;
|
||||
} finally {
|
||||
archiving.value = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function useLinks() {
|
||||
const addNewLink = computed<string>(() => {
|
||||
return `/content/${props.collection}/+`;
|
||||
});
|
||||
|
||||
const currentCollectionLink = computed<string>(() => {
|
||||
return `/content/${props.collection}`;
|
||||
});
|
||||
selection.value = [];
|
||||
await refresh();
|
||||
|
||||
return { addNewLink, currentCollectionLink };
|
||||
confirmArchive.value = false;
|
||||
} catch (err: any) {
|
||||
error.value = err;
|
||||
} finally {
|
||||
archiving.value = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function useBookmarks() {
|
||||
const bookmarkDialogActive = ref(false);
|
||||
const creatingBookmark = ref(false);
|
||||
function useLinks() {
|
||||
const addNewLink = computed<string>(() => {
|
||||
return `/content/${props.collection}/+`;
|
||||
});
|
||||
|
||||
return {
|
||||
bookmarkDialogActive,
|
||||
creatingBookmark,
|
||||
createBookmark,
|
||||
};
|
||||
const currentCollectionLink = computed<string>(() => {
|
||||
return `/content/${props.collection}`;
|
||||
});
|
||||
|
||||
async function createBookmark(bookmark: any) {
|
||||
creatingBookmark.value = true;
|
||||
return { addNewLink, currentCollectionLink };
|
||||
}
|
||||
|
||||
try {
|
||||
const newBookmark = await saveCurrentAsBookmark({
|
||||
bookmark: bookmark.name,
|
||||
icon: bookmark.icon,
|
||||
color: bookmark.color,
|
||||
});
|
||||
function useBookmarks() {
|
||||
const bookmarkDialogActive = ref(false);
|
||||
const creatingBookmark = ref(false);
|
||||
|
||||
router.push(`/content/${newBookmark.collection}?bookmark=${newBookmark.id}`);
|
||||
return {
|
||||
bookmarkDialogActive,
|
||||
creatingBookmark,
|
||||
createBookmark,
|
||||
};
|
||||
|
||||
bookmarkDialogActive.value = false;
|
||||
} catch (err: any) {
|
||||
unexpectedError(err);
|
||||
} finally {
|
||||
creatingBookmark.value = false;
|
||||
}
|
||||
}
|
||||
async function createBookmark(bookmark: any) {
|
||||
creatingBookmark.value = true;
|
||||
|
||||
try {
|
||||
const newBookmark = await saveCurrentAsBookmark({
|
||||
bookmark: bookmark.name,
|
||||
icon: bookmark.icon,
|
||||
color: bookmark.color,
|
||||
});
|
||||
|
||||
router.push(`/content/${newBookmark.collection}?bookmark=${newBookmark.id}`);
|
||||
|
||||
bookmarkDialogActive.value = false;
|
||||
} catch (err: any) {
|
||||
unexpectedError(err);
|
||||
} finally {
|
||||
creatingBookmark.value = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function clearFilters() {
|
||||
filter.value = null;
|
||||
search.value = null;
|
||||
}
|
||||
function clearFilters() {
|
||||
filter.value = null;
|
||||
search.value = null;
|
||||
}
|
||||
|
||||
function usePermissions() {
|
||||
const batchEditAllowed = computed(() => {
|
||||
const admin = userStore?.currentUser?.role.admin_access === true;
|
||||
if (admin) return true;
|
||||
function usePermissions() {
|
||||
const batchEditAllowed = computed(() => {
|
||||
const admin = userStore?.currentUser?.role.admin_access === true;
|
||||
if (admin) return true;
|
||||
|
||||
const updatePermissions = permissionsStore.permissions.find(
|
||||
(permission) => permission.action === 'update' && permission.collection === collection.value
|
||||
);
|
||||
const updatePermissions = permissionsStore.permissions.find(
|
||||
(permission) => permission.action === 'update' && permission.collection === collection.value
|
||||
);
|
||||
|
||||
return !!updatePermissions;
|
||||
});
|
||||
return !!updatePermissions;
|
||||
});
|
||||
|
||||
const batchArchiveAllowed = computed(() => {
|
||||
if (!currentCollection.value?.meta?.archive_field) return false;
|
||||
const admin = userStore?.currentUser?.role.admin_access === true;
|
||||
if (admin) return true;
|
||||
const batchArchiveAllowed = computed(() => {
|
||||
if (!currentCollection.value?.meta?.archive_field) return false;
|
||||
const admin = userStore?.currentUser?.role.admin_access === true;
|
||||
if (admin) return true;
|
||||
|
||||
const updatePermissions = permissionsStore.permissions.find(
|
||||
(permission) => permission.action === 'update' && permission.collection === collection.value
|
||||
);
|
||||
const updatePermissions = permissionsStore.permissions.find(
|
||||
(permission) => permission.action === 'update' && permission.collection === collection.value
|
||||
);
|
||||
|
||||
if (!updatePermissions) return false;
|
||||
if (!updatePermissions.fields) return false;
|
||||
if (updatePermissions.fields.includes('*')) return true;
|
||||
return updatePermissions.fields.includes(currentCollection.value.meta.archive_field);
|
||||
});
|
||||
if (!updatePermissions) return false;
|
||||
if (!updatePermissions.fields) return false;
|
||||
if (updatePermissions.fields.includes('*')) return true;
|
||||
return updatePermissions.fields.includes(currentCollection.value.meta.archive_field);
|
||||
});
|
||||
|
||||
const batchDeleteAllowed = computed(() => {
|
||||
const admin = userStore?.currentUser?.role.admin_access === true;
|
||||
if (admin) return true;
|
||||
const batchDeleteAllowed = computed(() => {
|
||||
const admin = userStore?.currentUser?.role.admin_access === true;
|
||||
if (admin) return true;
|
||||
|
||||
const deletePermissions = permissionsStore.permissions.find(
|
||||
(permission) => permission.action === 'delete' && permission.collection === collection.value
|
||||
);
|
||||
const deletePermissions = permissionsStore.permissions.find(
|
||||
(permission) => permission.action === 'delete' && permission.collection === collection.value
|
||||
);
|
||||
|
||||
return !!deletePermissions;
|
||||
});
|
||||
return !!deletePermissions;
|
||||
});
|
||||
|
||||
const createAllowed = computed(() => {
|
||||
const admin = userStore?.currentUser?.role.admin_access === true;
|
||||
if (admin) return true;
|
||||
const createAllowed = computed(() => {
|
||||
const admin = userStore?.currentUser?.role.admin_access === true;
|
||||
if (admin) return true;
|
||||
|
||||
const createPermissions = permissionsStore.permissions.find(
|
||||
(permission) => permission.action === 'create' && permission.collection === collection.value
|
||||
);
|
||||
const createPermissions = permissionsStore.permissions.find(
|
||||
(permission) => permission.action === 'create' && permission.collection === collection.value
|
||||
);
|
||||
|
||||
return !!createPermissions;
|
||||
});
|
||||
return !!createPermissions;
|
||||
});
|
||||
|
||||
return { batchEditAllowed, batchArchiveAllowed, batchDeleteAllowed, createAllowed };
|
||||
}
|
||||
},
|
||||
});
|
||||
return { batchEditAllowed, batchArchiveAllowed, batchDeleteAllowed, createAllowed };
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -32,28 +32,17 @@
|
||||
</private-view>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { defineComponent, computed } from 'vue';
|
||||
import ContentNavigation from '../components/navigation.vue';
|
||||
<script setup lang="ts">
|
||||
import { useUserStore } from '@/stores/user';
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import ContentNavigation from '../components/navigation.vue';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ContentOverview',
|
||||
components: {
|
||||
ContentNavigation,
|
||||
},
|
||||
props: {},
|
||||
setup() {
|
||||
const { t } = useI18n();
|
||||
const { t } = useI18n();
|
||||
|
||||
const userStore = useUserStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const isAdmin = computed(() => userStore.currentUser?.role.admin_access === true);
|
||||
|
||||
return { t, isAdmin };
|
||||
},
|
||||
});
|
||||
const isAdmin = computed(() => userStore.currentUser?.role.admin_access === true);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -12,18 +12,11 @@
|
||||
</private-view>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { defineComponent } from 'vue';
|
||||
import ContentNavigation from '../components/navigation.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: { ContentNavigation },
|
||||
setup() {
|
||||
const { t } = useI18n();
|
||||
return { t };
|
||||
},
|
||||
});
|
||||
const { t } = useI18n();
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
Reference in New Issue
Block a user