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