mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
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:
@@ -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
|
||||
|
||||
4
src/modules/activity/components/navigation/index.ts
Normal file
4
src/modules/activity/components/navigation/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import ActivityNavigation from './navigation.vue';
|
||||
|
||||
export { ActivityNavigation };
|
||||
export default ActivityNavigation;
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>activity nav</div>
|
||||
</template>
|
||||
24
src/modules/activity/index.ts
Normal file
24
src/modules/activity/index.ts
Normal 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,
|
||||
},
|
||||
],
|
||||
}));
|
||||
89
src/modules/activity/routes/browse/browse.vue
Normal file
89
src/modules/activity/routes/browse/browse.vue
Normal 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>
|
||||
4
src/modules/activity/routes/browse/index.ts
Normal file
4
src/modules/activity/routes/browse/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import ActivityBrowse from './browse.vue';
|
||||
|
||||
export { ActivityBrowse };
|
||||
export default ActivityBrowse;
|
||||
81
src/modules/activity/routes/detail/detail.vue
Normal file
81
src/modules/activity/routes/detail/detail.vue
Normal 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>
|
||||
4
src/modules/activity/routes/detail/index.ts
Normal file
4
src/modules/activity/routes/detail/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import ActivityDetail from './detail.vue';
|
||||
|
||||
export { ActivityDetail };
|
||||
export default ActivityDetail;
|
||||
@@ -96,7 +96,7 @@ type Values = {
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: 'collections-detail',
|
||||
name: 'files-detail',
|
||||
components: { FilesNavigation, ActivityDrawerDetail, SaveOptions },
|
||||
props: {
|
||||
primaryKey: {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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[];
|
||||
|
||||
@@ -96,7 +96,7 @@ type Values = {
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: 'collections-detail',
|
||||
name: 'users-detail',
|
||||
components: { UsersNavigation, ActivityDrawerDetail, SaveOptions },
|
||||
props: {
|
||||
primaryKey: {
|
||||
|
||||
@@ -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 };
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user