mirror of
https://github.com/strapi/strapi.git
synced 2025-08-10 01:38:10 +00:00
Merge branch 'master' into master
This commit is contained in:
commit
ac35c34b74
@ -19,7 +19,7 @@ yarn create strapi-app my-app --quickstart --no-run
|
|||||||
2. Generate a plugin:
|
2. Generate a plugin:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
strapi generate:plugin wysiwyg
|
yarn run strapi generate:plugin wysiwyg
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Install the needed dependencies:
|
3. Install the needed dependencies:
|
||||||
@ -126,7 +126,7 @@ export default MediaLib;
|
|||||||
**Path —** `./plugins/wysiwyg/admin/src/components/Wysiwyg/index.js`
|
**Path —** `./plugins/wysiwyg/admin/src/components/Wysiwyg/index.js`
|
||||||
|
|
||||||
```js
|
```js
|
||||||
iimport React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
import { Button } from '@buffetjs/core';
|
import { Button } from '@buffetjs/core';
|
||||||
@ -332,4 +332,4 @@ export default strapi => {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
And VOILA, if you create a new `collectionType` or a `singleType` with a `richtext` field you will see the implementation of [CKEditor]((https://ckeditor.com/ckeditor-5/) instead of the default WYSIWYG.
|
And VOILA, if you create a new `collectionType` or a `singleType` with a `richtext` field you will see the implementation of [CKEditor](https://ckeditor.com/ckeditor-5/) instead of the default WYSIWYG.
|
||||||
|
@ -15,7 +15,7 @@ const Wrapper = styled.div`
|
|||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
> p {
|
> p {
|
||||||
width 100%;
|
width: 100%;
|
||||||
margin-bottom: -8px;
|
margin-bottom: -8px;
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
@ -86,8 +86,7 @@ const Wrapper = styled.div`
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bordered {
|
.bordered {
|
||||||
border-top: 2px solid
|
border-top: 2px solid ${({ withSuccessBorder }) => (withSuccessBorder ? '#5a9e06' : '#1c5de7')};
|
||||||
${({ withSucessBorder }) => (withSucessBorder ? '#5a9e06' : '#1c5de7')};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.borderedSuccess {
|
.borderedSuccess {
|
||||||
|
@ -3,13 +3,7 @@ import PropTypes from 'prop-types';
|
|||||||
import { get, isEmpty, omit, set, upperFirst } from 'lodash';
|
import { get, isEmpty, omit, set, upperFirst } from 'lodash';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import { Link, Redirect } from 'react-router-dom';
|
import { Link, Redirect } from 'react-router-dom';
|
||||||
import {
|
import { auth, Button, getQueryParameters, getYupInnerErrors, request } from 'strapi-helper-plugin';
|
||||||
auth,
|
|
||||||
Button,
|
|
||||||
getQueryParameters,
|
|
||||||
getYupInnerErrors,
|
|
||||||
request,
|
|
||||||
} from 'strapi-helper-plugin';
|
|
||||||
import NavTopRightWrapper from '../../components/NavTopRightWrapper';
|
import NavTopRightWrapper from '../../components/NavTopRightWrapper';
|
||||||
import LogoStrapi from '../../assets/images/logo_strapi.png';
|
import LogoStrapi from '../../assets/images/logo_strapi.png';
|
||||||
import PageTitle from '../../components/PageTitle';
|
import PageTitle from '../../components/PageTitle';
|
||||||
@ -29,9 +23,9 @@ const AuthPage = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const [reducerState, dispatch] = useReducer(reducer, initialState);
|
const [reducerState, dispatch] = useReducer(reducer, initialState);
|
||||||
const codeRef = useRef();
|
const codeRef = useRef();
|
||||||
const aborController = new AbortController();
|
const abortController = new AbortController();
|
||||||
|
|
||||||
const { signal } = aborController;
|
const { signal } = abortController;
|
||||||
codeRef.current = getQueryParameters(search, 'code');
|
codeRef.current = getQueryParameters(search, 'code');
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Set the reset code provided by the url
|
// Set the reset code provided by the url
|
||||||
@ -49,17 +43,11 @@ const AuthPage = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
aborController.abort();
|
abortController.abort();
|
||||||
};
|
};
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [authType, codeRef]);
|
}, [authType, codeRef]);
|
||||||
const {
|
const { didCheckErrors, errors, modifiedData, submitSuccess, userEmail } = reducerState.toJS();
|
||||||
didCheckErrors,
|
|
||||||
errors,
|
|
||||||
modifiedData,
|
|
||||||
submitSuccess,
|
|
||||||
userEmail,
|
|
||||||
} = reducerState.toJS();
|
|
||||||
const handleChange = ({ target: { name, value } }) => {
|
const handleChange = ({ target: { name, value } }) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'ON_CHANGE',
|
type: 'ON_CHANGE',
|
||||||
@ -124,9 +112,7 @@ const AuthPage = ({
|
|||||||
} else if (authType === 'forgot-password') {
|
} else if (authType === 'forgot-password') {
|
||||||
formErrors = { email: formattedError[0] };
|
formErrors = { email: formattedError[0] };
|
||||||
} else {
|
} else {
|
||||||
strapi.notification.error(
|
strapi.notification.error(get(formattedError, '0.id', 'notification.error'));
|
||||||
get(formattedError, '0.id', 'notification.error')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -164,7 +150,7 @@ const AuthPage = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageTitle title={upperFirst(authType)} />
|
<PageTitle title={upperFirst(authType)} />
|
||||||
<Wrapper authType={authType} withSucessBorder={submitSuccess}>
|
<Wrapper authType={authType} withSuccessBorder={submitSuccess}>
|
||||||
<NavTopRightWrapper>
|
<NavTopRightWrapper>
|
||||||
<LocaleToggle isLogged className="localeDropdownMenuNotLogged" />
|
<LocaleToggle isLogged className="localeDropdownMenuNotLogged" />
|
||||||
</NavTopRightWrapper>
|
</NavTopRightWrapper>
|
||||||
@ -177,9 +163,7 @@ const AuthPage = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="headerDescription">
|
<div className="headerDescription">
|
||||||
{authType === 'register' && (
|
{authType === 'register' && <FormattedMessage id="Auth.header.register.description" />}
|
||||||
<FormattedMessage id="Auth.header.register.description" />
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
{/* TODO Forgot success style */}
|
{/* TODO Forgot success style */}
|
||||||
<div className="formContainer bordered">
|
<div className="formContainer bordered">
|
||||||
@ -217,9 +201,7 @@ const AuthPage = ({
|
|||||||
})}
|
})}
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
authType === 'login'
|
authType === 'login' ? 'col-6 loginButton' : 'col-12 buttonContainer'
|
||||||
? 'col-6 loginButton'
|
|
||||||
: 'col-12 buttonContainer'
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
@ -238,15 +220,9 @@ const AuthPage = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="linkContainer">
|
<div className="linkContainer">
|
||||||
{authType !== 'register' && authType !== 'reset-password' && (
|
{authType !== 'register' && authType !== 'reset-password' && (
|
||||||
<Link
|
<Link to={`/auth/${authType === 'login' ? 'forgot-password' : 'login'}`}>
|
||||||
to={`/auth/${
|
|
||||||
authType === 'login' ? 'forgot-password' : 'login'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id={`Auth.link.${
|
id={`Auth.link.${authType === 'login' ? 'forgot-password' : 'ready'}`}
|
||||||
authType === 'login' ? 'forgot-password' : 'ready'
|
|
||||||
}`}
|
|
||||||
/>
|
/>
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
|
@ -9,7 +9,7 @@ const Block = styled.div`
|
|||||||
padding: 19px 30px 30px 30px;
|
padding: 19px 30px 30px 30px;
|
||||||
box-shadow: 0 2px 4px 0 #e3e9f3;
|
box-shadow: 0 2px 4px 0 #e3e9f3;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
line-heigth: 18px;
|
line-height: 18px;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -213,12 +213,12 @@ const LinkWrapper = styled.a`
|
|||||||
&:first-child {
|
&:first-child {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
color: #919BAE;
|
color: #919bae;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.bold {
|
.bold {
|
||||||
color: #333740
|
color: #333740;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
@ -257,13 +257,4 @@ const SocialLinkWrapper = styled.div`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export {
|
export { ALink, Block, Container, LinkWrapper, P, Separator, SocialLinkWrapper, Wave };
|
||||||
ALink,
|
|
||||||
Block,
|
|
||||||
Container,
|
|
||||||
LinkWrapper,
|
|
||||||
P,
|
|
||||||
Separator,
|
|
||||||
SocialLinkWrapper,
|
|
||||||
Wave,
|
|
||||||
};
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
* NOTE: while this component should technically be a stateless functional
|
* NOTE: while this component should technically be a stateless functional
|
||||||
* component (SFC), hot reloading does not currently support SFCs. If hot
|
* component (SFC), hot reloading does not currently support SFCs. If hot
|
||||||
* reloading is not a neccessity for you then you can refactor it and remove
|
* reloading is not a necessity for you then you can refactor it and remove
|
||||||
* the linting exception.
|
* the linting exception.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ module.exports = ({ model, modelKey, strapi }) => {
|
|||||||
|
|
||||||
// verify the provided ids are related to this entity.
|
// verify the provided ids are related to this entity.
|
||||||
idsToKeep.forEach(id => {
|
idsToKeep.forEach(id => {
|
||||||
if (allIds.findIndex(currentId => currentId.toString() === id) === -1) {
|
if (allIds.findIndex(currentId => currentId.toString() === id.toString()) === -1) {
|
||||||
const err = new Error(
|
const err = new Error(
|
||||||
`Some of the provided components in ${key} are not related to the entity`
|
`Some of the provided components in ${key} are not related to the entity`
|
||||||
);
|
);
|
||||||
|
@ -12,10 +12,7 @@ const { trackUsage, captureStderr } = require('./utils/usage');
|
|||||||
const packageJSON = require('./resources/json/package.json');
|
const packageJSON = require('./resources/json/package.json');
|
||||||
const databaseJSON = require('./resources/json/database.json.js');
|
const databaseJSON = require('./resources/json/database.json.js');
|
||||||
|
|
||||||
module.exports = async function createProject(
|
module.exports = async function createProject(scope, { connection, dependencies }) {
|
||||||
scope,
|
|
||||||
{ connection, dependencies }
|
|
||||||
) {
|
|
||||||
console.log('Creating files.');
|
console.log('Creating files.');
|
||||||
|
|
||||||
const { rootPath } = scope;
|
const { rootPath } = scope;
|
||||||
@ -29,13 +26,12 @@ module.exports = async function createProject(
|
|||||||
const dotFiles = await fse.readdir(join(resources, 'dot-files'));
|
const dotFiles = await fse.readdir(join(resources, 'dot-files'));
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
dotFiles.map(name => {
|
dotFiles.map(name => {
|
||||||
return fse.copy(
|
return fse.copy(join(resources, 'dot-files', name), join(rootPath, `.${name}`));
|
||||||
join(resources, 'dot-files', name),
|
|
||||||
join(rootPath, `.${name}`)
|
|
||||||
);
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await trackUsage({ event: 'didCopyProjectFiles', scope });
|
||||||
|
|
||||||
// copy templates
|
// copy templates
|
||||||
await fse.writeJSON(
|
await fse.writeJSON(
|
||||||
join(rootPath, 'package.json'),
|
join(rootPath, 'package.json'),
|
||||||
@ -51,6 +47,8 @@ module.exports = async function createProject(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await trackUsage({ event: 'didWritePackageJSON', scope });
|
||||||
|
|
||||||
// ensure node_modules is created
|
// ensure node_modules is created
|
||||||
await fse.ensureDir(join(rootPath, 'node_modules'));
|
await fse.ensureDir(join(rootPath, 'node_modules'));
|
||||||
|
|
||||||
@ -66,11 +64,15 @@ module.exports = async function createProject(
|
|||||||
);
|
);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await trackUsage({ event: 'didCopyConfigurationFiles', scope });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
await fse.remove(scope.rootPath);
|
await fse.remove(scope.rootPath);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await trackUsage({ event: 'willInstallProjectDependencies', scope });
|
||||||
|
|
||||||
const installPrefix = chalk.yellow('Installing dependencies:');
|
const installPrefix = chalk.yellow('Installing dependencies:');
|
||||||
const loader = ora(installPrefix).start();
|
const loader = ora(installPrefix).start();
|
||||||
|
|
||||||
@ -93,6 +95,8 @@ module.exports = async function createProject(
|
|||||||
|
|
||||||
loader.stop();
|
loader.stop();
|
||||||
console.log(`Dependencies installed ${chalk.green('successfully')}.`);
|
console.log(`Dependencies installed ${chalk.green('successfully')}.`);
|
||||||
|
|
||||||
|
await trackUsage({ event: 'didInstallProjectDependencies', scope });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
loader.stop();
|
loader.stop();
|
||||||
await trackUsage({
|
await trackUsage({
|
||||||
@ -119,9 +123,7 @@ module.exports = async function createProject(
|
|||||||
);
|
);
|
||||||
console.log();
|
console.log();
|
||||||
console.log(
|
console.log(
|
||||||
`cd ${chalk.green(rootPath)} && ${chalk.cyan(
|
`cd ${chalk.green(rootPath)} && ${chalk.cyan(scope.useYarn ? 'yarn' : 'npm')} install`
|
||||||
scope.useYarn ? 'yarn' : 'npm'
|
|
||||||
)} install`
|
|
||||||
);
|
);
|
||||||
console.log();
|
console.log();
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@ function trackError({ scope, error }) {
|
|||||||
version: scope.strapiVersion,
|
version: scope.strapiVersion,
|
||||||
nodeVersion: process.version,
|
nodeVersion: process.version,
|
||||||
docker: scope.docker,
|
docker: scope.docker,
|
||||||
|
useYarn: scope.useYarn,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -92,6 +93,7 @@ function trackUsage({ event, scope, error }) {
|
|||||||
node_version: process.version,
|
node_version: process.version,
|
||||||
version: scope.strapiVersion,
|
version: scope.strapiVersion,
|
||||||
docker: scope.docker,
|
docker: scope.docker,
|
||||||
|
useYarn: scope.useYarn,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -29,7 +29,7 @@ module.exports = {
|
|||||||
const readStream = streamifier.createReadStream(file.buffer);
|
const readStream = streamifier.createReadStream(file.buffer);
|
||||||
const writeStream = client.upload({
|
const writeStream = client.upload({
|
||||||
...options,
|
...options,
|
||||||
remote: file.name,
|
remote: file.hash,
|
||||||
contentType: file.mime,
|
contentType: file.mime,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -38,22 +38,21 @@ module.exports = {
|
|||||||
writeStream.on('error', error => error && reject(error));
|
writeStream.on('error', error => error && reject(error));
|
||||||
writeStream.on('success', result => {
|
writeStream.on('success', result => {
|
||||||
remoteURL()
|
remoteURL()
|
||||||
.then(data =>
|
.then(data => {
|
||||||
resolve(
|
resolve(
|
||||||
Object.assign(file, {
|
Object.assign(file, {
|
||||||
name: result.name,
|
|
||||||
mime: result.contentType,
|
mime: result.contentType,
|
||||||
url: `${data.cdnSslUri}/${result.name}`,
|
url: `${data.cdnSslUri}/${result.name}`,
|
||||||
})
|
})
|
||||||
)
|
);
|
||||||
)
|
})
|
||||||
.catch(err => console.error(err) && reject(err));
|
.catch(err => console.error(err) && reject(err));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
delete(file) {
|
delete(file) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
client.removeFile(config.container, file.name, error => {
|
client.removeFile(config.container, file.hash, error => {
|
||||||
if (error) return reject(error);
|
if (error) return reject(error);
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user