Skip to content

Commit

Permalink
EPMRPP-89999 || Update import flow
Browse files Browse the repository at this point in the history
  • Loading branch information
Vadim73i committed May 8, 2024
1 parent e1cb3fb commit 9691446
Show file tree
Hide file tree
Showing 29 changed files with 554 additions and 182 deletions.
4 changes: 3 additions & 1 deletion app/localization/translated/be.json
Original file line number Diff line number Diff line change
Expand Up @@ -938,9 +938,9 @@
"IgnoreInAAModal.textMultiple": "Вы ўпэўненыя, што хочаце ігнараваць элементы ў Аўта-Аналізу?",
"IgnoreInAAModal.title": "Iгнараваць элемент ў Аўта-Аналізу",
"IgnoreInAAModal.titleMultiple": "Iгнараваць элементы ў Аўта-Аналізу",
"ImportLaunchModal.note": "Увага:",
"ImportModal.importConfirmation": "Пацвердзіць адмену",
"ImportModal.incorrectFileFormat": "Няправільны фармат файла",
"ImportModal.note": "Увага:",
"IncludeInAAModal.includeButton": "Уключыць",
"IncludeInAAModal.successMessage": "Элемент паспяхова дададзены ў Аўта-Аналіз",
"IncludeInAAModal.successMessageMultiple": "Элементы паспяхова дададзены ў Аўта-Аналіз",
Expand Down Expand Up @@ -1572,6 +1572,7 @@
"PhotoControls.uploadError": "Не ўдалося абнавіць фота",
"PhotoControls.uploadPhoto": "Запампаваць Фотаздымак",
"PhotoControls.wasDeleted": "Фота паспяхова выдалена",
"PluginDropDown.ReportType": "Тып дакладу:",
"PluginItem.disablePluginMessage": "Вы ўпэўнены, што хочаце адключыць плагін {pluginName}? Калі вы адключыце плагін, інфармацыя пра яго будзе хавацца ў {pluginLocation}, і карыстальнікі не змогуць з ім ўзаемадзейнічаць",
"PluginItem.disablePluginTitle": "Адключыць плагін",
"PluginItem.disabledPluginMessage": "Плагін быў адключаны",
Expand All @@ -1580,6 +1581,7 @@
"PluginItem.enabledPluginMessage": "Плагін быў уключаны",
"PluginItem.titleVersion": "версія {version}",
"Plugins.disabled.bts": "не будзе паказаны ў наладах праекта. Карыстальнікі не змогуць стварыць дэфект або прымацаваць праблему да існуючага дэфекту ў СОД",
"Plugins.disabled.import": "Зараз у асобнік не ўключаны/запампаваны плагін {name}. <a>Дакументацыя</a>",
"Plugins.disabled.notification": "не будзе паказаны ў наладах праекта. Карыстальнікі не змогуць атрымліваць абвесткі аб завершаных запусках, а таксама не змогуць адпраўляць запрашэння",
"Plugins.disabled.other": "не будзе паказаны ў наладах праекта",
"PluginsFilter.all": "Усе",
Expand Down
4 changes: 3 additions & 1 deletion app/localization/translated/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -938,9 +938,9 @@
"IgnoreInAAModal.textMultiple": "Вы уверены, что хотите игнорировать элементы в Авто-Анализ?",
"IgnoreInAAModal.title": "Игнорировать элемент при Авто-Анализе",
"IgnoreInAAModal.titleMultiple": "Игнорировать элементы при Авто-Анализе",
"ImportLaunchModal.note": "Внимание:",
"ImportModal.importConfirmation": "Подтвердить отмену",
"ImportModal.incorrectFileFormat": "Неправильный формат файла",
"ImportModal.note": "Внимание:",
"IncludeInAAModal.includeButton": "Включить",
"IncludeInAAModal.successMessage": "Элемент успешно добавлен в Авто-Анализ",
"IncludeInAAModal.successMessageMultiple": "Элементы успешно добавлены в Авто-Анализ",
Expand Down Expand Up @@ -1572,6 +1572,7 @@
"PhotoControls.uploadError": "Не удалось обновить фото",
"PhotoControls.uploadPhoto": "Загрузить Фото",
"PhotoControls.wasDeleted": "Фото успешно удалено",
"PluginDropDown.ReportType": "Тип отчёта:",
"PluginItem.disablePluginMessage": "Вы действительно хотите отключить плагин {pluginName}? Если вы отключите плагин, информация о нем будет скрыта в {pluginLocation}, и пользователи не смогут с ним взаимодействовать",
"PluginItem.disablePluginTitle": "Отключить плагин",
"PluginItem.disabledPluginMessage": "Плагин был отключен",
Expand All @@ -1580,6 +1581,7 @@
"PluginItem.enabledPluginMessage": "Плагин был включен",
"PluginItem.titleVersion": "версия {version}",
"Plugins.disabled.bts": "не будет показан в настройках проекта. Пользователи не смогут создать дефект или прикрепить проблему к существующему дефекту в СОД",
"Plugins.disabled.import": "В данный момент нет включенного/загруженного {name} плагина на инстансе. <a>Документация</a>",
"Plugins.disabled.notification": "не будет показан в настройках проекта. Пользователи не смогут получать оповещения о завершенных запусках, а также не смогут отправлять приглашения",
"Plugins.disabled.other": "не будет показан в настройках проекта",
"PluginsFilter.all": "Все",
Expand Down
4 changes: 3 additions & 1 deletion app/localization/translated/uk.json
Original file line number Diff line number Diff line change
Expand Up @@ -938,9 +938,9 @@
"IgnoreInAAModal.textMultiple": "Ви впевнені, що хочете ігнорувати елементи в Авто-Аналіз?",
"IgnoreInAAModal.title": "Ігнорувати елемент Авто-при Аналізі",
"IgnoreInAAModal.titleMultiple": "Ігнорувати елементи Авто-при Аналізі",
"ImportLaunchModal.note": "Увага:",
"ImportModal.importConfirmation": "Підтвердити скасування",
"ImportModal.incorrectFileFormat": "Неправильний формат файла",
"ImportModal.note": "Увага:",
"IncludeInAAModal.includeButton": "Включити",
"IncludeInAAModal.successMessage": "Елемент успішно додано в Авто-Аналіз",
"IncludeInAAModal.successMessageMultiple": "Елементи успішно додано в Авто-Аналіз",
Expand Down Expand Up @@ -1572,6 +1572,7 @@
"PhotoControls.uploadError": "Фото Не вдалося оновити",
"PhotoControls.uploadPhoto": "Фото Завантажити",
"PhotoControls.wasDeleted": "Фото успішно видалено",
"PluginDropDown.ReportType": "Тип звіту:",
"PluginItem.disablePluginMessage": "Ви впевнені, що хочете вимкнути плагін {pluginName}? Якщо ви вимкнете плагін, інформація про нього буде прихована в {pluginLocation}, і користувачі не можуть взаємодіяти з ним",
"PluginItem.disablePluginTitle": "Вимкнути плагін",
"PluginItem.disabledPluginMessage": "Плагін був відключений",
Expand All @@ -1580,6 +1581,7 @@
"PluginItem.enabledPluginMessage": "Плагін був включений",
"PluginItem.titleVersion": "версія {version}",
"Plugins.disabled.bts": "не буде показаний в настроюваннях проекту. Користувачі не зможуть створити дефект або проблему прикріпити до існуючого дефекту в СОД",
"Plugins.disabled.import": "Жоден плагін {name} наразі не ввімкнено/завантажено в екземпляр. <a>Документація</a>",
"Plugins.disabled.notification": "не буде показаний в настроюваннях проекту. Користувачі не зможуть отримувати оповіщення про завершених запусках, а також не зможуть відсилати запрошення",
"Plugins.disabled.other": "не буде показаний в настроюваннях проекту",
"PluginsFilter.all": "Всі",
Expand Down
4 changes: 3 additions & 1 deletion app/localization/translated/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -938,9 +938,9 @@
"IgnoreInAAModal.textMultiple": "您确定要在自动分析中忽略这些测试项吗?",
"IgnoreInAAModal.title": "在自动分析中忽略测试项",
"IgnoreInAAModal.titleMultiple": "在自动分析中忽略测试项",
"ImportLaunchModal.note": "注:",
"ImportModal.importConfirmation": "确认取消",
"ImportModal.incorrectFileFormat": "文件格式不正确",
"ImportModal.note": "注:",
"IncludeInAAModal.includeButton": "包含",
"IncludeInAAModal.successMessage": "测试项已成功包含在自动分析中",
"IncludeInAAModal.successMessageMultiple": "测试项已成功包含在自动分析中",
Expand Down Expand Up @@ -1572,6 +1572,7 @@
"PhotoControls.uploadError": "照片未成功上传",
"PhotoControls.uploadPhoto": "上传照片",
"PhotoControls.wasDeleted": "照片已删除",
"PluginDropDown.ReportType": "Report type:",
"PluginItem.disablePluginMessage": "您确定要禁用插件{pluginName}吗?如果您禁用该插件,有关它的信息将在{pluginLocation}上被隐藏,用户将无法与之交互",
"PluginItem.disablePluginTitle": "禁用插件",
"PluginItem.disabledPluginMessage": "插件已禁用",
Expand All @@ -1580,6 +1581,7 @@
"PluginItem.enabledPluginMessage": "插件已启用",
"PluginItem.titleVersion": "{version}",
"Plugins.disabled.bts": "{name}将在项目设置中隐藏。用户将无法在BTS中发布或关联问题",
"Plugins.disabled.import": "No {name} plugin is currently enabled/uploaded on the instance. <a>Documentation</a>",
"Plugins.disabled.notification": "{name}将在项目设置中隐藏。用户将无法收到通知并为新用户发送邀请",
"Plugins.disabled.other": "{name}将在项目设置中隐藏",
"PluginsFilter.all": "全部",
Expand Down
1 change: 1 addition & 0 deletions app/src/common/constants/pluginsGroupTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ export const NOTIFICATION_GROUP_TYPE = 'NOTIFICATION';
export const AUTHORIZATION_GROUP_TYPE = 'AUTH';
export const BTS_GROUP_TYPE = 'BTS';
export const ANALYZER_GROUP_TYPE = 'ANALYZER';
export const IMPORT_GROUP_TYPE = 'IMPORT';
export const OTHER_GROUP_TYPE = 'OTHER';
9 changes: 8 additions & 1 deletion app/src/components/integrations/messages.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
ANALYZER_GROUP_TYPE,
AUTHORIZATION_GROUP_TYPE,
BTS_GROUP_TYPE,
IMPORT_GROUP_TYPE,
NOTIFICATION_GROUP_TYPE,
OTHER_GROUP_TYPE,
} from 'common/constants/pluginsGroupTypes';
Expand Down Expand Up @@ -80,6 +81,11 @@ const messages = defineMessages({
defaultMessage:
'{name} will be hidden on project settings. RP users can not get notifications and send invitations for new users',
},
pluginDisabledImport: {
id: 'Plugins.disabled.import',
defaultMessage:
'No {name} plugin is currently enabled/uploaded on the instance. <a>Documentation</a>',
},
pluginDisabledOther: {
id: 'Plugins.disabled.other',
defaultMessage: '{name} will be hidden on project settings',
Expand All @@ -89,7 +95,8 @@ const messages = defineMessages({
export const PLUGIN_DISABLED_MESSAGES_BY_GROUP_TYPE = {
[BTS_GROUP_TYPE]: messages.pluginDisabledBts,
[NOTIFICATION_GROUP_TYPE]: messages.pluginDisabledNotification,
[OTHER_GROUP_TYPE]: messages.pluginDisabledOther,
[IMPORT_GROUP_TYPE]: messages.pluginDisabledImport,
[AUTHORIZATION_GROUP_TYPE]: messages.pluginDisabledOther,
[ANALYZER_GROUP_TYPE]: messages.pluginDisabledOther,
[OTHER_GROUP_TYPE]: messages.pluginDisabledOther,
};
1 change: 1 addition & 0 deletions app/src/controllers/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export {
isEmailIntegrationAvailableSelector,
isBtsPluginsExistSelector,
enabledBtsPluginsSelector,
enabledImportPluginsSelector,
globalIntegrationsSelector,
pluginsLoadingSelector,
} from './selectors';
Expand Down
10 changes: 9 additions & 1 deletion app/src/controllers/plugins/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
*/

import { createSelector } from 'reselect';
import { BTS_GROUP_TYPE, NOTIFICATION_GROUP_TYPE } from 'common/constants/pluginsGroupTypes';
import {
BTS_GROUP_TYPE,
IMPORT_GROUP_TYPE,
NOTIFICATION_GROUP_TYPE,
} from 'common/constants/pluginsGroupTypes';
import { EMAIL } from 'common/constants/pluginNames';
import {
filterAvailablePlugins,
Expand Down Expand Up @@ -72,6 +76,10 @@ export const enabledBtsPluginsSelector = createSelector(pluginsSelector, (plugin
plugins.filter((item) => item.groupType === BTS_GROUP_TYPE && item.enabled),
);

export const enabledImportPluginsSelector = createSelector(pluginsSelector, (plugins) =>
plugins.filter((plugin) => plugin.groupType === IMPORT_GROUP_TYPE && plugin.enabled),
);

export const createNamedIntegrationsSelector = (integrationName, integrationsSelector) =>
createSelector(integrationsSelector, (integrations) =>
filterIntegrationsByName(integrations, integrationName),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { GhostButton } from 'components/buttons/ghostButton';
import { PLUGINS_PAGE_EVENTS } from 'components/main/analytics/events';
import ImportIcon from 'common/img/import-inline.svg';
import { URLS } from 'common/urls';
import { MODAL_TYPE_UPLOAD_PLUGIN } from 'pages/common/modals/importModal/constants';
import DOMPurify from 'dompurify';
import styles from './actionPanel.scss';

export const UPLOAD = 'upload';
Expand Down Expand Up @@ -90,13 +90,15 @@ export class ActionPanel extends Component {
tracking.trackEvent(PLUGINS_PAGE_EVENTS.CLICK_UPLOAD_BTN);

this.props.showModalAction({
id: 'importModal',
id: 'importPluginModal',
data: {
type: MODAL_TYPE_UPLOAD_PLUGIN,
onImport: this.props.fetchPluginsAction,
title: formatMessage(messages.modalTitle),
importButton: formatMessage(messages.uploadButton),
tip: formatMessage(messages.uploadTip),
tip: formatMessage(messages.uploadTip, {
b: (data) => DOMPurify.sanitize(`<b>${data}</b>`),
span: (data) => DOMPurify.sanitize(`<span>${data}</span>`),
}),
incorrectFileSize: formatMessage(messages.incorrectFileSize),
url: URLS.plugin(),
singleImport: true,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
* Copyright 2024 EPAM Systems
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import React from 'react';
import { useIntl } from 'react-intl';
import Parser from 'html-react-parser';
import classNames from 'classnames/bind';
import Dropzone from 'react-dropzone';
import PropTypes from 'prop-types';
import { ImportFileIcon } from 'pages/common/modals/importModal/importFileIcon';
import { uniqueId } from 'common/utils';
import DropZoneIcon from 'common/img/shape-inline.svg';
import styles from './dropzoneField.scss';

const cx = classNames.bind(styles);

export const DropzoneField = ({
disabled,
incorrectFileSize,
tip,
singleImport,
incorrectFileFormatMessage,
files,
setFiles,
maxFileSize,
acceptFileMimeTypes,
}) => {
const { formatMessage } = useIntl();

const acceptFile = acceptFileMimeTypes.join(',');

const onDropAcceptedFileHandler = (file) => ({
file,
valid: true,
id: uniqueId(),
isLoading: false,
uploaded: false,
uploadingProgress: 0,
});

const formValidationMessage = (validationProperties) => {
const validationMessages = {
incorrectFileFormat: formatMessage(incorrectFileFormatMessage),
incorrectFileSize,
};
const validationMessage = [];

Object.keys(validationProperties).forEach((message) => {
if (validationProperties[message]) {
validationMessage.push(validationMessages[message]);
}
});

return validationMessage.join('. ').trim();
};

const validateFile = (file) => ({
incorrectFileFormat: !acceptFileMimeTypes.includes(file.type),
incorrectFileSize: file.size > maxFileSize,
});

const addFileRejectMessage = (file) => {
const validationProperties = validateFile(file);

return formValidationMessage(validationProperties);
};

const onDropRejectedFileHandler = (file) => ({
file,
valid: false,
id: uniqueId(),
rejectMessage: addFileRejectMessage(file),
});

const onDrop = (acceptedFiles, rejectedFiles) => {
const accepted = acceptedFiles.map(onDropAcceptedFileHandler);
const rejected = rejectedFiles.map(onDropRejectedFileHandler);

setFiles([...files, ...accepted, ...rejected]);
};

const onDelete = (id) => {
setFiles(files.filter((item) => item.id !== id));
};

return (
<Dropzone
className={cx('dropzone-wrapper')}
activeClassName={cx('dropzone-wrapper-active')}
accept={acceptFile}
onDrop={onDrop}
multiple={!singleImport}
maxSize={maxFileSize}
disabled={disabled}
>
{files.length === 0 && (
<div className={cx('dropzone')}>
<div className={cx('icon')}>{Parser(DropZoneIcon)}</div>
<p className={cx('message')}>{Parser(tip)}</p>
</div>
)}
{files.length > 0 && (
<div className={cx('files-list')}>
{files.map((item) => (
<ImportFileIcon {...item} onDelete={onDelete} key={item.id} />
))}
</div>
)}
</Dropzone>
);
};
DropzoneField.propTypes = {
disabled: PropTypes.bool,
incorrectFileSize: PropTypes.string,
tip: PropTypes.string,
singleImport: PropTypes.bool,
incorrectFileFormatMessage: PropTypes.object,
files: PropTypes.array,
setFiles: PropTypes.func,
maxFileSize: PropTypes.number.isRequired,
acceptFileMimeTypes: PropTypes.arrayOf(PropTypes.string).isRequired,
};
DropzoneField.defaultProps = {
disabled: false,
incorrectFileSize: '',
tip: '',
singleImport: true,
incorrectFileFormatMessage: {},
files: [],
setFiles: () => {},
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*!
* Copyright 2019 EPAM Systems
/*
* Copyright 2024 EPAM Systems
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -60,16 +60,3 @@
flex-wrap: wrap;
padding: 20px;
}

.note-label {
margin-top: 20px;
color: $COLOR--tealish;
font-size: 13px;
font-family: $FONT-SEMIBOLD, sans-serif;
}

.note-message {
font-family: $FONT-REGULAR, sans-serif;
font-size: 12px;
line-height: 1.5;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 EPAM Systems
* Copyright 2024 EPAM Systems
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,4 +14,4 @@
* limitations under the License.
*/

export { ImportModal } from './importModal';
export DropzoneField from './dropzoneField';
Loading

0 comments on commit 9691446

Please sign in to comment.