Merge branch 'main' of https://github.com/directus/next into main

This commit is contained in:
Ben Haynes
2020-09-21 18:29:06 -04:00
18 changed files with 98 additions and 37 deletions

View File

@@ -4,9 +4,12 @@ import ActivityService from '../services/activity';
import MetaService from '../services/meta';
import { Action } from '../types';
import { ForbiddenException } from '../exceptions';
import useCollection from '../middleware/use-collection';
const router = express.Router();
router.use(useCollection('directus_activity'));
router.get(
'/',
asyncHandler(async (req, res, next) => {

View File

@@ -9,9 +9,12 @@ import { pick } from 'lodash';
import { Transformation } from '../types/assets';
import storage from '../storage';
import PayloadService from '../services/payload';
import useCollection from '../middleware/use-collection';
const router = Router();
router.use(useCollection('directus_Files'));
router.get(
'/:pk',

View File

@@ -11,7 +11,6 @@ import ms from 'ms';
import cookieParser from 'cookie-parser';
import env from '../env';
import UsersService from '../services/users';
import { respond } from '../middleware/respond';
const router = Router();

View File

@@ -7,9 +7,12 @@ import { InvalidPayloadException, ForbiddenException } from '../exceptions';
import Joi from 'joi';
import { Field } from '../types/field';
import { types } from '../types';
import useCollection from '../middleware/use-collection';
const router = Router();
router.use(useCollection('directus_fields'));
router.get(
'/',
asyncHandler(async (req, res, next) => {

View File

@@ -11,9 +11,12 @@ import Joi from 'joi';
import { InvalidPayloadException, ForbiddenException } from '../exceptions';
import url from 'url';
import path from 'path';
import useCollection from '../middleware/use-collection';
const router = express.Router();
router.use(useCollection('directus_files'));
const multipartHandler = asyncHandler(async (req, res, next) => {
if (req.is('multipart/form-data') === false) return next();

View File

@@ -3,9 +3,12 @@ import asyncHandler from 'express-async-handler';
import FoldersService from '../services/folders';
import MetaService from '../services/meta';
import { ForbiddenException } from '../exceptions';
import useCollection from '../middleware/use-collection';
const router = express.Router();
router.use(useCollection('directus_folders'));
router.post(
'/',
asyncHandler(async (req, res, next) => {

View File

@@ -4,9 +4,12 @@ import PermissionsService from '../services/permissions';
import MetaService from '../services/meta';
import { clone } from 'lodash';
import { InvalidCredentialsException, ForbiddenException } from '../exceptions';
import useCollection from '../middleware/use-collection';
const router = express.Router();
router.use(useCollection('directus_permissions'));
router.post(
'/',
asyncHandler(async (req, res, next) => {

View File

@@ -3,9 +3,12 @@ import asyncHandler from 'express-async-handler';
import PresetsService from '../services/presets';
import MetaService from '../services/meta';
import { ForbiddenException } from '../exceptions';
import useCollection from '../middleware/use-collection';
const router = express.Router();
router.use(useCollection('directus_presets'));
router.post(
'/',
asyncHandler(async (req, res, next) => {

View File

@@ -3,9 +3,12 @@ import asyncHandler from 'express-async-handler';
import RelationsService from '../services/relations';
import MetaService from '../services/meta';
import { ForbiddenException } from '../exceptions';
import useCollection from '../middleware/use-collection';
const router = express.Router();
router.use(useCollection('directus_relations'));
router.post(
'/',
asyncHandler(async (req, res, next) => {

View File

@@ -2,9 +2,12 @@ import express from 'express';
import asyncHandler from 'express-async-handler';
import RevisionsService from '../services/revisions';
import MetaService from '../services/meta';
import useCollection from '../middleware/use-collection';
const router = express.Router();
router.use(useCollection('directus_revisions'));
router.get(
'/',
asyncHandler(async (req, res, next) => {

View File

@@ -3,9 +3,12 @@ import asyncHandler from 'express-async-handler';
import RolesService from '../services/roles';
import MetaService from '../services/meta';
import { ForbiddenException } from '../exceptions';
import useCollection from '../middleware/use-collection';
const router = express.Router();
router.use(useCollection('directus_roles'));
router.post(
'/',
asyncHandler(async (req, res, next) => {

View File

@@ -2,9 +2,12 @@ import express from 'express';
import asyncHandler from 'express-async-handler';
import SettingsService from '../services/settings';
import { ForbiddenException } from '../exceptions';
import useCollection from '../middleware/use-collection';
const router = express.Router();
router.use(useCollection('directus_settings'));
router.get(
'/',
asyncHandler(async (req, res, next) => {

View File

@@ -5,9 +5,12 @@ import { InvalidPayloadException, InvalidCredentialsException, ForbiddenExceptio
import UsersService from '../services/users';
import MetaService from '../services/meta';
import AuthService from '../services/authentication';
import useCollection from '../middleware/use-collection';
const router = express.Router();
router.use(useCollection('directus_users'));
router.post(
'/',
asyncHandler(async (req, res, next) => {

View File

@@ -3,9 +3,12 @@ import asyncHandler from 'express-async-handler';
import WebhooksService from '../services/webhooks';
import MetaService from '../services/meta';
import { ForbiddenException } from '../exceptions';
import useCollection from '../middleware/use-collection';
const router = express.Router();
router.use(useCollection('directus_webhooks'));
router.post(
'/',
asyncHandler(async (req, res, next) => {

View File

@@ -4,7 +4,7 @@ import env from "../env";
import { getCacheKey } from "../utils/get-cache-key";
import cache from '../cache';
import { Transform, transforms } from 'json2csv';
import { PassThrough } from "stream";
import { PassThrough } from 'stream';
export const respond: RequestHandler = asyncHandler(async (req, res) => {
if (req.method.toLowerCase() === 'get' && env.CACHE_ENABLED === true && cache && !req.sanitizedQuery.export) {
@@ -12,20 +12,44 @@ export const respond: RequestHandler = asyncHandler(async (req, res) => {
await cache.set(key, res.locals.payload);
}
if (req.sanitizedQuery.export === 'json') {
res.attachment('export.json');
res.set('Content-Type', 'application/json');
return res.status(200).send(JSON.stringify(res.locals.payload, null, '\t'));
}
if (req.sanitizedQuery.export) {
let filename = '';
if (req.sanitizedQuery.export === 'csv') {
res.attachment('export.csv');
res.set('Content-Type', 'text/csv');
const stream = new PassThrough();
stream.end(Buffer.from(JSON.stringify(res.locals.payload.data), 'utf-8'));
const json2csv = new Transform({ transforms: [transforms.flatten({ separator: '.' })] });
return stream.pipe(json2csv).pipe(res);
if (req.collection) {
filename += req.collection;
} else {
filename += 'Export';
}
filename += ' ' + getDateFormatted();
if (req.sanitizedQuery.export === 'json') {
res.attachment(`${filename}.json`);
res.set('Content-Type', 'application/json');
return res.status(200).send(JSON.stringify(res.locals.payload, null, '\t'));
}
if (req.sanitizedQuery.export === 'csv') {
res.attachment(`${filename}.csv`);
res.set('Content-Type', 'text/csv');
const stream = new PassThrough();
stream.end(Buffer.from(JSON.stringify(res.locals.payload.data), 'utf-8'));
const json2csv = new Transform({ transforms: [transforms.flatten({ separator: '.' })] });
return stream.pipe(json2csv).pipe(res);
}
}
return res.json(res.locals.payload);
});
function getDateFormatted() {
const date = new Date();
let month = String(date.getMonth() + 1);
if (month.length === 1) month = '0' + month;
let day = String(date.getDate());
if (day.length === 1) day = '0' + day;
return `${date.getFullYear()}-${month}-${day} at ${date.getHours()}.${date.getMinutes()}.${date.getSeconds()}`;
}

View File

@@ -31,13 +31,18 @@ export const useNotificationsStore = createStore({
return id;
},
hide(id: string) {
const toBeHidden = this.state.queue.find((n) => n.id === id);
if (!toBeHidden) return;
this.state.queue = this.state.queue.filter((n) => n.id !== id);
this.state.previous = [...this.state.previous, toBeHidden];
},
remove(id: string) {
const toBeRemoved = this.state.queue.find((n) => n.id === id);
if (!toBeRemoved) return;
this.state.queue = this.state.queue.filter((n) => n.id !== id);
this.state.previous = [...this.state.previous, toBeRemoved];
},
update(id: string, updates: Partial<Notification>) {
this.state.queue = this.state.queue.map(updateIfNeeded);

View File

@@ -3,7 +3,7 @@
<transition-expand tag="div">
<div v-if="active" class="inline">
<div class="padding-box">
<router-link class="link" :to="activityLink" :class="{ 'has-items': lastFour.length > 0 }">
<router-link class="link" to="/activity" :class="{ 'has-items': lastFour.length > 0 }">
{{ $t('show_all_activity') }}
</router-link>
<transition-group tag="div" name="notification" class="transition">
@@ -19,7 +19,7 @@
<drawer-button
:active="active"
@click="active = !active"
@click="$emit('input', !active)"
v-tooltip.left="$t('notifications')"
class="toggle"
icon="notifications"
@@ -37,28 +37,22 @@ import { useNotificationsStore } from '@/stores/';
export default defineComponent({
components: { DrawerButton, NotificationItem },
model: {
prop: 'active',
},
props: {
drawerOpen: {
type: Boolean,
default: false,
},
active: {
type: Boolean,
default: false,
},
},
setup(props) {
const notificationsStore = useNotificationsStore();
const activityLink = computed(() => `/activity`);
const active = ref(false);
watch(
() => props.drawerOpen,
(open: boolean) => {
if (open === false) {
active.value = false;
}
}
);
return { lastFour: notificationsStore.lastFour, activityLink, active };
return { lastFour: notificationsStore.lastFour };
},
});
</script>

View File

@@ -35,14 +35,14 @@
<div class="spacer" />
<notifications-preview :drawer-open="drawerOpen" />
<notifications-preview v-model="notificationsPreviewActive" :drawer-open="drawerOpen" />
</div>
</aside>
<v-overlay class="nav-overlay" :active="navOpen" @click="navOpen = false" />
<v-overlay class="drawer-overlay" :active="drawerOpen" @click="drawerOpen = false" />
<notifications-group :dense="drawerOpen === false" />
<notifications-group v-if="notificationsPreviewActive === false" :dense="drawerOpen === false" />
<template v-if="showDropEffect">
<div class="drop-border top" />
@@ -93,6 +93,8 @@ export default defineComponent({
const notificationsStore = useNotificationsStore();
const appStore = useAppStore();
const notificationsPreviewActive = ref(false);
const { drawerOpen } = toRefs(appStore.state);
const theme = computed(() => {
@@ -119,6 +121,7 @@ export default defineComponent({
dragging,
drawerOpen,
openDrawer,
notificationsPreviewActive,
};
function useFileUpload() {
@@ -237,10 +240,7 @@ export default defineComponent({
});
notificationsStore.remove(fileUploadNotificationID);
emitter.emit(Events.upload);
notificationsStore.remove(fileUploadNotificationID);
}
}