aboutsummaryrefslogtreecommitdiffstats
path: root/cds-ui/designer-client/src/app/modules/feature-modules/packages
diff options
context:
space:
mode:
authorKAPIL SINGAL <ks220y@att.com>2019-12-09 14:29:57 +0000
committerGerrit Code Review <gerrit@onap.org>2019-12-09 14:29:57 +0000
commitdac9afbc6df66dfe3700b37f12b51bccebf74e83 (patch)
tree22cbfc84b5eeb7761d8ebcf8b3ecbd2c7bef3815 /cds-ui/designer-client/src/app/modules/feature-modules/packages
parenta48981d05a85f45010ff4c8bf6e797037a9ea4fa (diff)
parent1b8623b4cf3e5ddf8eb3e9a6fd38cb3982eeb94f (diff)
Merge "rename ui project from client-franfurt to designer-client"
Diffstat (limited to 'cds-ui/designer-client/src/app/modules/feature-modules/packages')
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/blueprint.page.mock.ts50
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.css547
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html337
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.spec.ts25
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts128
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/model/BluePrint.model.ts58
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/model/packages-dashboard.state.ts33
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.css0
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.html18
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.spec.ts45
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.ts100
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.css0
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.html104
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.spec.ts36
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.ts32
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.css0
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.html7
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.spec.ts25
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.ts41
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/packages-dahsboard.component.spec.ts44
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/packages-dashboard.component.css0
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/packages-dashboard.component.html61
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/packages-dashboard.component.ts37
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/search-by-packages/search-by-packages.component.css0
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/search-by-packages/search-by-packages.component.html4
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/search-by-packages/search-by-packages.component.spec.ts25
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/search-by-packages/search-by-packages.component.ts25
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-list.service.ts66
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.module.ts36
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.routing.module.ts20
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.store.spec.ts44
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.store.ts104
32 files changed, 2052 insertions, 0 deletions
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/blueprint.page.mock.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/blueprint.page.mock.ts
new file mode 100644
index 000000000..9e0ce71d2
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/blueprint.page.mock.ts
@@ -0,0 +1,50 @@
+import { BluePrintPage } from './model/BluePrint.model';
+export function getBluePrintPageMock(): BluePrintPage {
+ return {
+ content: [
+ {
+ id: 'bc0dabea-3112-4202-a4b9-6a525bcc19a9',
+ artifactUUId: null,
+ artifactType: 'SDNC_MODEL',
+ artifactVersion: '1.0.0',
+ artifactDescription: 'Controller Blueprint for vLB_CDS123:1.0.0',
+ internalVersion: null,
+ createdDate: '2019-10-30T13:55:16.000Z',
+ artifactName: 'vLB_CDS123',
+ published: 'N',
+ updatedBy: 'Abdelmuhaimen Seaudi',
+ tags: 'test, vDNS-CDS, SCALE-OUT, MARCO'
+ },
+ {
+ id: 'a741913f-2b1b-4eb8-94b3-8c6b08928f0a',
+ artifactUUId: null,
+ artifactType: 'SDNC_MODEL',
+ artifactVersion: '1.0.0',
+ artifactDescription: 'Controller Blueprint for vLB_CDS12312312:1.0.0',
+ internalVersion: null,
+ createdDate: '2019-10-30T14:58:04.000Z',
+ artifactName: 'vLB_CDS12312312',
+ published: 'N',
+ updatedBy: 'Abdelmuhaimen Seaudi',
+ tags: 'test, vDNS-CDS, SCALE-OUT, MARCO'
+ }
+ ],
+ pageable: {
+ sort: {
+ sorted: true,
+ unsorted: false,
+ empty: false
+ },
+ offset: 0,
+ pageSize: 2,
+ pageNumber: 0,
+ paged: true,
+ unpaged: false
+ },
+ last: false,
+ totalElements: 4,
+ totalPages: 2,
+ first: true,
+ empty: false
+ };
+}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.css
new file mode 100644
index 000000000..067d30d7f
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.css
@@ -0,0 +1,547 @@
+
+body{
+ background-image: linear-gradient(-45deg, #000 6%, #fff 0) !important;
+ background-size: 6px 6px !important;
+}
+
+
+/*Header*/
+header{
+ height: 60px;
+ background-color: #1B3E6F;
+ box-shadow: 0 4px 10px rgba(238, 240, 245, 1.0);
+}
+.logo{
+ float: left;
+ width: 50px;
+ height: 60px;
+ background: url(/assets/img/logo-icon.svg) center center #fff no-repeat;
+}
+
+/**Bread Crumb**/
+.breadcrumb{
+ padding: 9px 20px;
+ background: transparent;
+ line-height: 40px;
+}
+.breadcrumb a,
+.breadcrumb a:hover{
+ color: #fff;
+}
+.breadcrumb .breadcrumb-item{
+ font-size: 12px;
+ font-weight: bold;
+}
+.breadcrumb .breadcrumb-item:first-child{
+ font-size: 16px;
+}
+.breadcrumb-item + .breadcrumb-item::before{
+ color: #fff;
+}
+.breadcrumb .breadcrumb-item.active p{
+ display: inline;
+ padding: 4px 10px;
+ background: #F4F9FE;
+ border-radius: 10px;
+ color: #C3CDDB;
+ font-size: 10px;
+}
+.sidebar-container{
+ height: calc(100vh - 60px) !important;
+}
+/**Topology Actions**/
+.topology-actions{
+ margin: 0;
+ height: 60px;
+}
+.topology-actions > li{
+ height: 59px;
+ display: inline-block;
+ padding: 0 20px;
+}
+.topology-actions > li:first-child{
+ border-right: solid 1px #16396A;
+}
+.topology-actions .btn-group{
+ margin-top: 11px;
+}
+.btn-topology-action,
+.btn-topology-action:hover{
+ margin: 0 6px;
+ padding: 6px 10px;
+ color: #fff;
+ border-radius: 50%;
+ border: solid .5px #fff;
+}
+.btn-topology-action:last-child{
+ margin-right: 0;
+}
+.btn-topology-action .fa{
+ width: 16px;
+ height: 16px;
+ text-align: center;
+}
+.topology-actions .dropdown-text,
+.dropdown-toggle:hover ~ .dropdown-text,
+.dropdown-toggle:focus ~ .dropdown-text{
+ top: 7px;
+ text-indent: 15px;
+ background: #1273EB;
+ border-radius: 15px;
+ border: 0;
+ box-shadow: none;
+ color: #fff;
+ font-weight: bold;
+ font-size: 13px;
+}
+.topology-actions .dropdown-text::after{
+ right: 15px;
+ top: 13px;
+ border-width: 6px 6px 0 6px;
+ border-color: #fff transparent transparent transparent;
+}
+.topology-actions .dropdown-toggle:focus ~ .dropdown-text::after{
+ top: 13px;
+ border-width: 0 6px 6px 6px;
+ border-color: transparent transparent #fff transparent
+}
+.topology-actions .dropdown-content:hover,
+.topology-actions .dropdown-toggle:focus ~ .dropdown-content{
+ padding: 12px 0;
+ text-indent: 0;
+ background: #fff;
+ border: 0;
+ border-radius: 2px;
+ box-shadow: 0 2px 6px rgba(47, 83, 151, .15)
+}
+.topology-actions .dropdown-content a{
+ padding: 0 20px;
+ color: #1B3E6F;
+ font-size: 13px;
+}
+.topology-actions .dropdown-content a:hover{
+ background: #F4F9FE;
+ text-decoration: none;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*Rotated Text*/
+button.rotate{
+ position: absolute;
+ margin-top: 1px;
+ padding: 0;
+ background: transparent;
+ border: 0;
+}
+.rotate{
+ vertical-align: bottom;
+ /* text-align: center; */
+}
+.rotate span{
+ display: inline-table !important;
+ -ms-writing-mode: tb-rl;
+ -webkit-writing-mode: vertical-rl;
+ writing-mode: vertical-rl !important;
+ transform: rotate(180deg);
+ white-space: nowrap;
+ background: #1B3E6F;
+ padding: 15px 12px;
+ font-weight: bold;
+ font-size: 12px;
+ color:#fff;
+ /* border-bottom-left-radius: 2px; */
+ border-top-left-radius: 2px;
+}
+.rotate i{
+ margin-right: 3px;
+ margin-top: 9px;
+ font-size: 15px;
+}
+.rotate span:first-child{
+ margin-bottom: 0;
+}
+.rotate a:hover{
+ text-decoration: none;
+}
+
+/*ACTIONS & COMPONENTS MENU*/
+.input-search-controller{
+ height: 50px;
+ padding-left: 30px;
+ background: url(src/assets/img/icon-search-light.svg) #fff 10px center no-repeat;
+ border-radius: 0;
+ border: 0;
+ border-bottom: solid 1px #D7E7F9;
+ color: #1B3E6F;
+ font-size: 13px;
+}
+.input-search-controller::placeholder{
+ color: #D0D7E4;
+ font-size: 11px;
+}
+.input-search-controller:focus{
+
+ box-shadow: 0 2px 6px 0 rgba(47, 83, 151, .15);
+ border-color: #DEE8F3;
+}
+.actions-scroll{
+ max-height: 160px;
+ overflow-y: auto;
+ margin-top: 12px;
+ margin-bottom: 20px;
+}
+.componentsList p{
+ margin-bottom: 0;
+ padding-left: 30px;
+ background-position: left center;
+ background-repeat: no-repeat;
+}
+p.compType-1{
+ background-image: url(/assets/img/icon-comType1-sm.svg);
+}
+p.compType-2{
+ background-image: url(/assets/img/icon-comType2-sm.svg);
+}
+p.compType-3{
+ background-image: url(/assets/img/icon-comType3-sm.svg);
+}
+p.compType-4{
+ background-image: url(/assets/img/icon-comType4-sm.svg);
+}
+/*Actions Wrapper*/
+.actions-wrapper{
+ position: absolute;
+ width: 100%;
+ top: 0;
+}
+.actions-container{
+ width: 92%;
+ margin: 0 auto;
+ background: red;
+}
+
+.controllerSidebar{
+ width: 320px;
+ background: #F4F9FE;
+ border: solid 1px #C1CDDD;
+ box-shadow: 0 2px 6px rgba(47, 83, 151, .10);
+}
+.controllerSidebar h1{
+ margin-bottom: 15px;
+ padding: 12px 0 12px 12px;
+ background: #fff;
+ font-size: 12px;
+ font-weight: bold;
+ text-transform: uppercase;
+ color: #C3CDDB;
+}
+.controllerSidebar b{
+ font-size: 12px;
+ color: #C3CDDB;
+}
+.actionBtns .btn{
+ margin: 0 15px 12px;
+ padding: 9px 20px;
+ border-radius: 2px !important;
+ font-size: 12px;
+ font-weight: bold;
+}
+.actionBtns .btn:first-child{
+ background: #1B3E6F;
+ border: solid 1px #1B3E6F;
+ color: #fff;
+}
+.actionBtns .btn:last-child{
+ padding-left: 34px;
+ background: url(src/assets/img/icon-import-blue.svg) 12px center #fff no-repeat;
+ border: solid 1px #D0DFF1;
+ color: #1B3E6F;
+}
+.actionsList,
+.componentsList{
+ padding: 0 12px 20px;
+}
+.componentsList{
+ padding-bottom: 0;
+}
+.actionsList .custom-checkbox,
+.componentsList .list-group-item{
+ margin-bottom: 10px;
+ padding-left: 40px;
+ background: #fff;
+ box-shadow: 0 2px 6px rgba(47, 83, 151, .15);
+ border-radius: 2px;
+}
+.actionsList .custom-control-label{
+ width: 100%;
+ padding: 6px;
+ vertical-align: unset;
+ color: #1B3E6F;
+ font-size: 14px;
+ line-height: 20px;
+ border-top-right-radius: 2px;
+ border-bottom-right-radius: 2px;
+}
+.actionsList .custom-control-label::before,
+.actionsList .custom-control-label::after{
+ top: 1.25rem;
+}
+.actionsList .custom-control-label p{
+ color: #C7D0DD;
+ font-size: 12px;
+}
+.custom-control-input:checked ~ .custom-control-label{
+ background-color: #1B3E6F !important;
+ color: #fff;
+}
+.inserActionBtns .btn{
+ border-radius: 15px !important;
+ padding: 6px 20px;
+ font-size: 12px;
+ font-weight: bold;
+ border: 0;
+
+}
+.inserActionBtns .btn:first-child{
+ background: #1273EB;
+ border: solid 1px #1273EB;
+ color: #fff;
+}
+.inserActionBtns .btn:last-child{
+ background: #fff;
+ border: solid 1px #D9E6F2;
+ color: #C3CDDB;
+}
+/*Components List*/
+.componentsList .list-group-item{
+ padding-left: 36px;
+ border: 0;
+ font-size: 14px;
+ background: url(src/assets/img/icon-drag.svg) #fff 20px center no-repeat;
+}
+
+/*CANVAS*/
+.editBar{
+ width: 350px;
+ margin: 0 auto 0;
+ padding: 6px 10px;
+ background:#F4F9FE;
+ border: solid 1px #E8EFF8;
+ box-shadow: 0 2px 6px rgba(47, 83, 151, .1);
+ margin-left: 20em;
+}
+.editBar .btn-group{
+ box-shadow: 0 2px 6px rgba(47, 83, 151, .15);
+}
+.editBar .btn{
+ background-color: #fff;
+ background-repeat: no-repeat;
+ background-position: left center;
+ border: 0;
+ color: #1B3E6F;
+ font-size: 10px;
+}
+.editBar .btn.active{
+ background-color: #1B3E6F !important;
+ color: #fff;
+}
+.viewBtns .btn{
+ background-position: 10px center;
+ padding-left: 30px;
+}
+.viewBtns .topologySource{
+ background-image: url(src/assets/img/icon-topologyView-active.svg);
+}
+.viewBtns .topologyView{
+ background-image: url(src/assets/img/icon-topologySource.svg);
+}
+.card.actionContainer{
+ margin: 20px 20px 40px 60px;
+ background: transparent;
+ border: 0;
+}
+.actionContainer .card-header{
+ padding: 0;
+ background: transparent;
+ border: 0;
+}
+.actionContainer .card-header span{
+ padding: 12px 20px;
+ border-top-left-radius: 2px;
+ border-top-right-radius: 2px;
+ font-size: 12px;
+ line-height: 38px;
+ font-weight: bold;
+ color: #1B3E6F;
+ background: #C3CDDB;
+}
+.actionContainer .card-body{
+ min-height: 170px;
+ padding: 15px 20px !important;
+ border: solid 1px #C3CDDB;
+ background: #fff;
+ box-shadow: 0 2px 6px rgba(18, 115, 235, .1);
+}
+.actionContainer a{
+ display: inline-block;
+ width: 230px;
+ height: 130px;
+ margin: 20px;
+ padding: 24px;
+ background: #1B3E6F;
+ color: #fff !important;
+ text-align: center;
+ border-radius: 2px;
+ border: solid 1px #1B3E6F;
+}
+.actionContainer a:hover{
+ cursor: pointer;
+ border: dashed 1px #E9FCC6;
+}.componentContainer img{
+ height: 38px;
+}
+.componentContainer h2{
+ margin-top: 9px;
+ font-size: 14px;
+ font-weight: bold;
+}
+.componentContainer p{
+ font-size: 12px;
+}
+
+/*ATTRIBUTES SIDE BAR*/
+.attributesSideBar{
+ width: 396px;
+ padding: 0;
+}
+.attributesSideBar .attributesContainer{
+ background: #fff;
+ border: solid 1px #C1CDDD;
+ box-shadow: 0 2px 6px rgba(47, 83, 151, .1);
+}
+.closeBar{
+ float: right;
+ width: 90%;
+ height: 40px;
+ background: url(/assets/img/icon-close.svg) center center #DCE8F4 no-repeat ;
+ border: 0;
+ outline: 0;
+}
+.closeBar:focus{
+ outline: none;
+}
+.attributesContainer h1{
+ margin-bottom: 10px;
+ padding: 12px 0 12px 15px;
+ background: #DEE8F3;
+ font-size: 12px;
+ font-weight: bold;
+ text-transform: uppercase;
+ color: #1B3E6F;
+}
+.actionName{
+ margin-bottom: 21px;
+}
+.attributesContainer label{
+ color: #1B3E6F;
+ text-transform: uppercase;
+ font-size: 11px;
+ font-weight: bold;
+}
+.attributesContainer .form-group{
+ margin-bottom: 9px;
+}
+.attributesContainer .form-control{
+ border-color: #F0F5FC;
+ border-radius: 2px;
+ box-shadow: 0 2px 6px rgba(47, 83, 151, .1);
+ color: #103D73;
+ font-size: 13px;
+}
+.attributesContainer .form-control:focus{
+ border-color: #66bfff;
+ box-shadow: 0 0 0 4px rgba(0,149,255,0.15);
+}
+.attributesContainer .form-control::placeholder{
+ color: #CFD7E5;
+}
+.scrolll{
+ max-height: 88.75vh;
+ overflow-y: auto;
+}
+.accordion > .card{
+ margin-bottom: 0 !important;
+ border: 0;
+}
+.accordion > .card .card-header{
+ margin: 0;
+ padding: 0;
+ background-color: #F4F9FE;
+ border: 0;
+ border-radius: 0;
+}
+.accordion > .card .card-body{
+ padding-bottom: 10px !important;
+}
+.accordion .btn-link{
+ padding: 0;
+ color: #C3CDDB;
+ font-weight: bold;
+ font-size: 13px;
+ text-transform: uppercase;
+ line-height: 38px;
+}
+.accordion .btn-link:hover{
+ color: #103D73;
+ text-decoration: unset;
+}
+.accordion .card-header .btn-link[aria-expanded="true"]:after,
+.accordion .card-header .btn-link[aria-expanded="false"]:after{
+ margin-right: 9px;
+ font-family: 'FontAwesome';
+ float: left;
+ font-weight: normal;
+ font-size: 12px;
+}
+.accordion .card-header .btn-link[aria-expanded="true"]:after{
+ content: "\f078";
+}
+.accordion .card-header .btn-link[aria-expanded="false"]:after{
+ content: "\f054";
+}
+.btn-addAttribute{
+ width: 20px;
+ height: 20px;
+ background-image: url(/assets/img/icon-add.svg);
+ background-position: center center;
+ background-repeat: no-repeat;
+ vertical-align: sub;
+}
+.btn-addAttribute:hover{
+ background-image: url(/assets/img/icon-add-hover.svg);
+}
+.btn-deleteAttribute{
+ padding: 5px 10px;
+ background: #FFE6E7;
+ border: solid .5px #FFC9CB;
+ border-radius: 2px;
+ color: #FF6469;
+ font-size: 10px;
+
+} \ No newline at end of file
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html
new file mode 100644
index 000000000..991e126c0
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html
@@ -0,0 +1,337 @@
+<!--Header-->
+<header>
+ <div class="row m-0">
+ <div class="col pl-0">
+ <p class="logo mb-0"></p>
+ <nav aria-label="breadcrumb">
+ <ol class="breadcrumb mb-0">
+ <li class="breadcrumb-item">
+ <a href="#">CBA Packages</a>
+ </li>
+ <li class="breadcrumb-item">
+ <a href="#">Package Name</a>
+ </li>
+ <li class="breadcrumb-item active" aria-current="page">
+ <p class="mb-0">Topology View</p>
+ </li>
+ </ol>
+ </nav>
+ </div>
+ <div class="col pr-0 text-right">
+ <ul class="topology-actions">
+ <li>
+ <div class="btn-group" role="group" aria-label="Basic example">
+ <a href="#" role="button" aria-pressed="true" class="btn-topology-action float tooltip-bottom" data-tooltip="Preview">
+ <i class="fa fa-eye"></i>
+ </a>
+ <a href="#" role="button" aria-pressed="true" class="btn-topology-action float tooltip-bottom" data-tooltip="Download">
+ <i class="fa fa-download"></i>
+ </a>
+ <a href="#" role="button" aria-pressed="true" class="btn-topology-action float tooltip-bottom" data-tooltip="Share">
+ <i class="fa fa-share-square"></i>
+ </a>
+ </div>
+ </li>
+ <li>
+ <div class="dropdown">
+ <input class="dropdown-toggle" type="text">
+ <div class="dropdown-text">Save</div>
+ <ul class="dropdown-content">
+ <li>
+ <a href="">Save</a>
+ </li>
+ <li>
+ <a href="">Save &amp; Deploy</a>
+ </li>
+ </ul>
+ </div>
+ </li>
+ </ul>
+
+
+ </div>
+ </div>
+</header>
+<ng-sidebar-container class="sidebar-container">
+ <!-- Controller SideBar -->
+ <ng-sidebar [(opened)]="controllerSideBar" [sidebarClass]="'demo-sidebar controllerSidebar container-fluid'" [mode]="'push'"
+ #sidebarLeft>
+ <div class="row">
+ <div class="col-12 p-0">
+ <form>
+ <input type="text" class="form-control input-search-controller" placeholder="Search actions and functions">
+ </form>
+ </div>
+ <h1 class="col-12">Actions</h1>
+ <div class="col-12 text-center p-0">
+ <div class="btn-group actionBtns" role="group">
+ <button type="button" class="btn">Insert Custom</button>
+ <button type="button" class="btn">Import Action</button>
+ </div>
+ </div>
+ <div class="col-12 actionsList">
+ <b>Select from other packages:</b>
+ <div class="actions-scroll">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox" class="custom-control-input" id="customCheck1">
+ <label class="custom-control-label" for="customCheck1">Action name
+ <p class="m-0">Toplogy name</p>
+ </label>
+ </div>
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox" class="custom-control-input" id="customCheck2">
+ <label class="custom-control-label" for="customCheck2">Action name
+ <p class="m-0">Toplogy name</p>
+ </label>
+ </div>
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox" class="custom-control-input" id="customCheck3">
+ <label class="custom-control-label" for="customCheck3">Action name
+ <p class="m-0">Toplogy name</p>
+ </label>
+ </div>
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox" class="custom-control-input" id="customCheck4">
+ <label class="custom-control-label" for="customCheck4">Action name
+ <p class="m-0">Toplogy name</p>
+ </label>
+ </div>
+ </div>
+ <div class="btn-group inserActionBtns" role="group" aria-label="Basic example">
+ <button type="button" class="btn btn-secondary mr-3">Insert</button>
+ <button type="button" class="btn btn-secondary">Cancel</button>
+ </div>
+ </div>
+ <h1 class="col-12">Functions</h1>
+ <div class="col-12 componentsList">
+ <b>Drag and drop function to Action’s box</b>
+ <ul class="list-group actions-scroll">
+ <li class="list-group-item">
+ <p class="compType-1">component-resource-resolution</p>
+ </li>
+ <li class="list-group-item">
+ <p class="compType-2">component-netconf-executor</p>
+ </li>
+ <li class="list-group-item">
+ <p class="compType-3">component-remote-ansible-executor</p>
+ </li>
+ <li class="list-group-item">
+ <p class="compType-4">dg-generic</p>
+ </li>
+ <li class="list-group-item">
+ <p class="compType-1">component-resource-resolution</p>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </ng-sidebar>
+ <!-- Page content -->
+ <div ng-sidebar-content id="paper">
+ <button class="rotate" (click)="_toggleSidebar1()">
+ <span>
+ Controller
+ <i class="fa fa-angle-double-left"></i>
+ </span>
+ </button>
+ <!-- Canvas -->
+ <div class="editBar text-center">
+ <div class="btn-group mr-2" role="group" aria-label="First group">
+ <button type="button" class="btn btn-secondary tooltip-bottom" data-tooltip="Undo">
+ <img src="/assets/img/icon-undoActive.svg">
+ </button>
+ <button type="button" class="btn btn-secondary tooltip-bottom" data-tooltip="Redo">
+ <img src="/assets/img/icon-redo.svg">
+ </button>
+ </div>
+ <div class="btn-group mr-2" role="group" aria-label="Second group">
+ <button type="button" class="btn btn-secondary tooltip-bottom" data-tooltip="Zoom Out">
+ <img src="/assets/img/icon-zoomOut.svg">
+ </button>
+ <button type="button" class="btn btn-secondary pl-0 pr-0">100%</button>
+ <button type="button" class="btn btn-secondary tooltip-bottom" data-tooltip="Zoom In">
+ <img src="/assets/img/icon-zoomIn.svg">
+ </button>
+ </div>
+ <div class="btn-group viewBtns" role="group" aria-label="Third group">
+ <button type="button" class="btn btn-secondary topologySource active">View</button>
+ <button type="button" class="btn btn-secondary topologyView">Source</button>
+ </div>
+ </div>
+ <div class="card actionContainer">
+ <div class="card-header">
+ <span>Action 1</span>
+ </div>
+ <div class="card-body">
+ <a (click)="sidebarRight.open()" class="componentContainer text-center">
+ <img src="/assets/img/icon-comType1.svg" title="">
+ <h2>config-assign</h2>
+ <p>component-resource-resolution</p>
+ </a>
+ <a (click)="sidebarRight.open()" class="componentContainer text-center">
+ <img src="/assets/img/icon-comType2.svg" title="">
+ <h2>execute</h2>
+ <p>component-netconf-executor</p>
+ </a>
+ <a (click)="sidebarRight.open()" class="componentContainer text-center">
+ <img src="/assets/img/icon-comType3.svg" title="">
+ <h2>function 1</h2>
+ <p>dg-generic</p>
+ </a>
+ <a (click)="sidebarRight.open()" class="componentContainer text-center">
+ <img src="/assets/img/icon-comType2.svg" title="">
+ <h2>execute</h2>
+ <p>component-netconf-executor</p>
+ </a>
+ </div>
+ </div>
+ <!-- <button (click)="_toggleSidebar2()" style="float:right;">Toggle sidebar right</button> -->
+ </div>
+ <!-- Attribute SideBar -->
+ <ng-sidebar [(opened)]="attributesSideBar" [sidebarClass]="'demo-sidebar attributesSideBar '" [mode]="'push'" [position]="'right'"
+ #sidebarRight>
+ <div class="container-fluid0">
+ <div class="row m-0">
+ <div class="col-2 pr-0">
+ <button (click)="sidebarRight.close()" class="closeBar"></button>
+ </div>
+ <div class="col-10 attributesContainer p-0">
+ <h1>Action Attributes</h1>
+ <div class="scrolll">
+ <div class="row m-0">
+ <div class="col-12">
+ <div class="form-group actionName">
+ <label for="exampleInputEmail1">Action Name</label>
+ <input type="text" class="form-control" placeholder="Action 1">
+ </div>
+ </div>
+ </div>
+ <div class="accordion" id="accordionExample">
+ <div class="card">
+ <div class="card-header row" id="headingOne">
+ <h2 class="col-10 mb-0">
+ <button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
+ Steps
+ </button>
+ </h2>
+ <div class="col-2 p-0 text-center">
+ <button class="btn btn-addAttribute" type="button"></button>
+ </div>
+ </div>
+
+ <div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordionExample">
+ <div class="card-body">
+ <div class="row">
+ <div class="col-9">
+ <label for="exampleInputEmail1">Name</label> &nbsp;
+ <button type="button" class="btn p-0">
+ <img src="/assets/img/icon-edit.svg">
+ </button>
+ </div>
+ <div class="col-3">
+ <button type="button" class="btn btn-deleteAttribute">Delete</button>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="exampleInputEmail1">Name</label>
+ <input type="text" class="form-control" placeholder="Action 1">
+ </div>
+ <div class="form-group">
+ <label for="exampleFormControlTextarea1">Description</label>
+ <textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
+ </div>
+ <div class="form-group">
+ <label for="exampleInputEmail1">Target</label>
+ <input type="text" class="form-control" placeholder="Action 1">
+ </div>
+
+ </div>
+ </div>
+ </div>
+ <div class="card">
+ <div class="card-header row" id="headingTwo">
+ <h2 class="col-10 mb-0">
+ <button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="true" aria-controls="collapseTwo">
+ Inputs
+ </button>
+ </h2>
+ <div class="col-2 p-0 text-center">
+ <button class="btn btn-addAttribute" type="button"></button>
+ </div>
+ </div>
+ <div id="collapseTwo" class="collapse show" aria-labelledby="headingTwo" data-parent="#accordionExample">
+ <div class="card-body">
+ <div class="row">
+ <div class="col-9">
+ <label for="exampleInputEmail1">Name</label> &nbsp;
+ <button type="button" class="btn p-0">
+ <img src="/assets/img/icon-edit.svg">
+ </button>
+ </div>
+ <div class="col-3">
+ <button type="button" class="btn btn-deleteAttribute">Delete</button>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="exampleInputEmail1">Name</label>
+ <input type="text" class="form-control" placeholder="Action 1">
+ </div>
+ <div class="form-group">
+ <label for="exampleFormControlTextarea1">Description</label>
+ <textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
+ </div>
+ <div class="form-group">
+ <label for="exampleInputEmail1">Target</label>
+ <input type="text" class="form-control" placeholder="Action 1">
+ </div>
+
+ </div>
+ </div>
+ </div>
+ <div class="card">
+ <div class="card-header row" id="headingThree">
+ <h2 class="col-10 mb-0">
+ <button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapseThree" aria-expanded="true" aria-controls="collapseThree">
+ Outputs
+ </button>
+ </h2>
+ <div class="col-2 p-0 text-center">
+ <button class="btn btn-addAttribute" type="button"></button>
+ </div>
+ </div>
+ <div id="collapseThree" class="collapse show" aria-labelledby="headingThree" data-parent="#accordionExample">
+ <div class="card-body">
+ <div class="row">
+ <div class="col-9">
+ <label for="exampleInputEmail1">Name</label> &nbsp;
+ <button type="button" class="btn p-0">
+ <img src="/assets/img/icon-edit.svg">
+ </button>
+ </div>
+ <div class="col-3">
+ <button type="button" class="btn btn-deleteAttribute">Delete</button>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="exampleInputEmail1">Name</label>
+ <input type="text" class="form-control" placeholder="Action 1">
+ </div>
+ <div class="form-group">
+ <label for="exampleFormControlTextarea1">Description</label>
+ <textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
+ </div>
+ <div class="form-group">
+ <label for="exampleInputEmail1">Target</label>
+ <input type="text" class="form-control" placeholder="Action 1">
+ </div>
+
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </ng-sidebar>
+
+</ng-sidebar-container> \ No newline at end of file
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.spec.ts
new file mode 100644
index 000000000..3b767cb81
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DesignerComponent } from './designer.component';
+
+describe('DesignerComponent', () => {
+ let component: DesignerComponent;
+ let fixture: ComponentFixture<DesignerComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ DesignerComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DesignerComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts
new file mode 100644
index 000000000..547c1e574
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts
@@ -0,0 +1,128 @@
+import { Component, OnInit, ViewEncapsulation } from '@angular/core';
+import * as $ from 'jquery';
+import * as _ from 'lodash';
+import * as joint from '../../../../../../node_modules/jointjs/dist/joint.js';
+
+@Component({
+ selector: 'app-designer',
+ templateUrl: './designer.component.html',
+ styleUrls: ['./designer.component.css'],
+ encapsulation: ViewEncapsulation.None
+})
+export class DesignerComponent implements OnInit {
+
+ private controllerSideBar: boolean;
+ private attributesSideBar: boolean;
+ public graph: any;
+ public paper: any;
+
+ constructor() {
+ this.controllerSideBar = true;
+ this.attributesSideBar = false;
+ }
+ private _toggleSidebar1() {
+ this.controllerSideBar = !this.controllerSideBar;
+ }
+ private _toggleSidebar2() {
+ this.attributesSideBar = !this.attributesSideBar;
+ }
+
+
+ ngOnInit() {
+ this.attachEditorBarToCanvas();
+ }
+
+ attachEditorBarToCanvas() {
+ this.graph = new joint.dia.Graph,
+ this.paper = new joint.dia.Paper({
+ el: $('#paper'),
+ model: this.graph,
+ height: 720,
+ width: 1200,
+ gridSize: 2,
+ drawGrid: true,
+ cellViewNamespace: joint.shapes
+ });
+
+ this.paper.setGrid({
+ name: 'dot',
+ args:
+ { color: 'black', thickness: 2, scaleFactor: 8 }
+
+ }).drawGrid();
+
+
+ joint.shapes["html"] = {};
+ joint.shapes["html"].Element = joint.shapes.basic.Rect.extend({
+ defaults: joint.util.deepSupplement({
+ type: 'html.Element'
+ }, joint.shapes.basic.Rect.prototype.defaults)
+ });
+
+ joint.shapes["html"].ElementView = joint.dia.ElementView.extend({
+
+ template: [
+ '<div>',
+ '<div id="editbar" class="editBar text-center">',
+ '<div class="btn-group mr-2" role="group" aria-label="First group">',
+ '<button type="button" class="btn btn-secondary tooltip-bottom" data-tooltip="Undo">',
+ '<img src="/assets/img/icon-undoActive.svg">',
+ '</button>',
+ '<button type="button" class="btn btn-secondary tooltip-bottom" data-tooltip="Redo">',
+ '<img src="/assets/img/icon-redo.svg">',
+ '</button>',
+ '</div>',
+ '<div class="btn-group mr-2" role="group" aria-label="Second group">',
+ '<button type="button" class="btn btn-secondary tooltip-bottom" data-tooltip="Zoom Out">',
+ '<img src="/assets/img/icon-zoomOut.svg">',
+ '</button>',
+ '<button type="button" class="btn btn-secondary pl-0 pr-0">100%</button>',
+ '<button type="button" class="btn btn-secondary tooltip-bottom" data-tooltip="Zoom In">',
+ '<img src="/assets/img/icon-zoomIn.svg">',
+ '</button>',
+ '</div>',
+ '<div class="btn-group viewBtns" role="group" aria-label="Third group">',
+ '<button type="button" class="btn btn-secondary topologySource active">View</button>',
+ '<button type="button" class="btn btn-secondary topologyView">Source</button>',
+ '</div>',
+ '</div>',
+ '</div>'
+ ].join(''),
+
+ initialize: function() {
+ _.bindAll(this, 'updateBox');
+ joint.dia.ElementView.prototype.initialize.apply(this, arguments);
+
+ this.$box = $(_.template(this.template)());
+ // Prevent paper from handling pointerdown.
+ this.$box.find('input,select').on('mousedown click', function(evt) {
+ evt.stopPropagation();
+ });
+ this.model.on('change', this.updateBox, this);
+
+ this.updateBox();
+ },
+ render: function() {
+ joint.dia.ElementView.prototype.render.apply(this, arguments);
+ this.paper.$el.prepend(this.$box);
+ this.updateBox();
+ return this;
+ },
+ updateBox: function() {
+ // Set the position and dimension of the box so that it covers the JointJS element.
+ var bbox = this.model.getBBox();
+ this.$box.css({
+ width: bbox.width,
+ height: bbox.height,
+ left: bbox.x,
+ top: bbox.y,
+ transform: 'rotate(' + (this.model.get('angle') || 0) + 'deg)'
+ });
+ }
+ });
+
+ var el1 = new joint.shapes["html"].Element({});
+ this.graph.addCells([el1]);
+ }
+
+}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/model/BluePrint.model.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/model/BluePrint.model.ts
new file mode 100644
index 000000000..46dab88f8
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/model/BluePrint.model.ts
@@ -0,0 +1,58 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2019 Orange. All rights reserved.
+===================================================================
+
+Unless otherwise specified, all software contained herein is licensed
+under the Apache License, Version 2.0 (the License);
+you may not use this software 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.
+============LICENSE_END============================================
+*/
+
+import { Page } from 'src/app/common/model/page';
+
+export class BlueprintModel {
+
+
+ constructor(id: string, artifactUUId: null, artifactType: string,
+ artifactVersion: string, artifactDescription: string,
+ internalVersion: null, createdDate: string, artifactName: string,
+ published: string, updatedBy: string, tags: string) {
+ this.id = id;
+ this.artifactUUId = artifactUUId;
+ this.artifactType = artifactType;
+ this.artifactVersion = artifactVersion;
+ this.artifactDescription = artifactDescription;
+ this.internalVersion = internalVersion;
+ this.createdDate = createdDate;
+ this.artifactName = artifactName;
+ this.published = published;
+ this.updatedBy = updatedBy;
+ this.tags = tags;
+ }
+
+ id: string;
+ artifactUUId?: null;
+ artifactType: string;
+ artifactVersion: string;
+ artifactDescription: string;
+ internalVersion?: null;
+ createdDate: string;
+ artifactName: string;
+ published: string;
+ updatedBy: string;
+ tags: string;
+}
+
+export class BluePrintPage extends Page<BlueprintModel> {
+}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/model/packages-dashboard.state.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/model/packages-dashboard.state.ts
new file mode 100644
index 000000000..068e93160
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/model/packages-dashboard.state.ts
@@ -0,0 +1,33 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2019 Orange. All rights reserved.
+===================================================================
+
+Unless otherwise specified, all software contained herein is licensed
+under the Apache License, Version 2.0 (the License);
+you may not use this software 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.
+============LICENSE_END============================================
+*/
+
+import {BluePrintPage} from './BluePrint.model';
+
+export class PackagesDashboardState {
+
+ page: BluePrintPage;
+ command: string;
+ currentPage = 0;
+ totalPackages: number;
+ tags: string[];
+ sortBy = 'DATE';
+ totalPackagesWithoutSearchorFilters: number;
+}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.css
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.css
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.html
new file mode 100644
index 000000000..6ce3a53a1
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.html
@@ -0,0 +1,18 @@
+<div class="dropdown packagesFilter w-100">
+ <input class="dropdown-toggle" type="text">
+ <div class="dropdown-text">ALL PACKAGES TAGS</div>
+ <ul class="dropdown-content w-100">
+ <li>
+ <div class="form-group">
+ <input type="text" (input)="reloadChanges($event)" class="form-control" placeholder="Search" autofocus>
+ </div>
+ </li>
+ <li *ngFor="let tag of viewedTags">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox" (click)="reloadPackages($event)" class="custom-control-input" id={{tag}}>
+ <label class="custom-control-label" for={{tag}}>{{tag}}</label>
+ </div>
+ </li>
+ </ul>
+</div>
+
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.spec.ts
new file mode 100644
index 000000000..8285d8962
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.spec.ts
@@ -0,0 +1,45 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2019 Orange. All rights reserved.
+===================================================================
+
+Unless otherwise specified, all software contained herein is licensed
+under the Apache License, Version 2.0 (the License);
+you may not use this software 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.
+============LICENSE_END============================================
+*/
+
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { TagsFilteringComponent } from './filter-by-tags.component';
+
+describe('SearchByTagsComponent', () => {
+ let component: TagsFilteringComponent;
+ let fixture: ComponentFixture<TagsFilteringComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ TagsFilteringComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TagsFilteringComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.ts
new file mode 100644
index 000000000..b4007215a
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.ts
@@ -0,0 +1,100 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2019 Orange. All rights reserved.
+===================================================================
+
+Unless otherwise specified, all software contained herein is licensed
+under the Apache License, Version 2.0 (the License);
+you may not use this software 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.
+============LICENSE_END============================================
+*/
+
+import {Component, OnDestroy, OnInit} from '@angular/core';
+import {PackagesStore} from '../../packages.store';
+import {BlueprintModel, BluePrintPage} from '../../model/BluePrint.model';
+
+@Component({
+ selector: 'app-filter-by-tags',
+ templateUrl: './filter-by-tags.component.html',
+ styleUrls: ['./filter-by-tags.component.css']
+})
+
+export class TagsFilteringComponent implements OnInit {
+
+ page: BluePrintPage;
+ tags: string[] = [];
+ viewedTags: string[] = [];
+ searchTag = '';
+ viewedPackages: BlueprintModel[] = [];
+ private checkBoxTages = '';
+
+
+ constructor(private packagesStore: PackagesStore,
+ ) {
+ this.packagesStore.state$.subscribe(state => {
+ console.log(state);
+ if (state.page) {
+ this.viewedPackages = state.page.content;
+ this.viewedPackages.forEach(element => {
+ element.tags.split(',').forEach(tag => {
+ this.tags.push(tag.trim());
+ });
+ this.tags = this.tags.filter((value, index, self) => self.indexOf(value) === index);
+ this.assignTags();
+
+ });
+ }
+ });
+ }
+
+ ngOnInit() {
+
+ }
+
+ reloadChanges(event: any) {
+ this.searchTag = event.target.value;
+ this.filterItem(this.searchTag);
+ }
+
+ private assignTags() {
+ this.viewedTags = this.tags;
+ }
+
+ private filterItem(value) {
+ if (!value) {
+ this.assignTags();
+ }
+ this.viewedTags = this.tags.filter(
+ item => item.toLowerCase().indexOf(value.toLowerCase()) > -1
+ );
+ }
+
+ reloadPackages(event: any) {
+
+ if (!event.target.checked) {
+ this.checkBoxTages = this.checkBoxTages.replace(event.target.id + ',', '')
+ .replace(event.target.id, '');
+ } else {
+ this.checkBoxTages += event.target.id.trim() + ',';
+ }
+ console.log(this.checkBoxTages);
+ if (!this.checkBoxTages.includes(',')) {
+ return;
+ }
+ this.viewedPackages = [];
+ // this.packagesStore.getPagesFilterByTags(this.checkBoxTages);
+ // this.viewedPackages = this.viewedPackages.filter((value, index, self) => self.indexOf(value) === index);
+ }
+
+
+}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.css
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.css
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.html
new file mode 100644
index 000000000..18428d4b4
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.html
@@ -0,0 +1,104 @@
+<div class="row packages-card">
+ <div class="col-lg-3 col-md-6">
+ <!--Add Package Card-->
+ <div class="card addPaackage-card">
+ <div class="card-body text-center">
+ <img src="/assets/img/icon-addPackage.svg">
+ </div>
+ <div class="card-footer row">
+ <div class="col">
+ <a href="#" role="button" aria-pressed="true" class="btn-create-package float">Create Package
+ </a>
+ </div>
+ <div class="col">
+ <a href="#" role="button" aria-pressed="true" class="btn-import-package float">Import Package
+ </a>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="col-lg-3 col-md-6" *ngFor="let bluePrint of viewedPackages">
+
+ <!--Card 1-->
+ <div>
+ <div class="card">
+ <div class="card-body">
+ <div class="row">
+ <div class="col-9 pr-0">
+ <h5 class="card-title" [routerLink]="['/packages/package', bluePrint.id]" (click)="testDispatch(bluePrint)">
+ <img class="icon-deployed" src="/assets/img/icon-deploy.svg">
+ {{bluePrint.artifactName}}
+ </h5>
+
+ </div>
+ <div class="col-3">
+
+ <div class="dropdown">
+ <input class="dropdown-toggle" type="text">
+ <div class="dropdown-text">
+ <img src="/assets/img/icon-menuDots.svg" title="Actions">
+ </div>
+ <ul class="dropdown-content">
+ <li class="action-clone">
+ <a href="#">Clone</a>
+ </li>
+ <li class="action-archive">
+ <a href="#">Archive</a>
+ </li>
+ <li class="action-delete">
+ <a href="#">Delete</a>
+ </li>
+ </ul>
+ </div>
+
+ </div>
+ </div>
+ <div class="row">
+ <div class="col">
+ <p class="mb-0">Last modified {{ bluePrint.createdDate | date:'short' }}
+ </p>
+ <p>By {{bluePrint.updatedBy}}</p>
+ <ul class="package-contributers">
+ <li>
+ <button type="button" class="border-fade" data-toggle="tooltip"
+ data-placement="bottom"
+ title="User name">
+ <img src="/assets/img/img-user1.jpeg">
+ </button>
+ </li>
+ <li>
+ <button type="button" data-toggle="tooltip" data-placement="bottom"
+ title="User name">
+ <img src="/assets/img/img-user2.jpg">
+ </button>
+ </li>
+ <li>
+ <button type="button" data-toggle="tooltip" data-placement="bottom"
+ title="User name">
+ <img src="/assets/img/img-user3.jpg">
+ </button>
+ </li>
+ <li>
+ <a href="">5 contributors</a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ <div class="card-footer">
+ <div class="row">
+ <div class="col">
+ <button type="button" class="btn btn-card-topology">Topology View
+ </button>
+ </div>
+ <div class="col">
+ <button type="button" class="btn btn-card-config">Configuration</button>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ </div>
+
+ </div>
+ </div>
+</div>
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.spec.ts
new file mode 100644
index 000000000..f45f25996
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.spec.ts
@@ -0,0 +1,36 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { PackageListComponent } from './package-list.component';
+import { PackagesStore } from '../../packages.store';
+import { getBluePrintPageMock } from '../../blueprint.page.mock';
+import { of } from 'rxjs';
+
+describe('PackageListComponent', () => {
+ let component: PackageListComponent;
+ let fixture: ComponentFixture<PackageListComponent>;
+ let store: Partial<PackagesStore>;
+
+ beforeEach(async(() => {
+
+ store = { state$: of(getBluePrintPageMock()) };
+
+ TestBed.configureTestingModule({
+ declarations: [ PackageListComponent ],
+ providers: [{ provide: PackagesStore, useValue: store }]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(PackageListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+
+ // TODO create another test with store in mind
+});
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.ts
new file mode 100644
index 000000000..c7ec0af20
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.ts
@@ -0,0 +1,32 @@
+import {Component, OnInit} from '@angular/core';
+import {BlueprintModel} from '../../model/BluePrint.model';
+import {PackagesStore} from '../../packages.store';
+
+@Component({
+ selector: 'app-packages-list',
+ templateUrl: './package-list.component.html',
+ styleUrls: ['./package-list.component.css']
+})
+export class PackageListComponent implements OnInit {
+
+ viewedPackages: BlueprintModel[] = [];
+
+
+ constructor(private packagesStore: PackagesStore) {
+ console.log('PackageListComponent');
+ this.packagesStore.state$.subscribe(state => {
+ console.log(state);
+ if (state.page) {
+ this.viewedPackages = state.page.content;
+ }
+ });
+ }
+
+ ngOnInit() {
+ this.packagesStore.getAll();
+ }
+
+ testDispatch(bluePrint: BlueprintModel) {
+ console.log(bluePrint.id);
+ }
+}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.css
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.css
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.html
new file mode 100644
index 000000000..b5245f757
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.html
@@ -0,0 +1,7 @@
+<!--Package Paginator-->
+<div class="col package-paginator pr-0">
+ <ngb-pagination [collectionSize]="totalCount" [(page)]="pageNumber" [pageSize]="pageSize" class="float-right"
+ (pageChange)="getPageFromService($event)"
+
+ ></ngb-pagination>
+</div>
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.spec.ts
new file mode 100644
index 000000000..ce7f99f62
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { PackagePaginationComponent } from './package-pagination.component';
+
+describe('PackagePaginationComponent', () => {
+ let component: PackagePaginationComponent;
+ let fixture: ComponentFixture<PackagePaginationComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ PackagePaginationComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(PackagePaginationComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.ts
new file mode 100644
index 000000000..49f91316b
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-pagination/package-pagination.component.ts
@@ -0,0 +1,41 @@
+import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core';
+import {PackagesStore} from '../../packages.store';
+import {map} from 'rxjs/operators';
+
+@Component({
+ selector: 'app-package-pagination',
+ templateUrl: './package-pagination.component.html',
+ styleUrls: ['./package-pagination.component.css'],
+})
+export class PackagePaginationComponent implements OnInit {
+ pageNumber: number;
+ totalCount: number;
+ pageSize: number;
+ previousPage: number;
+
+ constructor(private packagesStore: PackagesStore) {
+ this.pageSize = packagesStore.pageSize;
+
+ this.packagesStore.state$
+ .subscribe(state => {
+ this.pageNumber = state.currentPage;
+ this.totalCount = state.totalPackages;
+ });
+ }
+
+ ngOnInit() {
+ }
+
+ public getPageFromService(page) {
+ console.log('getPageFromService', page);
+ if (isNaN(page)) {
+ page = 1;
+ console.log('page change to first...', page);
+ }
+ if (this.previousPage !== page) {
+ this.packagesStore.getPage(page - 1, this.packagesStore.pageSize);
+ this.previousPage = page;
+ }
+ }
+
+}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/packages-dahsboard.component.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/packages-dahsboard.component.spec.ts
new file mode 100644
index 000000000..fe156b6cb
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/packages-dahsboard.component.spec.ts
@@ -0,0 +1,44 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2019 Orange. All rights reserved.
+===================================================================
+
+Unless otherwise specified, all software contained herein is licensed
+under the Apache License, Version 2.0 (the License);
+you may not use this software 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.
+============LICENSE_END============================================
+*/
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { PackagesDashboardComponent } from './packages-dashboard.component';
+
+describe('PackagesDashboardComponent', () => {
+ let component: PackagesDashboardComponent;
+ let fixture: ComponentFixture<PackagesDashboardComponent>;
+
+ beforeEach(async(() => {
+
+
+ TestBed.configureTestingModule({
+ declarations: [PackagesDashboardComponent ],
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(PackagesDashboardComponent);
+ component = fixture.componentInstance;
+ }));
+
+ fit('should create', () => {
+ fixture.detectChanges();
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/packages-dashboard.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/packages-dashboard.component.css
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/packages-dashboard.component.css
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/packages-dashboard.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/packages-dashboard.component.html
new file mode 100644
index 000000000..ac510893b
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/packages-dashboard.component.html
@@ -0,0 +1,61 @@
+<app-header>
+</app-header>
+<div class="new-wrapper">
+ <div class="container-fluid main-container">
+
+ <div class="container-fluid body-container">
+ <nav class="row">
+ <!--Nav Tabs-->
+ <div class="col pr-0">
+ <div class="nav nav-tabs " id="nav-tab" role="tablist">
+ <a class="nav-item nav-link active" id="nav-home-tab" data-toggle="tab" href="#nav-home"
+ role="tab" aria-controls="nav-home"
+ aria-selected="true">All</a>
+ <a class="nav-item nav-link" id="nav-profile-tab" data-toggle="tab" href="#nav-profile"
+ role="tab" aria-controls="nav-profile"
+ aria-selected="false">Deployed</a>
+ <a class="nav-item nav-link" id="nav-contact-tab" data-toggle="tab" href="#nav-contact"
+ role="tab" aria-controls="nav-contact"
+ aria-selected="false">Under Construction</a>
+ <a class="nav-item nav-link" id="nav-contact1-tab" data-toggle="tab" href="#nav-contact1"
+ role="tab" aria-controls="nav-contact1"
+ aria-selected="false">Archived</a>
+ </div>
+ </div>
+ <!--Nav Search & Filter-->
+ <div class="col search-filter-col">
+ <div class="row">
+ <div class="col-7">
+ <app-packages-search></app-packages-search>
+ </div>
+ <div class="col-5 pl-2">
+ <app-filter-by-tags class="w-100"></app-filter-by-tags>
+ </div>
+
+ </div>
+ </div>
+ </nav>
+ <div class="row mt-4">
+ <div class="col">
+ <div class="tab-content" id="nav-tabContent">
+ <div class="tab-pane fade show active" id="nav-home" role="tabpanel" aria-labelledby="nav-home-tab">
+ <div class="row">
+ <div class="col sort-packages">
+
+ </div>
+ <app-package-pagination></app-package-pagination>
+
+ </div>
+ <app-packages-list></app-packages-list>
+
+ </div>
+ <div class="tab-pane fade" id="nav-profile" role="tabpanel" aria-labelledby="nav-profile-tab">...</div>
+ <div class="tab-pane fade" id="nav-contact" role="tabpanel" aria-labelledby="nav-contact-tab">...</div>
+ <div class="tab-pane fade" id="nav-contact1" role="tabpanel" aria-labelledby="nav-contact1-tab">...
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/packages-dashboard.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/packages-dashboard.component.ts
new file mode 100644
index 000000000..4e33a9df1
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/packages-dashboard.component.ts
@@ -0,0 +1,37 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2019 Orange. All rights reserved.
+===================================================================
+
+Unless otherwise specified, all software contained herein is licensed
+under the Apache License, Version 2.0 (the License);
+you may not use this software 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.
+============LICENSE_END============================================
+*/
+import {Component, OnInit} from '@angular/core';
+import {PackagesStore} from '../packages.store';
+
+@Component({
+ selector: 'app-packages-dashboard',
+ templateUrl: './packages-dashboard.component.html',
+ styleUrls: ['./packages-dashboard.component.css']
+})
+export class PackagesDashboardComponent implements OnInit {
+
+ constructor() { }
+
+ ngOnInit() {
+
+ console.log('PackagesDashboardComponent');
+ }
+}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/search-by-packages/search-by-packages.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/search-by-packages/search-by-packages.component.css
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/search-by-packages/search-by-packages.component.css
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/search-by-packages/search-by-packages.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/search-by-packages/search-by-packages.component.html
new file mode 100644
index 000000000..e7c605fd1
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/search-by-packages/search-by-packages.component.html
@@ -0,0 +1,4 @@
+<div class="searchBox">
+ <input class="searchInput" [ngClass]="{'searchBox-expanded': searchQuery}" (input)="searchPackages($event)" type="text" name="" placeholder="Search packages">
+ <button class="searchButton" href="#"></button>
+</div> \ No newline at end of file
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/search-by-packages/search-by-packages.component.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/search-by-packages/search-by-packages.component.spec.ts
new file mode 100644
index 000000000..7e50c55cc
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/search-by-packages/search-by-packages.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { PackagesSearchComponent } from './search-by-packages.component';
+
+describe('PackagesSearchComponent', () => {
+ let component: PackagesSearchComponent;
+ let fixture: ComponentFixture<PackagesSearchComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [PackagesSearchComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(PackagesSearchComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/search-by-packages/search-by-packages.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/search-by-packages/search-by-packages.component.ts
new file mode 100644
index 000000000..91304e5c2
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/search-by-packages/search-by-packages.component.ts
@@ -0,0 +1,25 @@
+import {Component, OnInit} from '@angular/core';
+import {PackagesStore} from '../../packages.store';
+
+@Component({
+ selector: 'app-packages-search',
+ templateUrl: './search-by-packages.component.html',
+ styleUrls: ['./search-by-packages.component.css']
+})
+export class PackagesSearchComponent implements OnInit {
+
+ private searchQuery = '';
+
+ constructor(private packagesStore: PackagesStore) {
+ }
+
+ ngOnInit() {
+ }
+
+
+ searchPackages(event: any) {
+ this.searchQuery = event.target.value;
+ this.searchQuery = this.searchQuery.trim();
+ this.packagesStore.search(this.searchQuery);
+ }
+}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-list.service.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-list.service.ts
new file mode 100644
index 000000000..e8a98099c
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-list.service.ts
@@ -0,0 +1,66 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2019 Orange. All rights reserved.
+===================================================================
+
+Unless otherwise specified, all software contained herein is licensed
+under the Apache License, Version 2.0 (the License);
+you may not use this software 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.
+============LICENSE_END============================================
+*/
+
+import {Injectable} from '@angular/core';
+import {Observable} from 'rxjs';
+import {ApiService} from '../../../common/core/services/api.typed.service';
+import {BlueprintURLs} from '../../../common/constants/app-constants';
+import {BlueprintModel, BluePrintPage} from './model/BluePrint.model';
+
+
+@Injectable({
+ providedIn: 'root'
+})
+export class PackagesListService {
+ packages: BlueprintModel[] = [];
+ private numberOfPackages: number;
+
+ constructor(private api: ApiService<BluePrintPage>) {
+ }
+
+ getPagedPackages(pageNumber: number, pageSize: number, sortBy: string): Observable<BluePrintPage[]> {
+ return this.api.get(BlueprintURLs.getPagedBlueprints, {
+ offset: pageNumber,
+ limit: pageSize,
+ sort: sortBy
+ });
+ }
+
+ searchByTags(keyword: string): Observable<any> {
+ return this.api.get(BlueprintURLs.getMetaDate + '/' + keyword);
+ }
+
+ getCountOfAllPackages(observable: Observable<number>) {
+ observable.subscribe(data => {
+ this.numberOfPackages = data;
+ console.log(data);
+ });
+ }
+
+ getPagedPackagesByKeyWord(keyWord: string, pageNumber: number, pageSize: number, sortBy: string) {
+
+ return this.api.get(BlueprintURLs.getMetaDatePageable + '/' + keyWord, {
+ offset: pageNumber,
+ limit: pageSize,
+ sort: sortBy
+ });
+ }
+}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.module.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.module.ts
new file mode 100644
index 000000000..f24ae8b00
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.module.ts
@@ -0,0 +1,36 @@
+import {NgModule} from '@angular/core';
+import {CommonModule} from '@angular/common';
+import {ApiService} from '../../../common/core/services/api.typed.service';
+import {PackagesRoutingModule} from './packages.routing.module';
+import {NgbPaginationModule} from '@ng-bootstrap/ng-bootstrap';
+import { SharedModulesModule } from '../../shared-modules/shared-modules.module';
+import { PackagesDashboardComponent } from './packages-dashboard/packages-dashboard.component';
+import { PackageListComponent } from './packages-dashboard/package-list/package-list.component';
+import { DesignerComponent } from './designer/designer.component';
+import { SidebarModule } from 'ng-sidebar';
+import { PackagePaginationComponent } from './packages-dashboard/package-pagination/package-pagination.component';
+import { PackagesSearchComponent } from './packages-dashboard/search-by-packages/search-by-packages.component';
+import { TagsFilteringComponent } from './packages-dashboard/filter-by-tags/filter-by-tags.component';
+
+
+
+@NgModule({
+ declarations: [PackagesDashboardComponent,
+ TagsFilteringComponent,
+ PackageListComponent,
+ DesignerComponent,
+ PackagePaginationComponent,
+ PackagesSearchComponent,
+ ],
+ imports: [
+ CommonModule,
+ PackagesRoutingModule,
+ NgbPaginationModule,
+ SharedModulesModule,
+ SidebarModule.forRoot(),
+ ],
+ providers: [ApiService],
+ bootstrap: []
+})
+export class PackagesModule {
+}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.routing.module.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.routing.module.ts
new file mode 100644
index 000000000..83044dde5
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.routing.module.ts
@@ -0,0 +1,20 @@
+import {NgModule} from '@angular/core';
+import {Routes, RouterModule} from '@angular/router';
+import {PackagesDashboardComponent} from './packages-dashboard/packages-dashboard.component';
+import {DesignerComponent} from './designer/designer.component';
+
+
+const routes: Routes = [
+ {
+ path: '',
+ component: PackagesDashboardComponent
+ },
+ {path: 'designer', component: DesignerComponent},
+];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
+})
+export class PackagesRoutingModule {
+}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.store.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.store.spec.ts
new file mode 100644
index 000000000..b091ed90e
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.store.spec.ts
@@ -0,0 +1,44 @@
+import { TestBed } from '@angular/core/testing';
+import { PackagesStore } from './packages.store';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { PackagesListService } from './packages-list.service';
+import { of } from 'rxjs';
+import { BluePrintPage } from './model/BluePrint.model';
+import { getBluePrintPageMock } from './blueprint.page.mock';
+
+describe('PackagesStore', () => {
+ let store: PackagesStore;
+
+ const MOCK_BLUEPRINTS_PAGE: BluePrintPage = getBluePrintPageMock();
+
+ let httpMock: HttpTestingController;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ HttpClientTestingModule
+ ],
+ providers: [
+ PackagesStore,
+ PackagesListService
+ ]
+ });
+ httpMock = TestBed.get(HttpTestingController);
+
+ });
+
+ it('should correctly get page of packages', () => {
+ const packagesServiceSpy = jasmine.createSpyObj('PackagesListService', ['getPagedPackages']);
+
+ // set the value to return when the `getPagedPackages` spy is called.
+ packagesServiceSpy.getPagedPackages.and.returnValue(of([MOCK_BLUEPRINTS_PAGE]));
+ store = new PackagesStore(packagesServiceSpy);
+
+ store.getPagedPackages(0, 2);
+ store.state$.subscribe(page => {
+ expect(store.state).toEqual(MOCK_BLUEPRINTS_PAGE);
+ });
+
+ });
+});
+
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.store.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.store.ts
new file mode 100644
index 000000000..d770bf737
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.store.ts
@@ -0,0 +1,104 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2019 Orange. All rights reserved.
+===================================================================
+
+Unless otherwise specified, all software contained herein is licensed
+under the Apache License, Version 2.0 (the License);
+you may not use this software 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.
+============LICENSE_END============================================
+*/
+
+import {Injectable} from '@angular/core';
+import {BluePrintPage} from './model/BluePrint.model';
+import {Store} from '../../../common/core/stores/Store';
+import {PackagesListService} from './packages-list.service';
+import {PackagesDashboardState} from './model/packages-dashboard.state';
+
+
+@Injectable({
+ providedIn: 'root'
+})
+export class PackagesStore extends Store<PackagesDashboardState> {
+ // TDOD fixed for now as there is no requirement to change it from UI
+ public pageSize = 5;
+
+ constructor(private packagesServiceList: PackagesListService) {
+ super(new PackagesDashboardState());
+ }
+
+ public getAll() {
+ console.log('getting all packages...');
+ this.getPagedPackages(0, this.pageSize);
+ }
+
+ public search(command: string) {
+ if (command) {
+ this.searchPagedPackages(command, 0, this.pageSize);
+ } else {
+ this.getPagedPackages(0, this.pageSize);
+ }
+ }
+
+ public getPage(pageNumber: number, pageSize: number) {
+ if (this.isCommandExist()) {
+ this.searchPagedPackages(this.state.command, pageNumber, pageSize);
+ } else {
+ this.getPagedPackages(pageNumber, pageSize);
+ }
+ }
+
+ public sortPagedPackages(sortBy: string) {
+ if (this.isCommandExist()) {
+ this.searchPagedPackages(this.state.command, this.state.currentPage, this.pageSize, sortBy);
+ } else {
+ this.getPagedPackages(this.state.currentPage, this.pageSize, sortBy);
+ }
+
+ }
+
+ private getPagedPackages(pageNumber: number, pageSize: number, sortBy: string = this.state.sortBy) {
+
+ this.packagesServiceList.getPagedPackages(pageNumber, pageSize, sortBy)
+ .subscribe((pages: BluePrintPage[]) => {
+ this.setState({
+ ...this.state,
+ page: pages[0],
+ command: '',
+ totalPackages: pages[0].totalElements,
+ currentPage: pageNumber,
+ // this param is set only in get all as it represents the total number of pacakges in the server
+ totalPackagesWithoutSearchorFilters: pages[0].totalElements,
+ sortBy
+ });
+ });
+ }
+
+ private searchPagedPackages(keyWord: string, pageNumber: number, pageSize: number, sortBy: string = this.state.sortBy) {
+ this.packagesServiceList.getPagedPackagesByKeyWord(keyWord, pageNumber, pageSize, sortBy)
+ .subscribe((pages: BluePrintPage[]) => {
+ this.setState({
+ ...this.state,
+ page: pages[0],
+ command: keyWord,
+ totalPackages: pages[0].totalElements,
+ currentPage: pageNumber,
+ sortBy
+ });
+ });
+ }
+
+ private isCommandExist() {
+ return this.state.command;
+ }
+}