mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
@@ -18,17 +18,12 @@
|
||||
</v-button>
|
||||
|
||||
<div class="content">
|
||||
<v-overlay v-if="$slots.sidebar" absolute :active="sidebarActive" @click="sidebarActive = false" />
|
||||
<nav
|
||||
v-if="$slots.sidebar"
|
||||
class="sidebar"
|
||||
:class="{ active: sidebarActive }"
|
||||
@click="sidebarActive = false"
|
||||
>
|
||||
<v-overlay v-if="$slots.sidebar" absolute @click="sidebarActive = false" />
|
||||
<nav v-if="$slots.sidebar" class="sidebar">
|
||||
<slot name="sidebar" />
|
||||
</nav>
|
||||
<main ref="mainEl" class="main">
|
||||
<header-bar :title="title">
|
||||
<header-bar :title="title" @primary="$emit('cancel')" primary-action-icon="close">
|
||||
<template #headline>
|
||||
<slot name="subtitle">
|
||||
<p v-if="subtitle" class="subtitle">{{ subtitle }}</p>
|
||||
@@ -47,6 +42,12 @@
|
||||
<template #title:append><slot name="header:append" /></template>
|
||||
</header-bar>
|
||||
|
||||
<v-detail class="mobile-sidebar" :label="sidebarLabel">
|
||||
<nav v-if="$slots.sidebar">
|
||||
<slot name="sidebar" />
|
||||
</nav>
|
||||
</v-detail>
|
||||
|
||||
<slot />
|
||||
</main>
|
||||
</div>
|
||||
@@ -57,6 +58,7 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, computed, provide } from '@vue/composition-api';
|
||||
import HeaderBar from '@/views/private/components/header-bar/header-bar.vue';
|
||||
import i18n from '../../lang';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@@ -87,9 +89,12 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: 'box',
|
||||
},
|
||||
sidebarLabel: {
|
||||
type: String,
|
||||
default: i18n.t('sidebar'),
|
||||
},
|
||||
},
|
||||
setup(props, { emit, listeners }) {
|
||||
const sidebarActive = ref(false);
|
||||
const localActive = ref(false);
|
||||
|
||||
const mainEl = ref<Element>();
|
||||
@@ -110,7 +115,7 @@ export default defineComponent({
|
||||
return listeners.hasOwnProperty('cancel');
|
||||
});
|
||||
|
||||
return { sidebarActive, _active, mainEl, showCancel };
|
||||
return { _active, mainEl, showCancel };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -128,6 +133,7 @@ body {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
max-width: var(--v-drawer-max-width);
|
||||
height: 100%;
|
||||
background-color: var(--background-page);
|
||||
@@ -156,27 +162,18 @@ body {
|
||||
overflow: hidden;
|
||||
|
||||
.sidebar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
flex-basis: 220px;
|
||||
flex-shrink: 0;
|
||||
width: 220px;
|
||||
height: 100%;
|
||||
background-color: var(--background-normal);
|
||||
transform: translateX(-100%);
|
||||
transition: transform var(--slow) var(--transition-out);
|
||||
|
||||
&.active {
|
||||
transform: translateX(0);
|
||||
transition-timing-function: var(--transition-in);
|
||||
}
|
||||
display: none;
|
||||
|
||||
@include breakpoint(medium) {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: block;
|
||||
flex-basis: 220px;
|
||||
flex-shrink: 0;
|
||||
width: 220px;
|
||||
height: 100%;
|
||||
height: auto;
|
||||
transform: translateX(0);
|
||||
background-color: var(--background-normal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,4 +205,13 @@ body {
|
||||
width: calc(100% - 64px);
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-sidebar {
|
||||
margin: var(--content-padding);
|
||||
|
||||
nav {
|
||||
background-color: var(--background-subdued);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
"
|
||||
:subtitle="localType ? $t(`field_${localType}`) : null"
|
||||
persistent
|
||||
:sidebar-label="currentTabInfo.text"
|
||||
>
|
||||
<template #sidebar>
|
||||
<setup-tabs :current.sync="currentTab" :tabs="tabs" :type="localType" />
|
||||
@@ -183,7 +184,7 @@ export default defineComponent({
|
||||
|
||||
initLocalStore(props.collection, props.field, localType.value);
|
||||
|
||||
const { tabs, currentTab } = useTabs();
|
||||
const { tabs, currentTab, currentTabInfo } = useTabs();
|
||||
|
||||
const saving = ref(false);
|
||||
|
||||
@@ -200,6 +201,7 @@ export default defineComponent({
|
||||
existingField,
|
||||
collectionInfo,
|
||||
translationsManual,
|
||||
currentTabInfo,
|
||||
};
|
||||
|
||||
function useTabs() {
|
||||
@@ -257,7 +259,12 @@ export default defineComponent({
|
||||
|
||||
const currentTab = ref(['schema']);
|
||||
|
||||
return { tabs, currentTab };
|
||||
const currentTabInfo = computed(() => {
|
||||
const tabKey = currentTab.value[0];
|
||||
return tabs.value.find((tab) => tab.value === tabKey);
|
||||
});
|
||||
|
||||
return { tabs, currentTab, currentTabInfo };
|
||||
|
||||
function relationshipDisabled() {
|
||||
return isEmpty(state.fieldData.field);
|
||||
|
||||
@@ -5,16 +5,19 @@
|
||||
class="new-collection"
|
||||
persistent
|
||||
@cancel="$router.push('/settings/data-model')"
|
||||
:sidebar-label="$t(currentTab)"
|
||||
>
|
||||
<template #sidebar>
|
||||
<v-tabs vertical v-model="currentTab">
|
||||
<v-tab value="collection">{{ $t('collection_setup') }}</v-tab>
|
||||
<v-tab value="system" :disabled="!collectionName">{{ $t('optional_system_fields') }}</v-tab>
|
||||
<v-tab value="collection_setup">{{ $t('collection_setup') }}</v-tab>
|
||||
<v-tab value="optional_system_fields" :disabled="!collectionName">
|
||||
{{ $t('optional_system_fields') }}
|
||||
</v-tab>
|
||||
</v-tabs>
|
||||
</template>
|
||||
|
||||
<v-tabs-items class="content" v-model="currentTab">
|
||||
<v-tab-item value="collection">
|
||||
<v-tab-item value="collection_setup">
|
||||
<v-notice type="info">{{ $t('creating_collection_info') }}</v-notice>
|
||||
|
||||
<div class="grid">
|
||||
@@ -67,7 +70,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</v-tab-item>
|
||||
<v-tab-item value="system">
|
||||
<v-tab-item value="optional_system_fields">
|
||||
<v-notice type="info">{{ $t('creating_collection_system') }}</v-notice>
|
||||
|
||||
<div class="grid system">
|
||||
@@ -95,8 +98,8 @@
|
||||
<template #actions>
|
||||
<v-button
|
||||
:disabled="!collectionName || collectionName.length === 0"
|
||||
v-if="currentTab[0] === 'collection'"
|
||||
@click="currentTab = ['system']"
|
||||
v-if="currentTab[0] === 'collection_setup'"
|
||||
@click="currentTab = ['optional_system_fields']"
|
||||
v-tooltip.bottom="$t('next')"
|
||||
icon
|
||||
rounded
|
||||
@@ -104,7 +107,7 @@
|
||||
<v-icon name="arrow_forward" />
|
||||
</v-button>
|
||||
<v-button
|
||||
v-if="currentTab[0] === 'system'"
|
||||
v-if="currentTab[0] === 'optional_system_fields'"
|
||||
@click="save"
|
||||
:loading="saving"
|
||||
v-tooltip.bottom="$t('finish_setup')"
|
||||
@@ -133,7 +136,7 @@ export default defineComponent({
|
||||
const fieldsStore = useFieldsStore();
|
||||
const relationsStore = useRelationsStore();
|
||||
|
||||
const currentTab = ref(['collection']);
|
||||
const currentTab = ref(['collection_setup']);
|
||||
|
||||
const collectionName = ref(null);
|
||||
const singleton = ref(false);
|
||||
@@ -225,7 +228,7 @@ export default defineComponent({
|
||||
await fieldsStore.hydrate();
|
||||
|
||||
notify({
|
||||
title: 'Collection Created',
|
||||
title: i18n.t('collection_created'),
|
||||
type: 'success',
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<template>
|
||||
<v-drawer :title="modalTitle" :active="true" class="new-collection" persistent>
|
||||
<v-drawer
|
||||
:title="modalTitle"
|
||||
:active="true"
|
||||
class="new-collection"
|
||||
persistent
|
||||
:sidebar-label="currentTabInfo && currentTabInfo.text"
|
||||
>
|
||||
<template #sidebar v-if="!loading">
|
||||
<tabs :current-tab.sync="currentTab" :tabs="tabs" />
|
||||
</template>
|
||||
@@ -117,6 +123,12 @@ export default defineComponent({
|
||||
|
||||
const currentTab = ref<string[]>([]);
|
||||
|
||||
const currentTabInfo = computed(() => {
|
||||
const tabKey = currentTab.value?.[0];
|
||||
if (!tabKey) return null;
|
||||
return tabs.value.find((tab) => tab.value === tabKey);
|
||||
});
|
||||
|
||||
watch(
|
||||
tabs,
|
||||
(newTabs, oldTabs) => {
|
||||
@@ -126,7 +138,7 @@ export default defineComponent({
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
return { permission, role, loading, modalTitle, tabs, currentTab };
|
||||
return { permission, role, loading, modalTitle, tabs, currentTab, currentTabInfo };
|
||||
|
||||
async function load() {
|
||||
loading.value = true;
|
||||
|
||||
@@ -5,7 +5,15 @@
|
||||
</v-button>
|
||||
|
||||
<div class="action-buttons">
|
||||
<v-button class="sidebar-toggle" icon rounded secondary outlined @click="$emit('toggle:sidebar')">
|
||||
<v-button
|
||||
class="sidebar-toggle"
|
||||
icon
|
||||
rounded
|
||||
secondary
|
||||
outlined
|
||||
@click="$emit('toggle:sidebar')"
|
||||
v-if="showSidebarToggle"
|
||||
>
|
||||
<v-icon name="info" outline />
|
||||
</v-button>
|
||||
|
||||
@@ -18,7 +26,12 @@
|
||||
import { defineComponent, ref } from '@vue/composition-api';
|
||||
|
||||
export default defineComponent({
|
||||
props: {},
|
||||
props: {
|
||||
showSidebarToggle: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const active = ref(false);
|
||||
return { active };
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<header class="header-bar" ref="headerEl" :class="{ collapsed: collapsed }">
|
||||
<v-button secondary class="nav-toggle" icon rounded @click="$emit('toggle:nav')">
|
||||
<v-icon name="menu" />
|
||||
<v-button secondary class="nav-toggle" icon rounded @click="$emit('primary')" v-if="$listeners.primary">
|
||||
<v-icon :name="primaryActionIcon" />
|
||||
</v-button>
|
||||
|
||||
<div class="title-outer-prepend" v-if="$scopedSlots['title-outer:prepend']">
|
||||
@@ -12,6 +12,7 @@
|
||||
<div class="headline">
|
||||
<slot name="headline" />
|
||||
</div>
|
||||
|
||||
<div class="title">
|
||||
<slot name="title">
|
||||
<slot name="title:prepend" />
|
||||
@@ -26,9 +27,11 @@
|
||||
<div class="spacer" />
|
||||
|
||||
<slot name="actions:prepend" />
|
||||
<header-bar-actions @toggle:sidebar="$emit('toggle:sidebar')">
|
||||
|
||||
<header-bar-actions :show-sidebar-toggle="showSidebarToggle" @toggle:sidebar="$emit('toggle:sidebar')">
|
||||
<slot name="actions" />
|
||||
</header-bar-actions>
|
||||
|
||||
<slot name="actions:append" />
|
||||
</header>
|
||||
</template>
|
||||
@@ -44,6 +47,14 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
showSidebarToggle: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
primaryActionIcon: {
|
||||
type: String,
|
||||
default: 'menu',
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const headerEl = ref<Element>();
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-drawer v-model="_active" :title="$t('item_revision')" @cancel="_active = false">
|
||||
<v-drawer
|
||||
v-model="_active"
|
||||
:title="$t('item_revision')"
|
||||
@cancel="_active = false"
|
||||
:sidebar-label="$t(currentTab[0])"
|
||||
>
|
||||
<template #subtitle>
|
||||
<revisions-drawer-picker :revisions="revisions" :current.sync="_current" />
|
||||
</template>
|
||||
@@ -14,9 +19,9 @@
|
||||
</template>
|
||||
|
||||
<div class="content">
|
||||
<revisions-drawer-preview v-if="currentTab[0] === 'preview'" :revision="currentRevision" />
|
||||
<revisions-drawer-preview v-if="currentTab[0] === 'revision_preview'" :revision="currentRevision" />
|
||||
<revisions-drawer-updates
|
||||
v-if="currentTab[0] === 'updates'"
|
||||
v-if="currentTab[0] === 'updates_made'"
|
||||
:revision="currentRevision"
|
||||
:revisions="revisions"
|
||||
/>
|
||||
@@ -80,7 +85,7 @@ export default defineComponent({
|
||||
const _active = useSync(props, 'active', emit);
|
||||
const _current = useSync(props, 'current', emit);
|
||||
|
||||
const currentTab = ref(['preview']);
|
||||
const currentTab = ref(['revision_preview']);
|
||||
|
||||
const currentRevision = computed(() => {
|
||||
return props.revisions.find((revision) => revision.id === props.current);
|
||||
@@ -89,11 +94,11 @@ export default defineComponent({
|
||||
const tabs = [
|
||||
{
|
||||
text: i18n.t('revision_preview'),
|
||||
value: 'preview',
|
||||
value: 'revision_preview',
|
||||
},
|
||||
{
|
||||
text: i18n.t('updates_made'),
|
||||
value: 'updates',
|
||||
value: 'updates_made',
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -19,7 +19,12 @@
|
||||
</div>
|
||||
</aside>
|
||||
<div class="content" ref="contentEl">
|
||||
<header-bar :title="title" @toggle:sidebar="sidebarOpen = !sidebarOpen" @toggle:nav="navOpen = !navOpen">
|
||||
<header-bar
|
||||
show-sidebar-toggle
|
||||
:title="title"
|
||||
@toggle:sidebar="sidebarOpen = !sidebarOpen"
|
||||
@primary="navOpen = !navOpen"
|
||||
>
|
||||
<template v-for="(_, scopedSlotName) in $scopedSlots" v-slot:[scopedSlotName]="slotData">
|
||||
<slot :name="scopedSlotName" v-bind="slotData" />
|
||||
</template>
|
||||
@@ -65,9 +70,9 @@ import SidebarButton from './components/sidebar-button/';
|
||||
import NotificationsGroup from './components/notifications-group/';
|
||||
import NotificationsPreview from './components/notifications-preview/';
|
||||
import NotificationDialogs from './components/notification-dialogs/';
|
||||
import { useUserStore, useAppStore } from '@/stores';
|
||||
import i18n from '@/lang';
|
||||
import emitter, { Events } from '@/events';
|
||||
import { useUserStore, useAppStore } from '../../stores';
|
||||
import i18n from '../../lang';
|
||||
import emitter, { Events } from '../../events';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@@ -127,7 +132,7 @@ export default defineComponent({
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/styles/mixins/breakpoint';
|
||||
@import '../../styles/mixins/breakpoint';
|
||||
|
||||
.private-view {
|
||||
--content-padding: 12px;
|
||||
|
||||
Reference in New Issue
Block a user