Merge branch 'main' into aggregation

This commit is contained in:
rijkvanzanten
2021-06-09 14:16:36 -04:00
529 changed files with 36532 additions and 32331 deletions

2
docs/.gitignore vendored
View File

@@ -1 +1 @@
index.json
dist

View File

@@ -372,11 +372,6 @@ module.exports = {
title: 'Breadcrumb',
type: 'page',
},
{
path: 'reference/app/components/v-button-group',
title: 'Button Group',
type: 'page',
},
{
path: 'reference/app/components/v-button',
title: 'Button',

View File

@@ -1,11 +1,40 @@
const dirTree = require('directory-tree');
const path = require('path');
const fse = require('fs-extra');
const dirTree = require('directory-tree');
console.log('Building docs...');
const tree = dirTree('.', {
extensions: /\.md$/,
exclude: /(node_modules|.vuepress|.vscode|dist)/,
normalizePath: true,
});
fse.writeJSONSync('index.json', tree);
const index = `export default ${generateIndex(tree.children)};`;
fse.ensureDirSync('dist');
fse.writeFileSync('dist/index.js', index);
console.log('Built docs');
function generateIndex(tree) {
const children = tree
.map((child) => {
if (child.type === 'file') {
const baseName = path.basename(child.name, child.extension);
const basePath = path.join(path.dirname(child.path), path.basename(child.path, child.extension));
return `{name:'${baseName}',path:'${basePath}',import:()=>import('../${child.path}?raw')}`;
} else if (child.type === 'directory') {
const children = generateIndex(child.children);
if (children === '[]') return null;
return `{name:'${child.name}',path:'${child.path}',children:${children}}`;
} else {
return null;
}
})
.filter((child) => child !== null);
return `[${children.join(',')}]`;
}

View File

@@ -18,8 +18,8 @@ developers and an intuitive App for non-technical users.** Written entirely in J
[Node.js](https://nodejs.dev) and [Vue.js](https://vuejs.org)), Directus is completely open-source, modular, and
extensible, allowing it to be fully tailored to the requirements of any project.
The platform can be used as a headless content management, or for democratizing data (customer, inventory, business,
project, etc) across an organization.
The platform can be used for an individual purpose, such as headless content management, or more broadly to democratize
an entire organization's data (customers, inventory, business intelligence, projects, etc).
::: tip What's in a name?

View File

@@ -74,6 +74,7 @@ module.exports = function registerHook({ exceptions }) {
| Scope | Actions | Before |
| ------------------------------- | ----------------------------------------------------------- | ---------------- |
| `cron()` | [See below for configuration](#interval-cron) | No |
| `server` | `start` and `stop` | Optional |
| `init` | | Optional |
| `routes.init` | `before` and `after` | No |
@@ -103,6 +104,12 @@ module.exports = function registerHook({ exceptions }) {
<sup>2</sup> oAuth provider name can replaced with wildcard for any oauth providers `oauth.*.login`\
<sup>3</sup> Doesn't support `.before` modifier
#### Interval (cron)
Hooks support running on an interval through [`node-cron`](https://www.npmjs.com/package/node-cron). To set this up,
provide a cron statement in the event scope as follows: `cron(<statement>)`, for example `cron(15 14 1 * *)` (at 14:15
on day-of-month 1) or `cron(5 4 * * sun)` (at 04:05 on Sunday).
## 3. Register your Hook
Each custom hook is registered to its event scope using a function with the following format:

View File

@@ -94,7 +94,7 @@ To configure manual sorting for a collection:
1. Navigate to **Settings > Data Model > [Collection Name]**
2. Create a field with the **Integer** type
* Optional: Set the field to be **Hidden**
- Optional: Set the field to be **Hidden**
3. Select the field you just created in the **Sort Field** dropdown
::: tip Automatic Setup
@@ -106,7 +106,8 @@ field, the collection's sort settings will automatically be configured for you.
::: tip Interface Sorting
To configure manual sorting within an Interface (eg: M2M, O2M, or M2A), configure as above, but also set the **Sort Field** on the field's Relationship pane.
To configure manual sorting within an Interface (eg: M2M, O2M, or M2A), configure as above, but also set the **Sort
Field** on the field's Relationship pane.
:::

View File

@@ -5,6 +5,8 @@ There are two ways to migrate from an existing Directus 8.X instance:
- [Automated Script](#automated-script) (recommended)
- [Manual Database Export/Import](#manual-database-export-import)
Be sure to check the [Breaking changes](#breaking-changes) if you are consuming the API from an application.
## Automated Script
We created a (community maintained) script, that will automatically copy over the schema, content, files, users, and
@@ -64,3 +66,9 @@ Once the tables are in, you can start configuring the details of the schema. Thi
interfaces, displays, and their options for your fields.
This would also be a good time to reconfigure your permissions, to ensure they are accurate.
## Breaking changes
- [Filter operators](/reference/filter-rules.md) have changed, now they are preceeded with an underscore eg:
`/items/users?filter[comments.thread.title][like]=Directus` is now
`/items/users?filter[comments][thread][title][_like]=Directus`

View File

@@ -67,7 +67,7 @@ See [Creating a Thumbnail Preset](/guides/files/#creating-a-thumbnail-preset)
See [Styles > Custom CSS](/guides/styles/#custom-css)
## Upgrading a Project
## Upgrading / Updating a Project
1. Backup your project
2. Run `npm update`

22
docs/index.d.ts vendored
View File

@@ -1,19 +1,17 @@
export type File = {
type: 'file';
size: number;
path: string;
export type DocsFile = {
name: string;
extension: string;
path: string;
import: () => Promise<{ default: string }>;
};
export type Directory = {
type: 'directory';
size: number;
path: string;
export type DocsFolder = {
name: string;
children: (Directory | File)[];
path: string;
children: DocsRoutes;
};
export type DocsRoutes = (DocsFolder | DocsFile)[];
export type Link = {
name: string;
to: string;
@@ -30,5 +28,5 @@ export type Divider = {
divider: true;
};
declare const files: Directory;
export default files;
declare const docs: DocsRoutes;
export default docs;

View File

@@ -1,9 +1,9 @@
{
"name": "@directus/docs",
"private": false,
"version": "9.0.0-rc.73",
"version": "9.0.0-rc.74",
"description": "",
"main": "index.json",
"main": "dist/index.js",
"scripts": {
"build": "node build.js",
"dev": "npm-watch build",
@@ -35,7 +35,7 @@
"lodash.get": "^4.4.2",
"micromark": "^2.10.1",
"npm-watch": "^0.9.0",
"slugify": "^1.4.6",
"slugify": "^1.5.3",
"vuepress": "^1.7.1",
"vuepress-plugin-clean-urls": "^1.1.2"
}

View File

@@ -14,7 +14,7 @@ Bounces items in or out depending if the get added or removed from the view.
</template>
<script lang="ts">
import { defineComponent, ref } from '@vue/composition-api';
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup(props) {

View File

@@ -14,7 +14,7 @@ Fades items in or out depending if the get added or removed from the view.
</template>
<script lang="ts">
import { defineComponent, ref } from '@vue/composition-api';
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup(props) {

View File

@@ -14,7 +14,7 @@ Use around a `v-if` or `v-show` component to have it expand in and out of view.
</template>
<script lang="ts">
import { defineComponent, ref } from '@vue/composition-api';
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup(props) {

View File

@@ -1,56 +0,0 @@
# Button Group
Provides the ability to make groups of buttons. Uses the v-item-group component and adds styling to the buttons. For
more information about how to use groups, look into v-item-group.
## Usage
```html
<template>
<v-button-group v-model="selection">
<v-button v-slot:default="{ active }">Click me to {{ active ? 'activate' : 'deactivate' }}</v-button>
</v-button-group>
</template>
<script lang="ts">
import { defineComponent, ref } from '@vue/composition-api';
export default defineComponent({
setup() {
const selection = ref([]);
return { selection };
},
});
</script>
```
## Reference
#### Props
| Prop | Description | Default | Type |
| ----------- | ------------------------------------------------------- | ----------- | ---------------------- |
| `mandatory` | Require an item to be selected | `false` | `Boolean` |
| `max` | Only allow a maximum of n items | `-1` | `Number` |
| `multiple` | Allow multiple items to be selected | `false` | `Boolean` |
| `value` | The v-model value. Selection of indexes / custom values | `undefined` | `(string or number)[]` |
| `rounded` | Adds rounded corners to the sides | `false` | `Boolean` |
| `tile` | Adds sharp corners to the sides | `false` | `Boolean` |
#### Slots
| Slot | Description | Data |
| --------- | ----------- | ---- |
| _default_ | | -- |
#### Events
| Event | Description | Value |
| ------- | -------------------------------- | ---------------------- |
| `input` | Used to update the v-model value | `(string or number)[]` |
#### CSS Variables
| Variable | Default |
| ------------------------------------------ | -------------------- |
| `--v-button-group-background-color-active` | `var(--primary-alt)` |

View File

@@ -64,11 +64,11 @@ Keep in mind to pass the `value` prop with a unique value when using arrays in `
## Indeterminate
The indeterminate state can be set with the `indeterminate` prop. We recommend using the `.sync` modifier with the
The indeterminate state can be set with the `indeterminate` prop. We recommend using the `v-model` directive with the
indeterminate prop, so the checkbox can set change it too:
```html
<v-checkbox :indeterminate.sync="indeterminate">
<v-checkbox v-model:indeterminate="indeterminate">
<script>
export default {
data() {

View File

@@ -12,12 +12,12 @@ Use the detail component to hide not so important information or elements.
#### Props
| Prop | Description | Default | Type |
| ------------ | ----------------------- | ------------------ | --------- |
| `active` | Used with `v-model` | `undefined` | `Boolean` |
| `label` | Label of detail | `i18n.t('toggle')` | `String` |
| `start-open` | Have it open by default | `false` | `Boolean` |
| `disabled` | Disable any interaction | `false` | `Boolean` |
| Prop | Description | Default | Type |
| ------------ | ----------------------- | ------------------------- | --------- |
| `active` | Used with `v-model` | `undefined` | `Boolean` |
| `label` | Label of detail | `i18n.global.t('toggle')` | `String` |
| `start-open` | Have it open by default | `false` | `Boolean` |
| `disabled` | Disable any interaction | `false` | `Boolean` |
#### Events

View File

@@ -13,14 +13,14 @@ relational or nested data.
#### Props
| Prop | Description | Default | Type |
| --------------- | ------------------------------------------------------ | ------------------- | --------- |
| `title`\* | The title of the drawer | | `String` |
| `subtitle` | The subtitle of the drawer | `null` | `String` |
| `active` | Can be used with `v-model` to open or close the drawer | `undefined` | `Boolean` |
| `persistent` | Disallow closing the drawer by clicking out of it | `false` | `Boolean` |
| `icon` | An icon for the drawer | `'box'` | `String` |
| `sidebar-label` | A label for the sidebar | `i18n.t('sidebar')` | `String` |
| Prop | Description | Default | Type |
| --------------- | ------------------------------------------------------ | -------------------------- | --------- |
| `title`\* | The title of the drawer | | `String` |
| `subtitle` | The subtitle of the drawer | `null` | `String` |
| `active` | Can be used with `v-model` to open or close the drawer | `undefined` | `Boolean` |
| `persistent` | Disallow closing the drawer by clicking out of it | `false` | `Boolean` |
| `icon` | An icon for the drawer | `'box'` | `String` |
| `sidebar-label` | A label for the sidebar | `i18n.global.t('sidebar')` | `String` |
#### Events

View File

@@ -33,14 +33,14 @@ representation.
## FancySelectItem
| Prop | Description | Type |
| ------------- | ------------------------------------------ | ---------------------------------------- |
| `icon` | Which icon to display | `string` |
| `value` | Which value the item represents | `string or number` |
| `text` | The displayed text | `undefined or string or TranslateResult` |
| `description` | Optional description to display | `undefined or string or TranslateResult` |
| `divider` | If set to true, display an divider instead | `undefined or boolean` |
| `iconRight` | Display an optional icon to the right | `undefined or string` |
| Prop | Description | Type |
| ------------- | ------------------------------------------ | ---------------------- |
| `icon` | Which icon to display | `string` |
| `value` | Which value the item represents | `string or number` |
| `text` | The displayed text | `undefined or string` |
| `description` | Optional description to display | `undefined or string` |
| `divider` | If set to true, display an divider instead | `undefined or boolean` |
| `iconRight` | Display an optional icon to the right | `undefined or string` |
## Reference

View File

@@ -5,7 +5,7 @@ Renders a form using interfaces based on the passed collection name.
```html
<v-form
collection="articles"
:edits.sync="{}"
v-model="{}"
:initial-values="{
title: 'Hello World'
}"
@@ -21,7 +21,7 @@ Renders a form using interfaces based on the passed collection name.
| `collection` | The collection of which you want to render the fields | `undefined` | `String` |
| `fields` | Array of fields to render. This can be used instead of the collection prop | `undefined` | `Field[]` |
| `initial-values` | Object of the starting values of the fields | `null` | `FieldValues` |
| `edits` | The edits that were made after the form was rendered. Being used in `v-model` | `null` | `FieldValues` |
| `model-value` | The edits that were made after the form was rendered. Being used in `v-model` | `null` | `FieldValues` |
| `loading` | Display the form in a loading state. Prevents the ctx menus from being used and renders skeleton loaders for the fields | `false` | `Boolean` |
| `batch-mode` | If enabled, allows to select multiple entries | `false` | `Boolean` |
| `primary-key` | The primary key of the given collection | `null` | `[String, Number]` |
@@ -36,6 +36,6 @@ n/a
#### Events
| Event | Description | Value |
| ------- | ------------------------ | ----- |
| `input` | Edits have been updated. | |
| Event | Description | Value |
| -------------------- | ------------------------ | ----- |
| `update:model-value` | Edits have been updated. | |

View File

@@ -18,7 +18,7 @@ elements like a list of cards, or a button group.
</template>
<script lang="ts">
import { defineComponent, ref } from '@vue/composition-api';
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup() {
@@ -103,7 +103,7 @@ useful when you're working with a predefined list of items:
</template>
<script lang="ts">
import { defineComponent, ref } from '@vue/composition-api';
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup() {

View File

@@ -4,7 +4,7 @@ Renders a dropdown menu. Can be attached to an activator element or free floatin
**NOTE**
Due to the fact that a menu is rendered through a portal, dialogs don't work great when rendered from within a menu.
Due to the fact that a menu is rendered through a teleport, dialogs don't work great when rendered from within a menu.
## Reference

View File

@@ -50,7 +50,7 @@ in the header item for this column sent to `headers`.
```html
<v-table :headers="headers" :items="items">
<template #header.name="{ header }">
<template #[`header.name`]="{ header }">
<v-button>{{ header.text }}</v-button>
</template>
</v-table>
@@ -65,7 +65,7 @@ header item for this column sent to `headers`.
```html
<v-table :headers="headers" :items="items">
<template #item.name="{ item }">
<template #[`item.name`]="{ item }">
<v-button>{{ item.name }}</v-button>
</template>
</v-table>
@@ -76,15 +76,15 @@ In this slot, you have access to the `item` through the scoped slot binding.
## Resizable rows
Adding the `show-resize` prop allows the user to resize the columns at will. You can keep your headers updated by using
the `.sync` modifier or listening to the `update:headers` event:
the `v-model` directive or listening to the `update:headers` event:
```html
<template>
<v-table :headers.sync="headers" :items="[]" show-resize>
<v-table v-model:headers="headers" :items="[]" show-resize>
</template>
<script>
import { defineComponent, ref } from '@vue/composition-api';
import { defineComponent, ref } from 'vue';
import { HeaderRaw } from '@/components/v-table/types';
export default defineComponent({
@@ -112,39 +112,39 @@ export default defineComponent({
#### Props
| Prop | Description | Default | Type |
| -------------------- | ---------------------------------------------------------------------------------------------- | -------------------- | ------------- |
| `headers`\* | What columns to show in the table. Supports the `.sync` modifier | | `HeaderRaw[]` |
| `items`\* | The individual items to render as rows | | `Item[]` |
| `disabled` | Disable edits to items in the form (drag/select) | `false` | `Boolean` |
| `fixed-header` | Make the header fixed | `false` | `Boolean` |
| `inline` | Display the table inline with other text | `false` | `Boolean` |
| `item-key` | Primary key of the item. Used for keys / selections | `'id'` | `String` |
| `loading-text` | What text to show when table is loading with no items | `i18n.t('loading')` | `String` |
| `loading` | Show progress indicator | `false` | `Boolean` |
| `manual-sort-key` | What field to use for manual sorting | `null` | `String` |
| `must-sort` | Requires the sort to be on a particular column | `false` | `Boolean` |
| `no-items-text` | What text to show when table doesn't contain any rows | `i18n.t('no_items')` | `String` |
| `row-height` | Height of the individual rows in px | `48` | `Number` |
| `selection-use-keys` | What field to use for selection | `false` | `Boolean` |
| `selection` | What items are selected. Can be used with `v-model` as well | `() => []` | `any` |
| `server-sort` | Handle sorting on the parent level. | `false` | `Boolean` |
| `show-manual-sort` | Show manual sort drag handles | `false` | `Boolean` |
| `show-resize` | Show resize handlers | `false` | `Boolean` |
| `show-select` | Show checkboxes | `false` | `Boolean` |
| `sort` | What column / order to sort by. Supports the `.sync` modifier. `{ by: string, desc: boolean }` | `null` | `Sort` |
| Prop | Description | Default | Type |
| -------------------- | ------------------------------------------------------------------------------------------------- | --------------------------- | ------------- |
| `headers`\* | What columns to show in the table. Supports the `v-model` directive | | `HeaderRaw[]` |
| `items`\* | The individual items to render as rows | | `Item[]` |
| `disabled` | Disable edits to items in the form (drag/select) | `false` | `Boolean` |
| `fixed-header` | Make the header fixed | `false` | `Boolean` |
| `inline` | Display the table inline with other text | `false` | `Boolean` |
| `item-key` | Primary key of the item. Used for keys / selections | `'id'` | `String` |
| `loading-text` | What text to show when table is loading with no items | `i18n.global.t('loading')` | `String` |
| `loading` | Show progress indicator | `false` | `Boolean` |
| `manual-sort-key` | What field to use for manual sorting | `null` | `String` |
| `must-sort` | Requires the sort to be on a particular column | `false` | `Boolean` |
| `no-items-text` | What text to show when table doesn't contain any rows | `i18n.global.t('no_items')` | `String` |
| `row-height` | Height of the individual rows in px | `48` | `Number` |
| `selection-use-keys` | What field to use for selection | `false` | `Boolean` |
| `selection` | What items are selected. Can be used with `v-model` as well | `() => []` | `any` |
| `server-sort` | Handle sorting on the parent level. | `false` | `Boolean` |
| `show-manual-sort` | Show manual sort drag handles | `false` | `Boolean` |
| `show-resize` | Show resize handlers | `false` | `Boolean` |
| `show-select` | Show checkboxes | `false` | `Boolean` |
| `sort` | What column / order to sort by. Supports the `v-model` directive. `{ by: string, desc: boolean }` | `null` | `Sort` |
#### Events
| Event | Description | Value |
| ---------------- | ------------------------------------------------- | ------------------------------- |
| `update:sort` | `.sync` event for `sort` prop | `{ by: string, desc: boolean }` |
| `click:row` | When a row has been clicked | |
| `update:items` | When changes to the items where made | |
| `manual-sort` | When a user manually sorts the items | |
| `update:headers` | `.sync` event for `headers` prop or `HeaderRaw[]` | |
| `item-selected` | Emitted when an item is selected or deselected | `{ item: any, value: boolean }` |
| `select` | Emitted when selected items change | `any[]` |
| Event | Description | Value |
| ---------------- | --------------------------------------------------- | ------------------------------- |
| `update:sort` | `v-model` event for `sort` prop | `{ by: string, desc: boolean }` |
| `click:row` | When a row has been clicked | |
| `update:items` | When changes to the items where made | |
| `manual-sort` | When a user manually sorts the items | |
| `update:headers` | `v-model` event for `headers` prop or `HeaderRaw[]` | |
| `item-selected` | Emitted when an item is selected or deselected | `{ item: any, value: boolean }` |
| `select` | Emitted when selected items change | `any[]` |
#### Slots