mirror of
https://github.com/strapi/strapi.git
synced 2025-10-27 08:02:56 +00:00
Merge branch 'features/media-lib' of github.com:strapi/strapi into features/media-lib-settings
Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
commit
074d30ccfb
@ -198,6 +198,7 @@ In order to add a link into the global section of the settings view you need to
|
|||||||
|
|
||||||
**Path —** `plugins/my-plugin/admin/src/index.js`.
|
**Path —** `plugins/my-plugin/admin/src/index.js`.
|
||||||
|
|
||||||
|
```
|
||||||
import pluginPkg from '../../package.json';
|
import pluginPkg from '../../package.json';
|
||||||
// Import the component
|
// Import the component
|
||||||
import Settings from './containers/Settings';
|
import Settings from './containers/Settings';
|
||||||
@ -272,4 +273,3 @@ return strapi.registerPlugin(plugin);
|
|||||||
::: danger
|
::: danger
|
||||||
It is currently not possible to add a link into another plugin's setting section
|
It is currently not possible to add a link into another plugin's setting section
|
||||||
:::
|
:::
|
||||||
```
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
const colors = {
|
const colors = {
|
||||||
black: '#000000',
|
black: '#3b3b3b',
|
||||||
white: '#ffffff',
|
white: '#ffffff',
|
||||||
red: '#ff203c',
|
red: '#ff203c',
|
||||||
orange: '#ff5d00',
|
orange: '#ff5d00',
|
||||||
@ -14,6 +14,10 @@ const colors = {
|
|||||||
'gray-light': '#636c72',
|
'gray-light': '#636c72',
|
||||||
'gray-lighter': '#eceeef',
|
'gray-lighter': '#eceeef',
|
||||||
'gray-lightest': '#f7f7f9',
|
'gray-lightest': '#f7f7f9',
|
||||||
|
brightGrey: '#f0f3f8',
|
||||||
|
lightGrey: '#fafafa',
|
||||||
|
grey: '#9ea7b8',
|
||||||
|
greyDark: '#292b2c',
|
||||||
|
|
||||||
content: {
|
content: {
|
||||||
background: '#fafafb',
|
background: '#fafafb',
|
||||||
|
|||||||
8
packages/strapi-admin/admin/src/themes/fontSizes.js
Normal file
8
packages/strapi-admin/admin/src/themes/fontSizes.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
const fontSizes = {
|
||||||
|
xs: '11px',
|
||||||
|
sm: '12px',
|
||||||
|
md: '13px',
|
||||||
|
lg: '18px',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default fontSizes;
|
||||||
8
packages/strapi-admin/admin/src/themes/fontWeights.js
Normal file
8
packages/strapi-admin/admin/src/themes/fontWeights.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
const fontWeights = {
|
||||||
|
regular: 400,
|
||||||
|
semiBold: 500,
|
||||||
|
bold: 600,
|
||||||
|
black: 900,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default fontWeights;
|
||||||
@ -1,9 +1,13 @@
|
|||||||
import colors from './colors';
|
import colors from './colors';
|
||||||
|
import fontSizes from './fontSizes';
|
||||||
|
import fontWeights from './fontWeights';
|
||||||
import sizes from './sizes';
|
import sizes from './sizes';
|
||||||
|
|
||||||
const theme = {
|
const theme = {
|
||||||
main: {
|
main: {
|
||||||
colors,
|
colors,
|
||||||
|
fontSizes,
|
||||||
|
fontWeights,
|
||||||
sizes,
|
sizes,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,6 +6,14 @@ const sizes = {
|
|||||||
height: '6rem',
|
height: '6rem',
|
||||||
width: '24rem',
|
width: '24rem',
|
||||||
},
|
},
|
||||||
|
margins: {
|
||||||
|
// TODO:
|
||||||
|
sm: '10px',
|
||||||
|
},
|
||||||
|
padding: {
|
||||||
|
// TODO
|
||||||
|
md: '30px',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default sizes;
|
export default sizes;
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
"app.components.BlockLink.documentation.content": "Ознакомьтесь с концепциями, справочниками и обучающими материалами.",
|
"app.components.BlockLink.documentation.content": "Ознакомьтесь с концепциями, справочниками и обучающими материалами.",
|
||||||
"app.components.Button.cancel": "Отменить",
|
"app.components.Button.cancel": "Отменить",
|
||||||
"app.components.Button.save": "Сохранить",
|
"app.components.Button.save": "Сохранить",
|
||||||
|
"app.components.Button.reset": "Сброс",
|
||||||
"app.components.ComingSoonPage.comingSoon": "Скоро",
|
"app.components.ComingSoonPage.comingSoon": "Скоро",
|
||||||
"app.components.ComingSoonPage.featuresNotAvailable": "Этот функционал все еще находится в активной разработке.",
|
"app.components.ComingSoonPage.featuresNotAvailable": "Этот функционал все еще находится в активной разработке.",
|
||||||
"app.components.DownloadInfo.download": "Выполняется загрузка...",
|
"app.components.DownloadInfo.download": "Выполняется загрузка...",
|
||||||
@ -75,8 +76,10 @@
|
|||||||
"app.components.LeftMenuLinkContainer.general": "Общие",
|
"app.components.LeftMenuLinkContainer.general": "Общие",
|
||||||
"app.components.LeftMenuLinkContainer.installNewPlugin": "Магазин",
|
"app.components.LeftMenuLinkContainer.installNewPlugin": "Магазин",
|
||||||
"app.components.LeftMenuLinkContainer.listPlugins": "Плагины",
|
"app.components.LeftMenuLinkContainer.listPlugins": "Плагины",
|
||||||
|
"app.components.LeftMenuLinkContainer.contentTypes": "Типы контента",
|
||||||
"app.components.LeftMenuLinkContainer.noPluginsInstalled": "Нет установленных плагинов",
|
"app.components.LeftMenuLinkContainer.noPluginsInstalled": "Нет установленных плагинов",
|
||||||
"app.components.LeftMenuLinkContainer.plugins": "Плагины",
|
"app.components.LeftMenuLinkContainer.plugins": "Плагины",
|
||||||
|
"app.components.LeftMenuLinkContainer.settings": "Настройки",
|
||||||
"app.components.ListPluginsPage.description": "Список установленных плагинов в проекте.",
|
"app.components.ListPluginsPage.description": "Список установленных плагинов в проекте.",
|
||||||
"app.components.ListPluginsPage.helmet.title": "Список плагинов",
|
"app.components.ListPluginsPage.helmet.title": "Список плагинов",
|
||||||
"app.components.ListPluginsPage.title": "Плагины",
|
"app.components.ListPluginsPage.title": "Плагины",
|
||||||
@ -105,6 +108,7 @@
|
|||||||
"app.components.listPlugins.title.plural": "{number} плагинов установлено",
|
"app.components.listPlugins.title.plural": "{number} плагинов установлено",
|
||||||
"app.components.listPlugins.title.singular": "{number} плагин установлен",
|
"app.components.listPlugins.title.singular": "{number} плагин установлен",
|
||||||
"app.components.listPluginsPage.deletePlugin.error": "Произошла ошибка при удалении плагина",
|
"app.components.listPluginsPage.deletePlugin.error": "Произошла ошибка при удалении плагина",
|
||||||
|
"app.links.configure-view": "Настройка представления",
|
||||||
"app.utils.SelectOption.defaultMessage": " ",
|
"app.utils.SelectOption.defaultMessage": " ",
|
||||||
"app.utils.defaultMessage": " ",
|
"app.utils.defaultMessage": " ",
|
||||||
"app.utils.placeholder.defaultMessage": " ",
|
"app.utils.placeholder.defaultMessage": " ",
|
||||||
@ -125,7 +129,9 @@
|
|||||||
"components.Input.error.validation.minSupMax": "Не может быть выше",
|
"components.Input.error.validation.minSupMax": "Не может быть выше",
|
||||||
"components.Input.error.validation.regex": "Значение не соответствует регулярному выражению.",
|
"components.Input.error.validation.regex": "Значение не соответствует регулярному выражению.",
|
||||||
"components.Input.error.validation.required": "Обязательное значение.",
|
"components.Input.error.validation.required": "Обязательное значение.",
|
||||||
|
"components.Input.error.validation.unique": "Это значение уже используется.",
|
||||||
"components.InputSelect.option.placeholder": "Выберите здесь",
|
"components.InputSelect.option.placeholder": "Выберите здесь",
|
||||||
|
"component.Input.error.validation.integer": "Значение должно быть целочисленным",
|
||||||
"components.ListRow.empty": "Нет данных для отображения.",
|
"components.ListRow.empty": "Нет данных для отображения.",
|
||||||
"components.OverlayBlocker.description": "Вы воспользовались функционалом, который требует перезапуска сервера. Пожалуйста, подождите, пока сервер не будет запущен.",
|
"components.OverlayBlocker.description": "Вы воспользовались функционалом, который требует перезапуска сервера. Пожалуйста, подождите, пока сервер не будет запущен.",
|
||||||
"components.OverlayBlocker.description.serverError": "Сервер должен был перезагрузиться, пожалуйста, проверьте ваши логи в терминале.",
|
"components.OverlayBlocker.description.serverError": "Сервер должен был перезагрузиться, пожалуйста, проверьте ваши логи в терминале.",
|
||||||
@ -163,7 +169,6 @@
|
|||||||
"HomePage.community": "Присоединяйтесь к сообществу",
|
"HomePage.community": "Присоединяйтесь к сообществу",
|
||||||
"HomePage.roadmap": "Смотрите нашу дорожную карту",
|
"HomePage.roadmap": "Смотрите нашу дорожную карту",
|
||||||
"HomePage.greetings": "Привет {name}!",
|
"HomePage.greetings": "Привет {name}!",
|
||||||
|
|
||||||
"Auth.advanced.allow_register": "",
|
"Auth.advanced.allow_register": "",
|
||||||
"Auth.privacy-policy-agreement.terms": "условия",
|
"Auth.privacy-policy-agreement.terms": "условия",
|
||||||
"Auth.privacy-policy-agreement.policy": "политика конфиденциальности",
|
"Auth.privacy-policy-agreement.policy": "политика конфиденциальности",
|
||||||
@ -212,8 +217,43 @@
|
|||||||
"Auth.header.register.description": "Для завершения установки и обеспечения безопасности приложения, создайте вашего первого пользователя (root admin), заполнив форму ниже.",
|
"Auth.header.register.description": "Для завершения установки и обеспечения безопасности приложения, создайте вашего первого пользователя (root admin), заполнив форму ниже.",
|
||||||
"Auth.link.forgot-password": "Забыли пароль?",
|
"Auth.link.forgot-password": "Забыли пароль?",
|
||||||
"Auth.link.ready": "Готовы войти?",
|
"Auth.link.ready": "Готовы войти?",
|
||||||
|
"Settings.global": "Глобальные настройки",
|
||||||
|
"Settings.error": "Ошибка",
|
||||||
|
"Settings.webhooks.title": "Webhooks",
|
||||||
|
"Settings.webhooks.singular": "webhook",
|
||||||
|
"Settings.webhooks.list.description": "Уведомления с помощью POST событий.",
|
||||||
|
"Settings.webhooks.list.button.add": "Добавить новый webhook",
|
||||||
|
"Settings.webhooks.list.button.delete": "Удалить",
|
||||||
|
"Settings.webhooks.list.empty.title": "Пока еще нет webhooks",
|
||||||
|
"Settings.webhooks.list.empty.description": "Добавить первый в этот список.",
|
||||||
|
"Settings.webhooks.list.empty.link": "Просмотреть документацию",
|
||||||
|
"Settings.webhooks.enabled": "Включен",
|
||||||
|
"Settings.webhooks.disabled": "Выключен",
|
||||||
|
"Settings.webhooks.create": "Создание webhook",
|
||||||
|
"Settings.webhooks.create.header": "Создание нового заголовка",
|
||||||
|
"Settings.webhooks.form.name": "Название",
|
||||||
|
"Settings.webhooks.form.url": "Url",
|
||||||
|
"Settings.webhooks.form.headers": "Заголовки",
|
||||||
|
"Settings.webhooks.form.events": "События",
|
||||||
|
"Settings.webhooks.key": "Ключ",
|
||||||
|
"Settings.webhooks.value": "Значение",
|
||||||
|
"Settings.webhooks.trigger": "Триггер",
|
||||||
|
"Settings.webhooks.trigger.title": "Сохранить перед триггером",
|
||||||
|
"Settings.webhooks.trigger.cancel": "Отмена триггера",
|
||||||
|
"Settings.webhooks.trigger.pending": "Ожидание…",
|
||||||
|
"Settings.webhooks.trigger.success": "Успех!",
|
||||||
|
"Settings.webhooks.trigger.success.label": "Триггер выполнен",
|
||||||
|
"Settings.webhooks.trigger.save": "Пожалуйста сохраните триггер",
|
||||||
|
"Settings.webhooks.trigger.test": "Тест триггер",
|
||||||
|
"Settings.webhooks.events.create": "Создание",
|
||||||
|
"Settings.webhooks.events.edit": "Редактирование",
|
||||||
|
"Settings.webhooks.events.delete": "Удаление",
|
||||||
|
"Settings.webhooks.created": "Webhook создан",
|
||||||
"app.containers.App.notification.error.init": "Произошла ошибка при запросе к API",
|
"app.containers.App.notification.error.init": "Произошла ошибка при запросе к API",
|
||||||
"components.Input.error.password.noMatch": "Пароль не совпадает",
|
"components.Input.error.password.noMatch": "Пароль не совпадает",
|
||||||
"form.button.done": "Выполнено",
|
"form.button.done": "Выполнено",
|
||||||
"notification.form.error.fields": "Форма содержит некоторые ошибки"
|
"form.button.finish": "Финиш",
|
||||||
|
"notification.form.error.fields": "Форма содержит некоторые ошибки",
|
||||||
|
"notification.form.success.fields": "Изменения сохранены",
|
||||||
|
"global.prompt.unsaved": "Вы действительно хотите покинуть эту страницу? Все Ваши изменения будут потеряны"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -249,6 +249,7 @@ async function watchFiles(dir, ignoreFiles = []) {
|
|||||||
const cacheDir = path.join(dir, '.cache');
|
const cacheDir = path.join(dir, '.cache');
|
||||||
const pkgJSON = require(path.join(dir, 'package.json'));
|
const pkgJSON = require(path.join(dir, 'package.json'));
|
||||||
const admin = path.join(dir, 'admin');
|
const admin = path.join(dir, 'admin');
|
||||||
|
const extensionsPath = path.join(dir, 'extensions');
|
||||||
|
|
||||||
const appPlugins = Object.keys(pkgJSON.dependencies).filter(
|
const appPlugins = Object.keys(pkgJSON.dependencies).filter(
|
||||||
dep =>
|
dep =>
|
||||||
@ -256,12 +257,7 @@ async function watchFiles(dir, ignoreFiles = []) {
|
|||||||
fs.existsSync(path.resolve(getPkgPath(dep), 'admin', 'src', 'index.js'))
|
fs.existsSync(path.resolve(getPkgPath(dep), 'admin', 'src', 'index.js'))
|
||||||
);
|
);
|
||||||
const pluginsToWatch = appPlugins.map(plugin =>
|
const pluginsToWatch = appPlugins.map(plugin =>
|
||||||
path.join(
|
path.join(extensionsPath, plugin.replace(/^strapi-plugin-/i, ''), 'admin')
|
||||||
dir,
|
|
||||||
'extensions',
|
|
||||||
plugin.replace(/^strapi-plugin-/i, ''),
|
|
||||||
'admin'
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
const filesToWatch = [admin, ...pluginsToWatch];
|
const filesToWatch = [admin, ...pluginsToWatch];
|
||||||
|
|
||||||
@ -272,20 +268,20 @@ async function watchFiles(dir, ignoreFiles = []) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
watcher.on('all', async (event, filePath) => {
|
watcher.on('all', async (event, filePath) => {
|
||||||
const re = /\/extensions\/([^\/]*)\/.*$/gm;
|
const isExtension = filePath.includes(extensionsPath);
|
||||||
const matched = re.exec(filePath);
|
const pluginName = isExtension
|
||||||
const isExtension = matched !== null;
|
? filePath.replace(extensionsPath, '').split(path.sep)[1]
|
||||||
const pluginName = isExtension ? matched[1] : '';
|
: '';
|
||||||
|
|
||||||
const packageName = isExtension
|
const packageName = isExtension
|
||||||
? `strapi-plugin-${pluginName}`
|
? `strapi-plugin-${pluginName}`
|
||||||
: 'strapi-admin';
|
: 'strapi-admin';
|
||||||
|
|
||||||
const targetPath = isExtension
|
const targetPath = isExtension
|
||||||
? filePath
|
? path.normalize(
|
||||||
.split(`${path.sep}extensions${path.sep}`)[1]
|
filePath.split(extensionsPath)[1].replace(pluginName, '')
|
||||||
.replace(pluginName, '')
|
)
|
||||||
: filePath.split(`${path.sep}admin`)[1];
|
: path.normalize(filePath.split(admin)[1]);
|
||||||
|
|
||||||
const destFolder = isExtension
|
const destFolder = isExtension
|
||||||
? path.join(cacheDir, 'plugins', packageName)
|
? path.join(cacheDir, 'plugins', packageName)
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import routerPropTypes from './router';
|
import routerPropTypes from './router';
|
||||||
|
import themeShape from './themeShape';
|
||||||
|
|
||||||
export {
|
export { routerPropTypes, themeShape };
|
||||||
routerPropTypes,
|
|
||||||
};
|
|
||||||
|
|||||||
@ -0,0 +1,14 @@
|
|||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
const themeShape = {
|
||||||
|
theme: PropTypes.shape({
|
||||||
|
main: PropTypes.shape({
|
||||||
|
colors: PropTypes.object,
|
||||||
|
fontSizes: PropTypes.object,
|
||||||
|
fontWeights: PropTypes.object,
|
||||||
|
sizes: PropTypes.object,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
export default themeShape;
|
||||||
@ -1,32 +0,0 @@
|
|||||||
import styled from 'styled-components';
|
|
||||||
import colors from '../../assets/styles/colors';
|
|
||||||
import sizes from '../../assets/styles/sizes';
|
|
||||||
|
|
||||||
const HeaderNavWrapper = styled.section`
|
|
||||||
display: flex;
|
|
||||||
padding: 0 ${sizes.margin * 3}px;
|
|
||||||
position: relative;
|
|
||||||
justify-content: space-between;
|
|
||||||
height: 65px;
|
|
||||||
font-size: 1.8rem;
|
|
||||||
> hr {
|
|
||||||
position: absolute;
|
|
||||||
left: ${sizes.margin * 3}px;
|
|
||||||
bottom: 0;
|
|
||||||
width: calc(100% - ${sizes.margin * 6}px);
|
|
||||||
height: 1px;
|
|
||||||
background: ${colors.brightGrey};
|
|
||||||
border: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
span {
|
|
||||||
padding-top: 16px;
|
|
||||||
}
|
|
||||||
.settings-tabs {
|
|
||||||
position: absolute;
|
|
||||||
right: ${sizes.margin * 3}px;
|
|
||||||
bottom: -${sizes.margin * 0.1}px;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export default HeaderNavWrapper;
|
|
||||||
@ -4,7 +4,7 @@ export { default as sizes } from './assets/styles/sizes';
|
|||||||
|
|
||||||
// CommonPropTypes
|
// CommonPropTypes
|
||||||
export { default as routerPropTypes } from './commonPropTypes/router';
|
export { default as routerPropTypes } from './commonPropTypes/router';
|
||||||
|
export { default as themePropTypes } from './commonPropTypes/themeShape';
|
||||||
// Components
|
// Components
|
||||||
export { default as BackHeader } from './components/BackHeader';
|
export { default as BackHeader } from './components/BackHeader';
|
||||||
export { default as BlockerComponent } from './components/BlockerComponent';
|
export { default as BlockerComponent } from './components/BlockerComponent';
|
||||||
@ -17,7 +17,6 @@ export { default as ErrorBoundary } from './components/ErrorBoundary';
|
|||||||
export { default as ExtendComponent } from './components/ExtendComponent';
|
export { default as ExtendComponent } from './components/ExtendComponent';
|
||||||
export { default as GlobalPagination } from './components/GlobalPagination';
|
export { default as GlobalPagination } from './components/GlobalPagination';
|
||||||
export { default as HeaderNav } from './components/HeaderNav';
|
export { default as HeaderNav } from './components/HeaderNav';
|
||||||
export { default as HeaderNavWrapper } from './components/HeaderNavWrapper';
|
|
||||||
export { default as HeaderModal } from './components/HeaderModal';
|
export { default as HeaderModal } from './components/HeaderModal';
|
||||||
export { default as HeaderModalTitle } from './components/HeaderModalTitle';
|
export { default as HeaderModalTitle } from './components/HeaderModalTitle';
|
||||||
export { default as HeaderSearch } from './components/HeaderSearch';
|
export { default as HeaderSearch } from './components/HeaderSearch';
|
||||||
|
|||||||
@ -0,0 +1,12 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
import { Container } from 'reactstrap';
|
||||||
|
|
||||||
|
const ContainerFluid = styled(Container)`
|
||||||
|
padding: 0;
|
||||||
|
`;
|
||||||
|
|
||||||
|
ContainerFluid.defaultProps = {
|
||||||
|
fluid: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ContainerFluid;
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const Flex = styled.div`
|
||||||
|
display: flex;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default Flex;
|
||||||
@ -3,8 +3,10 @@ import PropTypes from 'prop-types';
|
|||||||
|
|
||||||
const Label = styled.label`
|
const Label = styled.label`
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 204px;
|
height: 203px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
margin-top: 36px;
|
||||||
|
margin-bottom: 18px;
|
||||||
padding-top: 46px;
|
padding-top: 46px;
|
||||||
border: 2px dashed #e3e9f3;
|
border: 2px dashed #e3e9f3;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
@ -18,16 +20,12 @@ const Label = styled.label`
|
|||||||
right: 0;
|
right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
${({ isDragging }) => {
|
${({ isDragging }) =>
|
||||||
if (isDragging) {
|
isDragging &&
|
||||||
return `
|
`
|
||||||
background-color: rgba(28, 93, 231, 0.01);
|
background-color: rgba(28, 93, 231, 0.01);
|
||||||
border: 2px dashed rgba(28, 93, 231, 0.1);
|
border: 2px dashed rgba(28, 93, 231, 0.1);
|
||||||
`;
|
`}
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
Label.defaultProps = {
|
Label.defaultProps = {
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* NOTE:
|
||||||
|
* This component should be put in the strapi-helper-plugin
|
||||||
|
* at some point so the other packages can benefits from the updates
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
import { themePropTypes } from 'strapi-helper-plugin';
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
height: 59px;
|
||||||
|
line-height: 59px;
|
||||||
|
background-color: ${({ theme }) => theme.main.colors.lightGrey};
|
||||||
|
color: ${({ theme }) => theme.main.colors.black};
|
||||||
|
font-size: ${({ theme }) => theme.main.fontSizes.md};
|
||||||
|
font-weight: ${({ theme }) => theme.main.fontWeights.bold};
|
||||||
|
`;
|
||||||
|
|
||||||
|
Wrapper.propTypes = themePropTypes;
|
||||||
|
|
||||||
|
export default Wrapper;
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* NOTE:
|
||||||
|
* This component should be put in the strapi-helper-plugin
|
||||||
|
* at some point so the other packages can benefits from the updates
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { Fragment } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { HeaderModalTitle } from 'strapi-helper-plugin';
|
||||||
|
import ModalSection from '../ModalSection';
|
||||||
|
import Wrapper from './Wrapper';
|
||||||
|
|
||||||
|
const ModalHeader = ({ headers }) => {
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
<ModalSection>
|
||||||
|
<HeaderModalTitle>
|
||||||
|
{headers.map(({ key, element }) => {
|
||||||
|
return <Fragment key={key}>{element}</Fragment>;
|
||||||
|
})}
|
||||||
|
</HeaderModalTitle>
|
||||||
|
</ModalSection>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ModalHeader.defaultProps = {
|
||||||
|
headers: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
ModalHeader.propTypes = {
|
||||||
|
headers: PropTypes.array,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ModalHeader;
|
||||||
@ -1,24 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* ModalNav
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
import styled from 'styled-components';
|
|
||||||
|
|
||||||
const ModalNav = styled.div`
|
|
||||||
display: flex;
|
|
||||||
height: 3.8rem;
|
|
||||||
padding-top: 0.6rem;
|
|
||||||
color: #9ea7b8;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
font-weight: 500;
|
|
||||||
letter-spacing: 0.7px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
|
|
||||||
> div:last-child {
|
|
||||||
margin-left: 3rem;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export default ModalNav;
|
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
import { themePropTypes } from 'strapi-helper-plugin';
|
||||||
|
|
||||||
|
const Hr = styled.hr`
|
||||||
|
margin: 0px;
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
border: 0;
|
||||||
|
background: ${({ theme }) => theme.main.colors.brightGrey};
|
||||||
|
`;
|
||||||
|
|
||||||
|
Hr.propTypes = themePropTypes;
|
||||||
|
|
||||||
|
export default Hr;
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import Flex from '../Flex';
|
||||||
|
import ModalSection from '../ModalSection';
|
||||||
|
import ModalTab from '../ModalTab';
|
||||||
|
import Hr from './Hr';
|
||||||
|
|
||||||
|
const ModalNavWrapper = ({ children, links, onClickGoTo, to }) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ModalSection justifyContent="space-between">
|
||||||
|
<Flex>
|
||||||
|
{links.map(link => {
|
||||||
|
const isActive = link.to === to;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ModalTab
|
||||||
|
key={link.to}
|
||||||
|
label={link.label}
|
||||||
|
to={link.to}
|
||||||
|
isActive={isActive}
|
||||||
|
isDisabled={link.isDisabled}
|
||||||
|
onClick={onClickGoTo}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Flex>
|
||||||
|
{children}
|
||||||
|
</ModalSection>
|
||||||
|
<ModalSection>
|
||||||
|
<Hr />
|
||||||
|
</ModalSection>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ModalNavWrapper.defaultProps = {
|
||||||
|
children: null,
|
||||||
|
links: [],
|
||||||
|
onClickGoTo: () => {},
|
||||||
|
to: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
ModalNavWrapper.propTypes = {
|
||||||
|
children: PropTypes.node,
|
||||||
|
links: PropTypes.array,
|
||||||
|
onClickGoTo: PropTypes.func,
|
||||||
|
to: PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ModalNavWrapper;
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { themePropTypes } from 'strapi-helper-plugin';
|
||||||
|
|
||||||
|
const ModalSection = styled.section`
|
||||||
|
display: flex;
|
||||||
|
justify-content: ${({ justifyContent }) => justifyContent};
|
||||||
|
padding: 0 ${({ theme }) => theme.main.sizes.padding.md};
|
||||||
|
`;
|
||||||
|
|
||||||
|
ModalSection.defaultProps = {
|
||||||
|
justifyContent: 'initial',
|
||||||
|
};
|
||||||
|
|
||||||
|
ModalSection.propTypes = {
|
||||||
|
...themePropTypes,
|
||||||
|
justifyContent: PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ModalSection;
|
||||||
@ -1,23 +1,30 @@
|
|||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
const Wrapper = styled.div(({ isActive, isDisabled }) => {
|
const Wrapper = styled.div(({ isActive, isDisabled, theme }) => {
|
||||||
const cursor = isDisabled ? 'not-allowed' : 'pointer';
|
const cursor = isDisabled ? 'not-allowed' : 'pointer';
|
||||||
|
const baseStyle = {
|
||||||
|
color: '#9ea7b8',
|
||||||
|
cursor,
|
||||||
|
fontSize: theme.main.fontSizes.sm,
|
||||||
|
fontWeight: theme.main.fontWeights.bold,
|
||||||
|
letterSpacing: '0.7px',
|
||||||
|
marginTop: '34px',
|
||||||
|
marginRight: '30px',
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
};
|
||||||
|
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
return {
|
return {
|
||||||
|
...baseStyle,
|
||||||
height: '3rem',
|
height: '3rem',
|
||||||
cursor,
|
|
||||||
color: '#007eff',
|
color: '#007eff',
|
||||||
fontWeight: 600,
|
|
||||||
borderBottom: '2px solid #007eff',
|
borderBottom: '2px solid #007eff',
|
||||||
zIndex: 99,
|
zIndex: 99,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return baseStyle;
|
||||||
cursor,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Wrapper.defaultProps = {
|
Wrapper.defaultProps = {
|
||||||
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* HeaderNavLink
|
* ModalTab
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -10,7 +10,7 @@ import { FormattedMessage } from 'react-intl';
|
|||||||
import getTrad from '../../utils/getTrad';
|
import getTrad from '../../utils/getTrad';
|
||||||
import Wrapper from './Wrapper';
|
import Wrapper from './Wrapper';
|
||||||
|
|
||||||
const HeaderNavLink = ({ isDisabled, to, isActive, onClick }) => {
|
const ModalTab = ({ isDisabled, label, to, isActive, onClick }) => {
|
||||||
const handleClick = e => {
|
const handleClick = e => {
|
||||||
if (isDisabled) {
|
if (isDisabled) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -23,22 +23,23 @@ const HeaderNavLink = ({ isDisabled, to, isActive, onClick }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Wrapper isActive={isActive} isDisabled={isDisabled} onClick={handleClick}>
|
<Wrapper isActive={isActive} isDisabled={isDisabled} onClick={handleClick}>
|
||||||
<FormattedMessage id={getTrad(`modal.nav.${to}`)} />
|
<FormattedMessage id={getTrad(`modal.nav.${label}`)} />
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
HeaderNavLink.defaultProps = {
|
ModalTab.defaultProps = {
|
||||||
isActive: false,
|
isActive: false,
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
onClick: () => {},
|
onClick: () => {},
|
||||||
};
|
};
|
||||||
|
|
||||||
HeaderNavLink.propTypes = {
|
ModalTab.propTypes = {
|
||||||
to: PropTypes.string.isRequired,
|
to: PropTypes.string.isRequired,
|
||||||
isActive: PropTypes.bool,
|
isActive: PropTypes.bool,
|
||||||
isDisabled: PropTypes.bool,
|
isDisabled: PropTypes.bool,
|
||||||
|
label: PropTypes.string.isRequired,
|
||||||
onClick: PropTypes.func,
|
onClick: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default HeaderNavLink;
|
export default ModalTab;
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const Text = styled.p`
|
||||||
|
margin: 0;
|
||||||
|
line-height: 18px;
|
||||||
|
color: ${({ theme, color }) => theme.main.colors[color]};
|
||||||
|
font-size: ${({ theme, fontSize }) => theme.main.fontSizes[fontSize]};
|
||||||
|
font-weight: ${({ theme, fontWeight }) => theme.main.fontWeights[fontWeight]};
|
||||||
|
`;
|
||||||
|
|
||||||
|
Text.defaultProps = {
|
||||||
|
color: 'greyDark',
|
||||||
|
fontSize: 'md',
|
||||||
|
fontWeight: 'regular',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Text;
|
||||||
@ -1,18 +1,20 @@
|
|||||||
import React, { useReducer } from 'react';
|
import React, { useReducer } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { HeaderNavWrapper, ModalBody, ModalForm } from 'strapi-helper-plugin';
|
|
||||||
import ModalNav from '../ModalNav';
|
|
||||||
import NavLink from '../NavLink';
|
|
||||||
import InputFile from '../InputFile';
|
import InputFile from '../InputFile';
|
||||||
|
import ModalNavWrapper from '../ModalNavWrapper';
|
||||||
|
import ModalSection from '../ModalSection';
|
||||||
import init from './init';
|
import init from './init';
|
||||||
import reducer, { initialState } from './reducer';
|
import reducer, { initialState } from './reducer';
|
||||||
|
|
||||||
const UploadForm = ({ addFilesToUpload }) => {
|
const UploadForm = ({ addFilesToUpload }) => {
|
||||||
const [reducerState, dispatch] = useReducer(reducer, initialState, init);
|
const [reducerState, dispatch] = useReducer(reducer, initialState, init);
|
||||||
const { to } = reducerState.toJS();
|
const { to } = reducerState.toJS();
|
||||||
const links = ['computer', 'url'];
|
const links = [
|
||||||
|
{ to: 'computer', label: 'computer', isDisabled: false },
|
||||||
|
{ to: 'url', label: 'url', isDisabled: true },
|
||||||
|
];
|
||||||
|
|
||||||
const handleGoTo = to => {
|
const handleClickGoTo = to => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'SET_TAB',
|
type: 'SET_TAB',
|
||||||
to,
|
to,
|
||||||
@ -21,38 +23,11 @@ const UploadForm = ({ addFilesToUpload }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<HeaderNavWrapper>
|
<ModalNavWrapper links={links} to={to} onClickGoTo={handleClickGoTo} />
|
||||||
<div className="settings-tabs" style={{ left: 30 }}>
|
<ModalSection>
|
||||||
<ModalNav>
|
|
||||||
{links.map(link => {
|
|
||||||
const isActive = link === to;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<NavLink
|
|
||||||
key={link}
|
|
||||||
to={link}
|
|
||||||
isActive={isActive}
|
|
||||||
isDisabled={link === 'url'}
|
|
||||||
onClick={handleGoTo}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ModalNav>
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
</HeaderNavWrapper>
|
|
||||||
<ModalForm>
|
|
||||||
<ModalBody style={{ paddingTop: 35, paddingBottom: 18 }}>
|
|
||||||
<div className="container-fluid">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
{to === 'computer' && <InputFile onChange={addFilesToUpload} />}
|
{to === 'computer' && <InputFile onChange={addFilesToUpload} />}
|
||||||
{to === 'url' && <div>COMING SOON</div>}
|
{to === 'url' && <div>COMING SOON</div>}
|
||||||
</div>
|
</ModalSection>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ModalBody>
|
|
||||||
</ModalForm>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -0,0 +1,7 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const ButtonWrapper = styled.div`
|
||||||
|
padding-top: 28px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default ButtonWrapper;
|
||||||
@ -1,17 +0,0 @@
|
|||||||
import styled from 'styled-components';
|
|
||||||
import { HeaderNavWrapper } from 'strapi-helper-plugin';
|
|
||||||
|
|
||||||
const Wrapper = styled(HeaderNavWrapper)`
|
|
||||||
padding-top: 27px;
|
|
||||||
font-size: 12px;
|
|
||||||
|
|
||||||
.assets-selected {
|
|
||||||
padding-top: 7px;
|
|
||||||
line-height: 18px;
|
|
||||||
}
|
|
||||||
.infos {
|
|
||||||
color: #9ea7b8;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export default Wrapper;
|
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const ListWrapper = styled.div`
|
||||||
|
margin-bottom: 4px;
|
||||||
|
padding-top: 14px;
|
||||||
|
max-height: 350px;
|
||||||
|
overflow: auto;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default ListWrapper;
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const TextWrapper = styled.div`
|
||||||
|
padding-top: 34px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default TextWrapper;
|
||||||
@ -1,13 +1,16 @@
|
|||||||
/* eslint-disable react/no-array-index-key */
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import { ModalBody } from 'strapi-helper-plugin';
|
|
||||||
import { Button } from '@buffetjs/core';
|
import { Button } from '@buffetjs/core';
|
||||||
import createMatrix from '../../utils/createMatrix';
|
import createMatrix from '../../utils/createMatrix';
|
||||||
import getTrad from '../../utils/getTrad';
|
import getTrad from '../../utils/getTrad';
|
||||||
import HeaderWrapper from './HeaderWrapper';
|
import ContainerFluid from '../ContainerFluid';
|
||||||
|
import ModalSection from '../ModalSection';
|
||||||
|
import Text from '../Text';
|
||||||
|
import ButtonWrapper from './ButtonWrapper';
|
||||||
|
import TextWrapper from './TextWrapper';
|
||||||
import RowItem from './RowItem';
|
import RowItem from './RowItem';
|
||||||
|
import ListWrapper from './ListWrapper';
|
||||||
|
|
||||||
const UploadList = ({
|
const UploadList = ({
|
||||||
filesToUpload,
|
filesToUpload,
|
||||||
@ -22,22 +25,23 @@ const UploadList = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<HeaderWrapper>
|
<ModalSection justifyContent="space-between">
|
||||||
<div>
|
<TextWrapper>
|
||||||
<div className="assets-selected">
|
<Text fontSize="md" fontWeight="bold">
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id={getTrad(titleId)}
|
id={getTrad(titleId)}
|
||||||
values={{ number: filesToUploadLength }}
|
values={{ number: filesToUploadLength }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</Text>
|
||||||
<div className="infos">
|
|
||||||
|
<Text fontSize="sm" color="grey">
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id={getTrad('modal.upload-list.sub-header-subtitle')}
|
id={getTrad('modal.upload-list.sub-header-subtitle')}
|
||||||
values={{ number: filesToUploadLength }}
|
values={{ number: filesToUploadLength }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</Text>
|
||||||
</div>
|
</TextWrapper>
|
||||||
<div>
|
<ButtonWrapper>
|
||||||
<FormattedMessage id={getTrad('modal.upload-list.sub-header.button')}>
|
<FormattedMessage id={getTrad('modal.upload-list.sub-header.button')}>
|
||||||
{label => (
|
{label => (
|
||||||
<Button
|
<Button
|
||||||
@ -48,18 +52,12 @@ const UploadList = ({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</FormattedMessage>
|
</FormattedMessage>
|
||||||
</div>
|
</ButtonWrapper>
|
||||||
</HeaderWrapper>
|
</ModalSection>
|
||||||
<ModalBody>
|
|
||||||
<div
|
<ModalSection>
|
||||||
className="container"
|
<ContainerFluid>
|
||||||
style={{
|
<ListWrapper>
|
||||||
marginTop: -4,
|
|
||||||
marginBottom: 4,
|
|
||||||
overflow: 'auto',
|
|
||||||
maxHeight: 350,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{matrix.map(({ key, rowContent }) => {
|
{matrix.map(({ key, rowContent }) => {
|
||||||
return (
|
return (
|
||||||
<div className="row" key={key}>
|
<div className="row" key={key}>
|
||||||
@ -73,8 +71,9 @@ const UploadList = ({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</ListWrapper>
|
||||||
</ModalBody>
|
</ContainerFluid>
|
||||||
|
</ModalSection>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,8 +2,6 @@ import React, { useEffect, useReducer, useRef } from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { get } from 'lodash';
|
import { get } from 'lodash';
|
||||||
import {
|
import {
|
||||||
HeaderModal,
|
|
||||||
HeaderModalTitle,
|
|
||||||
Modal,
|
Modal,
|
||||||
ModalFooter,
|
ModalFooter,
|
||||||
useGlobalContext,
|
useGlobalContext,
|
||||||
@ -12,6 +10,7 @@ import {
|
|||||||
import { Button } from '@buffetjs/core';
|
import { Button } from '@buffetjs/core';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import pluginId from '../../pluginId';
|
import pluginId from '../../pluginId';
|
||||||
|
import ModalHeader from '../../components/ModalHeader';
|
||||||
import stepper from './utils/stepper';
|
import stepper from './utils/stepper';
|
||||||
import init from './init';
|
import init from './init';
|
||||||
import reducer, { initialState } from './reducer';
|
import reducer, { initialState } from './reducer';
|
||||||
@ -141,13 +140,14 @@ const ModalStepper = ({ isOpen, onToggle }) => {
|
|||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} onToggle={onToggle} onClosed={handleClosed}>
|
<Modal isOpen={isOpen} onToggle={onToggle} onClosed={handleClosed}>
|
||||||
{/* header title */}
|
{/* header title */}
|
||||||
<HeaderModal>
|
<ModalHeader
|
||||||
<section>
|
headers={[
|
||||||
<HeaderModalTitle>
|
{
|
||||||
<FormattedMessage id={headerTradId} />
|
key: headerTradId,
|
||||||
</HeaderModalTitle>
|
element: <FormattedMessage id={headerTradId} />,
|
||||||
</section>
|
},
|
||||||
</HeaderModal>
|
]}
|
||||||
|
/>
|
||||||
{/* body of the modal */}
|
{/* body of the modal */}
|
||||||
{Component && (
|
{Component && (
|
||||||
<Component
|
<Component
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user