Skip to content

Commit

Permalink
Merge branch 'main' into fix/non-required-json-input
Browse files Browse the repository at this point in the history
  • Loading branch information
markkaylor committed Mar 13, 2023
2 parents f07fc24 + 98632e1 commit 7533a8d
Show file tree
Hide file tree
Showing 926 changed files with 36,366 additions and 29,827 deletions.
27 changes: 27 additions & 0 deletions .eslintrc.front.js
Expand Up @@ -38,5 +38,32 @@ module.exports = {
'react/jsx-no-constructed-context-values': 'warn',
'react/jsx-no-useless-fragment': 'warn',
'react/no-unstable-nested-components': 'warn',
'no-restricted-imports': [
'error',
{
paths: [
{
name: '@strapi/design-system',
importNames: ['Stack'],
message:
"'Stack' has been deprecated. Please import 'Flex' from '@strapi/design-system' instead.",
},
],
patterns: [
{
group: [
'@strapi/design-system/*',
'!@strapi/design-system/v2',
'@strapi/design-system/v2/*',
],
message: 'Please use the default import from "@strapi/design-system" packages instead.',
},
{
group: ['@strapi/icons/*'],
message: 'Please use the default import from "@strapi/icons" packages instead.',
},
],
},
],
},
};
2 changes: 1 addition & 1 deletion .github/actions/check-pr-status/package.json
@@ -1,6 +1,6 @@
{
"name": "check-pr-status",
"version": "4.6.1",
"version": "4.7.1",
"main": "dist/index.js",
"license": "MIT",
"private": true,
Expand Down
40 changes: 40 additions & 0 deletions .github/workflows/adminBundleSize.yml
@@ -0,0 +1,40 @@
name: Admin bundle-size

on:
pull_request:
paths:
- '**/admin/src/**.js'
- '**/ee/admin/**.js'
- '**/helper-plugin/lib/src/**.js'
- '**/translations/**.json'

# Might be too broad, but it runs the action even if a
# package.json wasn't changed, e.g. for non-pinned dependencies
- 'yarn.lock'

jobs:
admin_size:
runs-on: ubuntu-latest

# Allows the action to comment on PRs
permissions:
contents: read
pull-requests: write

steps:
- uses: actions/checkout@v3

- uses: actions/setup-node@v3
with:
node-version: 18
cache: yarn

- uses: preactjs/compressed-size-action@v2
with:
pattern: '**/build/**/*.{js,css,html,svg}'
strip-hash: "\\.(?:(\\w{8})\\.chunk)|(?:\\.(\\w{8}))"
minimum-change-threshold: 10

# FIXME: exclude unnamed webpack chunks - remove once webpack
# does not create them anymore
exclude: '{**/build/**/+([0-9]{,4})*,**/node_modules/**}'
22 changes: 21 additions & 1 deletion .github/workflows/tests.yml
Expand Up @@ -74,7 +74,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node: [14, 16, 18]
node: [18]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
Expand All @@ -97,6 +97,26 @@ jobs:
directory: ./coverage
flags: front,unit_front

build:
name: 'build (node: ${{ matrix.node }})'
needs: [lint, unit_front]
runs-on: ubuntu-latest
strategy:
matrix:
node: [14, 16, 18]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
- uses: actions/cache@v3
with:
path: '**/node_modules'
key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
- run: yarn install --frozen-lockfile
- name: Build
run: yarn build --scope @strapi/admin --scope @strapi/helper-plugin

api_ce_pg:
runs-on: ubuntu-latest
needs: [lint, unit_back, unit_front]
Expand Down
10 changes: 5 additions & 5 deletions docs/docs/core/content-manager/relations.mdx
Expand Up @@ -147,7 +147,7 @@ The input field for relation fields consist of two components:

### `RelationInputDataManager`

This container component handles data fetching and data normalization for the `RelationInput` component. This has been extracted from
This container component handles data fetching and data normalization for the `RelationInput` component. This has been extracted from
the `RelationInput` so that Strapi is able to move the underlying component into the design-system if the community would need it
(most other input components can be consumed from there).

Expand All @@ -163,7 +163,7 @@ would otherwise have a negative impact on the overall performance of the content
This hook takes care of data-fetching and normalizes results relations aswell as search-results.

```ts
const { relations: RelationResults, search: RelationResults, searchFor } = useRelation(reactQueryCacheKey: string, options: Options);
const { relations: RelationResults, search: RelationResults, searchFor } = useRelation(reactQueryCacheKey: Array<string | object>, options: Options);
```

### `Options`
Expand Down Expand Up @@ -205,10 +205,10 @@ type RelationResults = RelationResult[];

type RelationResult = {
id: number;
href?: string; // based on `shouldAddLink` and the `targetModel`
href?: string; // based on `shouldAddLink` and the `targetModel`
publicationState: 'draft' | 'published';
mainField: string; // will fallback to "id" if not set
}
mainField: string; // will fallback to "id" if not set
};
```

#### `relations`
Expand Down
17 changes: 17 additions & 0 deletions docs/docs/core/database/intro.md
@@ -0,0 +1,17 @@
---
title: Introduction
slug: /database
tags:
- database
---

# Database

This section is an overview of all the features related to the Database package:

```mdx-code-block
import DocCardList from '@theme/DocCardList';
import { useCurrentSidebarCategory } from '@docusaurus/theme-common';
<DocCardList items={useCurrentSidebarCategory().items} />
```
119 changes: 119 additions & 0 deletions docs/docs/core/database/relations/reordering.mdx
@@ -0,0 +1,119 @@
---
title: Relations
slug: /database/relations/reordering
description: Conceptual guide to relations reordering in the Database
tags:
- database
- relations
- reordering
---

Strapi allows you to reorder a relation list.

<img src="/img/database/reordering.png" alt="An example of reordering in the CM" />

This reordering feature is available in the Content Manager and the API.

## Code location

`packages/core/database/lib/entity-manager/relations-orderer.js`

## How is the order stored in DB?

- We store the order value of the relation in an `order` field.
- For bidirectional relations, we store the order value of the other side in an `inverse_order` field.

We store order values for all type of relations, except for:

- Polymorphic relations (too complicated to implement).
- One to one relations (as there is only one relation per pair)

### Many to many (Addresses <-> Categories)

<img src="/img/database/m2m-example.png" alt="many to many relation" />

- `category_order` is the order value of the categories relations in an address entity.
- `address_order` is the order value of the addresses relations in a category entity.

### One to one (Kitchensinks <-> Tags)

<img src="/img/database/o2o-example.png" alt="one to one relation" />

- there is no `order` fields as there is only one relation per pair.

### One way relation (Restaurants <-> Categories)

Where a restaurant has many categories:

<img src="/img/database/mw-example.png" alt="many way relation" />

- `category_order` is the order value of the categories relations in a restaurant entity.
- There is no `restaurant_order` as it is a one way relation.

## How to reorder relations in the DB layer

See more on [Strapi Docs](https://docs.strapi.io/dev-docs/api/rest/relations#connect)

The database layer should receive a payload shown below:

```js
category: {
connect: [
{ id: 6, position: { after: 1} }, // It should be after relation id=1
{ id: 8, position: { end: true }}, // It should be at the end
],
disconnect: [
{ id: 4 }
]
}
```

## How does relations reordering work?

We use fractional indexing. This means that we use decimal numbers to order the relations. See the following diagrams below for a more detailed understanding.

### Simple example

<img src="/img/database/reordering-algo-1.png" alt="An example of reordering in the CM" />

### Complex example

<img src="/img/database/reordering-algo-2.png" alt="An example of reordering in the CM" />

### Algorithm steps

From the `connect` array:

- For every element, **load relations by id**, **from fields `after` or `before`**.
- Start computing based on the `after` and `before` relations:
- **Initialize** with after/before relations (**step 1**). Let's call these ones **init relations.**
- **Apply the updates** from the `connect` array, **sequentially**.
- If the update is of type `before`:
- Place the element with the given `id` **before** the specified element in the list.
- If the specified element is an `init relation`, place the element in between that relation and the one before it.
- To determine the order value, **order = beforeRelation.order - 0.5**. This ensures the element is placed before the `before` relation and after the one before it.
- Else **order = beforeRelation.order**
- If the update is of type `after`:
- Place the element with the given `id` **after** the specified element in the list.
- If the specified element is an `init relation`, place the element in between that relation and the one after it.
- To determine the order value, **order = beforeRelation.order + 0.5**. This ensures the element is placed before the `after` relation and before the one after it.
- Else **order = beforeRelation.order**
- If the update is of type `end`:
- Place at the **end**
- If placing after an init relation: **order = lastRelation.order + 0.5**
- Else **order = lastRelation.order**
- If the update is of type `start`:
-Place at the **start**
- **order = 0.5**
- `before/after`: If the **id does not exist in the current array**, **throw an error**
- If an **id** was **already in this array, remove the previous one**
- **Grouping by the order value**, and ignoring init relations
- Recalculate order values for each group, so there are no repeated numbers & they keep the same order.
- Example : [ {id: 5 , order: 1.5}, {id: 3, order: 1.5 } ][ {id: 5 , order: 1.33}, {id: 3, order: 1.66 } ]
- **Insert values in the database**
- **Update database order based on their order position.** (using ROW_NUMBER() clause)

From the disconnect array:

- Delete the relations from the database.
- Reorder the remaining elements in the database based on their position, using ROW_NUMBER() clause.
4 changes: 4 additions & 0 deletions docs/docs/core/helper-plugin/hooks/use-fetch-client.mdx
Expand Up @@ -39,6 +39,10 @@ const Component = () => {
}
```

