diff --git a/packages/manager/apps/pci/package.json b/packages/manager/apps/pci/package.json
index 044b2156a756..2d805fd4ed0a 100644
--- a/packages/manager/apps/pci/package.json
+++ b/packages/manager/apps/pci/package.json
@@ -11,6 +11,7 @@
"start:watch": "lerna exec --stream --parallel --scope='@ovh-ux/manager-pci-app' --include-filtered-dependencies -- yarn run dev:watch"
},
"dependencies": {
+ "@ovh-ux/ng-ovh-uirouter-layout": "^0.0.0",
"@ovh-ux/manager-cloud-styles": "^0.3.0-alpha.0",
"@ovh-ux/manager-config": "^0.2.0",
"@ovh-ux/manager-core": "^5.0.0",
diff --git a/packages/manager/apps/public-cloud/src/sidebar/sidebar.constant.js b/packages/manager/apps/public-cloud/src/sidebar/sidebar.constant.js
index 3cdbd01b9bc1..c690ee1ce624 100644
--- a/packages/manager/apps/public-cloud/src/sidebar/sidebar.constant.js
+++ b/packages/manager/apps/public-cloud/src/sidebar/sidebar.constant.js
@@ -20,19 +20,19 @@ export const MENU = [
},
{
options: {
- state: 'pci.projects.project2',
+ state: 'pci.projects.project.storages.objects',
},
translation: 'cloud_sidebar_storage_object_storage',
},
{
options: {
- state: 'pci.projects.project2',
+ state: 'pci.projects.project.storages.archives',
},
translation: 'cloud_sidebar_storage_cold_storage',
},
{
options: {
- state: 'pci.projects.project2',
+ state: 'pci.projects.project.storages.snapshots',
},
translation: 'cloud_sidebar_storage_volume_storage',
},
diff --git a/packages/manager/modules/pci/package.json b/packages/manager/modules/pci/package.json
index d1bf781ccd50..752ca18e58f4 100644
--- a/packages/manager/modules/pci/package.json
+++ b/packages/manager/modules/pci/package.json
@@ -64,7 +64,7 @@
"ovh-angular-pagination-front": "ovh-ux/ovh-angular-pagination-front#^5.1.0",
"ovh-angular-q-allsettled": "ovh-ux/ovh-angular-q-allSettled#^0.3.1",
"ovh-angular-responsive-page-switcher": "^1.1.0",
- "ovh-api-services": "^6.8.0",
+ "ovh-api-services": "git+https://github.com/ovh-ux/ovh-api-services.git#feat/cloud-project-storage-aapi",
"ovh-common-style": "^5.0.0",
"ovh-jquery-ui-draggable-ng": "ovh-ux/ovh-jquery-ui-draggable-ng#^0.0.5",
"ovh-manager-webfont": "^1.1.0",
diff --git a/packages/manager/modules/pci/src/projects/project/index.js b/packages/manager/modules/pci/src/projects/project/index.js
index f6112fa1d59f..ce568cd168c6 100644
--- a/packages/manager/modules/pci/src/projects/project/index.js
+++ b/packages/manager/modules/pci/src/projects/project/index.js
@@ -6,7 +6,6 @@ import 'angular-translate';
import 'ovh-api-services';
import 'ovh-ui-angular';
-
import edit from './edit';
import instances from './instances';
import kubernetes from './kubernetes';
diff --git a/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/add/add.routing.js b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/add/add.routing.js
new file mode 100644
index 000000000000..293ab72c82bb
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/add/add.routing.js
@@ -0,0 +1,20 @@
+export default /* @ngInject */ ($stateProvider) => {
+ $stateProvider
+ .state('pci.projects.project.storages.archives.add', {
+ url: '/new',
+ component: 'pciProjectStorageContainersAdd',
+ resolve: {
+ goBack: /* @ngInject */ ($rootScope, $state, projectId) => (reload = false) => {
+ if (reload) {
+ $rootScope.$emit('pci_storages_containers_refresh');
+ }
+ return $state.go('pci.projects.project.storages.archives', {
+ projectId,
+ });
+ },
+ cancelLink: /* @ngInject */ ($state, projectId) => $state.href('pci.projects.project.storages.archives', {
+ projectId,
+ }),
+ },
+ });
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/add/index.js b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/add/index.js
new file mode 100644
index 000000000000..c11c2990f59a
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/add/index.js
@@ -0,0 +1,28 @@
+import angular from 'angular';
+import '@ovh-ux/manager-core';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+import 'angular-ui-bootstrap';
+
+import containersAdd from '../../containers/add';
+import routing from './add.routing';
+
+const moduleName = 'ovhManagerPciStoragesCloudArchivesAdd';
+
+angular
+ .module(moduleName, [
+ containersAdd,
+ 'ngTranslateAsyncLoader',
+ 'oui',
+ 'ovh-api-services',
+ 'ovhManagerCore',
+ 'pascalprecht.translate',
+ 'ui.router',
+ ])
+ .config(routing)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/cloud-archive.routing.js b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/cloud-archive.routing.js
new file mode 100644
index 000000000000..02372c9c3831
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/cloud-archive.routing.js
@@ -0,0 +1,22 @@
+export default /* @ngInject */ ($stateProvider) => {
+ $stateProvider
+ .state('pci.projects.project.storages.archives.archive', {
+ url: '/{containerId}',
+ component: 'pciProjectStorageContainersContainer',
+ resolve: {
+ containerId: /* @ngInject */ $transition$ => $transition$.params().containerId,
+ addObject: /* @ngInject */ ($state, projectId, containerId) => () => $state.go('pci.projects.project.storages.archives.archive.add', {
+ projectId,
+ containerId,
+ }),
+ deleteObject: /* @ngInject */ ($state, projectId, containerId) => object => $state.go('pci.projects.project.storages.archives.archive.delete', {
+ projectId,
+ containerId,
+ objectId: object.name,
+ }),
+ goBack: /* @ngInject */ ($state, projectId) => () => $state.go('pci.projects.project.storages.archives', {
+ projectId,
+ }),
+ },
+ });
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/delete/delete.routing.js b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/delete/delete.routing.js
new file mode 100644
index 000000000000..67ad8702fb34
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/delete/delete.routing.js
@@ -0,0 +1,23 @@
+export default /* @ngInject */ ($stateProvider) => {
+ $stateProvider
+ .state('pci.projects.project.storages.archives.delete', {
+ url: '/delete?containerId',
+ views: {
+ modal: {
+ component: 'pciProjectStorageContainersContainerDelete',
+ },
+ },
+ layout: 'modal',
+ resolve: {
+ containerId: /* @ngInject */$transition$ => $transition$.params().containerId,
+ goBack: /* @ngInject */ ($rootScope, $state, projectId) => (reload = false) => {
+ if (reload) {
+ $rootScope.$emit('pci_storages_containers_refresh');
+ }
+ return $state.go('pci.projects.project.storages.archives', {
+ projectId,
+ });
+ },
+ },
+ });
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/delete/index.js b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/delete/index.js
new file mode 100644
index 000000000000..ee96487939a4
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/delete/index.js
@@ -0,0 +1,27 @@
+import angular from 'angular';
+import '@ovh-ux/manager-core';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+
+import containers from '../../../containers';
+import routing from './delete.routing';
+
+const moduleName = 'ovhManagerPciStoragesCloudArchivesArchiveDelete';
+
+angular
+ .module(moduleName, [
+ containers,
+ 'ngTranslateAsyncLoader',
+ 'oui',
+ 'ovh-api-services',
+ 'ovhManagerCore',
+ 'pascalprecht.translate',
+ 'ui.router',
+ ])
+ .config(routing)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/index.js b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/index.js
new file mode 100644
index 000000000000..edf9b54fb154
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/index.js
@@ -0,0 +1,33 @@
+import angular from 'angular';
+import '@ovh-ux/manager-core';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+
+import containers from '../../containers/container';
+import deleteContainer from './delete';
+import addObject from './object/add';
+import deleteObject from './object/delete';
+import routing from './cloud-archive.routing';
+
+const moduleName = 'ovhManagerPciStoragesCloudArchivesArchive';
+
+angular
+ .module(moduleName, [
+ addObject,
+ containers,
+ deleteContainer,
+ deleteObject,
+ 'ngTranslateAsyncLoader',
+ 'oui',
+ 'ovh-api-services',
+ 'ovhManagerCore',
+ 'pascalprecht.translate',
+ 'ui.router',
+ ])
+ .config(routing)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/object/add/add.routing.js b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/object/add/add.routing.js
new file mode 100644
index 000000000000..c8c3f90bf7f6
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/object/add/add.routing.js
@@ -0,0 +1,29 @@
+export default /* @ngInject */ ($stateProvider) => {
+ $stateProvider
+ .state('pci.projects.project.storages.archives.archive.add', {
+ url: '/new',
+ views: {
+ modal: {
+ component: 'pciProjectStorageContainersContainerObjectAdd',
+ },
+ },
+ layout: 'modal',
+ resolve: {
+ archive: () => true,
+ goBack: /* @ngInject */ (
+ $rootScope,
+ $state,
+ projectId,
+ containerId,
+ ) => (reload = false) => {
+ if (reload) {
+ $rootScope.$emit('pci_storages_containers_container_refresh');
+ }
+ return $state.go('pci.projects.project.storages.archives.archive', {
+ projectId,
+ containerId,
+ });
+ },
+ },
+ });
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/object/add/index.js b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/object/add/index.js
new file mode 100644
index 000000000000..6e82f3c22403
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/object/add/index.js
@@ -0,0 +1,27 @@
+import angular from 'angular';
+import '@ovh-ux/manager-core';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+
+import containers from '../../../../containers';
+import routing from './add.routing';
+
+const moduleName = 'ovhManagerPciStoragesCloudArchivesArchiveObjectAdd';
+
+angular
+ .module(moduleName, [
+ containers,
+ 'ngTranslateAsyncLoader',
+ 'oui',
+ 'ovh-api-services',
+ 'ovhManagerCore',
+ 'pascalprecht.translate',
+ 'ui.router',
+ ])
+ .config(routing)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/object/delete/delete.routing.js b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/object/delete/delete.routing.js
new file mode 100644
index 000000000000..60402f784f29
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/object/delete/delete.routing.js
@@ -0,0 +1,29 @@
+export default /* @ngInject */ ($stateProvider) => {
+ $stateProvider
+ .state('pci.projects.project.storages.archives.archive.delete', {
+ url: '/delete?objectId',
+ views: {
+ modal: {
+ component: 'pciProjectStorageContainersContainerObjectDelete',
+ },
+ },
+ layout: 'modal',
+ resolve: {
+ objectId: /* @ngInject */$transition$ => $transition$.params().objectId,
+ goBack: /* @ngInject */ (
+ $rootScope,
+ $state,
+ projectId,
+ containerId,
+ ) => (reload = false) => {
+ if (reload) {
+ $rootScope.$emit('pci_storages_containers_container_refresh');
+ }
+ return $state.go('pci.projects.project.storages.archives.archive', {
+ projectId,
+ containerId,
+ });
+ },
+ },
+ });
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/object/delete/index.js b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/object/delete/index.js
new file mode 100644
index 000000000000..231033280d9b
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archive/object/delete/index.js
@@ -0,0 +1,27 @@
+import angular from 'angular';
+import '@ovh-ux/manager-core';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+
+import containers from '../../../../containers';
+import routing from './delete.routing';
+
+const moduleName = 'ovhManagerPciStoragesCloudArchivesArchiveObjectDelete';
+
+angular
+ .module(moduleName, [
+ containers,
+ 'ngTranslateAsyncLoader',
+ 'oui',
+ 'ovh-api-services',
+ 'ovhManagerCore',
+ 'pascalprecht.translate',
+ 'ui.router',
+ ])
+ .config(routing)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archives.routing.js b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archives.routing.js
new file mode 100644
index 000000000000..633545fe2c70
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/cloud-archives.routing.js
@@ -0,0 +1,21 @@
+export default /* @ngInject */ ($stateProvider) => {
+ $stateProvider
+ .state('pci.projects.project.storages.archives', {
+ url: '/cloud-archives',
+ component: 'pciProjectStorageContainers',
+ resolve: {
+ archive: () => true,
+ addContainer: /* @ngInject */($state, projectId) => () => $state.go('pci.projects.project.storages.archives.add', {
+ projectId,
+ }),
+ viewContainer: /* @ngInject */($state, projectId) => container => $state.go('pci.projects.project.storages.archives.archive', {
+ projectId,
+ containerId: container.id,
+ }),
+ deleteContainer: /* @ngInject */($state, projectId) => container => $state.go('pci.projects.project.storages.archives.delete', {
+ projectId,
+ containerId: container.id,
+ }),
+ },
+ });
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/index.js b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/index.js
new file mode 100644
index 000000000000..32deb486bdf9
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/cloud-archives/index.js
@@ -0,0 +1,34 @@
+import angular from 'angular';
+import '@ovh-ux/manager-core';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'oclazyload';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+
+import containers from '../containers';
+
+import addObject from './add';
+import cloudArchive from './cloud-archive';
+
+import routing from './cloud-archives.routing';
+
+const moduleName = 'ovhManagerPciStoragesCloudArchives';
+
+angular
+ .module(moduleName, [
+ addObject,
+ containers,
+ cloudArchive,
+ 'ngTranslateAsyncLoader',
+ 'oui',
+ 'ovh-api-services',
+ 'ovhManagerCore',
+ 'pascalprecht.translate',
+ 'ui.router',
+ ])
+ .config(routing)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/add/add.component.js b/packages/manager/modules/pci/src/projects/project/storages/containers/add/add.component.js
new file mode 100644
index 000000000000..ee5cee2d83b1
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/add/add.component.js
@@ -0,0 +1,13 @@
+import controller from './add.controller';
+import template from './add.html';
+
+export default {
+ controller,
+ template,
+ bindings: {
+ projectId: '<',
+ archive: '<',
+ goBack: '<',
+ cancelLink: '<',
+ },
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/add/add.controller.js b/packages/manager/modules/pci/src/projects/project/storages/containers/add/add.controller.js
new file mode 100644
index 000000000000..b4a8c7163502
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/add/add.controller.js
@@ -0,0 +1,127 @@
+import get from 'lodash/get';
+import map from 'lodash/map';
+
+import Container from '../container.class';
+
+import {
+ OBJECT_CONTAINER_TYPES,
+} from '../containers.constants';
+
+export default class PciStoragesContainersAddController {
+ /* @ngInject */
+ constructor(
+ $translate,
+ CucCloudMessage,
+ PciProjectStorageBlockService,
+ PciProjectStorageContainersService,
+ ) {
+ this.$translate = $translate;
+ this.CucCloudMessage = CucCloudMessage;
+ this.PciProjectStorageBlockService = PciProjectStorageBlockService;
+ this.PciProjectStorageContainersService = PciProjectStorageContainersService;
+ }
+
+ $onInit() {
+ this.displaySelectedRegion = false;
+ this.displaySelectedType = false;
+
+ this.types = OBJECT_CONTAINER_TYPES;
+ this.typesList = map(
+ this.types,
+ type => ({
+ id: type,
+ name: this.$translate.instant(`pci_projects_project_storages_containers_add_type_${type}_description`),
+ }),
+ );
+
+ this.loadings = {
+ regions: true,
+ types: false,
+ save: false,
+ };
+
+ this.container = new Container({
+ archive: this.archive,
+ });
+
+ return this.$translate.refresh()
+ .then(() => this.loadMessages())
+ .then(() => this.PciProjectStorageBlockService.getAvailablesRegions(this.projectId))
+ .then((regions) => {
+ this.regions = regions;
+ })
+ .catch((err) => {
+ this.CucCloudMessage.error(
+ this.$translate.instant(
+ 'pci_projects_project_storages_containers_add_error_query',
+ { message: get(err, 'data.message', '') },
+ ),
+ 'pci.projects.project.storages.containers.add',
+ );
+ })
+ .finally(() => {
+ this.loadings.regions = false;
+ });
+ }
+
+ loadMessages() {
+ this.CucCloudMessage.unSubscribe('pci.projects.project.storages.containers.add');
+ this.messageHandler = this.CucCloudMessage.subscribe(
+ 'pci.projects.project.storages.containers.add',
+ {
+ onMessage: () => this.refreshMessages(),
+ },
+ );
+ }
+
+ refreshMessages() {
+ this.messages = this.messageHandler.getMessages();
+ }
+
+ onRegionsFocus() {
+ this.displaySelectedRegion = false;
+ }
+
+ onRegionChange() {
+ this.displaySelectedRegion = true;
+ }
+
+ onTypesFocus() {
+ this.displaySelectedType = false;
+ }
+
+ onTypeChange() {
+ this.displaySelectedType = true;
+ this.container.containerType = this.selectedType.id;
+ }
+
+ add() {
+ this.loadings.save = true;
+
+ return this.PciProjectStorageContainersService
+ .addContainer(this.projectId, this.container)
+ .then(() => {
+ this.CucCloudMessage.success(
+ this.$translate.instant(
+ 'pci_projects_project_storages_containers_add_success_message',
+ { container: this.container.name },
+ ),
+ 'pci.projects.project.storages.containers',
+ );
+
+ return this.goBack(true);
+ })
+ .catch((err) => {
+ this.CucCloudMessage.error(
+ this.$translate.instant(
+ 'pci_projects_project_storages_containers_add_error_post',
+ { message: get(err, 'data.message', '') },
+ ),
+ 'pci.projects.project.storages.containers.add',
+ );
+ })
+ .finally(() => {
+ this.loadings.save = false;
+ });
+ }
+}
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/add/add.html b/packages/manager/modules/pci/src/projects/project/storages/containers/add/add.html
new file mode 100644
index 000000000000..ac0c41c3a0d7
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/add/add.html
@@ -0,0 +1,68 @@
+
+
{{:: 'pci_projects_project_storages_containers_add_back_label' | translate }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/add/index.js b/packages/manager/modules/pci/src/projects/project/storages/containers/add/index.js
new file mode 100644
index 000000000000..5e7979cf4031
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/add/index.js
@@ -0,0 +1,27 @@
+import angular from 'angular';
+import '@ovh-ux/manager-core';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+import 'angular-ui-bootstrap';
+
+import component from './add.component';
+
+const moduleName = 'ovhManagerPciStoragesContainersAdd';
+
+angular
+ .module(moduleName, [
+ 'ngTranslateAsyncLoader',
+ 'oui',
+ 'ovh-api-services',
+ 'ovhManagerCore',
+ 'pascalprecht.translate',
+ 'ui.router',
+ 'ui.bootstrap',
+ ])
+ .component('pciProjectStorageContainersAdd', component)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/add/translations/Messages_fr_FR.json b/packages/manager/modules/pci/src/projects/project/storages/containers/add/translations/Messages_fr_FR.json
new file mode 100644
index 000000000000..6f9654824081
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/add/translations/Messages_fr_FR.json
@@ -0,0 +1,21 @@
+{
+ "pci_projects_project_storages_containers_add_back_label": "Retour",
+ "pci_projects_project_storages_containers_add_title": "Créer un conteneur d'objets",
+ "pci_projects_project_storages_containers_add_region_title": "Sélectionnez une localisation",
+ "pci_projects_project_storages_containers_add_type_title": "Sélectionnez un type de conteneur",
+ "pci_projects_project_storages_containers_add_type_static_label": "Hébergement statique",
+ "pci_projects_project_storages_containers_add_type_static_description": "Accès rapide et performant pour vos sites. Liez vos domaines et déposez vos fichiers.",
+ "pci_projects_project_storages_containers_add_type_public_label": "Public",
+ "pci_projects_project_storages_containers_add_type_public_description": "Facturation, informations légales, logs. Archivez simplement et selon vos usages.",
+ "pci_projects_project_storages_containers_add_type_private_label": "Privé",
+ "pci_projects_project_storages_containers_add_type_private_description": "Multimédia, binaires, e-commerce. Stockez une infinité de données.",
+ "pci_projects_project_storages_containers_add_name_title": "Nom du conteneur",
+ "pci_projects_project_storages_containers_add_submit_title": "Validation",
+ "pci_projects_project_storages_containers_add_submit_label": "Ajouter le conteneur",
+ "pci_projects_project_storages_containers_add_cancel_label": "Annuler",
+ "pci_projects_project_storages_containers_add_save_form": "Création du conteneur en cours",
+
+ "pci_projects_project_storages_containers_add_error_query": "Une erreur est survenue lors de la récupération des régions : {{ message }}",
+ "pci_projects_project_storages_containers_add_success_message": "Le conteneur {{container}} a été ajouté",
+ "pci_projects_project_storages_containers_add_error_post": "Une erreur est survenue lors de l'ajout du conteneur {{ container }} : {{ message }}"
+}
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container-object.class.js b/packages/manager/modules/pci/src/projects/project/storages/containers/container-object.class.js
new file mode 100644
index 000000000000..0b5f8cafcb65
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container-object.class.js
@@ -0,0 +1,16 @@
+import moment from 'moment';
+
+export default class ContainerObject {
+ constructor(resource) {
+ this.retrievalDate = null;
+ Object.assign(this, resource);
+
+ this.updateRetrievalDate();
+ }
+
+ updateRetrievalDate() {
+ if (this.retrievalDelay) {
+ this.retrievalDate = moment().add(this.retrievalDelay, 'seconds').toISOString();
+ }
+ }
+}
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container.class.js b/packages/manager/modules/pci/src/projects/project/storages/containers/container.class.js
new file mode 100644
index 000000000000..ab78f76fe03e
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container.class.js
@@ -0,0 +1,6 @@
+export default class Container {
+ constructor(resource) {
+ this.publicUrl = null;
+ Object.assign(this, resource);
+ }
+}
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/container.component.js b/packages/manager/modules/pci/src/projects/project/storages/containers/container/container.component.js
new file mode 100644
index 000000000000..cc4214b92bd8
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/container.component.js
@@ -0,0 +1,15 @@
+import controller from './container.controller';
+import template from './container.html';
+
+export default {
+ controller,
+ template,
+ bindings: {
+ archive: '<',
+ projectId: '<',
+ containerId: '<',
+ goBack: '<',
+ addObject: '<',
+ deleteObject: '<',
+ },
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/container.controller.js b/packages/manager/modules/pci/src/projects/project/storages/containers/container/container.controller.js
new file mode 100644
index 000000000000..b76aed126fc5
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/container.controller.js
@@ -0,0 +1,136 @@
+import get from 'lodash/get';
+
+import { CONTAINER_DEFAULT_USER } from '../containers.constants';
+
+export default class PciStoragesContainersContainerController {
+ /* @ngInject */
+ constructor(
+ $q,
+ $rootScope,
+ $translate,
+ $window,
+ CucCloudMessage,
+ PciProjectStorageContainersService,
+ ) {
+ this.$q = $q;
+ this.$rootScope = $rootScope;
+ this.$translate = $translate;
+ this.$window = $window;
+ this.CucCloudMessage = CucCloudMessage;
+ this.PciProjectStorageContainersService = PciProjectStorageContainersService;
+
+ this.defaultUser = CONTAINER_DEFAULT_USER;
+ }
+
+ $onInit() {
+ this.$rootScope.$on('pci_storages_containers_container_refresh', () => this.refreshContainer());
+
+ this.columnsParameters = [{
+ name: 'retrievalState',
+ hidden: !this.archive,
+ }];
+
+ this.containers = null;
+
+ this.isLoading = true;
+ return this.$translate.refresh()
+ .then(() => this.loadMessages())
+ .then(() => this.getContainer())
+ .then(() => this.getContainerPassword())
+ .catch(err => this.CucCloudMessage.error(
+ this.$translate.instant(
+ `pci_projects_project_storages_containers_container_${this.archive ? 'archive' : 'object'}_error_query`,
+ { message: get(err, 'data.message', '') },
+ ),
+ 'pci.projects.project.storages.containers.container',
+ ))
+ .finally(() => {
+ this.isLoading = false;
+ });
+ }
+
+ getContainerPassword() {
+ if (this.archive) {
+ return this.PciProjectStorageContainersService
+ .getArchivePassword(this.projectId, this.container)
+ .then((password) => {
+ this.defaultPassword = password;
+ });
+ }
+ return this.$q.resolve();
+ }
+
+ getContainer() {
+ return this.PciProjectStorageContainersService
+ .getContainer(this.projectId, this.containerId)
+ .then((container) => {
+ this.container = container;
+ });
+ }
+
+ refreshContainer() {
+ this.isLoading = true;
+ return this.getContainer()
+ .catch(err => this.CucCloudMessage.error(
+ this.$translate.instant(
+ `pci_projects_project_storages_containers_container_${this.archive ? 'archive' : 'object'}_error_query`,
+ { message: get(err, 'data.message', '') },
+ ),
+ 'pci.projects.project.storages.containers.container',
+ ))
+ .finally(() => {
+ this.isLoading = false;
+ });
+ }
+
+ loadMessages() {
+ this.CucCloudMessage.unSubscribe('pci.projects.project.storages.containers.container');
+ this.messageHandler = this.CucCloudMessage.subscribe(
+ 'pci.projects.project.storages.containers.container',
+ {
+ onMessage: () => this.refreshMessages(),
+ },
+ );
+ }
+
+ refreshMessages() {
+ this.messages = this.messageHandler.getMessages();
+ }
+
+ downloadObject(object) {
+ return this.PciProjectStorageContainersService
+ .downloadObject(this.projectId, this.containerId, object)
+ .then((url) => {
+ this.$window.location = url;
+ })
+ .catch(err => this.CucCloudMessage.error(
+ this.$translate.instant(
+ `pci_projects_project_storages_containers_container_${this.archive ? 'archive' : 'object'}_error_download`,
+ { message: get(err, 'data.message', '') },
+ ),
+ 'pci.projects.project.storages.containers.container',
+ ));
+ }
+
+ unsealObject(object) {
+ return this.PciProjectStorageContainersService
+ .unsealObject(this.projectId, this.container, object)
+ .then(() => this.refreshContainer())
+ .then(() => this.CucCloudMessage.success(
+ this.$translate.instant(
+ 'pci_projects_project_storages_containers_container_archive_success_unseal',
+ {
+ archive: object.name,
+ },
+ ),
+ 'pci.projects.project.storages.containers.container',
+ ))
+ .catch(err => this.CucCloudMessage.error(
+ this.$translate.instant(
+ 'pci_projects_project_storages_containers_container_archive_error_unseal',
+ { message: get(err, 'data.message', '') },
+ ),
+ 'pci.projects.project.storages.containers.container',
+ ));
+ }
+}
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/container.html b/packages/manager/modules/pci/src/projects/project/storages/containers/container/container.html
new file mode 100644
index 000000000000..c2ed94ab99a3
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/container.html
@@ -0,0 +1,131 @@
+
+
+
+
{{:: 'pci_projects_project_storages_containers_container_back_label' | translate }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/delete/delete.component.js b/packages/manager/modules/pci/src/projects/project/storages/containers/container/delete/delete.component.js
new file mode 100644
index 000000000000..5fc75668e463
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/delete/delete.component.js
@@ -0,0 +1,13 @@
+import controller from './delete.controller';
+import template from './delete.html';
+
+export default {
+ controller,
+ template,
+ bindings: {
+ archive: '<',
+ projectId: '<',
+ containerId: '<',
+ goBack: '<',
+ },
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/delete/delete.controller.js b/packages/manager/modules/pci/src/projects/project/storages/containers/container/delete/delete.controller.js
new file mode 100644
index 000000000000..2848b79a0e1e
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/delete/delete.controller.js
@@ -0,0 +1,96 @@
+import get from 'lodash/get';
+
+export default class PciBlockStorageDetailsDeleteController {
+ /* @ngInject */
+ constructor(
+ $translate,
+ CucCloudMessage,
+ PciProjectStorageContainersService,
+ ) {
+ this.$translate = $translate;
+ this.CucCloudMessage = CucCloudMessage;
+ this.PciProjectStorageContainersService = PciProjectStorageContainersService;
+ }
+
+ $onInit() {
+ this.loadings = {
+ init: false,
+ save: false,
+ };
+
+ this.initLoaders();
+ }
+
+ initLoaders() {
+ this.loadings.init = true;
+ return this.$translate.refresh()
+ .then(() => this.loadMessages())
+ .then(() => this.PciProjectStorageContainersService
+ .getContainer(this.projectId, this.containerId))
+ .then((container) => {
+ this.container = container;
+ return this.container;
+ })
+ .catch((err) => {
+ this.CucCloudMessage.error(
+ this.$translate.instant(
+ 'pci_projects_project_storages_containers_container_delete_error_load',
+ { message: get(err, 'data.message', '') },
+ ),
+ 'pci.projects.project.storages.containers.delete',
+ );
+ })
+ .finally(() => {
+ this.loadings.init = false;
+ });
+ }
+
+ loadMessages() {
+ return new Promise((resolve) => {
+ this.CucCloudMessage.unSubscribe('pci.projects.project.storages.containers.delete');
+ this.messageHandler = this.CucCloudMessage.subscribe(
+ 'pci.projects.project.storages.containers.delete',
+ {
+ onMessage: () => this.refreshMessages(),
+ },
+ );
+ resolve();
+ });
+ }
+
+ refreshMessages() {
+ this.messages = this.messageHandler.getMessages();
+ }
+
+ deleteStorage() {
+ this.loadings.save = true;
+ return this.PciProjectStorageContainersService
+ .deleteContainer(this.projectId, this.container)
+ .then(() => {
+ this.CucCloudMessage.success(
+ this.$translate.instant(
+ 'pci_projects_project_storages_containers_container_delete_success_message',
+ {
+ container: this.container.name,
+ },
+ ),
+ 'pci.projects.project.storages.containers',
+ );
+ return this.goBack(true);
+ })
+ .catch((err) => {
+ this.CucCloudMessage.error(
+ this.$translate.instant(
+ 'pci_projects_project_storages_containers_container_delete_error_delete',
+ {
+ message: get(err, 'data.message', null),
+ },
+ ),
+ 'pci.projects.project.storages.containers.delete',
+ );
+ })
+ .finally(() => {
+ this.loadings.save = false;
+ });
+ }
+}
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/delete/delete.html b/packages/manager/modules/pci/src/projects/project/storages/containers/container/delete/delete.html
new file mode 100644
index 000000000000..ca76d9cac8cb
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/delete/delete.html
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/delete/index.js b/packages/manager/modules/pci/src/projects/project/storages/containers/container/delete/index.js
new file mode 100644
index 000000000000..bf035e25a32b
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/delete/index.js
@@ -0,0 +1,23 @@
+import angular from 'angular';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+
+import component from './delete.component';
+
+const moduleName = 'ovhManagerPciStoragesContainersContainerDelete';
+
+angular
+ .module(moduleName, [
+ 'ui.router',
+ 'oui',
+ 'ovh-api-services',
+ 'ngTranslateAsyncLoader',
+ 'pascalprecht.translate',
+ ])
+ .component('pciProjectStorageContainersContainerDelete', component)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/delete/translations/Messages_fr_FR.json b/packages/manager/modules/pci/src/projects/project/storages/containers/container/delete/translations/Messages_fr_FR.json
new file mode 100644
index 000000000000..88eed0d3d444
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/delete/translations/Messages_fr_FR.json
@@ -0,0 +1,13 @@
+{
+ "pci_projects_project_storages_containers_container_delete_archive_title": "Supprimer un conteneur d'archive",
+ "pci_projects_project_storages_containers_container_delete_object_title": "Supprimer un conteneur d'objet",
+ "pci_projects_project_storages_containers_container_delete_submit_label": "Confirmer",
+ "pci_projects_project_storages_containers_container_delete_cancel_label": "Annuler",
+ "pci_projects_project_storages_containers_container_delete_content": "Supprimer définitivement {{ container }}",
+ "pci_projects_project_storages_containers_container_delete_archive_erase_message": "Toutes les données sur le conteneur d'archive seront perdues.",
+ "pci_projects_project_storages_containers_container_delete_object_erase_message": "Toutes les données sur le conteneur d'objet seront perdues.",
+
+ "pci_projects_project_storages_containers_container_delete_error_load": "Une erreur est survenue lors du chargement du conteneur : {{ message }}.",
+ "pci_projects_project_storages_containers_container_delete_success_message": "Le conteneur {{ container }} a été supprimé.",
+ "pci_projects_project_storages_containers_container_delete_error_delete": "Une erreur est survenue lors de la suppression du conteneur {{ container }} : {{ message }}."
+}
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/index.js b/packages/manager/modules/pci/src/projects/project/storages/containers/container/index.js
new file mode 100644
index 000000000000..aa3ae63672a0
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/index.js
@@ -0,0 +1,31 @@
+import angular from 'angular';
+import '@ovh-ux/manager-core';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+import 'angular-ui-bootstrap';
+
+import deleteContainer from './delete';
+import object from './object';
+import component from './container.component';
+
+const moduleName = 'ovhManagerPciStoragesContainersContainer';
+
+angular
+ .module(moduleName, [
+ deleteContainer,
+ object,
+ 'ngTranslateAsyncLoader',
+ 'oui',
+ 'ovh-api-services',
+ 'ovhManagerCore',
+ 'pascalprecht.translate',
+ 'ui.router',
+ 'ui.bootstrap',
+ ])
+ .component('pciProjectStorageContainersContainer', component)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/add/add.component.js b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/add/add.component.js
new file mode 100644
index 000000000000..36516661e0e2
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/add/add.component.js
@@ -0,0 +1,13 @@
+import controller from './add.controller';
+import template from './add.html';
+
+export default {
+ controller,
+ template,
+ bindings: {
+ archive: '<',
+ projectId: '<',
+ containerId: '<',
+ goBack: '<',
+ },
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/add/add.controller.js b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/add/add.controller.js
new file mode 100644
index 000000000000..5ffb0808e7b0
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/add/add.controller.js
@@ -0,0 +1,98 @@
+import get from 'lodash/get';
+
+export default class PciBlockStorageContainersContainerObjectAddController {
+ /* @ngInject */
+ constructor(
+ $translate,
+ $window,
+ CucCloudMessage,
+ PciProjectStorageContainersService,
+ ) {
+ this.$translate = $translate;
+ this.$window = $window;
+ this.CucCloudMessage = CucCloudMessage;
+ this.PciProjectStorageContainersService = PciProjectStorageContainersService;
+ }
+
+ $onInit() {
+ this.loadings = {
+ init: false,
+ save: false,
+ };
+
+ this.initLoaders();
+ }
+
+ initLoaders() {
+ this.prefix = '/';
+ this.files = [];
+
+ this.loadings.init = true;
+ return this.$translate.refresh()
+ .then(() => this.loadMessages())
+ .then(() => this.PciProjectStorageContainersService
+ .getContainer(this.projectId, this.containerId))
+ .then((container) => {
+ this.container = container;
+ return this.container;
+ })
+ .catch((err) => {
+ this.CucCloudMessage.error(
+ this.$translate.instant(
+ `pci_projects_project_storages_containers_container_object_add_${this.archive ? 'archive' : 'object'}_error_load`,
+ { message: get(err, 'data.message', '') },
+ ),
+ 'pci.projects.project.storages.containers.container.object.add',
+ );
+ })
+ .finally(() => {
+ this.loadings.init = false;
+ });
+ }
+
+ loadMessages() {
+ return new Promise((resolve) => {
+ this.CucCloudMessage.unSubscribe('pci.projects.project.storages.containers.container.object.add');
+ this.messageHandler = this.CucCloudMessage.subscribe(
+ 'pci.projects.project.storages.containers.container.object.add',
+ {
+ onMessage: () => this.refreshMessages(),
+ },
+ );
+ resolve();
+ });
+ }
+
+ refreshMessages() {
+ this.messages = this.messageHandler.getMessages();
+ }
+
+ addObjects() {
+ this.loadings.save = true;
+ return this.PciProjectStorageContainersService
+ .addObjects(this.projectId, this.container, this.prefix, this.files)
+ .then(() => {
+ this.CucCloudMessage.success(
+ this.$translate.instant(
+ `pci_projects_project_storages_containers_container_object_add_${this.archive ? 'archive' : 'object'}_success_message`,
+ ),
+ 'pci.projects.project.storages.containers.container',
+ );
+ return this.goBack(true);
+ })
+ .catch((err) => {
+ this.CucCloudMessage.error(
+ this.$translate.instant(
+ `pci_projects_project_storages_containers_container_object_add_${this.archive ? 'archive' : 'object'}_error_delete`,
+ {
+ message: get(err, 'data.message', null),
+ },
+ ),
+ 'pci.projects.project.storages.containers.container.object.add',
+ );
+ })
+ .finally(() => {
+ this.loadings.save = false;
+ });
+ }
+}
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/add/add.html b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/add/add.html
new file mode 100644
index 000000000000..d2d58a020f82
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/add/add.html
@@ -0,0 +1,22 @@
+
\ No newline at end of file
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/add/index.js b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/add/index.js
new file mode 100644
index 000000000000..d3429e22bdcb
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/add/index.js
@@ -0,0 +1,21 @@
+import angular from 'angular';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'ovh-ui-angular';
+
+import component from './add.component';
+
+const moduleName = 'ovhManagerPciStoragesContainersContainerObjectAdd';
+
+angular
+ .module(moduleName, [
+ 'ui.router',
+ 'oui',
+ 'ngTranslateAsyncLoader',
+ 'pascalprecht.translate',
+ ])
+ .component('pciProjectStorageContainersContainerObjectAdd', component)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/add/translations/Messages_fr_FR.json b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/add/translations/Messages_fr_FR.json
new file mode 100644
index 000000000000..e0c376aea307
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/add/translations/Messages_fr_FR.json
@@ -0,0 +1,16 @@
+{
+ "pci_projects_project_storages_containers_container_object_add_archive_title": "Ajouter des archives",
+ "pci_projects_project_storages_containers_container_object_add_object_title": "Ajouter des objets",
+
+ "pci_projects_project_storages_containers_container_object_add_submit_label": "Importer",
+ "pci_projects_project_storages_containers_container_object_add_cancel_label": "Annuler",
+ "pci_projects_project_storages_containers_container_object_add_prefix_label": "Préfixe",
+ "pci_projects_project_storages_containers_container_object_add_files_label": "Importer des fichiers",
+
+ "pci_projects_project_storages_containers_container_object_add_archive_error_load": "Une erreur est survenue lors du chargement de l'archive : {{ message }}.",
+ "pci_projects_project_storages_containers_container_object_add_object_error_load": "Une erreur est survenue lors du chargement de l'objet : {{ message }}.",
+ "pci_projects_project_storages_containers_container_object_add_archive_success_message": "Les archives ont été importées.",
+ "pci_projects_project_storages_containers_container_object_add_object_success_message": "Les objets ont été importés.",
+ "pci_projects_project_storages_containers_container_object_add_archive_error_delete": "Une erreur est survenue lors de l'import des archives : {{ message }}.",
+ "pci_projects_project_storages_containers_container_object_add_object_error_delete": "Une erreur est survenue lors de l'import des objets {{ object }} : {{ message }}."
+}
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/delete/delete.component.js b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/delete/delete.component.js
new file mode 100644
index 000000000000..af7e25cf7f7d
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/delete/delete.component.js
@@ -0,0 +1,14 @@
+import controller from './delete.controller';
+import template from './delete.html';
+
+export default {
+ controller,
+ template,
+ bindings: {
+ archive: '<',
+ projectId: '<',
+ containerId: '<',
+ objectId: '<',
+ goBack: '<',
+ },
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/delete/delete.controller.js b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/delete/delete.controller.js
new file mode 100644
index 000000000000..289f541dc67e
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/delete/delete.controller.js
@@ -0,0 +1,100 @@
+import get from 'lodash/get';
+
+export default class PciBlockStorageContainersContainerObjectDeleteController {
+ /* @ngInject */
+ constructor(
+ $translate,
+ $window,
+ CucCloudMessage,
+ PciProjectStorageContainersService,
+ ) {
+ this.$translate = $translate;
+ this.$window = $window;
+ this.CucCloudMessage = CucCloudMessage;
+ this.PciProjectStorageContainersService = PciProjectStorageContainersService;
+ }
+
+ $onInit() {
+ this.loadings = {
+ init: false,
+ save: false,
+ };
+
+ this.initLoaders();
+ }
+
+ initLoaders() {
+ this.loadings.init = true;
+ return this.$translate.refresh()
+ .then(() => this.loadMessages())
+ .then(() => this.PciProjectStorageContainersService
+ .getObject(this.projectId, this.containerId, this.objectId))
+ .then(({ container, object }) => {
+ this.object = object;
+ this.container = container;
+
+ return this.object;
+ })
+ .catch((err) => {
+ this.CucCloudMessage.error(
+ this.$translate.instant(
+ `pci_projects_project_storages_containers_container_object_delete_${this.archive ? 'archive' : 'object'}_error_load`,
+ { message: get(err, 'data.message', '') },
+ ),
+ 'pci.projects.project.storages.containers.container.object.delete',
+ );
+ })
+ .finally(() => {
+ this.loadings.init = false;
+ });
+ }
+
+ loadMessages() {
+ return new Promise((resolve) => {
+ this.CucCloudMessage.unSubscribe('pci.projects.project.storages.containers.container.object.delete');
+ this.messageHandler = this.CucCloudMessage.subscribe(
+ 'pci.projects.project.storages.containers.container.object.delete',
+ {
+ onMessage: () => this.refreshMessages(),
+ },
+ );
+ resolve();
+ });
+ }
+
+ refreshMessages() {
+ this.messages = this.messageHandler.getMessages();
+ }
+
+ deleteObject() {
+ this.loadings.save = true;
+ return this.PciProjectStorageContainersService
+ .deleteObject(this.projectId, this.container, this.object)
+ .then(() => {
+ this.CucCloudMessage.success(
+ this.$translate.instant(
+ `pci_projects_project_storages_containers_container_object_delete_${this.archive ? 'archive' : 'object'}_success_message`,
+ {
+ object: this.object.name,
+ },
+ ),
+ 'pci.projects.project.storages.containers.container',
+ );
+ return this.goBack(true);
+ })
+ .catch((err) => {
+ this.CucCloudMessage.error(
+ this.$translate.instant(
+ `pci_projects_project_storages_containers_container_object_delete_${this.archive ? 'archive' : 'object'}_error_delete`,
+ {
+ message: get(err, 'data.message', null),
+ },
+ ),
+ 'pci.projects.project.storages.containers.container.object.delete',
+ );
+ })
+ .finally(() => {
+ this.loadings.save = false;
+ });
+ }
+}
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/delete/delete.html b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/delete/delete.html
new file mode 100644
index 000000000000..b89c215bd431
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/delete/delete.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/delete/index.js b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/delete/index.js
new file mode 100644
index 000000000000..e70b909ba8b9
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/delete/index.js
@@ -0,0 +1,23 @@
+import angular from 'angular';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+
+import component from './delete.component';
+
+const moduleName = 'ovhManagerPciStoragesContainersContainerObjectDelete';
+
+angular
+ .module(moduleName, [
+ 'ui.router',
+ 'oui',
+ 'ovh-api-services',
+ 'ngTranslateAsyncLoader',
+ 'pascalprecht.translate',
+ ])
+ .component('pciProjectStorageContainersContainerObjectDelete', component)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/delete/translations/Messages_fr_FR.json b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/delete/translations/Messages_fr_FR.json
new file mode 100644
index 000000000000..3f2b3e2dc776
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/delete/translations/Messages_fr_FR.json
@@ -0,0 +1,14 @@
+{
+ "pci_projects_project_storages_containers_container_object_delete_archive_title": "Supprimer une archive",
+ "pci_projects_project_storages_containers_container_object_delete_object_title": "Supprimer un objet",
+ "pci_projects_project_storages_containers_container_object_delete_submit_label": "Confirmer",
+ "pci_projects_project_storages_containers_container_object_delete_cancel_label": "Annuler",
+ "pci_projects_project_storages_containers_container_object_delete_content": "Voulez-vous supprimer {{ object }} ?",
+
+ "pci_projects_project_storages_containers_container_object_delete_archive_error_load": "Une erreur est survenue lors du chargement de l'archive : {{ message }}",
+ "pci_projects_project_storages_containers_container_object_delete_object_error_load": "Une erreur est survenue lors du chargement de l'objet : {{ message }}",
+ "pci_projects_project_storages_containers_container_object_delete_archive_success_message": "L'archive {{ object }} a été supprimée",
+ "pci_projects_project_storages_containers_container_object_delete_object_success_message": "L'objet {{ object }} a été supprimé",
+ "pci_projects_project_storages_containers_container_object_delete_archive_error_delete": "Une erreur est survenue lors de la suppression de l'archive {{ object }} : {{ message }}",
+ "pci_projects_project_storages_containers_container_object_delete_object_error_delete": "Une erreur est survenue lors de la suppression de l'objet {{ object }} : {{ message }}"
+}
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/index.js b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/index.js
new file mode 100644
index 000000000000..1ee996e5edbd
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/object/index.js
@@ -0,0 +1,29 @@
+import angular from 'angular';
+import '@ovh-ux/manager-core';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+import 'angular-ui-bootstrap';
+
+import addObject from './add';
+import deleteObject from './delete';
+
+const moduleName = 'ovhManagerPciStoragesContainersContainerObject';
+
+angular
+ .module(moduleName, [
+ addObject,
+ deleteObject,
+ 'ngTranslateAsyncLoader',
+ 'oui',
+ 'ovh-api-services',
+ 'ovhManagerCore',
+ 'pascalprecht.translate',
+ 'ui.router',
+ 'ui.bootstrap',
+ ])
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/container/translations/Messages_fr_FR.json b/packages/manager/modules/pci/src/projects/project/storages/containers/container/translations/Messages_fr_FR.json
new file mode 100644
index 000000000000..ba65f4b46377
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/container/translations/Messages_fr_FR.json
@@ -0,0 +1,33 @@
+{
+ "pci_projects_project_storages_containers_container_back_label": "Retour",
+ "pci_projects_project_storages_containers_container_archive_info_storedObjects": "Archives : {{ count }}",
+ "pci_projects_project_storages_containers_container_object_info_storedObjects": "Objets : {{ count }}",
+ "pci_projects_project_storages_containers_container_info_storedBytes": "Espace utilisé : {{ bytes }}",
+ "pci_projects_project_storages_containers_container_info_publicUrl": "URL du conteneur",
+ "pci_projects_project_storages_containers_container_info_publicUrl_help": "Cette information est nécessaire pour récupérer ou manipuler vos objets via l'API. Rendez-vous dans la section guide pour plus de détails.",
+ "pci_projects_project_storages_containers_container_archive_info_staticUrl": "Adresse du serveur pour rsync/sftp/scp :",
+ "pci_projects_project_storages_containers_container_object_info_staticUrl": "Valeur de l'enregistrement CNAME/TXT :",
+ "pci_projects_project_storages_containers_container_archive_info_user": "Nom de l'utilisateur : {{ user }}",
+ "pci_projects_project_storages_containers_container_archive_info_password": "Mot de passe (la concaténation des champs suivant) :",
+
+ "pci_projects_project_storages_containers_container_name_label": "Nom",
+ "pci_projects_project_storages_containers_container_lastModified_label": "Dernière modification",
+ "pci_projects_project_storages_containers_container_size_label": "Taille",
+ "pci_projects_project_storages_containers_container_contentType_label": "Type",
+ "pci_projects_project_storages_containers_container_retrievalState_label": "Disponibilité",
+ "pci_projects_project_storages_containers_container_retrievalState_unsealed": "Oui",
+ "pci_projects_project_storages_containers_container_retrievalState_sealed": "Gelée",
+ "pci_projects_project_storages_containers_container_unseal_label": "Dégeler",
+ "pci_projects_project_storages_containers_container_download_label": "Télécharger",
+ "pci_projects_project_storages_containers_container_delete_label": "Supprimer",
+
+ "pci_projects_project_storages_containers_container_add_archive_label": "Créer des archives",
+ "pci_projects_project_storages_containers_container_add_object_label": "Créer des objets",
+
+ "pci_projects_project_storages_containers_container_archive_error_query": "Une erreur est survenue lors de la récupération du conteneur d'archive : {{ message }}.",
+ "pci_projects_project_storages_containers_container_object_error_query": "Une erreur est survenue lors de la récupération du conteneur d'objet : {{ message }}.",
+ "pci_projects_project_storages_containers_container_archive_error_download": "Une erreur est survenue lors du téléchargement de l'archive : {{ message }}.",
+ "pci_projects_project_storages_containers_container_object_error_download": "Une erreur est survenue lors du téléchargement de l'objet : {{ message }}.",
+ "pci_projects_project_storages_containers_container_archive_error_unseal": "Une erreur est survenue lors du dégel de l'archive : {{ message }}.",
+ "pci_projects_project_storages_containers_container_archive_success_unseal": "Le dégel de l'archive {{archive}} est en cours."
+}
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/containers.component.js b/packages/manager/modules/pci/src/projects/project/storages/containers/containers.component.js
new file mode 100644
index 000000000000..f6022ade86ca
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/containers.component.js
@@ -0,0 +1,14 @@
+import controller from './containers.controller';
+import template from './containers.html';
+
+export default {
+ controller,
+ template,
+ bindings: {
+ projectId: '<',
+ addContainer: '<',
+ viewContainer: '<',
+ deleteContainer: '<',
+ archive: '<',
+ },
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/containers.constants.js b/packages/manager/modules/pci/src/projects/project/storages/containers/containers.constants.js
new file mode 100644
index 000000000000..263955863e83
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/containers.constants.js
@@ -0,0 +1,69 @@
+export const OBJECT_CONTAINER_TYPE_STATIC = 'static';
+export const OBJECT_CONTAINER_TYPE_PRIVATE = 'private';
+export const OBJECT_CONTAINER_TYPE_PUBLIC = 'public';
+export const OBJECT_CONTAINER_TYPES = [
+ OBJECT_CONTAINER_TYPE_STATIC,
+ OBJECT_CONTAINER_TYPE_PRIVATE,
+ OBJECT_CONTAINER_TYPE_PUBLIC,
+];
+
+export const OBJECT_TYPE_SEALED = 'sealed';
+export const OBJECT_TYPE_UNSEALING = 'unsealing';
+export const OBJECT_TYPE_UNSEALED = 'unsealed';
+export const OBJECT_TYPE_PCA = 'pca';
+export const OBJECT_TYPES = [
+ OBJECT_TYPE_SEALED,
+ OBJECT_TYPE_UNSEALING,
+ OBJECT_TYPE_UNSEALED,
+ OBJECT_TYPE_PCA,
+];
+
+export const CLOUD_PCA_FILE_STATE = {
+ SEALED: 'sealed',
+ UNSEALING: 'unsealing',
+ UNSEALED: 'unsealed',
+};
+
+export const CONTAINER_DEFAULT_USER = 'pca';
+
+export const CONTAINER_DEFAULT_PASSWORD_TENANTNAME = '';
+export const CONTAINER_DEFAULT_PASSWORD_USERNAME = '';
+export const CONTAINER_DEFAULT_PASSWORD_PASSWORD = '';
+export const CONTAINER_DEFAULT_PASSWORD = [
+ CONTAINER_DEFAULT_PASSWORD_TENANTNAME,
+ CONTAINER_DEFAULT_PASSWORD_USERNAME,
+ CONTAINER_DEFAULT_PASSWORD_PASSWORD,
+].join('.');
+
+export const X_CONTAINER_HEADERS_REGEX = /^(X-Container|X-Storage)/i;
+
+export const X_AUTH_TOKEN = 'X-Auth-Token';
+export const X_STORAGE_POLICY = 'x-storage-policy';
+export const X_CONTAINER_READ = 'x-container-read';
+export const X_CONTAINER_META_WEB_LISTINGS = 'x-container-meta-web-listings';
+export const X_CONTAINER_READ_PUBLIC_VALUE = '.r:*,.rlistings';
+
+
+export default {
+
+ CONTAINER_DEFAULT_USER,
+ CONTAINER_DEFAULT_PASSWORD_TENANTNAME,
+ CONTAINER_DEFAULT_PASSWORD_USERNAME,
+ CONTAINER_DEFAULT_PASSWORD_PASSWORD,
+ CONTAINER_DEFAULT_PASSWORD,
+
+ OBJECT_CONTAINER_TYPES,
+
+ OBJECT_TYPE_SEALED,
+ OBJECT_TYPE_UNSEALING,
+ OBJECT_TYPE_UNSEALED,
+ OBJECT_TYPE_PCA,
+ OBJECT_TYPES,
+
+ X_AUTH_TOKEN,
+ X_CONTAINER_HEADERS_REGEX,
+ X_CONTAINER_META_WEB_LISTINGS,
+ X_CONTAINER_READ,
+ X_CONTAINER_READ_PUBLIC_VALUE,
+ X_STORAGE_POLICY,
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/containers.controller.js b/packages/manager/modules/pci/src/projects/project/storages/containers/containers.controller.js
new file mode 100644
index 000000000000..6c45d17c6e88
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/containers.controller.js
@@ -0,0 +1,65 @@
+import get from 'lodash/get';
+
+export default class PciStoragesContainersController {
+ /* @ngInject */
+ constructor(
+ $rootScope,
+ $translate,
+ CucCloudMessage,
+ PciProjectStorageContainersService,
+ ) {
+ this.$rootScope = $rootScope;
+ this.$translate = $translate;
+ this.CucCloudMessage = CucCloudMessage;
+ this.PciProjectStorageContainersService = PciProjectStorageContainersService;
+ }
+
+ $onInit() {
+ this.$rootScope.$on('pci_storages_containers_refresh', () => this.refreshContainers());
+
+ this.containers = null;
+
+ this.isLoading = true;
+ return this.$translate.refresh()
+ .then(() => this.loadMessages())
+ .then(() => this.getContainers())
+ .finally(() => {
+ this.isLoading = false;
+ });
+ }
+
+ getContainers() {
+ return this.PciProjectStorageContainersService.getAll(this.projectId, this.archive)
+ .then((containers) => {
+ this.containers = containers;
+ })
+ .catch(err => this.CucCloudMessage.error(
+ this.$translate.instant(
+ 'pci_projects_project_storages_containers_error_query',
+ { message: get(err, 'data.message', '') },
+ ),
+ ));
+ }
+
+ refreshContainers() {
+ this.isLoading = true;
+ return this.getContainers()
+ .finally(() => {
+ this.isLoading = false;
+ });
+ }
+
+ loadMessages() {
+ this.CucCloudMessage.unSubscribe('pci.projects.project.storages.containers');
+ this.messageHandler = this.CucCloudMessage.subscribe(
+ 'pci.projects.project.storages.containers',
+ {
+ onMessage: () => this.refreshMessages(),
+ },
+ );
+ }
+
+ refreshMessages() {
+ this.messages = this.messageHandler.getMessages();
+ }
+}
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/containers.html b/packages/manager/modules/pci/src/projects/project/storages/containers/containers.html
new file mode 100644
index 000000000000..1a2e181811fc
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/containers.html
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/containers.service.js b/packages/manager/modules/pci/src/projects/project/storages/containers/containers.service.js
new file mode 100644
index 000000000000..19b296b370b1
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/containers.service.js
@@ -0,0 +1,361 @@
+import angular from 'angular';
+import find from 'lodash/find';
+import has from 'lodash/has';
+import map from 'lodash/map';
+import pickBy from 'lodash/pickBy';
+import reduce from 'lodash/reduce';
+import startsWith from 'lodash/startsWith';
+import endsWith from 'lodash/endsWith';
+import moment from 'moment';
+
+import Container from './container.class';
+import ContainerObject from './container-object.class';
+
+import {
+ CONTAINER_DEFAULT_PASSWORD_TENANTNAME,
+ CONTAINER_DEFAULT_PASSWORD_USERNAME,
+ CONTAINER_DEFAULT_PASSWORD,
+ OBJECT_CONTAINER_TYPE_STATIC,
+ OBJECT_CONTAINER_TYPE_PUBLIC,
+ OBJECT_TYPE_SEALED,
+ X_AUTH_TOKEN,
+ X_CONTAINER_HEADERS_REGEX,
+ X_CONTAINER_READ,
+ X_CONTAINER_READ_PUBLIC_VALUE,
+} from './containers.constants';
+
+export default class PciStoragesContainersService {
+ /* @ngInject */
+ constructor(
+ $http,
+ $q,
+ OvhApiCloudProjectStorage,
+ OvhApiCloudProjectUser,
+ ) {
+ this.$http = $http;
+ this.$q = $q;
+ this.OvhApiCloudProjectStorage = OvhApiCloudProjectStorage;
+ this.OvhApiCloudProjectUser = OvhApiCloudProjectUser;
+ }
+
+ getAccessAndToken(projectId) {
+ return this.OvhApiCloudProjectStorage
+ .v6()
+ .access({
+ projectId,
+ })
+ .$promise
+ .then(({ token, endpoints }) => ({
+ token,
+ endpoints: reduce(
+ endpoints,
+ (result, endpoint) => ({
+ ...result,
+ [endpoint.region.toLowerCase()]: endpoint.url,
+ }),
+ {},
+ ),
+ }));
+ }
+
+ getArchivePassword(projectId, { region }) {
+ return this.OvhApiCloudProjectUser
+ .v6()
+ .query({
+ serviceName: projectId,
+ })
+ .$promise
+ .then((users) => {
+ const promises = {
+ users,
+ };
+ if (users.length > 0) {
+ promises.openrc = this.OvhApiCloudProjectUser
+ .Aapi()
+ .openrc({
+ serviceName: projectId,
+ userId: users[0].id,
+ region,
+ })
+ .$promise;
+ }
+ return this.$q.all(promises);
+ })
+ .then(({ users, openrc }) => {
+ if (openrc) {
+ let cleanedOpenRc = { ...openrc };
+ if (users.length > 1) {
+ cleanedOpenRc = Object.keys(openrc).reduce((object, key) => {
+ if (key !== 'osUsername') {
+ return {
+ ...object,
+ [key]: openrc[key],
+ };
+ }
+ return object;
+ }, {});
+ }
+ return cleanedOpenRc;
+ }
+ return {};
+ })
+ .then((connectionInformation) => {
+ let password = `${CONTAINER_DEFAULT_PASSWORD}`;
+ if (has(connectionInformation, 'osTenantName')) {
+ password = password.replace(
+ CONTAINER_DEFAULT_PASSWORD_TENANTNAME,
+ connectionInformation.osTenantName,
+ );
+ }
+ if (has(connectionInformation, 'osUsername')) {
+ password = password.replace(
+ CONTAINER_DEFAULT_PASSWORD_USERNAME,
+ connectionInformation.osUsername,
+ );
+ }
+
+ return password;
+ });
+ }
+
+ getAll(projectId, isArchive = null) {
+ const queryParams = {
+ serviceName: projectId,
+ };
+
+ if (isArchive === true) {
+ queryParams.archive = true;
+ } else if (isArchive === false) {
+ queryParams.archive = false;
+ }
+
+ return this.OvhApiCloudProjectStorage
+ .Aapi()
+ .query(queryParams)
+ .$promise
+ .then(containers => map(containers, container => new Container(container)));
+ }
+
+ getContainer(projectId, containerId) {
+ return this.OvhApiCloudProjectStorage
+ .v6()
+ .get({
+ projectId,
+ containerId,
+ })
+ .$promise
+ .then(container => this.$q.all({
+ container,
+ publicUrl: this.getContainerUrl(projectId, container),
+ }))
+ .then(({ container, publicUrl }) => new Container({
+ ...container,
+ objects: map(container.objects, object => new ContainerObject(object)),
+ id: containerId,
+ publicUrl,
+ }));
+ }
+
+ getContainerUrl(projectId, container, file = null) {
+ return this.getAccessAndToken(projectId)
+ .then(({ endpoints }) => {
+ const url = `${endpoints[container.region.toLowerCase()]}/${encodeURIComponent(container.name)}`;
+ if (file) {
+ return `${url}/${encodeURIComponent(file)}`;
+ }
+ return url;
+ });
+ }
+
+ requestContainer(projectId, container, optsParam = {}) {
+ const opts = pickBy(optsParam, (value, key) => key !== 'file');
+ return this.getAccessAndToken(projectId)
+ .then(accessToken => this.$q.all({
+ accessToken,
+ url: this.getContainerUrl(projectId, container, optsParam.file),
+ }))
+ .then(({ accessToken, url }) => this.$http(angular.merge({
+ method: 'GET',
+ url,
+ headers: {
+ [X_AUTH_TOKEN]: accessToken.token,
+ },
+ }, opts)));
+ }
+
+ getContainerMetaData(projectId, container) {
+ return this.requestContainer(projectId, container, { method: 'HEAD' })
+ .then(metadata => pickBy(
+ metadata.headers(),
+ (value, key) => X_CONTAINER_HEADERS_REGEX.test(key),
+ ));
+ }
+
+ addContainer(projectId, {
+ archive,
+ containerType,
+ name,
+ region,
+ }) {
+ return this.OvhApiCloudProjectStorage
+ .v6()
+ .save(
+ {
+ projectId,
+ },
+ {
+ archive,
+ containerName: name,
+ region: region.name,
+ },
+ )
+ .$promise
+ .then((container) => {
+ let returnPromise = this.$q.resolve();
+ if (containerType === OBJECT_CONTAINER_TYPE_STATIC) {
+ returnPromise = this.setContainerAsStatic(projectId, container);
+ } else if (containerType === OBJECT_CONTAINER_TYPE_PUBLIC) {
+ returnPromise = this.setContainerAsPublic(projectId, container);
+ }
+ return returnPromise;
+ });
+ }
+
+ setContainerAsStatic(projectId, container) {
+ return this.OvhApiCloudProjectStorage
+ .v6()
+ .static({
+ projectId,
+ containerId: container.id,
+ }, {})
+ .$promise;
+ }
+
+ setContainerAsPublic(projectId, container) {
+ return this.getContainerMetaData(projectId, container)
+ .then((metadata) => {
+ if (metadata[X_CONTAINER_READ] !== X_CONTAINER_READ_PUBLIC_VALUE) {
+ return this.requestContainer(projectId, container, {
+ method: 'PUT',
+ headers: {
+ [X_CONTAINER_READ]: X_CONTAINER_READ_PUBLIC_VALUE,
+ },
+ });
+ }
+ return $.resolve();
+ });
+ }
+
+ deleteContainer(projectId, { id }) {
+ return this.OvhApiCloudProjectStorage
+ .v6()
+ .delete({
+ projectId,
+ containerId: id,
+ })
+ .$promise;
+ }
+
+ getObject(projectId, containerId, objectId) {
+ return this.getContainer(projectId, containerId)
+ .then(container => ({
+ container,
+ object: find(container.objects, { name: objectId }),
+ }));
+ }
+
+ static getFilePath(filePrefix, file) {
+ let prefix = '';
+ if (filePrefix) {
+ prefix = filePrefix;
+ if (startsWith(filePrefix, '/')) {
+ prefix = prefix.substring(1);
+ }
+ if (!endsWith(filePrefix, '/')) {
+ prefix = `${prefix}/`;
+ }
+ }
+ return `${prefix}${file.name}`;
+ }
+
+ addObjects(projectId, container, filePrefix, files) {
+ return this.$q.all(map(
+ files,
+ file => this.addObject(projectId, container, filePrefix, file),
+ ));
+ }
+
+ addObject(projectId, container, filePrefix, file) {
+ const config = {
+ headers: {
+ 'Content-Type': file.type,
+ },
+ data: file,
+ };
+
+ return this.$q.all({
+ url: this.getContainerUrl(
+ projectId,
+ container,
+ PciStoragesContainersService.getFilePath(filePrefix, file),
+ ),
+ accessToken: this.getAccessAndToken(projectId),
+ })
+ .then(({ accessToken, url }) => this.upload(url, config, accessToken));
+ }
+
+
+ upload(url, config, accessToken) {
+ return this.$http.put(
+ url,
+ config.data,
+ {
+ headers: {
+ ...config.headers,
+ [X_AUTH_TOKEN]: accessToken.token,
+ },
+ },
+ );
+ }
+
+ deleteObject(projectId, container, object) {
+ return this.requestContainer(projectId, container, {
+ method: 'DELETE',
+ file: object.name,
+ });
+ }
+
+ getObjectUrl(projectId, containerId, object) {
+ const expirationDate = moment().add(1, 'week').toISOString();
+ return this.OvhApiCloudProjectStorage
+ .v6()
+ .getURL({
+ projectId,
+ containerId,
+ }, {
+ expirationDate,
+ objectName: object.name,
+ }).$promise
+ .then(resp => resp.getURL);
+ }
+
+ downloadObject(projectId, containerId, object) {
+ return this.getObjectUrl(projectId, containerId, object);
+ }
+
+ unsealObject(projectId, container, object) {
+ if (object.retrievalState === OBJECT_TYPE_SEALED) {
+ return this.getObjectUrl(projectId, container.id, object)
+ .then(url => this.$http.get(url))
+ .catch((error) => {
+ // This call make a CORS error, but still initiate the process,
+ // swallow status -1 which is what we get when cors fail.
+ if (error.status !== -1) {
+ throw error;
+ }
+ });
+ }
+
+ return this.$q.resolve();
+ }
+}
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/index.js b/packages/manager/modules/pci/src/projects/project/storages/containers/index.js
new file mode 100644
index 000000000000..b279074cb391
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/index.js
@@ -0,0 +1,29 @@
+import angular from 'angular';
+import '@ovh-ux/manager-core';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+import 'angular-ui-bootstrap';
+
+import component from './containers.component';
+import service from './containers.service';
+
+const moduleName = 'ovhManagerPciStoragesContainers';
+
+angular
+ .module(moduleName, [
+ 'ngTranslateAsyncLoader',
+ 'oui',
+ 'ovh-api-services',
+ 'ovhManagerCore',
+ 'pascalprecht.translate',
+ 'ui.router',
+ 'ui.bootstrap',
+ ])
+ .component('pciProjectStorageContainers', component)
+ .service('PciProjectStorageContainersService', service)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/containers/translations/Messages_fr_FR.json b/packages/manager/modules/pci/src/projects/project/storages/containers/translations/Messages_fr_FR.json
new file mode 100644
index 000000000000..bf5f3c214c3c
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/containers/translations/Messages_fr_FR.json
@@ -0,0 +1,23 @@
+{
+ "pci_projects_project_storages_containers_archive_title": "Cloud Archive",
+ "pci_projects_project_storages_containers_object_title": "Object Storage",
+ "pci_projects_project_storages_containers_name_label": "Nom",
+ "pci_projects_project_storages_containers_region_label": "Localisation",
+
+ "pci_projects_project_storages_containers_containerType_label": "Type",
+ "pci_projects_project_storages_containers_containerType_public": "Public",
+ "pci_projects_project_storages_containers_containerType_private": "Privé",
+ "pci_projects_project_storages_containers_containerType_static": "Statique",
+
+ "pci_projects_project_storages_containers_storedObjects_label": "Nombre d'objets",
+ "pci_projects_project_storages_containers_storedBytes_label": "Espace utilisé",
+
+ "pci_projects_project_storages_containers_view_archive_label": "Voir les archives",
+ "pci_projects_project_storages_containers_view_object_label": "Voir les objets",
+ "pci_projects_project_storages_containers_delete_label": "Supprimer",
+
+ "pci_projects_project_storages_blocks_add_archive_label": "Créer un conteneur d'archive",
+ "pci_projects_project_storages_blocks_add_object_label": "Créer un conteneur d'objets",
+
+ "pci_projects_project_storages_containers_error_query": "Une erreur est survenue lors de la récupération des conteneurs."
+}
diff --git a/packages/manager/modules/pci/src/projects/project/storages/index.js b/packages/manager/modules/pci/src/projects/project/storages/index.js
index 02c76aa7ece0..5a89894035a6 100644
--- a/packages/manager/modules/pci/src/projects/project/storages/index.js
+++ b/packages/manager/modules/pci/src/projects/project/storages/index.js
@@ -2,6 +2,8 @@ import angular from 'angular';
import 'ovh-ui-angular';
import blocks from './blocks';
+import cloudArchive from './cloud-archives';
+import objects from './objects';
import routing from './storages.routing';
const moduleName = 'ovhManagerPciStorages';
@@ -9,6 +11,8 @@ const moduleName = 'ovhManagerPciStorages';
angular
.module(moduleName, [
blocks,
+ cloudArchive,
+ objects,
'ui.router',
])
.config(routing);
diff --git a/packages/manager/modules/pci/src/projects/project/storages/objects/add/add.routing.js b/packages/manager/modules/pci/src/projects/project/storages/objects/add/add.routing.js
new file mode 100644
index 000000000000..fd32c7a873bb
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/objects/add/add.routing.js
@@ -0,0 +1,20 @@
+export default /* @ngInject */ ($stateProvider) => {
+ $stateProvider
+ .state('pci.projects.project.storages.objects.add', {
+ url: '/new',
+ component: 'pciProjectStorageContainersAdd',
+ resolve: {
+ goBack: /* @ngInject */ ($rootScope, $state, projectId) => (reload = false) => {
+ if (reload) {
+ $rootScope.$emit('pci_storages_containers_refresh');
+ }
+ return $state.go('pci.projects.project.storages.objects', {
+ projectId,
+ });
+ },
+ cancelLink: /* @ngInject */ ($state, projectId) => $state.href('pci.projects.project.storages.objects', {
+ projectId,
+ }),
+ },
+ });
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/objects/add/index.js b/packages/manager/modules/pci/src/projects/project/storages/objects/add/index.js
new file mode 100644
index 000000000000..59ddc41029e5
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/objects/add/index.js
@@ -0,0 +1,29 @@
+import angular from 'angular';
+import '@ovh-ux/manager-core';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'oclazyload';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+import 'angular-ui-bootstrap';
+
+import containersAdd from '../../containers/add';
+import routing from './add.routing';
+
+const moduleName = 'ovhManagerPciStoragesObjectsAdd';
+
+angular
+ .module(moduleName, [
+ containersAdd,
+ 'ngTranslateAsyncLoader',
+ 'oui',
+ 'ovh-api-services',
+ 'ovhManagerCore',
+ 'pascalprecht.translate',
+ 'ui.router',
+ ])
+ .config(routing)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/objects/index.js b/packages/manager/modules/pci/src/projects/project/storages/objects/index.js
new file mode 100644
index 000000000000..ac09796e7d65
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/objects/index.js
@@ -0,0 +1,33 @@
+import angular from 'angular';
+import '@ovh-ux/manager-core';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+
+import containers from '../containers';
+
+import addObject from './add';
+import object from './object';
+
+import routing from './objects.routing';
+
+const moduleName = 'ovhManagerPciStoragesObjects';
+
+angular
+ .module(moduleName, [
+ addObject,
+ containers,
+ object,
+ 'ngTranslateAsyncLoader',
+ 'oui',
+ 'ovh-api-services',
+ 'ovhManagerCore',
+ 'pascalprecht.translate',
+ 'ui.router',
+ ])
+ .config(routing)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/objects/object/delete/delete.routing.js b/packages/manager/modules/pci/src/projects/project/storages/objects/object/delete/delete.routing.js
new file mode 100644
index 000000000000..fa2bf12ccfd3
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/objects/object/delete/delete.routing.js
@@ -0,0 +1,23 @@
+export default /* @ngInject */ ($stateProvider) => {
+ $stateProvider
+ .state('pci.projects.project.storages.objects.delete', {
+ url: '/delete?containerId',
+ views: {
+ modal: {
+ component: 'pciProjectStorageContainersContainerDelete',
+ },
+ },
+ layout: 'modal',
+ resolve: {
+ containerId: /* @ngInject */$transition$ => $transition$.params().containerId,
+ goBack: /* @ngInject */ ($rootScope, $state, projectId) => (reload = false) => {
+ if (reload) {
+ $rootScope.$emit('pci_storages_containers_refresh');
+ }
+ return $state.go('pci.projects.project.storages.objects', {
+ projectId,
+ });
+ },
+ },
+ });
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/objects/object/delete/index.js b/packages/manager/modules/pci/src/projects/project/storages/objects/object/delete/index.js
new file mode 100644
index 000000000000..8d4ed5a6ae46
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/objects/object/delete/index.js
@@ -0,0 +1,27 @@
+import angular from 'angular';
+import '@ovh-ux/manager-core';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+
+import containers from '../../../containers';
+import routing from './delete.routing';
+
+const moduleName = 'ovhManagerPciStoragesObjectsObjectDelete';
+
+angular
+ .module(moduleName, [
+ containers,
+ 'ngTranslateAsyncLoader',
+ 'oui',
+ 'ovh-api-services',
+ 'ovhManagerCore',
+ 'pascalprecht.translate',
+ 'ui.router',
+ ])
+ .config(routing)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/objects/object/index.js b/packages/manager/modules/pci/src/projects/project/storages/objects/object/index.js
new file mode 100644
index 000000000000..f90eb4841728
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/objects/object/index.js
@@ -0,0 +1,33 @@
+import angular from 'angular';
+import '@ovh-ux/manager-core';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+
+import containers from '../../containers/container';
+import deleteContainer from './delete';
+import addObject from './object/add';
+import deleteObject from './object/delete';
+import routing from './object.routing';
+
+const moduleName = 'ovhManagerPciStoragesObjectsObjectObject';
+
+angular
+ .module(moduleName, [
+ containers,
+ addObject,
+ deleteContainer,
+ deleteObject,
+ 'ngTranslateAsyncLoader',
+ 'oui',
+ 'ovh-api-services',
+ 'ovhManagerCore',
+ 'pascalprecht.translate',
+ 'ui.router',
+ ])
+ .config(routing)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/objects/object/object.routing.js b/packages/manager/modules/pci/src/projects/project/storages/objects/object/object.routing.js
new file mode 100644
index 000000000000..38e306b52d54
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/objects/object/object.routing.js
@@ -0,0 +1,22 @@
+export default /* @ngInject */ ($stateProvider) => {
+ $stateProvider
+ .state('pci.projects.project.storages.objects.object', {
+ url: '/{containerId}',
+ component: 'pciProjectStorageContainersContainer',
+ resolve: {
+ containerId: /* @ngInject */ $transition$ => $transition$.params().containerId,
+ addObject: /* @ngInject */ ($state, projectId, containerId) => () => $state.go('pci.projects.project.storages.objects.object.add', {
+ projectId,
+ containerId,
+ }),
+ deleteObject: /* @ngInject */ ($state, projectId, containerId) => object => $state.go('pci.projects.project.storages.objects.object.delete', {
+ projectId,
+ containerId,
+ objectId: object.name,
+ }),
+ goBack: /* @ngInject */ ($state, projectId) => () => $state.go('pci.projects.project.storages.objects', {
+ projectId,
+ }),
+ },
+ });
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/objects/object/object/add/add.routing.js b/packages/manager/modules/pci/src/projects/project/storages/objects/object/object/add/add.routing.js
new file mode 100644
index 000000000000..2cec7b01f998
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/objects/object/object/add/add.routing.js
@@ -0,0 +1,28 @@
+export default /* @ngInject */ ($stateProvider) => {
+ $stateProvider
+ .state('pci.projects.project.storages.objects.object.add', {
+ url: '/new',
+ views: {
+ modal: {
+ component: 'pciProjectStorageContainersContainerObjectAdd',
+ },
+ },
+ layout: 'modal',
+ resolve: {
+ goBack: /* @ngInject */ (
+ $rootScope,
+ $state,
+ projectId,
+ containerId,
+ ) => (reload = false) => {
+ if (reload) {
+ $rootScope.$emit('pci_storages_containers_container_refresh');
+ }
+ return $state.go('pci.projects.project.storages.objects.object', {
+ projectId,
+ containerId,
+ });
+ },
+ },
+ });
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/objects/object/object/add/index.js b/packages/manager/modules/pci/src/projects/project/storages/objects/object/object/add/index.js
new file mode 100644
index 000000000000..9cf072aecc47
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/objects/object/object/add/index.js
@@ -0,0 +1,27 @@
+import angular from 'angular';
+import '@ovh-ux/manager-core';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+
+import containers from '../../../../containers';
+import routing from './add.routing';
+
+const moduleName = 'ovhManagerPciStoragesObjectsObjectObjectAdd';
+
+angular
+ .module(moduleName, [
+ containers,
+ 'ngTranslateAsyncLoader',
+ 'oui',
+ 'ovh-api-services',
+ 'ovhManagerCore',
+ 'pascalprecht.translate',
+ 'ui.router',
+ ])
+ .config(routing)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/objects/object/object/delete/delete.routing.js b/packages/manager/modules/pci/src/projects/project/storages/objects/object/object/delete/delete.routing.js
new file mode 100644
index 000000000000..f4d4ee6d21b6
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/objects/object/object/delete/delete.routing.js
@@ -0,0 +1,29 @@
+export default /* @ngInject */ ($stateProvider) => {
+ $stateProvider
+ .state('pci.projects.project.storages.objects.object.delete', {
+ url: '/delete?objectId',
+ views: {
+ modal: {
+ component: 'pciProjectStorageContainersContainerObjectDelete',
+ },
+ },
+ layout: 'modal',
+ resolve: {
+ objectId: /* @ngInject */$transition$ => $transition$.params().objectId,
+ goBack: /* @ngInject */ (
+ $rootScope,
+ $state,
+ projectId,
+ containerId,
+ ) => (reload = false) => {
+ if (reload) {
+ $rootScope.$emit('pci_storages_containers_container_refresh');
+ }
+ return $state.go('pci.projects.project.storages.objects.object', {
+ projectId,
+ containerId,
+ });
+ },
+ },
+ });
+};
diff --git a/packages/manager/modules/pci/src/projects/project/storages/objects/object/object/delete/index.js b/packages/manager/modules/pci/src/projects/project/storages/objects/object/object/delete/index.js
new file mode 100644
index 000000000000..6cd3b1582bea
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/objects/object/object/delete/index.js
@@ -0,0 +1,27 @@
+import angular from 'angular';
+import '@ovh-ux/manager-core';
+import '@ovh-ux/ng-translate-async-loader';
+import '@uirouter/angularjs';
+import 'angular-translate';
+import 'ovh-ui-angular';
+import 'ovh-api-services';
+
+import containers from '../../../../containers';
+import routing from './delete.routing';
+
+const moduleName = 'ovhManagerPciStoragesObjectsObjectObjectDelete';
+
+angular
+ .module(moduleName, [
+ containers,
+ 'ngTranslateAsyncLoader',
+ 'oui',
+ 'ovh-api-services',
+ 'ovhManagerCore',
+ 'pascalprecht.translate',
+ 'ui.router',
+ ])
+ .config(routing)
+ .run(/* @ngTranslationsInject:json ./translations */);
+
+export default moduleName;
diff --git a/packages/manager/modules/pci/src/projects/project/storages/objects/objects.routing.js b/packages/manager/modules/pci/src/projects/project/storages/objects/objects.routing.js
new file mode 100644
index 000000000000..e5745d958992
--- /dev/null
+++ b/packages/manager/modules/pci/src/projects/project/storages/objects/objects.routing.js
@@ -0,0 +1,21 @@
+export default /* @ngInject */ ($stateProvider) => {
+ $stateProvider
+ .state('pci.projects.project.storages.objects', {
+ url: '/objects',
+ component: 'pciProjectStorageContainers',
+ resolve: {
+ archive: () => false,
+ addContainer: /* @ngInject */($state, projectId) => () => $state.go('pci.projects.project.storages.objects.add', {
+ projectId,
+ }),
+ viewContainer: /* @ngInject */($state, projectId) => container => $state.go('pci.projects.project.storages.objects.object', {
+ projectId,
+ containerId: container.id,
+ }),
+ deleteContainer: /* @ngInject */($state, projectId) => container => $state.go('pci.projects.project.storages.objects.delete', {
+ projectId,
+ containerId: container.id,
+ }),
+ },
+ });
+};
diff --git a/yarn.lock b/yarn.lock
index e30838d91762..9fa8d1d8592d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9357,6 +9357,13 @@ ovh-api-services@^6.11.0:
dependencies:
lodash "^3.10.1"
+ovh-api-services@^6.4.0:
+ version "6.9.0"
+ resolved "https://registry.yarnpkg.com/ovh-api-services/-/ovh-api-services-6.9.0.tgz#842c8d4a3a0322fd2777144914de16510d03d8c2"
+ integrity sha512-th4gojJ13/Z2XNtylkX9ZO3o82WsKCFBiHFyc1OZeEJy7E32w3wNi8cN7USlyXuP3j/NsKrSEWKD1ZOddGBcMg==
+ dependencies:
+ lodash "^3.10.1"
+
ovh-common-style@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/ovh-common-style/-/ovh-common-style-3.2.2.tgz#66f4637c7393d1bd5118b05b63b034f26120a41f"