Allow hidden modules and add activity module (#362)

* Fix wrong component names

* Hide selection in table when there is no selection prop

* Add activity module

* Support hidden option in module definition
This commit is contained in:
Rijk van Zanten
2020-04-08 14:05:44 -04:00
committed by GitHub
parent 442ad58ff6
commit 6979fadb6c
13 changed files with 242 additions and 12 deletions

View File

@@ -59,7 +59,7 @@
v-if="loading || itemCount > 0"
ref="table"
fixed-header
show-select
:show-select="selection !== undefined"
show-resize
must-sort
:sort="tableSort"
@@ -124,7 +124,7 @@ export default defineComponent({
},
selection: {
type: Array as PropType<Item[]>,
default: () => [],
default: undefined,
},
viewOptions: {
type: Object as PropType<ViewOptions>,
@@ -355,11 +355,11 @@ export default defineComponent({
};
function onRowClick(item: Item) {
if (props.selectMode || _selection.value.length > 0) {
if (props.selectMode || _selection.value?.length > 0) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(table.value as any).onItemSelected({
item,
value: _selection.value.includes(item) === false,
value: _selection.value?.includes(item) === false,
});
} else {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion

View File

@@ -0,0 +1,4 @@
import ActivityNavigation from './navigation.vue';
export { ActivityNavigation };
export default ActivityNavigation;

View File

@@ -0,0 +1,3 @@
<template>
<div>activity nav</div>
</template>

View File

@@ -0,0 +1,24 @@
import { defineModule } from '@/modules/define';
import ActivityBrowse from './routes/browse/';
import ActivityDetail from './routes/detail/';
export default defineModule(({ i18n }) => ({
id: 'activity',
hidden: true,
name: i18n.t('activity'),
icon: 'notifications',
routes: [
{
name: 'activity-browse',
path: '/',
component: ActivityBrowse,
props: true,
},
{
name: 'activity-detail',
path: '/:primaryKey',
component: ActivityDetail,
props: true,
},
],
}));

View File

@@ -0,0 +1,89 @@
<template>
<private-view :title="$t('activity')">
<template #title-outer:prepend>
<v-button rounded disabled icon secondary>
<v-icon name="notifications" />
</v-button>
</template>
<template #drawer><portal-target name="drawer" /></template>
<template #navigation>
<activity-navigation />
</template>
<layout-tabular
class="layout"
ref="layout"
collection="directus_activity"
:view-options.sync="viewOptions"
:view-query.sync="viewQuery"
:detail-route="'/{{project}}/activity/{{primaryKey}}'"
/>
</private-view>
</template>
<script lang="ts">
import { defineComponent, computed, ref } from '@vue/composition-api';
import ActivityNavigation from '../../components/navigation/';
import useProjectsStore from '@/stores/projects';
import { i18n } from '@/lang';
import { LayoutComponent } from '@/layouts/types';
import useCollectionPreset from '@/compositions/use-collection-preset';
type Item = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[field: string]: any;
};
export default defineComponent({
name: 'activity-browse',
components: { ActivityNavigation },
props: {},
setup() {
const layout = ref<LayoutComponent>(null);
const projectsStore = useProjectsStore();
const { viewOptions, viewQuery } = useCollectionPreset(ref('directus_activity'));
const { breadcrumb } = useBreadcrumb();
return {
breadcrumb,
layout,
viewOptions,
viewQuery,
};
function useBreadcrumb() {
const breadcrumb = computed(() => {
const currentProjectKey = projectsStore.state.currentProjectKey;
return [
{
name: i18n.tc('collection', 2),
to: `/${currentProjectKey}/collections`,
},
];
});
return { breadcrumb };
}
},
});
</script>
<style lang="scss" scoped>
.action-delete {
--v-button-background-color: var(--danger);
--v-button-background-color-hover: var(--danger-dark);
}
.action-batch {
--v-button-background-color: var(--warning);
--v-button-background-color-hover: var(--warning-150);
}
.layout {
--layout-offset-top: 64px;
}
</style>

View File

@@ -0,0 +1,4 @@
import ActivityBrowse from './browse.vue';
export { ActivityBrowse };
export default ActivityBrowse;

View File

@@ -0,0 +1,81 @@
<template>
<private-view :title="$t('editing', { collection: $t('activity') })">
<template #title-outer:prepend>
<v-button rounded icon secondary exact :to="breadcrumb[0].to">
<v-icon name="arrow_back" />
</v-button>
</template>
<template #headline>
<v-breadcrumb :items="breadcrumb" />
</template>
<template #navigation>
<activity-navigation />
</template>
<v-form collection="directus_activity" :loading="loading" :initial-values="item" />
</private-view>
</template>
<script lang="ts">
import { defineComponent, computed, toRefs, ref } from '@vue/composition-api';
import useProjectsStore from '@/stores/projects';
import ActivityNavigation from '../../components/navigation/';
import { i18n } from '@/lang';
import useItem from '@/compositions/use-item';
import SaveOptions from '@/views/private/components/save-options';
type Values = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[field: string]: any;
};
export default defineComponent({
name: 'activity-detail',
components: { ActivityNavigation, SaveOptions },
props: {
primaryKey: {
type: String,
required: true,
},
},
setup(props) {
const projectsStore = useProjectsStore();
const { currentProjectKey } = toRefs(projectsStore.state);
const { primaryKey } = toRefs(props);
const { breadcrumb } = useBreadcrumb();
const { item, loading, error } = useItem(ref('directus_activity'), primaryKey);
return {
item,
loading,
error,
breadcrumb,
};
function useBreadcrumb() {
const breadcrumb = computed(() => [
{
name: i18n.t('activity'),
to: `/${currentProjectKey.value}/activity/`,
},
]);
return { breadcrumb };
}
},
});
</script>
<style lang="scss" scoped>
.action-delete {
--v-button-background-color: var(--danger);
--v-button-background-color-hover: var(--danger-dark);
}
.v-form {
padding: var(--content-padding);
}
</style>

View File

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

View File

@@ -96,7 +96,7 @@ type Values = {
};
export default defineComponent({
name: 'collections-detail',
name: 'files-detail',
components: { FilesNavigation, ActivityDrawerDetail, SaveOptions },
props: {
primaryKey: {

View File

@@ -1,7 +1,14 @@
import CollectionsModule from './collections/';
import FilesModule from './files/';
import UsersModule from './users/';
import ActivityModule from './activity/';
import SettingsModule from './settings/';
export const modules = [CollectionsModule, UsersModule, FilesModule, SettingsModule];
export const modules = [
ActivityModule,
CollectionsModule,
UsersModule,
FilesModule,
SettingsModule,
];
export default modules;

View File

@@ -1,8 +1,10 @@
import VueI18n from 'vue-i18n';
import { RouteConfig } from 'vue-router';
import { Ref } from '@vue/composition-api';
export type ModuleConfig = {
id: string;
hidden?: boolean | Ref<boolean>;
icon: string;
name: string | VueI18n.TranslateResult;
routes: RouteConfig[];

View File

@@ -96,7 +96,7 @@ type Values = {
};
export default defineComponent({
name: 'collections-detail',
name: 'users-detail',
components: { UsersNavigation, ActivityDrawerDetail, SaveOptions },
props: {
primaryKey: {

View File

@@ -11,7 +11,7 @@
</template>
<script lang="ts">
import { defineComponent } from '@vue/composition-api';
import { defineComponent, Ref } from '@vue/composition-api';
import { useProjectsStore } from '@/stores/projects';
import { modules } from '@/modules/';
import ModuleBarLogo from '../module-bar-logo/';
@@ -26,10 +26,22 @@ export default defineComponent({
const projectsStore = useProjectsStore();
const { currentProjectKey } = projectsStore.state;
const _modules = modules.map((module) => ({
...module,
to: `/${currentProjectKey}/${module.id}/`,
}));
const _modules = modules
.map((module) => ({
...module,
to: `/${currentProjectKey}/${module.id}/`,
}))
.filter((module) => {
if (module.hidden !== undefined) {
if (
(module.hidden as boolean) === true ||
(module.hidden as Ref<boolean>).value === true
) {
return false;
}
}
return true;
});
return { _modules };
},