:::tip
Remember to use a relative path for your requestURL, following this format `/{yourRelativePath}`
:::

## Methods

Essentially, this is an abstraction around the axios instance exposed by a hook. It provides a simple interface to handle API calls to the Strapi backend.
Expand Down
1 change: 1 addition & 0 deletions docs/docs/core/utils/async.md
Expand Up @@ -16,6 +16,7 @@ Available functions:

- pipeAsync
- mapAsync
- reduceAsync

[See API reference](../../api/Utils) (TODO)

Expand Down
23 changes: 23 additions & 0 deletions docs/docs/how-to-install-packages.md
@@ -0,0 +1,23 @@
---
title: How to install packages
slug: /how-to-install-packages
tags:
- lerna
- packages
---

# Best practices for installing packages in Strapi

When working with the Strapi monorepo, it's important to follow best practices for installing packages to avoid potential issues and ensure consistent results. Instead of using the standard **`yarn add`** command, we recommend using **`yarn lerna add <package_name> --scope @strapi/<module_name>`** for installing packages. Actually, you may encounter the following error using `yarn add`:

`An unexpected error occurred: "expected workspace package to exist for \"@typescript-eslint/typescript-estree\'`

This approach uses Lerna, a tool for managing JavaScript projects with multiple packages, to ensure that the package is installed in the correct location(s) and version across all modules that include it. The **`--scope`** flag specifies the specific module(s) that the package should be installed in, ensuring that it's only installed where it's needed.

