Skip to content

Commit

Permalink
Merge branch 'main' into fix-blocking-invalid-cookie
Browse files Browse the repository at this point in the history
  • Loading branch information
br41nslug committed May 14, 2024
2 parents 326aa35 + 2ecee4e commit 0ea71f2
Show file tree
Hide file tree
Showing 43 changed files with 531 additions and 420 deletions.
5 changes: 5 additions & 0 deletions .changeset/bright-trains-greet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@directus/app': patch
---

Reduced the number of session token refreshes if the token is still fresh
5 changes: 5 additions & 0 deletions .changeset/empty-baboons-wave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@directus/sdk": patch
---

Fixed running SDK in dev mode
5 changes: 5 additions & 0 deletions .changeset/fresh-garlics-cheer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@directus/app': patch
---

Added missing translations for focal point coordinate form fields
8 changes: 8 additions & 0 deletions .changeset/happy-oranges-play.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
---
"@directus/api": patch
"@directus/app": patch
"@directus/components": patch
"@directus/extensions": patch
"@directus/extensions-registry": patch
"@directus/release-notes-generator": patch
"@directus/storage-driver-gcs": patch
"@directus/themes": patch
"@directus/update-check": patch
---

Updated dependencies
5 changes: 5 additions & 0 deletions .changeset/new-carrots-do.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@directus/app': patch
---

Fixed display template not showing newly added fields under collection field settings
5 changes: 5 additions & 0 deletions .changeset/old-lizards-sleep.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@directus/app': patch
---

Added reload button when the app errors out
5 changes: 5 additions & 0 deletions .changeset/plenty-trees-draw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@directus/api': patch
---

Fixed count function on relational, filtered fields
5 changes: 5 additions & 0 deletions .changeset/twenty-hats-laugh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@directus/api': patch
---

Fixed `_between` and `_nbetween` filters using a function, such as `count()` and `year()`
5 changes: 5 additions & 0 deletions .changeset/yellow-frogs-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@directus/app": patch
---

Fixed missing field selection dropdown for functions in filter interface
4 changes: 4 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,7 @@ body:
- Directus Cloud
validations:
required: true
- type: input
attributes:
label: Database
description: If applicable, the vendor and version of the database being used. For example, PostgreSQL 16.
6 changes: 3 additions & 3 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,11 @@
"sharp": "0.33.3",
"snappy": "7.2.2",
"stream-json": "1.8.0",
"tar": "7.0.1",
"tar": "7.1.0",
"tsx": "4.9.3",
"wellknown": "0.5.0",
"ws": "8.17.0",
"zod": "3.23.6",
"zod": "3.23.8",
"zod-validation-error": "3.2.0"
},
"devDependencies": {
Expand Down Expand Up @@ -202,7 +202,7 @@
"@types/lodash-es": "4.17.12",
"@types/mime-types": "2.1.4",
"@types/ms": "0.7.34",
"@types/node": "18.19.31",
"@types/node": "18.19.33",
"@types/node-schedule": "2.1.7",
"@types/nodemailer": "6.4.15",
"@types/object-hash": "3.0.6",
Expand Down
19 changes: 18 additions & 1 deletion api/src/database/helpers/fn/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Query, SchemaOverview } from '@directus/types';
import type { Knex } from 'knex';
import { applyFilter, generateAlias } from '../../../utils/apply-query.js';
import type { AliasMap } from '../../../utils/get-column-path.js';
import { DatabaseHelper } from '../types.js';

