mirror of
https://github.com/strapi/strapi.git
synced 2025-12-27 07:03:38 +00:00
Merge branch 'feature/upload' of github.com:strapi/strapi into feature/upload
This commit is contained in:
commit
5cbfa32d48
@ -104,7 +104,7 @@
|
||||
"components.Input.error.custom-error": "{errorMessage} ",
|
||||
|
||||
"components.ListRow.empty": "There is no data to be shown.",
|
||||
|
||||
|
||||
"notification.error": "An error occurred",
|
||||
|
||||
"Users & Permissions": "Users & Permissions",
|
||||
|
||||
@ -111,7 +111,7 @@
|
||||
|
||||
"Auth & Permissions": "認證 & 權限",
|
||||
"Content Manager": "內容管理",
|
||||
"Content Type Builder": "創建資料結構",
|
||||
"Content Type Builder": "建立和更新資料結構",
|
||||
"Settings Manager": "管理設定",
|
||||
"Email": "Email",
|
||||
"Password": "密碼",
|
||||
|
||||
@ -63,6 +63,7 @@
|
||||
.addonFocus {
|
||||
border-color: #78caff;
|
||||
border-right: 0;
|
||||
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
|
||||
}
|
||||
|
||||
.invalidSearch {
|
||||
|
||||
@ -27,7 +27,7 @@ class InputSelectWithErrors extends React.Component {
|
||||
this.setState({ errors });
|
||||
}
|
||||
|
||||
if (isEmpty(this.props.value) && this.props.validations.required) {
|
||||
if (isEmpty(this.props.value) && this.props.validations.required === true) {
|
||||
const target = {
|
||||
type: 'select',
|
||||
name: this.props.name,
|
||||
|
||||
@ -7,8 +7,10 @@ import cn from 'classnames';
|
||||
import styles from './styles.scss';
|
||||
|
||||
function InputText(props) {
|
||||
const placeholder = isEmpty(props.placeholder) ? 'app.utils.placeholder.defaultMessage' : props.placeholder;
|
||||
|
||||
return (
|
||||
<FormattedMessage id={props.placeholder} defaultMessage={props.placeholder}>
|
||||
<FormattedMessage id={placeholder} defaultMessage={placeholder}>
|
||||
{(message) => (
|
||||
<input
|
||||
autoFocus={props.autoFocus}
|
||||
@ -32,7 +34,7 @@ function InputText(props) {
|
||||
/>
|
||||
)}
|
||||
</FormattedMessage>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
InputText.defaultProps = {
|
||||
|
||||
@ -11,8 +11,8 @@
|
||||
"containers.Edit.reset": "重設",
|
||||
"containers.Edit.returnList": "回到清單",
|
||||
"containers.List.addAnEntry": "增加新的 {entity}",
|
||||
"containers.List.pluginHeaderDescription": "找到 {label} 個進入點",
|
||||
"containers.List.pluginHeaderDescription.singular": "找到 {label} 個進入點",
|
||||
"containers.List.pluginHeaderDescription": "找到 {label} 筆資料",
|
||||
"containers.List.pluginHeaderDescription.singular": "找到 {label} 筆資料",
|
||||
"components.LimitSelect.itemsPerPage": "每個頁面檔案數量",
|
||||
"containers.List.errorFetchRecords": "錯誤",
|
||||
|
||||
@ -52,5 +52,5 @@
|
||||
"popUpWarning.button.cancel": "取消",
|
||||
"popUpWarning.button.confirm": "確認",
|
||||
"popUpWarning.title": "請確認",
|
||||
"popUpWarning.bodyMessage.contentType.delete": "您確定要刪除這個進入點嗎?"
|
||||
"popUpWarning.bodyMessage.contentType.delete": "您確定要刪除這筆資料嗎?"
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ function validate(value, validations) {
|
||||
}
|
||||
break;
|
||||
case 'required':
|
||||
if (value.length === 0) {
|
||||
if (validationValue === true && value.length === 0) {
|
||||
errors.push({ id: 'content-manager.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
|
||||
@ -14,6 +14,7 @@ import {
|
||||
findIndex,
|
||||
filter,
|
||||
get,
|
||||
has,
|
||||
includes,
|
||||
isEmpty,
|
||||
isUndefined,
|
||||
@ -455,18 +456,27 @@ export class Form extends React.Component { // eslint-disable-line react/prefer-
|
||||
}
|
||||
}
|
||||
|
||||
renderModalBodyChooseAttributes = () => (
|
||||
map(forms.attributesDisplay.items, (attribute, key) => (
|
||||
<AttributeCard
|
||||
key={key}
|
||||
attribute={attribute}
|
||||
autoFocus={key === 0}
|
||||
routePath={this.props.routePath}
|
||||
handleClick={this.goToAttributeTypeView}
|
||||
tabIndex={key}
|
||||
/>
|
||||
))
|
||||
)
|
||||
renderModalBodyChooseAttributes = () => {
|
||||
const attributesDisplay = forms.attributesDisplay.items;
|
||||
|
||||
// Don't display the media field if the upload plugin isn't installed
|
||||
if (!has(this.context.plugins.toJS(), 'upload')) {
|
||||
attributesDisplay.splice(8, 1);
|
||||
}
|
||||
|
||||
return (
|
||||
map(attributesDisplay, (attribute, key) => (
|
||||
<AttributeCard
|
||||
key={key}
|
||||
attribute={attribute}
|
||||
autoFocus={key === 0}
|
||||
routePath={this.props.routePath}
|
||||
handleClick={this.goToAttributeTypeView}
|
||||
tabIndex={key}
|
||||
/>
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
testContentType = (contentTypeName, cbSuccess, successData, cbFail, failData) => {
|
||||
// Check if the content type is in the localStorage (not saved) to prevent request error
|
||||
|
||||
@ -151,8 +151,8 @@
|
||||
"popUpWarning.bodyMessage.contentType.delete": "您確定要刪除這個資料結構嗎?",
|
||||
"popUpWarning.bodyMessage.attribute.delete": "您確定要刪除這個欄位嗎?",
|
||||
|
||||
"table.contentType.title.plural": "可用資料結構",
|
||||
"table.contentType.title.singular": "可用資料結構",
|
||||
"table.contentType.title.plural": "筆資料結構",
|
||||
"table.contentType.title.singular": "筆資料結構",
|
||||
"table.contentType.head.name": "名稱",
|
||||
"table.contentType.head.description": "說明",
|
||||
"table.contentType.head.fields": "欄位",
|
||||
|
||||
@ -136,8 +136,8 @@
|
||||
"list.languages.default.languages": "預設語言",
|
||||
"list.languages.set.languages": "設為預設",
|
||||
"list.databases.button.label": "增加新的連線",
|
||||
"list.databases.title.singular": "這個環境的連線",
|
||||
"list.databases.title.plural": "這個環境的連線",
|
||||
"list.databases.title.singular": "個環境連線",
|
||||
"list.databases.title.plural": "個環境連線",
|
||||
|
||||
"popUpWarning.title": "請確認",
|
||||
"popUpWarning.databases.danger.message":
|
||||
|
||||
@ -19,6 +19,6 @@
|
||||
|
||||
.subFormWrapper {
|
||||
margin-bottom: 14px;
|
||||
padding: 5px 30px 0 30px;
|
||||
padding: 23px 30px 0 30px;
|
||||
background-color: #FAFAFB;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"archive": ["rar", "zip"],
|
||||
"code": ["js", "json", "rb", "erb", "txt", "css", "scss", "html", "jsx"],
|
||||
"code": ["js", "json", "rb", "erb", "txt", "css", "scss", "html", "jsx", "svg"],
|
||||
"img": ["jpg", "jpeg", "png", "gif", "ico"],
|
||||
"pdf": ["pdf"],
|
||||
"powerpoint": ["ppt", "key", "xls"],
|
||||
|
||||
@ -40,7 +40,7 @@ function FileIcon({ fileType }) {
|
||||
className={(cn(
|
||||
styles.fileIconContainer,
|
||||
iconType === 'file-pdf-o' && styles.pdf,
|
||||
iconType === 'file-zip-o' && styles.zip,
|
||||
iconType === 'file-archive-o' && styles.zip,
|
||||
iconType === 'file-image-o' && styles.image,
|
||||
iconType === 'file-video-o' && styles.video,
|
||||
iconType === 'file-code-o' && styles.code,
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
.fileIconContainer {
|
||||
font-size: 20px;
|
||||
color: #BDBFC2;
|
||||
}
|
||||
|
||||
.image {
|
||||
color: #FFA35C;
|
||||
color: #8AA066;
|
||||
}
|
||||
|
||||
.pdf {
|
||||
@ -15,9 +16,9 @@
|
||||
}
|
||||
|
||||
.zip {
|
||||
color: #C29357;
|
||||
color: #715A31;
|
||||
}
|
||||
|
||||
.code {
|
||||
color: #BDBFC2;
|
||||
color: #515A6D;
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@
|
||||
}
|
||||
|
||||
.truncate {
|
||||
overflow-x: hidden;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@ export function* submit() {
|
||||
yield call(request, requestURL, { method: 'PUT', body });
|
||||
|
||||
// Update reducer with optimisticResponse
|
||||
strapi.notification.success('upload.notification.config.success');
|
||||
yield put(submitSucceeded(body));
|
||||
} catch(err) {
|
||||
console.log('err', err);
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
"PluginInputFile.text": "Drag & drop your files into this area or {link} from a file to upload",
|
||||
"PluginInputFile.link": "browse",
|
||||
|
||||
|
||||
"notification.delete.success": "The file has been deleted",
|
||||
"notification.dropFile.success": "Your file has been uploaded",
|
||||
"notification.dropFiles.success": "{number} files have been uploaded"
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
"EditForm.Input.select.inputDescription": "Files can either be uploaded on your server or on external providers.",
|
||||
"EditForm.Input.toggle.label": "Enable file upload",
|
||||
|
||||
"EmptyLi.message": "There is no uploaded files",
|
||||
"EmptyLi.message": "There are no uploaded files",
|
||||
|
||||
"EntriesNumber.number": "{number} file found",
|
||||
"EntriesNumber.number.plural": "{number} files found",
|
||||
@ -29,6 +29,7 @@
|
||||
"PluginInputFile.link": "browse",
|
||||
"PluginInputFile.loading": "Your files are being uploaded",
|
||||
|
||||
"notification.config.success": "The settings has been updated",
|
||||
"notification.delete.success": "The file has been deleted",
|
||||
"notification.dropFile.success": "Your file has been uploaded",
|
||||
"notification.dropFiles.success": "{number} files have been uploaded"
|
||||
|
||||
@ -59,42 +59,51 @@ CREATE TABLE ${quote}upload_file_morph${quote} (
|
||||
name: 'upload'
|
||||
});
|
||||
|
||||
fs.readdir(path.join(strapi.config.appPath, 'plugins', 'upload', 'node_modules'), async (err, node_modules) => {
|
||||
// get all upload provider
|
||||
const uploads = _.filter(node_modules, (node_module) => {
|
||||
return _.startsWith(node_module, ('strapi-upload'));
|
||||
});
|
||||
const loadProviders = (basePath, 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'));
|
||||
});
|
||||
|
||||
strapi.plugins.upload.config.providers = [];
|
||||
strapi.plugins.upload.config.providers = [];
|
||||
|
||||
// mount all providers to get configs
|
||||
_.forEach(uploads, (node_module) => {
|
||||
strapi.plugins.upload.config.providers.push(
|
||||
require(path.join(`${strapi.config.appPath}/plugins/upload/node_modules/${node_module}`))
|
||||
);
|
||||
});
|
||||
// mount all providers to get configs
|
||||
_.forEach(uploads, (node_module) => {
|
||||
strapi.plugins.upload.config.providers.push(
|
||||
require(path.join(`${basePath}/node_modules/${node_module}`))
|
||||
);
|
||||
});
|
||||
|
||||
try {
|
||||
// if provider config not exit set one by default
|
||||
const config = await pluginStore.get({key: 'provider'});
|
||||
try {
|
||||
// if provider config not exit set one by default
|
||||
const config = await pluginStore.get({key: 'provider'});
|
||||
|
||||
if (!config) {
|
||||
const provider = _.find(strapi.plugins.upload.config.providers, {provider: 'local'});
|
||||
if (!config) {
|
||||
const provider = _.find(strapi.plugins.upload.config.providers, {provider: 'local'});
|
||||
|
||||
const value = _.assign({}, provider, {
|
||||
enabled: true,
|
||||
// by default limit size to 1 GB
|
||||
sizeLimit: 1000000
|
||||
});
|
||||
const value = _.assign({}, provider, {
|
||||
enabled: true,
|
||||
// by default limit size to 1 GB
|
||||
sizeLimit: 1000000
|
||||
});
|
||||
|
||||
await pluginStore.set({key: 'provider', value});
|
||||
await pluginStore.set({key: 'provider', value});
|
||||
}
|
||||
} 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.stop();
|
||||
}
|
||||
} 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.stop();
|
||||
}
|
||||
|
||||
cb();
|
||||
cb();
|
||||
});
|
||||
}
|
||||
|
||||
// Load providers from the plugins' node_modules.
|
||||
loadProviders(path.join(strapi.config.appPath, 'plugins', 'upload'), () => {
|
||||
// Load providers from the root node_modules.
|
||||
loadProviders(path.join(strapi.config.appPath), cb);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
@ -22,11 +22,12 @@ module.exports = {
|
||||
environment: strapi.config.environment,
|
||||
type: 'plugin',
|
||||
name: 'upload'
|
||||
}).get({key: 'provider'});
|
||||
}).get({ key: 'provider' });
|
||||
|
||||
// Verify if the file upload is enable.
|
||||
if (config.enabled === false) {
|
||||
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Upload.status.disabled' }] }] : 'The file upload is disabled!');
|
||||
strapi.log.error('File upload is disabled');
|
||||
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Upload.status.disabled' }] }] : 'File upload is disabled');
|
||||
}
|
||||
|
||||
// Extract optional relational data.
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
"description": "This is the description of the plugin.",
|
||||
"strapi": {
|
||||
"name": "Files Upload",
|
||||
"icon": "upload",
|
||||
"icon": "cloud-upload",
|
||||
"description": "Description of upload plugin."
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@ -44,6 +44,11 @@ module.exports = {
|
||||
upload: async (files, config) => {
|
||||
// Get upload provider settings to configure the provider to use.
|
||||
const provider = _.find(strapi.plugins.upload.config.providers, { provider: config.provider });
|
||||
|
||||
if (!provider) {
|
||||
throw new Error(`The provider package isn't installed. Please run \`npm install strapi-upload-${config.provider}\``);
|
||||
}
|
||||
|
||||
const actions = provider.init(config);
|
||||
|
||||
// Execute upload function of the provider for all files.
|
||||
|
||||
@ -4,9 +4,6 @@
|
||||
"name": "user",
|
||||
"description": ""
|
||||
},
|
||||
"options": {
|
||||
"timestamps": true
|
||||
},
|
||||
"attributes": {
|
||||
"username": {
|
||||
"type": "string",
|
||||
|
||||
@ -28,8 +28,20 @@ function getBool(envVar, defaultValue) {
|
||||
const loggerConfig = {
|
||||
level: getLogLevel(),
|
||||
timestamp: getBool(process.env.STRAPI_LOG_TIMESTAMP, false),
|
||||
prettyPrint: getBool(process.env.STRAPI_LOG_PRETTY_PRINT, true),
|
||||
forceColor: getBool(process.env.STRAPI_LOG_FORCE_COLOR, true),
|
||||
// prettyPrint: getBool(process.env.STRAPI_LOG_PRETTY_PRINT, true),
|
||||
forceColor: getBool(process.env.STRAPI_LOG_FORCE_COLOR, true)
|
||||
};
|
||||
|
||||
module.exports = pino(loggerConfig);
|
||||
const pretty = pino.pretty({
|
||||
formatter: (logs, options) => {
|
||||
return `\u001b[90m[${new Date().toISOString()}] ${options.prefix.toLowerCase()} ${options.asColoredText(logs.level, logs.msg)}`;
|
||||
}
|
||||
});
|
||||
|
||||
pretty.pipe(process.stdout);
|
||||
|
||||
const logger = getBool(process.env.STRAPI_LOG_PRETTY_PRINT, true) ?
|
||||
pino(loggerConfig, pretty):
|
||||
pino(loggerConfig);
|
||||
|
||||
module.exports = logger;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user