mirror of
https://github.com/strapi/strapi.git
synced 2025-11-03 19:36:20 +00:00
Merge branch 'master' into enhancement/pr-auto-close
This commit is contained in:
commit
8fdb12a009
12
.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
vendored
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:**
|
||||
|
||||
|
||||
@ -74,7 +74,7 @@ To use the providers authentication, set your credentials in
|
||||
|
||||
Redirect your user to: `GET /connect/:provider`.
|
||||
|
||||
After his approval, he will be redirected to `/auth/:provider/callback`. The jwt and user will be available in the querystring.
|
||||
After their approval, they will be redirected to `/auth/:provider/callback`. The jwt and user will be available in the querystring.
|
||||
|
||||
Response payload:
|
||||
|
||||
|
||||
@ -26,11 +26,11 @@ By default Strapi provides a local email system. You might want to send email wi
|
||||
To install a new provider run:
|
||||
|
||||
```
|
||||
$ npm install strapi-email-sendgrid@alpha --save
|
||||
$ npm install strapi-provider-email-sendgrid@alpha --save
|
||||
```
|
||||
|
||||
We have two providers available `strapi-email-sendgrid` and `strapi-upload-mailgun`, use the alpha tag to install one of them. Then, visit `/admin/plugins/email/configurations/development` on your web browser and configure the provider.
|
||||
We have two providers available `strapi-provider-email-sendgrid` and `strapi-provider-upload-mailgun`, use the alpha tag to install one of them. Then, visit `/admin/plugins/email/configurations/development` on your web browser and configure the provider.
|
||||
|
||||
If you want to create your own, make sure the name starts with `strapi-email-` (duplicating an existing one will be easier to create), modify the `auth` config object and customize the `send` functions.
|
||||
If you want to create your own, make sure the name starts with `strapi-provider-email-` (duplicating an existing one will be easier to create), modify the `auth` config object and customize the `send` functions.
|
||||
|
||||
Check all community providers available on npmjs.org - [Providers list](https://www.npmjs.com/search?q=strapi-email-)
|
||||
Check all community providers available on npmjs.org - [Providers list](https://www.npmjs.com/search?q=strapi-provider-email-)
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -296,7 +296,7 @@ A `product` can be related to many `categories`, so a `category` can have many `
|
||||
```
|
||||
|
||||
::: note
|
||||
The `dominant` key allows you to define in which table/collection (only for NoSQL databases) should be stored the array that defines the relationship. Because there is no join table in NoSQL, this key is required for NoSQL databases (ex: MongoDB).
|
||||
(NoSQL databases only) The `dominant` key defines which table/collection should store the array that defines the relationship. Because there are no join tables in NoSQL, this key is required for NoSQL databases (ex: MongoDB).
|
||||
:::
|
||||
|
||||
**Path —** `./api/category/models/Category.settings.json`.
|
||||
|
||||
@ -17,7 +17,7 @@ Please send the request using multipart/form-data encoding
|
||||
**Parameters**
|
||||
|
||||
- `files`: The file(s) to upload. The value(s) can be a Buffer or Stream.
|
||||
- `path`: (optional): The folder where the file(s) will be uploaded to (only supported on strapi-upload-aws-s3 now).
|
||||
- `path`: (optional): The folder where the file(s) will be uploaded to (only supported on strapi-provider-upload-aws-s3 now).
|
||||
- `refId`: (optional): The ID of the entry which the file(s) will be linked to.
|
||||
- `ref`: (optional): The name of the model which the file(s) will be linked to (see more below).
|
||||
- `source`: (optional): The name of the plugin where the model is located.
|
||||
@ -136,11 +136,11 @@ By default Strapi provides a local file upload system. You might want to upload
|
||||
To install a new provider run:
|
||||
|
||||
```
|
||||
$ npm install strapi-upload-aws-s3@alpha --save
|
||||
$ npm install strapi-provider-upload-aws-s3@alpha --save
|
||||
```
|
||||
|
||||
We have two providers available `strapi-upload-aws-s3` and `strapi-upload-cloudinary`, use the alpha tag to install one of them. Then, visit `/admin/plugins/upload/configurations/development` on your web browser and configure the provider.
|
||||
We have two providers available `strapi-provider-upload-aws-s3` and `strapi-provider-upload-cloudinary`, use the alpha tag to install one of them. Then, visit `/admin/plugins/upload/configurations/development` on your web browser and configure the provider.
|
||||
|
||||
If you want to create your own, make sure the name starts with `strapi-upload-` (duplicating an existing one will be easier to create), modify the `auth` config object and customize the `upload` and `delete` functions.
|
||||
If you want to create your own, make sure the name starts with `strapi-provider-upload-` (duplicating an existing one will be easier to create), modify the `auth` config object and customize the `upload` and `delete` functions.
|
||||
|
||||
Check all community providers available on npmjs.org - [Providers list](https://www.npmjs.com/search?q=strapi-upload-)
|
||||
Check all community providers available on npmjs.org - [Providers list](https://www.npmjs.com/search?q=strapi-provider-upload-)
|
||||
|
||||
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright@React-FullStory (https://github.com/cereallarceny/react-fullstory)
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const canUseDOM = !!(
|
||||
typeof window !== 'undefined' &&
|
||||
window.document &&
|
||||
window.document.createElement
|
||||
);
|
||||
|
||||
export const getWindowFullStory = () => window[window['_fs_namespace']];
|
||||
|
||||
class FullStory extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
window['_fs_debug'] = false;
|
||||
window['_fs_host'] = 'fullstory.com';
|
||||
window['_fs_org'] = props.org;
|
||||
window['_fs_namespace'] = 'FS';
|
||||
(function(m,n,e,t,l,o,g,y) {
|
||||
if (e in m) {
|
||||
if(m.console && m.console.log) {
|
||||
m.console.log('FullStory namespace conflict. Please set window["_fs_namespace"].');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
g = m[e]= function(a,b,s) {
|
||||
g.q ? g.q.push([a,b,s]) : g._api(a,b,s);
|
||||
};
|
||||
g.q=[];
|
||||
o = n.createElement(t);
|
||||
o.async = 1;
|
||||
o.src = `https://${window._fs_host}/s/fs.js`;
|
||||
y = n.getElementsByTagName(t)[0];
|
||||
y.parentNode.insertBefore(o,y);
|
||||
g.identify = function(i,v,s) {
|
||||
g(l,{ uid:i },s);
|
||||
|
||||
if (v) {
|
||||
g(l,v,s);
|
||||
}
|
||||
};
|
||||
g.setUserVars = function(v,s) {
|
||||
g(l,v,s);
|
||||
};
|
||||
g.event = function(i,v,s) {
|
||||
g('event',{ n:i,p:v },s);
|
||||
};
|
||||
g.shutdown = function() {
|
||||
g("rec",!1);
|
||||
};
|
||||
g.restart = function() {
|
||||
g("rec",!0);
|
||||
};
|
||||
g.consent = function(a) {
|
||||
g("consent",!arguments.length||a);
|
||||
};
|
||||
g.identifyAccount = function(i,v) {
|
||||
o = 'account';
|
||||
v = v||{};
|
||||
v.acctId = i;
|
||||
g(o,v);
|
||||
};
|
||||
g.clearUserCookie = function() {};
|
||||
})(window, document, window['_fs_namespace'], 'script', 'user');
|
||||
}
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (!canUseDOM || !getWindowFullStory()) return false;
|
||||
|
||||
getWindowFullStory().shutdown();
|
||||
|
||||
delete getWindowFullStory();
|
||||
}
|
||||
|
||||
render() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
FullStory.propTypes = {
|
||||
org: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default FullStory;
|
||||
@ -1,3 +1,3 @@
|
||||
{
|
||||
"languages": ["en", "ar", "es", "fr", "de", "it", "ko", "nl", "pl", "pt", "pt-BR", "ru", "tr", "zh", "zh-Hans", "ja"]
|
||||
"languages": ["en", "ar", "es", "fa", "fr", "de", "it", "ko", "nl", "pl", "pt", "pt-BR", "ru", "tr", "zh", "zh-Hans", "ja"]
|
||||
}
|
||||
|
||||
@ -43,6 +43,7 @@ import Logout from 'components/Logout';
|
||||
import NotFoundPage from 'containers/NotFoundPage/Loadable';
|
||||
import OverlayBlocker from 'components/OverlayBlocker';
|
||||
import PluginPage from 'containers/PluginPage';
|
||||
import FullStory from 'components/FullStory';
|
||||
// Utils
|
||||
import auth from 'utils/auth';
|
||||
import injectReducer from 'utils/injectReducer';
|
||||
@ -73,12 +74,12 @@ export class AdminPage extends React.Component {
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const { adminPage: { allowGa }, location: { pathname }, plugins } = this.props;
|
||||
const { adminPage: { uuid }, location: { pathname }, plugins } = this.props;
|
||||
|
||||
if (prevProps.location.pathname !== pathname) {
|
||||
this.checkLogin(this.props);
|
||||
|
||||
if (allowGa) {
|
||||
if (uuid) {
|
||||
ReactGA.pageview(pathname);
|
||||
}
|
||||
}
|
||||
@ -198,6 +199,7 @@ export class AdminPage extends React.Component {
|
||||
|
||||
return (
|
||||
<div className={styles.adminPage}>
|
||||
{this.props.adminPage.uuid ? <FullStory org="GK708" /> : ''}
|
||||
{this.showLeftMenu() && (
|
||||
<LeftMenu
|
||||
plugins={this.retrievePlugins()}
|
||||
|
||||
@ -11,7 +11,7 @@ import {
|
||||
} from './constants';
|
||||
|
||||
const initialState = fromJS({
|
||||
allowGa: true,
|
||||
uuid: false,
|
||||
currentEnvironment: 'development',
|
||||
isLoading: true,
|
||||
layout: Map({}),
|
||||
@ -22,7 +22,7 @@ function adminPageReducer(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
case GET_ADMIN_DATA_SUCCEEDED:
|
||||
return state
|
||||
.update('allowGa', () => action.data.allowGa)
|
||||
.update('uuid', () => action.data.uuid)
|
||||
.update('currentEnvironment', () => action.data.currentEnvironment)
|
||||
.update('layout', () => Map(action.data.layout))
|
||||
.update('strapiVersion', () => action.data.strapiVersion)
|
||||
|
||||
@ -16,13 +16,13 @@ function* getData() {
|
||||
yield call(request, `${strapi.backendURL}/users/me`, { method: 'GET' });
|
||||
}
|
||||
|
||||
const [{ allowGa }, { strapiVersion }, { currentEnvironment }, { layout }] = yield all([
|
||||
const [{ uuid }, { strapiVersion }, { currentEnvironment }, { layout }] = yield all([
|
||||
call(request, '/admin/gaConfig', { method: 'GET' }),
|
||||
call(request, '/admin/strapiVersion', { method: 'GET' }),
|
||||
call(request, '/admin/currentEnvironment', { method: 'GET' }),
|
||||
call(request, '/admin/layout', { method: 'GET' }),
|
||||
]);
|
||||
yield put(getAdminDataSucceeded({ allowGa, strapiVersion, currentEnvironment, layout }));
|
||||
yield put(getAdminDataSucceeded({ uuid, strapiVersion, currentEnvironment, layout }));
|
||||
|
||||
} catch(err) {
|
||||
console.log(err); // eslint-disable-line no-console
|
||||
|
||||
@ -37,6 +37,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/kr.svg';
|
||||
case 'ja':
|
||||
return 'https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.1.0/flags/4x3/jp.svg';
|
||||
case 'fa':
|
||||
return 'https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.1.0/flags/4x3/ir.svg';
|
||||
default:
|
||||
return `https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.1.0/flags/4x3/${locale}.svg`;
|
||||
}
|
||||
|
||||
@ -28,19 +28,19 @@
|
||||
"app.components.EmptyAttributes.title": "Aún no hay campos",
|
||||
"app.components.HomePage.button.blog": "VER MÁS EN EL BLOG",
|
||||
"app.components.HomePage.button.quickStart": "INICIAR EL TUTORIAL DE INICIO RÁPIDO",
|
||||
"app.components.HomePage.community": "Encuentra la comunidad en la web",
|
||||
"app.components.HomePage.community.content": "Discutir con los miembros del equipo, colaboradores y desarrolladores en diferentes canales.",
|
||||
"app.components.HomePage.community": "Encuentre la comunidad en la web",
|
||||
"app.components.HomePage.community.content": "Hable con los miembros del equipo, colaboradores y desarrolladores en diferentes canales.",
|
||||
"app.components.HomePage.create": "Crea tu primer Tipo de Contenido",
|
||||
"app.components.HomePage.createBlock.content.first": "El ",
|
||||
"app.components.HomePage.createBlock.content.second": " le ayudará a definir la estructura de datos de sus modelos. Si eres nuevo aquí, te recomendamos encarecidamente que sigas nuestro ",
|
||||
"app.components.HomePage.createBlock.content.second": " le ayudará a definir la estructura de datos de sus modelos. Si es nuevo aquí, le recomendamos encarecidamente que siga nuestro ",
|
||||
"app.components.HomePage.createBlock.content.tutorial": " ",
|
||||
"app.components.HomePage.cta": "CONFIRMAR",
|
||||
"app.components.HomePage.newsLetter": "Suscríbase al boletín de noticias para ponerse en contacto con Strapi",
|
||||
"app.components.HomePage.support": "APÓYANOS",
|
||||
"app.components.HomePage.support.content": "¡Al comprar la camiseta, nos permitirá continuar nuestro trabajo en el proyecto para darle la mejor experiencia posible!",
|
||||
"app.components.HomePage.support.link": "CONSIGUE TU CAMISETA AHORA",
|
||||
"app.components.HomePage.support.link": "CONSIGA SU CAMISETA AHORA",
|
||||
"app.components.HomePage.welcome": "¡Bienvenido a bordo!",
|
||||
"app.components.HomePage.welcome.again": "Bienvenido ",
|
||||
"app.components.HomePage.welcome.again": "¡Bienvenido ",
|
||||
"app.components.HomePage.welcomeBlock.content": "Estamos felices de tenerlo como miembro de la comunidad. Estamos constantemente en busca de comentarios así que no dude en enviarnos un DM en ",
|
||||
"app.components.HomePage.welcomeBlock.content.again": "Esperamos que estés progresando en tu proyecto.... Siéntase libre de leer las últimas novedades sobre Strapi. Estamos dando lo mejor de nosotros mismos para mejorar el producto basándonos en sus comentarios.",
|
||||
"app.components.HomePage.welcomeBlock.content.issues": "problema.",
|
||||
|
||||
141
packages/strapi-admin/admin/src/translations/fa.json
Normal file
141
packages/strapi-admin/admin/src/translations/fa.json
Normal file
@ -0,0 +1,141 @@
|
||||
{
|
||||
"Analytics": "آنالیز",
|
||||
"Content Manager": "مدیریت محتوا",
|
||||
"Content Type Builder": "سازنده ی الگوی محتوایی",
|
||||
"Email": "ایمیل",
|
||||
"Files Upload": "آپلود فایل",
|
||||
"HomePage.notification.newsLetter.success": "موفقیت در اشتراک خبر نامه",
|
||||
"New entry": "رکورد جدید",
|
||||
"Password": "رمز عبور",
|
||||
"Provider": "سرویس دهنده",
|
||||
"ResetPasswordToken": "بازنشانی رمز عبور",
|
||||
"Role": "نقش",
|
||||
"Roles & Permissions": "نقش ها و دسترسی ها",
|
||||
"Settings Manager": "مدیریت تنظیمات",
|
||||
"Username": "نام کاربری",
|
||||
"Users": "کاربران",
|
||||
"Users & Permissions": "کاربران و دسترسی ها",
|
||||
"app.components.BlockLink.code": "نمونه کد",
|
||||
"app.components.BlockLink.code.content": "با بررسی و آزمایش پروژه های واقعی توسط جامعه توسعه دهنده Strapi را یاد بگیرید.",
|
||||
"app.components.BlockLink.documentation": "خواندن مستندات",
|
||||
"app.components.BlockLink.documentation.content": "مفاهیم، راهنمای مرجع و آموزش ها را فرا بگیرید.",
|
||||
"app.components.Button.cancel": "کنسل",
|
||||
"app.components.Button.save": "ذخیره",
|
||||
"app.components.ComingSoonPage.comingSoon": "بزودی",
|
||||
"app.components.ComingSoonPage.featuresNotAvailable": "این ویژگی هنوز در حال توسعه است.",
|
||||
"app.components.DownloadInfo.download": "در حال دانلود...",
|
||||
"app.components.DownloadInfo.text": "ممکن است دقایقی طول بکشد، با تشکر از شکیبایی شما.",
|
||||
"app.components.EmptyAttributes.title": "هیچ فیلدی وجود ندارد",
|
||||
"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": "مارا حمایت کنید",
|
||||
"app.components.HomePage.support.content": "با خرید تی شرت ما میتوانیم به توسعه Strapi ادامه داده و بهترین تجربه را برای شما فراهم کنیم!",
|
||||
"app.components.HomePage.support.link": "هم اکنون تی شرت خود را دریافت کنید",
|
||||
"app.components.HomePage.welcome": "خوش آمدید!",
|
||||
"app.components.HomePage.welcome.again": "خوش آمدید ",
|
||||
"app.components.HomePage.welcomeBlock.content": "خرسندیم که شما را به عنوان عضوی از جامعه توسعه دهنده بشناسیم، ما هر لحظه به دنبال دریافت بازخورد شما هستیم، در ارسال بازخورد تردید نکنید ",
|
||||
"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": "جستجوی افزونه... (برای مثال: authentication)",
|
||||
"app.components.InstallPluginPage.description": "به راحتی برنامه خود را توسعه دهید.",
|
||||
"app.components.InstallPluginPage.helmet": "فروشگاه - افزونه ها",
|
||||
"app.components.InstallPluginPage.plugin.support-us.description": "با خرید تی شرت ما میتوانیم به توسعه Strapi ادامه داده و بهترین تجربه را برای شما فراهم کنیم!",
|
||||
"app.components.InstallPluginPage.title": "فروشگاه - افزونه ها",
|
||||
"app.components.InstallPluginPopup.downloads": "دانلود",
|
||||
"app.components.InstallPluginPopup.navLink.avis": "مشاهده",
|
||||
"app.components.InstallPluginPopup.navLink.changelog": "تغییرات",
|
||||
"app.components.InstallPluginPopup.navLink.description": "توضیحات",
|
||||
"app.components.InstallPluginPopup.navLink.faq": "پرسش و پاسخ",
|
||||
"app.components.InstallPluginPopup.navLink.screenshots": "تصاویر",
|
||||
"app.components.InstallPluginPopup.noDescription": "توضیحاتی وجود ندارد",
|
||||
"app.components.LeftMenuFooter.poweredBy": "قدرت گرفته از ",
|
||||
"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": "حمایت از ما",
|
||||
"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.SelectOption.defaultMessage": " ",
|
||||
"app.utils.defaultMessage": " ",
|
||||
"app.utils.placeholder.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": "این مقدار پست الکترونیک صحیح نیست",
|
||||
"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": "نمی تواند بالاتر باشد",
|
||||
"components.Input.error.validation.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": "تبدیل به حالت markdown",
|
||||
"components.Wysiwyg.ToggleMode.preview": "تبدیل به حالت نمایشی",
|
||||
"components.Wysiwyg.collapse": "کوچک کردن",
|
||||
"components.Wysiwyg.selectOptions.H1": "عنوان H1",
|
||||
"components.Wysiwyg.selectOptions.H2": "عنوان H2",
|
||||
"components.Wysiwyg.selectOptions.H3": "عنوان H3",
|
||||
"components.Wysiwyg.selectOptions.H4": "عنوان H4",
|
||||
"components.Wysiwyg.selectOptions.H5": "عنوان H5",
|
||||
"components.Wysiwyg.selectOptions.H6": "عنوان H6",
|
||||
"components.Wysiwyg.selectOptions.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": "این مدل وجود ندارد",
|
||||
"app.utils.delete": "حذف"
|
||||
}
|
||||
@ -28,8 +28,7 @@ module.exports = {
|
||||
|
||||
getGaConfig: async ctx => {
|
||||
try {
|
||||
const allowGa = _.get(strapi.config, 'info.customs.allowGa', true);
|
||||
ctx.send({ allowGa });
|
||||
ctx.send({ uuid: _.get(strapi.config, 'uuid', false) });
|
||||
} catch(err) {
|
||||
ctx.badRequest(null, [{ messages: [{ id: 'An error occurred' }] }]);
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ If you don't want to share your data with us, you can simply modify the `strapi`
|
||||
```json
|
||||
{
|
||||
"strapi": {
|
||||
"allowGa": false
|
||||
"uuid": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@ -12,7 +12,15 @@ module.exports = {
|
||||
// After saving a value.
|
||||
// Fired after an `insert` or `update` query.
|
||||
// afterSave: async (model, response, options) => {},
|
||||
|
||||
// Before fetching all values.
|
||||
// Fired before a `fetchAll` operation.
|
||||
// beforeFetchCollection: async (model, columns, options) => {},
|
||||
|
||||
// After fetching all values.
|
||||
// Fired after a `fetchAll` operation.
|
||||
// afterFetchCollection: async (model, columns, options) => {},
|
||||
|
||||
// Before fetching a value.
|
||||
// Fired before a `fetch` operation.
|
||||
// beforeFetch: async (model, columns, options) => {},
|
||||
|
||||
@ -97,13 +97,13 @@ module.exports = {
|
||||
acc[current] = params.values[current];
|
||||
} else if (response[current] && _.isArray(response[current]) && current !== 'id') {
|
||||
// Records to add in the relation.
|
||||
const toAdd = _.differenceWith(params.values[current], response[current], (a, b) =>
|
||||
a[this.primaryKey].toString() === b[this.primaryKey].toString()
|
||||
const toAdd = _.differenceWith(params.values[current], response[current], (a, b) =>
|
||||
(a[this.primaryKey] || a).toString() === (b[this.primaryKey] || b).toString()
|
||||
);
|
||||
|
||||
// Records to remove in the relation.
|
||||
const toRemove = _.differenceWith(response[current], params.values[current], (a, b) =>
|
||||
a[this.primaryKey].toString() === b[this.primaryKey].toString()
|
||||
(a[this.primaryKey] || a).toString() === (b[this.primaryKey] || b).toString()
|
||||
)
|
||||
.filter(x => toAdd.find(y => x.id === y.id) === undefined);
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ import React from 'react';
|
||||
import Select from 'react-select';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
import { cloneDeep, isArray, isNull, isUndefined, get, findIndex, isEmpty } from 'lodash';
|
||||
import { cloneDeep, includes, isArray, isNull, isUndefined, get, findIndex, isEmpty } from 'lodash';
|
||||
|
||||
// Utils.
|
||||
import request from 'utils/request';
|
||||
@ -103,6 +103,15 @@ class SelectMany extends React.PureComponent {
|
||||
});
|
||||
};
|
||||
|
||||
handleInputChange = (value) => {
|
||||
const clonedOptions = this.state.options;
|
||||
const filteredValues = clonedOptions.filter(data => includes(data.label, value));
|
||||
|
||||
if (filteredValues.length === 0) {
|
||||
return this.getOptions(value);
|
||||
}
|
||||
}
|
||||
|
||||
handleChange = value => {
|
||||
// Remove new added value from available option;
|
||||
this.state.options = this.state.options.filter(el =>
|
||||
@ -169,6 +178,7 @@ class SelectMany extends React.PureComponent {
|
||||
id={this.props.relation.alias}
|
||||
isLoading={this.state.isLoading}
|
||||
onChange={this.handleChange}
|
||||
onInputChange={this.handleInputChange}
|
||||
onMenuScrollToBottom={this.handleBottomScroll}
|
||||
options={this.state.options}
|
||||
placeholder={<FormattedMessage id='content-manager.containers.Edit.addAnItem' />}
|
||||
|
||||
@ -102,7 +102,7 @@ module.exports = async cb => {
|
||||
disabled: false,
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
// Don't display fields that are hidden by default like the resetPasswordToken for the model user
|
||||
_.unset(fields, fieldsToRemove);
|
||||
schemaModel.attributes = _.omit(schemaModel.attributes, fieldsToRemove);
|
||||
@ -339,16 +339,16 @@ module.exports = async cb => {
|
||||
});
|
||||
|
||||
// Update other keys
|
||||
sameApis.map(apiPath => {
|
||||
sameApis.forEach(apiPath => {
|
||||
// This doesn't keep the prevSettings for the relations, the user will have to reset it.
|
||||
// We might have to improve this if we want the order of the relations to be kept
|
||||
const keysToUpdate = ['relations', 'loadedModel', 'associations', 'attributes', ['editDisplay', 'relations']].map(key => apiPath.concat(key));
|
||||
['relations', 'loadedModel', 'associations', 'attributes', ['editDisplay', 'relations']]
|
||||
.map(key => apiPath.concat(key))
|
||||
.forEach(keyPath => {
|
||||
const newValue = _.get(schema.models, keyPath);
|
||||
|
||||
keysToUpdate.map(keyPath => {
|
||||
const newValue = _.get(schema.models, keyPath);
|
||||
|
||||
_.set(prevSchema.models, keyPath, newValue);
|
||||
});
|
||||
_.set(prevSchema.models, keyPath, newValue);
|
||||
});
|
||||
});
|
||||
|
||||
// Special handler for the upload relations
|
||||
@ -363,6 +363,7 @@ module.exports = async cb => {
|
||||
});
|
||||
|
||||
await pluginStore.set({ key: 'schema', value: prevSchema });
|
||||
|
||||
} catch(err) {
|
||||
console.log('error', err);
|
||||
}
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
const _ = require('lodash');
|
||||
|
||||
/**
|
||||
* Retrieve the path of each API
|
||||
* @param {Object}} data
|
||||
* @param {Object}} data
|
||||
* @returns {Array} Array of API path ['plugins.upload.file', 'plugins.users-permissions.user', ...]
|
||||
*/
|
||||
const getApis = (data) => Object.keys(data).reduce((acc, curr) => {
|
||||
@ -10,8 +11,8 @@ const getApis = (data) => Object.keys(data).reduce((acc, curr) => {
|
||||
}
|
||||
|
||||
if (curr === 'plugins') {
|
||||
Object.keys(data[curr]).map(plugin => {
|
||||
Object.keys(data[curr][plugin]).map(api => {
|
||||
Object.keys(data[curr]).forEach(plugin => {
|
||||
Object.keys(data[curr][plugin]).forEach(api => {
|
||||
acc = acc.concat([`${curr}.${plugin}.${api}`]);
|
||||
});
|
||||
});
|
||||
@ -23,8 +24,8 @@ const getApis = (data) => Object.keys(data).reduce((acc, curr) => {
|
||||
|
||||
/**
|
||||
* Retrieve all the fields from an api
|
||||
* @param {Object} data
|
||||
* @param {Array} apis
|
||||
* @param {Object} data
|
||||
* @param {Array} apis
|
||||
* @returns {Array} Array composed of fields path for instance : [['plugins.users-permissions.user.fields.username', 'plugins.users-permissions.user.fields.email', 'plugins.users-permissions.user.fields.password'], [...]]
|
||||
*/
|
||||
const getApisKeys = (data, apis) => apis.map(apiPath => {
|
||||
@ -43,12 +44,12 @@ const getApisUploadRelations = (data, sameArray) => sameArray.map(apiPath => {
|
||||
.filter(relationName => {
|
||||
return _.get(data.models, [...relationPath, relationName, 'plugin' ]) === 'upload';
|
||||
});
|
||||
|
||||
|
||||
return relations.map(relation => `${apiPath.join('.')}.editDisplay.availableFields.${relation}`);
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {String} attrPath
|
||||
* @returns {Array}
|
||||
*/
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
"attribute.float": "Número flotante",
|
||||
"attribute.integer": "Número entero",
|
||||
"attribute.json": "JSON",
|
||||
"attribute.media": "Medios",
|
||||
"attribute.media": "Multimedia",
|
||||
"attribute.password": "Contraseña",
|
||||
"attribute.relation": "Relación",
|
||||
"attribute.string": "Cadena de texto",
|
||||
@ -28,7 +28,7 @@
|
||||
"error.validation.minLength": "El valor es demasiado corto.",
|
||||
"error.validation.minSupMax": "No puede ser superior",
|
||||
"error.validation.regex": "El valor no coincide con el valor de regex.",
|
||||
"error.validation.required": "Esta entrada de valor es obligatoria.",
|
||||
"error.validation.required": "Es requerido un valor para este registro.",
|
||||
"form.attribute.item.appearance.description": "Si no, el valor será editable a través de un campo textarea básico",
|
||||
"form.attribute.item.appearance.label": "Mostrar como WYSIWYG",
|
||||
"form.attribute.item.appearance.name": "Apariencia",
|
||||
@ -41,7 +41,7 @@
|
||||
"form.attribute.item.enumeration.graphql.description": "Le permite redefinir el nombre generado por defecto para GraphQL",
|
||||
"form.attribute.item.enumeration.name": "Nombre",
|
||||
"form.attribute.item.enumeration.placeholder": "Ej: mañana, mediodía, noche",
|
||||
"form.attribute.item.enumeration.rules": "Valores (sepárelos con una coma)",
|
||||
"form.attribute.item.enumeration.rules": "Valores (separados con una coma)",
|
||||
"form.attribute.item.json.name": "Nombre",
|
||||
"form.attribute.item.maximum": "Valor máximo",
|
||||
"form.attribute.item.maximumLength": "Longitud máxima",
|
||||
@ -50,17 +50,17 @@
|
||||
"form.attribute.item.minimum": "Valor mínimo",
|
||||
"form.attribute.item.minimumLength": "Longitud mínima",
|
||||
"form.attribute.item.number.name": "Nombre",
|
||||
"form.attribute.item.number.type": "Formato de número",
|
||||
"form.attribute.item.number.type": "Tipo de número",
|
||||
"form.attribute.item.number.type.decimal": "decimal (ex: 2.22)",
|
||||
"form.attribute.item.number.type.float": "flotante (ex: 3.3333333333)",
|
||||
"form.attribute.item.number.type.integer": "entero (ej: 10)",
|
||||
"form.attribute.item.requiredField": "Campo obligatorio",
|
||||
"form.attribute.item.requiredField.description": "No podrá crear una entrada si este campo está vacío",
|
||||
"form.attribute.item.requiredField.description": "No podrá crear un registro si este campo está vacío",
|
||||
"form.attribute.item.settings.name": "Ajustes",
|
||||
"form.attribute.item.string.name": "Nombre",
|
||||
"form.attribute.item.textarea.name": "Nombre",
|
||||
"form.attribute.item.uniqueField": "Campo único",
|
||||
"form.attribute.item.uniqueField.description": "No podrá crear una entrada si hay una entrada existente con contenido idéntico",
|
||||
"form.attribute.item.uniqueField.description": "No podrá crear un registro si ya existe otro registro con el mismo contenido",
|
||||
"form.attribute.settings.default": "Valor por defecto",
|
||||
"form.attribute.settings.default.checkboxLabel": "Ajustar a verdadero",
|
||||
"form.button.cancel": "Cancelar",
|
||||
@ -117,18 +117,18 @@
|
||||
"popUpForm.attributes.json.description": "Datos en formato JSON",
|
||||
"popUpForm.attributes.json.name": "JSON",
|
||||
"popUpForm.attributes.media.description": "Imágenes, vídeos, PDFs y otros archivos",
|
||||
"popUpForm.attributes.media.name": "Medios",
|
||||
"popUpForm.attributes.media.name": "Multimedia",
|
||||
"popUpForm.attributes.number.description": "Todo lo que es número",
|
||||
"popUpForm.attributes.number.name": "Número",
|
||||
"popUpForm.attributes.password.description": "Contraseña de usuario...",
|
||||
"popUpForm.attributes.password.name": "Contraseña",
|
||||
"popUpForm.attributes.relation.description": "Se refiere a un Tipo de Contenido",
|
||||
"popUpForm.attributes.relation.name": "Relación",
|
||||
"popUpForm.attributes.string.description": "Títulos, nombres, párrafos, lista de nombres",
|
||||
"popUpForm.attributes.string.description": "Títulos, nombres, enunciados, lista de nombres",
|
||||
"popUpForm.attributes.string.name": "Cadena de texto",
|
||||
"popUpForm.attributes.text.description": "Descripciones, párrafos de texto, artículos ",
|
||||
"popUpForm.attributes.text.description": "Descripciones, párrafos de texto, artículos",
|
||||
"popUpForm.attributes.text.name": "Texto",
|
||||
"popUpForm.choose.attributes.header.title": "Añadir Nuevo Campo",
|
||||
"popUpForm.choose.attributes.header.title": "Añadir nuevo Campo",
|
||||
"popUpForm.create": "Añadir Nuevo",
|
||||
"popUpForm.create.contentType.header.title": "Añadir nuevo Tipo de Contenido",
|
||||
"popUpForm.edit": "Editar",
|
||||
|
||||
@ -105,9 +105,9 @@ module.exports = {
|
||||
_.set(schema, [...schemaPath, 'editDisplay', 'fields'], newList.toJS());
|
||||
}
|
||||
|
||||
Object.keys(attributes).map(attribute => {
|
||||
Object.keys(attributes).forEach(attribute => {
|
||||
const appearances = _.get(attributes, [attribute, 'appearance'], {});
|
||||
Object.keys(appearances).map(appearance => {
|
||||
Object.keys(appearances).forEach(appearance => {
|
||||
_.set(layout, ['attributes', attribute, 'appearance'], appearances[appearance] ? appearance : '' );
|
||||
});
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ module.exports = async cb => {
|
||||
fs.readdir(path.join(basePath, 'node_modules'), async (err, node_modules) => {
|
||||
// get all email providers
|
||||
const emails = _.filter(node_modules, (node_module) => {
|
||||
return _.startsWith(node_module, ('strapi-email'));
|
||||
return _.startsWith(node_module, ('strapi-provider-email'));
|
||||
});
|
||||
|
||||
// mount all providers to get configs
|
||||
@ -51,7 +51,7 @@ module.exports = async cb => {
|
||||
}
|
||||
} catch (err) {
|
||||
strapi.log.error(`Can't load ${config.provider} email provider.`);
|
||||
strapi.log.warn(`Please install strapi-email-${config.provider} --save in ${path.join(strapi.config.appPath, 'plugins', 'email')} folder.`);
|
||||
strapi.log.warn(`Please install strapi-provider-email-${config.provider} --save in ${path.join(strapi.config.appPath, 'plugins', 'email')} folder.`);
|
||||
strapi.stop();
|
||||
}
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
"prepublishOnly": "IS_MONOREPO=true npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"strapi-email-sendmail": "3.0.0-alpha.14.5"
|
||||
"strapi-provider-email-sendmail": "3.0.0-alpha.14.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"react-copy-to-clipboard": "5.0.1",
|
||||
@ -49,4 +49,4 @@
|
||||
"npm": ">= 5.0.0"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ module.exports = {
|
||||
const provider = _.find(strapi.plugins.email.config.providers, { provider: config.provider });
|
||||
|
||||
if (!provider) {
|
||||
throw new Error(`The provider package isn't installed. Please run \`npm install strapi-email-${config.provider}\``);
|
||||
throw new Error(`The provider package isn't installed. Please run \`npm install strapi-provider-email-${config.provider}\``);
|
||||
}
|
||||
|
||||
const actions = provider.init(config);
|
||||
|
||||
@ -373,14 +373,14 @@ module.exports = {
|
||||
source: association.plugin,
|
||||
};
|
||||
|
||||
if (association.type === 'model') {
|
||||
params.id = obj[association.alias];
|
||||
} else {
|
||||
// Get refering model.
|
||||
const ref = association.plugin
|
||||
? strapi.plugins[association.plugin].models[params.model]
|
||||
: strapi.models[params.model];
|
||||
// Get refering model.
|
||||
const ref = association.plugin
|
||||
? strapi.plugins[association.plugin].models[params.model]
|
||||
: strapi.models[params.model];
|
||||
|
||||
if (association.type === 'model') {
|
||||
params.id = _.get(obj, [association.alias, ref.primaryKey], obj[association.alias]);
|
||||
} else {
|
||||
// Apply optional arguments to make more precise nested request.
|
||||
const convertedParams = strapi.utils.models.convertParams(
|
||||
name,
|
||||
|
||||
@ -26,7 +26,7 @@ module.exports = async cb => {
|
||||
fs.readdir(path.join(basePath, 'node_modules'), async (err, node_modules) => {
|
||||
// get all upload provider
|
||||
const uploads = _.filter(node_modules, (node_module) => {
|
||||
return _.startsWith(node_module, ('strapi-upload'));
|
||||
return _.startsWith(node_module, ('strapi-provider-upload'));
|
||||
});
|
||||
|
||||
// mount all providers to get configs
|
||||
@ -53,7 +53,7 @@ module.exports = async cb => {
|
||||
}
|
||||
} catch (err) {
|
||||
strapi.log.error(`Can't load ${config.provider} upload provider.`);
|
||||
strapi.log.warn(`Please install strapi-upload-${config.provider} --save in ${path.join(strapi.config.appPath, 'plugins', 'upload')} folder.`);
|
||||
strapi.log.warn(`Please install strapi-provider-upload-${config.provider} --save in ${path.join(strapi.config.appPath, 'plugins', 'upload')} folder.`);
|
||||
strapi.stop();
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"react-copy-to-clipboard": "^5.0.1",
|
||||
"strapi-upload-local": "3.0.0-alpha.14.5",
|
||||
"strapi-provider-upload-local": "3.0.0-alpha.14.5",
|
||||
"stream-to-array": "^2.3.0",
|
||||
"uuid": "^3.2.1"
|
||||
},
|
||||
@ -47,4 +47,4 @@
|
||||
"npm": ">= 3.0.0"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ module.exports = {
|
||||
|
||||
if (!provider) {
|
||||
throw new Error(
|
||||
`The provider package isn't installed. Please run \`npm install strapi-upload-${
|
||||
`The provider package isn't installed. Please run \`npm install strapi-provider-upload-${
|
||||
config.provider
|
||||
}\``,
|
||||
);
|
||||
|
||||
@ -8,7 +8,7 @@ export default function checkFormValidity(settingType, data, providerToEdit = ''
|
||||
const isProviderEnabled = get(data, 'enabled');
|
||||
const keys = providerToEdit === 'email' ? [] : ['key', 'secret'];
|
||||
|
||||
keys.map(key => {
|
||||
keys.forEach(key => {
|
||||
if (isProviderEnabled && isEmpty(get(data, key))) {
|
||||
formErrors.push({ name: key, errors: [{ id: 'components.Input.error.validation.required' }] });
|
||||
}
|
||||
@ -16,9 +16,9 @@ export default function checkFormValidity(settingType, data, providerToEdit = ''
|
||||
break;
|
||||
}
|
||||
case 'email-templates': {
|
||||
Object.keys(data.options).map((value) => {
|
||||
Object.keys(data.options).forEach((value) => {
|
||||
if (isObject(data.options[value])) {
|
||||
Object.keys(data.options[value]).map(subValue => {
|
||||
Object.keys(data.options[value]).forEach(subValue => {
|
||||
if (isEmpty(get(data, ['options', value, subValue]))) {
|
||||
formErrors.push({ name: `options.${value}.${subValue}`, errors: [{ id: 'components.Input.error.validation.required' }] });
|
||||
}
|
||||
|
||||
@ -199,9 +199,9 @@ module.exports = {
|
||||
const prefix = curr.config.prefix;
|
||||
const path = prefix !== undefined ? `${prefix}${curr.path}` : `/${current}${curr.path}`;
|
||||
_.set(curr, 'path', path);
|
||||
|
||||
|
||||
return acc.concat(curr);
|
||||
}, []);
|
||||
}, []);
|
||||
|
||||
acc[current] = routes;
|
||||
|
||||
@ -221,7 +221,7 @@ module.exports = {
|
||||
// Aggregate first level actions.
|
||||
const appActions = Object.keys(strapi.api || {}).reduce((acc, api) => {
|
||||
Object.keys(_.get(strapi.api[api], 'controllers', {}))
|
||||
.map(controller => {
|
||||
.forEach(controller => {
|
||||
const actions = Object.keys(strapi.api[api].controllers[controller])
|
||||
.filter(action => _.isFunction(strapi.api[api].controllers[controller][action]))
|
||||
.map(action => `application.${controller}.${action.toLowerCase()}`);
|
||||
@ -235,7 +235,7 @@ module.exports = {
|
||||
// Aggregate plugins' actions.
|
||||
const pluginsActions = Object.keys(strapi.plugins).reduce((acc, plugin) => {
|
||||
Object.keys(strapi.plugins[plugin].controllers)
|
||||
.map(controller => {
|
||||
.forEach(controller => {
|
||||
const actions = Object.keys(strapi.plugins[plugin].controllers[controller])
|
||||
.filter(action => _.isFunction(strapi.plugins[plugin].controllers[controller][action]))
|
||||
.map(action => `${plugin}.${controller}.${action.toLowerCase()}`);
|
||||
|
||||
11
packages/strapi-provider-email-amazon-ses/README.md
Normal file
11
packages/strapi-provider-email-amazon-ses/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# strapi-provider-email-amazon-ses
|
||||
|
||||
## Resources
|
||||
|
||||
- [MIT License](LICENSE.md)
|
||||
|
||||
## Links
|
||||
|
||||
- [Strapi website](http://strapi.io/)
|
||||
- [Strapi community on Slack](http://slack.strapi.io)
|
||||
- [Strapi news on Twitter](https://twitter.com/strapijs)
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "strapi-email-amazon-ses",
|
||||
"name": "strapi-provider-email-amazon-ses",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Amazon SES provider for strapi email",
|
||||
"homepage": "http://strapi.io",
|
||||
@ -16,9 +16,6 @@
|
||||
"dependencies": {
|
||||
"node-ses": "^2.1.0"
|
||||
},
|
||||
"strapi": {
|
||||
"isProvider": true
|
||||
},
|
||||
"author": {
|
||||
"email": "nikolay@tsenkov.net",
|
||||
"name": "Nikolay tsenkov"
|
||||
@ -42,4 +39,4 @@
|
||||
"npm": ">= 5.3.0"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
# strapi-email-sendmail
|
||||
# strapi-provider-email-sendmail
|
||||
|
||||
## Resources
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "strapi-email-mailgun",
|
||||
"name": "strapi-provider-email-mailgun",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Mailgun provider for strapi email plugin",
|
||||
"homepage": "http://strapi.io",
|
||||
@ -42,4 +42,4 @@
|
||||
"npm": ">= 5.3.0"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
# strapi-email-sendmail
|
||||
# strapi-provider-email-sendmail
|
||||
|
||||
## Resources
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "strapi-email-sendgrid",
|
||||
"name": "strapi-provider-email-sendgrid",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Sendgrid provider for strapi email",
|
||||
"homepage": "http://strapi.io",
|
||||
@ -42,4 +42,4 @@
|
||||
"npm": ">= 5.3.0"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
11
packages/strapi-provider-email-sendmail/README.md
Normal file
11
packages/strapi-provider-email-sendmail/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# strapi-provider-email-sendmail
|
||||
|
||||
## Resources
|
||||
|
||||
- [MIT License](LICENSE.md)
|
||||
|
||||
## Links
|
||||
|
||||
- [Strapi website](http://strapi.io/)
|
||||
- [Strapi community on Slack](http://slack.strapi.io)
|
||||
- [Strapi news on Twitter](https://twitter.com/strapijs)
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "strapi-email-sendmail",
|
||||
"name": "strapi-provider-email-sendmail",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Sendmail provider for strapi email",
|
||||
"homepage": "http://strapi.io",
|
||||
@ -41,4 +41,4 @@
|
||||
"npm": ">= 5.3.0"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
# strapi-email-amazon-ses
|
||||
# strapi-provider-upload-local
|
||||
|
||||
## Resources
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "strapi-upload-aws-s3",
|
||||
"name": "strapi-provider-upload-aws-s3",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "AWS S3 provider for strapi upload",
|
||||
"homepage": "http://strapi.io",
|
||||
@ -43,4 +43,4 @@
|
||||
"npm": ">= 5.3.0"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
11
packages/strapi-provider-upload-cloudinary/README.md
Normal file
11
packages/strapi-provider-upload-cloudinary/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# strapi-provider-upload-cloudinary
|
||||
|
||||
## Resources
|
||||
|
||||
- [MIT License](LICENSE.md)
|
||||
|
||||
## Links
|
||||
|
||||
- [Strapi website](http://strapi.io/)
|
||||
- [Strapi community on Slack](http://slack.strapi.io)
|
||||
- [Strapi news on Twitter](https://twitter.com/strapijs)
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "strapi-upload-cloudinary",
|
||||
"name": "strapi-provider-upload-cloudinary",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Cloudinary provider for strapi upload",
|
||||
"homepage": "http://strapi.io",
|
||||
@ -43,4 +43,4 @@
|
||||
"npm": ">= 5.3.0"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
# strapi-email-sendmail
|
||||
# strapi-provider-upload-local
|
||||
|
||||
## Resources
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "strapi-upload-local",
|
||||
"name": "strapi-provider-upload-local",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Local provider for strapi upload",
|
||||
"homepage": "http://strapi.io",
|
||||
@ -39,4 +39,4 @@
|
||||
"npm": ">= 5.3.0"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
11
packages/strapi-provider-upload-rackspace/README.md
Normal file
11
packages/strapi-provider-upload-rackspace/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# strapi-provider-upload-rackspace
|
||||
|
||||
## Resources
|
||||
|
||||
- [MIT License](LICENSE.md)
|
||||
|
||||
## Links
|
||||
|
||||
- [Strapi website](http://strapi.io/)
|
||||
- [Strapi community on Slack](http://slack.strapi.io)
|
||||
- [Strapi news on Twitter](https://twitter.com/strapijs)
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "strapi-upload-rackspace",
|
||||
"name": "strapi-provider-upload-rackspace",
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"description": "Rackspace provider for strapi upload",
|
||||
"main": "./lib",
|
||||
@ -13,4 +13,4 @@
|
||||
"pkgcloud": "^1.5.0",
|
||||
"streamifier": "^0.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
# strapi-upload-local
|
||||
|
||||
## Resources
|
||||
|
||||
- [MIT License](LICENSE.md)
|
||||
|
||||
## Links
|
||||
|
||||
- [Strapi website](http://strapi.io/)
|
||||
- [Strapi community on Slack](http://slack.strapi.io)
|
||||
- [Strapi news on Twitter](https://twitter.com/strapijs)
|
||||
@ -1,11 +0,0 @@
|
||||
# strapi-upload-cloudinary
|
||||
|
||||
## Resources
|
||||
|
||||
- [MIT License](LICENSE.md)
|
||||
|
||||
## Links
|
||||
|
||||
- [Strapi website](http://strapi.io/)
|
||||
- [Strapi community on Slack](http://slack.strapi.io)
|
||||
- [Strapi news on Twitter](https://twitter.com/strapijs)
|
||||
@ -1,11 +0,0 @@
|
||||
# strapi-upload-local
|
||||
|
||||
## Resources
|
||||
|
||||
- [MIT License](LICENSE.md)
|
||||
|
||||
## Links
|
||||
|
||||
- [Strapi website](http://strapi.io/)
|
||||
- [Strapi community on Slack](http://slack.strapi.io)
|
||||
- [Strapi news on Twitter](https://twitter.com/strapijs)
|
||||
@ -1,11 +0,0 @@
|
||||
# strapi-upload-rackspace
|
||||
|
||||
## Resources
|
||||
|
||||
- [MIT License](LICENSE.md)
|
||||
|
||||
## Links
|
||||
|
||||
- [Strapi website](http://strapi.io/)
|
||||
- [Strapi community on Slack](http://slack.strapi.io)
|
||||
- [Strapi news on Twitter](https://twitter.com/strapijs)
|
||||
@ -368,7 +368,7 @@ const enableHookNestedDependencies = function (name, flattenHooksConfig, force =
|
||||
});
|
||||
|
||||
return apiModelsUsed.length !== 0;
|
||||
}) || 0; // Filter model with the right connector
|
||||
}); // Filter model with the right connector
|
||||
|
||||
flattenHooksConfig[name] = {
|
||||
enabled: force || modelsUsed.length > 0 // Will return false if there is no model, else true.
|
||||
|
||||
@ -119,17 +119,17 @@ shell.cd('../strapi-plugin-graphql');
|
||||
watcher('📦 Linking strapi-plugin-graphql...', 'npm link --no-optional', false);
|
||||
|
||||
// Plugin services
|
||||
shell.cd('../strapi-upload-local');
|
||||
watcher('📦 Linking strapi-upload-local...', 'npm link --no-optional', false);
|
||||
shell.cd('../strapi-provider-upload-local');
|
||||
watcher('📦 Linking strapi-provider-upload-local...', 'npm link --no-optional', false);
|
||||
|
||||
shell.cd('../strapi-email-sendmail');
|
||||
watcher('📦 Linking strapi-email-sendmail...', 'npm link --no-optional', false);
|
||||
shell.cd('../strapi-provider-email-sendmail');
|
||||
watcher('📦 Linking strapi-provider-email-sendmail...', 'npm link --no-optional', false);
|
||||
|
||||
// Plugins with admin
|
||||
shell.cd('../strapi-plugin-email');
|
||||
shell.rm('-f', 'package-lock.json');
|
||||
watcher('', 'npm install ../strapi-helper-plugin --no-optional');
|
||||
watcher('', 'npm install ../strapi-email-sendmail --no-optional');
|
||||
watcher('', 'npm install ../strapi-provider-email-sendmail --no-optional');
|
||||
watcher('📦 Linking strapi-plugin-email...', 'npm link --no-optional', false);
|
||||
|
||||
shell.cd('../strapi-plugin-users-permissions');
|
||||
@ -151,7 +151,7 @@ watcher('📦 Linking strapi-plugin-settings-manager...', 'npm link --no-option
|
||||
// Plugins with admin and other plugin's dependencies
|
||||
shell.cd('../strapi-plugin-upload');
|
||||
watcher('', 'npm install ../strapi-helper-plugin --no-optional');
|
||||
watcher('', 'npm install ../strapi-upload-local --no-optional');
|
||||
watcher('', 'npm install ../strapi-provider-upload-local --no-optional');
|
||||
shell.rm('-f', 'package-lock.json');
|
||||
watcher('📦 Linking strapi-plugin-upload...', 'npm link --no-optional', false);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user