Support link-modules and add docs link (#368)

* Allow link type modules

* Add docs module

* Allow buttons to render as <a>

* Update button readme

* Use link buttons in module sidebar when needed
This commit is contained in:
Rijk van Zanten
2020-04-09 10:23:07 -04:00
committed by GitHub
parent f2034f7ade
commit 7a2ee0215f
9 changed files with 55 additions and 16 deletions

View File

@@ -60,7 +60,8 @@ The loading slot is rendered _on top_ of the content that was there before. Make
| `small` | Render small | `false` |
| `large` | Render large | `false` |
| `x-large` | Render extra large | `false` |
| `to` | Render as vue router-link | `false` |
| `to` | Render as vue router-link | `null` |
| `href` | Render as anchor | `null` |
| `align` | Align content in button. One of `left | center | right` | `'center'` |
| `dashed` | Render the border dashed. Meant to be used with `outlined`. | `false` |
| `tile` | Render without border radius | `false` |

View File

@@ -23,6 +23,9 @@
:type="type"
:disabled="disabled"
:to="to"
:href="href"
:target="component === 'a' ? '_blank' : null"
:ref="component === 'a' ? 'noopener noreferer' : null"
@click="onClick"
>
<span class="content" :class="{ invisible: loading }">
@@ -43,6 +46,7 @@ import { defineComponent, computed, PropType } from '@vue/composition-api';
import { Location } from 'vue-router';
import useSizeClass, { sizeProps } from '@/compositions/size-class';
import { useGroupable } from '@/compositions/groupable';
import { notEmpty } from '@/utils/is-empty';
export default defineComponent({
props: {
@@ -78,6 +82,10 @@ export default defineComponent({
type: [String, Object] as PropType<string | Location>,
default: null,
},
href: {
type: String,
default: null,
},
exact: {
type: Boolean,
default: false,
@@ -108,7 +116,11 @@ export default defineComponent({
setup(props, { emit }) {
const sizeClass = useSizeClass(props);
const component = computed<string>(() => (props.to ? 'router-link' : 'button'));
const component = computed<'a' | 'router-link' | 'button'>(() => {
if (notEmpty(props.href)) return 'a';
if (notEmpty(props.to)) return 'router-link';
return 'button';
});
const { active, toggle } = useGroupable(props.value, 'button-group');
return { sizeClass, onClick, component, active, toggle };

View File

@@ -124,6 +124,7 @@
"webhooks": "Webhooks",
"roles": "User Roles",
"help_and_docs": "Help & Docs",
"about_directus": "About Directus",
@@ -390,7 +391,6 @@
"forgot_password": "Forgot Password",
"greater_than": "Greater than",
"greater_than_equal": "Greater than or equal to",
"help_and_docs": "Help & Docs",
"hidden": "Hidden",
"hidden_browse": "Hidden on Browse",
"hidden_detail": "Hidden on Detail",

View File

@@ -13,17 +13,19 @@ export function defineModule(
options = config;
}
options.routes = options.routes.map((route) => {
if (route.path) {
route.path = `/:project/${options.id}${route.path}`;
}
if (options.routes !== undefined) {
options.routes = options.routes.map((route) => {
if (route.path) {
route.path = `/:project/${options.id}${route.path}`;
}
if (route.redirect) {
route.redirect = `/:project/${options.id}${route.redirect}`;
}
if (route.redirect) {
route.redirect = `/:project/${options.id}${route.redirect}`;
}
return route;
});
return route;
});
}
return options;
}

View File

@@ -0,0 +1,8 @@
import { defineModule } from '@/modules/define';
export default defineModule(({ i18n }) => ({
id: 'docs',
name: i18n.t('help_and_docs'),
icon: 'help',
link: 'https://docs.directus.io',
}));

View File

@@ -2,6 +2,7 @@ import CollectionsModule from './collections/';
import FilesModule from './files/';
import UsersModule from './users/';
import ActivityModule from './activity/';
import DocsModule from './docs/';
import SettingsModule from './settings/';
export const modules = [
@@ -9,6 +10,8 @@ export const modules = [
CollectionsModule,
UsersModule,
FilesModule,
DocsModule,
SettingsModule,
];
export default modules;

View File

@@ -2,7 +2,10 @@ import { RouteConfig } from 'vue-router';
import { replaceRoutes } from '@/router';
import modules from './index';
const moduleRoutes: RouteConfig[] = modules.map((module) => module.routes).flat();
const moduleRoutes: RouteConfig[] = modules
.map((module) => module.routes)
.filter((r) => r)
.flat();
replaceRoutes((routes) => insertBeforeProjectWildcard(routes, moduleRoutes));

View File

@@ -7,7 +7,8 @@ export type ModuleConfig = {
hidden?: boolean | Ref<boolean>;
icon: string;
name: string | VueI18n.TranslateResult;
routes: RouteConfig[];
routes?: RouteConfig[];
link?: string;
};
export type ModuleContext = { i18n: VueI18n };

View File

@@ -2,7 +2,15 @@
<div class="module-bar">
<module-bar-logo />
<div class="modules">
<v-button v-for="module in _modules" :key="module.id" icon x-large :to="module.to" tile>
<v-button
v-for="module in _modules"
:key="module.id"
icon
x-large
:to="module.to"
:href="module.href"
tile
>
<v-icon :name="module.icon" />
</v-button>
</div>
@@ -29,7 +37,8 @@ export default defineComponent({
const _modules = modules
.map((module) => ({
...module,
to: `/${currentProjectKey}/${module.id}/`,
href: module.link || null,
to: module.link === undefined ? `/${currentProjectKey}/${module.id}/` : null,
}))
.filter((module) => {
if (module.hidden !== undefined) {