diff --git a/app/localization/translated/be.json b/app/localization/translated/be.json
index 2c02b42be6..7522258c86 100644
--- a/app/localization/translated/be.json
+++ b/app/localization/translated/be.json
@@ -1553,6 +1553,17 @@
"OrganizationsControl.allOrganizations": "Усе арганізацыі",
"OrganizationsControl.organization": "Арганізацыя",
"OrganizationsItem.open": "адкрыць",
+ "OrganizationsPage.title": "Усе арганізацыі",
+ "OrganizationsPage.description": "Спіс даступных вам арганізацый у дадзены момант пусты. Калі ласка, звяжыцеся са сваім адміністратарам, каб атрымаць прызначэнне ва ўжо існуючую арганізацыю.",
+ "OrganizationsPage.createOrganization": "Стварыць арганізацыю",
+ "OrganizationsPage.createNewOrganization": "Стварыце новую арганізацыю, каб пачаць свой шлях на партале справаздач",
+ "OrganizationsPage.noOrganizationsYet": "Пакуль няма арганізацый",
+ "OrganizationsPage.noOrganizationsAvailableYet": "Пакуль няма даступных арганізацый",
+ "OrganizationsPage.synchedOrganization": "Сінхранізаваная арганізацыя",
+ "OrganizationsPage.lastLaunch": "Апошні запуск быў ажыццёўлены больш 3 месяцаў таму",
+ "OrganizationsPage.organizationUsers": "Карыстальнікі арганізацыі",
+ "OrganizationsPage.organizationProjects": "Арганізацыйныя праекты",
+ "OrganizationsPage.latestLaunch": "Апошняе выкананне запуску",
"OrganizationsPopover.allOrganizations": "Усе арганізацыі",
"OrganizationsControl.assignmentsList": "Прызначаны спіс",
"OverallStatisticsControls.ContentFieldsValidationError": "Абярыце па меншай меры адзін элемент",
diff --git a/app/localization/translated/es.json b/app/localization/translated/es.json
index 5bae1f2199..7b4cfb5216 100644
--- a/app/localization/translated/es.json
+++ b/app/localization/translated/es.json
@@ -1544,6 +1544,17 @@
"OrganizationsControl.allOrganizations": "All organizations",
"OrganizationsControl.organization": "Organization",
"OrganizationsItem.open": "open",
+ "OrganizationsPage.title": "All Organizations",
+ "OrganizationsPage.description": "The list of organizations available to you is currently empty. Please contact your Administrator to be assigned to an existing one.",
+ "OrganizationsPage.createOrganization": "Create Organization",
+ "OrganizationsPage.createNewOrganization": "Create a new organization to begin your ReportPortal journey",
+ "OrganizationsPage.noOrganizationsYet": "No organizations yet",
+ "OrganizationsPage.noOrganizationsAvailableYet": "No organizations available yet",
+ "OrganizationsPage.synchedOrganization": "Synched organization",
+ "OrganizationsPage.lastLaunch": "The last launch was executed more than 3 months ago",
+ "OrganizationsPage.organizationUsers": "Organization users",
+ "OrganizationsPage.organizationProjects": "Organization projects",
+ "OrganizationsPage.latestLaunch": "The latest launch execution",
"OrganizationsPopover.allOrganizations": "All organizatoins",
"OrganizationsControl.assignmentsList": "Assignments list",
"OverallStatisticsControls.ContentFieldsValidationError": "Seleccione al menos un elemento",
diff --git a/app/localization/translated/ru.json b/app/localization/translated/ru.json
index 14d88011bb..e7d3459876 100644
--- a/app/localization/translated/ru.json
+++ b/app/localization/translated/ru.json
@@ -1553,6 +1553,17 @@
"OrganizationsControl.allOrganizations": "Все организации",
"OrganizationsControl.organization": "Организация",
"OrganizationsItem.open": "открыть",
+ "OrganizationsPage.title": "Все организации",
+ "OrganizationsPage.description": "Список доступных вам организаций в данный момент пуст. Пожалуйста, свяжитесь со своим администратором, чтобы получить назначение в уже существующую организацию.",
+ "OrganizationsPage.createOrganization": "Создать организацию",
+ "OrganizationsPage.createNewOrganization": "Создайте новую организацию, чтобы начать свой путь на портале отчетов",
+ "OrganizationsPage.noOrganizationsYet": "Пока нет организаций",
+ "OrganizationsPage.noOrganizationsAvailableYet": "Пока нет доступных организаций",
+ "OrganizationsPage.synchedOrganization": "Синхронизированная организация",
+ "OrganizationsPage.lastLaunch": "Последний запуск был осуществлен более 3 месяцев назад",
+ "OrganizationsPage.organizationUsers": "Пользователи организации",
+ "OrganizationsPage.organizationProjects": "Организационные проекты",
+ "OrganizationsPage.latestLaunch": "Последнее выполнение запуска",
"OrganizationsPopover.allOrganizations": "Все организации",
"OrganizationsControl.assignmentsList": "Назначенный список",
"OverallStatisticsControls.ContentFieldsValidationError": "Выберите не меньше одного элемента",
diff --git a/app/localization/translated/uk.json b/app/localization/translated/uk.json
index 85f9be9e75..91b20b2c30 100644
--- a/app/localization/translated/uk.json
+++ b/app/localization/translated/uk.json
@@ -1553,6 +1553,17 @@
"OrganizationsControl.allOrganizations": "Всі організації",
"OrganizationsControl.organization": "Організація",
"OrganizationsItem.open": "відкрити",
+ "OrganizationsPage.title": "Всі організації",
+ "OrganizationsPage.description": "Список доступних вам організацій в даний момент порожній. Будь ласка, зв'яжіться зі своїм адміністратором, щоб отримати призначення в уже існуючу організацію.",
+ "OrganizationsPage.createOrganization": "Створити організацію",
+ "OrganizationsPage.createNewOrganization": "Створіть нову організацію, щоб розпочати свій шлях на порталі звітів",
+ "OrganizationsPage.noOrganizationsYet": "Поки немає організацій",
+ "OrganizationsPage.noOrganizationsAvailableYet": "Поки що немає доступних організацій",
+ "OrganizationsPage.synchedOrganization": "Синхронізована організація",
+ "OrganizationsPage.lastLaunch": "Останній запуск був здійснений більше 3 місяців тому",
+ "OrganizationsPage.organizationUsers": "Користувачі організації",
+ "OrganizationsPage.organizationProjects": "Організаційні проекти",
+ "OrganizationsPage.latestLaunch": "Останнє виконання запуску",
"OrganizationsPopover.allOrganizations": "Всі організації",
"OrganizationsControl.assignmentsList": "Призначений список",
"OverallStatisticsControls.ContentFieldsValidationError": "Виберіть не менше одного елемента",
diff --git a/app/localization/translated/zh.json b/app/localization/translated/zh.json
index 03ac388c6b..d9d06d2171 100644
--- a/app/localization/translated/zh.json
+++ b/app/localization/translated/zh.json
@@ -1553,6 +1553,17 @@
"OrganizationsControl.allOrganizations": "All organizations",
"OrganizationsControl.organization": "组织",
"OrganizationsItem.open": "open",
+ "OrganizationsPage.title": "All Organizations",
+ "OrganizationsPage.description": "The list of organizations available to you is currently empty. Please contact your Administrator to be assigned to an existing one.",
+ "OrganizationsPage.createOrganization": "Create Organization",
+ "OrganizationsPage.createNewOrganization": "Create a new organization to begin your ReportPortal journey",
+ "OrganizationsPage.noOrganizationsYet": "No organizations yet",
+ "OrganizationsPage.noOrganizationsAvailableYet": "No organizations available yet",
+ "OrganizationsPage.synchedOrganization": "Synched organization",
+ "OrganizationsPage.lastLaunch": "The last launch was executed more than 3 months ago",
+ "OrganizationsPage.organizationUsers": "Organization users",
+ "OrganizationsPage.organizationProjects": "Organization projects",
+ "OrganizationsPage.latestLaunch": "The latest launch execution",
"OrganizationsPopover.allOrganizations": "All organizations",
"OrganizationsControl.assignmentsList": "Assignments list",
"OverallStatisticsControls.ContentFieldsValidationError": "您必须选中至少一个测试项",
diff --git a/app/package-lock.json b/app/package-lock.json
index 1f6708ae6c..92c6e53539 100644
--- a/app/package-lock.json
+++ b/app/package-lock.json
@@ -12,7 +12,7 @@
"@formatjs/intl-pluralrules": "1.3.9",
"@formatjs/intl-relativetimeformat": "4.5.1",
"@formatjs/intl-utils": "1.6.0",
- "@reportportal/ui-kit": "^0.0.1-alpha.28",
+ "@reportportal/ui-kit": "^0.0.1-alpha.29",
"axios": "1.6.4",
"c3": "0.7.20",
"chart.js": "2.9.4",
@@ -24,7 +24,7 @@
"d3": "7.8.5",
"d3-selection": "1.4.0",
"date-fns": "2.29.3",
- "dompurify": "^2.5.4",
+ "dompurify": "2.5.4",
"dotenv": "5.0.1",
"downshift": "6.1.7",
"fast-deep-equal": "3.1.3",
@@ -78,7 +78,7 @@
"reset-css": "2.2.1",
"semver-diff": "3.1.1",
"simplemde": "1.11.2",
- "swagger-ui-react": "^5.17.12",
+ "swagger-ui-react": "5.17.12",
"video.js": "7.17.0"
},
"devDependencies": {
@@ -3465,9 +3465,9 @@
"integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA=="
},
"node_modules/@reportportal/ui-kit": {
- "version": "0.0.1-alpha.28",
- "resolved": "https://registry.npmjs.org/@reportportal/ui-kit/-/ui-kit-0.0.1-alpha.28.tgz",
- "integrity": "sha512-NWt0kJt87waqZwfKKKaenxbUlOipFFbal+aj2mAe2u3tHytvy3dlcU/vcnvcWL4OH3LwybnjF9vxuMYhpOWF5A==",
+ "version": "0.0.1-alpha.29",
+ "resolved": "https://registry.npmjs.org/@reportportal/ui-kit/-/ui-kit-0.0.1-alpha.29.tgz",
+ "integrity": "sha512-fAy8zZd7Hsrdh5AS+ptAdjxXV/Qj4OyHUKWL1Veo0UwYsz3LkSP1Vb+qXmDksPW/FEPrHrvYwc1UjnxSRU+uAg==",
"dependencies": {
"@floating-ui/react": "^0.26.16",
"@floating-ui/react-dom": "^2.0.1",
@@ -4418,7 +4418,7 @@
"version": "22.0.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.0.tgz",
"integrity": "sha512-VT7KSYudcPOzP5Q0wfbowyNLaVR8QWUdw+088uFWwfvpY6uCWaXpqV6ieLAu9WBcnTa7H4Z5RLK8I5t2FuOcqw==",
- "devOptional": true,
+ "dev": true,
"dependencies": {
"undici-types": "~6.11.1"
}
@@ -26385,7 +26385,7 @@
"version": "6.11.1",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz",
"integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ==",
- "devOptional": true
+ "dev": true
},
"node_modules/unicode-canonical-property-names-ecmascript": {
"version": "2.0.0",
diff --git a/app/package.json b/app/package.json
index 471c9c3ad2..0634581202 100644
--- a/app/package.json
+++ b/app/package.json
@@ -25,7 +25,7 @@
"@formatjs/intl-pluralrules": "1.3.9",
"@formatjs/intl-relativetimeformat": "4.5.1",
"@formatjs/intl-utils": "1.6.0",
- "@reportportal/ui-kit": "^0.0.1-alpha.28",
+ "@reportportal/ui-kit": "^0.0.1-alpha.29",
"axios": "1.6.4",
"c3": "0.7.20",
"chart.js": "2.9.4",
diff --git a/app/src/pages/instance/projectsPage/projectsGrid/index.js b/app/src/common/constants/organizationTypes.js
similarity index 86%
rename from app/src/pages/instance/projectsPage/projectsGrid/index.js
rename to app/src/common/constants/organizationTypes.js
index 8d0e58776f..09a2cc0e27 100644
--- a/app/src/pages/instance/projectsPage/projectsGrid/index.js
+++ b/app/src/common/constants/organizationTypes.js
@@ -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.
@@ -14,4 +14,4 @@
* limitations under the License.
*/
-export { ProjectsGrid } from './projectsGrid';
+export const ORGANIZATION_EXTERNAL_TYPE = 'EXTERNAL';
diff --git a/app/src/common/utils/permissions/index.js b/app/src/common/utils/permissions/index.js
index 6feda1c009..fde6863d48 100644
--- a/app/src/common/utils/permissions/index.js
+++ b/app/src/common/utils/permissions/index.js
@@ -41,5 +41,6 @@ export {
canWorkWithTests,
canSeeEmailMembers,
canSeeSidebarOptions,
+ canCreateOrganization,
} from './permissions';
export { getRoleTitle } from './getRoleTitle';
diff --git a/app/src/controllers/appInfo/selectors.js b/app/src/controllers/appInfo/selectors.js
index 71496cd3ff..919745c2b5 100644
--- a/app/src/controllers/appInfo/selectors.js
+++ b/app/src/controllers/appInfo/selectors.js
@@ -22,7 +22,7 @@ import {
patternAnalysisEnabledSelector,
projectInfoIdSelector,
} from 'controllers/project/selectors';
-import { activeOrganizationIdSelector } from 'controllers/organizations/organization/selectors';
+import { activeOrganizationIdSelector } from 'controllers/organization/selectors';
import {
ANALYTICS_INSTANCE_KEY,
ANALYTICS_ALL_KEY,
diff --git a/app/src/controllers/instance/events/reducer.js b/app/src/controllers/instance/events/reducer.js
index f8ca68958b..28bb556fa9 100644
--- a/app/src/controllers/instance/events/reducer.js
+++ b/app/src/controllers/instance/events/reducer.js
@@ -15,17 +15,13 @@
*/
import { combineReducers } from 'redux';
-import { createPageScopedReducer } from 'common/utils/createPageScopedReducer';
import { fetchReducer } from 'controllers/fetch';
import { loadingReducer } from 'controllers/loading';
-import { PROJECT_DETAILS_PAGE } from 'controllers/pages';
import { alternativePaginationReducer } from 'controllers/pagination';
import { initialPaginationState, NAMESPACE } from './constants';
-const reducer = combineReducers({
+export const eventsReducer = combineReducers({
events: fetchReducer(NAMESPACE, { contentPath: 'items' }),
pagination: alternativePaginationReducer(NAMESPACE, initialPaginationState),
loading: loadingReducer(NAMESPACE),
});
-
-export const eventsReducer = createPageScopedReducer(reducer, PROJECT_DETAILS_PAGE);
diff --git a/app/src/controllers/organizations/actionCreators.js b/app/src/controllers/instance/organizations/actionCreators.js
similarity index 100%
rename from app/src/controllers/organizations/actionCreators.js
rename to app/src/controllers/instance/organizations/actionCreators.js
diff --git a/app/src/pages/instance/projectsPage/index.js b/app/src/controllers/instance/organizations/constants.js
similarity index 65%
rename from app/src/pages/instance/projectsPage/index.js
rename to app/src/controllers/instance/organizations/constants.js
index 1017bea8ee..ee0ccc1ba2 100644
--- a/app/src/pages/instance/projectsPage/index.js
+++ b/app/src/controllers/instance/organizations/constants.js
@@ -14,5 +14,13 @@
* limitations under the License.
*/
-export { AddProjectModal } from 'pages/organization/organizationProjectsPage/modals/addProjectModal';
-export { ProjectsPage } from './projectsPage';
+export const NAMESPACE = 'organizations';
+
+export const FETCH_ORGANIZATIONS = 'fetchOrganizations';
+export const DEFAULT_PAGE_SIZE_OPTIONS = [10, 20, 50, 100];
+export const DEFAULT_LIMITATION = 20;
+export const initialPaginationState = {
+ size: DEFAULT_LIMITATION,
+ totalElements: 0,
+ totalPages: 0,
+};
diff --git a/app/src/controllers/organizations/index.js b/app/src/controllers/instance/organizations/index.js
similarity index 85%
rename from app/src/controllers/organizations/index.js
rename to app/src/controllers/instance/organizations/index.js
index 30db3f8dda..c28ec3d2ef 100644
--- a/app/src/controllers/organizations/index.js
+++ b/app/src/controllers/instance/organizations/index.js
@@ -17,5 +17,9 @@
export { FETCH_ORGANIZATIONS } from './constants';
export { fetchOrganizationsAction } from './actionCreators';
export { organizationsReducer } from './reducer';
-export { organizationsListSelector, organizationsListLoadingSelector } from './selectors';
+export {
+ organizationsListSelector,
+ organizationsListLoadingSelector,
+ organizationsListPaginationSelector,
+} from './selectors';
export { organizationsSagas } from './sagas';
diff --git a/app/src/controllers/organizations/reducer.js b/app/src/controllers/instance/organizations/reducer.js
similarity index 76%
rename from app/src/controllers/organizations/reducer.js
rename to app/src/controllers/instance/organizations/reducer.js
index 71c8f9be46..d04e3e9eaf 100644
--- a/app/src/controllers/organizations/reducer.js
+++ b/app/src/controllers/instance/organizations/reducer.js
@@ -17,11 +17,13 @@
import { combineReducers } from 'redux';
import { fetchReducer } from 'controllers/fetch';
import { loadingReducer } from 'controllers/loading';
-import { organizationReducer } from 'controllers/organizations/organization/reducer';
-import { NAMESPACE } from './constants';
+import { alternativePaginationReducer } from 'controllers/pagination';
+import { organizationReducer } from 'controllers/organization/reducer';
+import { initialPaginationState, NAMESPACE } from './constants';
export const organizationsReducer = combineReducers({
list: fetchReducer(NAMESPACE, { contentPath: 'items' }),
listLoading: loadingReducer(NAMESPACE),
+ pagination: alternativePaginationReducer(NAMESPACE, initialPaginationState),
organization: organizationReducer,
});
diff --git a/app/src/controllers/organizations/sagas.js b/app/src/controllers/instance/organizations/sagas.js
similarity index 90%
rename from app/src/controllers/organizations/sagas.js
rename to app/src/controllers/instance/organizations/sagas.js
index 12cc042350..c179fb1676 100644
--- a/app/src/controllers/organizations/sagas.js
+++ b/app/src/controllers/instance/organizations/sagas.js
@@ -18,9 +18,9 @@ import { takeEvery, all, put } from 'redux-saga/effects';
import { URLS } from 'common/urls';
import { showDefaultErrorNotification } from 'controllers/notification';
import { fetchDataAction } from 'controllers/fetch';
-import { organizationSagas } from 'controllers/organizations/organization/sagas';
+import { organizationSagas } from 'controllers/organization';
+import { projectsSagas } from 'controllers/organization/projects';
import { FETCH_ORGANIZATIONS, NAMESPACE } from './constants';
-import { projectsSagas } from './projects';
function* fetchOrganizations() {
try {
diff --git a/app/src/controllers/organizations/selectors.js b/app/src/controllers/instance/organizations/selectors.js
similarity index 89%
rename from app/src/controllers/organizations/selectors.js
rename to app/src/controllers/instance/organizations/selectors.js
index 5ea88f415d..b3a76a75a5 100644
--- a/app/src/controllers/organizations/selectors.js
+++ b/app/src/controllers/instance/organizations/selectors.js
@@ -19,3 +19,6 @@ export const organizationsSelector = (state) => state.organizations || {};
export const organizationsListSelector = (state) => organizationsSelector(state).list || [];
export const organizationsListLoadingSelector = (state) => organizationsSelector(state).listLoading;
+
+export const organizationsListPaginationSelector = (state) =>
+ organizationsSelector(state).pagination;
diff --git a/app/src/controllers/instance/projects/actionCreators.js b/app/src/controllers/instance/projects/actionCreators.js
deleted file mode 100644
index 26ad63b675..0000000000
--- a/app/src/controllers/instance/projects/actionCreators.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2019 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 {
- toggleItemSelectionAction,
- toggleAllItemsAction,
- defineGroupOperation,
- unselectAllItemsAction,
-} from 'controllers/groupOperations';
-import { showModalAction } from 'controllers/modal';
-import { PROJECT_DETAILS_PAGE, PROJECT_SETTINGS_PAGE } from 'controllers/pages';
-import {
- FETCH_PROJECTS,
- START_SET_VIEW_MODE,
- NAMESPACE,
- DELETE_PROJECT,
- NAVIGATE_TO_PROJECT,
- CONFIRM_ASSIGN_TO_PROJECT,
- ADD_PROJECT,
-} from './constants';
-
-export const fetchProjectsAction = (params) => ({
- type: FETCH_PROJECTS,
- payload: params,
-});
-
-export const startSetViewMode = (viewMode) => ({
- type: START_SET_VIEW_MODE,
- payload: { viewMode },
-});
-
-export const toggleProjectSelectionAction = toggleItemSelectionAction(NAMESPACE);
-export const toggleAllProjectsAction = toggleAllItemsAction(NAMESPACE);
-export const unselectAllProjectsAction = unselectAllItemsAction(NAMESPACE);
-
-export const deleteItemsAction = defineGroupOperation(
- NAMESPACE,
- 'deleteProjects',
- (items, { onConfirm, header, mainContent, userId, warning, eventsInfo }) =>
- showModalAction({
- id: 'deleteItemsModal',
- data: { items, onConfirm, header, mainContent, userId, warning, eventsInfo },
- }),
- () => {},
-);
-
-export const addProjectAction = (projectKey) => ({
- type: ADD_PROJECT,
- payload: projectKey,
-});
-
-export const deleteProjectAction = (project) => ({
- type: DELETE_PROJECT,
- payload: project,
-});
-
-export const navigateToProjectAction = (project) => ({
- type: NAVIGATE_TO_PROJECT,
- payload: project,
-});
-
-export const confirmAssignToProject = (project) => ({
- type: CONFIRM_ASSIGN_TO_PROJECT,
- payload: project,
-});
-
-export const navigateToProjectSectionAction = ({ organizationSlug, projectSlug }, section) => ({
- type: PROJECT_DETAILS_PAGE,
- payload: {
- projectSlug,
- projectSection: section,
- organizationSlug,
- },
-});
-
-export const navigateToProjectSettingsAction = ({ organizationSlug, projectSlug }) => ({
- type: PROJECT_SETTINGS_PAGE,
- payload: {
- projectSlug,
- organizationSlug,
- },
-});
diff --git a/app/src/controllers/instance/projects/constants.js b/app/src/controllers/instance/projects/constants.js
deleted file mode 100644
index 3c06d38596..0000000000
--- a/app/src/controllers/instance/projects/constants.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2019 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 { PAGE_KEY, SIZE_KEY } from 'controllers/pagination';
-import { formatSortingString, SORTING_ASC } from 'controllers/sorting';
-
-export const FETCH_PROJECTS = 'fetchProjects';
-export const NAMESPACE = 'projects';
-export const DEFAULT_PAGE_SIZE = 12;
-export const DEFAULT_PAGINATION = {
- [PAGE_KEY]: 1,
- [SIZE_KEY]: DEFAULT_PAGE_SIZE,
-};
-export const TABLE_VIEW = 'table';
-export const GRID_VIEW = 'grid';
-export const USER_VIEW = 'projects_view_mode';
-export const SET_PROJECTS_VIEW_MODE = 'setProjectsViewMode';
-export const START_SET_VIEW_MODE = 'startSetProjectsViewMode';
-export const ADD_PROJECT = 'addProject';
-export const DELETE_PROJECT = 'deleteProject';
-export const DEFAULT_SORT_COLUMN = 'name';
-export const DEFAULT_SORTING = formatSortingString([DEFAULT_SORT_COLUMN], SORTING_ASC);
-export const NAVIGATE_TO_PROJECT = 'navigateToProject';
-export const CONFIRM_ASSIGN_TO_PROJECT = 'confirmAssignToProject';
-export const ERROR_CODES = {
- PROJECT_EXISTS: 4095,
-};
diff --git a/app/src/controllers/instance/projects/index.js b/app/src/controllers/instance/projects/index.js
deleted file mode 100644
index 91026173d8..0000000000
--- a/app/src/controllers/instance/projects/index.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2019 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.
- */
-
-export {
- fetchProjectsAction,
- startSetViewMode,
- toggleProjectSelectionAction,
- toggleAllProjectsAction,
- unselectAllProjectsAction,
- addProjectAction,
- deleteItemsAction,
- deleteProjectAction,
- navigateToProjectAction,
- navigateToProjectSectionAction,
-} from './actionCreators';
-export { projectsReducer } from './reducer';
-export {
- projectsPaginationSelector,
- projectsSelector,
- loadingSelector,
- viewModeSelector,
- selectedProjectsSelector,
- querySelector,
-} from './selectors';
-export { projectsSagas } from './sagas';
-export {
- DEFAULT_PAGE_SIZE,
- DEFAULT_PAGINATION,
- GRID_VIEW,
- TABLE_VIEW,
- DEFAULT_SORT_COLUMN,
-} from './constants';
diff --git a/app/src/controllers/instance/projects/reducer.js b/app/src/controllers/instance/projects/reducer.js
deleted file mode 100644
index 0bec777db6..0000000000
--- a/app/src/controllers/instance/projects/reducer.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2019 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 { combineReducers } from 'redux';
-import { fetchReducer } from 'controllers/fetch';
-import { paginationReducer } from 'controllers/pagination';
-import { loadingReducer } from 'controllers/loading';
-import { PROJECTS_PAGE } from 'controllers/pages';
-import { groupOperationsReducer } from 'controllers/groupOperations';
-import { ASSIGN_TO_PROJECT_SUCCESS, UNASSIGN_FROM_PROJECT_SUCCESS } from 'controllers/user';
-import { queueReducers } from 'common/utils/queueReducers';
-import { createPageScopedReducer } from 'common/utils/createPageScopedReducer';
-import { NAMESPACE, SET_PROJECTS_VIEW_MODE, GRID_VIEW } from './constants';
-
-export const setViewModeReducer = (state = GRID_VIEW, { type = '', payload = {} }) => {
- switch (type) {
- case SET_PROJECTS_VIEW_MODE:
- return payload;
-
- default:
- return state;
- }
-};
-
-export const projectFetchReducer = fetchReducer(NAMESPACE, {
- contentPath: 'content',
- initialState: [],
-});
-
-export const assignProjectReducer = (state = [], { type = '', payload = {} }) => {
- switch (type) {
- case ASSIGN_TO_PROJECT_SUCCESS:
- return state.map((project) =>
- project.projectKey === payload.projectKey
- ? { ...project, usersQuantity: project.usersQuantity + 1 }
- : project,
- );
- case UNASSIGN_FROM_PROJECT_SUCCESS: {
- const { projectKey } = payload;
- return state.map((project) =>
- project.projectKey === projectKey
- ? { ...project, usersQuantity: project.usersQuantity - 1 }
- : project,
- );
- }
- default:
- return state;
- }
-};
-
-const reducer = combineReducers({
- projects: queueReducers(projectFetchReducer, assignProjectReducer),
- pagination: paginationReducer(NAMESPACE),
- loading: loadingReducer(NAMESPACE),
- viewMode: setViewModeReducer,
- groupOperations: groupOperationsReducer(NAMESPACE),
-});
-
-export const projectsReducer = createPageScopedReducer(reducer, PROJECTS_PAGE);
diff --git a/app/src/controllers/instance/projects/reducer.test.js b/app/src/controllers/instance/projects/reducer.test.js
deleted file mode 100644
index c24be45e84..0000000000
--- a/app/src/controllers/instance/projects/reducer.test.js
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright 2019 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 { ASSIGN_TO_PROJECT_SUCCESS, UNASSIGN_FROM_PROJECT_SUCCESS } from 'controllers/user';
-import { FETCH_SUCCESS } from 'controllers/fetch';
-import { SET_PROJECTS_VIEW_MODE, TABLE_VIEW, GRID_VIEW, NAMESPACE } from './constants';
-import { setViewModeReducer, assignProjectReducer, projectFetchReducer } from './reducer';
-
-const VIEW_MODE_INITIAL_STATE = GRID_VIEW;
-const PROJECTS = [
- {
- id: 1,
- projectName: 'superadmin_personal',
- usersQuantity: 3,
- launchesQuantity: 36,
- launchesPerUser: null,
- uniqueTickets: null,
- launchesPerWeek: null,
- lastRun: 1553585182771,
- creationDate: 1553072627019,
- entryType: 'PERSONAL',
- organization: null,
- },
-];
-const PROJECTS_AFTER_ASSIGN = [
- {
- id: 1,
- projectName: 'superadmin_personal',
- usersQuantity: 4,
- launchesQuantity: 36,
- launchesPerUser: null,
- uniqueTickets: null,
- launchesPerWeek: null,
- lastRun: 1553585182771,
- creationDate: 1553072627019,
- entryType: 'PERSONAL',
- organization: null,
- },
-];
-
-const PROJECTS_AFTER_UNASSIGN = [
- {
- id: 1,
- projectName: 'superadmin_personal',
- usersQuantity: 2,
- launchesQuantity: 36,
- launchesPerUser: null,
- uniqueTickets: null,
- launchesPerWeek: null,
- lastRun: 1553585182771,
- creationDate: 1553072627019,
- entryType: 'PERSONAL',
- organization: null,
- },
-];
-
-describe('projects reducer', () => {
- describe('setViewModeReducer', () => {
- test('should return initial state', () => {
- expect(setViewModeReducer(undefined, {})).toBe(VIEW_MODE_INITIAL_STATE);
- });
-
- test('should return old state on unknown action', () => {
- const oldState = TABLE_VIEW;
- expect(setViewModeReducer(oldState, { type: 'foo' })).toBe(oldState);
- });
-
- test('should handle SET_PROJECTS_VIEW_MODE', () => {
- const payload = TABLE_VIEW;
- const newState = setViewModeReducer(VIEW_MODE_INITIAL_STATE, {
- type: SET_PROJECTS_VIEW_MODE,
- payload,
- });
- expect(newState).toEqual(payload);
- });
- });
-
- describe('projectFetchReducer', () => {
- test('should return initial state', () => {
- expect(projectFetchReducer(undefined, {})).toEqual([]);
- });
-
- test('should return old state on unknown action', () => {
- const oldState = PROJECTS;
- expect(projectFetchReducer(oldState, {})).toBe(oldState);
- });
-
- test('should ignore unsuitable namespaces', () => {
- const payload = PROJECTS;
- const newState = projectFetchReducer(undefined, {
- type: FETCH_SUCCESS,
- payload,
- meta: {
- namespace: 'other',
- },
- });
- expect(newState).toEqual([]);
- });
-
- test('should handle FETCH_SUCCESS', () => {
- const payload = { content: PROJECTS };
- const newState = projectFetchReducer(undefined, {
- type: FETCH_SUCCESS,
- payload,
- meta: {
- namespace: NAMESPACE,
- },
- });
- expect(newState).toEqual(PROJECTS);
- });
- });
-
- describe('assignProjectReducer', () => {
- test('should return initial state', () => {
- expect(assignProjectReducer(undefined, {})).toEqual([]);
- });
-
- test('should return old state on unknown action', () => {
- const oldState = PROJECTS;
- expect(assignProjectReducer(oldState, [{ id: 2 }])).toBe(oldState);
- });
-
- test('should handle ASSIGN_TO_PROJECT_SUCCESS', () => {
- const payload = {
- projectName: PROJECTS[0].projectName,
- };
- const newState = assignProjectReducer(PROJECTS, {
- type: ASSIGN_TO_PROJECT_SUCCESS,
- payload,
- });
- expect(newState).toEqual(PROJECTS_AFTER_ASSIGN);
- });
-
- test('should handle UNASSIGN_FROM_PROJECT_SUCCESS', () => {
- const oldState = PROJECTS;
- const payload = {
- projectName: PROJECTS[0].projectName,
- };
- const newState = assignProjectReducer(oldState, {
- type: UNASSIGN_FROM_PROJECT_SUCCESS,
- payload,
- });
- expect(newState).toEqual(PROJECTS_AFTER_UNASSIGN);
- });
- });
-});
diff --git a/app/src/controllers/instance/projects/sagas.js b/app/src/controllers/instance/projects/sagas.js
deleted file mode 100644
index 27c97ee479..0000000000
--- a/app/src/controllers/instance/projects/sagas.js
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 2019 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 { takeEvery, takeLatest, all, put, select, call } from 'redux-saga/effects';
-import { fetchDataAction } from 'controllers/fetch';
-import { URLS } from 'common/urls';
-import { showNotification, NOTIFICATION_TYPES } from 'controllers/notification';
-import { assignToProjectSuccessAction } from 'controllers/user';
-import { PROJECT_TYPE_INTERNAL } from 'common/constants/projectsObjectTypes';
-import { MEMBERS } from 'common/constants/projectSections';
-import { fetch, getStorageItem, setStorageItem } from 'common/utils';
-import { PROJECT_PAGE, urlOrganizationAndProjectSelector } from 'controllers/pages';
-import { hideModalAction } from 'controllers/modal';
-import { PROJECT_MANAGER } from 'common/constants/projectRoles';
-
-import {
- NAMESPACE,
- FETCH_PROJECTS,
- START_SET_VIEW_MODE,
- USER_VIEW,
- GRID_VIEW,
- SET_PROJECTS_VIEW_MODE,
- ADD_PROJECT,
- DELETE_PROJECT,
- NAVIGATE_TO_PROJECT,
- ERROR_CODES,
-} from './constants';
-import { navigateToProjectSectionAction } from './actionCreators';
-import { querySelector } from './selectors';
-
-function* fetchProjects() {
- const query = yield select(querySelector);
- yield put(
- fetchDataAction(NAMESPACE)(URLS.projects(), {
- params: { ...query },
- }),
- );
-}
-
-function* watchFetchProjects() {
- yield takeEvery(FETCH_PROJECTS, fetchProjects);
-}
-
-function* setViewMode(action) {
- const userView = getStorageItem(USER_VIEW) || GRID_VIEW;
- const viewMode = action.payload.viewMode || userView;
-
- setStorageItem(USER_VIEW, viewMode);
-
- yield put({ type: SET_PROJECTS_VIEW_MODE, payload: viewMode });
-}
-function* watchSetViewMode() {
- yield takeEvery(START_SET_VIEW_MODE, setViewMode);
-}
-
-function* addProject({ payload: projectName }) {
- try {
- yield call(fetch, URLS.project(), {
- method: 'post',
- data: {
- entryType: PROJECT_TYPE_INTERNAL,
- projectName,
- },
- });
- const projectInfo = {
- projectName: projectName.toLowerCase(),
- projectRole: PROJECT_MANAGER,
- entryType: PROJECT_TYPE_INTERNAL,
- };
- const { organizationSlug, projectSlug } = yield select(urlOrganizationAndProjectSelector);
- yield put(assignToProjectSuccessAction(projectInfo));
- yield put(hideModalAction());
- yield put(
- showNotification({
- messageId: 'addProjectSuccess',
- type: NOTIFICATION_TYPES.SUCCESS,
- values: { name: projectName },
- }),
- );
- yield put(navigateToProjectSectionAction({ organizationSlug, projectSlug }, MEMBERS));
- } catch (err) {
- if (err.errorCode === ERROR_CODES.PROJECT_EXISTS) {
- yield put(
- showNotification({
- messageId: 'projectExists',
- type: NOTIFICATION_TYPES.ERROR,
- values: { name: projectName },
- }),
- );
- } else {
- yield put(
- showNotification({
- messageId: 'failureDefault',
- type: NOTIFICATION_TYPES.ERROR,
- values: { error: err.message },
- }),
- );
- }
- }
-}
-
-function* watchAddProject() {
- yield takeEvery(ADD_PROJECT, addProject);
-}
-
-function* deleteProject({ payload: project }) {
- try {
- yield call(fetch, URLS.project([project.id]), {
- method: 'delete',
- });
- } catch (err) {
- const error = err.message;
- yield put(
- showNotification({
- messageId: 'deleteError',
- type: NOTIFICATION_TYPES.ERROR,
- values: { error },
- }),
- );
- }
- yield put({ type: FETCH_PROJECTS });
-}
-
-function* watchDeleteProject() {
- yield takeLatest(DELETE_PROJECT, deleteProject);
-}
-
-function* navigateToProject({ payload }) {
- const { project } = payload;
- const { organizationSlug, projectSlug } = project;
-
- yield put({
- type: PROJECT_PAGE,
- payload: { organizationSlug, projectSlug },
- });
-}
-
-function* watchNavigateToProject() {
- yield takeEvery(NAVIGATE_TO_PROJECT, navigateToProject);
-}
-
-export function* projectsSagas() {
- yield all([
- watchFetchProjects(),
- watchSetViewMode(),
- watchAddProject(),
- watchDeleteProject(),
- watchNavigateToProject(),
- ]);
-}
diff --git a/app/src/controllers/instance/projects/selectors.js b/app/src/controllers/instance/projects/selectors.js
deleted file mode 100644
index 39ba83e962..0000000000
--- a/app/src/controllers/instance/projects/selectors.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2019 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 { createQueryParametersSelector } from 'controllers/pages';
-import { createSelectedItemsSelector } from 'controllers/groupOperations';
-import { DEFAULT_PAGINATION, DEFAULT_SORTING } from './constants';
-import { administrateDomainSelector } from '../selectors';
-
-const domainSelector = (state) => administrateDomainSelector(state).projects || {};
-
-export const projectsPaginationSelector = (state) => domainSelector(state).pagination;
-export const projectsSelector = (state) => domainSelector(state).projects;
-export const loadingSelector = (state) => domainSelector(state).loading || false;
-export const viewModeSelector = (state) => domainSelector(state).viewMode;
-
-const groupOperationsSelector = (state) => domainSelector(state).groupOperations;
-export const selectedProjectsSelector = createSelectedItemsSelector(groupOperationsSelector);
-
-export const querySelector = createQueryParametersSelector({
- defaultPagination: DEFAULT_PAGINATION,
- defaultSorting: DEFAULT_SORTING,
-});
diff --git a/app/src/controllers/instance/reducer.js b/app/src/controllers/instance/reducer.js
index db09167b07..1cc5dac45f 100644
--- a/app/src/controllers/instance/reducer.js
+++ b/app/src/controllers/instance/reducer.js
@@ -17,10 +17,8 @@
import { combineReducers } from 'redux';
import { eventsReducer } from './events';
import { allUsersReducer } from './allUsers';
-import { projectsReducer } from './projects';
export const instanceReducer = combineReducers({
events: eventsReducer,
allUsers: allUsersReducer,
- projects: projectsReducer,
});
diff --git a/app/src/controllers/instance/sagas.js b/app/src/controllers/instance/sagas.js
index e8c1b64c31..e7ec416c19 100644
--- a/app/src/controllers/instance/sagas.js
+++ b/app/src/controllers/instance/sagas.js
@@ -20,7 +20,6 @@ import { projectSectionSelector } from 'controllers/pages';
import { projectKeySelector, fetchProjectAction } from 'controllers/project';
import { fetchMembersAction } from 'controllers/members';
import { FETCH_PROJECT_DATA } from './constants';
-import { projectsSagas } from './projects';
import { allUsersSagas } from './allUsers';
import { eventsSagas, fetchEventsAction } from './events';
@@ -42,5 +41,5 @@ function* watchFetchProjectData() {
}
export function* instanceSagas() {
- yield all([eventsSagas(), watchFetchProjectData(), allUsersSagas(), projectsSagas()]);
+ yield all([eventsSagas(), watchFetchProjectData(), allUsersSagas()]);
}
diff --git a/app/src/controllers/members/reducer.js b/app/src/controllers/members/reducer.js
index d2a7ee0a7e..29f4ea01ce 100644
--- a/app/src/controllers/members/reducer.js
+++ b/app/src/controllers/members/reducer.js
@@ -19,7 +19,7 @@ import { createPageScopedReducer } from 'common/utils/createPageScopedReducer';
import { fetchReducer } from 'controllers/fetch';
import { paginationReducer } from 'controllers/pagination';
import { loadingReducer } from 'controllers/loading';
-import { PROJECT_MEMBERS_PAGE, PROJECT_DETAILS_PAGE } from 'controllers/pages';
+import { PROJECT_MEMBERS_PAGE } from 'controllers/pages';
import { NAMESPACE } from './constants';
const reducer = combineReducers({
@@ -29,7 +29,4 @@ const reducer = combineReducers({
});
// we must clear the members state when the page has changed from PROJECT_DETAILS_PAGE, as it is used there
-export const membersReducer = createPageScopedReducer(reducer, [
- PROJECT_MEMBERS_PAGE,
- PROJECT_DETAILS_PAGE,
-]);
+export const membersReducer = createPageScopedReducer(reducer, [PROJECT_MEMBERS_PAGE]);
diff --git a/app/src/controllers/organizations/organization/actionCreators.js b/app/src/controllers/organization/actionCreators.js
similarity index 100%
rename from app/src/controllers/organizations/organization/actionCreators.js
rename to app/src/controllers/organization/actionCreators.js
diff --git a/app/src/controllers/organizations/organization/constants.js b/app/src/controllers/organization/constants.js
similarity index 100%
rename from app/src/controllers/organizations/organization/constants.js
rename to app/src/controllers/organization/constants.js
diff --git a/app/src/controllers/organizations/organization/index.js b/app/src/controllers/organization/index.js
similarity index 100%
rename from app/src/controllers/organizations/organization/index.js
rename to app/src/controllers/organization/index.js
diff --git a/app/src/controllers/organizations/projects/actionCreators.js b/app/src/controllers/organization/projects/actionCreators.js
similarity index 79%
rename from app/src/controllers/organizations/projects/actionCreators.js
rename to app/src/controllers/organization/projects/actionCreators.js
index 586181e6f6..6da9ce1c6e 100644
--- a/app/src/controllers/organizations/projects/actionCreators.js
+++ b/app/src/controllers/organization/projects/actionCreators.js
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-import { PROJECT_DETAILS_PAGE } from 'controllers/pages';
import { CREATE_PROJECT, FETCH_ORGANIZATION_PROJECTS, NAVIGATE_TO_PROJECT } from './constants';
export const fetchOrganizationProjectsAction = (params) => {
@@ -33,12 +32,3 @@ export const navigateToProjectAction = (project) => ({
type: NAVIGATE_TO_PROJECT,
payload: project,
});
-
-export const navigateToProjectSectionAction = ({ organizationSlug, projectSlug }, section) => ({
- type: PROJECT_DETAILS_PAGE,
- payload: {
- projectSlug,
- projectSection: section,
- organizationSlug,
- },
-});
diff --git a/app/src/controllers/organizations/projects/constants.js b/app/src/controllers/organization/projects/constants.js
similarity index 96%
rename from app/src/controllers/organizations/projects/constants.js
rename to app/src/controllers/organization/projects/constants.js
index a0e18b037f..18a785927c 100644
--- a/app/src/controllers/organizations/projects/constants.js
+++ b/app/src/controllers/organization/projects/constants.js
@@ -50,3 +50,7 @@ export const initialPaginationState = {
totalElements: 0,
totalPages: 0,
};
+
+export const ERROR_CODES = {
+ PROJECT_EXISTS: 4095,
+};
diff --git a/app/src/controllers/organizations/projects/index.js b/app/src/controllers/organization/projects/index.js
similarity index 88%
rename from app/src/controllers/organizations/projects/index.js
rename to app/src/controllers/organization/projects/index.js
index 7b1d0e1770..4d223dc072 100644
--- a/app/src/controllers/organizations/projects/index.js
+++ b/app/src/controllers/organization/projects/index.js
@@ -14,11 +14,7 @@
* limitations under the License.
*/
-export {
- fetchOrganizationProjectsAction,
- navigateToProjectAction,
- navigateToProjectSectionAction,
-} from './actionCreators';
+export { fetchOrganizationProjectsAction, navigateToProjectAction } from './actionCreators';
export { projectsReducer } from './reducer';
export {
projectsPaginationSelector,
diff --git a/app/src/controllers/organizations/projects/reducer.js b/app/src/controllers/organization/projects/reducer.js
similarity index 100%
rename from app/src/controllers/organizations/projects/reducer.js
rename to app/src/controllers/organization/projects/reducer.js
diff --git a/app/src/controllers/organizations/projects/sagas.js b/app/src/controllers/organization/projects/sagas.js
similarity index 90%
rename from app/src/controllers/organizations/projects/sagas.js
rename to app/src/controllers/organization/projects/sagas.js
index 99de0ef08d..33e45c09ed 100644
--- a/app/src/controllers/organizations/projects/sagas.js
+++ b/app/src/controllers/organization/projects/sagas.js
@@ -20,12 +20,11 @@ import { URLS } from 'common/urls';
import { fetch } from 'common/utils';
import { hideModalAction } from 'controllers/modal';
import { NOTIFICATION_TYPES, showNotification } from 'controllers/notification';
-import { ERROR_CODES } from 'controllers/instance/projects/constants';
-import { fetchOrganizationBySlugAction } from '../organization';
-import { activeOrganizationSelector } from '../organization/selectors';
+import { fetchOrganizationBySlugAction } from '..';
+import { activeOrganizationSelector } from '../selectors';
import { fetchOrganizationProjectsAction } from './actionCreators';
import { querySelector } from './selectors';
-import { CREATE_PROJECT, FETCH_ORGANIZATION_PROJECTS, NAMESPACE } from './constants';
+import { CREATE_PROJECT, ERROR_CODES, FETCH_ORGANIZATION_PROJECTS, NAMESPACE } from './constants';
function* fetchOrganizationProjects({ payload: organizationId }) {
const query = yield select(querySelector);
diff --git a/app/src/controllers/organizations/projects/selectors.js b/app/src/controllers/organization/projects/selectors.js
similarity index 96%
rename from app/src/controllers/organizations/projects/selectors.js
rename to app/src/controllers/organization/projects/selectors.js
index 183f0155c9..3f450eab23 100644
--- a/app/src/controllers/organizations/projects/selectors.js
+++ b/app/src/controllers/organization/projects/selectors.js
@@ -19,7 +19,7 @@ import { createQueryParametersSelector } from 'controllers/pages';
import { SORTING_ASC } from 'controllers/sorting';
import { getAlternativePaginationAndSortParams, PAGE_KEY, SIZE_KEY } from 'controllers/pagination';
import { SORTING_KEY, DEFAULT_PAGINATION } from './constants';
-import { organizationSelector } from '../organization/selectors';
+import { organizationSelector } from '../selectors';
const domainSelector = (state) => organizationSelector(state).projects || {};
diff --git a/app/src/controllers/organizations/organization/reducer.js b/app/src/controllers/organization/reducer.js
similarity index 96%
rename from app/src/controllers/organizations/organization/reducer.js
rename to app/src/controllers/organization/reducer.js
index b600dc0546..c8514b38a3 100644
--- a/app/src/controllers/organizations/organization/reducer.js
+++ b/app/src/controllers/organization/reducer.js
@@ -18,7 +18,7 @@ import { combineReducers } from 'redux';
import { fetchReducer } from 'controllers/fetch';
import { loadingReducer } from 'controllers/loading';
import { queueReducers } from 'common/utils';
-import { projectsReducer } from '../projects/reducer';
+import { projectsReducer } from './projects/reducer';
import { FETCH_ORGANIZATION_BY_SLUG, SET_ACTIVE_ORGANIZATION } from './constants';
const setActiveOrganizationReducer = (state = [], { type = '', payload = {} }) => {
diff --git a/app/src/controllers/organizations/organization/sagas.js b/app/src/controllers/organization/sagas.js
similarity index 95%
rename from app/src/controllers/organizations/organization/sagas.js
rename to app/src/controllers/organization/sagas.js
index e14841d845..68c0e6dbdf 100644
--- a/app/src/controllers/organizations/organization/sagas.js
+++ b/app/src/controllers/organization/sagas.js
@@ -17,10 +17,10 @@
import { takeEvery, all, put, select, take } from 'redux-saga/effects';
import { createFetchPredicate, fetchDataAction } from 'controllers/fetch';
import { redirect } from 'redux-first-router';
-import { PROJECTS_PAGE } from 'controllers/pages';
+import { ORGANIZATIONS_PAGE } from 'controllers/pages';
import { URLS } from 'common/urls';
import { showDefaultErrorNotification } from 'controllers/notification';
-import { fetchOrganizationProjectsAction } from 'controllers/organizations/projects';
+import { fetchOrganizationProjectsAction } from 'controllers/organization/projects';
import { FETCH_ORGANIZATION_BY_SLUG, PREPARE_ACTIVE_ORGANIZATION_PROJECTS } from './constants';
import { activeOrganizationSelector } from './selectors';
@@ -43,7 +43,7 @@ function* prepareActiveOrganizationProjects({ payload: { organizationSlug } }) {
} catch (error) {
yield put(
redirect({
- type: PROJECTS_PAGE,
+ type: ORGANIZATIONS_PAGE,
}),
);
}
diff --git a/app/src/controllers/organizations/organization/selectors.js b/app/src/controllers/organization/selectors.js
similarity index 92%
rename from app/src/controllers/organizations/organization/selectors.js
rename to app/src/controllers/organization/selectors.js
index d786e5cc42..10269b7e36 100644
--- a/app/src/controllers/organizations/organization/selectors.js
+++ b/app/src/controllers/organization/selectors.js
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-import { organizationsSelector } from 'controllers/organizations/selectors';
+import { organizationsSelector } from 'controllers/instance/organizations/selectors';
export const organizationSelector = (state) => organizationsSelector(state).organization || {};
diff --git a/app/src/controllers/pages/constants.js b/app/src/controllers/pages/constants.js
index 7d648dc496..845842861d 100644
--- a/app/src/controllers/pages/constants.js
+++ b/app/src/controllers/pages/constants.js
@@ -22,8 +22,6 @@ export const CLEAR_PAGE_STATE = 'clearPageStateAction';
// undefined page
export const NO_PAGE = undefined;
// admin
-export const PROJECTS_PAGE = 'PROJECTS_PAGE';
-export const PROJECT_DETAILS_PAGE = 'PROJECT_DETAILS_PAGE';
export const ALL_USERS_PAGE = 'ALL_USERS_PAGE';
export const SERVER_SETTINGS_PAGE = 'SERVER_SETTINGS_PAGE';
export const SERVER_SETTINGS_TAB_PAGE = 'SERVER_SETTINGS_TAB_PAGE';
@@ -32,6 +30,7 @@ export const PLUGINS_TAB_PAGE = 'PLUGINS_TAB_PAGE';
export const PLUGIN_UI_EXTENSION_ADMIN_PAGE = 'PLUGIN_UI_EXTENSION_ADMIN_PAGE';
// inside
export const API_PAGE = 'API_PAGE';
+export const ORGANIZATIONS_PAGE = 'ORGANIZATIONS_PAGE';
export const ORGANIZATION_PROJECTS_PAGE = 'ORGANIZATION_PROJECTS_PAGE';
export const ORGANIZATION_MEMBERS_PAGE = 'ORGANIZATION_MEMBERS_PAGE';
export const ORGANIZATION_SETTINGS_PAGE = 'ORGANIZATION_SETTINGS_PAGE';
@@ -71,9 +70,8 @@ export const PROJECT_PLUGIN_PAGE = 'PROJECT_PLUGIN_PAGE';
export const pageNames = {
[NOT_FOUND]: NOT_FOUND,
+ ORGANIZATIONS_PAGE,
ORGANIZATION_PROJECTS_PAGE,
- PROJECTS_PAGE,
- PROJECT_DETAILS_PAGE,
ALL_USERS_PAGE,
SERVER_SETTINGS_PAGE,
SERVER_SETTINGS_TAB_PAGE,
@@ -112,8 +110,6 @@ export const pageNames = {
};
export const adminPageNames = {
- [PROJECTS_PAGE]: PROJECTS_PAGE,
- [PROJECT_DETAILS_PAGE]: PROJECT_DETAILS_PAGE,
[ALL_USERS_PAGE]: ALL_USERS_PAGE,
[SERVER_SETTINGS_PAGE]: SERVER_SETTINGS_PAGE,
[SERVER_SETTINGS_TAB_PAGE]: SERVER_SETTINGS_TAB_PAGE,
diff --git a/app/src/controllers/pages/index.js b/app/src/controllers/pages/index.js
index 47af91266d..a9540b4d42 100644
--- a/app/src/controllers/pages/index.js
+++ b/app/src/controllers/pages/index.js
@@ -50,8 +50,6 @@ export { updatePagePropertiesAction, clearPageStateAction } from './actionCreato
export {
NO_PAGE,
- PROJECTS_PAGE,
- PROJECT_DETAILS_PAGE,
ALL_USERS_PAGE,
SERVER_SETTINGS_PAGE,
SERVER_SETTINGS_TAB_PAGE,
@@ -92,6 +90,7 @@ export {
CLEAR_PAGE_STATE,
PLUGIN_UI_EXTENSION_ADMIN_PAGE,
PROJECT_PLUGIN_PAGE,
+ ORGANIZATIONS_PAGE,
ORGANIZATION_PROJECTS_PAGE,
ORGANIZATION_MEMBERS_PAGE,
ORGANIZATION_SETTINGS_PAGE,
diff --git a/app/src/controllers/plugins/uiExtensions/createImportProps.js b/app/src/controllers/plugins/uiExtensions/createImportProps.js
index 51269bfe80..97859abccc 100644
--- a/app/src/controllers/plugins/uiExtensions/createImportProps.js
+++ b/app/src/controllers/plugins/uiExtensions/createImportProps.js
@@ -122,7 +122,6 @@ import { DottedPreloader } from 'components/preloaders/dottedPreloader';
import { FieldProvider } from 'components/fields/fieldProvider';
import { FieldErrorHint } from 'components/fields/fieldErrorHint';
import { SimpleBreadcrumbs } from 'components/main/simpleBreadcrumbs';
-
import { statisticsLinkSelector, defectLinkSelector, launchSelector } from 'controllers/testItem';
import { Grid } from 'components/main/grid';
import { InputCheckbox } from 'components/inputs/inputCheckbox';
@@ -130,7 +129,6 @@ import { AttributeListContainer as AttributeListField } from 'components/contain
import { AsyncAutocomplete } from 'components/inputs/autocompletes/asyncAutocomplete';
import { InputSearch } from 'components/inputs/inputSearch';
import { PaginationToolbar } from 'components/main/paginationToolbar';
-import { ProjectName } from 'pages/instance/projectsPage/projectName';
import { debounce } from 'common/utils/debounce';
import { DotsMenuButton } from 'components/buttons/dotsMenuButton';
import { GhostMenuButton } from 'components/buttons/ghostMenuButton';
@@ -196,6 +194,7 @@ import { Tabs } from 'components/main/tabs';
import { withTooltip } from 'components/main/tooltips/tooltip';
import { Breadcrumbs } from 'componentLibrary/breadcrumbs';
import { PlainTable } from 'componentLibrary/plainTable';
+import { ProjectName } from 'pages/organization/organizationProjectsPage/projectsListTable/projectName';
const BUTTONS = {
GhostButton,
diff --git a/app/src/controllers/user/sagas.js b/app/src/controllers/user/sagas.js
index 745e52b7bf..8eee8b4337 100644
--- a/app/src/controllers/user/sagas.js
+++ b/app/src/controllers/user/sagas.js
@@ -22,7 +22,7 @@ import { PROJECT_MANAGER } from 'common/constants/projectRoles';
import { getStorageItem, setStorageItem } from 'common/utils/storageUtils';
import { userAssignedSelector, urlOrganizationAndProjectSelector } from 'controllers/pages';
import { getLogTimeFormatFromStorage } from 'controllers/log/storageUtils';
-import { setActiveOrganizationAction } from 'controllers/organizations/organization/actionCreators';
+import { setActiveOrganizationAction } from 'controllers/organization/actionCreators';
import {
assignToProjectSuccessAction,
assignToProjectErrorAction,
diff --git a/app/src/layouts/instanceLayout/instanceSidebar/instanceSidebar.jsx b/app/src/layouts/instanceLayout/instanceSidebar/instanceSidebar.jsx
index 1439f24f70..e6a01821df 100644
--- a/app/src/layouts/instanceLayout/instanceSidebar/instanceSidebar.jsx
+++ b/app/src/layouts/instanceLayout/instanceSidebar/instanceSidebar.jsx
@@ -25,9 +25,9 @@ import {
SERVER_SETTINGS_PAGE,
PLUGINS_PAGE,
ALL_USERS_PAGE,
- PROJECTS_PAGE,
PLUGIN_UI_EXTENSION_ADMIN_PAGE,
USER_PROFILE_PAGE,
+ ORGANIZATIONS_PAGE,
} from 'controllers/pages/constants';
import { SIDEBAR_EVENTS } from 'components/main/analytics/events';
import {
@@ -63,7 +63,7 @@ export const InstanceSidebar = ({ onClickNavBtn }) => {
{
onClick: (isSidebarCollapsed) =>
onClickButton({ itemName: messages.organizations.defaultMessage, isSidebarCollapsed }),
- link: { type: PROJECTS_PAGE },
+ link: { type: ORGANIZATIONS_PAGE },
icon: OrganizationsIcon,
message: formatMessage(messages.organizations),
},
@@ -117,7 +117,7 @@ export const InstanceSidebar = ({ onClickNavBtn }) => {
return sidebarItems;
};
- const link = { type: PROJECTS_PAGE };
+ const link = { type: ORGANIZATIONS_PAGE };
const linkToUserProfilePage = { type: USER_PROFILE_PAGE };
const titles = {
shortTitle: formatMessage(messages.all),
diff --git a/app/src/layouts/organizationLayout/organizationSidebar/organizationSidebar.jsx b/app/src/layouts/organizationLayout/organizationSidebar/organizationSidebar.jsx
index f50ff36982..00c82d7075 100644
--- a/app/src/layouts/organizationLayout/organizationSidebar/organizationSidebar.jsx
+++ b/app/src/layouts/organizationLayout/organizationSidebar/organizationSidebar.jsx
@@ -25,8 +25,8 @@ import {
ORGANIZATION_PROJECTS_PAGE,
ORGANIZATION_MEMBERS_PAGE,
ORGANIZATION_SETTINGS_PAGE,
- PROJECTS_PAGE,
USER_PROFILE_PAGE_ORGANIZATION_LEVEL,
+ ORGANIZATIONS_PAGE,
} from 'controllers/pages/constants';
import { uiExtensionSidebarComponentsSelector } from 'controllers/plugins/uiExtensions';
import { AppSidebar } from 'layouts/common/appSidebar';
@@ -37,7 +37,7 @@ import ProjectsIcon from 'common/img/sidebar/projects-icon-inline.svg';
import {
activeOrganizationNameSelector,
activeOrganizationSelector,
-} from 'controllers/organizations/organization';
+} from 'controllers/organization';
import { SIDEBAR_EVENTS } from 'components/main/analytics/events';
import { OrganizationsControlWithPopover } from '../../organizationsControl';
import { messages } from '../../messages';
@@ -107,7 +107,7 @@ export const OrganizationSidebar = ({ onClickNavBtn }) => {
return sidebarItems;
};
- const link = { type: PROJECTS_PAGE };
+ const link = { type: ORGANIZATIONS_PAGE };
const linkToUserProfilePage = {
type: USER_PROFILE_PAGE_ORGANIZATION_LEVEL,
payload: { organizationSlug },
diff --git a/app/src/layouts/organizationsControl/organizationsControl.jsx b/app/src/layouts/organizationsControl/organizationsControl.jsx
index 2ec45af4c7..4eec67c154 100644
--- a/app/src/layouts/organizationsControl/organizationsControl.jsx
+++ b/app/src/layouts/organizationsControl/organizationsControl.jsx
@@ -17,7 +17,7 @@
import PropTypes from 'prop-types';
import Parser from 'html-react-parser';
import classNames from 'classnames/bind';
-import Link from 'redux-first-router-link';
+import { NavLink } from 'components/main/navLink';
import { withPopover } from 'componentLibrary/popover';
import { useTracking } from 'react-tracking';
import { SIDEBAR_EVENTS } from 'components/main/analytics/events';
@@ -52,7 +52,7 @@ export const OrganizationsControl = ({
{isExtendedNav ? (
<>
{Parser(ArrowLeftIcon)}
- {
@@ -61,7 +61,7 @@ export const OrganizationsControl = ({
}}
>
{titles.topTitle}
-
+
>
) : (
{titles.topTitle}
diff --git a/app/src/layouts/organizationsControl/organizationsPopover/organizationsPopover.jsx b/app/src/layouts/organizationsControl/organizationsPopover/organizationsPopover.jsx
index 7b05fda389..287680e998 100644
--- a/app/src/layouts/organizationsControl/organizationsPopover/organizationsPopover.jsx
+++ b/app/src/layouts/organizationsControl/organizationsPopover/organizationsPopover.jsx
@@ -24,7 +24,7 @@ import { availableProjectsSelector } from 'controllers/user';
import {
urlProjectSlugSelector,
urlOrganizationSlugSelector,
- PROJECTS_PAGE,
+ ORGANIZATIONS_PAGE,
} from 'controllers/pages';
import { ScrollWrapper } from 'components/main/scrollWrapper';
import { NavLink } from 'components/main/navLink';
@@ -120,7 +120,7 @@ export const OrganizationsPopover = ({ closePopover, closeSidebar }) => {
<>
{
onClose();
diff --git a/app/src/layouts/projectLayout/projectSidebar/projectSidebar.jsx b/app/src/layouts/projectLayout/projectSidebar/projectSidebar.jsx
index 6f70503dcc..12296e956d 100644
--- a/app/src/layouts/projectLayout/projectSidebar/projectSidebar.jsx
+++ b/app/src/layouts/projectLayout/projectSidebar/projectSidebar.jsx
@@ -47,7 +47,7 @@ import DebugIcon from 'common/img/sidebar/debug-icon-inline.svg';
import MembersIcon from 'common/img/sidebar/members-icon-inline.svg';
import SettingsIcon from 'common/img/sidebar/settings-icon-inline.svg';
import { projectNameSelector } from 'controllers/project';
-import { activeOrganizationNameSelector } from 'controllers/organizations/organization';
+import { activeOrganizationNameSelector } from 'controllers/organization';
import { OrganizationsControlWithPopover } from '../../organizationsControl';
import { messages } from '../../messages';
diff --git a/app/src/pages/organization/emptyPageState/emptyPageState.jsx b/app/src/pages/common/emptyPageState/emptyPageState.jsx
similarity index 100%
rename from app/src/pages/organization/emptyPageState/emptyPageState.jsx
rename to app/src/pages/common/emptyPageState/emptyPageState.jsx
diff --git a/app/src/pages/organization/emptyPageState/emptyPageState.scss b/app/src/pages/common/emptyPageState/emptyPageState.scss
similarity index 100%
rename from app/src/pages/organization/emptyPageState/emptyPageState.scss
rename to app/src/pages/common/emptyPageState/emptyPageState.scss
diff --git a/app/src/pages/organization/emptyPageState/index.js b/app/src/pages/common/emptyPageState/index.js
similarity index 100%
rename from app/src/pages/organization/emptyPageState/index.js
rename to app/src/pages/common/emptyPageState/index.js
diff --git a/app/src/pages/instance/allUsersPage/allUsersGrid/projectsAndRolesColumn/rolesRow/rolesRow.jsx b/app/src/pages/instance/allUsersPage/allUsersGrid/projectsAndRolesColumn/rolesRow/rolesRow.jsx
index c90822bb64..0fad2f73dd 100644
--- a/app/src/pages/instance/allUsersPage/allUsersGrid/projectsAndRolesColumn/rolesRow/rolesRow.jsx
+++ b/app/src/pages/instance/allUsersPage/allUsersGrid/projectsAndRolesColumn/rolesRow/rolesRow.jsx
@@ -30,7 +30,7 @@ import { isEmptyValue } from 'common/utils/isEmptyValue';
import Parser from 'html-react-parser';
import CrossIcon from 'common/img/cross-icon-inline.svg';
import CheckIcon from 'common/img/check-inline.svg';
-import { ProjectName } from 'pages/instance/projectsPage/projectName';
+import { ProjectName } from 'pages/organization/organizationProjectsPage/projectsListTable/projectName';
import styles from './rolesRow.scss';
const cx = classNames.bind(styles);
diff --git a/app/src/pages/instance/organizationsPage/img/empty-organizations-inline.svg b/app/src/pages/instance/organizationsPage/img/empty-organizations-inline.svg
new file mode 100644
index 0000000000..83e43b0f5b
--- /dev/null
+++ b/app/src/pages/instance/organizationsPage/img/empty-organizations-inline.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/pages/instance/projectsPage/projectMenu/index.js b/app/src/pages/instance/organizationsPage/index.js
similarity index 91%
rename from app/src/pages/instance/projectsPage/projectMenu/index.js
rename to app/src/pages/instance/organizationsPage/index.js
index 89d7ac444c..0eeb670fcb 100644
--- a/app/src/pages/instance/projectsPage/projectMenu/index.js
+++ b/app/src/pages/instance/organizationsPage/index.js
@@ -14,4 +14,4 @@
* limitations under the License.
*/
-export { ProjectMenu } from './projectMenu';
+export { OrganizationsPage } from './organizationsPage';
diff --git a/app/src/pages/instance/organizationsPage/messages.js b/app/src/pages/instance/organizationsPage/messages.js
new file mode 100644
index 0000000000..b8a353c300
--- /dev/null
+++ b/app/src/pages/instance/organizationsPage/messages.js
@@ -0,0 +1,64 @@
+/*!
+ * 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 { defineMessages } from 'react-intl';
+
+export const messages = defineMessages({
+ title: {
+ id: 'OrganizationsPage.title',
+ defaultMessage: 'All Organizations',
+ },
+ description: {
+ id: 'OrganizationsPage.description',
+ defaultMessage: `The list of organizations available to you is currently empty. Please contact your Administrator to be assigned to an existing one.`,
+ },
+ createOrganization: {
+ id: 'OrganizationsPage.createOrganization',
+ defaultMessage: 'Create Organization',
+ },
+ createNewOrganization: {
+ id: 'OrganizationsPage.createNewOrganization',
+ defaultMessage: 'Create a new organization to begin your ReportPortal journey',
+ },
+ noOrganizationsYet: {
+ id: 'OrganizationsPage.noOrganizationsYet',
+ defaultMessage: 'No organizations yet',
+ },
+ noOrganizationsAvailableYet: {
+ id: 'OrganizationsPage.noOrganizationsAvailableYet',
+ defaultMessage: 'No organizations available yet',
+ },
+ synchedOrganization: {
+ id: 'OrganizationsPage.synchedOrganization',
+ defaultMessage: 'Synched organization',
+ },
+ lastLaunch: {
+ id: 'OrganizationsPage.lastLaunch',
+ defaultMessage: 'The last launch was executed more than 3 months ago',
+ },
+ organizationUsers: {
+ id: 'OrganizationsPage.organizationUsers',
+ defaultMessage: 'Organization users',
+ },
+ organizationProjects: {
+ id: 'OrganizationsPage.organizationProjects',
+ defaultMessage: 'Organization projects',
+ },
+ latestLaunch: {
+ id: 'OrganizationsPage.latestLaunch',
+ defaultMessage: 'The latest launch execution',
+ },
+});
diff --git a/app/src/pages/instance/organizationsPage/organizationsPage.jsx b/app/src/pages/instance/organizationsPage/organizationsPage.jsx
new file mode 100644
index 0000000000..bec6b9243d
--- /dev/null
+++ b/app/src/pages/instance/organizationsPage/organizationsPage.jsx
@@ -0,0 +1,81 @@
+/*!
+ * 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 { useSelector } from 'react-redux';
+import { userRolesSelector } from 'controllers/pages';
+import { canCreateOrganization } from 'common/utils/permissions';
+import classNames from 'classnames/bind';
+import { useIntl } from 'react-intl';
+import { BubblesLoader, PlusIcon } from '@reportportal/ui-kit';
+import { ScrollWrapper } from 'components/main/scrollWrapper';
+import { EmptyPageState } from 'pages/common/emptyPageState';
+import {
+ organizationsListLoadingSelector,
+ organizationsListSelector,
+} from 'controllers/instance/organizations';
+import EmptyIcon from './img/empty-organizations-inline.svg';
+import { messages } from './messages';
+import styles from './organizationsPage.scss';
+import { OrganizationsPageHeader } from './organizationsPageHeader';
+import { OrganizationsPanelView } from './organizationsPanelView';
+
+const cx = classNames.bind(styles);
+
+export const OrganizationsPage = () => {
+ const { formatMessage } = useIntl();
+ const userRoles = useSelector(userRolesSelector);
+ const hasPermission = canCreateOrganization(userRoles);
+ const organizationsList = useSelector(organizationsListSelector);
+ const isOrganizationsLoading = useSelector(organizationsListLoadingSelector);
+ const isEmptyOrganizations = organizationsList.length === 0;
+
+ const getEmptyPageState = () =>
+ isOrganizationsLoading ? (
+
+
+
+ ) : (
+ }
+ label={formatMessage(
+ hasPermission ? messages.noOrganizationsYet : messages.noOrganizationsAvailableYet,
+ )}
+ description={formatMessage(
+ hasPermission ? messages.createNewOrganization : messages.description,
+ )}
+ buttonTitle={formatMessage(messages.createOrganization)}
+ />
+ );
+
+ return (
+
+
+
+ {isEmptyOrganizations ? (
+ getEmptyPageState()
+ ) : (
+
+ )}
+
+
+ );
+};
diff --git a/app/src/pages/instance/projectsPage/projectsToolbar/projectsSorting/projectsSorting.scss b/app/src/pages/instance/organizationsPage/organizationsPage.scss
similarity index 76%
rename from app/src/pages/instance/projectsPage/projectsToolbar/projectsSorting/projectsSorting.scss
rename to app/src/pages/instance/organizationsPage/organizationsPage.scss
index 5ace68b99d..2c8dbc2c44 100644
--- a/app/src/pages/instance/projectsPage/projectsToolbar/projectsSorting/projectsSorting.scss
+++ b/app/src/pages/instance/organizationsPage/organizationsPage.scss
@@ -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.
@@ -14,14 +14,15 @@
* limitations under the License.
*/
-.caption {
- font-family: $FONT-REGULAR;
- color: $COLOR--black-2;
- font-size: 13px;
- padding-top: 3px;
+ .organizations-page {
+ display: flex;
+ flex-direction: column;
+ min-height: 100%;
}
-.sorting-block {
+
+.loader {
display: flex;
- justify-content: flex-end;
+ justify-content: center;
align-items: center;
+ height: 100%;
}
diff --git a/app/src/pages/instance/projectsPage/projectName/index.js b/app/src/pages/instance/organizationsPage/organizationsPageHeader/index.js
similarity index 89%
rename from app/src/pages/instance/projectsPage/projectName/index.js
rename to app/src/pages/instance/organizationsPage/organizationsPageHeader/index.js
index d730662b5f..d271e1ac82 100644
--- a/app/src/pages/instance/projectsPage/projectName/index.js
+++ b/app/src/pages/instance/organizationsPage/organizationsPageHeader/index.js
@@ -14,4 +14,4 @@
* limitations under the License.
*/
-export { ProjectName } from './projectName';
+export { OrganizationsPageHeader } from './organizationsPageHeader';
diff --git a/app/src/pages/instance/organizationsPage/organizationsPageHeader/organizationsPageHeader.jsx b/app/src/pages/instance/organizationsPage/organizationsPageHeader/organizationsPageHeader.jsx
new file mode 100644
index 0000000000..acb30ddfc4
--- /dev/null
+++ b/app/src/pages/instance/organizationsPage/organizationsPageHeader/organizationsPageHeader.jsx
@@ -0,0 +1,55 @@
+/*
+ * 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 PropTypes from 'prop-types';
+import Parser from 'html-react-parser';
+import classNames from 'classnames/bind';
+import searchIcon from 'common/img/newIcons/search-outline-inline.svg';
+import filterIcon from 'common/img/newIcons/filters-outline-inline.svg';
+import { useIntl } from 'react-intl';
+import { messages } from '../messages';
+import styles from './organizationsPageHeader.scss';
+
+const cx = classNames.bind(styles);
+
+export const OrganizationsPageHeader = ({ isEmpty }) => {
+ const { formatMessage } = useIntl();
+
+ return (
+
+
+
{formatMessage(messages.title)}
+
+ {!isEmpty && (
+
+ {Parser(searchIcon)}
+ {Parser(filterIcon)}
+
+ )}
+
+
+
+ );
+};
+
+OrganizationsPageHeader.propTypes = {
+ isEmpty: PropTypes.bool,
+};
+
+OrganizationsPageHeader.defaultProps = {
+ isEmpty: false,
+};
diff --git a/app/src/pages/instance/organizationsPage/organizationsPageHeader/organizationsPageHeader.scss b/app/src/pages/instance/organizationsPage/organizationsPageHeader/organizationsPageHeader.scss
new file mode 100644
index 0000000000..7b88e39bd6
--- /dev/null
+++ b/app/src/pages/instance/organizationsPage/organizationsPageHeader/organizationsPageHeader.scss
@@ -0,0 +1,74 @@
+/*!
+ * 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.
+ */
+
+.organizations-page-header-container {
+ padding: 48px 32px 12px 32px;
+ border-bottom: 1px solid $COLOR--e-100;
+ background: $COLOR--bg-000;
+ box-sizing: border-box;
+ position: sticky;
+ top: 0;
+ z-index: 2;
+}
+
+.header {
+ display: flex;
+ justify-content: space-between;
+}
+
+.title {
+ font-family: $FONT-REGULAR;
+ font-size: 20px;
+ line-height: 31px;
+ color: $COLOR--almost-black;
+ text-transform: capitalize;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.actions {
+ display: flex;
+ align-items: center;
+ gap: 32px;
+
+ .icons {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ i {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ &.search-icon {
+ width: 40px;
+ height: 36px;
+ }
+
+ &.filters-icon {
+ width: 57px;
+ height: 36px;
+ }
+
+ svg {
+ width: 16px;
+ height: 16px;
+ }
+ }
+ }
+}
diff --git a/app/src/pages/instance/projectsPage/projectStatisticButton/index.js b/app/src/pages/instance/organizationsPage/organizationsPanelView/index.js
similarity index 90%
rename from app/src/pages/instance/projectsPage/projectStatisticButton/index.js
rename to app/src/pages/instance/organizationsPage/organizationsPanelView/index.js
index 6058f26919..a3d475bbc4 100644
--- a/app/src/pages/instance/projectsPage/projectStatisticButton/index.js
+++ b/app/src/pages/instance/organizationsPage/organizationsPanelView/index.js
@@ -14,4 +14,4 @@
* limitations under the License.
*/
-export { ProjectStatisticButton } from './projectStatisticButton';
+export { OrganizationsPanelView } from './organizationsPanelView';
diff --git a/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/last-update-inline.svg b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/last-update-inline.svg
new file mode 100644
index 0000000000..408c1dc8db
--- /dev/null
+++ b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/last-update-inline.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/outdated-inline.svg b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/outdated-inline.svg
new file mode 100644
index 0000000000..680751e6fa
--- /dev/null
+++ b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/outdated-inline.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/personal-organization-inline.svg b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/personal-organization-inline.svg
new file mode 100644
index 0000000000..75193f3a86
--- /dev/null
+++ b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/personal-organization-inline.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/projects-inline.svg b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/projects-inline.svg
new file mode 100644
index 0000000000..99eb213923
--- /dev/null
+++ b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/projects-inline.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/synched-organization-inline.svg b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/synched-organization-inline.svg
new file mode 100644
index 0000000000..1218f81475
--- /dev/null
+++ b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/synched-organization-inline.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/user-inline.svg b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/user-inline.svg
new file mode 100644
index 0000000000..3a7a3610f4
--- /dev/null
+++ b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/img/user-inline.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/app/src/pages/instance/projectsPage/projects/index.js b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/index.js
similarity index 91%
rename from app/src/pages/instance/projectsPage/projects/index.js
rename to app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/index.js
index 309e61c5f4..38f1063de1 100644
--- a/app/src/pages/instance/projectsPage/projects/index.js
+++ b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/index.js
@@ -14,4 +14,4 @@
* limitations under the License.
*/
-export { Projects } from './projects';
+export { OrganizationCard } from './organizationCard';
diff --git a/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/organizationCard.jsx b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/organizationCard.jsx
new file mode 100644
index 0000000000..0af3c72896
--- /dev/null
+++ b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/organizationCard.jsx
@@ -0,0 +1,125 @@
+/*!
+ * 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 classNames from 'classnames/bind';
+import PropTypes from 'prop-types';
+import { useIntl, FormattedRelativeTime } from 'react-intl';
+import Parser from 'html-react-parser';
+import { useSelector } from 'react-redux';
+import { Tooltip } from '@reportportal/ui-kit';
+import { NavLink } from 'components/main/navLink';
+import { ORGANIZATION_PROJECTS_PAGE } from 'controllers/pages/constants';
+import { userRolesSelector } from 'controllers/pages';
+import { MANAGER } from 'common/constants/projectRoles';
+import { ADMINISTRATOR } from 'common/constants/accountRoles';
+import { getRelativeUnits } from 'common/utils/timeDateUtils';
+import { ORGANIZATION_EXTERNAL_TYPE } from 'common/constants/organizationTypes';
+import UserIcon from './img/user-inline.svg';
+import ProjectsIcon from './img/projects-inline.svg';
+import LastUpdateIcon from './img/last-update-inline.svg';
+import SynchedIcon from './img/synched-organization-inline.svg';
+import OutdatedIcon from './img/outdated-inline.svg';
+import PersonalIcon from './img/personal-organization-inline.svg';
+import { messages } from '../../messages';
+import styles from './organizationCard.scss';
+
+const cx = classNames.bind(styles);
+const THREE_MONTHS = 3600 * 24 * 30 * 1000;
+
+export const OrganizationCard = ({ organization }) => {
+ const { formatMessage } = useIntl();
+ const { userRole, organizationRole } = useSelector(userRolesSelector);
+ const hasPermission = userRole === ADMINISTRATOR || organizationRole === MANAGER;
+ const usersCount = organization.relationships.users.meta.count;
+ const projectsCount = organization.relationships.projects.meta.count;
+ const lastLaunch = organization.relationships.launches.meta.last_occurred_at;
+ const { value: relativeTime, unit } = getRelativeUnits(new Date(lastLaunch));
+ const isOutdated = Date.now() - new Date(lastLaunch).getTime() > THREE_MONTHS;
+
+ const cartInfo = [
+ {
+ icon: UserIcon,
+ className: cx('icon-wrapper'),
+ content: formatMessage(messages.organizationUsers),
+ bottomElement: {usersCount} ,
+ },
+ {
+ icon: ProjectsIcon,
+ className: cx('icon-wrapper'),
+ content: formatMessage(messages.organizationProjects),
+ bottomElement: {projectsCount} ,
+ },
+ {
+ icon: LastUpdateIcon,
+ className: cx('last-update'),
+ content: formatMessage(messages.latestLaunch),
+ bottomElement: ,
+ },
+ ];
+
+ return (
+
+
+
+ {organization.name}
+
+ {hasPermission &&
+ (organization.type === ORGANIZATION_EXTERNAL_TYPE ? (
+
+ {Parser(SynchedIcon)}
+
+ ) : (
+ {Parser(PersonalIcon)}
+ ))}
+ {hasPermission && isOutdated && (
+
+ {Parser(OutdatedIcon)}
+
+ )}
+
+ {hasPermission && (
+
+ {cartInfo.map(({ icon, className, content, bottomElement }) => (
+
+
+ {Parser(icon)}
+
+ {bottomElement}
+
+ ))}
+
+ )}
+
+ );
+};
+
+OrganizationCard.propTypes = {
+ organization: PropTypes.object.isRequired,
+};
diff --git a/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/organizationCard.scss b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/organizationCard.scss
new file mode 100644
index 0000000000..eb888c83ef
--- /dev/null
+++ b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationCard/organizationCard.scss
@@ -0,0 +1,91 @@
+/*!
+ * 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.
+ */
+
+.organization-card {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ padding: 16px;
+ box-sizing: border-box;
+ height: 160px;
+ border-radius: 8px;
+ min-width: 320px;
+ max-width: 400px;
+ box-shadow: $BOX_SHADOW--item;
+ background-color: $COLOR--white-two;
+
+ i {
+ display: block;
+ height: 16px;
+ }
+}
+
+.last-update,
+.icon-wrapper {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-family: $FONT-ROBOTO-REGULAR;
+ color: $COLOR--almost-black;
+ font-size: 13px;
+ line-height: 20px;
+ width: 98px;
+}
+
+.last-update {
+ width: auto;
+ max-width: 152px;
+}
+
+.icon {
+ width: 16px;
+
+ svg {
+ width: 16px;
+ height: 16px;
+ }
+}
+
+.date {
+ min-height: 20px;
+ font-family: $FONT-ROBOTO-REGULAR;
+ color: $COLOR--almost-black;
+ font-size: 13px;
+ line-height: 20px;
+}
+
+.cart-info {
+ display: flex;
+ gap: 10px;
+}
+
+.organization-name {
+ display: flex;
+ align-items: center;
+ gap: 16px;
+}
+
+.tooltip-wrapper {
+ width: 16px;
+}
+
+.organization-link {
+ text-decoration: none;
+ font-family: $FONT-ROBOTO-MEDIUM;
+ color: $COLOR--almost-black;
+ font-size: 13px;
+ line-height: 20px;
+}
diff --git a/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationsPanelView.jsx b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationsPanelView.jsx
new file mode 100644
index 0000000000..9f89a8c345
--- /dev/null
+++ b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationsPanelView.jsx
@@ -0,0 +1,81 @@
+/*!
+ * 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 classNames from 'classnames/bind';
+import PropTypes from 'prop-types';
+import { SORTING_ASC, withSortingURL } from 'controllers/sorting';
+import { DEFAULT_PAGINATION, PAGE_KEY, withPagination } from 'controllers/pagination';
+import { PaginationWrapper } from 'components/main/paginationWrapper';
+import { organizationsListPaginationSelector } from 'controllers/instance/organizations';
+import {
+ DEFAULT_LIMITATION,
+ DEFAULT_PAGE_SIZE_OPTIONS,
+} from 'controllers/instance/organizations/constants';
+import styles from './organizationsPanelView.scss';
+import { OrganizationCard } from './organizationCard';
+
+const cx = classNames.bind(styles);
+
+const OrganizationsPanelViewWrapped = ({
+ organizationsList,
+ pageSize,
+ activePage,
+ itemCount,
+ pageCount,
+ onChangePage,
+ onChangePageSize,
+}) => (
+ 0}
+ pageSize={pageSize}
+ activePage={activePage}
+ totalItems={itemCount}
+ totalPages={pageCount}
+ pageSizeOptions={DEFAULT_PAGE_SIZE_OPTIONS}
+ changePage={onChangePage}
+ changePageSize={onChangePageSize}
+ >
+
+ {organizationsList.map((organization) => (
+
+ ))}
+
+
+);
+
+OrganizationsPanelViewWrapped.propTypes = {
+ organizationsList: PropTypes.array,
+ pageSize: PropTypes.number,
+ activePage: PropTypes.number,
+ itemCount: PropTypes.number.isRequired,
+ pageCount: PropTypes.number.isRequired,
+ onChangePage: PropTypes.func.isRequired,
+ onChangePageSize: PropTypes.func.isRequired,
+};
+
+OrganizationsPanelViewWrapped.defaultProps = {
+ organizationsList: [],
+ pageSize: DEFAULT_LIMITATION,
+ activePage: DEFAULT_PAGINATION[PAGE_KEY],
+};
+
+export const OrganizationsPanelView = withSortingURL({
+ defaultDirection: SORTING_ASC,
+})(
+ withPagination({
+ paginationSelector: organizationsListPaginationSelector,
+ })(OrganizationsPanelViewWrapped),
+);
diff --git a/app/src/controllers/organizations/constants.js b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationsPanelView.scss
similarity index 79%
rename from app/src/controllers/organizations/constants.js
rename to app/src/pages/instance/organizationsPage/organizationsPanelView/organizationsPanelView.scss
index ca55b9008f..222187af4f 100644
--- a/app/src/controllers/organizations/constants.js
+++ b/app/src/pages/instance/organizationsPage/organizationsPanelView/organizationsPanelView.scss
@@ -1,4 +1,4 @@
-/*
+/*!
* Copyright 2024 EPAM Systems
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,6 +14,11 @@
* limitations under the License.
*/
-export const NAMESPACE = 'organizations';
-
-export const FETCH_ORGANIZATIONS = 'fetchOrganizations';
+.organizations-list {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ flex-wrap: wrap;
+ gap: 24px;
+ padding-top: 24px;
+}
diff --git a/app/src/pages/instance/projectsPage/messages.js b/app/src/pages/instance/projectsPage/messages.js
deleted file mode 100644
index 78b7689334..0000000000
--- a/app/src/pages/instance/projectsPage/messages.js
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2019 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 { defineMessages } from 'react-intl';
-import { MEMBERS, MONITORING } from 'common/constants/projectSections';
-
-export const messages = defineMessages({
- statisticButtonTooltip: {
- id: 'ProjectStatisticButton.buttonTooltip',
- defaultMessage: 'See detailed information',
- },
- pageTitle: {
- id: 'ProjectsPage.title',
- defaultMessage: 'All projects',
- },
- addProject: {
- id: 'ProjectsPage.addProject',
- defaultMessage: 'Create Project',
- },
- addProjectTitle: {
- id: 'ProjectsPage.addProjectTitle',
- defaultMessage: 'Add project',
- },
- projectNameLabel: {
- id: 'ProjectsPage.projectNameLabel',
- defaultMessage: 'Name',
- },
- projectNamePlaceholder: {
- id: 'ProjectsPage.projectNamePlaceholder',
- defaultMessage: 'Enter project’s name',
- },
- projectLengthHint: {
- id: 'ProjectsPage.projectLengthHint',
- defaultMessage: 'Project name ',
- },
- [`${MEMBERS}HeaderButton`]: {
- id: 'ProjectDetailsPageMembers.headerButton',
- defaultMessage: 'Project Members',
- },
- [`${MONITORING}HeaderButton`]: {
- id: 'ProjectDetailsPageEvents.headerButton',
- defaultMessage: 'Project Monitoring',
- },
- deleteProjectsCount: {
- id: 'ProjectsPage.deleteProjectsCount',
- defaultMessage: '{count} items selected',
- },
- deleteModalHeader: {
- id: 'ProjectsPage.deleteModalHeader',
- defaultMessage: 'Delete project',
- },
- deleteModalMultipleHeader: {
- id: 'ProjectsPage.deleteModalMultipleHeader',
- defaultMessage: 'Delete projects',
- },
- deleteModalContent: {
- id: 'ProjectsPage.deleteModalContent',
- defaultMessage: 'Are you sure you want to delete the project {name}?',
- },
- deleteModalMultipleContent: {
- id: 'ProjectsPage.deleteModalMultipleContent',
- defaultMessage: 'Are you sure you want to delete the projects {names}?',
- },
- deleteError: {
- id: 'ProjectsPage.deleteError',
- defaultMessage: 'Error when deleting projects',
- },
- deleteSuccess: {
- id: 'ProjectsPage.deleteSuccess',
- defaultMessage: 'Project has been deleted',
- },
- deleteSuccessMultiple: {
- id: 'ProjectsPage.deleteSuccessMultiple',
- defaultMessage: 'Projects have been deleted',
- },
- deleteErrorMultiple: {
- id: 'ProjectsPage.deleteErrorMultiple',
- defaultMessage: 'Error when deleting projects',
- },
- members: {
- id: 'ProjectPanel.members',
- defaultMessage: 'Members',
- },
- settings: {
- id: 'ProjectPanel.settings',
- defaultMessage: 'Settings',
- },
- assign: {
- id: 'ProjectPanel.assign',
- defaultMessage: 'Assign',
- },
- unassign: {
- id: 'ProjectPanel.unassign',
- defaultMessage: 'Unassign',
- },
- delete: {
- id: 'ProjectPanel.delete',
- defaultMessage: 'Delete',
- },
- monitoring: {
- id: 'ProjectPanel.monitoring',
- defaultMessage: 'Monitoring',
- },
- unassignFromPersonal: {
- id: 'ProjectPanel.unassignFromPersonal',
- defaultMessage: 'Impossible to unassign user from personal project',
- },
- launchesQuantity: {
- id: 'ProjectPanel.launchesQuantity',
- defaultMessage: 'Launches',
- },
- membersQuantity: {
- id: 'ProjectPanel.membersQuantity',
- defaultMessage: 'Members',
- },
- linkedTooltip: {
- id: 'ProjectPanel.linkedTooltip',
- defaultMessage: 'Synced with UPSA',
- },
- personalTooltip: {
- id: 'ProjectPanel.personalTooltip',
- defaultMessage: 'Personal project',
- },
- personal: {
- id: 'ProjectPanel.personal',
- defaultMessage: 'Personal',
- },
- internalTooltip: {
- id: 'ProjectPanel.internalTooltip',
- defaultMessage: 'Internal project',
- },
- internal: {
- id: 'ProjectPanel.internal',
- defaultMessage: 'Internal',
- },
- noMembers: {
- id: 'ProjectPanel.noMembers',
- defaultMessage: 'No members',
- },
- noLaunches: {
- id: 'ProjectPanel.noLaunches',
- defaultMessage: 'No launches',
- },
- lastLaunch: {
- id: 'ProjectPanel.lastLaunch',
- defaultMessage: '{date} run',
- },
- searchPlaceholder: {
- id: 'ProjectsPage.searchPlaceholder',
- defaultMessage: 'Search by name',
- },
- nameCol: { id: 'ProjectsGrid.nameCol', defaultMessage: 'Name' },
- projectTypeCol: { id: 'ProjectsGrid.projectTypeCol', defaultMessage: 'Project Type' },
- organizationCol: { id: 'ProjectsGrid.organizationCol', defaultMessage: 'Organization' },
- membersCol: { id: 'ProjectsGrid.membersCol', defaultMessage: 'Members' },
- membersColShort: { id: 'ProjectsGrid.membersColShort', defaultMessage: 'Mmbrs' },
- launchesCol: { id: 'ProjectsGrid.launchesCol', defaultMessage: 'Launches' },
- launchesColShort: { id: 'ProjectsGrid.launchesColShort', defaultMessage: 'Lnchs' },
- lastLaunchCol: { id: 'ProjectsGrid.lastLaunchCol', defaultMessage: 'Last Launch date' },
- lastLaunchColShort: { id: 'ProjectsGrid.lastLaunchColShort', defaultMessage: 'Lnch date' },
- sortBy: { id: 'ProjectsPage.sortBy', defaultMessage: 'Sort by' },
- dateCol: { id: 'ProjectsPage.dateCol', defaultMessage: 'Date' },
-});
diff --git a/app/src/pages/instance/projectsPage/projectMenu/projectMenu.jsx b/app/src/pages/instance/projectsPage/projectMenu/projectMenu.jsx
deleted file mode 100644
index c0e78da4af..0000000000
--- a/app/src/pages/instance/projectsPage/projectMenu/projectMenu.jsx
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright 2019 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 { Component } from 'react';
-import PropTypes from 'prop-types';
-import { connect } from 'react-redux';
-import { injectIntl } from 'react-intl';
-import track from 'react-tracking';
-import {
- assignToProjectAction,
- unassignFromProjectAction,
- assignedProjectsSelector,
- userIdSelector,
-} from 'controllers/user';
-import { showModalAction } from 'controllers/modal';
-import { deleteProjectAction, navigateToProjectSectionAction } from 'controllers/instance/projects';
-import { fetchProjectSuccessAction } from 'controllers/project';
-import { MEMBERS, MONITORING } from 'common/constants/projectSections';
-import { DotsMenuButton, SEPARATOR_ITEM, DANGER_ITEM } from 'components/buttons/dotsMenuButton';
-import { ADMIN_PROJECTS_PAGE_EVENTS } from 'components/main/analytics/events';
-import { navigateToProjectSettingsAction } from 'controllers/instance/projects/actionCreators';
-import { fetch } from 'common/utils';
-import { URLS } from 'common/urls';
-import { messages } from '../messages';
-
-@connect(
- (state, ownProps) => ({
- isAssigned: !!assignedProjectsSelector(state)[ownProps.project.projectName],
- userId: userIdSelector(state),
- }),
- {
- showModal: showModalAction,
- assignToProject: assignToProjectAction,
- unassignFromProject: unassignFromProjectAction,
- deleteProject: deleteProjectAction,
- navigateToProjectSection: navigateToProjectSectionAction,
- navigateToProjectSettings: navigateToProjectSettingsAction,
- fetchProjectSuccess: fetchProjectSuccessAction,
- },
-)
-@injectIntl
-@track()
-export class ProjectMenu extends Component {
- static propTypes = {
- project: PropTypes.object.isRequired,
- intl: PropTypes.object.isRequired,
- isAssigned: PropTypes.bool.isRequired,
- userId: PropTypes.string.isRequired,
- navigateToProjectSection: PropTypes.func.isRequired,
- navigateToProjectSettings: PropTypes.func.isRequired,
- fetchProjectSuccess: PropTypes.func.isRequired,
- assignToProject: PropTypes.func.isRequired,
- unassignFromProject: PropTypes.func.isRequired,
- deleteProject: PropTypes.func.isRequired,
- showModal: PropTypes.func.isRequired,
- tracking: PropTypes.shape({
- trackEvent: PropTypes.func,
- getTrackingData: PropTypes.func,
- }).isRequired,
- };
-
- onAssign = () => {
- const { assignToProject, project, tracking } = this.props;
- tracking.trackEvent(ADMIN_PROJECTS_PAGE_EVENTS.ASSIGN_ACTION);
- assignToProject(project);
- };
-
- onUnassign = () => {
- const { unassignFromProject, project, tracking } = this.props;
- tracking.trackEvent(ADMIN_PROJECTS_PAGE_EVENTS.UNASSIGN_ACTION);
- unassignFromProject(project);
- };
-
- onDelete = () => {
- const { showModal, intl, userId, project, tracking } = this.props;
- const { projectName } = project;
- tracking.trackEvent(ADMIN_PROJECTS_PAGE_EVENTS.DELETE_PROJECT_BTN);
- showModal({
- id: 'deleteItemsModal',
- data: {
- items: [project],
- onConfirm: this.onDeleteSubmit,
- header: intl.formatMessage(messages.deleteModalHeader),
- mainContent: intl.formatMessage(messages.deleteModalContent, {
- name: `'${projectName} '`,
- }),
- userId,
- eventsInfo: {
- closeIcon: ADMIN_PROJECTS_PAGE_EVENTS.CLOSE_ICON_DELETE_MODAL,
- cancelBtn: ADMIN_PROJECTS_PAGE_EVENTS.CANCEL_BTN_DELETE_MODAL,
- deleteBtn: ADMIN_PROJECTS_PAGE_EVENTS.DELETE_BTN_DELETE_MODAL,
- },
- },
- });
- };
-
- onDeleteSubmit = () => {
- this.props.deleteProject(this.props.project);
- };
-
- getMenuItems = () => {
- const { intl, project, isAssigned, userId } = this.props;
- const isPersonalProject = project.projectName === `${userId}_personal`;
- return [
- {
- onClick: this.navigateToMembers,
- label: intl.formatMessage(messages.members),
- value: 'action-members',
- },
- {
- onClick: this.navigateToEventsMonitoring,
- label: intl.formatMessage(messages.monitoring),
- value: 'action-monitoring',
- },
- {
- onClick: this.navigateToSettings,
- label: intl.formatMessage(messages.settings),
- value: 'action-settings',
- },
- {
- type: SEPARATOR_ITEM,
- },
- {
- onClick: this.onUnassign,
- label: intl.formatMessage(messages.unassign),
- value: 'action-unassign',
- hidden: !isAssigned,
- disabled: isPersonalProject,
- title: isPersonalProject ? intl.formatMessage(messages.unassignFromPersonal) : '',
- },
- {
- onClick: this.onAssign,
- label: intl.formatMessage(messages.assign),
- value: 'action-assign',
- hidden: isAssigned,
- },
- {
- onClick: this.onDelete,
- label: intl.formatMessage(messages.delete),
- value: 'action-delete',
- type: DANGER_ITEM,
- },
- ];
- };
-
- navigateWithFetchProject = (projectKey, payload, path) => {
- fetch(URLS.projectByName(projectKey)).then((project) => {
- this.props.fetchProjectSuccess(project);
- this.props.navigateToProjectSection(payload, path);
- });
- };
-
- navigateToMembers = () => {
- const {
- tracking: { trackEvent },
- project: { organizationSlug, projectSlug, projectKey },
- } = this.props;
-
- trackEvent(ADMIN_PROJECTS_PAGE_EVENTS.MEMBERS_ACTION);
- this.navigateWithFetchProject(projectKey, { organizationSlug, projectSlug }, MEMBERS);
- };
-
- navigateToSettings = () => {
- const {
- tracking: { trackEvent },
- project: { organizationSlug, projectSlug },
- } = this.props;
-
- trackEvent(ADMIN_PROJECTS_PAGE_EVENTS.SETTINGS_ACTION);
- this.props.navigateToProjectSettings({ organizationSlug, projectSlug });
- };
-
- navigateToEventsMonitoring = () => {
- const {
- tracking: { trackEvent },
- project: { organizationSlug, projectSlug, projectKey },
- } = this.props;
-
- trackEvent(ADMIN_PROJECTS_PAGE_EVENTS.CLICK_EVENT_MONITORING);
- this.navigateWithFetchProject(projectKey, { organizationSlug, projectSlug }, MONITORING);
- };
-
- render() {
- return (
- this.props.tracking.trackEvent(ADMIN_PROJECTS_PAGE_EVENTS.PROJECT_MENU)}
- />
- );
- }
-}
diff --git a/app/src/pages/instance/projectsPage/projectName/projectName.jsx b/app/src/pages/instance/projectsPage/projectName/projectName.jsx
deleted file mode 100644
index e293510ef2..0000000000
--- a/app/src/pages/instance/projectsPage/projectName/projectName.jsx
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2019 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, { Component } from 'react';
-import track from 'react-tracking';
-import classNames from 'classnames/bind';
-import PropTypes from 'prop-types';
-import Link from 'redux-first-router-link';
-import { connect } from 'react-redux';
-import { ADMIN_PROJECTS_PAGE_EVENTS } from 'components/main/analytics/events';
-import { SCREEN_XS_MAX_MEDIA } from 'common/constants/screenSizeVariables';
-import { navigateToProjectAction } from 'controllers/instance/projects';
-import { PROJECT_PAGE } from 'controllers/pages';
-import { assignedProjectsSelector } from 'controllers/user';
-import styles from './projectName.scss';
-
-const cx = classNames.bind(styles);
-
-@connect(
- (state, ownProps) => ({
- isAssigned: !!assignedProjectsSelector(state)[ownProps.project.projectKey],
- }),
- {
- navigateToProject: navigateToProjectAction,
- },
-)
-@track()
-export class ProjectName extends Component {
- static propTypes = {
- project: PropTypes.object.isRequired,
- navigateToProject: PropTypes.func.isRequired,
- isAssigned: PropTypes.bool,
- tracking: PropTypes.shape({
- trackEvent: PropTypes.func,
- getTrackingData: PropTypes.func,
- }).isRequired,
- disableAnalytics: PropTypes.bool,
- };
-
- static defaultProps = {
- isAssigned: false,
- disableAnalytics: false,
- };
-
- onProjectClick = (event) => {
- const { tracking, isAssigned, disableAnalytics } = this.props;
- if (!isAssigned && window.matchMedia(SCREEN_XS_MAX_MEDIA).matches) {
- event.preventDefault();
- return;
- }
- this.props.navigateToProject({
- project: this.props.project,
- });
- if (!disableAnalytics) {
- tracking.trackEvent(ADMIN_PROJECTS_PAGE_EVENTS.PROJECT_NAME);
- }
- event.preventDefault();
- };
-
- render() {
- const {
- project: { projectSlug, organizationSlug, projectName },
- isAssigned,
- } = this.props;
-
- return (
-
- {projectName}
-
- );
- }
-}
diff --git a/app/src/pages/instance/projectsPage/projectName/projectName.scss b/app/src/pages/instance/projectsPage/projectName/projectName.scss
deleted file mode 100644
index 5faa7f726c..0000000000
--- a/app/src/pages/instance/projectsPage/projectName/projectName.scss
+++ /dev/null
@@ -1,31 +0,0 @@
-/*!
- * Copyright 2019 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.
- */
-
-.name {
- font-family: $FONT-REGULAR;
- text-decoration: none;
- color: $COLOR--topaz;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- cursor: pointer;
- &.mobile-disabled {
- @media (max-width: $SCREEN_XS_MAX) {
- cursor: default;
- color: $COLOR--black-2;
- }
- }
-}
diff --git a/app/src/pages/instance/projectsPage/projectStatisticButton/projectStatisticButton.jsx b/app/src/pages/instance/projectsPage/projectStatisticButton/projectStatisticButton.jsx
deleted file mode 100644
index 28d158d8ca..0000000000
--- a/app/src/pages/instance/projectsPage/projectStatisticButton/projectStatisticButton.jsx
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2019 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 PropTypes from 'prop-types';
-import Link from 'redux-first-router-link';
-import React from 'react';
-import { PROJECT_DETAILS_PAGE } from 'controllers/pages';
-import { Icon } from 'components/main/icon/icon';
-import { useIntl } from 'react-intl';
-import { messages } from '../messages';
-
-export const ProjectStatisticButton = ({ projectSlug, onClick, organizationSlug }) => {
- const { formatMessage } = useIntl();
- return (
-
-
-
- );
-};
-
-ProjectStatisticButton.propTypes = {
- projectSlug: PropTypes.string.isRequired,
- organizationSlug: PropTypes.string.isRequired,
- onClick: PropTypes.func,
-};
-
-ProjectStatisticButton.defaultProps = {
- onClick: () => {},
-};
diff --git a/app/src/pages/instance/projectsPage/projects/projects.jsx b/app/src/pages/instance/projectsPage/projects/projects.jsx
deleted file mode 100644
index f0329a2510..0000000000
--- a/app/src/pages/instance/projectsPage/projects/projects.jsx
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright 2019 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, { Component } from 'react';
-import PropTypes from 'prop-types';
-import { connect } from 'react-redux';
-import { injectIntl } from 'react-intl';
-import track from 'react-tracking';
-
-import { SIZE_KEY, withPagination, PAGE_KEY } from 'controllers/pagination';
-import { SORTING_ASC, withSortingURL } from 'controllers/sorting';
-import {
- DEFAULT_PAGINATION,
- TABLE_VIEW,
- GRID_VIEW,
- projectsPaginationSelector,
- viewModeSelector,
- loadingSelector,
- projectsSelector,
- DEFAULT_SORT_COLUMN,
- unselectAllProjectsAction,
-} from 'controllers/instance/projects';
-import { COMMON_LOCALE_KEYS } from 'common/constants/localization';
-import { PaginationToolbar } from 'components/main/paginationToolbar';
-import { NoItemMessage } from 'components/main/noItemMessage';
-import { ADMIN_PROJECTS_PAGE_EVENTS } from 'components/main/analytics/events';
-
-import { ProjectsPanelView } from '../projectsPanelView';
-import { ProjectsGrid } from '../projectsGrid';
-import { ProjectsToolbar } from '../projectsToolbar';
-
-@connect(
- (state) => ({
- viewMode: viewModeSelector(state),
- loading: loadingSelector(state),
- projects: projectsSelector(state),
- }),
- {
- unselectAllProjectsAction,
- },
-)
-@withSortingURL({
- defaultFields: [DEFAULT_SORT_COLUMN],
- defaultDirection: SORTING_ASC,
-})
-@withPagination({
- paginationSelector: projectsPaginationSelector,
-})
-@injectIntl
-@track()
-export class Projects extends Component {
- static propTypes = {
- activePage: PropTypes.number,
- itemCount: PropTypes.number,
- pageCount: PropTypes.number,
- pageSize: PropTypes.number,
- onChangePage: PropTypes.func.isRequired,
- onChangePageSize: PropTypes.func.isRequired,
- sortingColumn: PropTypes.string,
- sortingDirection: PropTypes.string,
- onChangeSorting: PropTypes.func,
- intl: PropTypes.object.isRequired,
- viewMode: PropTypes.string,
- loading: PropTypes.bool,
- projects: PropTypes.arrayOf(PropTypes.object),
- unselectAllProjectsAction: PropTypes.func.isRequired,
- tracking: PropTypes.shape({
- trackEvent: PropTypes.func,
- getTrackingData: PropTypes.func,
- }).isRequired,
- };
-
- static defaultProps = {
- activePage: DEFAULT_PAGINATION[PAGE_KEY],
- itemCount: null,
- pageCount: null,
- pageSize: DEFAULT_PAGINATION[SIZE_KEY],
- viewMode: GRID_VIEW,
- loading: false,
- projects: [],
- sortingColumn: null,
- sortingDirection: null,
- onChangeSorting: () => {},
- };
-
- componentWillUnmount() {
- this.props.unselectAllProjectsAction();
- }
-
- handleChangeSorting = (field) => {
- this.props.onChangeSorting(field);
- this.props.tracking.trackEvent(ADMIN_PROJECTS_PAGE_EVENTS.CHANGE_SORTING);
- };
-
- render() {
- const {
- activePage,
- itemCount,
- pageCount,
- pageSize,
- onChangePage,
- onChangePageSize,
- viewMode,
- loading,
- intl,
- projects,
- sortingColumn,
- sortingDirection,
- } = this.props;
-
- return (
-
-
-
- {viewMode === TABLE_VIEW ? (
-
- ) : (
-
- )}
-
- {!!pageCount && !loading && (
-
- )}
- {!projects.length && !loading && (
-
- )}
-
- );
- }
-}
diff --git a/app/src/pages/instance/projectsPage/projectsGrid/projectsGrid.jsx b/app/src/pages/instance/projectsPage/projectsGrid/projectsGrid.jsx
deleted file mode 100644
index 6e14e09e1f..0000000000
--- a/app/src/pages/instance/projectsPage/projectsGrid/projectsGrid.jsx
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright 2019 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, { PureComponent } from 'react';
-import { connect } from 'react-redux';
-import PropTypes from 'prop-types';
-import { injectIntl } from 'react-intl';
-import classNames from 'classnames/bind';
-import { Grid } from 'components/main/grid';
-import {
- loadingSelector,
- projectsSelector,
- selectedProjectsSelector,
- toggleAllProjectsAction,
- toggleProjectSelectionAction,
-} from 'controllers/instance/projects';
-import {
- NAME,
- TYPE,
- ORGANIZATION,
- USERS_QUANTITY,
- LAST_RUN,
- LAUNCHES_QUANTITY,
-} from 'common/constants/projectsObjectTypes';
-import {
- NameColumn,
- ProjectTypeColumn,
- OrganizationColumn,
- MembersColumn,
- LaunchesColumn,
- LastLaunchColumn,
- MenuColumn,
- StatisticColumn,
-} from './projectsGridColumns';
-
-import styles from './projectsGrid.scss';
-import { messages } from '../messages';
-
-const cx = classNames.bind(styles);
-
-const STATISTIC_COLUMN = 'statistic';
-const MENU_COLUMN = 'menu';
-
-@connect(
- (state) => ({
- projects: projectsSelector(state),
- loading: loadingSelector(state),
- selectedProjects: selectedProjectsSelector(state),
- }),
- {
- toggleProjectSelectionAction,
- toggleAllProjectsAction,
- },
-)
-@injectIntl
-export class ProjectsGrid extends PureComponent {
- static propTypes = {
- intl: PropTypes.object.isRequired,
- projects: PropTypes.arrayOf(PropTypes.object),
- selectedProjects: PropTypes.arrayOf(PropTypes.object),
- loading: PropTypes.bool,
- toggleProjectSelectionAction: PropTypes.func.isRequired,
- toggleAllProjectsAction: PropTypes.func.isRequired,
- sortingColumn: PropTypes.string,
- sortingDirection: PropTypes.string,
- onChangeSorting: PropTypes.func,
- };
-
- static defaultProps = {
- projects: [],
- selectedProjects: [],
- loading: false,
- sortingColumn: null,
- sortingDirection: null,
- onChangeSorting: () => {},
- };
-
- getColumns = () => [
- {
- id: STATISTIC_COLUMN,
- component: StatisticColumn,
- },
- {
- id: NAME,
- title: {
- full: this.props.intl.formatMessage(messages.nameCol),
- },
- maxHeight: 170,
- component: NameColumn,
- sortable: true,
- },
- {
- id: TYPE,
- title: {
- full: this.props.intl.formatMessage(messages.projectTypeCol),
- },
- component: ProjectTypeColumn,
- sortable: true,
- },
- {
- id: ORGANIZATION,
- title: {
- full: this.props.intl.formatMessage(messages.organizationCol),
- },
- component: OrganizationColumn,
- sortable: true,
- },
- {
- id: USERS_QUANTITY,
- title: {
- full: this.props.intl.formatMessage(messages.membersCol),
- short: this.props.intl.formatMessage(messages.membersColShort),
- },
- component: MembersColumn,
- sortable: true,
- },
- {
- id: LAUNCHES_QUANTITY,
- title: {
- full: this.props.intl.formatMessage(messages.launchesCol),
- short: this.props.intl.formatMessage(messages.launchesColShort),
- },
- component: LaunchesColumn,
- sortable: true,
- },
- {
- id: LAST_RUN,
- title: {
- full: this.props.intl.formatMessage(messages.lastLaunchCol),
- short: this.props.intl.formatMessage(messages.lastLaunchColShort),
- },
- component: LastLaunchColumn,
- sortable: true,
- },
- {
- id: MENU_COLUMN,
- component: MenuColumn,
- },
- ];
-
- COLUMNS = this.getColumns();
-
- render() {
- const {
- projects,
- loading,
- selectedProjects,
- sortingColumn,
- sortingDirection,
- onChangeSorting,
- } = this.props;
-
- return (
- this.props.toggleAllProjectsAction(projects)}
- className={cx('projects-grid')}
- gridRowClassName={cx('projects-grid-row')}
- headerClassName={cx('projects-header')}
- sortingColumn={sortingColumn}
- sortingDirection={sortingDirection}
- onChangeSorting={onChangeSorting}
- />
- );
- }
-}
diff --git a/app/src/pages/instance/projectsPage/projectsGrid/projectsGrid.scss b/app/src/pages/instance/projectsPage/projectsGrid/projectsGrid.scss
deleted file mode 100644
index 5d29d44e19..0000000000
--- a/app/src/pages/instance/projectsPage/projectsGrid/projectsGrid.scss
+++ /dev/null
@@ -1,115 +0,0 @@
-/*!
- * Copyright 2019 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.
- */
-
-.projects-col {
- font-size: 13px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.project-type-col {
- &:first-letter {
- text-transform: capitalize;
- }
-}
-
-.projects-grid {
- @media (max-width: $SCREEN_SM_MAX) {
- table-layout: fixed;
- }
-}
-
-.projects-grid-row {
- > :first-child {
- width: 1%;
- }
- > :last-child {
- padding-top: 22px;
- }
- > :nth-child(2) {
- max-width: 0;
- }
- > :nth-child(4) {
- max-width: 0;
- }
- > :nth-child(7) {
- width: 12%;
- white-space: pre-wrap;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- @media (max-width: $SCREEN_SM_MAX) {
- display: table-row;
- > :nth-child(3),
- > :nth-child(4) {
- display: none;
- }
- }
-}
-
-.projects-header {
- > :first-child {
- width: 1%;
- min-width: 20px;
- }
- > :nth-child(2) {
- width: 30%;
- }
- > :nth-child(3),
- > :nth-child(4) {
- width: 15%;
- }
-
- > :nth-child(5),
- > :nth-child(6) {
- width: 10%;
- }
-
- > :nth-child(7) {
- width: 15%;
- }
- > :nth-child(8),
- > :nth-child(9) {
- min-width: 20px;
- }
- @media (max-width: $SCREEN_SM_MAX) {
- display: table-row;
- > :first-child {
- width: 10%;
- min-width: 20px;
- }
- > :nth-child(2) {
- width: 25%;
- }
- > :nth-child(3),
- > :nth-child(4) {
- display: none;
- }
-
- > :nth-child(5),
- > :nth-child(6) {
- width: 14%;
- }
-
- > :nth-child(7) {
- width: 25%;
- }
- > :nth-child(8) {
- min-width: 12%;
- }
- }
-}
diff --git a/app/src/pages/instance/projectsPage/projectsGrid/projectsGridColumns.jsx b/app/src/pages/instance/projectsPage/projectsGrid/projectsGridColumns.jsx
deleted file mode 100644
index 9e6d258f64..0000000000
--- a/app/src/pages/instance/projectsPage/projectsGrid/projectsGridColumns.jsx
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2019 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 PropTypes from 'prop-types';
-import { FormattedMessage } from 'react-intl';
-import classNames from 'classnames/bind';
-import { AbsRelTime } from 'components/main/absRelTime';
-import styles from './projectsGrid.scss';
-import { ProjectMenu } from '../projectMenu';
-import { ProjectStatisticButton } from '../projectStatisticButton';
-import { ProjectName } from '../projectName';
-
-const cx = classNames.bind(styles);
-
-export const NameColumn = ({ className, value }) => (
-
-);
-NameColumn.propTypes = {
- className: PropTypes.string.isRequired,
- value: PropTypes.object,
-};
-NameColumn.defaultProps = {
- value: {},
-};
-
-export const ProjectTypeColumn = ({ className, value }) => (
-
- {value.entryType.toLowerCase()}
-
-);
-ProjectTypeColumn.propTypes = {
- className: PropTypes.string.isRequired,
- value: PropTypes.object,
-};
-ProjectTypeColumn.defaultProps = {
- value: {},
-};
-
-export const OrganizationColumn = ({ className, value }) => (
-
- {value.organization}
-
-);
-OrganizationColumn.propTypes = {
- className: PropTypes.string.isRequired,
- value: PropTypes.object,
-};
-OrganizationColumn.defaultProps = {
- value: {},
-};
-
-export const MembersColumn = ({ className, value }) => (
- {value.usersQuantity}
-);
-MembersColumn.propTypes = {
- className: PropTypes.string.isRequired,
- value: PropTypes.object,
-};
-MembersColumn.defaultProps = {
- value: {},
-};
-
-export const LaunchesColumn = ({ className, value }) => (
- {value.launchesQuantity}
-);
-LaunchesColumn.propTypes = {
- className: PropTypes.string.isRequired,
- value: PropTypes.object,
-};
-LaunchesColumn.defaultProps = {
- value: {},
-};
-
-export const LastLaunchColumn = ({ className, value }) => (
-
- {value.lastRun ? (
-
- ) : (
-
- )}
-
-);
-LastLaunchColumn.propTypes = {
- className: PropTypes.string.isRequired,
- value: PropTypes.object,
-};
-LastLaunchColumn.defaultProps = {
- value: {},
-};
-
-export const MenuColumn = ({ className, value }) => (
-
-);
-MenuColumn.propTypes = {
- className: PropTypes.string.isRequired,
- value: PropTypes.object,
-};
-MenuColumn.defaultProps = {
- value: {},
-};
-
-export const StatisticColumn = ({ className, value }) => (
-
-);
-StatisticColumn.propTypes = {
- className: PropTypes.string.isRequired,
- value: PropTypes.object,
-};
-StatisticColumn.defaultProps = {
- value: {},
-};
diff --git a/app/src/pages/instance/projectsPage/projectsPage.jsx b/app/src/pages/instance/projectsPage/projectsPage.jsx
deleted file mode 100644
index 346015091f..0000000000
--- a/app/src/pages/instance/projectsPage/projectsPage.jsx
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright 2019 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, { Component } from 'react';
-import PropTypes from 'prop-types';
-import { connect } from 'react-redux';
-import { injectIntl } from 'react-intl';
-import classNames from 'classnames/bind';
-import track from 'react-tracking';
-import { ADMIN_PROJECTS_PAGE_EVENTS, ADMIN_PROJECTS_PAGE } from 'components/main/analytics/events';
-import { PageLayout, PageHeader, PageSection } from 'layouts/pageLayout';
-import {
- PROJECTS_PAGE,
- PROJECT_DETAILS_PAGE,
- projectSectionSelector,
- urlProjectSlugSelector,
- urlOrganizationSlugSelector,
-} from 'controllers/pages';
-import { showModalAction } from 'controllers/modal';
-import { MEMBERS, MONITORING } from 'common/constants/projectSections';
-import { GhostButton } from 'components/buttons/ghostButton';
-import AddProjectIcon from 'common/img/add-project-inline.svg';
-import ProjectUsersIcon from 'common/img/project-users-inline.svg';
-import ProjectMonitoringIcon from 'common/img/project-monitoring-inline.svg';
-import { MembersPage } from 'pages/common/membersPage';
-import { addProjectAction, navigateToProjectSectionAction } from 'controllers/instance/projects';
-import { projectNameSelector, projectKeySelector } from 'controllers/project';
-import { ProjectStatusPage } from '../projectStatusPage';
-import { ProjectEventsPage } from '../projectEventsPage';
-import { Projects } from './projects';
-import { messages } from './messages';
-import styles from './projectsPage.scss';
-
-const cx = classNames.bind(styles);
-
-const HEADER_BUTTONS = [
- {
- key: MONITORING,
- icon: ProjectMonitoringIcon,
- },
- {
- key: MEMBERS,
- icon: ProjectUsersIcon,
- },
-];
-
-@connect(
- (state) => ({
- projectSlug: urlProjectSlugSelector(state),
- organizationSlug: urlOrganizationSlugSelector(state),
- projectName: projectNameSelector(state),
- projectKey: projectKeySelector(state),
- section: projectSectionSelector(state),
- }),
- {
- addProject: addProjectAction,
- showModal: showModalAction,
- navigateToSection: navigateToProjectSectionAction,
- },
-)
-@injectIntl
-@track({ page: ADMIN_PROJECTS_PAGE })
-export class ProjectsPage extends Component {
- static propTypes = {
- intl: PropTypes.object.isRequired,
- navigateToSection: PropTypes.func.isRequired,
- addProject: PropTypes.func.isRequired,
- showModal: PropTypes.func.isRequired,
- section: PropTypes.string,
- tracking: PropTypes.shape({
- trackEvent: PropTypes.func,
- getTrackingData: PropTypes.func,
- }).isRequired,
- projectName: PropTypes.string.isRequired,
- projectKey: PropTypes.string.isRequired,
- organizationSlug: PropTypes.string.isRequired,
- projectSlug: PropTypes.string.isRequired,
- };
-
- static defaultProps = {
- section: undefined,
- };
-
- onHeaderButtonClick = (section) => () => {
- this.props.tracking.trackEvent(ADMIN_PROJECTS_PAGE_EVENTS.HEADER_BUTTON_CLICK(section));
- this.props.navigateToSection(
- {
- organizationSlug: this.props.organizationSlug,
- projectSlug: this.props.projectSlug,
- },
- section,
- );
- };
-
- getBreadcrumbs = () => {
- const {
- intl: { formatMessage },
- section,
- organizationSlug,
- projectSlug,
- projectName,
- } = this.props;
-
- const breadcrumbs = [
- {
- title: formatMessage(messages.pageTitle),
- link: {
- type: PROJECTS_PAGE,
- },
- },
- ];
-
- if (projectSlug) {
- breadcrumbs.push({
- title: projectName,
- link: {
- type: PROJECT_DETAILS_PAGE,
- payload: { projectSlug, projectSection: null, organizationSlug },
- },
- });
- }
-
- if (section) {
- breadcrumbs.push({
- title: formatMessage(messages[section]),
- });
- }
-
- return breadcrumbs;
- };
-
- showAddProjectModal = () => {
- this.props.tracking.trackEvent(ADMIN_PROJECTS_PAGE_EVENTS.ADD_PROJECT_BTN);
- this.props.showModal({
- id: 'addProjectModal',
- data: {
- onSubmit: (values) => this.props.addProject(values.projectName),
- eventsInfo: {
- addBtn: ADMIN_PROJECTS_PAGE_EVENTS.ADD_BTN_ADD_PROJECT_MODAL,
- closeIcon: ADMIN_PROJECTS_PAGE_EVENTS.CLOSE_ICON_ADD_PROJECT_MODAL,
- cancelBtn: ADMIN_PROJECTS_PAGE_EVENTS.CANCEL_BTN_ADD_PROJECT_MODAL,
- },
- },
- });
- };
-
- renderHeaderButtons = () => {
- const {
- intl: { formatMessage },
- projectSlug,
- section,
- } = this.props;
-
- if (!projectSlug) {
- return (
-
-
- {formatMessage(messages.addProject)}
-
-
- );
- }
-
- return (
-
- {HEADER_BUTTONS.map(({ key, icon }) => (
-
- {formatMessage(messages[`${key}HeaderButton`])}
-
- ))}
-
- );
- };
-
- renderSection = () => {
- const { projectSlug, projectKey, section } = this.props;
-
- if (!projectSlug) {
- return ;
- }
-
- switch (section) {
- case MEMBERS:
- return ;
- case MONITORING:
- return ;
- default:
- return ;
- }
- };
-
- render() {
- return (
-
- {this.renderHeaderButtons()}
- {this.renderSection()}
-
- );
- }
-}
diff --git a/app/src/pages/instance/projectsPage/projectsPage.scss b/app/src/pages/instance/projectsPage/projectsPage.scss
deleted file mode 100644
index e5e5bf5ab2..0000000000
--- a/app/src/pages/instance/projectsPage/projectsPage.scss
+++ /dev/null
@@ -1,28 +0,0 @@
-/*!
- * Copyright 2019 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.
- */
-
-.header-buttons {
- white-space: nowrap;
- button {
- margin-left: 10px;
- }
-}
-
-.mobile-hide {
- @media (max-width: $SCREEN_XS_MAX) {
- display: none;
- }
-}
diff --git a/app/src/pages/instance/projectsPage/projectsPanelView/index.js b/app/src/pages/instance/projectsPage/projectsPanelView/index.js
deleted file mode 100644
index 92e4e9f0fa..0000000000
--- a/app/src/pages/instance/projectsPage/projectsPanelView/index.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright 2019 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.
- */
-
-export { ProjectsPanelView } from './projectsPanelView';
diff --git a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/constants.js b/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/constants.js
deleted file mode 100644
index 48543e99e7..0000000000
--- a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/constants.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2019 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.
- */
-
-export const UPSA_PROJECT = 'UPSA';
-export const PERSONAL_PROJECT = 'PERSONAL';
-export const INTERNAL_PROJECT = 'INTERNAL';
diff --git a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/index.js b/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/index.js
deleted file mode 100644
index 967490054c..0000000000
--- a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/index.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright 2019 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.
- */
-
-export { ProjectPanel } from './projectPanel';
-export { ConfirmationModal } from 'pages/common/modals/confirmationModal';
diff --git a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/projectPanel.jsx b/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/projectPanel.jsx
deleted file mode 100644
index 9d2abc3501..0000000000
--- a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/projectPanel.jsx
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright 2019 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, { Component } from 'react';
-import track from 'react-tracking';
-import { ADMIN_PROJECTS_PAGE_EVENTS } from 'components/main/analytics/events';
-import { injectIntl } from 'react-intl';
-import classNames from 'classnames/bind';
-import PropTypes from 'prop-types';
-import { Icon } from 'components/main/icon/icon';
-import { getRelativeUnits } from 'common/utils/timeDateUtils';
-import { ProjectName } from 'pages/organization/organizationProjectsPage/projectsListTable/projectName';
-import { ProjectMenu } from '../../projectMenu';
-import { StatisticsItem } from './statisticsItem';
-import { ProjectTooltipIcon } from './projectTooltipIcon';
-import { ProjectStatisticButton } from '../../projectStatisticButton';
-import { UPSA_PROJECT, PERSONAL_PROJECT, INTERNAL_PROJECT } from './constants';
-import { messages } from '../../messages';
-import styles from './projectPanel.scss';
-
-const cx = classNames.bind(styles);
-
-@injectIntl
-@track()
-export class ProjectPanel extends Component {
- static propTypes = {
- project: PropTypes.object.isRequired,
- intl: PropTypes.object.isRequired,
- tracking: PropTypes.shape({
- trackEvent: PropTypes.func,
- getTrackingData: PropTypes.func,
- }).isRequired,
- };
-
- getProjectIcon() {
- const {
- intl,
- project: { entryType },
- } = this.props;
- switch (entryType) {
- case UPSA_PROJECT:
- return (
-
-
-
-
-
- );
- case PERSONAL_PROJECT:
- return (
-
-
-
-
-
- );
- default:
- return (
-
-
-
-
-
- );
- }
- }
- getOrganization() {
- const {
- intl,
- project: { entryType, organizationSlug },
- } = this.props;
- return (
- organizationSlug ||
- (entryType === PERSONAL_PROJECT && intl.formatMessage(messages.personal)) ||
- (entryType === INTERNAL_PROJECT && intl.formatMessage(messages.internal))
- );
- }
-
- render() {
- const {
- project: {
- projectSlug,
- entryType,
- lastRun,
- launchesQuantity,
- usersQuantity,
- organizationSlug,
- },
- intl,
- } = this.props;
- const { value: relativeTime, unit } = getRelativeUnits(new Date(lastRun).getTime());
-
- const organization = this.getOrganization();
- return (
-
-
-
- {this.getProjectIcon(entryType)}
-
- {organization}
-
-
-
-
-
-
- {lastRun && (
-
- {intl.formatMessage(messages.lastLaunch, {
- date: intl.formatRelativeTime(relativeTime, unit),
- })}
-
- )}
-
-
-
-
-
-
-
- this.props.tracking.trackEvent(ADMIN_PROJECTS_PAGE_EVENTS.STATISTIC_ICON)
- }
- />
-
-
-
- );
- }
-}
diff --git a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/projectPanel.scss b/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/projectPanel.scss
deleted file mode 100644
index 8074c9a132..0000000000
--- a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/projectPanel.scss
+++ /dev/null
@@ -1,82 +0,0 @@
-/*!
- * Copyright 2019 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.
- */
-
-.container {
- height: 160px;
- width: 100%;
- min-width: 200px;
- border-radius: 4px;
- box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.09);
- background-color: $COLOR--white-two;
-}
-
-.info-block {
- padding: 15px;
- text-align: left;
- height: 62px;
-}
-
-.header {
- display: flex;
- flex-wrap: nowrap;
- line-height: 1;
-}
-
-.header-item {
- flex: 0 0 auto;
-}
-
-.header-stretch-item {
- flex: 1 1 auto;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.hr {
- margin: 0px;
- display: block;
- height: 1px;
- border: 0;
- border-top: 1px solid $COLOR--gray-91;
- padding: 0;
-}
-
-.name {
- display: block;
- width: 100%;
- font-family: $FONT-REGULAR;
- font-size: 15px;
- line-height: 1.5;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.gray-text {
- width: 100%;
- height: 18px;
- font-family: $FONT-REGULAR;
- font-size: 12px;
- line-height: 1.5;
- color: $COLOR--gray-47;
-}
-
-.statistic-items {
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- align-items: flex-end;
-}
diff --git a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/projectTooltipIcon/index.js b/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/projectTooltipIcon/index.js
deleted file mode 100644
index 1a9f80ae02..0000000000
--- a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/projectTooltipIcon/index.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright 2019 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.
- */
-
-export { ProjectTooltipIcon } from './projectTooltipIcon';
diff --git a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/projectTooltipIcon/projectTooltipIcon.jsx b/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/projectTooltipIcon/projectTooltipIcon.jsx
deleted file mode 100644
index fdfe41fdc2..0000000000
--- a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/projectTooltipIcon/projectTooltipIcon.jsx
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2019 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 { Component } from 'react';
-import PropTypes from 'prop-types';
-import { withTooltip } from 'components/main/tooltips/tooltip';
-import { TextTooltip } from 'components/main/tooltips/textTooltip';
-
-@withTooltip({
- TooltipComponent: TextTooltip,
- data: {
- width: 180,
- noArrow: false,
- },
-})
-export class ProjectTooltipIcon extends Component {
- static propTypes = {
- children: PropTypes.node,
- };
- static defaultProps = {
- children: '',
- };
-
- render() {
- const { children } = this.props;
- return {children}
;
- }
-}
diff --git a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/statisticsItem/index.js b/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/statisticsItem/index.js
deleted file mode 100644
index 7eea752653..0000000000
--- a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/statisticsItem/index.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright 2019 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.
- */
-
-export { StatisticsItem } from './statisticsItem';
diff --git a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/statisticsItem/statisticsItem.jsx b/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/statisticsItem/statisticsItem.jsx
deleted file mode 100644
index a094be2a8d..0000000000
--- a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/statisticsItem/statisticsItem.jsx
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2019 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 PropTypes from 'prop-types';
-import classNames from 'classnames/bind';
-import styles from './statisticsItem.scss';
-
-const cx = classNames.bind(styles);
-export const StatisticsItem = ({ caption, value, emptyValueCaption }) => (
-
-
{caption}
- {value ? (
-
{value}
- ) : (
-
{emptyValueCaption}
- )}
-
-);
-
-StatisticsItem.propTypes = {
- caption: PropTypes.string.isRequired,
- value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
- emptyValueCaption: PropTypes.string,
-};
-
-StatisticsItem.defaultProps = {
- value: '0',
- emptyValueCaption: '-',
-};
diff --git a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/statisticsItem/statisticsItem.scss b/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/statisticsItem/statisticsItem.scss
deleted file mode 100644
index a2618ccddf..0000000000
--- a/app/src/pages/instance/projectsPage/projectsPanelView/projectPanel/statisticsItem/statisticsItem.scss
+++ /dev/null
@@ -1,37 +0,0 @@
-/*!
- * Copyright 2019 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.
- */
-
-.caption {
- font-family: $FONT-REGULAR;
- font-size: 12px;
- line-height: 1.5;
- color: $COLOR--gray-47;
-}
-
-.value {
- font-family: $FONT-REGULAR;
- font-size: 15px;
- line-height: 18px;
- color: $COLOR--black-2;
- height: 19px;
-}
-
-.empty-value {
- font-family: $FONT-REGULAR;
- font-size: 12px;
- line-height: 18px;
- color: $COLOR--black-2;
-}
diff --git a/app/src/pages/instance/projectsPage/projectsPanelView/projectsPanelView.jsx b/app/src/pages/instance/projectsPage/projectsPanelView/projectsPanelView.jsx
deleted file mode 100644
index c3958656e4..0000000000
--- a/app/src/pages/instance/projectsPage/projectsPanelView/projectsPanelView.jsx
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright 2019 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, { Component, Fragment } from 'react';
-import PropTypes from 'prop-types';
-import classNames from 'classnames/bind';
-import { connect } from 'react-redux';
-import { loadingSelector, projectsSelector } from 'controllers/instance/projects';
-import { organizationsListSelector } from 'controllers/organizations';
-import { SpinningPreloader } from 'components/preloaders/spinningPreloader';
-import { ProjectPanel } from './projectPanel';
-import styles from './projectsPanelView.scss';
-
-const cx = classNames.bind(styles);
-
-@connect((state) => ({
- organizations: organizationsListSelector(state),
- projects: projectsSelector(state),
- loading: loadingSelector(state),
-}))
-export class ProjectsPanelView extends Component {
- static propTypes = {
- organizations: PropTypes.array,
- projects: PropTypes.array,
- loading: PropTypes.bool,
- onMembers: PropTypes.func,
- onSettings: PropTypes.func,
- onAssign: PropTypes.func,
- onUnassign: PropTypes.func,
- onDelete: PropTypes.func,
- };
-
- static defaultProps = {
- organizations: [],
- projects: [],
- loading: false,
- onMembers: () => {},
- onSettings: () => {},
- onAssign: () => {},
- onUnassign: () => {},
- onDelete: () => {},
- };
-
- getPanelList = (projects) => {
- const { organizations } = this.props;
-
- return projects.map((project) => {
- const { organizationId } = project;
-
- const organizationSlug = organizations.find(({ id }) => id === Number(organizationId))?.slug;
- const projectWithOrganizationSlug = {
- ...project,
- organizationSlug,
- };
-
- return (
-
- );
- });
- };
-
- render() {
- const { projects, loading } = this.props;
- return (
-
- {loading && (
-
-
-
- )}
- {!loading &&
- (projects.length ? (
- {this.getPanelList(projects)}
- ) : (
- ''
- ))}
-
- );
- }
-}
diff --git a/app/src/pages/instance/projectsPage/projectsPanelView/projectsPanelView.scss b/app/src/pages/instance/projectsPage/projectsPanelView/projectsPanelView.scss
deleted file mode 100644
index 5fed59b1b3..0000000000
--- a/app/src/pages/instance/projectsPage/projectsPanelView/projectsPanelView.scss
+++ /dev/null
@@ -1,25 +0,0 @@
-/*!
- * Copyright 2019 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.
- */
-
-.panel-list {
- height: 100%;
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
- grid-gap: 30px 30px;
- flex-wrap: wrap;
- background-color: $COLOR--white-two;
- padding: 15px;
-}
diff --git a/app/src/pages/instance/projectsPage/projectsToolbar/index.js b/app/src/pages/instance/projectsPage/projectsToolbar/index.js
deleted file mode 100644
index d8d2e3de2f..0000000000
--- a/app/src/pages/instance/projectsPage/projectsToolbar/index.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright 2019 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.
- */
-
-export { ProjectsToolbar } from './projectsToolbar';
diff --git a/app/src/pages/instance/projectsPage/projectsToolbar/projectEntities.jsx b/app/src/pages/instance/projectsPage/projectsToolbar/projectEntities.jsx
deleted file mode 100644
index ee0f1e88ea..0000000000
--- a/app/src/pages/instance/projectsPage/projectsToolbar/projectEntities.jsx
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright 2019 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 { Component } from 'react';
-import PropTypes from 'prop-types';
-import { injectIntl, defineMessages } from 'react-intl';
-import { commonValidators } from 'common/utils/validation';
-import {
- EntityContains,
- EntityInputConditional,
- EntityDropdown,
- EntityItemStartTime,
-} from 'components/filterEntities';
-import {
- CONDITION_CNT,
- CONDITION_EQ,
- CONDITION_BETWEEN,
- CONDITION_GREATER_EQ,
- CONDITION_LESS_EQ,
- CONDITION_IN,
-} from 'components/filterEntities/constants';
-import { bindDefaultValue } from 'components/filterEntities/utils';
-import {
- PROJECT_TYPE_INTERNAL,
- PROJECT_TYPE_PERSONAL,
- PROJECT_TYPE_UPSA,
- TYPE,
- NAME,
- ORGANIZATION,
- USERS_QUANTITY,
- LAST_RUN,
- LAUNCHES_QUANTITY,
- PROJECTS,
-} from 'common/constants/projectsObjectTypes';
-import { ADMIN_PROJECTS_PAGE_EVENTS } from 'components/main/analytics/events';
-
-const messages = defineMessages({
- contains: { id: 'projectsGrid.contains', defaultMessage: 'Contains' },
- type: { id: 'projectsGrid.type', defaultMessage: 'Type' },
- lastRun: {
- id: 'projectsGrid.lastRun',
- defaultMessage: 'Last run',
- },
- numberOfLaunches: {
- id: 'projectsGrid.numberOfLaunches',
- defaultMessage: 'Launches',
- },
- numberOfMembers: {
- id: 'projectsGrid.numberOfMembers',
- defaultMessage: 'Members',
- },
- organizationName: {
- id: 'projectsGrid.organizationName',
- defaultMessage: 'Organization ',
- },
- projectTypeInternal: {
- id: 'projectsGrid.projectTypeInternal',
- defaultMessage: 'Internal',
- },
- projectName: {
- id: 'projectsGrid.projectName',
- defaultMessage: 'Project',
- },
- projectTypePersonal: {
- id: 'projectsGrid.projectTypePersonal',
- defaultMessage: 'Personal',
- },
- projectTypeUpsa: {
- id: 'projectsGrid.projectTypeUpsa',
- defaultMessage: 'UPSA',
- },
-});
-
-@injectIntl
-export class ProjectEntities extends Component {
- static propTypes = {
- intl: PropTypes.object.isRequired,
- filterValues: PropTypes.object,
- render: PropTypes.func.isRequired,
- };
-
- static defaultProps = {
- filterValues: {},
- };
- getEntities = () => {
- const { intl } = this.props;
- return [
- {
- id: PROJECTS,
- component: EntityContains,
- value: this.bindDefaultValue(PROJECTS),
- title: intl.formatMessage(messages.contains),
- active: true,
- removable: false,
- },
- {
- id: TYPE,
- component: EntityDropdown,
- value: this.bindDefaultValue(TYPE, {
- condition: CONDITION_IN,
- }),
- title: intl.formatMessage(messages.type),
- active: true,
- removable: false,
- customProps: {
- options: [
- {
- label: intl.formatMessage(messages.projectTypeInternal),
- value: PROJECT_TYPE_INTERNAL,
- },
- {
- label: intl.formatMessage(messages.projectTypePersonal),
- value: PROJECT_TYPE_PERSONAL,
- },
- {
- label: intl.formatMessage(messages.projectTypeUpsa),
- value: PROJECT_TYPE_UPSA,
- },
- ],
- multiple: true,
- selectAll: true,
- },
- },
- {
- id: LAST_RUN,
- component: EntityItemStartTime,
- value: this.bindDefaultValue(LAST_RUN, {
- value: '',
- condition: CONDITION_BETWEEN,
- }),
- title: intl.formatMessage(messages.lastRun),
- active: true,
- removable: false,
- customProps: {
- withoutDynamic: true,
- events: ADMIN_PROJECTS_PAGE_EVENTS.REFINE_FILTERS_PANEL_EVENTS.commonEvents,
- },
- },
- {
- id: LAUNCHES_QUANTITY,
- component: EntityInputConditional,
- value: this.bindDefaultValue(LAUNCHES_QUANTITY, {
- condition: CONDITION_GREATER_EQ,
- }),
- validationFunc: commonValidators.launchNumericEntity,
- title: intl.formatMessage(messages.numberOfLaunches),
- active: true,
- removable: false,
- customProps: {
- conditions: [CONDITION_EQ, CONDITION_GREATER_EQ, CONDITION_LESS_EQ],
- placeholder: null,
- maxLength: 18,
- },
- },
- {
- id: USERS_QUANTITY,
- component: EntityInputConditional,
- value: this.bindDefaultValue(USERS_QUANTITY, {
- condition: CONDITION_GREATER_EQ,
- }),
- validationFunc: commonValidators.launchNumericEntity,
- title: intl.formatMessage(messages.numberOfMembers),
- active: true,
- removable: false,
- customProps: {
- conditions: [CONDITION_EQ, CONDITION_GREATER_EQ, CONDITION_LESS_EQ],
- placeholder: null,
- maxLength: 18,
- },
- },
- {
- id: NAME,
- component: EntityInputConditional,
- value: this.bindDefaultValue(NAME, {
- condition: CONDITION_CNT,
- }),
- title: intl.formatMessage(messages.projectName),
- active: true,
- removable: false,
- customProps: {
- placeholder: null,
- maxLength: 256,
- },
- },
- {
- id: ORGANIZATION,
- component: EntityInputConditional,
- value: this.bindDefaultValue(ORGANIZATION, {
- condition: CONDITION_CNT,
- }),
- title: intl.formatMessage(messages.organizationName),
- active: true,
- removable: false,
- customProps: {
- placeholder: null,
- maxLength: 256,
- },
- },
- ];
- };
- bindDefaultValue = bindDefaultValue;
- render() {
- const { render, ...rest } = this.props;
- return render({
- ...rest,
- filterEntities: this.getEntities(),
- });
- }
-}
diff --git a/app/src/pages/instance/projectsPage/projectsToolbar/projectsSorting/index.js b/app/src/pages/instance/projectsPage/projectsToolbar/projectsSorting/index.js
deleted file mode 100644
index f3547dfc69..0000000000
--- a/app/src/pages/instance/projectsPage/projectsToolbar/projectsSorting/index.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright 2019 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.
- */
-
-export { ProjectsSorting } from './projectsSorting';
diff --git a/app/src/pages/instance/projectsPage/projectsToolbar/projectsSorting/projectsSorting.jsx b/app/src/pages/instance/projectsPage/projectsToolbar/projectsSorting/projectsSorting.jsx
deleted file mode 100644
index b94f4bebe6..0000000000
--- a/app/src/pages/instance/projectsPage/projectsToolbar/projectsSorting/projectsSorting.jsx
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 2019 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, { Component } from 'react';
-import PropTypes from 'prop-types';
-import { injectIntl } from 'react-intl';
-import classNames from 'classnames/bind';
-import { SORTING_ASC } from 'controllers/sorting';
-import { InputDropdownSorting } from 'components/inputs/inputDropdownSorting';
-import {
- CREATION_DATE,
- NAME,
- TYPE,
- ORGANIZATION,
- USERS_QUANTITY,
- LAST_RUN,
- LAUNCHES_QUANTITY,
-} from 'common/constants/projectsObjectTypes';
-import styles from './projectsSorting.scss';
-import { messages } from '../../messages';
-
-const cx = classNames.bind(styles);
-
-@injectIntl
-export class ProjectsSorting extends Component {
- static propTypes = {
- intl: PropTypes.object,
- sortingColumn: PropTypes.string,
- sortingDirection: PropTypes.string,
- onChangeSorting: PropTypes.func,
- };
-
- static defaultProps = {
- intl: {},
- sortingColumn: null,
- sortingDirection: SORTING_ASC,
- onChangeSorting: () => {},
- };
-
- getSortOptions = () => [
- {
- value: CREATION_DATE,
- label: this.props.intl.formatMessage(messages.dateCol),
- disabled: false,
- },
- {
- value: NAME,
- label: this.props.intl.formatMessage(messages.nameCol),
- disabled: false,
- },
- {
- value: USERS_QUANTITY,
- label: this.props.intl.formatMessage(messages.membersCol),
- disabled: false,
- },
- {
- value: LAUNCHES_QUANTITY,
- label: this.props.intl.formatMessage(messages.launchesCol),
- disabled: false,
- },
- {
- value: LAST_RUN,
- label: this.props.intl.formatMessage(messages.lastLaunchCol),
- disabled: false,
- },
- {
- value: TYPE,
- label: this.props.intl.formatMessage(messages.projectTypeCol),
- disabled: false,
- },
- {
- value: ORGANIZATION,
- label: this.props.intl.formatMessage(messages.organizationCol),
- disabled: false,
- },
- ];
-
- handleChange = (field) => {
- this.props.onChangeSorting(field);
- };
-
- render() {
- const { intl, sortingColumn, sortingDirection } = this.props;
-
- return (
-
-
{intl.formatMessage(messages.sortBy)}:
-
-
- );
- }
-}
diff --git a/app/src/pages/instance/projectsPage/projectsToolbar/projectsToolbar.jsx b/app/src/pages/instance/projectsPage/projectsToolbar/projectsToolbar.jsx
deleted file mode 100644
index 771ace7b88..0000000000
--- a/app/src/pages/instance/projectsPage/projectsToolbar/projectsToolbar.jsx
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright 2019 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, { Component, Fragment } from 'react';
-import PropTypes from 'prop-types';
-import { connect } from 'react-redux';
-import { FormattedMessage, injectIntl } from 'react-intl';
-import classNames from 'classnames/bind';
-import track from 'react-tracking';
-import { InputFilter } from 'components/inputs/inputFilter';
-import { FilterEntitiesURLContainer } from 'components/filterEntities/containers';
-import { GhostButton } from 'components/buttons/ghostButton';
-import { ADMIN_PROJECTS_PAGE_EVENTS } from 'components/main/analytics/events';
-
-import {
- GRID_VIEW,
- TABLE_VIEW,
- startSetViewMode,
- viewModeSelector,
- selectedProjectsSelector,
- fetchProjectsAction,
- deleteItemsAction,
- unselectAllProjectsAction,
- querySelector,
-} from 'controllers/instance/projects';
-import { showScreenLockAction, hideScreenLockAction } from 'controllers/screenLock';
-import { showNotification, NOTIFICATION_TYPES } from 'controllers/notification';
-
-import ExportIcon from 'common/img/export-inline.svg';
-import GridViewDashboardIcon from 'common/img/grid-inline.svg';
-import TableViewDashboardIcon from 'common/img/table-inline.svg';
-import { COMMON_LOCALE_KEYS } from 'common/constants/localization';
-import { URLS } from 'common/urls';
-import { fetch } from 'common/utils';
-import { PROJECTS } from 'common/constants/projectsObjectTypes';
-import { collectFilterEntities } from 'components/filterEntities/containers/utils';
-import { downloadFile } from 'common/utils/downloadFile';
-import { messages } from '../messages';
-import { ProjectEntities } from './projectEntities';
-import { ProjectsSorting } from './projectsSorting';
-import styles from './projectsToolbar.scss';
-
-const cx = classNames.bind(styles);
-@connect(
- (state) => ({
- filterEntities: collectFilterEntities(querySelector(state)),
- selectedProjects: selectedProjectsSelector(state),
- viewMode: viewModeSelector(state),
- }),
- {
- setViewMode: startSetViewMode,
- deleteItemsAction,
- showScreenLockAction,
- hideScreenLockAction,
- showNotification,
- fetchProjectsAction,
- unselectAllProjectsAction,
- },
-)
-@injectIntl
-@track()
-export class ProjectsToolbar extends Component {
- static propTypes = {
- intl: PropTypes.object.isRequired,
- viewMode: PropTypes.string,
- setViewMode: PropTypes.func.isRequired,
- selectedProjects: PropTypes.arrayOf(PropTypes.object),
- filterEntities: PropTypes.object,
- deleteItemsAction: PropTypes.func.isRequired,
- showScreenLockAction: PropTypes.func.isRequired,
- hideScreenLockAction: PropTypes.func.isRequired,
- showNotification: PropTypes.func.isRequired,
- fetchProjectsAction: PropTypes.func.isRequired,
- unselectAllProjectsAction: PropTypes.func.isRequired,
- sortingColumn: PropTypes.string,
- sortingDirection: PropTypes.string,
- onChangeSorting: PropTypes.func,
- tracking: PropTypes.shape({
- trackEvent: PropTypes.func,
- getTrackingData: PropTypes.func,
- }).isRequired,
- };
-
- static defaultProps = {
- viewMode: GRID_VIEW,
- selectedProjects: [],
- filterEntities: {},
- sortingColumn: null,
- sortingDirection: null,
- onChangeSorting: () => {},
- };
-
- onExportProjects = () => {
- const { filterEntities, sortingColumn, sortingDirection, tracking } = this.props;
- tracking.trackEvent(ADMIN_PROJECTS_PAGE_EVENTS.EXPORT_BTN);
- downloadFile(
- URLS.exportProjects(
- filterEntities,
- sortingColumn &&
- sortingDirection && {
- 'page.sort': `${sortingColumn},${sortingDirection}`,
- },
- ),
- );
- };
-
- getSelectedProjectsNames = () =>
- this.props.selectedProjects.map(({ projectName }) => `'${projectName} '`).join(', ');
-
- confirmDeleteItems = (projectsToDelete) => {
- const ids = projectsToDelete.map((project) => project.id);
-
- this.props.showScreenLockAction();
-
- fetch(URLS.project(ids), {
- method: 'delete',
- })
- .then(() => {
- this.props.unselectAllProjectsAction();
- this.props.fetchProjectsAction();
- this.props.hideScreenLockAction();
- this.props.showNotification({
- message:
- projectsToDelete.length === 1
- ? this.props.intl.formatMessage(messages.deleteSuccess)
- : this.props.intl.formatMessage(messages.deleteSuccessMultiple),
- type: NOTIFICATION_TYPES.SUCCESS,
- });
- })
- .catch(() => {
- this.props.hideScreenLockAction();
- this.props.showNotification({
- message:
- projectsToDelete.length === 1
- ? this.props.intl.formatMessage(messages.deleteError)
- : this.props.intl.formatMessage(messages.deleteErrorMultiple),
- type: NOTIFICATION_TYPES.ERROR,
- });
- });
- };
-
- deleteProjects = () => {
- const { selectedProjects, intl, tracking } = this.props;
- tracking.trackEvent(ADMIN_PROJECTS_PAGE_EVENTS.DELETE_PROJECT_BTN);
-
- this.props.deleteItemsAction(selectedProjects, {
- onConfirm: this.confirmDeleteItems,
- header:
- selectedProjects.length === 1
- ? intl.formatMessage(messages.deleteModalHeader)
- : intl.formatMessage(messages.deleteModalMultipleHeader),
- mainContent:
- selectedProjects.length === 1
- ? intl.formatMessage(messages.deleteModalContent, {
- name: this.getSelectedProjectsNames(),
- })
- : intl.formatMessage(messages.deleteModalMultipleContent, {
- names: this.getSelectedProjectsNames(),
- }),
- eventsInfo: {
- closeIcon: ADMIN_PROJECTS_PAGE_EVENTS.CLOSE_ICON_DELETE_MODAL,
- cancelBtn: ADMIN_PROJECTS_PAGE_EVENTS.CANCEL_BTN_DELETE_MODAL,
- deleteBtn: ADMIN_PROJECTS_PAGE_EVENTS.DELETE_BTN_DELETE_MODAL,
- },
- });
- };
-
- render() {
- const {
- intl,
- tracking,
- viewMode,
- setViewMode,
- selectedProjects,
- sortingColumn,
- sortingDirection,
- onChangeSorting,
- } = this.props;
- const selectedProjectsCount = selectedProjects.length;
-
- return (
-
-
- (
-
- )}
- />
-
-
- {selectedProjectsCount > 0 ? (
-
-
- {intl.formatMessage(messages.deleteProjectsCount, {
- count: selectedProjectsCount,
- })}
-
-
- {intl.formatMessage(COMMON_LOCALE_KEYS.DELETE)}
-
-
- ) : (
-
- {viewMode === GRID_VIEW && (
-
- )}
-
-
-
-
-
-
- {
- setViewMode(GRID_VIEW);
- tracking.trackEvent(ADMIN_PROJECTS_PAGE_EVENTS.SET_TILE_VIEW);
- }}
- />
-
-
- {
- setViewMode(TABLE_VIEW);
- tracking.trackEvent(ADMIN_PROJECTS_PAGE_EVENTS.SET_TABLE_VIEW);
- }}
- />
-
-
- )}
-
-
- );
- }
-}
diff --git a/app/src/pages/instance/projectsPage/projectsToolbar/projectsToolbar.scss b/app/src/pages/instance/projectsPage/projectsToolbar/projectsToolbar.scss
deleted file mode 100644
index 862649e95c..0000000000
--- a/app/src/pages/instance/projectsPage/projectsToolbar/projectsToolbar.scss
+++ /dev/null
@@ -1,82 +0,0 @@
-/*!
- * Copyright 2019 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.
- */
-
-.toolbar {
- padding: 10px 15px;
- display: flex;
- justify-content: space-between;
- background-color: $COLOR--white-two;
-}
-
-.search {
- flex: 0 1 400px;
- > :first-child {
- width: 100%;
- }
-
- @media (max-width: $SCREEN_XS_MAX) {
- width: 100%;
- }
-}
-
-.buttons {
- display: flex;
- align-items: center;
-}
-
-.toolbar-button {
- margin-left: 10px;
-
- svg {
- width: 20px;
- height: 20px;
- }
-}
-
-.toolbar-active-button {
- button {
- background-color: $COLOR--topaz;
-
- path {
- fill: $COLOR--white-two !important;
- }
- }
-}
-
-.delete-info {
- color: $COLOR--charcoal-grey;
- margin-right: 20px;
- font-size: 13px;
-}
-
-.delete-button {
- border: none;
- background: none;
- cursor: pointer;
- font-family: $FONT-SEMIBOLD;
- color: $COLOR--topaz;
- font-size: 13px;
- outline: none;
- &:focus {
- text-decoration: underline;
- }
-}
-
-.mobile-hide {
- @media (max-width: $SCREEN_XS_MAX) {
- display: none;
- }
-}
diff --git a/app/src/pages/organization/organizationProjectsPage/organizationProjectsPage.jsx b/app/src/pages/organization/organizationProjectsPage/organizationProjectsPage.jsx
index 94265d35b5..2cc2f9f8ef 100644
--- a/app/src/pages/organization/organizationProjectsPage/organizationProjectsPage.jsx
+++ b/app/src/pages/organization/organizationProjectsPage/organizationProjectsPage.jsx
@@ -20,16 +20,16 @@ import classNames from 'classnames/bind';
import Parser from 'html-react-parser';
import { BubblesLoader, PlusIcon } from '@reportportal/ui-kit';
import { useIntl } from 'react-intl';
-import { loadingSelector, projectsSelector } from 'controllers/organizations/projects/selectors';
-import { activeOrganizationLoadingSelector } from 'controllers/organizations/organization/selectors';
+import { loadingSelector, projectsSelector } from 'controllers/organization/projects/selectors';
+import { activeOrganizationLoadingSelector } from 'controllers/organization/selectors';
import { ScrollWrapper } from 'components/main/scrollWrapper';
import { userRolesSelector } from 'controllers/pages';
import { showModalAction } from 'controllers/modal';
-import { createProjectAction } from 'controllers/organizations/projects/actionCreators';
+import { createProjectAction } from 'controllers/organization/projects/actionCreators';
import { useState } from 'react';
import { COMMON_LOCALE_KEYS } from 'common/constants/localization';
+import { EmptyPageState } from 'pages/common/emptyPageState';
import { ProjectsPageHeader } from './projectsPageHeader';
-import { EmptyPageState } from '../emptyPageState';
import EmptyIcon from './img/empty-projects-icon-inline.svg';
import NoResultsIcon from './img/no-results-icon-inline.svg';
import { messages } from './messages';
diff --git a/app/src/pages/organization/organizationProjectsPage/projectsListTable/projectName/projectName.jsx b/app/src/pages/organization/organizationProjectsPage/projectsListTable/projectName/projectName.jsx
index 2242bb5853..c044b8e789 100644
--- a/app/src/pages/organization/organizationProjectsPage/projectsListTable/projectName/projectName.jsx
+++ b/app/src/pages/organization/organizationProjectsPage/projectsListTable/projectName/projectName.jsx
@@ -21,7 +21,7 @@ import Link from 'redux-first-router-link';
import { useDispatch, useSelector } from 'react-redux';
import { ADMIN_PROJECTS_PAGE_EVENTS } from 'components/main/analytics/events';
import { SCREEN_XS_MAX_MEDIA } from 'common/constants/screenSizeVariables';
-import { navigateToProjectAction } from 'controllers/organizations/projects';
+import { navigateToProjectAction } from 'controllers/organization/projects';
import { setActiveProjectKeyAction } from 'controllers/user';
import { userAssignedSelector, PROJECT_PAGE } from 'controllers/pages';
import styles from './projectName.scss';
diff --git a/app/src/pages/organization/organizationProjectsPage/projectsListTable/projectsListTable.jsx b/app/src/pages/organization/organizationProjectsPage/projectsListTable/projectsListTable.jsx
index 7ef3928e65..905ddde36a 100644
--- a/app/src/pages/organization/organizationProjectsPage/projectsListTable/projectsListTable.jsx
+++ b/app/src/pages/organization/organizationProjectsPage/projectsListTable/projectsListTable.jsx
@@ -20,21 +20,21 @@ import { useIntl } from 'react-intl';
import { MeatballMenuIcon, Popover, Table } from '@reportportal/ui-kit';
import classNames from 'classnames/bind';
import { useDispatch, useSelector } from 'react-redux';
+import { AbsRelTime } from 'components/main/absRelTime';
+import { SORTING_ASC, withSortingURL } from 'controllers/sorting';
+import { DEFAULT_PAGINATION, PAGE_KEY, withPagination } from 'controllers/pagination';
+import { PaginationWrapper } from 'components/main/paginationWrapper';
import {
activeOrganizationSelector,
prepareActiveOrganizationProjectsAction,
-} from 'controllers/organizations/organization';
-import { AbsRelTime } from 'components/main/absRelTime';
-import { projectsPaginationSelector } from 'controllers/organizations/projects/selectors';
-import { SORTING_ASC, withSortingURL } from 'controllers/sorting';
+} from 'controllers/organization';
import {
- DEFAULT_PAGE_SIZE_OPTIONS,
DEFAULT_LIMITATION,
+ DEFAULT_PAGE_SIZE_OPTIONS,
DEFAULT_SORT_COLUMN,
+ projectsPaginationSelector,
SORTING_KEY,
-} from 'controllers/organizations/projects/constants';
-import { DEFAULT_PAGINATION, PAGE_KEY, withPagination } from 'controllers/pagination';
-import { PaginationWrapper } from 'components/main/paginationWrapper';
+} from 'controllers/organization/projects';
import { messages } from '../messages';
import { ProjectName } from './projectName';
import styles from './projectsListTable.scss';
diff --git a/app/src/pages/organization/organizationProjectsPage/projectsPageHeader/projectsPageHeader.jsx b/app/src/pages/organization/organizationProjectsPage/projectsPageHeader/projectsPageHeader.jsx
index 9b661e556c..f85f4f871f 100644
--- a/app/src/pages/organization/organizationProjectsPage/projectsPageHeader/projectsPageHeader.jsx
+++ b/app/src/pages/organization/organizationProjectsPage/projectsPageHeader/projectsPageHeader.jsx
@@ -20,13 +20,13 @@ import { useSelector } from 'react-redux';
import Parser from 'html-react-parser';
import { Button, PlusIcon, FieldText } from '@reportportal/ui-kit';
import classNames from 'classnames/bind';
-import { PROJECTS_PAGE } from 'controllers/pages';
+import { ORGANIZATIONS_PAGE } from 'controllers/pages';
import searchIcon from 'common/img/newIcons/search-outline-inline.svg';
import filterIcon from 'common/img/newIcons/filters-outline-inline.svg';
import { Breadcrumbs } from 'componentLibrary/breadcrumbs';
-import { activeOrganizationSelector } from 'controllers/organizations/organization';
-import { SEARCH_KEY } from 'controllers/organizations/projects/constants';
-import { loadingSelector } from 'controllers/organizations/projects';
+import { activeOrganizationSelector } from 'controllers/organization';
+import { SEARCH_KEY } from 'controllers/organization/projects/constants';
+import { loadingSelector } from 'controllers/organization/projects';
import { useEffect, useState } from 'react';
import { withFilter } from 'controllers/filter';
import projectsIcon from './img/projects-inline.svg';
@@ -56,7 +56,7 @@ export const ProjectsPageHeaderWrapped = ({
const breadcrumbs = [
{
title: formatMessage(messages.allOrganizations),
- link: { type: PROJECTS_PAGE },
+ link: { type: ORGANIZATIONS_PAGE },
},
{
title: organizationName,
diff --git a/app/src/pages/organization/projectTeamPage/projectTeamPage.jsx b/app/src/pages/organization/projectTeamPage/projectTeamPage.jsx
index bf0dad265a..51c0ace9a0 100644
--- a/app/src/pages/organization/projectTeamPage/projectTeamPage.jsx
+++ b/app/src/pages/organization/projectTeamPage/projectTeamPage.jsx
@@ -23,8 +23,8 @@ import { useIntl } from 'react-intl';
import { BubblesLoader } from '@reportportal/ui-kit';
import { ScrollWrapper } from 'components/main/scrollWrapper';
import { showModalAction } from 'controllers/modal';
+import { EmptyPageState } from 'pages/common/emptyPageState';
import { ProjectTeamPageHeader } from './projectTeamPageHeader';
-import { EmptyPageState } from '../emptyPageState';
import { ProjectTeamListTable } from './projectTeamListTable';
import EmptyIcon from './img/empty-members-icon-inline.svg';
import { messages } from './messages';
diff --git a/app/src/routes/constants.js b/app/src/routes/constants.js
index dfc8ed5910..33f5e3ffa0 100644
--- a/app/src/routes/constants.js
+++ b/app/src/routes/constants.js
@@ -17,7 +17,6 @@
import { NOT_FOUND } from 'redux-first-router';
import { EmptyLayout } from 'layouts/emptyLayout';
-import { ProjectsPage } from 'pages/instance/projectsPage';
import { AllUsersPage } from 'pages/instance/allUsersPage';
import { ServerSettingsPage } from 'pages/instance/serverSettingsPage';
import { PluginsPage } from 'pages/instance/pluginsPage';
@@ -44,7 +43,6 @@ import {
PROJECT_USERDEBUG_LOG_PAGE,
LAUNCHES_PAGE,
HISTORY_PAGE,
- PROJECT_DETAILS_PAGE,
OAUTH_SUCCESS,
PLUGIN_UI_EXTENSION_ADMIN_PAGE,
PROJECT_PLUGIN_PAGE,
@@ -65,6 +63,7 @@ import { ProjectTeamPage } from 'pages/organization/projectTeamPage';
import { ProjectLayout } from 'layouts/projectLayout';
import { OrganizationLayout } from 'layouts/organizationLayout';
import { InstanceLayout } from 'layouts/instanceLayout';
+import { OrganizationsPage } from 'pages/instance/organizationsPage';
export const ANONYMOUS_ACCESS = 'anonymous';
export const ADMIN_ACCESS = 'admin';
@@ -90,6 +89,11 @@ export const pageRendering = {
[USER_PROFILE_PAGE_PROJECT_LEVEL]: { component: ProfilePage, layout: ProjectLayout },
[USER_PROFILE_SUB_PAGE_PROJECT_LEVEL]: { component: ProfilePage, layout: ProjectLayout },
API_PAGE: { component: ApiPage, layout: ProjectLayout },
+ ORGANIZATIONS_PAGE: {
+ component: OrganizationsPage,
+ layout: InstanceLayout,
+ rawContent: true,
+ },
ORGANIZATION_PROJECTS_PAGE: {
component: OrganizationProjectsPage,
layout: OrganizationLayout,
@@ -115,16 +119,6 @@ export const pageRendering = {
},
PROJECT_USERDEBUG_PAGE: { component: LaunchesPage, layout: ProjectLayout },
PROJECT_USERDEBUG_TEST_ITEM_PAGE: { component: TestItemPage, layout: ProjectLayout },
- PROJECTS_PAGE: {
- component: ProjectsPage,
- layout: InstanceLayout,
- rawContent: true,
- },
- [PROJECT_DETAILS_PAGE]: {
- component: ProjectsPage,
- layout: InstanceLayout,
- rawContent: true,
- },
ALL_USERS_PAGE: {
component: AllUsersPage,
layout: InstanceLayout,
diff --git a/app/src/routes/routesMap.js b/app/src/routes/routesMap.js
index a31150077b..7d882453bc 100644
--- a/app/src/routes/routesMap.js
+++ b/app/src/routes/routesMap.js
@@ -37,8 +37,6 @@ import {
PROJECT_USERDEBUG_PAGE,
HISTORY_PAGE,
UNIQUE_ERRORS_PAGE,
- PROJECTS_PAGE,
- PROJECT_DETAILS_PAGE,
ALL_USERS_PAGE,
SERVER_SETTINGS_PAGE,
SERVER_SETTINGS_TAB_PAGE,
@@ -66,10 +64,10 @@ import {
USER_PROFILE_SUB_PAGE,
USER_PROFILE_SUB_PAGE_ORGANIZATION_LEVEL,
USER_PROFILE_SUB_PAGE_PROJECT_LEVEL,
+ ORGANIZATIONS_PAGE,
} from 'controllers/pages';
import { GENERAL, AUTHORIZATION_CONFIGURATION, ANALYTICS } from 'common/constants/settingsTabs';
import { INSTALLED, STORE } from 'common/constants/pluginsTabs';
-import { MEMBERS, MONITORING } from 'common/constants/projectSections';
import { ANONYMOUS_REDIRECT_PATH_STORAGE_KEY, isAuthorizedSelector } from 'controllers/auth';
import {
fetchDashboardsAction,
@@ -86,13 +84,9 @@ import { fetchPluginsAction, fetchGlobalIntegrationsAction } from 'controllers/p
import { fetchTestItemsAction, setLevelAction } from 'controllers/testItem';
import { fetchFiltersPageAction } from 'controllers/filter';
import { fetchMembersAction } from 'controllers/members';
-import { fetchProjectDataAction } from 'controllers/instance';
import { fetchAllUsersAction } from 'controllers/instance/allUsers/actionCreators';
import { fetchLogPageData } from 'controllers/log';
import { fetchHistoryPageInfoAction } from 'controllers/itemsHistory';
-import { fetchProjectsAction } from 'controllers/instance/projects';
-import { fetchOrganizationsAction } from 'controllers/organizations';
-import { startSetViewMode } from 'controllers/instance/projects/actionCreators';
import { setSessionItem, updateStorageItem } from 'common/utils/storageUtils';
import { fetchClustersAction } from 'controllers/uniqueErrors';
import {
@@ -101,10 +95,11 @@ import {
PROJECT_ASSIGNMENT_ROUTE,
} from 'common/constants/userProfileRoutes';
import { parseQueryToFilterEntityAction } from 'controllers/filter/actionCreators';
+import { fetchOrganizationsAction } from 'controllers/instance/organizations';
import {
fetchOrganizationBySlugAction,
prepareActiveOrganizationProjectsAction,
-} from 'controllers/organizations/organization/actionCreators';
+} from 'controllers/organization';
import { pageRendering, ANONYMOUS_ACCESS, ADMIN_ACCESS } from './constants';
const redirectRoute = (path, createNewAction, onRedirect = () => {}) => ({
@@ -155,20 +150,6 @@ const routesMap = {
API_PAGE: '/api',
- [PROJECTS_PAGE]: {
- path: '/projects',
- thunk: (dispatch) => {
- dispatch(fetchProjectsAction());
- dispatch(fetchOrganizationsAction());
- dispatch(startSetViewMode());
- },
- },
- [PROJECT_DETAILS_PAGE]: {
- path: `/organizations/projects/organizations/:organizationSlug/projects/:projectSlug/:projectSection(${MEMBERS}|${MONITORING})?`,
- thunk: (dispatch) => {
- dispatch(fetchProjectDataAction());
- },
- },
[ALL_USERS_PAGE]: {
path: '/users',
thunk: (dispatch) => dispatch(fetchAllUsersAction()),
@@ -191,6 +172,13 @@ const routesMap = {
),
[PLUGINS_TAB_PAGE]: `/plugins/:pluginsTab(${INSTALLED}|${STORE})`,
+ [ORGANIZATIONS_PAGE]: {
+ path: '/organizations',
+ thunk: (dispatch) => {
+ dispatch(fetchOrganizationsAction());
+ },
+ },
+
[ORGANIZATION_PROJECTS_PAGE]: {
path: '/organizations/:organizationSlug/projects',
thunk: (dispatch, getState) => {
diff --git a/app/src/store/reducers.js b/app/src/store/reducers.js
index ac41f1abbf..62e6516228 100644
--- a/app/src/store/reducers.js
+++ b/app/src/store/reducers.js
@@ -37,7 +37,7 @@ import { instanceReducer } from 'controllers/instance';
import { pluginsReducer } from 'controllers/plugins';
import { initialDataReadyReducer } from 'controllers/initialData';
import { uniqueErrorsReducer } from 'controllers/uniqueErrors';
-import { organizationsReducer } from 'controllers/organizations';
+import { organizationsReducer } from 'controllers/instance/organizations';
export default {
appInfo: appInfoReducer,
diff --git a/app/src/store/rootSaga.js b/app/src/store/rootSaga.js
index e071334974..70e84c979e 100644
--- a/app/src/store/rootSaga.js
+++ b/app/src/store/rootSaga.js
@@ -30,12 +30,12 @@ import { historySagas } from 'controllers/itemsHistory';
import { logSagas } from 'controllers/log';
import { instanceSagas } from 'controllers/instance';
import { userSagas } from 'controllers/user';
-import { organizationsSagas } from 'controllers/organizations';
import { projectSagas } from 'controllers/project';
import { initialDataSagas } from 'controllers/initialData';
import { pageSagas } from 'controllers/pages';
import { pluginSagas } from 'controllers/plugins';
import { uniqueErrorsSagas } from 'controllers/uniqueErrors';
+import { organizationsSagas } from 'controllers/instance/organizations';
const sagas = [
notificationSagas,