export type FnHelperOptions = {
Expand Down Expand Up @@ -41,6 +42,7 @@ export abstract class FnHelper extends DatabaseHelper {
throw new Error(`Field ${collectionName}.${column} isn't a nested relational collection`);
}

// generate a unique alias for the relation collection, to prevent collisions in self referencing relations
const alias = generateAlias();

let countQuery = this.knex
Expand All @@ -49,7 +51,22 @@ export abstract class FnHelper extends DatabaseHelper {
.where(this.knex.raw(`??.??`, [alias, relation.field]), '=', this.knex.raw(`??.??`, [table, currentPrimary]));

if (options?.query?.filter) {
countQuery = applyFilter(this.knex, this.schema, countQuery, options.query.filter, relation.collection, {}).query;
// set the newly aliased collection in the alias map as the default parent collection, indicated by '', for any nested filters
const aliasMap: AliasMap = {
'': {
alias,
collection: relation.collection,
},
};

countQuery = applyFilter(
this.knex,
this.schema,
countQuery,
options.query.filter,
relation.collection,
aliasMap,
).query;
}

return this.knex.raw('(' + countQuery.toQuery() + ')');
Expand Down
14 changes: 8 additions & 6 deletions api/src/utils/apply-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,9 @@ export function applyFilter(

validateFilterOperator(type, filterOperator, special);

applyFilterToQuery(`${collection}.${filterPath[0]}`, filterOperator, filterValue, logical);
const aliasedCollection = aliasMap['']?.alias || collection;

applyFilterToQuery(`${aliasedCollection}.${filterPath[0]}`, filterOperator, filterValue, logical, collection);
}
}

Expand Down Expand Up @@ -666,7 +668,7 @@ export function applyFilter(
const type = getOutputTypeForFunction(functionName);

if (['integer', 'float', 'decimal'].includes(type)) {
compareValue = Number(compareValue);
compareValue = Array.isArray(compareValue) ? compareValue.map(Number) : Number(compareValue);
}
}

Expand Down Expand Up @@ -789,20 +791,20 @@ export function applyFilter(
}

if (operator === '_between') {
if (compareValue.length !== 2) return;

let value = compareValue;
if (typeof value === 'string') value = value.split(',');

if (value.length !== 2) return;

dbQuery[logical].whereBetween(selectionRaw, value);
}

if (operator === '_nbetween') {
if (compareValue.length !== 2) return;

let value = compareValue;
if (typeof value === 'string') value = value.split(',');

if (value.length !== 2) return;

dbQuery[logical].whereNotBetween(selectionRaw, value);
}

Expand Down
10 changes: 5 additions & 5 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
"@types/codemirror": "5.60.15",
"@types/color": "3.0.6",
"@types/diacritics": "1.3.3",
"@types/diff": "5.2.0",
"@types/diff": "5.2.1",
"@types/dompurify": "3.0.5",
"@types/file-saver": "2.0.7",
"@types/geojson": "7946.0.14",
Expand All @@ -99,10 +99,10 @@
"@unhead/addons": "1.9.9",
"@unhead/vue": "1.9.9",
"@vitejs/plugin-vue": "5.0.4",
"@vue/test-utils": "2.4.5",
"@vue/test-utils": "2.4.6",
"@vueuse/core": "10.9.0",
"@vueuse/router": "10.9.0",
"apexcharts": "3.49.0",
"apexcharts": "3.49.1",
"axios": "1.6.8",
"base-64": "1.0.0",
"caret-pos": "2.0.0",
Expand Down Expand Up @@ -138,8 +138,8 @@
"pretty-ms": "9.0.0",
"qrcode": "1.5.3",
"sass": "1.76.0",
"semver": "7.6.0",
"tinymce": "7.0.1",
"semver": "7.6.1",
"tinymce": "7.1.0",
"typescript": "5.4.5",
"vite": "5.2.11",
"vitest": "1.5.3",
Expand Down
14 changes: 12 additions & 2 deletions app/src/app.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<script setup lang="ts">
import { useSystem } from '@/composables/use-system';
import { useServerStore } from '@/stores/server';
import { getAssetUrl } from '@/utils/get-asset-url';
import { generateFavicon } from '@/utils/generate-favicon';
import { getAssetUrl } from '@/utils/get-asset-url';
import { useAppStore } from '@directus/stores';
import { ThemeProvider } from '@directus/themes';
import { useHead } from '@unhead/vue';
Expand Down Expand Up @@ -75,6 +75,10 @@ const customCSS = computed(() => {
const error = computed(() => appStore.error);
const reload = () => {
window.location.reload();
};
useSystem();
</script>

Expand All @@ -98,7 +102,9 @@ useSystem();
{{ t('unexpected_error_copy') }}

<template #append>
<v-error :error="error" />
<v-error class="error" :error="error" />

<v-button small @click="reload">{{ t('reload_page') }}</v-button>
</template>
</v-info>

Expand Down Expand Up @@ -137,4 +143,8 @@ useSystem();
.fade-leave-to {
opacity: 0;
}
.error {
margin-bottom: 24px;
}
</style>
17 changes: 15 additions & 2 deletions app/src/auth.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { resumeQueue } from '@/api';
import { DEFAULT_AUTH_PROVIDER } from '@/constants';
import { DEFAULT_AUTH_PROVIDER, SDK_AUTH_REFRESH_BEFORE_EXPIRES } from '@/constants';
import { dehydrate, hydrate } from '@/hydrate';
import { router } from '@/router';
import { sdk } from '@/sdk';
import { AuthenticationData, LoginOptions, RestCommand, authenticateShare, getAuthEndpoint } from '@directus/sdk';
import {
AuthenticationData,
LoginOptions,
RestCommand,
authenticateShare,
getAuthEndpoint,
readMe,
} from '@directus/sdk';
import { useAppStore } from '@directus/stores';
import { RouteLocationRaw } from 'vue-router';
import { Events, emitter } from './events';
Expand Down Expand Up @@ -95,6 +102,12 @@ export async function refresh({ navigate }: LogoutOptions = { navigate: true }):
if (!firstRefresh && !appStore.authenticated) return;

try {
// Skip access token refreshing if it is still fresh but validate the session
if (appStore.accessTokenExpiry && Date.now() < appStore.accessTokenExpiry - SDK_AUTH_REFRESH_BEFORE_EXPIRES) {
await sdk.request(readMe({ fields: ['id'] }));
return;
}

const response = await sdk.refresh();

appStore.accessTokenExpiry = Date.now() + (response.expires ?? 0);
Expand Down
5 changes: 4 additions & 1 deletion app/src/composables/use-field-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ export function useFieldTree(
const treeList = ref<FieldNode[]>([]);
const visitedPaths = ref<Set<string>>(new Set());

watch(() => collection.value, refresh, { immediate: true });
// Refresh when collection or fields of the collection are updated
watch([collection, () => collection.value && fieldsStore.getFieldsForCollectionSorted(collection.value)], refresh, {
immediate: true,
});

return { treeList, loadFieldRelations, refresh };

Expand Down
2 changes: 2 additions & 0 deletions app/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,5 @@ export const AUTH_SSO_DRIVERS = ['oauth2', 'openid', 'saml'];
export const DEFAULT_REPORT_BUG_URL = 'https://github.com/directus/directus/issues/new?template=bug_report.yml';
export const DEFAULT_REPORT_FEATURE_URL =
'https://github.com/directus/directus/discussions/new?category=feature-requests';

export const SDK_AUTH_REFRESH_BEFORE_EXPIRES = 10_000;
17 changes: 13 additions & 4 deletions app/src/interfaces/_system/system-filter/nodes.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { computed, toRefs } from 'vue';
import { useI18n } from 'vue-i18n';
import Draggable from 'vuedraggable';
import InputGroup from './input-group.vue';
import { fieldToFilter, getComparator, getField, getNodeName } from './utils';
import { fieldHasFunction, fieldToFilter, getComparator, getField, getNodeName } from './utils';
type FilterInfo = {
id: number;
Expand Down Expand Up @@ -98,7 +98,7 @@ function getFieldPreview(node: Record<string, any>) {
const fieldParts = fieldKey.split('.');
const fieldNames = fieldParts.map((fieldKey, index) => {
const hasFunction = fieldKey.includes('(') && fieldKey.includes(')');
const hasFunction = fieldHasFunction(fieldKey);
let key = fieldKey;
let functionName;
Expand Down Expand Up @@ -238,7 +238,7 @@ function replaceNode(index: number, newFilter: Filter) {
function getCompareOptions(name: string) {
let type: Type;
if (name.includes('(') && name.includes(')')) {
if (fieldHasFunction(name)) {
const functionName = name.split('(')[0] as FieldFunction;
type = getOutputTypeForFunction(functionName);
} else {
Expand All @@ -263,7 +263,15 @@ function getCompareOptions(name: string) {
function isExistingField(node: Record<string, any>): boolean {
if (!props.collection) return false;
const fieldKey = getField(node);
let fieldKey = getField(node);
if (fieldHasFunction(fieldKey)) {
const keyParts = fieldKey.split('.');
// the function is always in the last key part
const { field } = extractFieldFromFunction(keyParts.at(-1)!);
fieldKey = [...keyParts.slice(0, -1), field].join('.');
}
const field = fieldsStore.getField(props.collection, fieldKey);
return !!field;
}
Expand Down Expand Up @@ -428,6 +436,7 @@ function isExistingField(node: Record<string, any>): boolean {
.plain-name {
display: inline-block;
margin-right: 8px;
white-space: nowrap;
}
.name {
Expand Down
4 changes: 4 additions & 0 deletions app/src/interfaces/_system/system-filter/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export function getField(node: Record<string, any>): string {
return subFields !== '' ? `${name}.${subFields}` : name;
}

export function fieldHasFunction(field: string) {
return field.includes('(') && field.includes(')');
}

export function getComparator(node: Record<string, any>): string {
return getNodeName(get(node, getField(node)));
}
Expand Down
5 changes: 4 additions & 1 deletion app/src/lang/translations/en-US.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ n_files: '{n} Files'
verified: Verified
homepage: Homepage
repository: Repository
reload_page: Reload Page
reload_required: Reload Required
report_an_issue: Report an Issue
website: Website
Expand Down Expand Up @@ -762,7 +763,7 @@ cannot_edit_global_bookmarks: Can't Edit Global Bookmarks
bookmarks: Bookmarks
presets: Presets
unexpected_error: Unexpected Error
unexpected_error_copy: An unexpected error has occurred. Please try again later.
unexpected_error_copy: An unexpected error has occurred. Please try again.
copy_details: Copy Details
no_app_access: No App Access
no_app_access_copy: This user isn't allowed to use the admin app.
Expand Down Expand Up @@ -1283,6 +1284,8 @@ fields:
height: Height
charset: Charset
duration: Duration
focal_point_x: X-Coordinate
focal_point_y: Y-Coordinate
directus_users:
first_name: First Name
last_name: Last Name
Expand Down
Loading

0 comments on commit 0ea71f2

Please sign in to comment.