By using this method, Strapi developers can avoid issues with mismatched package versions or unnecessary dependencies in certain modules. This can help to keep the codebase clean and maintainable, and reduce the potential for conflicts or issues in the future.

Overall, we recommend using **`yarn lerna add`** with the **`--scope`** flag for installing packages in the Strapi mono repo, to ensure consistent and reliable results.

## Resources

- [Lerna Docs](https://futurestud.io/tutorials/lerna-install-dependencies-for-a-specific-package)
9 changes: 9 additions & 0 deletions docs/sidebars.js
Expand Up @@ -167,6 +167,15 @@ const sidebars = {
},
items: [],
},
{
type: 'category',
label: 'How to install packages in a module',
link: {
type: 'doc',
id: 'how-to-install-packages',
},
items: [],
},
],
api: [{ type: 'autogenerated', dirName: 'api' }],
community: [{ type: 'autogenerated', dirName: 'community' }],
Expand Down
Binary file added docs/static/img/database/m2m-example.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/database/mw-example.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/database/o2o-example.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/database/reordering-algo-1.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/database/reordering-algo-2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/database/reordering.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions examples/getstarted/config/admin.js
Expand Up @@ -6,4 +6,9 @@ module.exports = ({ env }) => ({
apiToken: {
salt: env('API_TOKEN_SALT', 'example-salt'),
},
transfer: {
token: {
salt: env('TRANSFER_TOKEN_SALT', 'example-salt'),
},
},
});

0 comments on commit 7533a8d

Please sign in to comment.