Fix version conflicts
12
.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
vendored
@ -7,6 +7,16 @@ about: Suggest an idea for this project 💡!
|
||||
|
||||
<!-- ⚠️ Make sure to browse the opened and closed issues before submitting your issue. -->
|
||||
|
||||
**What is the expected behavior?**
|
||||
<!--
|
||||
Please also submit your idea on the Strapi Product Board:
|
||||
https://portal.productboard.com/strapi/tabs/2-under-consideration/submit-idea
|
||||
|
||||
If your request on the product board is accepted this feature request issue will be closed,
|
||||
but will still accept public discussion.
|
||||
-->
|
||||
|
||||
- [ ] **I have created my request on the Product Board before I submitted this issue**
|
||||
- [ ] **I have looked at all the other requests on the Product Board before I submitted this issue**
|
||||
|
||||
**Please describe your feature request:**
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@ before_install:
|
||||
- export CHROME_BIN=chromium-browser
|
||||
- export DISPLAY=:99.0
|
||||
- sh -e /etc/init.d/xvfb start
|
||||
- git fetch -a
|
||||
# - sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
|
||||
# - npm cache clean --force
|
||||
# - rm -rf node_modules/
|
||||
@ -21,6 +22,7 @@ install:
|
||||
- npm run setup --debug
|
||||
|
||||
script:
|
||||
- npm run lint
|
||||
- npm run doc
|
||||
|
||||
cache:
|
||||
|
||||
@ -30,7 +30,7 @@ If you send a pull request, please do it against the `master` branch. We are dev
|
||||
***
|
||||
|
||||
## Setup Development Environment
|
||||
To facilitate the contribution, we drastically reduce the amount of commands necessary to install the entire development environment. First of all, you need to check if you're using the recommended versions of Node.js (v8) and npm (v5).
|
||||
To facilitate the contribution, we drastically reduce the amount of commands necessary to install the entire development environment. First of all, you need to check if you're using the [required versions of Node.js and npm](https://strapi.io/documentation/3.x.x/getting-started/installation.html#requirements)
|
||||
|
||||
Then, please follow the instructions below:
|
||||
|
||||
|
||||
@ -137,6 +137,10 @@ For general help using Strapi, please refer to [the official Strapi documentatio
|
||||
|
||||
Follow our [migration guides](https://github.com/strapi/strapi/wiki) on the wiki to keep your projects up-to-date.
|
||||
|
||||
## Roadmap
|
||||
|
||||
Check out our [roadmap](https://portal.productboard.com/strapi) to get informed by the latest feature released and the upcoming ones. You can also give us insights and vote for a specific feature.
|
||||
|
||||
## License
|
||||
|
||||
[MIT License](LICENSE.md) Copyright (c) 2015-2018 [Strapi Solutions](https://strapi.io/).
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
const container = require('markdown-it-container')
|
||||
|
||||
let ogprefix = 'og: http://ogp.me/ns#'
|
||||
let title = 'Strapi Documentation'
|
||||
let description = 'API creation made simple, secure and fast.'
|
||||
let color = '#2F80ED'
|
||||
let author = 'Strapi'
|
||||
let url = 'https://strapi.io/documentation/'
|
||||
|
||||
const ogprefix = 'og: http://ogp.me/ns#'
|
||||
const title = 'Strapi Documentation'
|
||||
const description = 'API creation made simple, secure and fast.'
|
||||
const color = '#2F80ED'
|
||||
const author = 'Strapi'
|
||||
const url = 'https://strapi.io/documentation/'
|
||||
|
||||
module.exports = {
|
||||
head: [
|
||||
@ -40,21 +39,27 @@ module.exports = {
|
||||
title,
|
||||
description,
|
||||
base: '/documentation/',
|
||||
ga: 'UA-54313258-1',
|
||||
themeConfig: {
|
||||
versions: [
|
||||
['Version 3.x.x', '/3.x.x/'],
|
||||
['Version 1.x.x', '/1.x.x/'],
|
||||
],
|
||||
repo: 'strapi/strapi',
|
||||
website: 'https://strapi.io',
|
||||
docsDir: 'docs',
|
||||
editLinks: true,
|
||||
editLinkText: 'Improve this page',
|
||||
serviceWorker: true,
|
||||
hiddenLinks: [
|
||||
'/3.x.x/cli/CLI.html',
|
||||
'/3.x.x/api-reference/reference.html',
|
||||
],
|
||||
sidebar: {
|
||||
'/3.x.x/': [
|
||||
{
|
||||
collapsable: false,
|
||||
title: 'Getting started',
|
||||
title: '🚀 Getting started',
|
||||
children: [
|
||||
'/3.x.x/getting-started/installation',
|
||||
'/3.x.x/getting-started/quick-start',
|
||||
@ -62,39 +67,31 @@ module.exports = {
|
||||
],
|
||||
},
|
||||
{
|
||||
collapsable: false,
|
||||
title: 'Guides',
|
||||
collapsable: true,
|
||||
title: '💡 Guides',
|
||||
children: [
|
||||
'/3.x.x/guides/authentication.md',
|
||||
'/3.x.x/configurations/configurations.md',
|
||||
'/3.x.x/guides/controllers.md',
|
||||
'/3.x.x/guides/deployment.md',
|
||||
'/3.x.x/guides/email.md',
|
||||
'/3.x.x/guides/upload.md',
|
||||
'/3.x.x/guides/filters.md',
|
||||
'/3.x.x/guides/graphql.md',
|
||||
'/3.x.x/guides/i18n.md',
|
||||
'/3.x.x/guides/models.md',
|
||||
'/3.x.x/guides/policies.md',
|
||||
'/3.x.x/guides/public-assets.md',
|
||||
'/3.x.x/guides/requests.md',
|
||||
'/3.x.x/guides/responses.md',
|
||||
'/3.x.x/guides/routing.md',
|
||||
'/3.x.x/guides/services.md',
|
||||
],
|
||||
},
|
||||
{
|
||||
collapsable: false,
|
||||
title: 'Globals',
|
||||
children: [
|
||||
'/3.x.x/api-reference/reference',
|
||||
'/3.x.x/cli/CLI',
|
||||
'/3.x.x/guides/authentication',
|
||||
'/3.x.x/configurations/configurations',
|
||||
'/3.x.x/guides/controllers',
|
||||
'/3.x.x/guides/deployment',
|
||||
'/3.x.x/guides/email',
|
||||
'/3.x.x/guides/upload',
|
||||
'/3.x.x/guides/filters',
|
||||
'/3.x.x/guides/graphql',
|
||||
'/3.x.x/guides/i18n',
|
||||
'/3.x.x/guides/models',
|
||||
'/3.x.x/guides/policies',
|
||||
'/3.x.x/guides/public-assets',
|
||||
'/3.x.x/guides/requests',
|
||||
'/3.x.x/guides/responses',
|
||||
'/3.x.x/guides/routing',
|
||||
'/3.x.x/guides/services',
|
||||
'/3.x.x/guides/webhooks',
|
||||
],
|
||||
},
|
||||
{
|
||||
collapsable: false,
|
||||
title: 'Advanced',
|
||||
collapsable: true,
|
||||
title: '⚙️️ Advanced',
|
||||
children: [
|
||||
'/3.x.x/advanced/customize-admin',
|
||||
'/3.x.x/advanced/hooks',
|
||||
@ -103,9 +100,36 @@ module.exports = {
|
||||
'/3.x.x/advanced/usage-tracking',
|
||||
],
|
||||
},
|
||||
{
|
||||
collapsable: true,
|
||||
title: '🔌 Plugin Development',
|
||||
children: [
|
||||
'/3.x.x/plugin-development/quick-start',
|
||||
'/3.x.x/plugin-development/plugin-architecture',
|
||||
'/3.x.x/plugin-development/backend-development',
|
||||
'/3.x.x/plugin-development/frontend-development',
|
||||
'/3.x.x/plugin-development/frontend-use-cases',
|
||||
'/3.x.x/plugin-development/utils',
|
||||
// '/3.x.x/plugin-development/ui-components', TODO: Add this file
|
||||
],
|
||||
},
|
||||
{
|
||||
collapsable: true,
|
||||
title: '💻 Command Line Interface',
|
||||
children: [
|
||||
'/3.x.x/cli/CLI',
|
||||
],
|
||||
},
|
||||
{
|
||||
collapsable: true,
|
||||
title: '🏗 API Reference',
|
||||
children: [
|
||||
'/3.x.x/api-reference/reference',
|
||||
],
|
||||
},
|
||||
{
|
||||
collapsable: false,
|
||||
title: 'Resources',
|
||||
title: '📚 Resources',
|
||||
children: [
|
||||
['https://github.com/strapi/strapi/blob/master/CONTRIBUTING.md', 'Contributing guide'],
|
||||
['https://github.com/strapi/strapi/wiki', 'Migration guides'],
|
||||
|
||||
@ -5,14 +5,7 @@
|
||||
@touchend="onTouchEnd">
|
||||
<Navbar v-if="shouldShowNavbar" @toggle-sidebar="toggleSidebar"/>
|
||||
<div class="sidebar-mask" @click="toggleSidebar(false)"></div>
|
||||
<Sidebar :items="sidebarItems" @toggle-sidebar="toggleSidebar">
|
||||
<div slot="top">
|
||||
<select @input="changeVersion($event.target.value)" class="version-selector">
|
||||
<option v-for="version in versions" :value="version.path" :selected="!!~$page.path.indexOf(version.path)">{{version.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<slot name="sidebar-bottom" slot="bottom"/>
|
||||
</Sidebar>
|
||||
<Sidebar :items="sidebarItems" @toggle-sidebar="toggleSidebar" />
|
||||
<div class="custom-layout" v-if="$page.frontmatter.layout">
|
||||
<component :is="$page.frontmatter.layout"/>
|
||||
</div>
|
||||
|
||||
@ -9,11 +9,19 @@
|
||||
<NavLink v-else :item="item"/>
|
||||
</div>
|
||||
<!-- repo link -->
|
||||
<a v-if="repoLink"
|
||||
:href="repoLink"
|
||||
<a
|
||||
:href="websiteLink"
|
||||
class="repo-link"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer">
|
||||
Website
|
||||
<OutboundLink/>
|
||||
</a>
|
||||
<a v-if="repoLink"
|
||||
:href="repoLink"
|
||||
class="repo-link"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer">
|
||||
{{ repoLabel }}
|
||||
<OutboundLink/>
|
||||
</a>
|
||||
@ -92,6 +100,22 @@ export default {
|
||||
}
|
||||
|
||||
return 'Source'
|
||||
},
|
||||
websiteLink () {
|
||||
const { website } = this.$site.themeConfig
|
||||
if (website) {
|
||||
return /^https?:/.test(website)
|
||||
? website
|
||||
: `https://${website}`
|
||||
}
|
||||
},
|
||||
slackLink () {
|
||||
const { slack } = this.$site.themeConfig
|
||||
if (slack) {
|
||||
return /^https?:/.test(slack)
|
||||
? slack
|
||||
: `https://${slack}`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,9 @@
|
||||
{{ $siteTitle }}
|
||||
</span>
|
||||
</router-link>
|
||||
<select @input="changeVersion($event.target.value)" class="version-selector">
|
||||
<option v-for="version in versions" :value="version.path" :selected="!!~$page.path.indexOf(version.path)">{{version.name}}</option>
|
||||
</select>
|
||||
<div class="links">
|
||||
<AlgoliaSearchBox v-if="isAlgoliaSearch" :options="algolia"/>
|
||||
<SearchBox v-else-if="$site.themeConfig.search !== false"/>
|
||||
@ -28,12 +31,24 @@ import NavLinks from './NavLinks.vue'
|
||||
export default {
|
||||
components: { SidebarButton, NavLinks, SearchBox, AlgoliaSearchBox },
|
||||
computed: {
|
||||
versions() {
|
||||
const { themeConfig } = this.$site
|
||||
return themeConfig.versions.map(version => ({
|
||||
name: version[0],
|
||||
path: version[1],
|
||||
}))
|
||||
},
|
||||
algolia () {
|
||||
return this.$themeLocaleConfig.algolia || this.$site.themeConfig.algolia || {}
|
||||
},
|
||||
isAlgoliaSearch () {
|
||||
return this.algolia && this.algolia.apiKey && this.algolia.indexName
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeVersion(to) {
|
||||
this.$router.push(to)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -10,7 +10,9 @@
|
||||
@blur="focused = false"
|
||||
@keyup.enter="go(focusIndex)"
|
||||
@keyup.up="onUp"
|
||||
@keyup.down="onDown">
|
||||
@keyup.down="onDown"
|
||||
placeholder="Search"
|
||||
>
|
||||
<ul class="suggestions"
|
||||
v-if="showSuggestions"
|
||||
:class="{ 'align-right': alignRight }"
|
||||
@ -63,8 +65,10 @@ export default {
|
||||
for (let i = 0; i < pages.length; i++) {
|
||||
if (res.length >= max) break
|
||||
const p = pages[i]
|
||||
// filter out results that do not match current ersion context
|
||||
if (~p.path.slice(1).indexOf(searchContext)) continue
|
||||
// filter out results that do not match current version context
|
||||
if ( ! p.path.startsWith(searchContext, 1)) {
|
||||
continue;
|
||||
}
|
||||
// filter out results that do not match current locale
|
||||
if (this.getPageLocalePath(p) !== localePath) continue
|
||||
if (matches(p)) {
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<DropdownTransition>
|
||||
<ul class="sidebar-group-items" ref="items" v-if="open || !collapsable">
|
||||
<li v-for="child in item.children">
|
||||
<SidebarLink :item="child"/>
|
||||
<SidebarLink :item="child" :open="open" :collapsable="collapsable"/>
|
||||
</li>
|
||||
</ul>
|
||||
</DropdownTransition>
|
||||
|
||||
@ -5,8 +5,8 @@ import AppLink from './AppLink'
|
||||
export default {
|
||||
functional: true,
|
||||
components: {AppLink},
|
||||
props: ['item'],
|
||||
render (h, { parent: { $page, $site, $route }, props: { item }}) {
|
||||
props: ['item', 'open', 'collapsable'],
|
||||
render (h, { parent: { $page, $site, $route }, props: { item, open, collapsable }}) {
|
||||
// use custom active class matching logic
|
||||
// due to edge case of paths ending with / + hash
|
||||
const selfActive = isActive($route, item.path)
|
||||
@ -15,7 +15,8 @@ export default {
|
||||
const active = item.type === 'auto'
|
||||
? selfActive || item.children.some(c => isActive($route, item.basePath + '#' + c.slug))
|
||||
: selfActive
|
||||
const link = renderLink(h, item.path, item.title || item.path, active)
|
||||
const hidden = $site.themeConfig.hiddenLinks.includes(item.path);
|
||||
const link = renderLink(h, item.path, item.title || item.path, active, hidden)
|
||||
const configDepth = $page.frontmatter.sidebarDepth != null
|
||||
? $page.frontmatter.sidebarDepth
|
||||
: $site.themeConfig.sidebarDepth
|
||||
@ -25,13 +26,16 @@ export default {
|
||||
} else if (active && item.headers && !hashRE.test(item.path)) {
|
||||
const children = groupHeaders(item.headers)
|
||||
return [link, renderChildren(h, children, item.path, $route, maxDepth)]
|
||||
} else if (collapsable && open && hidden && !active && item.headers && !hashRE.test(item.path)) {
|
||||
const children = groupHeaders(item.headers)
|
||||
return [link, renderChildren(h, children, item.path, $route, maxDepth)]
|
||||
} else {
|
||||
return link
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function renderLink (h, to, text, active) {
|
||||
function renderLink (h, to, text, active, hidden) {
|
||||
if (~to.indexOf('http')) return h('a',
|
||||
{
|
||||
attrs: {
|
||||
@ -48,6 +52,7 @@ function renderLink (h, to, text, active) {
|
||||
},
|
||||
class: {
|
||||
active,
|
||||
hidden,
|
||||
'sidebar-link': true
|
||||
}
|
||||
}, text)
|
||||
@ -58,7 +63,7 @@ function renderChildren (h, children, path, route, maxDepth, depth = 1) {
|
||||
return h('ul', { class: 'sidebar-sub-headers' }, children.map(c => {
|
||||
const active = isActive(route, path + '#' + c.slug)
|
||||
return h('li', { class: 'sidebar-sub-header' }, [
|
||||
renderLink(h, '#' + c.slug, c.title, active),
|
||||
renderLink(h, path + '#' + c.slug, c.title, active),
|
||||
renderChildren(h, c.children, path, route, maxDepth, depth + 1)
|
||||
])
|
||||
}))
|
||||
@ -87,6 +92,8 @@ a.sidebar-link
|
||||
font-weight 600
|
||||
color $accentColor
|
||||
border-left-color $accentColor
|
||||
&.hidden
|
||||
display: none
|
||||
.sidebar-group &
|
||||
padding-left 2rem
|
||||
.sidebar-sub-headers &
|
||||
|
||||
@ -8,7 +8,7 @@ $arrowBgColor = #ccc
|
||||
// layout
|
||||
$navbarHeight = 3.6rem
|
||||
$sidebarWidth = 20rem
|
||||
$contentWidth = 740px
|
||||
$contentWidth = 800px
|
||||
|
||||
// responsive breakpoints
|
||||
$MQNarrow = 959px
|
||||
|
||||
@ -27,9 +27,8 @@ a img + svg
|
||||
display none !important
|
||||
|
||||
.version-selector
|
||||
margin 1em 1em 0 1.5em
|
||||
margin-left 1.5rem
|
||||
color lighten($textColor, 25%)
|
||||
display block
|
||||
border 1px solid darken($borderColor, 10%)
|
||||
font-size .9rem
|
||||
line-height 2rem
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
The hooks are modules that add functionality to the core. They are loaded during the server boot. For example, if your project needs to work with a SQL database, your will have to add the hook `strapi-hook-bookshelf` to be able to connect your app with your database.
|
||||
|
||||
**Path —** `./hooks/documentation/lib/index.js`.
|
||||
**File structure**
|
||||
```js
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
@ -15,9 +15,7 @@ module.exports = strapi => {
|
||||
*/
|
||||
|
||||
defaults: {
|
||||
documentation: {
|
||||
path: '/public/documentation'
|
||||
}
|
||||
// config object
|
||||
},
|
||||
|
||||
/**
|
||||
@ -25,28 +23,11 @@ module.exports = strapi => {
|
||||
*/
|
||||
|
||||
initialize: cb => {
|
||||
try {
|
||||
// Check if documentation folder exist.
|
||||
fs.accessSync(path.resolve(process.cwd(), this.defaults.documentation.path));
|
||||
} catch (e) {
|
||||
// Otherwise, create the folder.
|
||||
fs.mkdirSync(path.resolve(process.cwd(), this.defaults.documentation.path));
|
||||
}
|
||||
// Write your code here.
|
||||
|
||||
// This function doesn't really exist,
|
||||
// it's just an example to tell you that you
|
||||
// run your business logic and when it's done
|
||||
// you just need to call the callback `cb`
|
||||
generateDocumentation(path.resolve(process.cwd(), this.defaults.documentation.path), function(err) {
|
||||
if (err) {
|
||||
// Error: it will display the error to the user
|
||||
// and the hook won't be loaded.
|
||||
return cb(err);
|
||||
}
|
||||
// this.defaults['your_config'] to access to your configs.
|
||||
|
||||
// Success.
|
||||
cb();
|
||||
});
|
||||
cb();
|
||||
}
|
||||
};
|
||||
|
||||
@ -57,14 +38,18 @@ module.exports = strapi => {
|
||||
- `defaults` (object): Contains the defaults configurations. This object is merged to `strapi.config.hook.settings.**`.
|
||||
- `initialize` (function): Called during the server boot. The callback `cb` needs to be called. Otherwise, the hook won't be loaded.
|
||||
|
||||
Every folder that follows this name pattern `strapi-*` in your `./node_modules` folder will be loaded as a hook. The hooks are accessible through the `strapi.hook` variable.
|
||||
The hooks are accessible through the `strapi.hook` variable.
|
||||
|
||||
## Structure
|
||||
|
||||
### Node modules
|
||||
|
||||
Every folder that follows this name pattern `strapi-hook-*` in your `./node_modules` folder will be loaded as a hook.
|
||||
|
||||
A hook needs to follow the structure below:
|
||||
|
||||
```
|
||||
/hook
|
||||
/strapi-hook-[...]
|
||||
└─── lib
|
||||
- index.js
|
||||
- LICENSE.md
|
||||
@ -74,6 +59,40 @@ A hook needs to follow the structure below:
|
||||
|
||||
The `index.js` is the entry point to your hook. It should look like the example above.
|
||||
|
||||
### Custom hooks
|
||||
|
||||
The framework allows to load hooks from the project directly without having to install them from npm. It's great way to take advantage of the features of the hooks system for code that doesn't need to be shared between apps. To achieve this, you have to create a `./hooks` folder at the root of your project and put the hooks into it.
|
||||
|
||||
```
|
||||
/project
|
||||
└─── admin
|
||||
└─── api
|
||||
└─── config
|
||||
└─── hooks
|
||||
│ └─── strapi-documentation
|
||||
│ - index.js
|
||||
│ └─── strapi-server-side-rendering
|
||||
│ - index.js
|
||||
└─── plugins
|
||||
└─── public
|
||||
- favicon.ico
|
||||
- package.json
|
||||
- server.js
|
||||
```
|
||||
|
||||
## Configuration and activation
|
||||
|
||||
To activate and configure your hook with custom options, you need to edit your `./config/hooks.json` file in your Strapi app.
|
||||
```javascript
|
||||
{
|
||||
...
|
||||
"hook-name": {
|
||||
"enabled": true,
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
It happens that a hook has a dependency to another one. For example, the `strapi-hook-bookshelf` has a dependency to `strapi-hook-knex`. Without it, the `strapi-hook-bookshelf` can't work correctly. It also means that the `strapi-hook-knex` hook has to be loaded before.
|
||||
@ -95,24 +114,3 @@ To handle this case, you need to update the `package.json` at the root of your h
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Custom hooks
|
||||
|
||||
The framework allows to load hooks from the project directly without having to install them from npm. It's great way to take advantage of the features of the hooks system for code that doesn't need to be shared between apps. To achieve this, you have to create a `./hooks` folder at the root of your project and put the hooks into it.
|
||||
|
||||
```
|
||||
/project
|
||||
└─── admin
|
||||
└─── api
|
||||
└─── config
|
||||
└─── hooks
|
||||
│ └─── strapi-documentation
|
||||
│ - index.js
|
||||
│ └─── strapi-server-side-rendering
|
||||
│ - index.js
|
||||
└─── plugins
|
||||
└─── public
|
||||
- favicon.ico
|
||||
- package.json
|
||||
- server.js
|
||||
```
|
||||
|
||||
BIN
docs/3.x.x/assets/getting-started_add_entry-.png
Normal file
|
After Width: | Height: | Size: 260 KiB |
|
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 601 KiB |
|
Before Width: | Height: | Size: 288 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 462 KiB |
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 440 KiB |
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 432 KiB |
BIN
docs/3.x.x/assets/getting-started_no_entry_.png
Normal file
|
After Width: | Height: | Size: 435 KiB |
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 455 KiB |
BIN
docs/3.x.x/assets/getting-started_with_entry_.png
Normal file
|
After Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 254 KiB After Width: | Height: | Size: 64 KiB |
@ -182,7 +182,7 @@ strapi generate:plugin <name>
|
||||
Example: `strapi generate:plugin user` will create the plugin at `./plugins/user`.
|
||||
|
||||
|
||||
Please refer to the [plugin develoment documentation](../plugin-development/quick-start.md) to know more.
|
||||
Please refer to the [plugin development documentation](../plugin-development/quick-start.md) to know more.
|
||||
|
||||
***
|
||||
|
||||
|
||||
@ -363,7 +363,7 @@ The session doesn't work with `mongo` as a client. The package that we should us
|
||||
- `port` (integer): Port on which the server should be running. Default value: `1337`.
|
||||
- `autoReload`
|
||||
- `enabled` (boolean): Enable or disabled server reload on files update. Default value: depends on the environment.
|
||||
- `emitErrors` (boolean): Enable errors to be emited to `koa` when they happen in order to attach custom logic or use error reporting services.
|
||||
- `emitErrors` (boolean): Enable errors to be emitted to `koa` when they happen in order to attach custom logic or use error reporting services.
|
||||
- `proxy`
|
||||
- `enabled` (boolean): Enable proxy support such as Apache or Nginx. Default value: `false`.
|
||||
- `ssl` (boolean): Enable proxy SSL support
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
# Installation
|
||||
|
||||
Installation is very easy and only takes a few seconds.
|
||||
### 👋 Welcome onboard!
|
||||
|
||||
You recently discovered Strapi and look forward to give it a try? Let's start with the installation!
|
||||
|
||||
## Requirements
|
||||
|
||||
@ -8,10 +10,11 @@ Please make sure your computer/server meets the following requirements:
|
||||
- [Node.js](https://nodejs.org) >= 10.x: Node.js is a server platform which runs JavaScript. Installation guide [here](https://nodejs.org/en/download/).
|
||||
- [NPM](https://www.npmjs.com/) >= 6.x: NPM is the package manager for Javascript. Installation guide [here](https://nodejs.org/en/download/).
|
||||
*(Make sure the database that you are using meets the requirement.)*
|
||||
- [MongoDB](https://www.mongodb.com/) >= 3.x: MongoDB is a powerful document store. Installation guide [here](https://www.mongodb.com/download-center?j#community).
|
||||
- [MySQL](https://www.mysql.com/) >= 5.6: MySQL is an open-source relational database management system. Installation guide [here](https://dev.mysql.com/downloads/).
|
||||
- [MariaDB](https://mariadb.org/) >= 10.1: MarialDB is a fork of MySQL and is guaranteed to stay open source. Installation guide [here](https://mariadb.org/download/).
|
||||
- [PostgreSQL](https://www.postgresql.org/) >= 10: PostgreSQL is an open-source object-relational database management system. Installation guide [here](https://www.postgresql.org/download/).
|
||||
- The database of your choice:
|
||||
- [MongoDB](https://www.mongodb.com/) >= 3.x: MongoDB is a powerful document store. Installation guide [here](https://www.mongodb.com/download-center?j#community).
|
||||
- [MySQL](https://www.mysql.com/) >= 5.6: MySQL is an open-source relational database management system. Installation guide [here](https://dev.mysql.com/downloads/).
|
||||
- [MariaDB](https://mariadb.org/) >= 10.1: MarialDB is a fork of MySQL and is guaranteed to stay open source. Installation guide [here](https://mariadb.org/download/).
|
||||
- [PostgreSQL](https://www.postgresql.org/) >= 10: PostgreSQL is an open-source object-relational database management system. Installation guide [here](https://www.postgresql.org/download/).
|
||||
|
||||
## Setup
|
||||
|
||||
@ -27,7 +30,7 @@ If you encounter npm permissions issues, [change the permissions to npm default
|
||||
|
||||
It takes about 20 seconds with a good Internet connection. You can take a coffee ☕️ if you have a slow one.
|
||||
|
||||
Having troubles during the installation? Check if someone already had the same issue https://github.com/strapi/strapi/issues. If not, you can [post one](https://github.com/strapi/strapi/issues/new), or ask for help https://strapi.io/support.
|
||||
Having troubles during the installation? Check if someone already had the [same issue](https://github.com/strapi/strapi/issues). If not, please [post one](https://github.com/strapi/strapi/issues/new).
|
||||
|
||||
## Check installation
|
||||
|
||||
@ -43,4 +46,4 @@ Strapi is installed globally on your computer. Type `strapi` in your terminal yo
|
||||
|
||||
***
|
||||
|
||||
Congrats! Now that Strapi is installed you can [create your first API](quick-start.md).
|
||||
👏 Congrats, you are all set! Now that Strapi is installed you can [create your first project](quick-start.md).
|
||||
|
||||
@ -3,22 +3,21 @@
|
||||
This section explains how to handle Strapi for the first time, ([check out our tutorial video](https://www.youtube.com/watch?v=yMl5IcFHA74)).
|
||||
|
||||
**Table of contents:**
|
||||
- [Quick start](#quick-start)
|
||||
- [Create your first project](#create-your-first-project)
|
||||
- [Create your first user](#create-your-first-user)
|
||||
- [Create your first API](#create-your-first-api)
|
||||
- [Files structure](#files-structure)
|
||||
- [Manage your data](#manage-your-data)
|
||||
- [Consume your API](#consume-your-api)
|
||||
- [List entries (GET)](#list-entries-get)
|
||||
- [Get a specific entry (GET)](#get-a-specific-entry-get)
|
||||
- [Create data (POST)](#create-data-post)
|
||||
- [Update data (PUT)](#update-data-put)
|
||||
- [Delete data (DELETE)](#delete-data-delete)
|
||||
- [1. Create your first project](#_1-create-a-project)
|
||||
- [2. Create your first user](#_2-register-the-first-user)
|
||||
- [3. Create your first Content Type](#_3-create-a-content-type)
|
||||
- [Files structure](#files-structure)
|
||||
- [4. Manage your data](#_4-add-content)
|
||||
- [5. Consume your API](#_5-consume-the-api)
|
||||
- [List entries (GET)](#list-entries-get)
|
||||
- [Get a specific entry (GET)](#get-a-specific-entry-get)
|
||||
- [Create data (POST)](#create-data-post)
|
||||
- [Update data (PUT)](#update-data-put)
|
||||
- [Delete data (DELETE)](#delete-data-delete)
|
||||
|
||||
***
|
||||
|
||||
## Create your first project
|
||||
## 1. Create a project
|
||||
|
||||
Creating your first project with Strapi is easy:
|
||||
|
||||
@ -34,6 +33,10 @@ strapi new my-project
|
||||
|
||||

|
||||
|
||||
::: note
|
||||
The CLI will ask you to choose your database: select MongoDB, Postgres or MySQL. Then, fill the database information in. The default values should work if you correctly installed the database system on your machine.
|
||||
:::
|
||||
|
||||
This action creates a new folder named `my-project` with the entire [files structure](../concepts/concepts.md#files-structure) of a Strapi application.
|
||||
|
||||
**#3 — Go to your project and launch the server:**
|
||||
@ -47,44 +50,42 @@ strapi start
|
||||
|
||||

|
||||
|
||||
Now that your app is running let's see how to [create your first user](#create-your-first-user).
|
||||
Now that your app is running let's see how to [create your first user](#_2-register-the-first-user).
|
||||
|
||||
***
|
||||
|
||||
## Create your first user
|
||||
## 2. Register the first user
|
||||
|
||||
In order to use the admin panel and to consume your API you first need to register your first user. This process only happens once if you don't have any user table created and is made to create the `admin user` that has all the permissions granted for your API.
|
||||
In order to use the admin panel and to consume your API you first need to register your first user. This process only happens once and is made to create the `admin user` who has all the permissions granted.
|
||||
|
||||
If your using MongoDB for your database you don't have to create your table manually (it's already handled by Strapi) otherwise you'll have to create your user table first.
|
||||
|
||||
To create your first user, start your server (`strapi start`) and go to : http://localhost:1337/admin.
|
||||
To create your first user, start your server (`strapi start`) and go to [http://localhost:1337/admin](http://localhost:1337/admin).
|
||||
|
||||

|
||||
|
||||
|
||||
Now that your first user is registered let's see how to [create your first api](#create-your-first-api).
|
||||
Now that your first user is registered let's see how to [create your first Content Type](#_3-create-a-content-type).
|
||||
|
||||
***
|
||||
## Create your first API
|
||||
|
||||
To create your first API, start your server (`strapi start`) and go to : http://localhost:1337/admin.
|
||||
## 3. Create a Content Type
|
||||
|
||||
At this point, your application is empty. To create your first API is to use the **Content Type Builder** plugin: a powerful UI to help you create an API in a few clicks. Let's take the example of an e-commerce API, which manages products.
|
||||
At this point, your project is empty. To create your first Content Type, you are going to use the **Content Type Builder** plugin: a powerful UI to help defining your Content Type's structure within a few clicks. Let's take the example of blog, which manages posts.
|
||||
|
||||
**#1 —** Go to the **Content Type Builder** plugin.
|
||||
|
||||

|
||||
|
||||
**#2 —** Create a Content Type named `Product` and submit the form.
|
||||
**#2 —** Create a Content Type named `Post` and submit the form.
|
||||
|
||||

|
||||
|
||||
**#3 —** Add three fields in this Content Type.
|
||||
|
||||
- A `string` field named `name`.
|
||||
- A `text` field named `description`.
|
||||
- A `number` field named `price` (with `float` as number format).
|
||||
- A `string` field named `title`.
|
||||
- A `text` field named `content` (tick the `Display as WYSIWYG` in the `Advanced Settings` tab).
|
||||
- A `media` field named `cover`.
|
||||
|
||||

|
||||

|
||||
|
||||
**#4 —** Save. That's it!
|
||||
|
||||
@ -95,22 +96,22 @@ See the [CLI documentation](../cli/CLI.md#strapi-generateapi) for more informati
|
||||
|
||||
### Files structure
|
||||
|
||||
A new directory has been created in the `./api` folder of your application which contains all the needed stuff for your `Product` Content Type: routes, controllers, services and models. Take a look at the [API structure documentation](../concepts/concepts.md#files-structure) for more informations.
|
||||
A new directory has been created in the `./api` folder of your application which contains all the needed stuff for your `Post` Content Type: routes, controllers, services and models. Take a look at the [API structure documentation](../concepts/concepts.md#files-structure) for more informations.
|
||||
|
||||
|
||||
**Well done, you created your first API using Strapi!**
|
||||
**Well done, you created your first Content Type using Strapi!**
|
||||
|
||||
***
|
||||
|
||||
## Manage your data
|
||||
## 4. Add content
|
||||
|
||||
After creating [your first Content Type](#create-your-first-api), it would be great to be able to create, edit or delete entries.
|
||||
After creating [your first Content Type](#_3-create-a-content-type), you probably want to create, edit or delete entries. No worries, everything is ready for you:
|
||||
|
||||
**#1 —** Go to the [**Product list**](http://localhost:1337/admin/plugins/content-manager/product/) by clicking on the link in the left menu (generated by the **Content Manager** plugin).
|
||||
**#1 —** Go to the [**Post list**](http://localhost:1337/admin/plugins/content-manager/post/) by clicking on the link in the left menu (generated by the **Content Manager** plugin).
|
||||
|
||||

|
||||
|
||||
**#2 —** Click on the button `Add New Product` and fill the form.
|
||||
**#2 —** Click on the button `Add New Post` and fill the form.
|
||||
|
||||

|
||||
|
||||
@ -120,125 +121,161 @@ After creating [your first Content Type](#create-your-first-api), it would be gr
|
||||
|
||||
***
|
||||
|
||||
## Consume your API
|
||||
## 5. Consume the API
|
||||
|
||||
Your API is now ready and [contains data](#manage-your-data). At this point, you'll probably want to use this data in mobile or desktop applications.
|
||||
In order to do so, you'll need to allow access to other users (identified as 'Guest').
|
||||
Your API is now ready and [contains data](#_4-add-content). At this point, you'll probably want to use this data in mobile or desktop applications.
|
||||
In order to do so, you'll need to allow access to other users (identified as 'Public').
|
||||
|
||||
**1 -** Go to the [**Auth & Permissions View**](http://localhost:1337/admin/plugins/users-permissions/roles) by clicking on **Auth & Permissions** link in the left menu and click on the **Guest Role** item.
|
||||
**1 -** Go to the [**Roles & Permissions View**](http://localhost:1337/admin/plugins/users-permissions/roles) by clicking on **Roles & Permissions** link in the left menu.
|
||||
|
||||

|
||||
|
||||
**2 -** Manage your APIs permissions in the **Permissions** section of the [**Edit Guest Role view**](http://localhost:1337/admin/plugins/users-permissions/roles/edit/1) by enabling or disabling specific actions.
|
||||
**2 -** Click on the `Public` role, enable the actions related to your new Content Type and save:
|
||||
|
||||

|
||||

|
||||
|
||||
::: note
|
||||
You should now be able to get the list of posts from the API: [http://localhost:1337/posts](http://localhost:1337/posts).
|
||||
:::
|
||||
|
||||
### List entries (GET)
|
||||
|
||||
To retrieve the list of products, use the `GET /products` route.
|
||||
To retrieve the list of posts, use the `GET /posts` route.
|
||||
|
||||
Generated APIs provide a handy way to filter and order queries. In that way, ordering products by price is as easy as `GET http://localhost:1337/products?_sort=price:asc`. For more informations, read the [filters documentation](../guides/filters.md)
|
||||
Generated APIs provide a handy way to filter and order queries. In that way, ordering posts by price is as easy as `GET http://localhost:1337/posts?_sort=price:asc`. For more informations, read the [filters documentation](../guides/filters.md).
|
||||
|
||||
Here is an example using jQuery.
|
||||
Here is an example using Axios:
|
||||
|
||||
```js
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: 'http://localhost:1337/products?_sort=price:asc', // Order by price.
|
||||
done: function(products) {
|
||||
console.log('Well done, here is the list of products: ', products);
|
||||
},
|
||||
fail: function(error) {
|
||||
import axios from 'axios';
|
||||
|
||||
// Request API.
|
||||
axios
|
||||
.get('http://localhost:1337/posts', {
|
||||
params: {
|
||||
_sort: 'createdAt:desc' // Generates http://localhost:1337/posts?_sort=createdAt:desc
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
// Handle success.
|
||||
console.log('Well done, here is the list of posts: ', response.data);
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
}
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Get a specific entry (GET)
|
||||
|
||||
If you want to get a specific entry, add the `id` of the wanted product at the end of the url.
|
||||
If you want to get a specific entry, add the `id` of the wanted post at the end of the url.
|
||||
|
||||
Examble with Axios:
|
||||
|
||||
```js
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: 'http://localhost:1337/products/123', // Where `123` is the `id` of the product.
|
||||
done: function(product) {
|
||||
console.log('Well done, here is the product having the `id` 123: ', product);
|
||||
},
|
||||
fail: function(error) {
|
||||
import axios from 'axios';
|
||||
|
||||
const postId = 'YOUR_POST_ID_HERE'; // Replace with one of your posts id.
|
||||
|
||||
// Request API.
|
||||
axios
|
||||
.get(`http://localhost:1337/posts/${postId}`)
|
||||
.then(response => {
|
||||
// Handle success.
|
||||
console.log('Well done, here is the post: ', response.data);
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
}
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Create data (POST)
|
||||
|
||||
Use the `POST` route to create a new entry.
|
||||
|
||||
jQuery example:
|
||||
Examble with Axios:
|
||||
|
||||
```js
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'http://localhost:1337/products',
|
||||
data: {
|
||||
name: 'Cheese cake',
|
||||
description: 'Chocolate cheese cake with ice cream',
|
||||
price: 5
|
||||
},
|
||||
done: function(product) {
|
||||
console.log('Congrats, your product has been successfully created: ', product); // Remember the product `id` for the next steps.
|
||||
},
|
||||
fail: function(error) {
|
||||
import axios from 'axios';
|
||||
|
||||
// Request API.
|
||||
axios
|
||||
.post(`http://localhost:1337/posts/`, {
|
||||
title: 'My new post'
|
||||
})
|
||||
.then(response => {
|
||||
// Handle success.
|
||||
console.log(
|
||||
'Well done, your post has been successfully created: ',
|
||||
response.data
|
||||
);
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
}
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Update data (PUT)
|
||||
|
||||
Use the `PUT` route to update an existing entry.
|
||||
|
||||
jQuery example:
|
||||
Examble with Axios:
|
||||
|
||||
```js
|
||||
$.ajax({
|
||||
type: 'PUT',
|
||||
url: 'http://localhost:1337/products/123', // Where `123` is the `id` of the product.
|
||||
data: {
|
||||
description: 'This is the new description'
|
||||
},
|
||||
done: function(product) {
|
||||
console.log('Congrats, your product has been successfully updated: ', product.description);
|
||||
},
|
||||
fail: function(error) {
|
||||
import axios from 'axios';
|
||||
|
||||
const postId = 'YOUR_POST_ID_HERE'; // Replace with one of your posts id.
|
||||
|
||||
// Request API.
|
||||
axios
|
||||
.put(`http://localhost:1337/posts/${postId}`, {
|
||||
title: 'Updated title'
|
||||
})
|
||||
.then(response => {
|
||||
// Handle success.
|
||||
console.log(
|
||||
'Well done, your post has been successfully updated: ',
|
||||
response.data
|
||||
);
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
}
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Delete data (DELETE)
|
||||
|
||||
Use the `DELETE` route to delete an existing entry.
|
||||
|
||||
jQuery example:
|
||||
Examble with Axios:
|
||||
|
||||
```js
|
||||
$.ajax({
|
||||
type: 'DELETE',
|
||||
url: 'http://localhost:1337/products/123', // Where `123` is the `id` of the product.
|
||||
done: function(product) {
|
||||
console.log('Congrats, your product has been successfully deleted: ', product);
|
||||
},
|
||||
fail: function(error) {
|
||||
console.log('An error occurred:', error);
|
||||
}
|
||||
});
|
||||
```
|
||||
import axios from 'axios';
|
||||
|
||||
const postId = 'YOUR_POST_ID_HERE'; // Replace with one of your posts id.
|
||||
|
||||
// Request API.
|
||||
axios
|
||||
.delete(`http://localhost:1337/posts/${postId}`)
|
||||
.then(response => {
|
||||
// Handle success.
|
||||
console.log(
|
||||
'Well done, your post has been successfully updated: ',
|
||||
response.data
|
||||
);
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
});
|
||||
```
|
||||
***
|
||||
|
||||
Congratulations! You successfully finished the Getting Started guide! Read the [concepts](../concepts/concepts.md) to understand more advanced concepts.
|
||||
#### 👏 Congratulations!
|
||||
|
||||
You successfully finished the Getting Started guide! Read the [concepts section](../concepts/concepts.md) to understand more deeply how to use and customize Strapi.
|
||||
|
||||
Also, feel free to join the community thanks to the different channels listed in the [community page](http://strapi.io/community): team members, contributors and developers will be happy to help you.
|
||||
|
||||
@ -4,33 +4,35 @@
|
||||
This feature requires the Users & Permissions plugin (installed by default).
|
||||
:::
|
||||
|
||||
## Register a new user
|
||||
## Registration
|
||||
|
||||
This route lets you create new users.
|
||||
|
||||
#### Usage
|
||||
|
||||
```js
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'http://localhost:1337/auth/local/register',
|
||||
data: {
|
||||
import axios from 'axios';
|
||||
|
||||
// Request API.
|
||||
axios
|
||||
.post('http://localhost:1337/auth/local/register', {
|
||||
username: 'Strapi user',
|
||||
email: 'user@strapi.io',
|
||||
password: 'strapiPassword'
|
||||
},
|
||||
done: function(auth) {
|
||||
})
|
||||
.then(response => {
|
||||
// Handle success.
|
||||
console.log('Well done!');
|
||||
console.log('User profile', auth.user);
|
||||
console.log('User token', auth.jwt);
|
||||
},
|
||||
fail: function(error) {
|
||||
console.log('User profile', response.data.user);
|
||||
console.log('User token', response.data.jwt);
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
}
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Login.
|
||||
## Login
|
||||
|
||||
This route lets you login your users by getting an authentication token.
|
||||
|
||||
@ -39,22 +41,24 @@ This route lets you login your users by getting an authentication token.
|
||||
- The `identifier` param can either be an email or a username.
|
||||
|
||||
```js
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'http://localhost:1337/auth/local',
|
||||
data: {
|
||||
identifier: 'user@strapi.io',
|
||||
password: 'strapiPassword'
|
||||
},
|
||||
done: function(auth) {
|
||||
import axios from 'axios';
|
||||
|
||||
// Request API.
|
||||
axios
|
||||
.post('http://localhost:1337/auth/local', {
|
||||
identifier: 'user@strapi.io',
|
||||
password: 'strapiPassword'
|
||||
})
|
||||
.then(response => {
|
||||
// Handle success.
|
||||
console.log('Well done!');
|
||||
console.log('User profile', auth.user);
|
||||
console.log('User token', auth.jwt);
|
||||
},
|
||||
fail: function(error) {
|
||||
console.log('User profile', response.data.user);
|
||||
console.log('User token', response.data.jwt);
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
}
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Providers
|
||||
@ -81,14 +85,14 @@ After his approval, he will be redirected to `/auth/:provider/callback`. The `jw
|
||||
|
||||
Response payload:
|
||||
|
||||
```js
|
||||
```json
|
||||
{
|
||||
"user": {},
|
||||
"jwt": ""
|
||||
}
|
||||
```
|
||||
|
||||
## Use your token to be identified as a user.
|
||||
## Token usage
|
||||
|
||||
By default, each API request is identified as `guest` role (see permissions of `guest`'s role in your admin dashboard). To make a request as a user, you have to set the `Authorization` token in your request headers. You receive a 401 error if you are not authorized to make this request or if your authorization header is not correct.
|
||||
|
||||
@ -97,22 +101,28 @@ By default, each API request is identified as `guest` role (see permissions of `
|
||||
- The `token` variable is the `data.jwt` received when login in or registering.
|
||||
|
||||
```js
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: 'http://localhost:1337/articles',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
},
|
||||
done: function(data) {
|
||||
console.log('Your data', data);
|
||||
},
|
||||
fail: function(error) {
|
||||
import axios from 'axios';
|
||||
|
||||
const token = 'YOUR_TOKEN_HERE';
|
||||
|
||||
// Request API.
|
||||
axios
|
||||
.get('http://localhost:1337/posts', {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
// Handle success.
|
||||
console.log('Data: ', response.data);
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
}
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Send forgot password request.
|
||||
## Forgotten password
|
||||
|
||||
This action sends an email to a user with the link of you reset password page. This link contains an URL param `code` which is required to reset user password.
|
||||
|
||||
@ -123,23 +133,25 @@ This action sends an email to a user with the link of you reset password page. T
|
||||
it is used to redirect the user to the new-password form.
|
||||
|
||||
```js
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'http://localhost:1337/auth/forgot-password',
|
||||
data: {
|
||||
import axios from 'axios';
|
||||
|
||||
// Request API.
|
||||
axios
|
||||
.post('http://localhost:1337/auth/forgot-password', {
|
||||
email: 'user@strapi.io',
|
||||
url: 'http:/localhost:1337/admin/plugins/users-permissions/auth/reset-password'
|
||||
},
|
||||
done: function() {
|
||||
})
|
||||
.then(response => {
|
||||
// Handle success.
|
||||
console.log('Your user received an email');
|
||||
},
|
||||
fail: function(error) {
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
}
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Reset user password.
|
||||
## Password reset
|
||||
|
||||
This action will reset the user password.
|
||||
|
||||
@ -148,24 +160,28 @@ This action will reset the user password.
|
||||
- `code` is the url params received from the email link (see forgot password)
|
||||
|
||||
```js
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'http://localhost:1337/auth/reset-password',
|
||||
data: {
|
||||
import axios from 'axios';
|
||||
|
||||
// Request API.
|
||||
axios
|
||||
.post('http://localhost:1337/auth/reset-password', {
|
||||
code: 'privateCode',
|
||||
password: 'myNewPassword',
|
||||
passwordConfirmation: 'myNewPassword'
|
||||
},
|
||||
done: function() {
|
||||
console.log('Your user password is reset');
|
||||
},
|
||||
fail: function(error) {
|
||||
})
|
||||
.then(response => {
|
||||
// Handle success.
|
||||
console.log('Your user\'s password has been changed.');
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
}
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## User Object In Strapi Context
|
||||
## User object in Strapi context
|
||||
|
||||
The `user` object is available to successfully authenticated requests.
|
||||
|
||||
#### Usage
|
||||
@ -190,7 +206,7 @@ The `user` object is available to successfully authenticated requests.
|
||||
|
||||
```
|
||||
|
||||
## Add a new provider
|
||||
## Adding a new provider
|
||||
|
||||
To add a new provider on Strapi, you will need to perform changes onto the following files:
|
||||
|
||||
@ -257,9 +273,9 @@ You may also want to take a look onto the numerous already made configurations [
|
||||
callback(err);
|
||||
} else {
|
||||
// Combine username and discriminator because discord username is not unique
|
||||
var username = `${body.username}#${body.discriminator}`;
|
||||
const username = `${body.username}#${body.discriminator}`;
|
||||
callback(null, {
|
||||
username: username,
|
||||
username,
|
||||
email: body.email
|
||||
});
|
||||
}
|
||||
@ -322,7 +338,7 @@ As for backend, we have a `switch...case` where we need to put our new provider
|
||||
Add the corresponding translation into: `packages/strapi-plugin-users-permissions/admin/src/translations/en.json`
|
||||
|
||||
```js
|
||||
"PopUpForm.Providers.discord.providerConfig.redirectURL": "The redirect URL to add in your Discord application configurations",
|
||||
'PopUpForm.Providers.discord.providerConfig.redirectURL': 'The redirect URL to add in your Discord application configurations',
|
||||
````
|
||||
|
||||
These two change will set up the popup message who appear on the UI when we will configure our new provider.
|
||||
|
||||
@ -672,15 +672,10 @@ module.exports = {
|
||||
|
||||
In this example, the policy `isAuthenticated` located in `./plugins/users-permissions/config/policies/isAuthenticated.js` will be executed first. Then, the `isOwner` policy located in the `Post` API `./api/post/config/policies/isOwner.js`. Next, it will execute the `logging` policy located in `./config/policies/logging.js`. Finally, the resolver will be executed.
|
||||
|
||||
<<<<<<< HEAD:docs/3.x.x/guides/graphql.md
|
||||
|
||||
::: note
|
||||
There is no custom resolver in that case, so it will execute the default resolver (Post.find) provided by the Shadow CRUD feature.
|
||||
:::
|
||||
=======
|
||||
The same process is applied to the `createPost` mutation.
|
||||
|
||||
> Note: There is no custom resolver in that case, so it will execute the default resolver (Post.find) provided by the Shadow CRUD feature.
|
||||
>>>>>>> 5705158a4368b144541493e08570ce0e93734ed8:docs/3.x.x/en/guides/graphql.md
|
||||
|
||||
### Link a query or mutation to a controller action
|
||||
|
||||
|
||||
@ -25,8 +25,8 @@ The info key on the model-json states information about the model. This informat
|
||||
|
||||
## Model options
|
||||
The options key on the model-json states.
|
||||
- `idAttribute`: This tells the model which attribute to expect as the unique identifier for each database row (typically an auto-incrementing primary key named 'id').
|
||||
- `idAttributeType`: Data type of `idAttribute`, accepted list of value bellow:
|
||||
- `idAttribute`: This tells the model which attribute to expect as the unique identifier for each database row (typically an auto-incrementing primary key named 'id'). _Only valid for strapi-hook-bookshelf_
|
||||
- `idAttributeType`: Data type of `idAttribute`, accepted list of value bellow. _Only valid for strapi-hook-bookshelf_
|
||||
|
||||
## Define the attributes
|
||||
|
||||
|
||||
121
docs/3.x.x/guides/webhooks.md
Normal file
@ -0,0 +1,121 @@
|
||||
# Webhooks
|
||||
|
||||
If you are using a static website generator (or framework with build option) with Strapi (Gatsby, Nuxt, Next, etc.) it is necessary to rebuild it when the content is updated in Strapi. In a Headless CMS, this is typically called a [Webhook feature](https://strapi.io/marketplace/webhooks). Unfortunately it is not available yet in Strapi even if [it has been requested](https://portal.productboard.com/strapi/c/27-webhooks).
|
||||
|
||||
But what we like at Strapi is to help developers. So even if the feature is not developed yet, here is an easy to implement work around!
|
||||
|
||||
### Discovering the lifecycle callbacks 🔍
|
||||
|
||||
As you may know, every Content Type (aka models) has lifecycle callbacks: functions which are triggered every time an entry is fetched, inserted, updated or deleted. Here is the list:
|
||||
|
||||
- Callbacks on `save` (both triggered on entry creation and update): `beforeSave`, `afterSave`.
|
||||
- Callbacks on `fetch`: `beforeFetch`, `afterFetch`.
|
||||
- Callbacks on `fetchAll`: `beforeFetchAll`, `afterFetchAll`.
|
||||
- Callbacks on `create`: `beforeCreate`, `afterCreate`.
|
||||
- Callbacks on `update`: `beforeUpdate`, `afterUpdate`.
|
||||
- Callbacks on `destroy`: `beforeDestroy`, `afterDestroy`.
|
||||
|
||||
All of these functions are available in a file located at `api/yourContentType/models/YourContentType.js`.
|
||||
|
||||
If your goal is to rebuild a static website, the only useful callbacks are `afterCreate`, `afterUpdate` and `afterDestroy`. So, uncomment them, add logs and try to create, update and delete entries from the admin panel.
|
||||
|
||||
*Path: `api/yourContentType/models/YourContentType.js`*
|
||||
|
||||
```js
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Lifecycle callbacks for the `Post` model.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
afterCreate: async (entry) => {
|
||||
console.log('afterCreate');
|
||||
},
|
||||
|
||||
afterUpdate: async (entry) => {
|
||||
console.log('afterUpdate');
|
||||
},
|
||||
|
||||
afterDestroy: async (entry) => {
|
||||
console.log('afterDestroy');
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Making the HTTP call 🔊
|
||||
|
||||
We are almost there: the only thing we still need to do is to actually make the HTTP call to the URL which will rebuild the static website.
|
||||
|
||||
#### URL config
|
||||
|
||||
So first of all, let's store this URL in a proper way. To do so, edit `config/environments/development/custom.json`:
|
||||
|
||||
*Path: `config/environments/development/custom.json`*
|
||||
|
||||
```json
|
||||
{
|
||||
"staticWebsiteBuildURL": "https://yourservice.com/"
|
||||
}
|
||||
```
|
||||
|
||||
Do the same thing for other environments.
|
||||
|
||||
#### HTTP call
|
||||
|
||||
Now it is time to make the HTTP call. In this example we will use `request` as it is already in the list of Strapi's dependencies. Let's install it:
|
||||
|
||||
```
|
||||
npm i request --save
|
||||
```
|
||||
|
||||
Edit `api/yourContentType/models/YourContentType.js`:
|
||||
|
||||
*Path: `api/yourContentType/models/YourContentType.js`*
|
||||
|
||||
```js
|
||||
'use strict';
|
||||
|
||||
const request = require('request');
|
||||
|
||||
/**
|
||||
* Lifecycle callbacks for the `Post` model.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
afterCreate: async (entry) => {
|
||||
axios.post(strapi.config.currentEnvironment.staticWebsiteBuildURL, entry)
|
||||
.catch(() => {
|
||||
// Ignore
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
afterUpdate: async (entry) => {
|
||||
axios.post(strapi.config.currentEnvironment.staticWebsiteBuildURL, entry)
|
||||
.catch(() => {
|
||||
// Ignore
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
afterDestroy: async (entry) => {
|
||||
axios.post(strapi.config.currentEnvironment.staticWebsiteBuildURL, entry)
|
||||
.catch(() => {
|
||||
// Ignore
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
#### Mongoose limitation
|
||||
|
||||
Until September 2018, `remove` lifecycle callback [was not supported by Mongoose](https://github.com/Automattic/mongoose/issues/3054). This has been added but `strapi-hook-mongoose` is not adapted yet to this update.
|
||||
|
||||
So, to trigger an url on delete, please add `request.post(strapi.config.currentEnvironment.staticWebsiteBuildURL, entry);` in:
|
||||
|
||||
- `remove` action of `api/yourContentType/services/YourContentType.js` (triggered by your public API).
|
||||
- `delete` action of `plugins/content-manager/services/ContentManager.js` (triggered by the Content Manager).
|
||||
|
||||
*Note: do not forget to require `request` at the top of these files.*
|
||||
@ -10,7 +10,9 @@ Go further with Strapi, official and community tutorials are here to help you:
|
||||
### Development
|
||||
|
||||
- [Building a static blog using Gatsby and Strapi (official)](https://hackernoon.com/building-a-static-blog-using-gatsby-and-strapi-8b5acfc82ad8)
|
||||
|
||||
- [🍝 Cooking a Deliveroo clone with Nuxt (Vue.js), GraphQL, Strapi and Stripe (official)](https://blog.strapi.io/cooking-a-deliveroo-clone-with-nuxt-vue-js-graphql-strapi-and-stripe-setup-part-1-7)
|
||||
- [🍝 Cooking a Deliveroo clone with Next.js (React), GraphQL, Strapi and Stripe](https://blog.strapi.io/strapi-next-setup)
|
||||
|
||||
### Deployment
|
||||
|
||||
- [Using mLab with Strapi (official)](https://medium.com/@strapi/using-mlab-with-strapi-e3f968a9c530)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
---
|
||||
meta:
|
||||
- http-equiv: refresh
|
||||
content: 0;url=/documentation/3.x.x/
|
||||
content: 0;url=/documentation/3.x.x/getting-started/installation.html
|
||||
---
|
||||
|
||||
@ -12,7 +12,8 @@
|
||||
"dependencies": {
|
||||
"directory-tree": "^2.1.0",
|
||||
"markdown-it-decorate": "^1.2.2",
|
||||
"vuepress": "^0.14.2"
|
||||
"vuepress": "^0.14.2",
|
||||
"cache-loader": "1.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"markdown-it-container": "^2.0.0"
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
{
|
||||
"private": true,
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"assert": "~1.3.0",
|
||||
"axios": "^0.18.0",
|
||||
"babel-eslint": "^6.1.2",
|
||||
"chalk": "^2.4.1",
|
||||
"eslint": "^3.12.2",
|
||||
"eslint": "^4.19.1",
|
||||
"eslint-plugin-babel": "^4.0.0",
|
||||
"eslint-plugin-react": "^6.8.0",
|
||||
"eslint-plugin-redux-saga": "^0.3.0",
|
||||
"eslint-plugin-react": "^7.7.0",
|
||||
"eslint-plugin-redux-saga": "^0.8.0",
|
||||
"istanbul": "~0.4.2",
|
||||
"jest": "^22.4.3",
|
||||
"jest-cli": "^22.4.4",
|
||||
|
||||
@ -15,10 +15,8 @@ defineMessages(messages);
|
||||
function LeftMenuFooter({ version }) { // eslint-disable-line react/prefer-stateless-function
|
||||
return (
|
||||
<div className={styles.leftMenuFooter}>
|
||||
<div>
|
||||
<FormattedMessage {...messages.poweredBy} />
|
||||
<a href="https://strapi.io" target="_blank">v{version}</a>
|
||||
</div>
|
||||
<FormattedMessage {...messages.poweredBy} />
|
||||
<a href={`https://github.com/strapi/strapi/releases/tag/v${version}`} target="_blank">v{version}</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
{
|
||||
"languages": ["ar", "en", "es", "fr", "de", "it", "ko", "nl", "pl", "pt", "pt-BR", "tr", "zh", "zh-Hans"]
|
||||
"languages": ["en", "ar", "es", "fr", "de", "it", "ko", "nl", "pl", "pt", "pt-BR", "ru", "tr", "zh", "zh-Hans", "ja"]
|
||||
}
|
||||
|
||||
@ -14,14 +14,12 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Switch, Route } from 'react-router-dom';
|
||||
|
||||
import AdminPage from 'containers/AdminPage';
|
||||
import NotFoundPage from 'containers/NotFoundPage';
|
||||
|
||||
import NotificationProvider from 'containers/NotificationProvider';
|
||||
|
||||
import AppLoader from 'containers/AppLoader';
|
||||
import LoadingIndicatorPage from 'components/LoadingIndicatorPage';
|
||||
import '../../styles/main.scss';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
export class App extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
@ -29,12 +27,22 @@ export class App extends React.Component { // eslint-disable-line react/prefer-s
|
||||
return (
|
||||
<div>
|
||||
<NotificationProvider />
|
||||
<div className={styles.container}>
|
||||
<Switch>
|
||||
<Route path="/" component={AdminPage} />
|
||||
<Route path="" component={NotFoundPage} />
|
||||
</Switch>
|
||||
</div>
|
||||
<AppLoader>
|
||||
{({ shouldLoad }) => {
|
||||
if (shouldLoad) {
|
||||
return <LoadingIndicatorPage />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<Switch>
|
||||
<Route path="/" component={AdminPage} />
|
||||
<Route path="" component={NotFoundPage} />
|
||||
</Switch>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</AppLoader>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -14,6 +14,11 @@ const selectPlugins = () => createSelector(
|
||||
(appState) => appState.get('plugins')
|
||||
);
|
||||
|
||||
const makeSelectApp = () => createSelector(
|
||||
selectApp(),
|
||||
appState => appState.toJS(),
|
||||
);
|
||||
|
||||
const selectHasUserPlugin = () => createSelector(
|
||||
selectApp(),
|
||||
(appState) => appState.get('hasUserPlugin'),
|
||||
@ -38,7 +43,7 @@ const makeSelectAppPlugins = () => createSelector(
|
||||
selectApp(),
|
||||
appState => appState.get('appPlugins').toJS(),
|
||||
);
|
||||
|
||||
export default makeSelectApp;
|
||||
export {
|
||||
selectApp,
|
||||
selectHasUserPlugin,
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
/**
|
||||
*
|
||||
* AppLoader
|
||||
*
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import makeSelectApp from 'containers/App/selectors';
|
||||
|
||||
class AppLoader extends React.Component {
|
||||
shouldLoad = () => {
|
||||
const { appPlugins, plugins: mountedPlugins } = this.props;
|
||||
|
||||
return appPlugins.length !== Object.keys(mountedPlugins).length;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children } = this.props;
|
||||
|
||||
return children({ shouldLoad: this.shouldLoad() });
|
||||
}
|
||||
}
|
||||
|
||||
AppLoader.propTypes = {
|
||||
appPlugins: PropTypes.array.isRequired,
|
||||
children: PropTypes.func.isRequired,
|
||||
plugins: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
const mapStateToProps = makeSelectApp();
|
||||
|
||||
export default connect(mapStateToProps, null)(AppLoader);
|
||||
@ -2,15 +2,14 @@ import 'whatwg-fetch';
|
||||
import { dropRight, take } from 'lodash';
|
||||
import removeMd from 'remove-markdown';
|
||||
import {
|
||||
all,
|
||||
call,
|
||||
fork,
|
||||
put,
|
||||
select,
|
||||
takeLatest,
|
||||
} from 'redux-saga/effects';
|
||||
|
||||
import request from 'utils/request';
|
||||
|
||||
import { getArticlesSucceeded, submitSucceeded } from './actions';
|
||||
import { GET_ARTICLES, SUBMIT } from './constants';
|
||||
import { makeSelectBody } from './selectors';
|
||||
@ -51,8 +50,10 @@ function* submit() {
|
||||
}
|
||||
|
||||
function* defaultSaga() {
|
||||
yield fork(takeLatest, SUBMIT, submit);
|
||||
yield fork(takeLatest, GET_ARTICLES, getArticles);
|
||||
yield all([
|
||||
fork(takeLatest, SUBMIT, submit),
|
||||
fork(takeLatest, GET_ARTICLES, getArticles),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
import { LOCATION_CHANGE } from 'react-router-redux';
|
||||
import { get } from 'lodash';
|
||||
import { fork, call, put, select, takeLatest, take, cancel } from 'redux-saga/effects';
|
||||
import { all, fork, call, put, select, takeLatest, take, cancel } from 'redux-saga/effects';
|
||||
import { pluginDeleted } from 'containers/App/actions';
|
||||
import auth from 'utils/auth';
|
||||
import request from 'utils/request';
|
||||
|
||||
import { selectLocale } from '../LanguageProvider/selectors';
|
||||
import { deletePluginSucceeded, getAppCurrentEnvSucceeded, getPluginsSucceeded } from './actions';
|
||||
import { GET_PLUGINS, ON_DELETE_PLUGIN_CONFIRM } from './constants';
|
||||
@ -36,10 +35,10 @@ export function* deletePlugin() {
|
||||
export function* pluginsGet() {
|
||||
try {
|
||||
// Fetch plugins.
|
||||
const response = yield [
|
||||
const response = yield all([
|
||||
call(request, '/admin/plugins', { method: 'GET' }),
|
||||
call(request, '/admin/currentEnvironment', { method: 'GET' }),
|
||||
];
|
||||
]);
|
||||
const locale = yield select(selectLocale());
|
||||
|
||||
const opts = {
|
||||
|
||||
@ -35,6 +35,8 @@ export class LocaleToggle extends React.Component { // eslint-disable-line
|
||||
return 'https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.1.0/flags/4x3/sa.svg';
|
||||
case 'ko':
|
||||
return 'https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.1.0/flags/4x3/kr.svg';
|
||||
case 'ja':
|
||||
return 'https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.1.0/flags/4x3/jp.svg';
|
||||
default:
|
||||
return `https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.1.0/flags/4x3/${locale}.svg`;
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@
|
||||
"app.components.InstallPluginPopup.navLink.avis": "avis",
|
||||
"app.components.InstallPluginPopup.navLink.changelog": "Änderungsprotokoll",
|
||||
"app.components.InstallPluginPopup.navLink.description": "Beschreibung",
|
||||
"app.components.InstallPluginPopup.navLink.faq": "faq",
|
||||
"app.components.InstallPluginPopup.navLink.faq": "FAQ",
|
||||
"app.components.InstallPluginPopup.navLink.screenshots": "Screenshots",
|
||||
"app.components.InstallPluginPopup.noDescription": "Keine Beschreibung verfügbar",
|
||||
"app.components.LeftMenuFooter.poweredBy": "Stolz präsentiert von ",
|
||||
@ -85,7 +85,7 @@
|
||||
"app.components.PluginCard.compatible": "Mit der App kompatibel",
|
||||
"app.components.PluginCard.compatibleCommunity": "Mit der Community kompatibel",
|
||||
"app.components.PluginCard.more-details": "Mehr Details",
|
||||
"app.components.PluginCard.price.free": "Umsonst",
|
||||
"app.components.PluginCard.price.free": "Kostenlos",
|
||||
"app.components.listPlugins.button": "Neues Plugin hinzufügen",
|
||||
"app.components.listPlugins.title.none": "Es ist kein Plugin installiert",
|
||||
"app.components.listPlugins.title.plural": "{number} Plugins sind installiert",
|
||||
|
||||
@ -136,5 +136,6 @@
|
||||
"components.popUpWarning.title": "Por favor, confirme",
|
||||
"notification.error": "Se ha producido un error",
|
||||
"notification.error.layout": "No se pudo recuperar el esquema",
|
||||
"request.error.model.unknown": "Este modelo no existe"
|
||||
"request.error.model.unknown": "Este modelo no existe",
|
||||
"app.utils.delete": "Eliminar"
|
||||
}
|
||||
@ -3,7 +3,7 @@
|
||||
"Auth & Permissions": "Auth & Permissions",
|
||||
"Content Manager": "Content Manager",
|
||||
"Content Type Builder": "Content Type Builder",
|
||||
"Email": "Email",
|
||||
"Email": "E-mail",
|
||||
"Files Upload": "Téléversement de fichiers",
|
||||
"HomePage.notification.newsLetter.success": "Vous avez souscrit à la newsletter",
|
||||
"New entry": "Nouvelle entrée",
|
||||
@ -20,8 +20,8 @@
|
||||
"app.components.BlockLink.code.content": "Apprenez en testant les projets développés par la communauté.",
|
||||
"app.components.BlockLink.documentation": "Voir la documentation",
|
||||
"app.components.BlockLink.documentation.content": "Découvrez les concepts, guides et tutoriaux.",
|
||||
"app.components.Button.cancel": "Cancel",
|
||||
"app.components.Button.save": "Save",
|
||||
"app.components.Button.cancel": "Annuler",
|
||||
"app.components.Button.save": "Sauvegarder",
|
||||
"app.components.ComingSoonPage.comingSoon": "Bientôt disponible",
|
||||
"app.components.ComingSoonPage.featuresNotAvailable": "Cette fonctionnalité est toujours en cours de développement.",
|
||||
"app.components.DownloadInfo.download": "Téléchargement en cours...",
|
||||
@ -39,32 +39,32 @@
|
||||
"app.components.HomePage.newsLetter": "Inscrivez-vous à la newsletter pour être contacté à propos de Strapi",
|
||||
"app.components.HomePage.support": "SUPPORT US",
|
||||
"app.components.HomePage.support.content": "En achetant notre T-shirt, vous nous aidez à poursuivre à maintenir le projet pour que nous puissions vous donner la meilleure expérience possible!",
|
||||
"app.components.HomePage.support.link": "OBTENEZ VOTRE T-SHIRT!",
|
||||
"app.components.HomePage.welcome": "Bienvenue à bord!",
|
||||
"app.components.HomePage.support.link": "OBTENEZ VOTRE T-SHIRT !",
|
||||
"app.components.HomePage.welcome": "Bienvenue à bord !",
|
||||
"app.components.HomePage.welcome.again": "Bienvenue ",
|
||||
"app.components.HomePage.welcomeBlock.content": "Nous sommes heureux de vous compter parmi nos membres. Nous sommes à l'écoute de vos retours alors, n'hésitez pas à nous envoyer des DM sur ",
|
||||
"app.components.HomePage.welcomeBlock.content.again": "Nous espérons que votre projet avance bien... Découvrez les derniers articles à propos de Strapi. Nous faisons de notre mieux pour améliorer le produit selon vos retours.",
|
||||
"app.components.HomePage.welcomeBlock.content.issues": "issues",
|
||||
"app.components.HomePage.welcomeBlock.content.raise": " ou soumetez des ",
|
||||
"app.components.ImgPreview.hint": "Drag & drop dans cette zone ou {browse} un fichier à télécharger",
|
||||
"app.components.ImgPreview.hint": "Glissez-déposez dans cette zone ou {browse} un fichier à télécharger",
|
||||
"app.components.ImgPreview.hint.browse": "recherchez",
|
||||
"app.components.InputFile.newFile": "Ajouter un nouveau fichier",
|
||||
"app.components.InputFile.newFile": "Ajouter un nouveau fichier",
|
||||
"app.components.InputFileDetails.open": "Ouvrir dans une nouvelle fenêtre",
|
||||
"app.components.InputFileDetails.originalName": "Nom d'origine:",
|
||||
"app.components.InputFileDetails.originalName": "Nom d'origine :",
|
||||
"app.components.InputFileDetails.remove": "Supprimer ce fichier",
|
||||
"app.components.InputFileDetails.size": "Taille:",
|
||||
"app.components.InstallPluginPage.InputSearch.label": " ",
|
||||
"app.components.InstallPluginPage.InputSearch.placeholder": "Recherchez un plugin... (ex: authentification)",
|
||||
"app.components.InstallPluginPage.InputSearch.placeholder": "Recherchez un plugin... (ex : authentification)",
|
||||
"app.components.InstallPluginPage.description": "Améliorez votre app sans efforts",
|
||||
"app.components.InstallPluginPage.helmet": "Marketplace - Plugins",
|
||||
"app.components.InstallPluginPage.plugin.support-us.description": "Soutenez-nous en achetant un Strapi tee shirt. Cela nous aidera a continuer de travailler sur le projet pour vous donner la meilleure expérience possible!",
|
||||
"app.components.InstallPluginPage.plugin.support-us.description": "Soutenez-nous en achetant un t-shirt Strapi. Cela nous aidera a continuer de travailler sur le projet pour vous donner la meilleure expérience possible!",
|
||||
"app.components.InstallPluginPage.title": "Marketplace - Plugins",
|
||||
"app.components.InstallPluginPopup.downloads": "téléchargements",
|
||||
"app.components.InstallPluginPopup.navLink.avis": "avis",
|
||||
"app.components.InstallPluginPopup.navLink.changelog": "changelog",
|
||||
"app.components.InstallPluginPopup.navLink.description": "Description",
|
||||
"app.components.InstallPluginPopup.navLink.faq": "faq",
|
||||
"app.components.InstallPluginPopup.navLink.screenshots": "Screenshots",
|
||||
"app.components.InstallPluginPopup.navLink.faq": "FAQ",
|
||||
"app.components.InstallPluginPopup.navLink.screenshots": "Captures d'écran",
|
||||
"app.components.InstallPluginPopup.noDescription": "Aucune description disponible",
|
||||
"app.components.LeftMenuFooter.poweredBy": "Propulsé par ",
|
||||
"app.components.LeftMenuLinkContainer.configuration": "Configurations",
|
||||
@ -82,8 +82,8 @@
|
||||
"app.components.PluginCard.Button.label.download": "Télécharger",
|
||||
"app.components.PluginCard.Button.label.install": "Déjà installé",
|
||||
"app.components.PluginCard.Button.label.support": "Nous soutenir",
|
||||
"app.components.PluginCard.compatible": "Compatble avec votre app",
|
||||
"app.components.PluginCard.compatibleCommunity": "Compatble avec la communauté",
|
||||
"app.components.PluginCard.compatible": "Compatible avec votre app",
|
||||
"app.components.PluginCard.compatibleCommunity": "Compatible avec la communauté",
|
||||
"app.components.PluginCard.more-details": "Plus de détails",
|
||||
"app.components.PluginCard.price.free": "Gratuit",
|
||||
"app.components.listPlugins.button": "Ajouter un Nouveau Plugin",
|
||||
@ -102,13 +102,13 @@
|
||||
"components.Input.error.attribute.taken": "Ce champ existe déjà",
|
||||
"components.Input.error.contentTypeName.taken": "Ce nom existe déjà",
|
||||
"components.Input.error.custom-error": "{errorMessage} ",
|
||||
"components.Input.error.validation.email": "Le format n'est pas de type email",
|
||||
"components.Input.error.validation.email": "Le format n'est pas de type e-mail",
|
||||
"components.Input.error.validation.json": "Le format JSON n'est pas respecté",
|
||||
"components.Input.error.validation.max": "La valeur est trop grande.",
|
||||
"components.Input.error.validation.maxLength": "La valeur est trop longue.",
|
||||
"components.Input.error.validation.min": "La valeur est trop basse.",
|
||||
"components.Input.error.validation.minLength": "La valeur est trop courte.",
|
||||
"components.Input.error.validation.minSupMax": "Ne peut pas être plus grand",
|
||||
"components.Input.error.validation.minSupMax": "Ne peut pas être plus grand.",
|
||||
"components.Input.error.validation.regex": "La valeur ne correspond pas au format attendu.",
|
||||
"components.Input.error.validation.required": "Ce champ est obligatoire.",
|
||||
"components.ListRow.empty": "Il n'y a pas de données à afficher.",
|
||||
@ -118,7 +118,7 @@
|
||||
"components.ProductionBlocker.description": "Pour des raisons de sécurité il est désactivé dans les autres environnements.",
|
||||
"components.ProductionBlocker.header": "Ce plugin est disponible uniquement en développement.",
|
||||
"components.Wysiwyg.ToggleMode.markdown": "Retour au markdown",
|
||||
"components.Wysiwyg.ToggleMode.preview": "Voir la preview",
|
||||
"components.Wysiwyg.ToggleMode.preview": "Voir une prévisualisation",
|
||||
"components.Wysiwyg.collapse": "Fermer",
|
||||
"components.Wysiwyg.selectOptions.H1": "Titre H1",
|
||||
"components.Wysiwyg.selectOptions.H2": "Titre H2",
|
||||
@ -127,16 +127,16 @@
|
||||
"components.Wysiwyg.selectOptions.H5": "Titre H5",
|
||||
"components.Wysiwyg.selectOptions.H6": "Titre H6",
|
||||
"components.Wysiwyg.selectOptions.title": "Ajouter un titre",
|
||||
"components.WysiwygBottomControls.charactersIndicators": "charactères",
|
||||
"components.WysiwygBottomControls.charactersIndicators": "caractères",
|
||||
"components.WysiwygBottomControls.fullscreen": "Plein écran",
|
||||
"components.WysiwygBottomControls.uploadFiles": "Ajouter des fichiers en les 'droppant', {browse}, ou en les collant depuis le presse-papier",
|
||||
"components.WysiwygBottomControls.uploadFiles": "Ajouter des fichiers en les 'glissant-déposant', {browse}, ou en les collant depuis le presse-papier",
|
||||
"components.WysiwygBottomControls.uploadFiles.browse": "en les selectionnant",
|
||||
"components.popUpWarning.button.cancel": "Annuler",
|
||||
"components.popUpWarning.button.confirm": "Confirmer",
|
||||
"components.popUpWarning.message": "Etes-vous sure de vouloir le supprimer?",
|
||||
"components.popUpWarning.message": "Etes-vous sure de vouloir le supprimer ?",
|
||||
"components.popUpWarning.title": "Merci de confirmer",
|
||||
"notification.error": "Une erreur est survenue",
|
||||
"notification.error.layout": "Impossible de récupérer le layout de l'admin",
|
||||
"request.error.model.unknown": "Le model n'existe pas",
|
||||
"app.utils.delete": "Supprimer"
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
"app.components.ComingSoonPage.featuresNotAvailable": "Questa funzionalità è ancora sotto sviluppo attivo.",
|
||||
"app.components.DownloadInfo.download": "Download in corso...",
|
||||
"app.components.DownloadInfo.text": "Potrebbe volerci un minuto. Grazie della pazienza.",
|
||||
"app.components.EmptyAttributes.title": "Campi non ancora presenti.",
|
||||
"app.components.HomePage.button.blog": "LEGGI DI PIÙ SUL BLOG",
|
||||
"app.components.HomePage.button.quickStart": "INIZIA IL TUTORIAL QUICK START",
|
||||
"app.components.HomePage.community": "Trova la community sul web",
|
||||
@ -137,4 +138,4 @@
|
||||
"notification.error.layout": "Non è stato possibile recuperare il layout",
|
||||
"request.error.model.unknow": "Questo modello non esiste",
|
||||
"request.error.model.unknown": "Questo modello non esiste"
|
||||
}
|
||||
}
|
||||
|
||||
141
packages/strapi-admin/admin/src/translations/ja.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Analytics": "分析",
|
||||
"Content Manager": "コンテンツ管理",
|
||||
"Content Type Builder": "コンテンツタイプ作成",
|
||||
"Email": "Email",
|
||||
"Files Upload": "ファイルアップロード",
|
||||
"HomePage.notification.newsLetter.success": "ニュースレターの購読しました。",
|
||||
"New entry": "新規投稿",
|
||||
"Password": "パスワード",
|
||||
"Provider": "Provider",
|
||||
"ResetPasswordToken": "パスワードトークンをリセット",
|
||||
"Role": "Role",
|
||||
"Roles & Permissions": "ロールと権限",
|
||||
"Settings Manager": "設定管理",
|
||||
"Username": "ユーザー名",
|
||||
"Users": "ユーザー",
|
||||
"Users & Permissions": "ユーザーと権限",
|
||||
"app.components.BlockLink.code": "コード例",
|
||||
"app.components.BlockLink.code.content": "コミュニティを開発した実際のプロジェクトをテストすることで学びます",
|
||||
"app.components.BlockLink.documentation": "ドキュメントを読む",
|
||||
"app.components.BlockLink.documentation.content": "コンセプト、リファレンスガイド、チュートリアルを探す",
|
||||
"app.components.Button.cancel": "キャンセル",
|
||||
"app.components.Button.save": "保存",
|
||||
"app.components.ComingSoonPage.comingSoon": "Coming soon",
|
||||
"app.components.ComingSoonPage.featuresNotAvailable": "この機能は現在開発中です",
|
||||
"app.components.DownloadInfo.download": "ダウンロード中...",
|
||||
"app.components.DownloadInfo.text": "これには数分かかることがあります。 お待ちください",
|
||||
"app.components.EmptyAttributes.title": "There are no fields yet",
|
||||
"app.components.HomePage.button.blog": "ブログでもっと見る",
|
||||
"app.components.HomePage.button.quickStart": "クイックスタートチュートリアルで始める",
|
||||
"app.components.HomePage.community": "コミュニティで見つける",
|
||||
"app.components.HomePage.community.content": "異なるチャンネルでチームメンバー、コントリビューターやデベロッパーと議論する",
|
||||
"app.components.HomePage.create": "コンテンツタイプを作成する",
|
||||
"app.components.HomePage.createBlock.content.first": " ",
|
||||
"app.components.HomePage.createBlock.content.second": "プラグインを使用すると、モデルのデータ構造を定義するのに役立ちます。ここで新しい方には、",
|
||||
"app.components.HomePage.createBlock.content.tutorial": "チュートリアル",
|
||||
"app.components.HomePage.cta": "確認",
|
||||
"app.components.HomePage.newsLetter": "ニュースレターを購読してStrapiと連絡をとる",
|
||||
"app.components.HomePage.support": "SUPPORT US",
|
||||
"app.components.HomePage.support.content": "Tシャツを購入することで、最高の体験を提供するためにプロジェクトの作業を続けることができます。",
|
||||
"app.components.HomePage.support.link": "今すぐT-シャツをゲット!",
|
||||
"app.components.HomePage.welcome": "ボードにようこそ!",
|
||||
"app.components.HomePage.welcome.again": "ようこそ ",
|
||||
"app.components.HomePage.welcomeBlock.content": "私たちはコミュニティメンバーのひとりとしてあなたをお待ちしております。私たちは常にフィードバックを求めていますので、DMを送ってください",
|
||||
"app.components.HomePage.welcomeBlock.content.again": "あなたのプロジェクトを進歩させていただければ幸いです... Strapiに関する最新の新情報をお読みください。私たちはあなたのフィードバックに基づいて製品を改善するために最善を尽くしています。",
|
||||
"app.components.HomePage.welcomeBlock.content.issues": "問題",
|
||||
"app.components.HomePage.welcomeBlock.content.raise": "または上げる",
|
||||
"app.components.ImgPreview.hint": "ファイルをドラッグ&ドロップ、もしくは、アップロード{browse}",
|
||||
"app.components.ImgPreview.hint.browse": "ブラウズ",
|
||||
"app.components.InputFile.newFile": "ファイルを追加",
|
||||
"app.components.InputFileDetails.open": "別のタブを開く",
|
||||
"app.components.InputFileDetails.originalName": "オリジナル名:",
|
||||
"app.components.InputFileDetails.remove": "ファイルを取り除く",
|
||||
"app.components.InputFileDetails.size": "サイズ:",
|
||||
"app.components.InstallPluginPage.InputSearch.label": " ",
|
||||
"app.components.InstallPluginPage.InputSearch.placeholder": "プラグインを探す... (ex: authentication)",
|
||||
"app.components.InstallPluginPage.description": "簡単にアプリを拡張する",
|
||||
"app.components.InstallPluginPage.helmet": "マーケットプレイス - プラグイン",
|
||||
"app.components.InstallPluginPage.plugin.support-us.description": "Strapi Tシャツを購入して私たちをサポートしてください。それは私たちがプロジェクトに取り組むことを可能にし、あなたに最高の経験を与えることを試みます!",
|
||||
"app.components.InstallPluginPage.title": "マーケットプレイス - プラグイン",
|
||||
"app.components.InstallPluginPopup.downloads": "ダウンロード",
|
||||
"app.components.InstallPluginPopup.navLink.avis": "ビュー",
|
||||
"app.components.InstallPluginPopup.navLink.changelog": "changelog",
|
||||
"app.components.InstallPluginPopup.navLink.description": "説明文",
|
||||
"app.components.InstallPluginPopup.navLink.faq": "faq",
|
||||
"app.components.InstallPluginPopup.navLink.screenshots": "スクリーンショット",
|
||||
"app.components.InstallPluginPopup.noDescription": "No description available",
|
||||
"app.components.LeftMenuFooter.poweredBy": "Powered by ",
|
||||
"app.components.LeftMenuLinkContainer.configuration": "構成",
|
||||
"app.components.LeftMenuLinkContainer.general": "一般",
|
||||
"app.components.LeftMenuLinkContainer.installNewPlugin": "マーケットプレイス",
|
||||
"app.components.LeftMenuLinkContainer.listPlugins": "プラグイン",
|
||||
"app.components.LeftMenuLinkContainer.noPluginsInstalled": "プラグインがインストールされていません",
|
||||
"app.components.LeftMenuLinkContainer.plugins": "プラグイン",
|
||||
"app.components.ListPluginsPage.description": "このプロジェクトでインストールされたプラグイン一覧",
|
||||
"app.components.ListPluginsPage.helmet.title": "プラグイン一覧",
|
||||
"app.components.ListPluginsPage.title": "プラグイン",
|
||||
"app.components.NotFoundPage.back": "ホームページに戻る",
|
||||
"app.components.NotFoundPage.description": "見つかりません",
|
||||
"app.components.Official": "オフィシャル",
|
||||
"app.components.PluginCard.Button.label.download": "ダウンロード",
|
||||
"app.components.PluginCard.Button.label.install": "インストール済み",
|
||||
"app.components.PluginCard.Button.label.support": "Support us",
|
||||
"app.components.PluginCard.compatible": "アプリとの互換性",
|
||||
"app.components.PluginCard.compatibleCommunity": "コミュニティとの互換性",
|
||||
"app.components.PluginCard.more-details": "詳細を見る",
|
||||
"app.components.PluginCard.price.free": "無料",
|
||||
"app.components.listPlugins.button": "プラグインを追加",
|
||||
"app.components.listPlugins.title.none": "インストール済みのプラグインはありません",
|
||||
"app.components.listPlugins.title.plural": "{number} 個のプラグインがインストールされました",
|
||||
"app.components.listPlugins.title.singular": "{number} 個のプラグインがインストールされました",
|
||||
"app.components.listPluginsPage.deletePlugin.error": "アンインストール中にエラーが発生しました",
|
||||
"app.utils.defaultMessage": " ",
|
||||
"app.utils.delete": "削除",
|
||||
"app.utils.placeholder.defaultMessage": " ",
|
||||
"app.utils.SelectOption.defaultMessage": " ",
|
||||
"components.AutoReloadBlocker.description": "以下のファイルを開いて、有効化してください",
|
||||
"components.AutoReloadBlocker.header": "プラグインを有効化するにはリロードが必要です",
|
||||
"components.ErrorBoundary.title": "なにかが間違っています...",
|
||||
"components.Input.error.attribute.key.taken": "この値はすでに存在しています",
|
||||
"components.Input.error.attribute.sameKeyAndName": "等しくありません",
|
||||
"components.Input.error.attribute.taken": "このフィールド名はすでに存在します",
|
||||
"components.Input.error.contentTypeName.taken": "この名前はすでに存在します",
|
||||
"components.Input.error.custom-error": "{errorMessage} ",
|
||||
"components.Input.error.validation.email": "E-mailアドレスではありません",
|
||||
"components.Input.error.validation.json": "JSONフォーマットではありません",
|
||||
"components.Input.error.validation.max": "値が高すぎます",
|
||||
"components.Input.error.validation.maxLength": "この値は長すぎます",
|
||||
"components.Input.error.validation.min": "値が低すぎます",
|
||||
"components.Input.error.validation.minLength": "値は短すぎます",
|
||||
"components.Input.error.validation.minSupMax": "Can't be superior",
|
||||
"components.Input.error.validation.regex": "The value not match the regex.",
|
||||
"components.Input.error.validation.required": "値は必須項目です",
|
||||
"components.ListRow.empty": "表示するデータがありません",
|
||||
"components.OverlayBlocker.description": "サーバーのりスタートが必要な機能を使用しています。サーバーが起動するまでお待ち下さい",
|
||||
"components.OverlayBlocker.title": "リスタートを待っています...",
|
||||
"components.PageFooter.select": "ページ毎に表示する投稿数",
|
||||
"components.ProductionBlocker.description": "このプラグインは、安全のため、他の環境では無効する必要があります",
|
||||
"components.ProductionBlocker.header": "このプラグインはデベロップ環境でのみ利用できます",
|
||||
"components.Wysiwyg.ToggleMode.markdown": "マークダウンに切り替える",
|
||||
"components.Wysiwyg.ToggleMode.preview": "プレビューに切り替える",
|
||||
"components.Wysiwyg.collapse": "Collapse",
|
||||
"components.Wysiwyg.selectOptions.H1": "Title H1",
|
||||
"components.Wysiwyg.selectOptions.H2": "Title H2",
|
||||
"components.Wysiwyg.selectOptions.H3": "Title H3",
|
||||
"components.Wysiwyg.selectOptions.H4": "Title H4",
|
||||
"components.Wysiwyg.selectOptions.H5": "Title H5",
|
||||
"components.Wysiwyg.selectOptions.H6": "Title H6",
|
||||
"components.Wysiwyg.selectOptions.title": "Add a title",
|
||||
"components.WysiwygBottomControls.charactersIndicators": "キャラクター",
|
||||
"components.WysiwygBottomControls.fullscreen": "広げる",
|
||||
"components.WysiwygBottomControls.uploadFiles": "ファイルをドラッグ&ドロップ, クリップボードからペースト もしくは {browse}.",
|
||||
"components.WysiwygBottomControls.uploadFiles.browse": "選ぶ",
|
||||
"components.popUpWarning.button.cancel": "キャンセル",
|
||||
"components.popUpWarning.button.confirm": "確認",
|
||||
"components.popUpWarning.message": "本当に削除しますか?",
|
||||
"components.popUpWarning.title": "確認してください",
|
||||
"notification.error": "エラーが発生しました",
|
||||
"notification.error.layout": "レイアウトを復旧できませんでした",
|
||||
"request.error.model.unknown": "modelが存在しません"
|
||||
}
|
||||
@ -25,6 +25,7 @@
|
||||
"app.components.ComingSoonPage.featuresNotAvailable": "Este recurso está em desenvolvimento",
|
||||
"app.components.DownloadInfo.download": "Transferência em progresso...",
|
||||
"app.components.DownloadInfo.text": "Isto poderá levar alguns minutos. Obrigado pela sua paciência",
|
||||
"app.components.EmptyAttributes.title": "Ainda não existem campos",
|
||||
"app.components.HomePage.button.blog": "VEJA MAIS NO BLOG",
|
||||
"app.components.HomePage.button.quickStart": "INICIAR TUTORIAL (Quick Start)",
|
||||
"app.components.HomePage.community": "Nossa comunidade na web",
|
||||
@ -91,6 +92,7 @@
|
||||
"app.components.listPluginsPage.deletePlugin.error": "Ocorreu um erro ao desinstalar extensão",
|
||||
"app.utils.SelectOption.defaultMessage": " ",
|
||||
"app.utils.defaultMessage": " ",
|
||||
"app.utils.delete": "Excluir",
|
||||
"app.utils.placeholder.defaultMessage": " ",
|
||||
"components.AutoReloadBlocker.description": "Abra o seguinte arquivo e ative o recurso.",
|
||||
"components.AutoReloadBlocker.header": "Auto recarregamento é necessário para esta extensão.",
|
||||
@ -136,4 +138,4 @@
|
||||
"notification.error": "Ocorreu um erro",
|
||||
"notification.error.layout": "Não foi possível recuperar o layout",
|
||||
"request.error.model.unknown": "Este modelo não existe"
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,5 +136,6 @@
|
||||
"components.popUpWarning.title": "Lütfen onaylayın",
|
||||
"notification.error": "Bir hata oluştu",
|
||||
"notification.error.layout": "Düzen alınamadı",
|
||||
"request.error.model.unknown": "Bu model bulunmamaktadır."
|
||||
"request.error.model.unknown": "Bu model bulunmamaktadır.",
|
||||
"app.utils.delete": "Sil"
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-admin",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Strapi Admin",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -31,8 +31,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"sanitize.css": "^4.1.0",
|
||||
"strapi-helper-plugin": "3.0.0-alpha.14.3",
|
||||
"strapi-utils": "3.0.0-alpha.14.3"
|
||||
"strapi-helper-plugin": "3.0.0-alpha.14.5",
|
||||
"strapi-utils": "3.0.0-alpha.14.5"
|
||||
},
|
||||
"author": {
|
||||
"name": "Strapi",
|
||||
|
||||
@ -18,7 +18,7 @@ const { packageManager } = require('strapi-utils'); // eslint-disable-line impor
|
||||
|
||||
module.exports = (scope, cb) => {
|
||||
// Copy the admin files.
|
||||
fs.copySync(path.resolve(__dirname, '..', 'files'), path.resolve(scope.rootPath, 'admin'));
|
||||
fs.copySync(path.resolve(__dirname, '..', 'templates', 'gitignore'), path.join(scope.rootPath, 'admin', '.gitignore'));
|
||||
|
||||
if (scope.developerMode) {
|
||||
return cb();
|
||||
|
||||
@ -1,13 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
// Node.js core.
|
||||
const path = require('path');
|
||||
|
||||
// Public node modules.
|
||||
const _ = require('lodash');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
@ -18,7 +12,6 @@ const fs = require('fs-extra');
|
||||
* @param {Object} scope
|
||||
* @param {Function} cb
|
||||
*/
|
||||
|
||||
module.exports = function (scope, cb) {
|
||||
if (scope.developerMode) {
|
||||
fs.mkdirsSync(path.resolve(scope.rootPath));
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-generate-admin",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Generate the default admin panel for a Strapi application.",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
@ -15,8 +15,8 @@
|
||||
"dependencies": {
|
||||
"fs-extra": "^4.0.1",
|
||||
"lodash": "^4.17.5",
|
||||
"strapi-admin": "3.0.0-alpha.14.3",
|
||||
"strapi-utils": "3.0.0-alpha.14.3"
|
||||
"strapi-admin": "3.0.0-alpha.14.5",
|
||||
"strapi-utils": "3.0.0-alpha.14.5"
|
||||
},
|
||||
"author": {
|
||||
"email": "hi@strapi.io",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-generate-api",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Generate an API for a Strapi application.",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -30,7 +30,7 @@ module.exports = {
|
||||
|
||||
return <%= globalID %>.query(function(qb) {
|
||||
_.forEach(filters.where, (where, key) => {
|
||||
if (_.isArray(where.value)) {
|
||||
if (_.isArray(where.value) && where.symbol !== 'IN') {
|
||||
for (const value in where.value) {
|
||||
qb[value ? 'where' : 'orWhere'](key, where.symbol, where.value[value])
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-generate-controller",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Generate a controller for a Strapi API.",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-generate-model",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Generate a model for a Strapi API.",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
3
packages/strapi-generate-new/files/config/.init.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"init": true
|
||||
}
|
||||
@ -11,6 +11,6 @@
|
||||
"enabled": false
|
||||
},
|
||||
"admin": {
|
||||
"autoOpen": true
|
||||
"autoOpen": false
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,13 +48,13 @@ module.exports = scope => {
|
||||
},
|
||||
'devDependencies': {
|
||||
'babel-eslint': '^7.1.1',
|
||||
'eslint': '^3.12.2',
|
||||
'eslint': '^4.19.1',
|
||||
'eslint-config-airbnb': '^13.0.0',
|
||||
'eslint-plugin-import': '^2.2.0',
|
||||
'eslint-plugin-react': '^6.8.0'
|
||||
'eslint-plugin-import': '^2.11.0',
|
||||
'eslint-plugin-react': '^7.7.0'
|
||||
},
|
||||
'dependencies': Object.assign({}, {
|
||||
'lodash': '4.x.x',
|
||||
'lodash': '^4.17.5',
|
||||
'strapi': getDependencyVersion(cliPkg, 'strapi'),
|
||||
[scope.client.connector]: getDependencyVersion(cliPkg, 'strapi'),
|
||||
}, additionalsDependencies, {
|
||||
|
||||
@ -94,8 +94,8 @@ module.exports = (scope, cb) => {
|
||||
});
|
||||
} else {
|
||||
const alphaDependencies = othersDependencies.map(dep => {
|
||||
if (_.includes(dep, 'strapi') && !_.includes(dep, '@alpha')) { // We need this for yarn
|
||||
return `${dep}@alpha`;
|
||||
if (_.includes(dep, 'strapi')) { // We need this for yarn
|
||||
return `${dep}@${scope.strapiPackageJSON.version}`;
|
||||
}
|
||||
|
||||
return dep;
|
||||
|
||||
@ -225,14 +225,14 @@ module.exports = (scope, cb) => {
|
||||
shell.exec(`mkdir ${scope.tmpPath}`);
|
||||
}
|
||||
|
||||
let cmd = `${packageCmd} ${scope.client.connector}@alpha`;
|
||||
let cmd = `${packageCmd} ${scope.client.connector}@${scope.strapiPackageJSON.version}`;
|
||||
|
||||
if (scope.client.module) {
|
||||
cmd += ` ${scope.client.module}`;
|
||||
}
|
||||
|
||||
if (scope.client.connector === 'strapi-hook-bookshelf') {
|
||||
cmd += ` strapi-hook-knex@alpha`;
|
||||
cmd += ` strapi-hook-knex@${scope.strapiPackageJSON.version}`;
|
||||
|
||||
scope.additionalsDependencies = ['strapi-hook-knex', 'knex'];
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-generate-new",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Generate a new Strapi application.",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
@ -19,7 +19,7 @@
|
||||
"listr": "^0.14.1",
|
||||
"lodash": "^4.17.5",
|
||||
"ora": "^2.1.0",
|
||||
"strapi-utils": "3.0.0-alpha.14.3",
|
||||
"strapi-utils": "3.0.0-alpha.14.5",
|
||||
"uuid": "^3.1.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-generate-plugin",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Generate an plugin for a Strapi application.",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-generate-policy",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Generate a policy for a Strapi API.",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-generate-service",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Generate a service for a Strapi API.",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-generate",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Master of ceremonies for the Strapi generators.",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
@ -17,7 +17,7 @@
|
||||
"fs-extra": "^4.0.0",
|
||||
"lodash": "^4.17.5",
|
||||
"reportback": "^2.0.1",
|
||||
"strapi-utils": "3.0.0-alpha.14.3"
|
||||
"strapi-utils": "3.0.0-alpha.14.5"
|
||||
},
|
||||
"author": {
|
||||
"name": "Strapi team",
|
||||
|
||||
@ -3,9 +3,8 @@ const shell = require('shelljs');
|
||||
|
||||
const pwd = shell.pwd();
|
||||
const isDevelopmentMode = path.resolve(pwd.stdout).indexOf('strapi-admin') !== -1;
|
||||
const isSetup = process.env.IS_MONOREPO || false;
|
||||
const appPath = isDevelopmentMode ? path.resolve(process.env.PWD, '..') : path.resolve(pwd.stdout, '..');
|
||||
// const isSetup = path.resolve(process.env.PWD, '..', '..') === path.resolve(process.env.INIT_CWD);
|
||||
const isSetup = process.env.IS_MONOREPO;
|
||||
|
||||
// Load the app configurations only when :
|
||||
// - starting the app in dev mode
|
||||
|
||||
@ -14,15 +14,8 @@ const isAdmin = process.env.IS_ADMIN === 'true';
|
||||
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
|
||||
const appPath = (() => {
|
||||
if (process.env.APP_PATH) {
|
||||
return process.env.APP_PATH;
|
||||
}
|
||||
|
||||
return isAdmin ? path.resolve(process.env.PWD, '..') : path.resolve(process.env.PWD, '..', '..');
|
||||
})();
|
||||
// const isSetup = path.resolve(process.env.PWD, '..', '..') === path.resolve(process.env.INIT_CWD);
|
||||
const isSetup = process.env.IS_MONOREPO;
|
||||
const isSetup = process.env.IS_MONOREPO || false;
|
||||
const appPath = process.env.APP_PATH || path.resolve(process.env.PWD, '..', ( isAdmin ? '' : '..' ));
|
||||
|
||||
const adminPath = (() => {
|
||||
if (isAdmin && isSetup) {
|
||||
|
||||
@ -16,19 +16,11 @@ const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
|
||||
|
||||
const isAdmin = process.env.IS_ADMIN === 'true';
|
||||
const isSetup = path.resolve(process.env.PWD, '..', '..') === path.resolve(process.env.INIT_CWD);
|
||||
const appPath = (() => {
|
||||
if (process.env.APP_PATH) {
|
||||
return process.env.APP_PATH;
|
||||
}
|
||||
|
||||
return isAdmin ? path.resolve(process.env.PWD, '..') : path.resolve(process.env.PWD, '..', '..');
|
||||
})();
|
||||
const appPath = process.env.APP_PATH || path.resolve(process.env.PWD, '..', ( isAdmin ? '' : '..' ));
|
||||
|
||||
const rootAdminpath = (() => {
|
||||
if (isSetup) {
|
||||
return isAdmin
|
||||
? path.resolve(appPath, 'strapi-admin')
|
||||
: path.resolve(appPath, 'packages', 'strapi-admin');
|
||||
return isAdmin ? path.resolve(appPath, 'strapi-admin') : path.resolve(appPath, 'packages', 'strapi-admin');
|
||||
}
|
||||
return path.resolve(appPath, 'admin');
|
||||
})();
|
||||
|
||||
@ -9,8 +9,7 @@ const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const isAdmin = process.env.IS_ADMIN === 'true';
|
||||
|
||||
// const isSetup = path.resolve(process.env.PWD, '..', '..') === path.resolve(process.env.INIT_CWD);
|
||||
const isSetup = process.env.IS_MONOREPO;
|
||||
const isSetup = process.env.IS_MONOREPO || false;
|
||||
const appPath = process.env.APP_PATH || path.resolve(process.env.PWD, '..', ( isAdmin ? '' : '..' ));
|
||||
|
||||
const rootAdminpath = (() => {
|
||||
|
||||
@ -15,14 +15,8 @@ const base = require('./webpack.base.babel');
|
||||
|
||||
const isAdmin = process.env.IS_ADMIN === 'true';
|
||||
// const isSetup = path.resolve(process.env.PWD, '..', '..') === path.resolve(process.env.INIT_CWD);
|
||||
const isSetup = process.env.IS_MONOREPO;
|
||||
const appPath = (() => {
|
||||
if (process.env.APP_PATH) {
|
||||
return process.env.APP_PATH;
|
||||
}
|
||||
|
||||
return isAdmin ? path.resolve(process.env.PWD, '..') : path.resolve(process.env.PWD, '..', '..');
|
||||
})();
|
||||
const isSetup = process.env.IS_MONOREPO || false;
|
||||
const appPath = process.env.APP_PATH || path.resolve(process.env.PWD, '..', ( isAdmin ? '' : '..' ));
|
||||
const adminPath = (() => {
|
||||
if (isSetup) {
|
||||
return isAdmin ? path.resolve(appPath, 'strapi-admin') : path.resolve(process.env.PWD, '..');
|
||||
@ -33,9 +27,7 @@ const adminPath = (() => {
|
||||
|
||||
const rootAdminpath = (() => {
|
||||
if (isSetup) {
|
||||
return isAdmin
|
||||
? path.resolve(appPath, 'strapi-admin')
|
||||
: path.resolve(appPath, 'packages', 'strapi-admin');
|
||||
return isAdmin ? path.resolve(appPath, 'strapi-admin') : path.resolve(appPath, 'packages', 'strapi-admin');
|
||||
}
|
||||
return path.resolve(appPath, 'admin');
|
||||
})();
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-helper-plugin",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Helper for Strapi plugins development",
|
||||
"engines": {
|
||||
"node": ">= 9.0.0",
|
||||
|
||||
@ -479,7 +479,7 @@ module.exports = function(strapi) {
|
||||
? column
|
||||
: `"${column}"`;
|
||||
|
||||
return ORM.knex.raw(`CREATE INDEX search_${_.toLower(indexName)} ON "${table}" USING gin(${attribute} gin_trgm_ops)`);
|
||||
return ORM.knex.raw(`CREATE INDEX IF NOT EXISTS search_${_.toLower(indexName)} ON "${table}" USING gin(${attribute} gin_trgm_ops)`);
|
||||
});
|
||||
|
||||
await Promise.all(indexes);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-hook-bookshelf",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Bookshelf hook for the Strapi framework",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
@ -21,8 +21,8 @@
|
||||
"lodash": "^4.17.5",
|
||||
"pluralize": "^6.0.0",
|
||||
"rimraf": "^2.6.2",
|
||||
"strapi-hook-knex": "3.0.0-alpha.14.3",
|
||||
"strapi-utils": "3.0.0-alpha.14.3"
|
||||
"strapi-hook-knex": "3.0.0-alpha.14.5",
|
||||
"strapi-utils": "3.0.0-alpha.14.5"
|
||||
},
|
||||
"strapi": {
|
||||
"dependencies": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-hook-ejs",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "EJS hook for the Strapi framework",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-hook-knex",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Knex hook for the Strapi framework",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -174,7 +174,10 @@ module.exports = function (strapi) {
|
||||
_.forEach(postLifecycle, (fn, key) => {
|
||||
if (_.isFunction(target[model.toLowerCase()][fn])) {
|
||||
collection.schema.post(key, function (doc, next) {
|
||||
target[model.toLowerCase()][fn](this, doc).then(next).catch(err => strapi.log.error(err));
|
||||
target[model.toLowerCase()][fn](this, doc).then(next).catch(err => {
|
||||
strapi.log.error(err);
|
||||
next(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -124,22 +124,11 @@ module.exports = {
|
||||
}
|
||||
|
||||
virtualFields.push(
|
||||
model.findOne({
|
||||
[model.primaryKey]: getValuePrimaryKey(value, model.primaryKey)
|
||||
module.exports.addRelation.call(model, {
|
||||
id: getValuePrimaryKey(value, this.primaryKey),
|
||||
values: _.pick(value, [this.primaryKey, details.via]),
|
||||
foreignKey: current
|
||||
})
|
||||
.populate([details.via])
|
||||
.lean()
|
||||
.then(entry => {
|
||||
if (_.isArray(entry[details.via])) {
|
||||
value[details.via] = entry[details.via].map(entry => _.get(entry, '_id', entry)).concat(value[details.via]);
|
||||
}
|
||||
|
||||
return module.exports.addRelation.call(model, {
|
||||
id: getValuePrimaryKey(value, this.primaryKey),
|
||||
values: _.pick(value, [this.primaryKey, details.via]),
|
||||
foreignKey: current
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-hook-mongoose",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Mongoose hook for the Strapi framework",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
@ -20,7 +20,7 @@
|
||||
"mongoose-float": "^1.0.2",
|
||||
"pluralize": "^6.0.0",
|
||||
"rimraf": "^2.6.2",
|
||||
"strapi-utils": "3.0.0-alpha.14.3"
|
||||
"strapi-utils": "3.0.0-alpha.14.5"
|
||||
},
|
||||
"author": {
|
||||
"email": "hi@strapi.io",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-hook-redis",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Redis hook for the Strapi framework",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
@ -19,7 +19,7 @@
|
||||
"lodash": "^4.17.5",
|
||||
"rimraf": "^2.6.2",
|
||||
"stack-trace": "0.0.10",
|
||||
"strapi-utils": "3.0.0-alpha.14.3"
|
||||
"strapi-utils": "3.0.0-alpha.14.5"
|
||||
},
|
||||
"author": {
|
||||
"email": "hi@strapi.io",
|
||||
|
||||
@ -16,7 +16,7 @@ const files = glob
|
||||
.filter(f => changedFiles.has(f))
|
||||
.filter(
|
||||
package =>
|
||||
!package.includes('README.md') &&
|
||||
!package.includes('CLI.md') &&
|
||||
!package.includes('strapi-middleware-views') &&
|
||||
!package.includes('strapi-lint') &&
|
||||
!package.includes('strapi-plugin-settings-manager'),
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-lint",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Strapi eslint and prettier configurations",
|
||||
"directories": {
|
||||
"lib": "lib"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-middleware-views",
|
||||
"version": "3.0.0-alpha.14.3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Views middleware to enable server-side rendering for the Strapi framework",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import moment from 'moment';
|
||||
import { isEmpty, isNull, isObject, toString } from 'lodash';
|
||||
import { isEmpty, isNull, isObject, toLower, toString } from 'lodash';
|
||||
import cn from 'classnames';
|
||||
|
||||
import CustomInputCheckbox from 'components/CustomInputCheckbox';
|
||||
@ -31,17 +31,17 @@ class TableRow extends React.Component {
|
||||
* @returns {*}
|
||||
*/
|
||||
getDisplayedValue(type, value, name) {
|
||||
switch (type.toLowerCase()) {
|
||||
switch (toLower(type)) {
|
||||
case 'string':
|
||||
case 'text':
|
||||
case 'email':
|
||||
case 'enumeration':
|
||||
return (value && !isEmpty(value.toString())) || name === 'id' ? value.toString() : '-';
|
||||
return (value && !isEmpty(toString(value))) || name === 'id' ? toString(value) : '-';
|
||||
case 'float':
|
||||
case 'integer':
|
||||
case 'biginteger':
|
||||
case 'decimal':
|
||||
return !isNull(value) ? value.toString() : '-';
|
||||
return !isNull(value) ? toString(value) : '-';
|
||||
case 'boolean':
|
||||
return value !== null ? toString(value) : '-';
|
||||
case 'date':
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
import { LOCATION_CHANGE } from 'react-router-redux';
|
||||
import { fork, put, call, takeLatest, take, cancel, select } from 'redux-saga/effects';
|
||||
import request from 'utils/request';
|
||||
|
||||
|
||||
import { getModelEntriesSucceeded, loadedModels, submitSucceeded } from './actions';
|
||||
import { GET_MODEL_ENTRIES, LOAD_MODELS, ON_SUBMIT } from './constants';
|
||||
import { makeSelectModifiedSchema } from './selectors';
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { LOCATION_CHANGE } from 'react-router-redux';
|
||||
import { findIndex, get, isArray, isEmpty, includes, isNumber, isString, map } from 'lodash';
|
||||
import {
|
||||
all,
|
||||
call,
|
||||
cancel,
|
||||
fork,
|
||||
@ -34,9 +35,9 @@ function* dataGet(action) {
|
||||
try {
|
||||
const modelName = yield select(makeSelectModelName());
|
||||
const params = { source: action.source };
|
||||
const [response] = yield [
|
||||
const [response] = yield all([
|
||||
call(request, `/content-manager/explorer/${modelName}/${action.id}`, { method: 'GET', params }),
|
||||
];
|
||||
]);
|
||||
const pluginHeaderTitle = yield call(templateObject, { mainField: action.mainField }, response);
|
||||
|
||||
yield put(getDataSucceeded(action.id, response, pluginHeaderTitle.mainField));
|
||||
@ -74,6 +75,7 @@ export function* submit() {
|
||||
const source = yield select(makeSelectSource());
|
||||
const schema = yield select(makeSelectSchema());
|
||||
let shouldAddTranslationSuffix = false;
|
||||
|
||||
// Remove the updated_at & created_at fields so it is updated correctly when using Postgres or MySQL db
|
||||
if (record.updated_at) {
|
||||
delete record.created_at;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
// Dependencies.
|
||||
import { LOCATION_CHANGE } from 'react-router-redux';
|
||||
import {
|
||||
all,
|
||||
call,
|
||||
cancel,
|
||||
fork,
|
||||
@ -9,10 +10,8 @@ import {
|
||||
take,
|
||||
takeLatest,
|
||||
} from 'redux-saga/effects';
|
||||
|
||||
// Utils.
|
||||
import request from 'utils/request';
|
||||
|
||||
// Actions
|
||||
import {
|
||||
deleteDataSuccess,
|
||||
@ -63,10 +62,10 @@ export function* dataGet(action) {
|
||||
params._q = _q;
|
||||
}
|
||||
|
||||
const response = yield [
|
||||
const response = yield all([
|
||||
call(request, countURL, { method: 'GET', params }),
|
||||
call(request, recordsURL, { method: 'GET', params }),
|
||||
];
|
||||
]);
|
||||
|
||||
yield put(getDataSucceeded(response));
|
||||
} catch(err) {
|
||||
|
||||
@ -47,12 +47,12 @@
|
||||
"containers.SettingPage.addRelationalField": "Füge ein neues relationales Feld hinzu",
|
||||
"containers.SettingPage.attributes": "Attribut Felder",
|
||||
"containers.SettingPage.attributes.description": "Reihenfolge der Attribute festlegen",
|
||||
"containers.SettingPage.editSettings.description": "Drag & drop the fields to build the layout",
|
||||
"containers.SettingPage.editSettings.title": "Edit — Settings",
|
||||
"containers.SettingPage.editSettings.description": "Ziehen die Felder via Drag & Drop, um das Layout zu erstellen",
|
||||
"containers.SettingPage.editSettings.title": "Bearbeiten — Einstellungen",
|
||||
"containers.SettingPage.listSettings.description": "Konfiguriere die Optionen für diesen Inhaltstyp.",
|
||||
"containers.SettingPage.listSettings.title": "Liste - Einstellungen",
|
||||
"containers.SettingPage.pluginHeaderDescription": "Konfiguriere die spezifischen Einstellungen für diesen Inhaltstyp.",
|
||||
"containers.SettingPage.relations": "Relational fields",
|
||||
"containers.SettingPage.relations": "Relational Felder",
|
||||
"containers.SettingsPage.Block.contentType.description": "Konfiguriere die spezifischen Einstellungen.",
|
||||
"containers.SettingsPage.Block.contentType.title": "Inhaltstypen",
|
||||
"containers.SettingsPage.Block.generalSettings.description": "Konfiguriere die Standardoptionen für deine Inhaltstypen.",
|
||||
@ -83,9 +83,9 @@
|
||||
"error.validation.required": "Dieser Wert ist erforderlich.",
|
||||
"form.Input.bulkActions": "Bulk-Bearbeitung aktivieren",
|
||||
"form.Input.defaultSort": "Standard-Sortierattribut",
|
||||
"form.Input.description": "Description",
|
||||
"form.Input.description.placeholder": "Display name in the profile",
|
||||
"form.Input.disabled": "Editable field",
|
||||
"form.Input.description": "Beschreibung",
|
||||
"form.Input.description.placeholder": "Zeige den Namen im Profil",
|
||||
"form.Input.disabled": "Editierbares Feld",
|
||||
"form.Input.filters": "Filter aktivieren",
|
||||
"form.Input.label": "Label",
|
||||
"form.Input.label.inputDescription": "Dieser Wert überschreibt das im Kopf der Tabelle angezeigte Label.",
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"EditRelations.title": "Données associées",
|
||||
"components.AddFilterCTA.add": "Filtres",
|
||||
"components.AddFilterCTA.hide": "Filtres",
|
||||
"components.DraggableAttr.edit": "Clicquez pour modifier",
|
||||
"components.DraggableAttr.edit": "Cliquez pour modifier",
|
||||
"components.EmptyAttributesBlock.button": "Voir la page des configurations",
|
||||
"components.EmptyAttributesBlock.description": "Vous pouvez modifiez vos paramètres",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "est",
|
||||
@ -46,16 +46,16 @@
|
||||
"containers.SettingPage.addField": "Ajouter un nouveau champs",
|
||||
"containers.SettingPage.addRelationalField": "Ajouter un nouveau champs relationnel",
|
||||
"containers.SettingPage.attributes": "Attributs",
|
||||
"containers.SettingPage.attributes.description": "Organiser les attributs du modèle",
|
||||
"containers.SettingPage.attributes.description": "Organisez les attributs du modèle",
|
||||
"containers.SettingPage.editSettings.description": "Glissez & déposez les champs pour construire le layout",
|
||||
"containers.SettingPage.editSettings.title": "Edit — Paramètres",
|
||||
"containers.SettingPage.listSettings.description": "Configurez les options de ce modèle",
|
||||
"containers.SettingPage.listSettings.title": "Liste — Paramètres",
|
||||
"containers.SettingPage.pluginHeaderDescription": "Configurez les paramètres de ce modèle",
|
||||
"containers.SettingPage.relations": "Champs relationnels",
|
||||
"containers.SettingsPage.Block.contentType.description": "Configurer les paramètres spécifiques",
|
||||
"containers.SettingsPage.Block.contentType.description": "Configurez les paramètres spécifiques",
|
||||
"containers.SettingsPage.Block.contentType.title": "Types de contenu",
|
||||
"containers.SettingsPage.Block.generalSettings.description": "Configurez les options par défault de vos modèles",
|
||||
"containers.SettingsPage.Block.generalSettings.description": "Configurez les options par défault de vos modèles",
|
||||
"containers.SettingsPage.Block.generalSettings.title": "Général",
|
||||
"containers.SettingsPage.pluginHeaderDescription": "Configurez les paramètres par défaut de vos modèles",
|
||||
"emptyAttributes.button": "Ouvrir le Content Type Builder",
|
||||
@ -84,17 +84,17 @@
|
||||
"form.Input.bulkActions": "Autoriser les actions groupées",
|
||||
"form.Input.defaultSort": "Attribut de tri par défault",
|
||||
"form.Input.description": "Description",
|
||||
"form.Input.description.placeholder": "Afficher le nom dans le profile",
|
||||
"form.Input.description.placeholder": "Afficher le nom dans le profil",
|
||||
"form.Input.disabled": "Champ editable",
|
||||
"form.Input.filters": "Autoriser les filtres",
|
||||
"form.Input.label": "Label",
|
||||
"form.Input.label.inputDescription": "Cette valeur modifie celle du champs de la table",
|
||||
"form.Input.pageEntries": "Nombre d'entrées par page",
|
||||
"form.Input.pageEntries.inputDescription": "Note: Vous pouvez modifier ces valeurs par modèle",
|
||||
"form.Input.pageEntries.inputDescription": "Note : Vous pouvez modifier ces valeurs par modèle",
|
||||
"form.Input.placeholder": "Placeholder",
|
||||
"form.Input.placeholder.placeholder": "Mon super placeholder",
|
||||
"form.Input.search": "Autoriser la search",
|
||||
"form.Input.search.field": "Autoriser la search sur ce champs",
|
||||
"form.Input.search": "Autoriser la recherche",
|
||||
"form.Input.search.field": "Autoriser la recherche sur ce champs",
|
||||
"form.Input.sort.field": "Autoriser le tri sur ce champs",
|
||||
"notification.error.displayedFields": "Vous devez avoir au moins un champ d'affiché",
|
||||
"notification.error.relationship.fetch": "Une erreur est survenue en récupérant les relations.",
|
||||
@ -107,8 +107,9 @@
|
||||
"popUpWarning.button.cancel": "Annuler",
|
||||
"popUpWarning.button.confirm": "Confirmer",
|
||||
"popUpWarning.title": "Confirmation requise",
|
||||
"popUpWarning.warning.cancelAllSettings": "Êtes-vous sûr de vouloir vos modifications?",
|
||||
"popUpWarning.warning.cancelAllSettings": "Êtes-vous sûr de vouloir abandonner vos modifications ?",
|
||||
"popUpWarning.warning.updateAllSettings": "Cela modifiera tous vos précédents paramètres.",
|
||||
"success.record.delete": "Supprimé",
|
||||
"success.record.save": "Sauvegardé"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
"components.AddFilterCTA.add": "Filtri",
|
||||
"components.AddFilterCTA.hide": "Filtri",
|
||||
"components.DraggableAttr.edit": "Clicca per modificare",
|
||||
"components.EmptyAttributesBlock.button": "Vai alla pagina delle impostazioni",
|
||||
"components.EmptyAttributesBlock.description" : "Puoi cambiare le tue impostazioni",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "si",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "contiene",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "contiene (maiuscole e minuscole)",
|
||||
@ -25,11 +27,14 @@
|
||||
"components.TableEmpty.withFilters": "Non vi è alcun {contentType} con l'applicazione di filtri...",
|
||||
"components.TableEmpty.withSearch": "Non vi è alcun {contentType} corrispondente alla ricerca ({search})...",
|
||||
"components.TableEmpty.withoutFilter": "Non vi è alcun {contentType}...",
|
||||
"containers.Edit.addAnItem": "Aggiungi un elemento...",
|
||||
"containers.Edit.clickToJump": "Clicca per andare alla riga",
|
||||
"containers.Edit.delete": "Elimina",
|
||||
"containers.Edit.editing": "Modificando...",
|
||||
"containers.Edit.reset": "Resetta",
|
||||
"containers.Edit.returnList": "Tornare alla lista",
|
||||
"containers.Edit.submit": "Salva",
|
||||
"containers.Edit.seeDetails": "Dettagli",
|
||||
"containers.Home.introduction": "Per modificare le voci, visitare il link nel menu di sinistra. Questo plugin non ha un suo modo corretto di modificare le impostazioni ed è ancora in fase di sviluppo attivo.",
|
||||
"containers.Home.pluginHeaderDescription": "Gestire le voci attraverso un potente e bella interfaccia.",
|
||||
"containers.Home.pluginHeaderTitle": "Content Manager",
|
||||
@ -37,9 +42,14 @@
|
||||
"containers.List.errorFetchRecords": "Errore",
|
||||
"containers.List.pluginHeaderDescription": "{label} voci non trovato",
|
||||
"containers.List.pluginHeaderDescription.singular": "{label} voce trovati",
|
||||
"containers.ListPage.displayedFields": "Campi visualizzati",
|
||||
"containers.SettingPage.addField": "Aggiungi un nuovo campo",
|
||||
"containers.SettingPage.addRelationalField": "Aggiungi nuovo campo relazionale",
|
||||
"containers.SettingPage.attributes": "Attributi",
|
||||
"containers.SettingPage.attributes.description": "Definisci l'ordine degli attributi",
|
||||
"containers.SettingPage.editSettings.description": "Sposta il campo per costruire il layout",
|
||||
"containers.SettingPage.editSettings.title": "Modifica - Impostazioni",
|
||||
"containers.SettingPage.relations": "Campi relazionali",
|
||||
"containers.SettingPage.listSettings.description": "Configura le opzioni per questo Tipo di Contenuto",
|
||||
"containers.SettingPage.listSettings.title": "Lista — Impostazioni",
|
||||
"containers.SettingPage.pluginHeaderDescription": "Configura le impostazioni specifiche per questo Tipo di Contenuto",
|
||||
@ -81,9 +91,12 @@
|
||||
"form.Input.label.inputDescription": "Questo valore sovrascrive l'etichetta mostrata nell'intestazione della tabella",
|
||||
"form.Input.pageEntries": "Righe per pagina",
|
||||
"form.Input.pageEntries.inputDescription": "Attenzione: Puoi sovrascrivere questo valore nella pagina delle impostazioni del Tipo di Contenuto",
|
||||
"form.Input.placeholder": "Segnaposto",
|
||||
"form.Input.placeholder.placeholder": "Il mio fantastico valore",
|
||||
"form.Input.search": "Abilita ricerca",
|
||||
"form.Input.search.field": "Abilita la ricerca su questo campo",
|
||||
"form.Input.sort.field": "Abilita ordinamento su questo campo",
|
||||
"notification.error.displayedFields": "E' necessario almeno un campo visualizzato",
|
||||
"notification.error.relationship.fetch": "Si è verificato un errore durante il rapporto di recupero.",
|
||||
"notification.info.SettingPage.disableSort": "E' necessario un attributo con l'ordinamento abilitato",
|
||||
"pageNotFound": "Pagina non trovata",
|
||||
@ -98,4 +111,4 @@
|
||||
"popUpWarning.warning.updateAllSettings": "Questa operazione modificherà tutte le tue impostazioni",
|
||||
"success.record.delete": "Eliminato",
|
||||
"success.record.save": "Salvato"
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,114 @@
|
||||
{
|
||||
"EditRelations.title": "リレーショナルデータ",
|
||||
"components.AddFilterCTA.add": "フィルタ",
|
||||
"components.AddFilterCTA.hide": "フィルタ",
|
||||
"components.DraggableAttr.edit": "クリックして編集",
|
||||
"components.EmptyAttributesBlock.button": "設定ページに移動",
|
||||
"components.EmptyAttributesBlock.description": "設定を変更することができます",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "は",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "含まれる",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "含まれる(大文字と小文字を区別)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "より大きい",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "より大きい、もしくは、等しい",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "より低い",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "より低い、もしくは、等しい",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "ではない",
|
||||
"components.FilterOptions.button.apply": "適用",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "適用",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "すべてクリア",
|
||||
"components.FiltersPickWrapper.PluginHeader.description": "エントリをフィルタリングするための条件を設定する",
|
||||
"components.FiltersPickWrapper.PluginHeader.title.filter": "フィルタ",
|
||||
"components.FiltersPickWrapper.hide": "隠す",
|
||||
"components.LimitSelect.itemsPerPage": "ページあたりのアイテム数",
|
||||
"components.Search.placeholder": "エントリを検索する...",
|
||||
"components.TableDelete.delete": "すべて削除",
|
||||
"components.TableDelete.entries.plural": "{number} 個のエントリが選択されました",
|
||||
"components.TableDelete.entries.singular": "{number} 個のエントリが選択されました",
|
||||
"components.TableEmpty.withFilters": "適用されたフィルタには{contentType}はありません...",
|
||||
"components.TableEmpty.withSearch": "検索に対応する{contentType}はありません({search})...",
|
||||
"components.TableEmpty.withoutFilter": "{contentType}はありません...",
|
||||
"containers.Edit.addAnItem": "アイテムを追加する...",
|
||||
"containers.Edit.clickToJump": "クリックするとエントリにジャンプします",
|
||||
"containers.Edit.delete": "削除",
|
||||
"containers.Edit.editing": "編集...",
|
||||
"containers.Edit.reset": "リセット",
|
||||
"containers.Edit.returnList": "リストに戻る",
|
||||
"containers.Edit.seeDetails": "詳細",
|
||||
"containers.Edit.submit": "保存",
|
||||
"containers.Home.introduction": "あなたのエントリーを編集するには、左側のメニューの特定のリンクに行きます。このプラグインは設定を編集する適切な方法がなく、まだアクティブな開発中です",
|
||||
"containers.Home.pluginHeaderDescription": "パワフルで美しいインターフェイスでエントリを管理します。",
|
||||
"containers.Home.pluginHeaderTitle": "コンテンツ マネージャ",
|
||||
"containers.List.addAnEntry": "{entity}を追加",
|
||||
"containers.List.errorFetchRecords": "エラー",
|
||||
"containers.List.pluginHeaderDescription": "{label} 個のエントリーが見つかりました",
|
||||
"containers.List.pluginHeaderDescription.singular": "{label} 個のエントリーが見つかりました",
|
||||
"containers.ListPage.displayedFields": "フィールドが表示されました",
|
||||
"containers.SettingPage.addField": "フィールドを追加",
|
||||
"containers.SettingPage.addRelationalField": "新しいリレーショナルフィールドを追加する",
|
||||
"containers.SettingPage.attributes": "属性フィールド",
|
||||
"containers.SettingPage.attributes.description": "属性の順序を定義する",
|
||||
"containers.SettingPage.editSettings.description": "フィールドをドラッグアンドドロップしてレイアウトを作成する",
|
||||
"containers.SettingPage.editSettings.title": "編集 — 設定",
|
||||
"containers.SettingPage.listSettings.description": "このコンテンツタイプのオプションを構成する",
|
||||
"containers.SettingPage.listSettings.title": "一覧 — 設定",
|
||||
"containers.SettingPage.pluginHeaderDescription": "このコンテンツタイプの特定の設定を構成する",
|
||||
"containers.SettingPage.relations": "リレーショナルフィールド",
|
||||
"containers.SettingsPage.Block.contentType.description": "特定の設定を構成する",
|
||||
"containers.SettingsPage.Block.contentType.title": "コンテンツタイプ",
|
||||
"containers.SettingsPage.Block.generalSettings.description": "コンテンツタイプのデフォルトオプションを設定する",
|
||||
"containers.SettingsPage.Block.generalSettings.title": "一般",
|
||||
"containers.SettingsPage.pluginHeaderDescription": "すべてのコンテンツタイプのデフォルト設定を構成する",
|
||||
"emptyAttributes.button": "コンテンツタイプビルダーに移動",
|
||||
"emptyAttributes.description": "コンテンツタイプに最初のフィールドを追加する",
|
||||
"emptyAttributes.title": "フィールドはまだありません",
|
||||
"error.attribute.key.taken": "この値は既に存在します",
|
||||
"error.attribute.sameKeyAndName": "同じにすることはできません",
|
||||
"error.attribute.taken": "このフィールド名は既に存在します",
|
||||
"error.contentTypeName.taken": "この名前は既に存在します",
|
||||
"error.model.fetch": "モデルの設定フェッチ中にエラーが発生しました",
|
||||
"error.record.create": "レコードの作成中にエラーが発生しました",
|
||||
"error.record.delete": "レコードの削除中にエラーが発生しました",
|
||||
"error.record.fetch": "レコードの取得中にエラーが発生しました",
|
||||
"error.record.update": "レコードの更新中にエラーが発生しました",
|
||||
"error.records.count": "カウントレコードのフェッチ中にエラーが発生しました.",
|
||||
"error.records.fetch": "レコードの取得中にエラーが発生しました",
|
||||
"error.schema.generation": "スキーマの生成中にエラーが発生しました",
|
||||
"error.validation.json": "これはJSONではありません",
|
||||
"error.validation.max": "値が高すぎます",
|
||||
"error.validation.maxLength": "値が長すぎます",
|
||||
"error.validation.min": "値が低すぎます",
|
||||
"error.validation.minLength": "値が小さすぎます",
|
||||
"error.validation.minSupMax": "優れていることはできません",
|
||||
"error.validation.regex": "値は正規表現と一致しません",
|
||||
"error.validation.required": "この値の入力は必須です",
|
||||
"form.Input.bulkActions": "一括処理を有効にする",
|
||||
"form.Input.defaultSort": "デフォルトのソート属性",
|
||||
"form.Input.description": "説明文",
|
||||
"form.Input.description.placeholder": "プロフィールの表示名",
|
||||
"form.Input.disabled": "編集可能なフィールド",
|
||||
"form.Input.filters": "フィルタを有効にする",
|
||||
"form.Input.label": "Label",
|
||||
"form.Input.label.inputDescription": "この値は、テーブルの先頭に表示されるラベル",
|
||||
"form.Input.pageEntries": "1ページあたりのエントリ数",
|
||||
"form.Input.pageEntries.inputDescription": "注:コンテンツタイプ設定ページでこの値を上書きすることができます。",
|
||||
"form.Input.placeholder": "プレースホルダー",
|
||||
"form.Input.placeholder.placeholder": "My awesome value",
|
||||
"form.Input.search": "検索を有効にする",
|
||||
"form.Input.search.field": "このフィールドで検索を有効にする",
|
||||
"form.Input.sort.field": "このフィールドでソートを有効にする",
|
||||
"notification.error.displayedFields": "少なくとも1つの表示フィールドが必要です",
|
||||
"notification.error.relationship.fetch": "リレーションシップフェッチ中にエラーが発生しました",
|
||||
"notification.info.SettingPage.disableSort": "並べ替えを許可する属性が1つ必要です",
|
||||
"pageNotFound": "ページが見つかりません",
|
||||
"plugin.description.long": "データベース内のデータを表示、編集、削除するための方法。",
|
||||
"plugin.description.short": "データベース内のデータを表示、編集、削除するための方法。",
|
||||
"popUpWarning.bodyMessage.contentType.delete": "このエントリを削除してもよろしいですか?",
|
||||
"popUpWarning.bodyMessage.contentType.delete.all": "これらのエントリを削除してもよろしいですか?",
|
||||
"popUpWarning.button.cancel": "キャンセル",
|
||||
"popUpWarning.button.confirm": "確認",
|
||||
"popUpWarning.title": "確認してください",
|
||||
"popUpWarning.warning.cancelAllSettings": "変更をキャンセルしてもよろしいですか?",
|
||||
"popUpWarning.warning.updateAllSettings": "これにより、すべての設定が変更されます",
|
||||
"success.record.delete": "削除",
|
||||
"success.record.save": "保存"
|
||||
}
|
||||
@ -3,6 +3,8 @@
|
||||
"components.AddFilterCTA.add": "Filtros",
|
||||
"components.AddFilterCTA.hide": "Filtros",
|
||||
"components.DraggableAttr.edit": "Clique para editar",
|
||||
"components.EmptyAttributesBlock.button": "Ir para página de configurações",
|
||||
"components.EmptyAttributesBlock.description": "Você pode alterar suas configurações",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "é",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "contém",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "contém (case sensitive)",
|
||||
@ -25,10 +27,13 @@
|
||||
"components.TableEmpty.withFilters": "Nenhum {contentType} com os filtros aplicados...",
|
||||
"components.TableEmpty.withSearch": "Nenhum {contentType} encontrado na pesquisa ({search})...",
|
||||
"components.TableEmpty.withoutFilter": "Nenhum {contentType}...",
|
||||
"containers.Edit.addAnItem": "Adicione um item...",
|
||||
"containers.Edit.clickToJump": "Clique para pular para o registro",
|
||||
"containers.Edit.delete": "Remove",
|
||||
"containers.Edit.editing": "Editando...",
|
||||
"containers.Edit.reset": "Reiniciar",
|
||||
"containers.Edit.returnList": "Retornar à lista",
|
||||
"containers.Edit.seeDetails": "Detalhes",
|
||||
"containers.Edit.submit": "Salvar",
|
||||
"containers.Home.introduction": "Para editar seus registros, acesse o link específico no menu à esquerda. Esta extensão não permite editar configurações, ainda está em desenvolvimento.",
|
||||
"containers.Home.pluginHeaderDescription": "Gerencie seus registros através de uma interface poderosa e elegante.",
|
||||
@ -37,15 +42,17 @@
|
||||
"containers.List.errorFetchRecords": "Erro",
|
||||
"containers.List.pluginHeaderDescription": "{label} registros encontrados",
|
||||
"containers.List.pluginHeaderDescription.singular": "{label} registro encontrado",
|
||||
"containers.ListPage.displayedFields": "Campos exibidos",
|
||||
"containers.SettingPage.addField": "Adicionar campo",
|
||||
"containers.SettingPage.addRelationalField": "Adicionar novo campo relacional",
|
||||
"containers.SettingPage.attributes": "Atributos",
|
||||
"containers.SettingPage.attributes.description": "Define a ordem dos atributos",
|
||||
"containers.SettingPage.editSettings.description": "Drag & drop the fields to build the layout",
|
||||
"containers.SettingPage.editSettings.title": "Edit — Settings",
|
||||
"containers.SettingPage.editSettings.description": "Arraste e solte os campos para construir o layout",
|
||||
"containers.SettingPage.editSettings.title": "Editar — Configurações",
|
||||
"containers.SettingPage.listSettings.description": "Configure as opções para este Tipo de Conteúdo",
|
||||
"containers.SettingPage.listSettings.title": "Lista — Configurações",
|
||||
"containers.SettingPage.pluginHeaderDescription": "Defina as configurações específicas para este Tipo de Conteúdo",
|
||||
"containers.SettingPage.relations": "Relational fields",
|
||||
"containers.SettingPage.relations": "Campos relacionais",
|
||||
"containers.SettingsPage.Block.contentType.description": "Defina as configurações específicas",
|
||||
"containers.SettingsPage.Block.contentType.title": "Tipos de Conteúdo",
|
||||
"containers.SettingsPage.Block.generalSettings.description": "Configure as opções padrões para seu Tipo de Conteúdo",
|
||||
@ -76,14 +83,20 @@
|
||||
"error.validation.required": "O valor deste registro é obrigatório.",
|
||||
"form.Input.bulkActions": "Habilitar ações em lote",
|
||||
"form.Input.defaultSort": "Atributo de ordenação padrão",
|
||||
"form.Input.description": "Descrição",
|
||||
"form.Input.description.placeholder": "Nome exibido no perfil",
|
||||
"form.Input.disabled": "Campo editável",
|
||||
"form.Input.filters": "Habilitar filtros",
|
||||
"form.Input.label": "Rótulo",
|
||||
"form.Input.label.inputDescription": "Este valor substitui o rótulo apresentado no cabeçalho da tabela",
|
||||
"form.Input.pageEntries": "Entradas por página",
|
||||
"form.Input.pageEntries.inputDescription": "Nota: Você pode substituir este valor na página de configurações do Tipo de Conteúdo.",
|
||||
"form.Input.placeholder": "Placeholder",
|
||||
"form.Input.placeholder.placeholder": "Meu valor incrível",
|
||||
"form.Input.search": "Habilitar busca",
|
||||
"form.Input.search.field": "Habilitar busca neste campo",
|
||||
"form.Input.sort.field": "Habilitar ordenação neste campo",
|
||||
"notification.error.displayedFields": "Você precisa ao menos um campo exibido",
|
||||
"notification.error.relationship.fetch": "Ocorreu um erro durante a busca da relação.",
|
||||
"notification.info.SettingPage.disableSort": "Você precisa de um atributo com permissão de ordenação",
|
||||
"pageNotFound": "Página não encontrada",
|
||||
@ -98,4 +111,4 @@
|
||||
"popUpWarning.warning.updateAllSettings": "Isto irá modificar todas as suas configurações",
|
||||
"success.record.delete": "Removido",
|
||||
"success.record.save": "Salvo"
|
||||
}
|
||||
}
|
||||
|
||||