diff --git a/src/ui_ng/lib/README.md b/src/ui_ng/lib/README.md
index 89e903d13..47cd19d79 100644
--- a/src/ui_ng/lib/README.md
+++ b/src/ui_ng/lib/README.md
@@ -74,13 +74,14 @@ Use **withTitle** to set whether self-contained a header with title or not. Defa
 Support two different display scope mode: under specific project or whole system. 
 
 If **projectId** is set to the id of specified project, then only show the replication rules bound with the project. Otherwise, show all the rules of the whole system.
+On specific project mode, without need projectId, but also need to provide projectName for display.
 
 **withReplicationJob** is used to determine whether or not show the replication jobs which are relevant with the selected replication rule.
 
-**readonly** is to disable all the create/edit/delete actions.
+**isSystemAdmin** is for judgment if user has administrator privilege, if true, user can do the create/edit/delete/replicate actions.
 
 ```
-<hbr-replication [projectId]="..." [withReplicationJob]='...' [readonly]="..."></hbr-replication>
+<hbr-replication [projectId]="..." [projectName]="..." [withReplicationJob]='...' [isSystemAdmin]="..."></hbr-replication>
 ```
 
 * **Endpoint Management View**
diff --git a/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.css.ts b/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.css.ts
index 83aaea83c..c0e232338 100644
--- a/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.css.ts
+++ b/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.css.ts
@@ -1,5 +1,70 @@
 export const CREATE_EDIT_RULE_STYLE: string = `
-.form-group-label-override {
-    font-size: 14px;
-    font-weight: 400;
-}`;
\ No newline at end of file
+/**
+ * Created by pengf on 9/28/2017.
+ */
+
+.select{
+    width: 186px;
+}
+.select .optionMore{
+    background-color: #bfbaba;
+    height: 1.6em;
+    font-size: 1.2em;
+    cursor: pointer;
+    text-align: center;
+}
+.hideFilter{ display: none;}
+h4{
+    color: #666;
+}
+.colorRed{color: red;}
+.colorRed a{text-decoration: underline;color: #007CBB;}
+.alertLabel{display:block; margin-top:0; line-height:1em; font-size:12px;}
+
+.inputWidth{width: 270px;}
+.endpointSelect{ width: 270px; margin-right: 20px;}
+.filterSelect{width: 315px;}
+.filterSelect clr-icon{margin-left: 15px;}
+.filterSelect label{width: 136px;}
+.filterSelect label input{width: 100%;}
+.cursor{cursor: pointer;}
+.pull-left{float: left;}
+.padLeft0{padding-left: 0;}
+.floatSetPar{display: inline-block; width: 120px;margin-right: 10px;}
+.floatSet {display: inline-block; width: 82px;margin-right: 4px;}
+.form-group{ min-height: 36px;}
+
+.projectInput{float: left;position: relative;}
+.switchIcon{width:20px;height:20px; margin-top: 10px;margin-left: 10px; cursor: pointer;}
+.addEndpoint{  margin-top: .25em !important;padding-left:2px;padding-right:2px;min-width:58px;margin-right:0}
+.shadow{position: absolute;top: 8px;}
+.is-solid{cursor: pointer;}
+.selectBox{
+    position: absolute;
+    width: 100%;
+    height: auto;
+    margin-top:-0.25rem;
+    border: 1px solid #ccc;
+    background-color: white;
+    border: 1px solid rgba(0,0,0,.15);
+    border-right-width: 2px;
+    border-bottom-width: 2px;
+    border-radius: 6px;
+    box-shadow: 0 5px 10px rgba(0,0,0,.2);
+    z-index: 100;
+}
+.selectBox ul li{
+    list-style: none;
+    padding: 3px 20px
+}
+.selectBox ul li:hover{
+    color: #262626;
+    background-image: linear-gradient(180deg,#f5f5f5 0,#e8e8e8);
+    background-repeat: repeat-x;
+}
+.form-group-override{
+    padding-left: 170px !important;
+}
+.form-group>label:first-child{font-size:14px; width:6.5rem;}
+.goLink{color:blue; border-bottom:1px solid blue; line-height:14px; cursor:pointer;}
+`;
\ No newline at end of file
diff --git a/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.html.ts b/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.html.ts
index 046f9587b..8817523d7 100644
--- a/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.html.ts
+++ b/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.html.ts
@@ -1,100 +1,134 @@
 export const CREATE_EDIT_RULE_TEMPLATE: string = `
-<clr-modal [(clrModalOpen)]="createEditRuleOpened" [clrModalStaticBackdrop]="staticBackdrop" [clrModalClosable]="closable">
-  <h3 class="modal-title">{{modalTitle}}</h3>
+<clr-modal [(clrModalOpen)]="createEditRuleOpened" [clrModalStaticBackdrop]="true" [clrModalClosable]="false">
+  <h3 class="modal-title">{{headerTitle | translate}}</h3>
   <hbr-inline-alert class="modal-title" (confirmEvt)="confirmCancel($event)"></hbr-inline-alert>
   <div class="modal-body" style="max-height: 85vh;">
-    <form #ruleForm="ngForm">
-      <section class="form-block">
-        <div class="alert alert-warning" *ngIf="!editable">
-          <div class="alert-item static">
-            <div class="alert-icon-wrapper">
-              <clr-icon class="alert-icon" shape="exclamation-circle"></clr-icon>
-            </div>
-            <span class="alert-text">
-              {{'REPLICATION.CANNOT_EDIT' | translate}}
-            </span>
-          </div>
+    <form [formGroup]="ruleForm"  novalidate>
+     <section class="form-block">
+      <div class="form-group form-group-override">
+       <label class="form-group-label-override required">{{'REPLICATION.NAME' | translate}}</label>
+       <label aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left"
+              [class.invalid]='(ruleForm.controls.name.touched && ruleForm.controls.name.invalid) || isRuleNameExist'>
+        <input type="text" id="ruleName" pattern="^[a-z0-9]+(?:[._-][a-z0-9]+)*$" class="inputWidth" required maxlength="255" formControlName="name" #ruleName (keyup)='checkRuleName()' autocomplete="off">
+        <span class="tooltip-content">{{ruleNameTooltip | translate}}</span>
+       </label><span class="spinner spinner-inline spinner-pos" [hidden]="!inNameChecking"></span>
+      </div>
+      <!--Description-->
+      <div class="form-group form-group-override">
+       <label class="form-group-label-override">{{'REPLICATION.DESCRIPTION' | translate}}</label>
+       <textarea type="text" id="ruleDescription" class="inputWidth" row= 3; formControlName="description"></textarea>
+      </div>
+      <!--Projects-->
+      <div class="form-group form-group-override">
+       <label class="form-group-label-override required">{{'REPLICATION.SOURCE' | translate}}&nbsp;{{'PROJECT.PROJECTS' | translate | lowercase}}</label>
+       <div formArrayName="projects">
+        <div class="projectInput inputWidth" *ngFor="let project of projects.controls; let i= index" [formGroupName]="i" (mouseleave)="leaveInput()">
+         <input *ngIf="!projectId" formControlName="name" type="text" class="inputWidth"  value="name" required
+                pattern="^[a-z0-9]+(?:[._-][a-z0-9]+)*$" (keyup)='handleValidation()' (focus)="focusClear($event)" autocomplete="off">
+         <input *ngIf="projectId" formControlName="name" type="text"  class="inputWidth"  value="name" readonly>
+         <div class="selectBox inputWidth"  [style.display]="selectedProjectList.length ? 'block' : 'none'" >
+          <ul>
+           <li *ngFor="let project of selectedProjectList" (click)="selectedProjectName(project?.name)">{{project?.name}}</li>
+          </ul>
+         </div>
         </div>
-        <div class="form-group">
-          <label for="policy_name" class="col-md-4 form-group-label-override">{{'REPLICATION.NAME' | translate}}<span style="color: red">*</span></label>
-          <label for="policy_name" class="col-md-8"  aria-haspopup="true" role="tooltip" [class.invalid]="name.errors && (name.dirty || name.touched)" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
-            <input type="text" id="policy_name" [(ngModel)]="createEditRule.name" name="name" size="20" #name="ngModel" required [readonly]="readonly">
-            <span class="tooltip-content" *ngIf="name.errors && name.errors.required && (name.dirty || name.touched)">
-              {{'REPLICATION.NAME_IS_REQUIRED' | translate}}
-            </span>
+       </div>
+       <label *ngIf="noProjectInfo.length != 0" class="colorRed alertLabel">{{noProjectInfo | translate}}</label>
+      </div>
+    
+    <!--images/Filter-->
+      <div class="form-group form-group-override">
+       <label class="form-group-label-override">{{'REPLICATION.SOURCE_IMAGES_FILTER' | translate}}</label>
+       <div formArrayName="filters">
+        <div class="filterSelect" *ngFor="let filter of filters.controls; let i=index"  [formGroupName]="i">
+         <div>
+          <div class="select floatSetPar">
+           <select formControlName="kind" (change)="filterChange($event)"  id="{{i}}" name="{{filterListData[i]?.name}}">
+            <option *ngFor="let filter of filterListData[i]?.options;" value="{{filter}}">{{filter}}</option>
+           </select>
+          </div>
+          <label aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left"
+                 [class.invalid]='ruleForm.controls.filters.controls[i].controls.pattern.touched && ruleForm.controls.filters.controls[i].controls.pattern.invalid'>
+           <input type="text" #filterValue required size="14" formControlName="pattern">
+           <span class="tooltip-content">{{'TOOLTIP.EMPTY' | translate}}</span>
           </label>
+          <clr-icon shape="times-circle" class="is-solid"  (click)="deleteFilter(i)"></clr-icon>
+         </div>
         </div>
-        <div class="form-group">
-          <label for="policy_description" class="col-md-4 form-group-label-override">{{'REPLICATION.DESCRIPTION' | translate}}</label>
-          <textarea class="col-md-8" id="policy_description" row="3" [(ngModel)]="createEditRule.description" name="description" size="20" #description="ngModel" [readonly]="readonly"></textarea>
+       </div>
+        <clr-icon shape="plus-circle" class="is-solid" [hidden]="isFilterHide" (click)="addNewFilter()" style="margin-top: 11px;"></clr-icon>
+      </div>
+      <!--Targets-->
+      <div class="form-group form-group-override">
+       <label class="form-group-label-override  required">{{'DESTINATION.ENDPOINT' | translate}}</label>
+       <div formArrayName="targets">
+        <div class="select endpointSelect pull-left" *ngFor="let target of targets.controls; let i= index" [formGroupName]="i">
+          <select id="ruleTarget" (change)="targetChange($event)"  formControlName="id">
+           <option *ngFor="let target of targetList" value="{{target.id}}">{{target.name}}-{{target.endpoint}}</option>
+          </select>
+         </div>
+       </div>
+       <label *ngIf="noEndpointInfo.length != 0" class="colorRed alertLabel">{{noEndpointInfo | translate}}</label>
+       <span class="goLink" *ngIf="noEndpointInfo.length != 0" (click)="goRegistry()">{{'SIDE_NAV.SYSTEM_MGMT.REGISTRY' | translate}}</span>
+       </div>
+    
+      <!--Trigger-->
+      <div class="form-group form-group-override">
+       <label class="form-group-label-override">{{'REPLICATION.TRIGGER_MODE' | translate}}</label>
+       <div  formGroupName="trigger">
+        <!--on trigger-->
+        <div class="select floatSetPar">
+         <select id="ruleTrigger" formControlName="kind"  (change)="selectTrigger($event)">
+          <option value="Manual">{{'REPLICATION.MANUAL' | translate}}</option>
+          <option value="Immediate">{{'REPLICATION.IMMEDIATE' | translate}}</option>
+          <option value="Scheduled">{{'REPLICATION.SCHEDULE' | translate}}</option>
+         </select>
         </div>
-        <div class="form-group">
-          <label class="col-md-4 form-group-label-override">{{'REPLICATION.ENABLE' | translate}}</label>
-          <div class="checkbox-inline">
-            <input type="checkbox" id="policy_enable" [(ngModel)]="createEditRule.enable" name="enable" #enable="ngModel" [disabled]="untoggleable">
-            <label for="policy_enable"></label>
+        <!--on push-->
+        <div formGroupName="schedule_param">
+          <div class="select floatSet" [hidden]="!isScheduleOpt">
+           <select name="scheduleType" formControlName="type" (change)="selectSchedule($event)">
+            <option value="Daily">{{'REPLICATION.DAILY' | translate}}</option>
+            <option value="Weekly">{{'REPLICATION.WEEKLY' | translate}}</option>
+           </select>
           </div>
-        </div>
-        <div class="form-group">
-          <label for="destination_name" class="col-md-4 form-group-label-override">{{'REPLICATION.DESTINATION_NAME' | translate}}<span style="color: red">*</span></label>
-          <div class="select" *ngIf="!isCreateEndpoint">
-            <select id="destination_name" [(ngModel)]="createEditRule.endpointId" name="endpointId" (change)="selectEndpoint()" [disabled]="testOngoing || readonly">
-              <option *ngFor="let t of endpoints" [value]="t.id" [selected]="t.id == createEditRule.endpointId">{{t.name}}</option>
-            </select>
-          </div>
-          <label class="col-md-8" *ngIf="isCreateEndpoint" for="destination_name" aria-haspopup="true" role="tooltip" [class.invalid]="endpointName.errors && (endpointName.dirty || endpointName.touched)"
-            class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
-            <input type="text" id="destination_name" [(ngModel)]="createEditRule.endpointName" name="endpointName" size="8" #endpointName="ngModel" value="" required> 
-            <span class="tooltip-content" *ngIf="endpointName.errors && endpointName.errors.required && (endpointName.dirty || endpointName.touched)">
-              {{'REPLICATION.DESTINATION_NAME_IS_REQUIRED' | translate}}
-            </span>
-          </label>
-          <div class="checkbox-inline" *ngIf="showNewDestination">
-            <input type="checkbox" id="check_new" (click)="newEndpoint(checkedAddNew.checked)" #checkedAddNew [checked]="isCreateEndpoint" [disabled]="testOngoing || readonly">
-            <label for="check_new">{{'REPLICATION.NEW_DESTINATION' | translate}}</label>
+          <!--weekly-->
+          <span [hidden]="!weeklySchedule || !isScheduleOpt">on &nbsp;</span>
+          <div  [hidden]="!weeklySchedule || !isScheduleOpt" class="select floatSet" style="width:104px">
+           <select name="scheduleDay" formControlName="weekday">
+            <option value="1">{{'WEEKLY.MONDAY' | translate}}</option>
+            <option value="2">{{'WEEKLY.TUESDAY' | translate}}</option>
+            <option value="3">{{'WEEKLY.WEDNESDAY' | translate}}</option>
+            <option value="4">{{'WEEKLY.THURSDAY' | translate}}</option>
+            <option value="5">{{'WEEKLY.FRIDAY' | translate}}</option>
+            <option value="6">{{'WEEKLY.SATURDAY' | translate}}</option>
+            <option value="7">{{'WEEKLY.SUNDAY' | translate}}</option>
+           </select>
           </div>
+          <!--daily/time-->
+          <span [hidden]="!isScheduleOpt">at &nbsp;</span>
+          <input [hidden]="!isScheduleOpt" type="time" formControlName="offtime"  required value="08:00" />
         </div>
-        <div class="form-group">
-          <label for="destination_url" class="col-md-4 form-group-label-override">{{'REPLICATION.DESTINATION_URL' | translate}}<span style="color: red">*</span></label>
-          <label for="destination_url" class="col-md-8" aria-haspopup="true" role="tooltip" [class.invalid]="endpointUrl.errors && (endpointUrl.dirty || endpointUrl.touched)"
-            class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
-            <input type="text" id="destination_url" [disabled]="testOngoing" [readonly]="readonly || !isCreateEndpoint"
-            [(ngModel)]="createEditRule.endpointUrl" size="20" name="endpointUrl" required #endpointUrl="ngModel">
-            <span class="tooltip-content" *ngIf="endpointUrl.errors && endpointUrl.errors.required && (endpointUrl.dirty || endpointUrl.touched)">
-              {{'REPLICATION.DESTINATION_URL_IS_REQUIRED' | translate}}
-            </span>
-          </label>
-        </div>
-        <div class="form-group">
-          <label for="destination_username" class="col-md-4 form-group-label-override">{{'REPLICATION.DESTINATION_USERNAME' | translate}}</label>
-          <input type="text" class="col-md-8" id="destination_username" [disabled]="testOngoing" [readonly]="readonly || !isCreateEndpoint" 
-          [(ngModel)]="createEditRule.username" size="20" name="username" #username="ngModel">
-        </div>
-        <div class="form-group">
-          <label for="destination_password" class="col-md-4 form-group-label-override">{{'REPLICATION.DESTINATION_PASSWORD' | translate}}</label>
-          <input type="password" class="col-md-8" id="destination_password" [disabled]="testOngoing" [readonly]="readonly || !isCreateEndpoint" 
-          [(ngModel)]="createEditRule.password" size="20" name="password" #password="ngModel">
-        </div>
-        <div class="form-group">
-          <label for="destination_insecure" class="col-md-4 form-group-label-override">{{'CONFIG.VERIFY_REMOTE_CERT' | translate }}</label>
-          <clr-checkbox #insecure  class="col-md-8" name="insecure" id="destination_insecure" [clrChecked]="!createEditRule.insecure"  [clrDisabled]="readonly || !isCreateEndpoint || testOngoing" (clrCheckedChange)="setInsecureValue($event)">
-             <a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right" style="top:-7px;">
-                    <clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
-                    <span class="tooltip-content">{{'CONFIG.TOOLTIP.VERIFY_REMOTE_CERT' | translate}}</span>
-                 </a>
-          </clr-checkbox>
-        </div>
-        <div class="form-group">
-          <label for="spin" class="col-md-4"></label>
-          <span class="col-md-8 spinner spinner-inline" [hidden]="!testOngoing"></span>
-          <span [style.color]="!pingStatus ? 'red': ''" class="form-group-label-override">{{ pingTestMessage }}</span>
-        </div>
-      </section>
+       </div>
+       <div style="width: 100%;" [hidden]="!isImmediate">
+        <clr-checkbox [clrChecked]="false" id="ruleDeletion" formControlName="replicate_deletion">
+         {{'REPLICATION.DELETE_REMOTE_IMAGES' | translate}}
+        </clr-checkbox>
+       </div>
+       <div  style="width: 100%;" >
+        <clr-checkbox [clrChecked]="true" id="ruleExit" formControlName="replicate_existing_image_now">
+         {{'REPLICATION.REPLICATE_IMMEDIATE' | translate}}
+        </clr-checkbox>
+       </div>
+      </div>
+      <div style="display:block;text-align:center">
+       <span class="spinner spinner-inline" [hidden]="inProgress === false"></span>
+     </div>
+     </section>
     </form>
   </div>
   <div class="modal-footer">
-      <button type="button" class="btn btn-outline" (click)="testConnection()" [disabled]="testOngoing || endpointUrl.errors || connectAbled">{{'REPLICATION.TEST_CONNECTION' | translate}}</button>
-      <button type="button" class="btn btn-outline" [disabled]="btnAbled" (click)="onCancel()">{{'BUTTON.CANCEL' | translate }}</button>
-      <button type="submit" class="btn btn-primary" [disabled]="!ruleForm.form.valid || testOngoing || !editable" (click)="onSubmit()">{{'BUTTON.OK' | translate}}</button>
+    <button type="button" id="ruleBtnCancel" class="btn btn-outline" [disabled]="this.inProgress" (click)="onCancel()">{{ 'BUTTON.CANCEL' | translate }}</button>
+    <button type="submit" id="ruleBtnOk" class="btn btn-primary"  (click)="onSubmit()" [disabled]="!ruleForm.valid || !isValid || !hasFormChange()">{{ 'BUTTON.SAVE' | translate }}</button>
   </div>
 </clr-modal>`;
diff --git a/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.spec.ts b/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.spec.ts
index 5485cdd1a..06118b582 100644
--- a/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.spec.ts
+++ b/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.spec.ts
@@ -1,4 +1,4 @@
-import { ComponentFixture, TestBed, async } from '@angular/core/testing'; 
+import { ComponentFixture, TestBed, async } from '@angular/core/testing';
 import { By } from '@angular/platform-browser';
 import { DebugElement } from '@angular/core';
 import { NoopAnimationsModule } from "@angular/platform-browser/animations";
@@ -25,52 +25,55 @@ import {
   JobLogDefaultService
  } from '../service/index';
 import { EndpointService, EndpointDefaultService } from '../service/endpoint.service';
+import {ProjectDefaultService, ProjectService} from "../service/project.service";
 import { JobLogViewerComponent } from '../job-log-viewer/job-log-viewer.component';
+import {Project} from "../project-policy-config/project";
 
 describe('CreateEditRuleComponent (inline template)', ()=>{
 
   let mockRules: ReplicationRule[] = [
     {
         "id": 1,
-        "project_id": 1,
-        "project_name": "library",
-        "target_id": 1,
-        "target_name": "target_01",
         "name": "sync_01",
-        "enabled": 0,
         "description": "",
-        "cron_str": "",    
-        "error_job_count": 2,
-        "deleted": 0
-    },
-    {
-        "id": 2,
-        "project_id": 1,
-        "project_name": "library",
-        "target_id": 3,
-        "target_name": "target_02",
-        "name": "sync_02",
-        "enabled": 1,
-        "description": "",
-        "cron_str": "",
-        "error_job_count": 1,
-        "deleted": 0
-    },
-    {
-        "id": 3,
-        "project_id": 1,
-        "project_name": "library",
-        "target_id": 2,
-        "target_name": "target_03",
-        "name": "sync_03",
-        "enabled": 0,
-        "description": "",
-        "cron_str": "",
-        "error_job_count": 0,
-        "deleted": 0
-    }
-  ];
-
+        "projects": [{ "project_id": 1,
+          "owner_id": 0,
+          "name": 'project_01',
+          "creation_time": '',
+          "deleted": 0,
+          "owner_name": '',
+          "togglable": false,
+          "update_time": '',
+          "current_user_role_id": 0,
+          "repo_count": 0,
+          "has_project_admin_role": false,
+          "is_member": false,
+          "role_name": '',
+          "metadata": {
+              "public": '',
+              "enable_content_trust": '',
+              "prevent_vul": '',
+              "severity": '',
+              "auto_scan": '',
+          }
+        }],
+        "targets": [{
+            "id": 1,
+            "endpoint": "https://10.117.4.151",
+            "name": "target_01",
+            "username": "admin",
+            "password": "",
+            "insecure": false,
+            "type": 0
+        }],
+        "trigger": {
+            "kind": "Manual",
+            "schedule_param": null
+        },
+        "filters": [],
+        "replicate_existing_image_now": false,
+        "replicate_deletion": false,
+    }]
   let mockJobs: ReplicationJobItem[] = [
     {
         "id": 1,
@@ -144,17 +147,68 @@ describe('CreateEditRuleComponent (inline template)', ()=>{
 
   let mockRule: ReplicationRule = {
       "id": 1,
-      "project_id": 1,
-      "project_name": "library",
-      "target_id": 1,
-      "target_name": "target_01",
       "name": "sync_01",
-      "enabled": 0,
       "description": "",
-      "cron_str": "",    
-      "error_job_count": 2,
-      "deleted": 0
-  };
+      "projects": [{ "project_id": 1,
+          "owner_id": 0,
+          "name": 'project_01',
+          "creation_time": '',
+          "deleted": 0,
+          "owner_name": '',
+          "togglable": false,
+          "update_time": '',
+          "current_user_role_id": 0,
+          "repo_count": 0,
+          "has_project_admin_role": false,
+          "is_member": false,
+          "role_name": '',
+          "metadata": {
+              "public": '',
+              "enable_content_trust": '',
+              "prevent_vul": '',
+              "severity": '',
+              "auto_scan": '',
+          }
+      }],
+      "targets": [{
+          "id": 1,
+          "endpoint": "https://10.117.4.151",
+          "name": "target_01",
+          "username": "admin",
+          "password": "",
+          "insecure": false,
+          "type": 0
+      }],
+      "trigger": {
+          "kind": "Manual",
+          "schedule_param": null
+      },
+      "filters": [],
+      "replicate_existing_image_now": false,
+      "replicate_deletion": false,
+  }
+  let mockProjects: Project[] = [
+        { "project_id": 1,
+            "owner_id": 0,
+            "name": 'project_01',
+            "creation_time": '',
+            "deleted": 0,
+            "owner_name": '',
+            "togglable": false,
+            "update_time": '',
+            "current_user_role_id": 0,
+            "repo_count": 0,
+            "has_project_admin_role": false,
+            "is_member": false,
+            "role_name": '',
+            "metadata": {
+                "public": '',
+                "enable_content_trust": '',
+                "prevent_vul": '',
+                "severity": '',
+                "auto_scan": '',
+            }
+        }];
 
   let fixture: ComponentFixture<ReplicationComponent>;
   let fixtureCreate: ComponentFixture<CreateEditRuleComponent>;
@@ -164,7 +218,7 @@ describe('CreateEditRuleComponent (inline template)', ()=>{
 
   let replicationService: ReplicationService;
   let endpointService: EndpointService;
- 
+
   let spyRules: jasmine.Spy;
   let spyOneRule: jasmine.Spy;
 
@@ -172,12 +226,11 @@ describe('CreateEditRuleComponent (inline template)', ()=>{
   let spyEndpoint: jasmine.Spy;
 
   let config: IServiceConfig = {
-    replicationRuleEndpoint: '/api/policies/replication/testing',
     replicationJobEndpoint: '/api/jobs/replication/testing',
     targetBaseEndpoint: '/api/targets/testing'
   };
 
-  beforeEach(async(()=>{
+  beforeEach(async(() =>{
     TestBed.configureTestingModule({
       imports: [ 
         SharedModule,
@@ -198,6 +251,7 @@ describe('CreateEditRuleComponent (inline template)', ()=>{
         { provide: SERVICE_CONFIG, useValue: config },
         { provide: ReplicationService, useClass: ReplicationDefaultService },
         { provide: EndpointService, useClass: EndpointDefaultService },
+        { provide: ProjectService, useClass: ProjectDefaultService },
         { provide: JobLogService, useClass: JobLogDefaultService }
       ]
     });
@@ -205,28 +259,27 @@ describe('CreateEditRuleComponent (inline template)', ()=>{
 
   beforeEach(()=>{
     fixture = TestBed.createComponent(ReplicationComponent);
-
+    fixtureCreate = TestBed.createComponent(CreateEditRuleComponent);
     comp = fixture.componentInstance;
+    compCreate = fixtureCreate.componentInstance;
     comp.projectId = 1;
     comp.search.ruleId = 1;
 
     replicationService = fixture.debugElement.injector.get(ReplicationService);
-   
+
+
+    endpointService = fixtureCreate.debugElement.injector.get(EndpointService) ;
+
     spyRules = spyOn(replicationService, 'getReplicationRules').and.returnValues(Promise.resolve(mockRules));
     spyOneRule = spyOn(replicationService, 'getReplicationRule').and.returnValue(Promise.resolve(mockRule));
     spyJobs = spyOn(replicationService, 'getJobs').and.returnValues(Promise.resolve(mockJob));
-    fixture.detectChanges();
-  });
 
-  beforeEach(()=>{
-    fixtureCreate = TestBed.createComponent(CreateEditRuleComponent);
-    
-    compCreate = fixtureCreate.componentInstance;
-    compCreate.projectId = 1;
 
-    endpointService = fixtureCreate.debugElement.injector.get(EndpointService);
     spyEndpoint = spyOn(endpointService, 'getEndpoints').and.returnValues(Promise.resolve(mockEndpoints));
+
     fixture.detectChanges();
+
+
   });
 
   it('Should open creation modal and load endpoints', async(()=>{
diff --git a/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.ts b/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.ts
index 64c367732..f15a8a810 100644
--- a/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.ts
+++ b/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.ts
@@ -11,437 +11,699 @@
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 // limitations under the License.
-import { Component, Input, Output, EventEmitter, ViewChild, AfterViewChecked } from '@angular/core';
-
-import { NgForm } from '@angular/forms';
-
-import { ReplicationService } from '../service/replication.service';
-import { EndpointService } from '../service/endpoint.service';
-
-import { ErrorHandler } from '../error-handler/error-handler';
-import { ActionType } from '../shared/shared.const';
-
+import {Component, OnInit, OnDestroy, ViewChild, ChangeDetectorRef, Input, EventEmitter, Output} from '@angular/core';
+import {Filter, ReplicationRule, Endpoint} from "../service/interface";
+import {Subject} from "rxjs/Subject";
+import {Subscription} from "rxjs/Subscription";
+import {FormArray, FormBuilder, FormGroup, Validators} from "@angular/forms";
+import {CreateEditEndpointComponent} from "../create-edit-endpoint/create-edit-endpoint.component";
+import {Router, ActivatedRoute} from "@angular/router";
+import {compareValue, isEmptyObject, toPromise} from "../utils";
 import { InlineAlertComponent } from '../inline-alert/inline-alert.component';
+import {ReplicationService} from "../service/replication.service";
+import {CREATE_EDIT_RULE_TEMPLATE} from "./create-edit-rule.component.html";
+import {CREATE_EDIT_RULE_STYLE} from "./create-edit-rule.component.css";
+import {ErrorHandler} from "../error-handler/error-handler";
+import {TranslateService} from "@ngx-translate/core";
+import {EndpointService} from "../service/endpoint.service";
+import {ProjectService} from "../service/project.service";
+import {Project} from "../project-policy-config/project";
 
-import { ReplicationRule } from '../service/interface';
-import { Endpoint } from '../service/interface';
+const ONE_HOUR_SECONDS = 3600;
+const ONE_DAY_SECONDS: number = 24 * ONE_HOUR_SECONDS;
 
-import { TranslateService } from '@ngx-translate/core';
-
-import { CREATE_EDIT_RULE_STYLE } from './create-edit-rule.component.css';
-import { CREATE_EDIT_RULE_TEMPLATE } from './create-edit-rule.component.html';
-
-import { toPromise } from '../utils';
-
-/**
- * Rule form model.
- */
-export interface CreateEditRule {
-  ruleId?: number | string;
-  name?: string;
-  description?: string;
-  enable?: boolean;
-  endpointId?: number | string;
-  endpointName?: string;
-  endpointUrl?: string;
-  username?: string;
-  password?: string;
-  insecure?: boolean;
-}
-
-const FAKE_PASSWORD: string = 'ywJZnDTM';
-
-@Component({
-  selector: 'create-edit-rule',
+@Component ({
+  selector: 'hbr-create-edit-rule',
   template: CREATE_EDIT_RULE_TEMPLATE,
-  styles: [ CREATE_EDIT_RULE_STYLE ]
+  styles: [CREATE_EDIT_RULE_STYLE]
+
 })
-export class CreateEditRuleComponent implements AfterViewChecked {
 
-  modalTitle: string;
+export class CreateEditRuleComponent implements OnInit, OnDestroy {
+  _localTime: Date = new Date();
+  targetList: Endpoint[] = [];
+  projectList: Project[] = [];
+  selectedProjectList: Project[] = [];
+  isFilterHide = false;
+  weeklySchedule: boolean;
+  isScheduleOpt: boolean;
+  isImmediate = false;
+  noProjectInfo = "";
+  noEndpointInfo = "";
+  noSelectedProject = true;
+  noSelectedEndpoint = true;
+  filterCount = 0;
+  triggerNames: string[] = ['Manual', 'Immediate', 'Scheduled'];
+  scheduleNames: string[] = ['Daily', 'Weekly'];
+  weekly: string[] = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
+  filterSelect: string[] = ['repository', 'tag'];
+  ruleNameTooltip = 'TOOLTIP.EMPTY';
+  headerTitle = 'REPLICATION.ADD_POLICY';
+
   createEditRuleOpened: boolean;
-  createEditRule: CreateEditRule = this.initCreateEditRule;
-  initVal: CreateEditRule = this.initCreateEditRule;
-  
-  actionType: ActionType;
-  
-  isCreateEndpoint: boolean;
+  filterListData: {[key: string]: any}[] = [];
+  inProgress = false;
+  inNameChecking = false;
+  isRuleNameExist = false;
+  nameChecker: Subject<string> = new Subject<string>();
+  proNameChecker: Subject<string> = new Subject<string>();
+  firstClick = 0;
+  policyId: number;
+
+  confirmSub: Subscription;
+  ruleForm: FormGroup;
+  copyUpdateForm: ReplicationRule;
+
   @Input() projectId: number;
+  @Input() projectName: string;
 
-  @Output() reload = new EventEmitter();
-
-  endpoints: Endpoint[];
-  
-  pingTestMessage: string;
-  testOngoing: boolean;
-  pingStatus: boolean;
-
-  btnAbled:boolean;
-
-
-  ruleForm: NgForm;
-
-  staticBackdrop: boolean = true;
-  closable: boolean = false;
-
-  @ViewChild('ruleForm')
-  currentForm: NgForm;
-
-  hasChanged: boolean;
-
-  editable: boolean;
-
-  get initCreateEditRule(): CreateEditRule {
-    return {
-      endpointId: '',
-      name: '',
-      enable: false,
-      description: '',
-      endpointName: '',
-      endpointUrl: '',
-      username: '',
-      password: '',
-      insecure: false
-    };
-  }
-
-  get initReplicationRule(): ReplicationRule {
-    return {
-      project_id: '',
-      project_name: '',
-      target_id: '',
-      target_name: '',
-      enabled: 0,
-      description: '',
-      cron_str: '',
-      error_job_count: 0,
-      deleted: 0
-    };
-  }
-
-  get initEndpoint(): Endpoint {
-    return {
-      endpoint: '',
-      name: '',
-      username: '',
-      password: '',
-      insecure: false,
-      type: 0
-    };
-  }
+  @Output() goToRegistry = new EventEmitter<any>();
+  @Output() reload = new EventEmitter<boolean>();
 
   @ViewChild(InlineAlertComponent)
   inlineAlert: InlineAlertComponent;
 
-  get readonly(): boolean {
-    return this.actionType === ActionType.EDIT && (this.createEditRule.enable || false);
+  emptyProject = {
+    project_id: -1,
+    name: '',
   }
-
-  get untoggleable(): boolean {
-    return this.actionType === ActionType.EDIT && (this.initVal.enable || false);
+  emptyEndpoint = {
+    id: -1,
+    endpoint: '',
+    name: '',
+    username: '',
+    password: '',
+    insecure: true,
+    type: 0,
   }
-
-
-  get showNewDestination(): boolean {
-    return this.actionType === ActionType.ADD_NEW || (!this.createEditRule.enable || false);
-  }
-  get connectAbled():boolean{
-    return !this.createEditRule.endpointId &&  !this.isCreateEndpoint;
-
-  }
-
   constructor(
-    private replicationService: ReplicationService,
-    private endpointService: EndpointService,
-    private errorHandler: ErrorHandler,
-    private translateService: TranslateService) {}
-  
-  prepareTargets(endpointId?: number | string) {
+              private fb: FormBuilder,
+              private repService: ReplicationService,
+              private endpointService: EndpointService,
+              private errorHandler: ErrorHandler,
+              private proService: ProjectService,
+              private translateService: TranslateService,
+              public ref: ChangeDetectorRef) {
+    this.createForm();
+  }
+
+  baseFilterData(name: string, option: string[], state: boolean) {
+    return {
+      name: name,
+      options: option,
+      state: state,
+      isValid: true
+    };
+  }
+
+  ngOnInit(): void {
     toPromise<Endpoint[]>(this.endpointService
         .getEndpoints())
-        .then(endpoints=>{
-            this.endpoints = endpoints; 
-            if(this.endpoints && this.endpoints.length > 0) {
-              let initialEndpoint: Endpoint | undefined;
-              (endpointId) ? initialEndpoint = this.endpoints.find(t=>t.id===endpointId) : initialEndpoint = this.endpoints[0]; 
-              if(!initialEndpoint) {
-                return;
-              } 
-              this.createEditRule.endpointId = initialEndpoint.id;
-              this.createEditRule.endpointName = initialEndpoint.name;
-              this.createEditRule.endpointUrl = initialEndpoint.endpoint;
-              this.createEditRule.username = initialEndpoint.username;
-              this.createEditRule.insecure = initialEndpoint.insecure;
-              this.createEditRule.password = FAKE_PASSWORD;
+        .then(targets => {
+          this.targetList = targets || [];
+        }).catch((error: any) => this.errorHandler.error(error));
 
-              this.initVal.endpointId = this.createEditRule.endpointId;
-              this.initVal.endpointUrl = this.createEditRule.endpointUrl;
-              this.initVal.username = this.createEditRule.username;
-              this.initVal.password = this.createEditRule.password;
-              this.initVal.insecure = this.createEditRule.insecure;
+    if (!this.projectId) {
+      toPromise<Project[]>(this.proService.listProjects("", undefined))
+          .then(targets => {
+            this.projectList = targets || [];
+          }).catch(error => this.errorHandler.error(error));
+    }
+
+    this.nameChecker.debounceTime(500).distinctUntilChanged().subscribe((ruleName: string) => {
+      this.isRuleNameExist = false;
+      this.inNameChecking = true;
+      toPromise<ReplicationRule[]>(this.repService.getReplicationRules(0, ruleName))
+          .then(response => {
+            if (response.some(rule => rule.name === ruleName)) {
+              this.ruleNameTooltip = 'TOOLTIP.RULE_USER_EXISTING';
+              this.isRuleNameExist = true;
             }
-          })
-          .catch(error=>{ 
-            this.errorHandler.error(error);
-            this.createEditRuleOpened = false;
-          });
+            this.inNameChecking = false;
+          }).catch(() => {
+        this.inNameChecking = false;
+      });
+    });
+
+    this.proNameChecker
+        .debounceTime(500)
+        .distinctUntilChanged()
+        .subscribe((name: string) => {
+            this.noProjectInfo = '';
+            this.selectedProjectList = [];
+            toPromise<Project[]>(this.proService.listProjects(name, undefined)).then((res: any) => {
+              if (res) {
+                this.selectedProjectList = res.slice(0, 10);
+                // if input value exit in project list
+                let pro = res.find((data: any) => data.name === name);
+                if (!pro) {
+                  this.noProjectInfo = 'REPLICATION.PROJECT_NOT_EXIST_INFO';
+                  this.noSelectedProject = true;
+                } else {
+                  this.noProjectInfo = '';
+                  this.noSelectedProject = false;
+                  this.setProject([pro])
+                }
+              } else {
+                this.noProjectInfo = 'REPLICATION.PROJECT_NOT_EXIST_INFO';
+                this.noSelectedProject = true;
+              }
+            }).catch((error: any) => {
+              this.errorHandler.error(error);
+              this.noProjectInfo = 'REPLICATION.PROJECT_NOT_EXIST_INFO';
+              this.noSelectedProject = true;
+              });
+        });
   }
 
-  openCreateEditRule(editable: boolean, ruleId?: number | string): void {
+    ngOnDestroy(): void {
+        if (this.confirmSub) {
+            this.confirmSub.unsubscribe();
+        }
+        if (this.nameChecker) {
+            this.nameChecker.unsubscribe();
+        }
+        if (this.proNameChecker) {
+            this.proNameChecker.unsubscribe();
+        }
+    }
 
-    this.createEditRule = this.initCreateEditRule;
-    this.editable = editable;
+  get isValid() {
+    return !(this.isRuleNameExist || this.noSelectedProject || this.noSelectedEndpoint || this.inProgress );
+  }
 
-    this.isCreateEndpoint = false;
-    this.hasChanged = false;
+  createForm() {
+    this.ruleForm = this.fb.group({
+      name: ['', Validators.required],
+      description: '',
+      projects: this.fb.array([]),
+      targets: this.fb.array([]),
+      trigger: this.fb.group({
+        kind: this.triggerNames[0],
+        schedule_param: this.fb.group({
+          type: this.scheduleNames[0],
+          weekday: 1,
+          offtime: '08:00'
+        }),
+      }),
+      filters: this.fb.array([]),
+      replicate_existing_image_now: true,
+      replicate_deletion: false
+    });
+  }
 
-    this.pingTestMessage = '';
-    this.pingStatus = true;
-    this.testOngoing = false;  
+  initForm(): void {
+    this.ruleForm.reset({
+      name: '',
+      description: '',
+      trigger: {kind: this.triggerNames[0], schedule_param: {
+          type: this.scheduleNames[0],
+          weekday: 1,
+          offtime: '08:00'
+      }},
+      replicate_existing_image_now: true,
+      replicate_deletion: false
+    });
+    this.setProject([this.emptyProject]);
+    this.setTarget([this.emptyEndpoint]);
+    this.setFilter([]);
 
-    if(ruleId) {
-      this.actionType = ActionType.EDIT;
-      this.translateService.get('REPLICATION.EDIT_POLICY_TITLE').subscribe(res=>this.modalTitle=res);
-      toPromise<ReplicationRule>(this.replicationService
-          .getReplicationRule(ruleId))
-          .then(rule=>{
-            if(rule) {
-              this.createEditRule.ruleId = ruleId;
-              this.createEditRule.name = rule.name;
-              this.createEditRule.description = rule.description;
-              this.createEditRule.enable = rule.enabled === 1? true : false;
-              this.prepareTargets(rule.target_id);         
+    this.copyUpdateForm = Object.assign({}, this.ruleForm.value);
+  }
 
-              this.initVal.name = this.createEditRule.name;
-              this.initVal.description = this.createEditRule.description;
-              this.initVal.enable = this.createEditRule.enable;
+  updateForm(rule: ReplicationRule): void {
+    rule.trigger = this.updateTrigger(rule.trigger);
+    this.ruleForm.reset({
+      name: rule.name,
+      description: rule.description,
+      trigger: rule.trigger,
+      replicate_existing_image_now: rule.replicate_existing_image_now,
+      replicate_deletion: rule.replicate_deletion
+    });
+    this.setProject(rule.projects);
+    this.noSelectedProject = false;
+    this.setTarget(rule.targets);
+    this.noSelectedEndpoint = false;
 
-              this.createEditRuleOpened = true;
-            }
-          }).catch(err=>this.errorHandler.error(err));
-    } else {
-      if(!this.projectId) {
-        this.errorHandler.error('Project ID cannot be unset');
+    if (rule.filters) {
+      this.setFilter(rule.filters);
+      this.updateFilter(rule.filters);
+    }
+
+    // Force refresh view
+    let hnd = setInterval(() => this.ref.markForCheck(), 100);
+    setTimeout(() => clearInterval(hnd), 2000);
+  }
+
+  get projects(): FormArray {
+    return this.ruleForm.get('projects') as FormArray;
+  }
+  setProject(projects: Project[]) {
+    const projectFGs = projects.map(project => this.fb.group(project));
+    const projectFormArray = this.fb.array(projectFGs);
+    this.ruleForm.setControl('projects', projectFormArray);
+  }
+
+  get filters(): FormArray {
+    return this.ruleForm.get('filters') as FormArray;
+  }
+  setFilter(filters: Filter[]) {
+    const filterFGs = filters.map(filter => this.fb.group(filter));
+    const filterFormArray = this.fb.array(filterFGs);
+    this.ruleForm.setControl('filters', filterFormArray);
+  }
+
+  get targets(): FormArray {
+    return this.ruleForm.get('targets') as FormArray;
+  }
+  setTarget(targets: Endpoint[]) {
+    const targetFGs = targets.map(target => this.fb.group(target));
+    const targetFormArray = this.fb.array(targetFGs);
+    this.ruleForm.setControl('targets', targetFormArray);
+  }
+
+  initFilter(name: string) {
+    return this.fb.group({
+      kind: name,
+      pattern: ['', Validators.required]
+    });
+  }
+
+  filterChange($event: any) {
+    if ($event && $event.target['value']) {
+      let id: number = $event.target.id;
+      let name: string = $event.target.name;
+      let value: string = $event.target['value'];
+
+      this.filterListData.forEach((data, index) => {
+        if (index === +id) {
+          data.name = $event.target.name = value;
+        }else {
+          data.options.splice(data.options.indexOf(value), 1);
+        }
+        if (data.options.indexOf(name) === -1) {
+          data.options.push(name);
+        }
+      });
+    }
+  }
+
+  targetChange($event: any) {
+    if ($event && $event.target) {
+      if ($event.target['value'] === '-1') {
+        this.noSelectedEndpoint = true;
         return;
       }
-      this.actionType = ActionType.ADD_NEW;
-      this.translateService.get('REPLICATION.ADD_POLICY').subscribe(res=>this.modalTitle=res);
-      this.prepareTargets(); 
-      this.createEditRuleOpened = true;
-    }
-  } 
-
-  newEndpoint(checkedAddNew: boolean): void {
-    this.isCreateEndpoint = checkedAddNew;
-    if(this.isCreateEndpoint) {
-      this.createEditRule.endpointName = '';
-      this.createEditRule.endpointUrl = '';
-      this.createEditRule.username = '';
-      this.createEditRule.password = '';
-      this.createEditRule.insecure = false;
-    } else {
-      this.prepareTargets();
+      let selecedTarget: Endpoint = this.targetList.find(target => target.id === +$event.target['value']);
+      this.setTarget([selecedTarget]);
+      this.noSelectedEndpoint = false;
     }
   }
 
-  selectEndpoint(): void {
-    let result: Endpoint | undefined = this.endpoints.find(target=>target.id == this.createEditRule.endpointId);
-    if(result) {
-      this.createEditRule.endpointId = result.id;
-      this.createEditRule.endpointUrl = result.endpoint;
-      this.createEditRule.username = result.username;
-      this.createEditRule.insecure = result.insecure;
-      this.createEditRule.password = FAKE_PASSWORD;
+    // Handle the form validation
+    handleValidation(): void {
+        let cont = this.ruleForm.controls["projects"];
+        if (cont && cont.valid) {
+            this.proNameChecker.next(cont.value[0].name);
+        }
     }
-  }
-    
-  getRuleByForm(): ReplicationRule {
-    let rule: ReplicationRule = this.initReplicationRule;
-    rule.project_id = this.projectId;
-    rule.id = this.createEditRule.ruleId;
-    rule.name = this.createEditRule.name;
-    rule.description = this.createEditRule.description;
-    rule.enabled = this.createEditRule.enable ? 1 : 0;
-    rule.target_id = this.createEditRule.endpointId || '';
-    return rule;
-  }
 
-  getEndpointByForm(): Endpoint {
-    let endpoint: Endpoint = this.initEndpoint;
-    endpoint.id = this.createEditRule.ruleId;
-    endpoint.name = this.createEditRule.endpointName || '';
-    endpoint.endpoint = this.createEditRule.endpointUrl || '';
-    endpoint.username = this.createEditRule.username;
-    endpoint.password = this.createEditRule.password;
-    endpoint.insecure = this.createEditRule.insecure;
-    return endpoint;
-  }
-
-  createReplicationRule(): void {
-    toPromise<ReplicationRule>(this.replicationService
-        .createReplicationRule(this.getRuleByForm()))
-        .then(response=>{
-            this.translateService.get('REPLICATION.CREATED_SUCCESS')
-                .subscribe(res=>this.errorHandler.info(res));
-            this.createEditRuleOpened = false;
-            this.reload.emit(true);
-          })
-        .catch(error=>{
-            if (error.status === 409) {
-              this.inlineAlert.showInlineError('REPLICATION.POLICY_ALREADY_EXISTS');
-            } else {
-              this.inlineAlert.showInlineError(error);
-            }            
-          });
-  }
-
-  updateReplicationRule(): void {
-    toPromise<ReplicationRule>(this.replicationService
-        .updateReplicationRule(this.getRuleByForm()))
-        .then(()=>{
-            this.translateService.get('REPLICATION.UPDATED_SUCCESS')
-                .subscribe(res=>this.errorHandler.info(res));
-            this.createEditRuleOpened = false;
-            this.reload.emit(true);
-          })
-        .catch(error=>{
-            if (error.status === 409) {
-              this.inlineAlert.showInlineError('REPLICATION.POLICY_ALREADY_EXISTS');
-            } else {
-              this.inlineAlert.showInlineError(error);
-            }
-          }
-        );
-  }
-
-  createWithEndpoint(actionType: ActionType): void {
-    toPromise<Endpoint>(this.endpointService
-      .createEndpoint(this.getEndpointByForm()))
-      .then(()=>{
-        toPromise<Endpoint[]>(this.endpointService
-          .getEndpoints(this.createEditRule.endpointName))
-          .then(endpoints=>{
-            if(endpoints && endpoints.length > 0) {
-              let addedEndpoint: Endpoint = endpoints[0];
-              this.createEditRule.endpointId = addedEndpoint.id;
-              switch(actionType) {
-              case ActionType.ADD_NEW:
-                this.createReplicationRule();
-                break;
-              case ActionType.EDIT:
-                this.updateReplicationRule();
-                break;
-              }
-            }
-         })
-         .catch(error=>{
-           this.inlineAlert.showInlineError(error);
-           this.errorHandler.error(error);
-         });
-      })
-      .catch(error=>{
-        this.inlineAlert.showInlineError(error);
-        this.errorHandler.error(error);
-      });
-  }
-
-  onSubmit() {
-    if(this.isCreateEndpoint) {
-      this.createWithEndpoint(this.actionType);
-    } else {
-      switch(this.actionType) {
-      case ActionType.ADD_NEW:
-        this.createReplicationRule();
-        break;
-      case ActionType.EDIT:
-        this.updateReplicationRule();
-        break;
+  focusClear($event: any): void {
+    if (this.policyId < 0 && this.firstClick === 0) {
+      if ($event && $event.target && $event.target['value']) {
+        $event.target['value'] = '';
       }
+      this.firstClick ++;
     }
   }
 
-  onCancel() {
-    if(this.hasChanged) {
-      this.inlineAlert.showInlineConfirmation({message: 'ALERT.FORM_CHANGE_CONFIRMATION'});
-    } else {
-      this.createEditRuleOpened = false;
-      this.ruleForm.reset();
+  leaveInput() {
+    this.selectedProjectList = [];
+  }
+
+    selectedProjectName(projectName: string) {
+      this.noSelectedProject = false;
+      let pro: Project = this.selectedProjectList.find(data => data.name === projectName);
+      this.setProject([pro]);
+      this.selectedProjectList = [];
+      this.noProjectInfo = "";
+    }
+
+  selectedProject(project: Project): void {
+    if (!project) {
+      this.noSelectedProject = true;
+    }else {
+      this.noSelectedProject = false;
+      this.setProject([project]);
     }
   }
 
-  setInsecureValue($event: any) {
-    this.createEditRule.insecure = !$event;
+  addNewFilter(): void {
+    if (this.filterCount === 0) {
+      this.filterListData.push(this.baseFilterData(this.filterSelect[0], this.filterSelect.slice(), true));
+      this.filters.push(this.initFilter(this.filterSelect[0]));
+
+    }else {
+      let nameArr: string[] = this.filterSelect.slice();
+      this.filterListData.forEach(data => {
+        nameArr.splice(nameArr.indexOf(data.name), 1);
+      });
+      // when add a new filter,the filterListData should change the options
+      this.filterListData.filter((data) => {
+        data.options.splice(data.options.indexOf(nameArr[0]), 1);
+      });
+      this.filterListData.push(this.baseFilterData(nameArr[0], nameArr, true));
+      this.filters.push(this.initFilter(nameArr[0]));
+    }
+    this.filterCount += 1;
+    if (this.filterCount >= this.filterSelect.length) {
+      this.isFilterHide = true;
+    }
   }
 
-  confirmCancel(confirmed: boolean) {
-    this.createEditRuleOpened = false;
-    this.inlineAlert.close();
-    this.ruleForm.reset();
-  }
-
-  ngAfterViewChecked(): void {
-    this.ruleForm = this.currentForm;
-    if(this.ruleForm) {
-      let comparison: {[key: string]: any} = {
-        name: this.initVal.name,
-        description: this.initVal.description,
-        enable: this.initVal.enable,
-        endpointId: this.initVal.endpointId,
-        targetName: this.initVal.name,
-        endpointUrl: this.initVal.endpointUrl,
-        username: this.initVal.username,
-        password: this.initVal.password,
-        insecure: this.initVal.insecure
-      };
-      let self: CreateEditRuleComponent | any = this;
-      if(self) {
-        self.ruleForm.valueChanges.subscribe((data: any)=>{
-          for(let key in data) {
-            let current = data[key];          
-            let origin: string = comparison[key];
-            if(((self.actionType === ActionType.EDIT && !self.readonly && !current ) || current) && current !== origin) {
-              self.hasChanged = true;
-              break;
-            } else {
-              self.hasChanged = false;
-              self.inlineAlert.close();
-            }
+  // delete a filter
+  deleteFilter(i: number): void {
+    if (i || i === 0) {
+      let delfilter = this.filterListData.splice(i, 1)[0];
+      if (this.filterCount === this.filterSelect.length) {
+        this.isFilterHide = false;
+      }
+      this.filterCount -= 1;
+      if (this.filterListData.length) {
+        let optionVal = delfilter.name;
+        this.filterListData.filter(data => {
+          if (data.options.indexOf(optionVal) === -1) {
+            data.options.push(optionVal);
           }
         });
       }
+      const control = <FormArray>this.ruleForm.controls['filters'];
+      control.removeAt(i);
     }
   }
 
-  testConnection() {
-    this.pingStatus = true;
-    this.btnAbled=true;
-    this.translateService.get('REPLICATION.TESTING_CONNECTION').subscribe(res=>this.pingTestMessage=res);
-    this.testOngoing = !this.testOngoing;
-    let pingTarget: Endpoint = this.initEndpoint;
-    if(this.isCreateEndpoint) {
-      pingTarget.endpoint = this.createEditRule.endpointUrl || '';
-      pingTarget.username = this.createEditRule.username;
-      pingTarget.password = this.createEditRule.password;
-      pingTarget.insecure = this.createEditRule.insecure;
-    } else {
-      for (let prop in pingTarget) {
-        delete pingTarget[prop];
+  selectTrigger($event: any): void {
+    if ($event && $event.target && $event.target['value']) {
+      let val: string = $event.target['value'];
+      if (val === this.triggerNames[2]) {
+        this.isScheduleOpt = true;
+        this.isImmediate = false;
+      }
+      if (val === this.triggerNames[1]) {
+        this.isScheduleOpt = false;
+        this.isImmediate = true;
+      }
+      if (val === this.triggerNames[0]) {
+        this.isScheduleOpt = false;
+        this.isImmediate = false;
       }
-      pingTarget.id = this.createEditRule.endpointId;
     }
-    toPromise<Endpoint>(this.endpointService
-        .pingEndpoint(pingTarget))
-        .then(()=>{
-            this.testOngoing = !this.testOngoing;
-            this.translateService.get('REPLICATION.TEST_CONNECTION_SUCCESS').subscribe(res=>this.pingTestMessage=res);
-            this.pingStatus = true;
-          this.btnAbled=false;
-          })
-         .catch(error=>{
-            this.testOngoing = !this.testOngoing;
-            this.translateService.get('REPLICATION.TEST_CONNECTION_FAILURE').subscribe(res=>this.pingTestMessage=res);
-            this.pingStatus = false;
-           this.btnAbled=false;
-          });
   }
+
+  // Replication Schedule select value exchange
+  selectSchedule($event: any): void {
+    if ($event && $event.target && $event.target['value']) {
+      switch ($event.target['value']) {
+        case this.scheduleNames[1]:
+          this.weeklySchedule = true;
+          this.ruleForm.patchValue({
+            trigger: {
+              schedule_param: {
+                weekday: 1,
+              }
+            }
+          });
+          break;
+        case this.scheduleNames[0]:
+          this.weeklySchedule = false;
+          break;
+      }
+    }
+  }
+
+  checkRuleName(): void {
+    let ruleName: string = this.ruleForm.controls['name'].value;
+    if (ruleName) {
+      this.nameChecker.next(ruleName);
+    } else {
+      this.ruleNameTooltip = 'TOOLTIP.EMPTY';
+    }
+  }
+
+  updateFilter(filters: any) {
+    let opt: string[] = this.filterSelect.slice();
+    filters.forEach((filter: any) => {
+      opt.splice(opt.indexOf(filter.kind), 1);
+    });
+    filters.forEach((filter: any) => {
+      let option: string [] = opt.slice();
+      option.unshift(filter.kind);
+      this.filterListData.push(this.baseFilterData(filter.kind, option, true));
+    });
+    this.filterCount = filters.length;
+    if (filters.length === this.filterSelect.length) {
+      this.isFilterHide = true;
+    }
+  }
+
+  updateTrigger(trigger: any) {
+    if (trigger['schedule_param']) {
+      this.isScheduleOpt = true;
+      this.isImmediate = false;
+      trigger['schedule_param']['offtime'] = this.getOfftime(trigger['schedule_param']['offtime']);
+      if (trigger['schedule_param']['weekday']) {
+        this.weeklySchedule = true;
+      }else {
+        // set default
+        trigger['schedule_param']['weekday'] = 1;
+      }
+    }else {
+      if (trigger['kind'] === this.triggerNames[0]) {
+        this.isImmediate = false;
+      }
+      if (trigger['kind'] === this.triggerNames[1]) {
+        this.isImmediate = true;
+      }
+      trigger['schedule_param'] = { type: this.scheduleNames[0],
+        weekday: this.weekly[0],
+        offtime: '08:00'};
+    }
+    return trigger;
+  }
+
+  setTriggerVaule(trigger: any) {
+    if (!this.isScheduleOpt) {
+      delete trigger['schedule_param'];
+      return trigger;
+    }else {
+      if (!this.weeklySchedule) {
+        delete trigger['schedule_param']['weekday'];
+      }else {
+        trigger['schedule_param']['weekday'] = +trigger['schedule_param']['weekday'];
+      }
+      trigger['schedule_param']['offtime'] = this.setOfftime(trigger['schedule_param']['offtime']);
+      return trigger;
+    }
+  }
+
+  public hasFormChange(): boolean {
+    return !isEmptyObject(this.getChanges());
+  }
+
+  onSubmit() {
+    // add new Replication rule
+    this.inProgress = true;
+    let copyRuleForm: ReplicationRule = this.ruleForm.value;
+    copyRuleForm.trigger = this.setTriggerVaule(copyRuleForm.trigger);
+    if (this.policyId < 0) {
+      this.repService.createReplicationRule(copyRuleForm)
+          .then(() => {
+            this.translateService.get('REPLICATION.CREATED_SUCCESS')
+                .subscribe(res => this.errorHandler.info(res));
+            this.inProgress = false;
+            this.reload.emit(true);
+            this.close();
+          }).catch((error: any) => {
+        this.inProgress = false;
+        this.inlineAlert.showInlineError(error);
+      });
+    } else {
+      this.repService.updateReplicationRule(this.policyId, this.ruleForm.value)
+          .then(() => {
+            this.translateService.get('REPLICATION.UPDATED_SUCCESS')
+                .subscribe(res => this.errorHandler.info(res));
+            this.inProgress = false;
+            this.reload.emit(true);
+            this.close();
+          }).catch((error: any) => {
+        this.inProgress = false;
+        this.inlineAlert.showInlineError(error);
+      });
+    }
+  }
+
+  openCreateEditRule(ruleId?: number | string): void {
+    this.initForm();
+    this.selectedProjectList = [];
+    this.filterCount = 0;
+    this.filterListData = [];
+    this.firstClick = 0;
+    this.noSelectedProject = true;
+    this.noSelectedEndpoint = true;
+    this.isRuleNameExist = false;
+
+    this.weeklySchedule = false;
+    this.isScheduleOpt = false;
+    this.isImmediate = false;
+    this.policyId = -1;
+    this.createEditRuleOpened = true;
+
+    this.noProjectInfo = "";
+    this.noEndpointInfo = "";
+    if (this.targetList.length === 0) {
+      this.noEndpointInfo = 'REPLICATION.NO_ENDPOINT_INFO';
+    }
+    if (this.projectList.length === 0 && !this.projectName) {
+      this.noProjectInfo = 'REPLICATION.NO_PROJECT_INFO';
+    }
+
+    if (ruleId) {
+      this.policyId = +ruleId;
+      this.headerTitle = 'REPLICATION.EDIT_POLICY_TITLE';
+      toPromise(this.repService.getReplicationRule(ruleId))
+          .then((response) => {
+            this.copyUpdateForm = Object.assign({}, response);
+            // set filter value is [] if callback fiter value is null.
+            this.copyUpdateForm.filters = response.filters ? response.filters : [];
+            this.updateForm(response);
+          }).catch((error: any) => {
+        this.inlineAlert.showInlineError(error);
+      });
+    }else {
+      this.headerTitle = 'REPLICATION.ADD_POLICY';
+        if (this.projectId) {
+          this.setProject([{project_id: this.projectId, name: this.projectName}]);
+          this.noSelectedProject = false;
+        }
+
+        this.copyUpdateForm = Object.assign({}, this.ruleForm.value);
+      }
+    }
+
+  close(): void {
+    this.createEditRuleOpened = false;
+  }
+
+  confirmCancel(confirmed: boolean) {
+    this.inlineAlert.close();
+    this.close();
+  }
+
+  onCancel(): void {
+    if (this.hasFormChange()) {
+      this.inlineAlert.showInlineConfirmation({ message: 'ALERT.FORM_CHANGE_CONFIRMATION' });
+    }else {
+      this.close();
+    }
+  }
+
+  goRegistry(): void {
+    this.goToRegistry.emit();
+  }
+
+  // UTC time
+  public getOfftime(daily_time: any): string {
+
+    let timeOffset = 0; // seconds
+    if (daily_time && typeof daily_time === 'number') {
+      timeOffset = +daily_time;
+    }
+
+    // Convert to current time
+    let timezoneOffset: number = this._localTime.getTimezoneOffset();
+    // Local time
+    timeOffset = timeOffset - timezoneOffset * 60;
+    if (timeOffset < 0) {
+      timeOffset = timeOffset + ONE_DAY_SECONDS;
+    }
+
+    if (timeOffset >= ONE_DAY_SECONDS) {
+      timeOffset -= ONE_DAY_SECONDS;
+    }
+
+    // To time string
+    let hours: number = Math.floor(timeOffset / ONE_HOUR_SECONDS);
+    let minutes: number = Math.floor((timeOffset - hours * ONE_HOUR_SECONDS) / 60);
+
+    let timeStr: string = '' + hours;
+    if (hours < 10) {
+      timeStr = '0' + timeStr;
+    }
+    if (minutes < 10) {
+      timeStr += ':0';
+    } else {
+      timeStr += ':';
+    }
+    timeStr += minutes;
+
+    return timeStr;
+  }
+  public setOfftime(v: string) {
+    if (!v || v === '') {
+      return;
+    }
+
+    let values: string[] = v.split(':');
+    if (!values || values.length !== 2) {
+      return;
+    }
+
+    let hours: number = +values[0];
+    let minutes: number = +values[1];
+    // Convert to UTC time
+    let timezoneOffset: number = this._localTime.getTimezoneOffset();
+    let utcTimes: number = hours * ONE_HOUR_SECONDS + minutes * 60;
+    utcTimes += timezoneOffset * 60;
+    if (utcTimes < 0) {
+      utcTimes += ONE_DAY_SECONDS;
+    }
+
+    if (utcTimes >= ONE_DAY_SECONDS) {
+      utcTimes -= ONE_DAY_SECONDS;
+    }
+
+    return utcTimes;
+  }
+
+  getChanges(): { [key: string]: any | any[] } {
+    let changes: { [key: string]: any | any[] } = {};
+    let ruleValue: { [key: string]: any | any[] } = this.ruleForm.value;
+    if (!ruleValue || !this.copyUpdateForm) {
+      return changes;
+    }
+    for (let prop in ruleValue) {
+      let field: any = this.copyUpdateForm[prop];
+      if (!compareValue(field, ruleValue[prop])) {
+        if (ruleValue[prop][0] && ruleValue[prop][0].project_id && (ruleValue[prop][0].project_id === field[0].project_id)) {
+          break;
+        }
+        if (ruleValue[prop][0] && ruleValue[prop][0].id && (ruleValue[prop][0].id === field[0].id)) {
+          break;
+        }
+        changes[prop] = ruleValue[prop];
+        // Number
+        if (typeof field === "number") {
+          changes[prop] = +changes[prop];
+        }
+
+        // Trim string value
+        if (typeof field === "string") {
+          changes[prop] = ('' + changes[prop]).trim();
+        }
+      }
+    }
+
+    return changes;
+  }
+
 }
\ No newline at end of file
diff --git a/src/ui_ng/lib/src/endpoint/endpoint.component.ts b/src/ui_ng/lib/src/endpoint/endpoint.component.ts
index f500ffd7f..53dd65343 100644
--- a/src/ui_ng/lib/src/endpoint/endpoint.component.ts
+++ b/src/ui_ng/lib/src/endpoint/endpoint.component.ts
@@ -137,23 +137,13 @@ export class EndpointComponent implements OnInit, OnDestroy {
 
     editTargets(targets: Endpoint[]) {
         if (targets && targets.length === 1) {
-            let target= targets[0];
+            let target = targets[0];
             let editable = true;
             if (!target.id) {
                 return;
             }
             let id: number | string = target.id;
-            toPromise<ReplicationRule[]>(this.endpointService
-                .getEndpointWithReplicationRules(id))
-                .then(
-                rules => {
-                    if (rules && rules.length > 0) {
-                        rules.forEach((rule) => editable = (rule && rule.enabled !== 1));
-                    }
-                    this.createEditEndpointComponent.openCreateEditTarget(editable, id);
-                    this.forceRefreshView(1000);
-                })
-                .catch(error => this.errorHandler.error(error));
+            this.createEditEndpointComponent.openCreateEditTarget(editable, id);
         }
     }
 
diff --git a/src/ui_ng/lib/src/index.ts b/src/ui_ng/lib/src/index.ts
index 79858a122..878e2d428 100644
--- a/src/ui_ng/lib/src/index.ts
+++ b/src/ui_ng/lib/src/index.ts
@@ -8,6 +8,7 @@ export * from './filter/index';
 export * from './endpoint/index';
 export * from './repository/index';
 export * from './create-edit-endpoint/index';
+export * from './create-edit-rule/index';
 export * from './repository-stackview/index';
 export * from './tag/index';
 export * from './list-replication-rule/index';
diff --git a/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.html.ts b/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.html.ts
index 9faec0912..47c006bad 100644
--- a/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.html.ts
+++ b/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.html.ts
@@ -1,7 +1,7 @@
 export const LIST_REPLICATION_RULE_TEMPLATE: string = `
 <div style="padding-bottom: 15px;">
 <clr-datagrid [clrDgLoading]="loading"  [(clrDgSingleSelected)]="selectedRow" [clDgRowSelection]="true">
-    <clr-dg-action-bar style="height:24px;" *ngIf="opereateAvailable || isSystemAdmin">
+    <clr-dg-action-bar style="height:24px;" *ngIf="isSystemAdmin">
         <button type="button" class="btn btn-sm btn-secondary" (click)="openModal()"><clr-icon shape="plus" size="16"></clr-icon>&nbsp;{{'REPLICATION.NEW_REPLICATION_RULE' | translate}}</button>
         <button type="button" class="btn btn-sm btn-secondary" [disabled]="!selectedRow" (click)="editRule(selectedRow)"><clr-icon shape="pencil" size="16"></clr-icon>&nbsp;{{'REPLICATION.EDIT_POLICY' | translate}}</button>
         <button type="button" class="btn btn-sm btn-secondary" [disabled]="!selectedRow" (click)="deleteRule(selectedRow)"><clr-icon shape="times" size="16"></clr-icon>&nbsp;{{'REPLICATION.DELETE_POLICY' | translate}}</button>
@@ -35,7 +35,6 @@ export const LIST_REPLICATION_RULE_TEMPLATE: string = `
       <clr-dg-pagination #pagination [clrDgPageSize]="5"></clr-dg-pagination>
     </clr-dg-footer>
 </clr-datagrid>
-<confirmation-dialog #toggleConfirmDialog  [batchInfors]="batchDelectionInfos"  (confirmAction)="toggleConfirm($event)"></confirmation-dialog>
 <confirmation-dialog #deletionConfirmDialog [batchInfors]="batchDelectionInfos" (confirmAction)="deletionConfirm($event)"></confirmation-dialog>
 </div>
 `;
\ No newline at end of file
diff --git a/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.spec.ts b/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.spec.ts
index 512391a18..39b2689e6 100644
--- a/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.spec.ts
+++ b/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.spec.ts
@@ -14,66 +14,91 @@ import { ErrorHandler } from '../error-handler/error-handler';
 import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
 import { ReplicationService, ReplicationDefaultService } from '../service/replication.service';
 
-
 describe('ListReplicationRuleComponent (inline template)', ()=>{
 
   let mockRules: ReplicationRule[] = [
     {
         "id": 1,
-        "project_id": 1,
-        "project_name": "library",
-        "target_id": 1,
-        "target_name": "target_01",
+        "projects": [{
+            "project_id": 33,
+            "owner_id": 1,
+            "name": "aeas",
+            "deleted": 0,
+            "togglable": false,
+            "current_user_role_id": 0,
+            "repo_count": 0,
+            "metadata": {
+                "public": false,
+                "enable_content_trust": "",
+                "prevent_vul": "",
+                "severity": "",
+                "auto_scan": ""},
+            "owner_name": "",
+            "creation_time": null,
+            "update_time": null,
+            "has_project_admin_role": true,
+            "is_member": true,
+            "role_name": ""
+        }],
+        "targets": [{
+            "endpoint": "",
+            "id": 0,
+            "insecure": false,
+            "name": "khans3",
+            "username": "",
+            "password": "",
+            "type": 0,
+        }],
         "name": "sync_01",
-        "enabled": 0,
         "description": "",
-        "cron_str": "",    
+        "filters": null,
+        "trigger": {"kind": "Manual", "schedule_param": null},
         "error_job_count": 2,
-        "deleted": 0
+        "replicate_deletion": false,
+        "replicate_existing_image_now": false,
     },
     {
-        "id": 2,
-        "project_id": 1,
-        "project_name": "library",
-        "target_id": 3,
-        "target_name": "target_02",
-        "name": "sync_02",
-        "enabled": 1,
-        "description": "",
-        "cron_str": "",
-        "error_job_count": 1,
-        "deleted": 0
-    },
-    {
-        "id": 3,
-        "project_id": 1,
-        "project_name": "library",
-        "target_id": 2,
-        "target_name": "target_03",
-        "name": "sync_03",
-        "enabled": 0,
-        "description": "",
-        "cron_str": "",
-        "error_job_count": 0,
-        "deleted": 0
-    }
+          "id": 2,
+          "projects": [{
+              "project_id": 33,
+              "owner_id": 1,
+              "name": "aeas",
+              "deleted": 0,
+              "togglable": false,
+              "current_user_role_id": 0,
+              "repo_count": 0,
+              "metadata": {
+                  "public": false,
+                  "enable_content_trust": "",
+                  "prevent_vul": "",
+                  "severity": "",
+                  "auto_scan": ""},
+              "owner_name": "",
+              "creation_time": null,
+              "update_time": null,
+              "has_project_admin_role": true,
+              "is_member": true,
+              "role_name": ""
+          }],
+          "targets": [{
+              "endpoint": "",
+              "id": 0,
+              "insecure": false,
+              "name": "khans3",
+              "username": "",
+              "password": "",
+              "type": 0,
+          }],
+          "name": "sync_02",
+          "description": "",
+          "filters": null,
+          "trigger": {"kind": "Manual", "schedule_param": null},
+          "error_job_count": 2,
+          "replicate_deletion": false,
+          "replicate_existing_image_now": false,
+      },
   ];
 
- 
-  let mockRule: ReplicationRule = {
-      "id": 1,
-      "project_id": 1,
-      "project_name": "library",
-      "target_id": 1,
-      "target_name": "target_01",
-      "name": "sync_01",
-      "enabled": 0,
-      "description": "",
-      "cron_str": "",    
-      "error_job_count": 2,
-      "deleted": 0
-  };
-
   let fixture: ComponentFixture<ListReplicationRuleComponent>;
   
   let comp: ListReplicationRuleComponent;
diff --git a/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.ts b/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.ts
index eb3d99334..ad8f33677 100644
--- a/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.ts
+++ b/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.ts
@@ -60,9 +60,8 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
   @Input() isSystemAdmin: boolean;
   @Input() selectedId: number | string;
   @Input() withReplicationJob: boolean;
-  @Input() readonly: boolean;
 
-  @Input() loading: boolean = false;
+  @Input() loading = false;
 
   @Output() reload = new EventEmitter<boolean>();
   @Output() selectOne = new EventEmitter<ReplicationRule>();
@@ -100,10 +99,6 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
     setInterval(() => ref.markForCheck(), 500);
   }
 
-  public get opereateAvailable(): boolean {
-    return !this.readonly && !this.projectId ? true : false;
-  }
-
   trancatedDescription(desc: string): string {
     if (desc.length > 35 ) {
       return desc.substr(0, 35);
@@ -135,7 +130,7 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
 
   retrieveRules(ruleName: string = ''): void {
     this.loading = true;
-    this.selectedRow = null;
+    /*this.selectedRow = null;*/
     toPromise<ReplicationRule[]>(this.replicationService
       .getReplicationRules(this.projectId, ruleName))
       .then(rules => {
@@ -156,36 +151,6 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
       });
   }
 
-  filterRuleStatus(status: string) {
-    if (status === 'all') {
-      this.changedRules = this.rules;
-    } else {
-      this.changedRules = this.rules.filter(policy => policy.enabled === +status);
-    }
-  }
-
-  toggleConfirm(message: ConfirmationAcknowledgement) {
-    if (message &&
-        message.source === ConfirmationTargets.TOGGLE_CONFIRM &&
-        message.state === ConfirmationState.CONFIRMED) {
-      this.batchDelectionInfos = [];
-      let rule: ReplicationRule = message.data;
-      let initBatchMessage = new BatchInfo ();
-      initBatchMessage.name = rule.name;
-      this.batchDelectionInfos.push(initBatchMessage);
-
-      if (rule) {
-        rule.enabled = rule.enabled === 0 ? 1 : 0;
-        toPromise<any>(this.replicationService
-            .enableReplicationRule(rule.id || '', rule.enabled))
-            .then(() =>
-                this.translateService.get('REPLICATION.TOGGLED_SUCCESS')
-                    .subscribe(res => this.batchDelectionInfos[0].status = res))
-            .catch(error => this.batchDelectionInfos[0].status = error);
-      }
-    }
-  }
-
   replicateRule(rules: ReplicationRule[]): void {
     this.replicateManual.emit(rules);
   }
@@ -216,17 +181,6 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
     this.editOne.emit(rule);
   }
 
-  toggleRule(rule: ReplicationRule) {
-    let toggleConfirmMessage: ConfirmationMessage = new ConfirmationMessage(
-      rule.enabled === 1 ? 'REPLICATION.TOGGLE_DISABLE_TITLE' : 'REPLICATION.TOGGLE_ENABLE_TITLE',
-      rule.enabled === 1 ? 'REPLICATION.CONFIRM_TOGGLE_DISABLE_POLICY' : 'REPLICATION.CONFIRM_TOGGLE_ENABLE_POLICY',
-      rule.name || '',
-      rule,
-      ConfirmationTargets.TOGGLE_CONFIRM
-    );
-    this.toggleConfirmDialog.open(toggleConfirmMessage);
-  }
-
   jobList(id: string | number): Promise<void> {
     let ruleData: ReplicationJobItem[];
     this.canDeleteRule = true;
diff --git a/src/ui_ng/lib/src/project-policy-config/project.ts b/src/ui_ng/lib/src/project-policy-config/project.ts
index 1f4a4fa6d..ed1d26e01 100644
--- a/src/ui_ng/lib/src/project-policy-config/project.ts
+++ b/src/ui_ng/lib/src/project-policy-config/project.ts
@@ -1,18 +1,18 @@
 export class Project {
     project_id: number;
-    owner_id: number;
+    owner_id?: number;
     name: string;
-    creation_time: Date | string;
-    deleted: number;
-    owner_name: string;
-    togglable: boolean;
-    update_time: Date | string;
-    current_user_role_id: number;
-    repo_count: number;
-    has_project_admin_role: boolean;
-    is_member: boolean;
-    role_name: string;
-    metadata: {
+    creation_time?: Date | string;
+    deleted?: number;
+    owner_name?: string;
+    togglable?: boolean;
+    update_time?: Date | string;
+    current_user_role_id?: number;
+    repo_count?: number;
+    has_project_admin_role?: boolean;
+    is_member?: boolean;
+    role_name?: string;
+    metadata?: {
       public: string | boolean;
       enable_content_trust: string | boolean;
       prevent_vul: string | boolean;
diff --git a/src/ui_ng/lib/src/replication/replication.component.html.ts b/src/ui_ng/lib/src/replication/replication.component.html.ts
index d396fffb4..91af4e7aa 100644
--- a/src/ui_ng/lib/src/replication/replication.component.html.ts
+++ b/src/ui_ng/lib/src/replication/replication.component.html.ts
@@ -11,7 +11,7 @@ export const REPLICATION_TEMPLATE: string = `
     </div>
     </div>
     <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
-      <hbr-list-replication-rule #listReplicationRule [readonly]="readonly" [projectId]="projectId" [isSystemAdmin]="isSystemAdmin"  (replicateManual)=replicateManualRule($event) (selectOne)="selectOneRule($event)" (hideJobs)="hideJobs()"  (openNewRule)="openModal()" (editOne)="openEditRule($event)" (reload)="reloadRules($event)" [loading]="loading" [withReplicationJob]="withReplicationJob" (redirect)="customRedirect($event)"></hbr-list-replication-rule>
+      <hbr-list-replication-rule #listReplicationRule [projectId]="projectId" [isSystemAdmin]="isSystemAdmin"  (replicateManual)=replicateManualRule($event) (selectOne)="selectOneRule($event)" (hideJobs)="hideJobs()"  (openNewRule)="openModal()" (editOne)="openEditRule($event)" (reload)="reloadRules($event)" [loading]="loading" [withReplicationJob]="withReplicationJob" (redirect)="customRedirect($event)"></hbr-list-replication-rule>
     </div>
     <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12" style="padding-left:0px;">
     <div *ngIf="withReplicationJob" class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
@@ -73,5 +73,6 @@ export const REPLICATION_TEMPLATE: string = `
     </div>
     </div>
     <job-log-viewer #replicationLogViewer></job-log-viewer>
+    <hbr-create-edit-rule [projectId]="projectId" [projectName]="projectName" (goToRegistry)="goRegistry()" (reload)="reloadRules($event)"></hbr-create-edit-rule>
     <confirmation-dialog #replicationConfirmDialog [batchInfors]="batchDelectionInfos" (confirmAction)="confirmReplication($event)"></confirmation-dialog>
 </div>`;
\ No newline at end of file
diff --git a/src/ui_ng/lib/src/replication/replication.component.spec.ts b/src/ui_ng/lib/src/replication/replication.component.spec.ts
index 7b720ec15..d349a809b 100644
--- a/src/ui_ng/lib/src/replication/replication.component.spec.ts
+++ b/src/ui_ng/lib/src/replication/replication.component.spec.ts
@@ -12,7 +12,7 @@ import { DatePickerComponent } from '../datetime-picker/datetime-picker.componen
 import { DateValidatorDirective } from '../datetime-picker/date-validator.directive';
 import { FilterComponent } from '../filter/filter.component';
 import { InlineAlertComponent } from '../inline-alert/inline-alert.component';
-import { ReplicationRule, ReplicationJob, Endpoint } from '../service/interface';
+import {ReplicationRule, ReplicationJob, Endpoint} from '../service/interface';
 
 import { ErrorHandler } from '../error-handler/error-handler';
 import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
@@ -20,49 +20,92 @@ import { ReplicationService, ReplicationDefaultService } from '../service/replic
 import { EndpointService, EndpointDefaultService } from '../service/endpoint.service';
 import { JobLogViewerComponent } from '../job-log-viewer/job-log-viewer.component';
 import { JobLogService, JobLogDefaultService, ReplicationJobItem } from '../service/index';
+import {Project} from "../project-policy-config/project";
+import {ProjectDefaultService, ProjectService} from "service/project.service";
 
-describe('Replication Component (inline template)', ()=>{
+describe('Replication Component (inline template)', () => {
 
   let mockRules: ReplicationRule[] = [
-    {
-        "id": 1,
-        "project_id": 1,
-        "project_name": "library",
-        "target_id": 1,
-        "target_name": "target_01",
-        "name": "sync_01",
-        "enabled": 0,
-        "description": "",
-        "cron_str": "",    
-        "error_job_count": 2,
-        "deleted": 0
-    },
-    {
-        "id": 2,
-        "project_id": 1,
-        "project_name": "library",
-        "target_id": 3,
-        "target_name": "target_02",
-        "name": "sync_02",
-        "enabled": 1,
-        "description": "",
-        "cron_str": "",
-        "error_job_count": 1,
-        "deleted": 0
-    },
-    {
-        "id": 3,
-        "project_id": 1,
-        "project_name": "library",
-        "target_id": 2,
-        "target_name": "target_03",
-        "name": "sync_03",
-        "enabled": 0,
-        "description": "",
-        "cron_str": "",
-        "error_job_count": 0,
-        "deleted": 0
-    }
+      {
+          "id": 1,
+          "projects": [{
+              "project_id": 33,
+              "owner_id": 1,
+              "name": "aeas",
+              "deleted": 0,
+              "togglable": false,
+              "current_user_role_id": 0,
+              "repo_count": 0,
+              "metadata": {
+                  "public": false,
+                  "enable_content_trust": "",
+                  "prevent_vul": "",
+                  "severity": "",
+                  "auto_scan": ""},
+              "owner_name": "",
+              "creation_time": null,
+              "update_time": null,
+              "has_project_admin_role": true,
+              "is_member": true,
+              "role_name": ""
+          }],
+          "targets": [{
+              "id": 1,
+              "endpoint": "https://10.117.4.151",
+              "name": "target_01",
+              "username": "admin",
+              "password": "",
+              "insecure": false,
+              "type": 0
+          }],
+          "name": "sync_01",
+          "description": "",
+          "filters": null,
+          "trigger": {"kind": "Manual", "schedule_param": null},
+          "error_job_count": 2,
+          "replicate_deletion": false,
+          "replicate_existing_image_now": false,
+      },
+      {
+          "id": 2,
+          "projects": [{
+              "project_id": 33,
+              "owner_id": 1,
+              "name": "aeas",
+              "deleted": 0,
+              "togglable": false,
+              "current_user_role_id": 0,
+              "repo_count": 0,
+              "metadata": {
+                  "public": false,
+                  "enable_content_trust": "",
+                  "prevent_vul": "",
+                  "severity": "",
+                  "auto_scan": ""},
+              "owner_name": "",
+              "creation_time": null,
+              "update_time": null,
+              "has_project_admin_role": true,
+              "is_member": true,
+              "role_name": ""
+          }],
+          "targets": [{
+              "id": 1,
+              "endpoint": "https://10.117.4.151",
+              "name": "target_01",
+              "username": "admin",
+              "password": "",
+              "insecure": false,
+              "type": 0
+          }],
+          "name": "sync_02",
+          "description": "",
+          "filters": null,
+          "trigger": {"kind": "Manual", "schedule_param": null},
+          "error_job_count": 2,
+          "replicate_deletion": false,
+          "replicate_existing_image_now": false,
+      }
   ];
 
   let mockJobs: ReplicationJobItem[] = [
@@ -81,7 +124,7 @@ describe('Replication Component (inline template)', ()=>{
         "repository": "library/mysql",
         "policy_id": 1,
         "operation": "transfer",
-        "update_time": new Date("2017-05-27 12:20:33"),        
+        "update_time": new Date("2017-05-27 12:20:33"),
         "tags": null
     },
     {
@@ -95,71 +138,66 @@ describe('Replication Component (inline template)', ()=>{
     }
   ];
 
+    let mockEndpoints: Endpoint[] = [
+        {
+            "id": 1,
+            "endpoint": "https://10.117.4.151",
+            "name": "target_01",
+            "username": "admin",
+            "password": "",
+            "insecure": false,
+            "type": 0
+        },
+        {
+            "id": 2,
+            "endpoint": "https://10.117.5.142",
+            "name": "target_02",
+            "username": "AAA",
+            "password": "",
+            "insecure": false,
+            "type": 0
+        },
+    ];
+
+    let mockProjects: Project[] = [
+        { "project_id": 1,
+            "owner_id": 0,
+            "name": 'project_01',
+            "creation_time": '',
+            "deleted": 0,
+            "owner_name": '',
+            "togglable": false,
+            "update_time": '',
+            "current_user_role_id": 0,
+            "repo_count": 0,
+            "has_project_admin_role": false,
+            "is_member": false,
+            "role_name": '',
+            "metadata": {
+                "public": '',
+                "enable_content_trust": '',
+                "prevent_vul": '',
+                "severity": '',
+                "auto_scan": '',
+            }
+        }];
+
   let mockJob: ReplicationJob = {
     metadata: {xTotalCount: 3},
     data: mockJobs
   };
 
-  let mockEndpoints: Endpoint[] = [
-    {
-        "id": 1,
-        "endpoint": "https://10.117.4.151",
-        "name": "target_01",
-        "username": "admin",
-        "password": "",
-        "insecure": false,
-        "type": 0
-    },
-    {
-        "id": 2,
-        "endpoint": "https://10.117.5.142",
-        "name": "target_02",
-        "username": "AAA",
-        "password": "",
-        "insecure": false,
-        "type": 0
-    },
-    {
-        "id": 3,
-        "endpoint": "https://101.1.11.111",
-        "name": "target_03",
-        "username": "admin",
-        "password": "",
-        "insecure": false,
-        "type": 0
-    },
-    {
-        "id": 4,
-        "endpoint": "http://4.4.4.4",
-        "name": "target_04",
-        "username": "",
-        "password": "",
-        "insecure": false,
-        "type": 0
-    }
-  ];
-
-  let mockRule: ReplicationRule = {
-      "id": 1,
-      "project_id": 1,
-      "project_name": "library",
-      "target_id": 1,
-      "target_name": "target_01",
-      "name": "sync_01",
-      "enabled": 0,
-      "description": "",
-      "cron_str": "",    
-      "error_job_count": 2,
-      "deleted": 0
-  };
-
   let fixture: ComponentFixture<ReplicationComponent>;
+  let fixtureCreate: ComponentFixture<CreateEditRuleComponent>;
   let comp: ReplicationComponent;
+  let compCreate: CreateEditRuleComponent;
   
   let replicationService: ReplicationService;
+  let endpointService: EndpointService;
   
   let spyRules: jasmine.Spy;
   let spyJobs: jasmine.Spy;
+  let spyEndpoint: jasmine.Spy;
   
   let deGrids: DebugElement[];
   let deRules: DebugElement;
@@ -194,23 +232,29 @@ describe('Replication Component (inline template)', ()=>{
         { provide: SERVICE_CONFIG, useValue: config },
         { provide: ReplicationService, useClass: ReplicationDefaultService },
         { provide: EndpointService, useClass: EndpointDefaultService },
+        { provide: ProjectService, useClass: ProjectDefaultService },
         { provide: JobLogService, useClass: JobLogDefaultService }
       ]
     });
   }));
 
-  beforeEach(()=>{
+  beforeEach(() => {
     fixture = TestBed.createComponent(ReplicationComponent);
-
+    fixtureCreate = TestBed.createComponent(CreateEditRuleComponent);
     comp = fixture.componentInstance;
+    compCreate = fixtureCreate.componentInstance;
     comp.projectId = 1;
     comp.search.ruleId = 1;
 
     replicationService = fixture.debugElement.injector.get(ReplicationService);
-           
+
+    endpointService = fixtureCreate.debugElement.injector.get(EndpointService);
+
     spyRules = spyOn(replicationService, 'getReplicationRules').and.returnValues(Promise.resolve(mockRules));
     spyJobs = spyOn(replicationService, 'getJobs').and.returnValues(Promise.resolve(mockJob));
-    
+
+    spyEndpoint = spyOn(endpointService, 'getEndpoints').and.returnValues(Promise.resolve(mockEndpoints));
+
     fixture.detectChanges();
     fixture.whenStable().then(()=>{
       fixture.detectChanges();
@@ -221,6 +265,7 @@ describe('Replication Component (inline template)', ()=>{
     });
   });
 
+
   it('Should load replication rules', async(()=>{    
     fixture.detectChanges();
     fixture.whenStable().then(()=>{
diff --git a/src/ui_ng/lib/src/replication/replication.component.ts b/src/ui_ng/lib/src/replication/replication.component.ts
index 7a8de6fba..5479f9ad5 100644
--- a/src/ui_ng/lib/src/replication/replication.component.ts
+++ b/src/ui_ng/lib/src/replication/replication.component.ts
@@ -12,8 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 import { Component, OnInit, ViewChild, Input, Output, OnDestroy, EventEmitter } from '@angular/core';
-import { ResponseOptions, RequestOptions } from '@angular/http';
-import { NgModel } from '@angular/forms';
 
 import { TranslateService } from '@ngx-translate/core';
 
@@ -23,7 +21,7 @@ import { ErrorHandler } from '../error-handler/error-handler';
 
 import { ReplicationService } from '../service/replication.service';
 import { RequestQueryParams } from '../service/RequestQueryParams';
-import { ReplicationRule, ReplicationJob, Endpoint, ReplicationJobItem } from '../service/interface';
+import { ReplicationRule, ReplicationJob, ReplicationJobItem } from '../service/interface';
 
 import {
   toPromise,
@@ -89,13 +87,14 @@ export class SearchOption {
 export class ReplicationComponent implements OnInit, OnDestroy {
 
   @Input() projectId: number | string;
+  @Input() projectName: string;
   @Input() isSystemAdmin: boolean;
   @Input() withReplicationJob: boolean;
-  @Input() readonly: boolean;
 
   @Output() redirect = new EventEmitter<ReplicationRule>();
   @Output() openCreateRule = new EventEmitter<any>();
   @Output() openEdit = new EventEmitter<string | number>();
+  @Output() goToRegistry = new EventEmitter<any>();
 
   search: SearchOption = new SearchOption();
 
@@ -106,7 +105,6 @@ export class ReplicationComponent implements OnInit, OnDestroy {
   currentJobStatus: { key: string, description: string };
 
   changedRules: ReplicationRule[];
-  initSelectedId: number | string;
 
   rules: ReplicationRule[];
   loading: boolean;
@@ -121,8 +119,8 @@ export class ReplicationComponent implements OnInit, OnDestroy {
   @ViewChild(ListReplicationRuleComponent)
   listReplicationRule: ListReplicationRuleComponent;
 
-/*  @ViewChild(CreateEditRuleComponent)
-  createEditPolicyComponent: CreateEditRuleComponent;*/
+  @ViewChild(CreateEditRuleComponent)
+  createEditPolicyComponent: CreateEditRuleComponent;
 
   @ViewChild("replicationLogViewer")
   replicationLogViewer: JobLogViewerComponent;
@@ -164,20 +162,22 @@ export class ReplicationComponent implements OnInit, OnDestroy {
     }
   }
 
+  // open replication rule
   openModal(): void {
-    this.openCreateRule.emit();
+    this.createEditPolicyComponent.openCreateEditRule();
   }
 
+  // edit replication rule
   openEditRule(rule: ReplicationRule) {
     if (rule) {
-      let editable = true;
-      if (rule.enabled === 1) {
-        editable = false;
-      }
-      this.openEdit.emit(rule.id);
+      this.createEditPolicyComponent.openCreateEditRule(rule.id);
     }
   }
 
+  goRegistry(): void {
+    this.goToRegistry.emit();
+  }
+
   //Server driven data loading
   clrLoadJobs(state: State): void {
     if (!state || !state.page || !this.search.ruleId) {
@@ -209,6 +209,12 @@ export class ReplicationComponent implements OnInit, OnDestroy {
     }
 
     this.jobsLoading = true;
+
+    //Do filtering and sorting
+    this.jobs = doFiltering<ReplicationJobItem>(this.jobs, state);
+    this.jobs = doSorting<ReplicationJobItem>(this.jobs, state);
+
+    this.jobsLoading = false;
     toPromise<ReplicationJob>(this.replicationService
       .getJobs(this.search.ruleId, params))
       .then(
diff --git a/src/ui_ng/lib/src/service/interface.ts b/src/ui_ng/lib/src/service/interface.ts
index 6b876154d..5aa592b98 100644
--- a/src/ui_ng/lib/src/service/interface.ts
+++ b/src/ui_ng/lib/src/service/interface.ts
@@ -1,3 +1,4 @@
+import {Project} from "../project-policy-config/project";
 /**
  * The base interface contains the general properties
  * 
@@ -83,18 +84,40 @@ export interface Endpoint extends Base {
  * 
  * @export
  * @interface ReplicationRule
+ * @interface Filter
+ * @interface Trigger
  */
 export interface ReplicationRule extends Base {
-    project_id: number | string;
-    project_name: string;
-    target_id: number | string;
-    target_name: string;
-    enabled: number;
-    description?: string;
-    cron_str?: string;
-    start_time?: Date;
-    error_job_count?: number;
-    deleted: number;
+    [key: string]: any;
+    id?: number;
+    name: string;
+    description: string;
+    projects: Project[];
+    targets: Endpoint[] ;
+    trigger: Trigger ;
+    filters: Filter[] ;
+    replicate_existing_image_now?: boolean;
+    replicate_deletion?: boolean;
+}
+
+export class Filter {
+    kind: string;
+    pattern: string;
+    constructor(kind: string, pattern: string) {
+        this.kind = kind;
+        this.pattern = pattern;
+    }
+}
+
+export class Trigger {
+    kind: string;
+    schedule_param: any | {
+        [key: string]: any | any[];
+    };
+    constructor(kind: string, param: any | { [key: string]: any | any[]; }) {
+        this.kind = kind;
+        this.schedule_param = param;
+    }
 }
 
 /**
@@ -115,7 +138,7 @@ export interface ReplicationJob {
  * @interface ReplicationJob
  */
 export interface ReplicationJobItem extends Base {
-    [key: string]: any | any[]
+    [key: string]: any | any[];
     status: string;
     repository: string;
     policy_id: number;
@@ -151,7 +174,7 @@ export interface AccessLog {
  * @interface AccessLogItem
  */
 export interface AccessLogItem {
-    [key: string]: any | any[]
+    [key: string]: any | any[];
     log_id: number;
     project_id: number;
     repo_name: string;
diff --git a/src/ui_ng/lib/src/service/project.service.ts b/src/ui_ng/lib/src/service/project.service.ts
index 341123dd7..6d90a20f4 100644
--- a/src/ui_ng/lib/src/service/project.service.ts
+++ b/src/ui_ng/lib/src/service/project.service.ts
@@ -6,7 +6,8 @@ import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
 
 import { Project } from '../project-policy-config/project';
 import { ProjectPolicy } from '../project-policy-config/project-policy-config.component';
-import {HTTP_JSON_OPTIONS, HTTP_GET_OPTIONS} from "../utils";
+import {HTTP_JSON_OPTIONS, HTTP_GET_OPTIONS, buildHttpRequestOptions} from "../utils";
+import {RequestQueryParams} from "./RequestQueryParams";
 
 /**
  * Define the service methods to handle the Prject related things.
@@ -38,6 +39,8 @@ export abstract class ProjectService {
      * @memberOf EndpointService
      */
     abstract updateProjectPolicy(projectId: number | string,  projectPolicy: ProjectPolicy): Observable<any> | Promise<any> | any;
+
+    abstract listProjects(name: string, isPublic: number, page?: number, pageSize?: number): Observable<Project[]> | Promise<Project[]> | Project[];
 }
 
 /**
@@ -68,6 +71,27 @@ export class ProjectDefaultService extends ProjectService {
                 .catch(error => Observable.throw(error));
   }
 
+    listProjects(name: string, isPublic: number, page?: number, pageSize?: number): Observable<Project[]> | Promise<Project[]> | Project[]  {
+        let params = new RequestQueryParams();
+        if (page && pageSize) {
+            params.set('page', page + '');
+            params.set('page_size', pageSize + '');
+        }
+        if (name && name.trim() !== "") {
+            params.set('name', name);
+
+        }
+        if (isPublic !== undefined) {
+            params.set('public', '' + isPublic);
+        }
+
+        // let options = new RequestOptions({ headers: this.getHeaders, search: params });
+        return this.http
+            .get(`/api/projects`, buildHttpRequestOptions(params))
+            .map(response => response.json())
+            .catch(error => Observable.throw(error));
+    }
+
   public updateProjectPolicy(projectId: number | string, projectPolicy: ProjectPolicy): any {
     return this.http
               .put(`/api/projects/${projectId}`, { 'metadata': {
diff --git a/src/ui_ng/lib/src/service/replication.service.ts b/src/ui_ng/lib/src/service/replication.service.ts
index ee111c279..ecb5b1797 100644
--- a/src/ui_ng/lib/src/service/replication.service.ts
+++ b/src/ui_ng/lib/src/service/replication.service.ts
@@ -1,6 +1,6 @@
 import { Observable } from 'rxjs/Observable';
 import { RequestQueryParams } from './RequestQueryParams';
-import { ReplicationJob, ReplicationRule, ReplicationJobItem } from './interface';
+import {ReplicationJob, ReplicationRule, ReplicationJobItem} from './interface';
 import { Injectable, Inject } from "@angular/core";
 import 'rxjs/add/observable/of';
 import { Http, RequestOptions } from '@angular/http';
@@ -62,7 +62,7 @@ export abstract class ReplicationService {
      * 
      * @memberOf ReplicationService
      */
-    abstract updateReplicationRule(replicationRule: ReplicationRule): Observable<any> | Promise<any> | any;
+    abstract updateReplicationRule(id: number, rep: ReplicationRule): Observable<any> | Promise<any> | any;
 
     /**
      * Delete the specified replication rule.
@@ -159,7 +159,7 @@ export class ReplicationDefaultService extends ReplicationService {
     //Private methods
     //Check if the rule object is valid
     _isValidRule(rule: ReplicationRule): boolean {
-        return rule !== undefined && rule != null && rule.name !== undefined && rule.name.trim() !== '' && rule.target_id !== 0;
+        return rule !== undefined && rule != null && rule.name !== undefined && rule.name.trim() !== '' && rule.targets.length !== 0;
     }
 
     public getReplicationRules(projectId?: number | string, ruleName?: string, queryParams?: RequestQueryParams): Observable<ReplicationRule[]> | Promise<ReplicationRule[]> | ReplicationRule[] {
@@ -177,7 +177,7 @@ export class ReplicationDefaultService extends ReplicationService {
 
         return this.http.get(this._ruleBaseUrl, buildHttpRequestOptions(queryParams)).toPromise()
             .then(response => response.json() as ReplicationRule[])
-            .catch(error => Promise.reject(error))
+            .catch(error => Promise.reject(error));
     }
 
     public getReplicationRule(ruleId: number | string): Observable<ReplicationRule> | Promise<ReplicationRule> | ReplicationRule {
@@ -201,13 +201,13 @@ export class ReplicationDefaultService extends ReplicationService {
             .catch(error => Promise.reject(error));
     }
 
-    public updateReplicationRule(replicationRule: ReplicationRule): Observable<any> | Promise<any> | any {
-        if (!this._isValidRule(replicationRule) || !replicationRule.id) {
+    public updateReplicationRule(id: number, rep: ReplicationRule): Observable<any> | Promise<any> | any {
+        if (!this._isValidRule(rep)) {
             return Promise.reject('Bad argument');
         }
 
-        let url: string = `${this._ruleBaseUrl}/${replicationRule.id}`;
-        return this.http.put(url, JSON.stringify(replicationRule), HTTP_JSON_OPTIONS).toPromise()
+        let url = `${this._ruleBaseUrl}/${id}`;
+        return this.http.put(url, JSON.stringify(rep), HTTP_JSON_OPTIONS).toPromise()
             .then(response => response)
             .catch(error => Promise.reject(error));
     }
@@ -298,7 +298,7 @@ export class ReplicationDefaultService extends ReplicationService {
             return Promise.reject('Bad argument');
         }
 
-        let logUrl: string = `${this._jobBaseUrl}/${jobId}/log`;
+        let logUrl = `${this._jobBaseUrl}/${jobId}/log`;
         return this.http.get(logUrl, HTTP_GET_OPTIONS).toPromise()
             .then(response => response.text())
             .catch(error => Promise.reject(error));
diff --git a/src/ui_ng/lib/src/shared/shared.module.ts b/src/ui_ng/lib/src/shared/shared.module.ts
index 365b14ee9..63d85fa16 100644
--- a/src/ui_ng/lib/src/shared/shared.module.ts
+++ b/src/ui_ng/lib/src/shared/shared.module.ts
@@ -2,8 +2,8 @@ import { NgModule } from '@angular/core';
 import { CommonModule } from '@angular/common';
 import { HttpModule, Http } from '@angular/http';
 import { ClarityModule } from 'clarity-angular';
-import { FormsModule } from '@angular/forms';
-import { TranslateModule, TranslateLoader, TranslateService, MissingTranslationHandler } from '@ngx-translate/core';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { TranslateModule, TranslateLoader, MissingTranslationHandler } from '@ngx-translate/core';
 import { MyMissingTranslationHandler } from '../i18n/missing-trans.handler';
 import { TranslateHttpLoader } from '@ngx-translate/http-loader';
 import { TranslatorJsonLoader } from '../i18n/local-json.loader';
@@ -41,6 +41,7 @@ export function GeneralTranslatorLoader(http: Http, config: IServiceConfig) {
         CommonModule,
         HttpModule,
         FormsModule,
+        ReactiveFormsModule,
         ClipboardModule,
         CookieModule.forRoot(),
         ClarityModule.forRoot(),
@@ -60,6 +61,7 @@ export function GeneralTranslatorLoader(http: Http, config: IServiceConfig) {
         CommonModule,
         HttpModule,
         FormsModule,
+        ReactiveFormsModule,
         CookieModule,
         ClipboardModule,
         ClarityModule,
diff --git a/src/ui_ng/package.json b/src/ui_ng/package.json
index 2afe1600e..88b5993f2 100644
--- a/src/ui_ng/package.json
+++ b/src/ui_ng/package.json
@@ -31,7 +31,7 @@
         "clarity-icons": "^0.10.17",
         "clarity-ui": "^0.10.17",
         "core-js": "^2.4.1",
-        "harbor-ui": "0.6.45",
+        "harbor-ui": "0.6.46",
         "intl": "^1.2.5",
         "mutationobserver-shim": "^0.3.2",
         "ngx-cookie": "^1.0.0",
diff --git a/src/ui_ng/src/app/harbor-routing.module.ts b/src/ui_ng/src/app/harbor-routing.module.ts
index 42e083df2..9b84013cd 100644
--- a/src/ui_ng/src/app/harbor-routing.module.ts
+++ b/src/ui_ng/src/app/harbor-routing.module.ts
@@ -50,8 +50,6 @@ import { LeavingConfigRouteDeactivate } from './shared/route/leaving-config-deac
 import { MemberGuard } from './shared/route/member-guard-activate.service';
 
 import { TagDetailPageComponent } from './repository/tag-detail/tag-detail-page.component';
-import { ReplicationRuleComponent} from "./replication/replication-rule/replication-rule.component";
-import {LeavingNewRuleRouteDeactivate} from "./shared/route/leaving-new-rule-deactivate.service";
 import { LeavingRepositoryRouteDeactivate } from './shared/route/leaving-repository-deactivate.service';
 
 const harborRoutes: Routes = [
@@ -92,20 +90,6 @@ const harborRoutes: Routes = [
         canActivate: [SystemAdminGuard],
         canActivateChild: [SystemAdminGuard],
       },
-      {
-          path: 'replications/:id/rule',
-          component: ReplicationRuleComponent,
-          canActivate: [SystemAdminGuard],
-          canActivateChild: [SystemAdminGuard],
-          canDeactivate: [LeavingNewRuleRouteDeactivate]
-      },
-      {
-        path: 'replications/new-rule',
-        component: ReplicationRuleComponent,
-        canActivate: [SystemAdminGuard],
-        canActivateChild: [SystemAdminGuard],
-        canDeactivate: [LeavingNewRuleRouteDeactivate]
-      },
       {
         path: 'tags/:id/:repo',
         component: TagRepositoryComponent,
diff --git a/src/ui_ng/src/app/replication/replication-page.component.html b/src/ui_ng/src/app/replication/replication-page.component.html
index 83bea8c9b..e61451484 100644
--- a/src/ui_ng/src/app/replication/replication-page.component.html
+++ b/src/ui_ng/src/app/replication/replication-page.component.html
@@ -1,3 +1,3 @@
 <div style="margin-top: 24px;">
-    <hbr-replication  [readonly]="true" #replicationView [projectId]="projectIdentify" [isSystemAdmin]="isSystemAdmin" [withReplicationJob]='true'  (openCreateRule)="openCreatePage()"  (openEdit)="openEditPage($event)"></hbr-replication>
+    <hbr-replication #replicationView [projectId]="projectIdentify" [projectName]="projectName" [isSystemAdmin]="isSystemAdmin" [withReplicationJob]='true' ></hbr-replication>
 </div>
\ No newline at end of file
diff --git a/src/ui_ng/src/app/replication/replication-page.component.ts b/src/ui_ng/src/app/replication/replication-page.component.ts
index 69c25e83d..863c36e0e 100644
--- a/src/ui_ng/src/app/replication/replication-page.component.ts
+++ b/src/ui_ng/src/app/replication/replication-page.component.ts
@@ -15,6 +15,8 @@ import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
 import {ActivatedRoute, Router} from '@angular/router';
 import { ReplicationComponent } from 'harbor-ui';
 import {SessionService} from "../shared/session.service";
+import {Project} from "../project/project";
+import {ProjectService} from "../project/project.service";
 
 @Component({
   selector: 'replicaton',
@@ -23,13 +25,25 @@ import {SessionService} from "../shared/session.service";
 export class ReplicationPageComponent implements OnInit, AfterViewInit {
   projectIdentify: string | number;
   @ViewChild("replicationView") replicationView: ReplicationComponent;
+  projectName: string;
 
   constructor(private route: ActivatedRoute,
-              private router: Router,
+              private proService: ProjectService,
               private session: SessionService) { }
 
   ngOnInit(): void {
     this.projectIdentify = +this.route.snapshot.parent.params['id'];
+
+    this.proService.listProjects("", undefined).toPromise()
+        .then(response => {
+          let projects = response.json() as Project[];
+          if (projects.length) {
+            let project = projects.find(data => data.project_id === this.projectIdentify);
+            if (project) {
+              this.projectName = project.name;
+            }
+          }
+        });
   }
 
   public get isSystemAdmin(): boolean {
@@ -37,14 +51,6 @@ export class ReplicationPageComponent implements OnInit, AfterViewInit {
     return account != null && account.has_admin_role > 0;
   }
 
-  openEditPage(id: number): void {
-    this.router.navigate(['harbor', 'replications', id, 'rule', { projectId: this.projectIdentify}]);
-  }
-
-  openCreatePage(): void {
-    this.router.navigate(['harbor', 'replications', 'new-rule', { projectId: this.projectIdentify}] );
-  }
-
   ngAfterViewInit(): void {
     let isCreated: boolean = this.route.snapshot.queryParams['is_create'];
     if (isCreated) {
diff --git a/src/ui_ng/src/app/replication/replication-rule/list-project-model/list-project-model.component.css b/src/ui_ng/src/app/replication/replication-rule/list-project-model/list-project-model.component.css
deleted file mode 100644
index ab5ec9250..000000000
--- a/src/ui_ng/src/app/replication/replication-rule/list-project-model/list-project-model.component.css
+++ /dev/null
@@ -1,5 +0,0 @@
-.datagrid .datagrid-head{border: 0;}
-.option-right{ position: absolute; right: 30px; top: 55px;}
-:host >>> .datagrid-head{height: 0;border-width: 0;}
-:host >>> .datagrid-scroll-wrapper .datagrid{margin-top: 0;}
-.modal-body{height: 30em; overflow-y: auto; margin-top: 20px;}
diff --git a/src/ui_ng/src/app/replication/replication-rule/list-project-model/list-project-model.component.html b/src/ui_ng/src/app/replication/replication-rule/list-project-model/list-project-model.component.html
deleted file mode 100644
index 0af247b58..000000000
--- a/src/ui_ng/src/app/replication/replication-rule/list-project-model/list-project-model.component.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<clr-modal [(clrModalOpen)]="ismodelOpen"  [clrModalClosable]="false">
-    <h3 class="modal-title">{{'PROJECT.ALL_PROJECTS' | translate}}</h3>
-    <inline-alert class="modal-title" ></inline-alert>
-    <div class="modal-body">
-    <div class="option-right">
-        <div class="select" style="float: left; left:-6px; top:8px;">
-            <select (change)="doFilterProject()" [(ngModel)]="selecteType">
-                <option value="0" [selected]="currentFilteredType === 0">{{projectTypes[0] | translate}}</option>
-                <option value="1">{{projectTypes[1] | translate}}</option>
-                <option value="2">{{projectTypes[2] | translate}}</option>
-            </select>
-        </div>
-        <hbr-filter [withDivider]="true" filterPlaceholder='{{"PROJECT.FILTER_PLACEHOLDER" | translate}}' (filter)="doSearchProject($event)" [currentValue]="projectName"></hbr-filter>
-        <span class="refresh-btn" (click)="refresh()">
-                <clr-icon shape="refresh"></clr-icon>
-            </span>
-    </div>
-
-    <clr-datagrid (clrDgRefresh)="clrLoad($event)" [clrDgLoading]="loading"  [(clrDgSingleSelected)]="selectedProject">
-        <clr-dg-row *ngFor="let project of projects; let i = index"  [clrDgItem]="project">
-            <clr-dg-cell>{{project.name}}</clr-dg-cell>
-        </clr-dg-row>
-        <clr-dg-footer>
-            <span *ngIf="pagination.totalItems">{{pagination.firstItem + 1}} - {{pagination.lastItem +1 }} {{'PROJECT.OF' | translate}} </span> {{pagination.totalItems }} {{'PROJECT.ITEMS' | translate}}
-            <clr-dg-pagination #pagination [clrDgPageSize]="pageSize" [(clrDgPage)]="currentPage" [clrDgTotalItems]="totalCount"></clr-dg-pagination>
-        </clr-dg-footer>
-    </clr-datagrid>
-    </div>
-<div class="modal-footer">
-    <button type="button" class="btn btn-outline" (click)="closeModel()">{{'BUTTON.CANCEL' | translate}}</button>
-    <button type="button" class="btn btn-primary" [disabled]="!selectedProject" (click)="oKModel()">{{'BUTTON.OK' | translate}}</button>
-</div>
-</clr-modal>
diff --git a/src/ui_ng/src/app/replication/replication-rule/list-project-model/list-project-model.component.ts b/src/ui_ng/src/app/replication/replication-rule/list-project-model/list-project-model.component.ts
deleted file mode 100644
index bf9738c99..000000000
--- a/src/ui_ng/src/app/replication/replication-rule/list-project-model/list-project-model.component.ts
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-import {
-    Component,
-    Output,
-    Input,
-    ChangeDetectionStrategy,
-    ChangeDetectorRef,
-    OnDestroy, EventEmitter
-} from '@angular/core';
-import { Router, NavigationExtras } from '@angular/router';
-
-import { SessionService } from '../../../shared/session.service';
-import { SearchTriggerService } from '../../../base/global-search/search-trigger.service';
-import { ProjectTypes, RoleInfo} from '../../../shared/shared.const';
-import { CustomComparator, doFiltering, doSorting, calculatePage } from '../../../shared/shared.utils';
-
-import { Comparator, State } from 'clarity-angular';
-import { MessageHandlerService } from '../../../shared/message-handler/message-handler.service';
-import { StatisticHandler } from '../../../shared/statictics/statistic-handler.service';
-import { Subscription } from 'rxjs/Subscription';
-import { ConfirmationDialogService } from '../../../shared/confirmation-dialog/confirmation-dialog.service';
-import { ConfirmationMessage } from '../../../shared/confirmation-dialog/confirmation-message';
-import { ConfirmationTargets, ConfirmationState, ConfirmationButtons } from '../../../shared/shared.const';
-import {ProjectService} from "../../../project/project.service";
-import {Project} from "../../../project/project";
-
-@Component({
-    selector: 'list-project-model',
-    templateUrl: 'list-project-model.component.html',
-    styleUrls: ['list-project-model.component.css'],
-    changeDetection: ChangeDetectionStrategy.OnPush
-})
-export class ListProjectModelComponent {
-    projectTypes = ProjectTypes;
-    loading: boolean = true;
-    projects: Project[] = [];
-    filteredType: number = 0;//All projects
-    searchKeyword: string = "";
-    ismodelOpen: boolean ;
-    currentFilteredType: number = 0;//all projects
-    projectName: string = "";
-    selectedProject: Project;
-
-    roleInfo = RoleInfo;
-    repoCountComparator: Comparator<Project> = new CustomComparator<Project>("repo_count", "number");
-    timeComparator: Comparator<Project> = new CustomComparator<Project>("creation_time", "date");
-    accessLevelComparator: Comparator<Project> = new CustomComparator<Project>("public", "number");
-    roleComparator: Comparator<Project> = new CustomComparator<Project>("current_user_role_id", "number");
-    currentPage: number = 1;
-    totalCount: number = 0;
-    pageSize: number = 10;
-    currentState: State;
-    @Output() selectedPro = new EventEmitter<Project>();
-
-    constructor(
-        private session: SessionService,
-        private router: Router,
-        private searchTrigger: SearchTriggerService,
-        private proService: ProjectService,
-        private msgHandler: MessageHandlerService,
-        private statisticHandler: StatisticHandler,
-        private deletionDialogService: ConfirmationDialogService,
-        private ref: ChangeDetectorRef) {
-    }
-
-    get selecteType(): number {
-        return this.currentFilteredType;
-    }
-    set selecteType(_project: number) {
-        this.currentFilteredType = _project;
-        if (window.sessionStorage) {
-            window.sessionStorage['projectTypeValue'] = _project;
-        }
-    }
-
-
-    clrLoad(state: State) {
-        this.selectedProject = null;
-        //Keep state for future filtering and sorting
-        this.currentState = state;
-
-        let pageNumber: number = calculatePage(state);
-        if (pageNumber <= 0) { pageNumber = 1; }
-
-        this.loading = true;
-
-        let passInFilteredType: number = undefined;
-        if (this.filteredType > 0) {
-            passInFilteredType = this.filteredType - 1;
-        }
-        this.proService.listProjects(this.searchKeyword, passInFilteredType, pageNumber, this.pageSize).toPromise()
-            .then(response => {
-                //Get total count
-                if (response.headers) {
-                    let xHeader: string = response.headers.get("X-Total-Count");
-                    if (xHeader) {
-                        this.totalCount = parseInt(xHeader, 0);
-                    }
-                }
-
-                this.projects = response.json() as Project[];
-                //Do customising filtering and sorting
-                this.projects = doFiltering<Project>(this.projects, state);
-                this.projects = doSorting<Project>(this.projects, state);
-
-                this.loading = false;
-            })
-            .catch(error => {
-                this.loading = false;
-                this.msgHandler.handleError(error);
-            });
-
-        //Force refresh view
-        let hnd = setInterval(() => this.ref.markForCheck(), 100);
-        setTimeout(() => clearInterval(hnd), 3000);
-    }
-
-    openModel(): void {
-        this.selectedProject = null;
-        this.ismodelOpen = true;
-        //Force refresh view
-        let hnd = setInterval(() => this.ref.markForCheck(), 100);
-        setTimeout(() => clearInterval(hnd), 2000);
-    }
-
-    refresh(): void {
-        this.currentPage = 1;
-        this.filteredType = 0;
-        this.searchKeyword = '';
-
-        this.reload();
-    }
-
-    doFilterProject(): void {
-        this.currentPage = 1;
-        this.filteredType = this.selecteType;
-        this.reload();
-    }
-
-    doSearchProject(proName: string): void {
-        this.projectName = proName;
-        this.currentPage = 1;
-        this.searchKeyword = proName;
-        this.reload();
-    }
-
-    reload(): void {
-        let st: State = this.currentState;
-        if (!st) {
-            st = {
-                page: {}
-            };
-        }
-        st.page.from = 0;
-        st.page.to = this.pageSize - 1;
-        st.page.size = this.pageSize;
-
-        this.clrLoad(st);
-    }
-
-    oKModel() {
-        this.ismodelOpen = false;
-        this.selectedPro.emit(this.selectedProject);
-    }
-
-    closeModel(): void {
-        this.ismodelOpen = false;
-    }
-}
diff --git a/src/ui_ng/src/app/replication/replication-rule/replication-rule.component.ts b/src/ui_ng/src/app/replication/replication-rule/replication-rule.component.ts
deleted file mode 100644
index f45431806..000000000
--- a/src/ui_ng/src/app/replication/replication-rule/replication-rule.component.ts
+++ /dev/null
@@ -1,590 +0,0 @@
-import {Component, OnInit, OnDestroy, ViewChild, ChangeDetectorRef, AfterViewInit} from '@angular/core';
-import {ProjectService} from '../../project/project.service';
-import {Project} from '../../project/project';
-import {ActivatedRoute, Router} from '@angular/router';
-import {FormArray, FormBuilder, FormGroup, Validators} from "@angular/forms";
-import {ReplicationRuleServie} from "./replication-rule.service";
-import {MessageHandlerService} from "../../shared/message-handler/message-handler.service";
-import {Target, Filter, ReplicationRule} from "./replication-rule";
-import {ConfirmationDialogService} from "../../shared/confirmation-dialog/confirmation-dialog.service";
-import { ConfirmationTargets, ConfirmationState } from '../../shared/shared.const';
-import {Subscription} from "rxjs/Subscription";
-import {ConfirmationMessage} from "../../shared/confirmation-dialog/confirmation-message";
-import {Subject} from "rxjs/Subject";
-import {ListProjectModelComponent} from "./list-project-model/list-project-model.component";
-import {toPromise, isEmptyObject, compareValue} from "harbor-ui/src/utils";
-import {CreateEditEndpointComponent} from "harbor-ui/src/create-edit-endpoint/create-edit-endpoint.component";
-
-const ONE_HOUR_SECONDS: number = 3600;
-const ONE_DAY_SECONDS: number = 24 * ONE_HOUR_SECONDS;
-
-@Component ({
-    selector: 'repliction-rule',
-    templateUrl: 'replication-rule.html',
-    styleUrls: ['replication-rule.css']
-
-})
-
-export class ReplicationRuleComponent implements OnInit, OnDestroy {
-    _localTime: Date = new Date();
-    policyId: number;
-    projectId: number;
-    targetList: Target[] = [];
-    isFilterHide: boolean = false;
-    weeklySchedule: boolean;
-    isScheduleOpt: boolean;
-    isImmediate: boolean = false;
-    noProjectInfo: string = "";
-    noSelectedProject: boolean = true;
-    noSelectedEndpoint: boolean = true;
-    filterCount: number = 0;
-    selectedprojectList: Project[] = [];
-    triggerNames: string[] = ['Manual', 'Immediate', 'Scheduled'];
-    scheduleNames: string[] = ['Daily', 'Weekly'];
-    weekly: string[] = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
-    filterSelect: string[] = ['repository', 'tag'];
-    ruleNameTooltip: string = 'TOOLTIP.EMPTY';
-    headerTitle: string = 'REPLICATION.ADD_POLICY';
-
-    filterListData: {[key: string]: any}[] = [];
-    inProgress: boolean = false;
-    inNameChecking: boolean = false;
-    isRuleNameExist: boolean = false;
-    isSubmitOver: boolean = false;
-    nameChecker: Subject<string> = new Subject<string>();
-
-    confirmSub: Subscription;
-    ruleForm: FormGroup;
-    copyUpdateForm: ReplicationRule;
-    emptyEndpoint = new Target();
-
-    @ViewChild(ListProjectModelComponent)
-    projectListModel: ListProjectModelComponent;
-
-    @ViewChild(CreateEditEndpointComponent)
-    createEditEndpointComponent: CreateEditEndpointComponent;
-
-    baseFilterData(name: string, option: string[], state: boolean) {
-        return {
-            name: name,
-            options: option,
-            state: state,
-            isValid: true
-        };
-    }
-
-    constructor(public projectService: ProjectService,
-                private router: Router,
-                private fb: FormBuilder,
-                private repService: ReplicationRuleServie,
-                private route: ActivatedRoute,
-                private msgHandler: MessageHandlerService,
-                private confirmService: ConfirmationDialogService,
-                public ref: ChangeDetectorRef) {
-        this.createForm();
-        Promise.all([this.repService.getEndpoints(), this.repService.listProjects()])
-            .then(res => {
-                if (!res[0]) {
-                    this.noSelectedEndpoint = true;
-                }else {
-                    this.targetList = res[0];
-                    if (!this.policyId) {
-                        res[0].unshift(this.emptyEndpoint);
-                        this.setTarget([res[0][0]]);
-                    }
-                }
-                if (!res[1]) {
-                    this.noProjectInfo = 'REPLICATION.NO_PROJECT_INFO';
-                }else {
-                    if (!this.policyId && !this.projectId) {
-                        this.setProject([res[1][0]]);
-                    }
-                    if (!this.policyId && this.projectId) {
-                        this.setProject( res[1].filter(rule => rule.project_id === this.projectId));
-                        this.noSelectedProject = false;
-                    }
-                }
-                if (!this.policyId) {
-                    this.copyUpdateForm = Object.assign({}, this.ruleForm.value);
-                }
-            });
-    }
-
-    ngOnInit(): void {
-       this.policyId = +this.route.snapshot.params['id'];
-       this.projectId = +this.route.snapshot.params['projectId'];
-       if (this.policyId) {
-           this.headerTitle = 'REPLICATION.EDIT_POLICY_TITLE';
-           this.repService.getReplicationRule(this.policyId)
-               .then((response) => {
-                    this.copyUpdateForm = Object.assign({}, response);
-                    // set filter value is [] if callback fiter value is null.
-                   this.copyUpdateForm.filters = response.filters ? response.filters : [];
-                    this.updateForm(response);
-               }).catch(error => {
-               this.msgHandler.handleError(error);
-           });
-       }
-
-       this.nameChecker.debounceTime(500).distinctUntilChanged().subscribe((ruleName: string) => {
-           this.isRuleNameExist = false;
-           this.inNameChecking = true;
-           toPromise<ReplicationRule[]>(this.repService.getReplicationRules(0, ruleName))
-               .then(response => {
-                   if (response.some(rule => rule.name === ruleName)) {
-                       this.ruleNameTooltip = 'TOOLTIP.RULE_USER_EXISTING';
-                       this.isRuleNameExist = true;
-                   }
-                   this.inNameChecking = false;
-               }).catch(() => {
-               this.inNameChecking = false;
-           });
-       });
-    }
-
-    ngOnDestroy(): void {
-        if (this.confirmSub) {
-            this.confirmSub.unsubscribe();
-        }
-        if (this.nameChecker) {
-            this.nameChecker.unsubscribe();
-        }
-    }
-
-    get isVaild() {
-        return !(this.isRuleNameExist || this.noSelectedProject || this.noSelectedEndpoint || this.inProgress || this.isSubmitOver);
-    }
-
-    createForm() {
-        this.ruleForm = this.fb.group({
-            name: ['', Validators.required],
-            description: '',
-            projects: this.fb.array([]),
-            targets: this.fb.array([]),
-            trigger: this.fb.group({
-                kind: this.triggerNames[0],
-                schedule_param: this.fb.group({
-                    type: this.scheduleNames[0],
-                    weekday: 1,
-                    offtime: '08:00'
-                }),
-            }),
-            filters: this.fb.array([]),
-            replicate_existing_image_now: true,
-            replicate_deletion: false
-        });
-    }
-
-    updateForm(rule: ReplicationRule): void {
-        rule.trigger = this.updateTrigger(rule.trigger);
-        this.ruleForm.reset({
-            name: rule.name,
-            description: rule.description,
-            trigger: rule.trigger,
-            replicate_existing_image_now: rule.replicate_existing_image_now,
-            replicate_deletion: rule.replicate_deletion
-        });
-        this.setProject(rule.projects);
-        this.noSelectedProject = false;
-        this.setTarget(rule.targets);
-        this.noSelectedEndpoint = false;
-
-        if (rule.filters) {
-            this.setFilter(rule.filters);
-            this.updateFilter(rule.filters);
-        }
-
-        // Force refresh view
-        let hnd = setInterval(() => this.ref.markForCheck(), 100);
-        setTimeout(() => clearInterval(hnd), 2000);
-    }
-
-    get projects(): FormArray {
-        return this.ruleForm.get('projects') as FormArray;
-    }
-    setProject(projects: Project[]) {
-        const projectFGs = projects.map(project => this.fb.group(project));
-        const projectFormArray = this.fb.array(projectFGs);
-        this.ruleForm.setControl('projects', projectFormArray);
-    }
-
-    get filters(): FormArray {
-        return this.ruleForm.get('filters') as FormArray;
-    }
-    setFilter(filters: Filter[]) {
-        const filterFGs = filters.map(filter => this.fb.group(filter));
-        const filterFormArray = this.fb.array(filterFGs);
-        this.ruleForm.setControl('filters', filterFormArray);
-    }
-
-    get targets(): FormArray {
-        return this.ruleForm.get('targets') as FormArray;
-    }
-    setTarget(targets: Target[]) {
-        const targetFGs = targets.map(target => this.fb.group(target));
-        const targetFormArray = this.fb.array(targetFGs);
-        this.ruleForm.setControl('targets', targetFormArray);
-    }
-
-    initFilter(name: string) {
-        return this.fb.group({
-            kind: name,
-            pattern: ['', Validators.required]
-        });
-    }
-
-    filterChange($event: any) {
-        if ($event && $event.target['value']) {
-            let id: number = $event.target.id;
-            let name: string = $event.target.name;
-            let value: string = $event.target['value'];
-
-            this.filterListData.forEach((data, index) => {
-                if (index === +id) {
-                    data.name = $event.target.name = value;
-                }else {
-                    data.options.splice(data.options.indexOf(value), 1);
-                }
-                if (data.options.indexOf(name) === -1) {
-                    data.options.push(name);
-                }
-            });
-        }
-    }
-
-    targetChange($event: any) {
-        if ($event && $event.target && event.target['value']) {
-            if ($event.target['value'] === '-1') {
-                this.noSelectedEndpoint = true;
-                return;
-            }
-            let selecedTarget: Target = this.targetList.find(target => target.id === +$event.target['value']);
-            this.setTarget([selecedTarget]);
-            this.noSelectedEndpoint = false;
-        }
-    }
-
-    openProjectModel(): void {
-        this.projectListModel.openModel();
-    }
-
-    selectedProject(project: Project): void {
-        if (!project) {
-            this.noSelectedProject = true;
-        }else {
-            this.noSelectedProject = false;
-            this.setProject([project]);
-        }
-    }
-
-    addNewFilter(): void {
-        if (this.filterCount === 0) {
-            this.filterListData.push(this.baseFilterData(this.filterSelect[0], this.filterSelect.slice(), true));
-            this.filters.push(this.initFilter(this.filterSelect[0]));
-
-        }else {
-            let nameArr: string[] = this.filterSelect.slice();
-            this.filterListData.forEach(data => {
-                nameArr.splice(nameArr.indexOf(data.name), 1);
-            });
-            // when add a new filter,the filterListData should change the options
-            this.filterListData.filter((data) => {
-                data.options.splice(data.options.indexOf(nameArr[0]), 1);
-            });
-            this.filterListData.push(this.baseFilterData(nameArr[0], nameArr, true));
-            this.filters.push(this.initFilter(nameArr[0]));
-        }
-        this.filterCount += 1;
-        if (this.filterCount >= this.filterSelect.length) {
-            this.isFilterHide = true;
-        }
-    }
-
-    // delete a filter
-    deleteFilter(i: number): void {
-        if (i || i === 0) {
-            let delfilter = this.filterListData.splice(i, 1)[0];
-            if (this.filterCount === this.filterSelect.length) {
-                this.isFilterHide = false;
-            }
-            this.filterCount -= 1;
-            if (this.filterListData.length) {
-                let optionVal = delfilter.name;
-                this.filterListData.filter(data => {
-                    if (data.options.indexOf(optionVal) === -1) {
-                        data.options.push(optionVal);
-                    }
-                });
-            }
-            const control = <FormArray>this.ruleForm.controls['filters'];
-            control.removeAt(i);
-        }
-    }
-
-    selectTrigger($event: any): void {
-        if ($event && $event.target && $event.target['value']) {
-            let val: string = $event.target['value'];
-            if (val === this.triggerNames[2]) {
-                this.isScheduleOpt = true;
-                this.isImmediate = false;
-            }
-            if (val === this.triggerNames[1]) {
-                this.isScheduleOpt = false;
-                this.isImmediate = true;
-            }
-            if (val === this.triggerNames[0]) {
-                this.isScheduleOpt = false;
-                this.isImmediate = false;
-            }
-        }
-    }
-
-    // Replication Schedule select value exchange
-    selectSchedule($event: any): void {
-        if ($event && $event.target && $event.target['value']) {
-            switch ($event.target['value']) {
-                case this.scheduleNames[1]:
-                    this.weeklySchedule = true;
-                    this.ruleForm.patchValue({
-                        trigger: {
-                            schedule_param: {
-                                weekday: 1,
-                            }
-                        }
-                    })
-                    break;
-                case this.scheduleNames[0]:
-                    this.weeklySchedule = false;
-                    break;
-            }
-        }
-    }
-
-    checkRuleName(): void {
-        let ruleName: string = this.ruleForm.controls['name'].value;
-        if (ruleName) {
-            this.nameChecker.next(ruleName);
-        } else {
-            this.ruleNameTooltip = 'TOOLTIP.EMPTY';
-        }
-    }
-
-    updateFilter(filters: any) {
-        let opt: string[] = this.filterSelect.slice();
-        filters.forEach((filter: any) => {
-            opt.splice(opt.indexOf(filter.kind), 1);
-        })
-        filters.forEach((filter: any) => {
-            let option: string [] = opt.slice();
-            option.unshift(filter.kind);
-            this.filterListData.push(this.baseFilterData(filter.kind, option, true));
-        });
-        this.filterCount = filters.length;
-        if (filters.length === this.filterSelect.length) {
-            this.isFilterHide = true;
-        }
-    }
-
-    updateTrigger(trigger: any) {
-        if (trigger['schedule_param']) {
-            this.isScheduleOpt = true;
-            this.isImmediate = false;
-            trigger['schedule_param']['offtime'] = this.getOfftime(trigger['schedule_param']['offtime']);
-            if (trigger['schedule_param']['weekday']) {
-                this.weeklySchedule = true;
-            }else {
-                // set default
-                trigger['schedule_param']['weekday'] = 1;
-            }
-        }else {
-            if (trigger['kind'] === this.triggerNames[0]) {
-                this.isImmediate = false;
-            }
-            trigger['schedule_param'] = { type: this.scheduleNames[0],
-                weekday: this.weekly[0],
-                offtime: '08:00'};
-        }
-        return trigger;
-    }
-
-    setTriggerVaule(trigger: any) {
-        if (!this.isScheduleOpt) {
-            delete trigger['schedule_param'];
-            return trigger;
-        }else {
-            if (!this.weeklySchedule) {
-                delete trigger['schedule_param']['weekday'];
-            }else {
-                trigger['schedule_param']['weekday'] = +trigger['schedule_param']['weekday'];
-            }
-            trigger['schedule_param']['offtime'] = this.setOfftime(trigger['schedule_param']['offtime']);
-            return trigger;
-        }
-    }
-
-    public hasFormChange(): boolean {
-        return !isEmptyObject(this.getChanges());
-    }
-
-    onSubmit() {
-        // add new Replication rule
-        this.inProgress = true;
-        let copyRuleForm: ReplicationRule = this.ruleForm.value;
-        copyRuleForm.trigger = this.setTriggerVaule(copyRuleForm.trigger);
-        if (!this.policyId) {
-            this.repService.createReplicationRule(copyRuleForm)
-                .then(() => {
-                    this.msgHandler.showSuccess('REPLICATION.CREATED_SUCCESS');
-                    this.inProgress = false;
-                    this.isSubmitOver = true;
-                    setTimeout(() => {
-                        this.copyUpdateForm = Object.assign({}, this.ruleForm.value);
-                        if (this.projectId) {
-                            this.router.navigate(['harbor/projects', this.projectId, 'replications']);
-                        }else {
-                            this.router.navigate(['/harbor/replications']);
-                        }
-                    }, 2000);
-
-                }).catch((error: any) => {
-                this.inProgress = false;
-                this.msgHandler.handleError(error);
-            });
-        } else {
-            this.repService.updateReplicationRule(this.policyId, this.ruleForm.value)
-                .then(() => {
-                    this.msgHandler.showSuccess('REPLICATION.UPDATED_SUCCESS');
-                    this.inProgress = false;
-                    this.isSubmitOver = true;
-                    setTimeout(() => {
-                        this.copyUpdateForm = Object.assign({}, this.ruleForm.value);
-                        if (this.projectId) {
-                            this.router.navigate(['harbor/projects', this.projectId, 'replications']);
-                        }else {
-                            this.router.navigate(['/harbor/replications']);
-                        }
-                    }, 2000);
-
-                }).catch((error: any) => {
-                this.inProgress = false;
-                this.msgHandler.handleError(error);
-            });
-        }
-    }
-
-    openModal() {
-        this.createEditEndpointComponent.openCreateEditTarget(true);
-    }
-
-    reload($event: boolean) {
-        if ($event) {
-            Promise.all([this.repService.getEndpoints()]).then(res => {
-                this.targetList = res[0];
-                this.setTarget([this.targetList[this.targetList.length - 1]]);
-                this.noSelectedEndpoint = false;
-            });
-        }
-    }
-
-    onCancel(): void {
-        this.router.navigate(['/harbor/replications']);
-    }
-
-    // UTC time
-    public getOfftime(daily_time: any): string {
-
-        let timeOffset: number = 0; // seconds
-        if (daily_time && typeof daily_time === 'number') {
-            timeOffset = +daily_time;
-        }
-
-        // Convert to current time
-        let timezoneOffset: number = this._localTime.getTimezoneOffset();
-        // Local time
-        timeOffset = timeOffset - timezoneOffset * 60;
-        if (timeOffset < 0) {
-            timeOffset = timeOffset + ONE_DAY_SECONDS;
-        }
-
-        if (timeOffset >= ONE_DAY_SECONDS) {
-            timeOffset -= ONE_DAY_SECONDS;
-        }
-
-        // To time string
-        let hours: number = Math.floor(timeOffset / ONE_HOUR_SECONDS);
-        let minutes: number = Math.floor((timeOffset - hours * ONE_HOUR_SECONDS) / 60);
-
-        let timeStr: string = '' + hours;
-        if (hours < 10) {
-            timeStr = '0' + timeStr;
-        }
-        if (minutes < 10) {
-            timeStr += ':0';
-        } else {
-            timeStr += ':';
-        }
-        timeStr += minutes;
-
-        return timeStr;
-    }
-    public setOfftime(v: string) {
-        if (!v || v === '') {
-            return;
-        }
-
-        let values: string[] = v.split(':');
-        if (!values || values.length !== 2) {
-            return;
-        }
-
-        let hours: number = +values[0];
-        let minutes: number = +values[1];
-        // Convert to UTC time
-        let timezoneOffset: number = this._localTime.getTimezoneOffset();
-        let utcTimes: number = hours * ONE_HOUR_SECONDS + minutes * 60;
-        utcTimes += timezoneOffset * 60;
-        if (utcTimes < 0) {
-            utcTimes += ONE_DAY_SECONDS;
-        }
-
-        if (utcTimes >= ONE_DAY_SECONDS) {
-            utcTimes -= ONE_DAY_SECONDS;
-        }
-
-        return utcTimes;
-    }
-
-    backReplication(): void {
-        this.router.navigate(['/harbor/replications']);
-    }
-    backProjectReplication(): void {
-        this.router.navigate(['harbor/projects', this.projectId, 'replications']);
-    }
-
-
-    getChanges(): { [key: string]: any | any[] } {
-        let changes: { [key: string]: any | any[] } = {};
-        let ruleValue: { [key: string]: any | any[] } = this.ruleForm.value;
-        if (!ruleValue || !this.copyUpdateForm) {
-            return changes;
-        }
-        for (let prop in ruleValue) {
-            let field = this.copyUpdateForm[prop];
-            if (!compareValue(field, ruleValue[prop])) {
-                changes[prop] = ruleValue[prop];
-                //Number
-                if (typeof field === "number") {
-                    changes[prop] = +changes[prop];
-                }
-
-                //Trim string value
-                if (typeof field === "string") {
-                    changes[prop] = ('' + changes[prop]).trim();
-                }
-            }
-        }
-
-        return changes;
-    }
-
-}
diff --git a/src/ui_ng/src/app/replication/replication-rule/replication-rule.css b/src/ui_ng/src/app/replication/replication-rule/replication-rule.css
deleted file mode 100644
index 4942247e5..000000000
--- a/src/ui_ng/src/app/replication/replication-rule/replication-rule.css
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * Created by pengf on 9/28/2017.
- */
-
-.select{
-    width: 186px;
-}
-.select .optionMore{
-    background-color: #bfbaba;
-    height: 1.6em;
-    font-size: 1.2em;
-    cursor: pointer;
-    text-align: center;
-}
-.hideFilter{ display: none;}
-h4{
-    color: #666;
-}
-.colorRed{color: red;}
-.colorRed a{text-decoration: underline;color: #007CBB;}
-
-label:first-child {
-    font-size: 15px;
-    left: -10px !important;
-}
-.inputWidth{width: 310px;}
-.endpointSelect{ width: 290px; margin-right: 34px;}
-.filterSelect{width: 350px;}
-.filterSelect clr-icon{margin-left: 10px;}
-.filterSelect label{width: 175px;}
-.filterSelect label input{width: 100%;}
-.cursor{cursor: pointer;}
-.pull-left{float: left;}
-.padLeft0{padding-left: 0;}
-.floatSet {display: inline-block; width: 120px;margin-right: 10px;}
-.form-group{ min-height: 36px;}
-
-.projectInput{float: left;}
-.projectInput input{background-color: white;}
-.switchIcon{width:20px;height:20px; margin-top: 10px;margin-left: 10px; cursor: pointer;}
-.addEndpoint{  margin-top: .25em !important;}
-.shadow{position: absolute;top: 8px;}
-.is-solid{cursor: pointer;}
\ No newline at end of file
diff --git a/src/ui_ng/src/app/replication/replication-rule/replication-rule.html b/src/ui_ng/src/app/replication/replication-rule/replication-rule.html
deleted file mode 100644
index b8a1b2bd6..000000000
--- a/src/ui_ng/src/app/replication/replication-rule/replication-rule.html
+++ /dev/null
@@ -1,128 +0,0 @@
-<div>
- <a class="cursor" *ngIf="!projectId" (click)="backReplication()">< {{'SIDE_NAV.SYSTEM_MGMT.REPLICATION' | translate}}</a>
- <a class="cursor" *ngIf="projectId" (click)="backProjectReplication()"><{{'SIDE_NAV.PROJECTS' | translate}} &nbsp; {{'SIDE_NAV.SYSTEM_MGMT.REPLICATION' | translate | lowercase}}</a>
- <h1 class="sub-header-title">{{headerTitle | translate}}</h1>
-<form [formGroup]="ruleForm"  novalidate>
- <section class="form-block">
-  <div class="form-group">
-   <label class="col-md-4 form-group-label-override">{{'REPLICATION.NAME' | translate}}<span class="colorRed">*</span></label>
-   <label class="col-md-8"  aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left"
-          [class.invalid]='(ruleForm.controls.name.touched && ruleForm.controls.name.invalid) || isRuleNameExist'>
-    <input type="text" id="ruleName" class="inputWidth" required maxlength="255" formControlName="name" #ruleName (keyup)='checkRuleName()' autocomplete="off">
-    <span class="tooltip-content">{{ruleNameTooltip | translate}}</span>
-   </label><span class="spinner spinner-inline spinner-pos" [hidden]="!inNameChecking"></span>
-  </div>
-  <!--Description-->
-  <div class="form-group">
-   <label class="col-md-4 form-group-label-override">{{'REPLICATION.DESCRIPTION' | translate}}</label>
-   <textarea type="text" id="ruleDescription" class="inputWidth" row= 3; formControlName="description"></textarea>
-  </div>
-  <!--Projects-->
-  <div class="form-group">
-   <label class="col-md-4 form-group-label-override">{{'REPLICATION.SOURCE' | translate}}&nbsp;{{'PROJECT.PROJECTS' | translate | lowercase}}<span class="colorRed">*</span></label>
-   <div formArrayName="projects" [style.visibility]="noSelectedProject?'hidden':'visible'">
-    <div class="projectInput" *ngFor="let project of projects.controls; let i= index" [formGroupName]="i">
-     <input formControlName="name" type="text" class="inputWidth" disabled  value="name">
-    </div>
-   </div>
-   <clr-icon *ngIf="!(noProjectInfo.length !=0 || projectId)" shape="search" class="is-solid switchIcon" (click)="openProjectModel()"></clr-icon>
-   <label *ngIf="noProjectInfo.length != 0" class="colorRed">{{noProjectInfo | translate}}</label>
-   <div class="shadow" [hidden]="!noSelectedProject || noProjectInfo.length != 0"><input  type="text" class="inputWidth" disabled ></div>
-  </div>
-
-<!--images/Filter-->
-  <div class="form-group">
-   <label class="col-md-4 form-group-label-override">{{'REPLICATION.SOURCE_IMAGES_FILTER' | translate}}</label>
-   <div formArrayName="filters">
-    <div class="filterSelect" *ngFor="let filter of filters.controls; let i=index"  [formGroupName]="i">
-     <div>
-      <div class="select floatSet">
-       <select formControlName="kind" (change)="filterChange($event)"  id="{{i}}" name="{{filterListData[i]?.name}}">
-        <option *ngFor="let filter of filterListData[i]?.options;" value="{{filter}}">{{filter}}</option>
-       </select>
-      </div>
-      <label aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left"
-             [class.invalid]='ruleForm.controls.filters.controls[i].controls.pattern.touched && ruleForm.controls.filters.controls[i].controls.pattern.invalid'>
-       <input type="text" #filterValue required size="14" formControlName="pattern">
-       <span class="tooltip-content">{{'TOOLTIP.EMPTY' | translate}}</span>
-      </label>
-      <clr-icon shape="times-circle" class="is-solid"  (click)="deleteFilter(i)"></clr-icon>
-     </div>
-    </div>
-   </div>
-    <clr-icon shape="plus-circle" class="is-solid" [hidden]="isFilterHide" (click)="addNewFilter()" style="margin-top: 11px;"></clr-icon>
-  </div>
-  <!--Targets-->
-  <div class="form-group">
-   <label class="col-md-4 form-group-label-override">{{'DESTINATION.ENDPOINT' | translate}} <span class="colorRed">*</span></label>
-   <div formArrayName="targets">
-    <div class="select endpointSelect pull-left" *ngFor="let target of targets.controls; let i= index" [formGroupName]="i">
-      <select id="ruleTarget " class="inputWidth" (change)="targetChange($event)"  formControlName="id">
-       <option *ngFor="let target of targetList" value="{{target.id}}">{{target.name}}-{{target.endpoint}}</option>
-      </select>
-     </div>
-    <button class="btn btn-info btn-sm addEndpoint" (click)="openModal()"><clr-icon shape="plus"></clr-icon>&nbsp;{{'REPLICATION.NEW' | translate}}</button>
-   </div>
-   </div>
-
-  <!--Trigger-->
-  <div class="form-group">
-   <label class="col-md-4 form-group-label-override">{{'REPLICATION.TRIGGER_MODE' | translate}}</label>
-   <div  formGroupName="trigger">
-    <!--on trigger-->
-    <div class="select floatSet">
-     <select id="ruleTrigger" formControlName="kind"  (change)="selectTrigger($event)">
-      <option value="Manual">{{'REPLICATION.MANUAL' | translate}}</option>
-      <option value="Immediate">{{'REPLICATION.IMMEDIATE' | translate}}</option>
-      <option value="Scheduled">{{'REPLICATION.SCHEDULE' | translate}}</option>
-     </select>
-    </div>
-    <!--on push-->
-    <div formGroupName="schedule_param">
-      <div class="select floatSet" [hidden]="!isScheduleOpt">
-       <select name="scheduleType" formControlName="type" (change)="selectSchedule($event)">
-        <option value="Daily">{{'REPLICATION.DAILY' | translate}}</option>
-        <option value="Weekly">{{'REPLICATION.WEEKLY' | translate}}</option>
-       </select>
-      </div>
-      <!--weekly-->
-      <span [hidden]="!weeklySchedule || !isScheduleOpt">on &nbsp;&nbsp;</span>
-      <div  [hidden]="!weeklySchedule || !isScheduleOpt" class="select floatSet">
-       <select name="scheduleDay" formControlName="weekday">
-        <option value="1">{{'WEEKLY.MONDAY' | translate}}</option>
-        <option value="2">{{'WEEKLY.TUESDAY' | translate}}</option>
-        <option value="3">{{'WEEKLY.WEDNESDAY' | translate}}</option>
-        <option value="4">{{'WEEKLY.THURSDAY' | translate}}</option>
-        <option value="5">{{'WEEKLY.FRIDAY' | translate}}</option>
-        <option value="6">{{'WEEKLY.SATURDAY' | translate}}</option>
-        <option value="7">{{'WEEKLY.SUNDAY' | translate}}</option>
-       </select>
-      </div>
-      <!--daily/time-->
-      <span [hidden]="!isScheduleOpt">at &nbsp;&nbsp;</span>
-      <input [hidden]="!isScheduleOpt" type="time" formControlName="offtime"  required value="08:00" />
-    </div>
-   </div>
-   <div style="width: 100%;" [hidden]="!isImmediate">
-    <clr-checkbox [clrChecked]="false" id="ruleDeletion" formControlName="replicate_deletion">
-     {{'REPLICATION.DELETE_REMOTE_IMAGES' | translate}}
-    </clr-checkbox>
-   </div>
-   <div  style="width: 100%;" >
-    <clr-checkbox [clrChecked]="true" id="ruleExit" formControlName="replicate_existing_image_now">
-     {{'REPLICATION.REPLICATE_IMMEDIATE' | translate}}
-    </clr-checkbox>
-   </div>
-  </div>
-
-  <div>
-   <span class="spinner spinner-inline" [hidden]="inProgress === false"></span>
-   <br>
-   <button type="submit" id="ruleBtnOk" class="btn btn-primary"  (click)="onSubmit()" [disabled]="!ruleForm.valid || !isVaild || !hasFormChange()">{{ 'BUTTON.SAVE' | translate }}</button>
-   <button type="button" id="ruleBtnCancel" class="btn btn-outline" [disabled]="this.inProgress || this.isSubmitOver" (click)="onCancel()">{{ 'BUTTON.CANCEL' | translate }}</button>
-  </div><!-- [disabled]="!ruleForm.valid"-->
- </section>
-</form>
- <list-project-model (selectedPro)="selectedProject($event)"></list-project-model>
- <hbr-create-edit-endpoint  (reload)="reload($event)"></hbr-create-edit-endpoint>
-</div>
\ No newline at end of file
diff --git a/src/ui_ng/src/app/replication/replication-rule/replication-rule.service.ts b/src/ui_ng/src/app/replication/replication-rule/replication-rule.service.ts
deleted file mode 100644
index fbe5a1c4c..000000000
--- a/src/ui_ng/src/app/replication/replication-rule/replication-rule.service.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * Created by pengf on 12/5/2017.
- */
-
-import {Injectable} from "@angular/core";
-import {Http, RequestOptions, Headers, URLSearchParams} from "@angular/http";
-import {Observable} from "rxjs/Observable";
-import {ReplicationRule, Target} from "./replication-rule";
-import {HTTP_GET_OPTIONS, HTTP_JSON_OPTIONS} from "../../shared/shared.utils";
-import {Project} from "../../project/project";
-
-@Injectable()
-export class ReplicationRuleServie {
-    headers = new Headers({'Content-type': 'application/json'});
-    options = new RequestOptions({'headers': this.headers});
-    baseurl =  '/api/policies/replication';
-    targetUrl= '/api/targets';
-
-    constructor(private http: Http) {}
-
-    public createReplicationRule(replicationRule: ReplicationRule): Observable<any> | Promise<any> | any {
-        /*if (!this._isValidRule(replicationRule)) {
-            return Promise.reject('Bad argument');
-        }*/
-
-        return this.http.post(this.baseurl, JSON.stringify(replicationRule), this.options).toPromise()
-            .then(response => response)
-            .catch(error => Promise.reject(error));
-    }
-
-    public getReplicationRules(projectId?: number | string, ruleName?: string): Promise<ReplicationRule[]> | ReplicationRule[] {
-        let queryParams = new URLSearchParams();
-        if (projectId) {
-            queryParams.set('project_id', '' + projectId);
-        }
-
-        if (ruleName) {
-            queryParams.set('name', ruleName);
-        }
-
-        return this.http.get(this.baseurl, {search: queryParams}).toPromise()
-            .then(response => response.json() as ReplicationRule[])
-            .catch(error => Promise.reject(error));
-    }
-
-    public getReplicationRule(policyId: number): Promise<ReplicationRule> {
-        let url: string = `${this.baseurl}/${policyId}`;
-        return this.http.get(url, HTTP_GET_OPTIONS).toPromise()
-            .then(response => response.json() as ReplicationRule)
-            .catch(error => Promise.reject(error));
-    }
-
-
-    public getEndpoints(): Promise<Target[]> | Target[] {
-        return this.http
-            .get(this.targetUrl)
-            .toPromise()
-            .then(response => response.json())
-            .catch(error => Promise.reject(error));
-    }
-
-    public listProjects(): Promise<Project[]> | Project[] {
-        return this.http.get(`/api/projects`, HTTP_GET_OPTIONS).toPromise()
-            .then(response => response.json())
-            .catch(error => Promise.reject(error));
-    }
-
-    public updateReplicationRule(id: number, rep: {[key: string]: any | any[] }): Observable<any> | Promise<any> | any {
-        let url: string = `${this.baseurl}/${id}`;
-        return this.http.put(url, JSON.stringify(rep), HTTP_JSON_OPTIONS).toPromise()
-            .then(response => response)
-            .catch(error => Promise.reject(error));
-    }
-
-}
diff --git a/src/ui_ng/src/app/replication/replication-rule/replication-rule.ts b/src/ui_ng/src/app/replication/replication-rule/replication-rule.ts
deleted file mode 100644
index bd320c9fa..000000000
--- a/src/ui_ng/src/app/replication/replication-rule/replication-rule.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import {Project} from "../../project/project";
-/**
- * Created by pengf on 12/7/2017.
- */
-
-export class Target {
-    id: number;
-    endpoint: string;
-    name: string;
-    username: string;
-    password: string;
-    type: number;
-    insecure: true;
-    creation_time: string;
-    update_time: string;
-    constructor() {
-        this.id = -1;
-        this.endpoint = "";
-        this.name = "";
-        this.username = "";
-        this.password = "";
-        this.type = 0;
-        this.insecure = true;
-        this.creation_time = "";
-        this.update_time = "";
-    }
-}
-
-export class Filter {
-    kind: string;
-    pattern: string;
-    constructor(kind: string, pattern: string) {
-        this.kind = kind;
-        this.pattern = pattern;
-    }
-}
-
-export class Trigger {
-    kind: string;
-    schedule_param: any | {
-        [key: string]: any | any[];
-    };
-    constructor(kind: string, param: any | { [key: string]: any | any[]; }) {
-        this.kind = kind;
-        this.schedule_param = param;
-    }
-}
-
-export interface ReplicationRule  {
-    id?: number;
-    name: string;
-    description: string;
-    projects: Project[];
-    targets: Target[] ;
-    trigger: Trigger ;
-    filters: Filter[] ;
-    replicate_existing_image_now?: boolean;
-    replicate_deletion?: boolean;
-}
-
diff --git a/src/ui_ng/src/app/replication/replication.module.ts b/src/ui_ng/src/app/replication/replication.module.ts
index 06cfca749..b8ca09742 100644
--- a/src/ui_ng/src/app/replication/replication.module.ts
+++ b/src/ui_ng/src/app/replication/replication.module.ts
@@ -20,10 +20,7 @@ import { TotalReplicationPageComponent } from './total-replication/total-replica
 import { DestinationPageComponent } from './destination/destination-page.component';
 
 import { SharedModule } from '../shared/shared.module';
-import {ReplicationRuleComponent} from "./replication-rule/replication-rule.component";
 import {ReactiveFormsModule} from "@angular/forms";
-import {ReplicationRuleServie} from "./replication-rule/replication-rule.service";
-import {ListProjectModelComponent} from "./replication-rule/list-project-model/list-project-model.component";
 
 @NgModule({
   imports: [
@@ -36,15 +33,11 @@ import {ListProjectModelComponent} from "./replication-rule/list-project-model/l
     ReplicationManagementComponent,
     TotalReplicationPageComponent,
     DestinationPageComponent,
-    ReplicationRuleComponent,
-    ListProjectModelComponent,
   ],
   exports: [
     ReplicationPageComponent,
     DestinationPageComponent,
     TotalReplicationPageComponent,
-    ReplicationRuleComponent,
-  ],
-  providers: [ReplicationRuleServie]
+  ]
 })
 export class ReplicationModule { }
\ No newline at end of file
diff --git a/src/ui_ng/src/app/replication/total-replication/total-replication-page.component.html b/src/ui_ng/src/app/replication/total-replication/total-replication-page.component.html
index c4ef6f6e5..799257e08 100644
--- a/src/ui_ng/src/app/replication/total-replication/total-replication-page.component.html
+++ b/src/ui_ng/src/app/replication/total-replication/total-replication-page.component.html
@@ -1,4 +1,4 @@
 <h2 class="custom-h2">{{'SIDE_NAV.SYSTEM_MGMT.REPLICATION' | translate}}</h2>
 <div style="margin-top: 24px;">
-    <hbr-replication [readonly]="false" [withReplicationJob]='true' [isSystemAdmin]="isSystemAdmin" (openCreateRule)="openCreatePage()"  (openEdit)="openEditPage($event)" (redirect)="customRedirect($event)"></hbr-replication>
+    <hbr-replication [withReplicationJob]='true' [isSystemAdmin]="isSystemAdmin" (goToRegistry)="goRegistry()" (redirect)="customRedirect($event)"></hbr-replication>
 </div>
\ No newline at end of file
diff --git a/src/ui_ng/src/app/replication/total-replication/total-replication-page.component.ts b/src/ui_ng/src/app/replication/total-replication/total-replication-page.component.ts
index c9e951046..2d38707a7 100644
--- a/src/ui_ng/src/app/replication/total-replication/total-replication-page.component.ts
+++ b/src/ui_ng/src/app/replication/total-replication/total-replication-page.component.ts
@@ -13,9 +13,10 @@
 // limitations under the License.
 import { Component } from '@angular/core';
 
-import {Router,ActivatedRoute} from "@angular/router";
-import {ReplicationRule} from "../replication-rule/replication-rule";
+import {Router, ActivatedRoute} from "@angular/router";
+
 import {SessionService} from "../../shared/session.service";
+import {ReplicationRule} from "harbor-ui";
 
 @Component({
   selector: 'total-replication',
@@ -31,17 +32,12 @@ export class TotalReplicationPageComponent {
       this.router.navigate(['../projects', rule.projects[0].project_id, 'replications'],  { relativeTo: this.activeRoute });
     }
   }
+  goRegistry(): void {
+    this.router.navigate(['../registries'],  { relativeTo: this.activeRoute });
+  }
 
   public get isSystemAdmin(): boolean {
     let account = this.session.getCurrentUser();
     return account != null && account.has_admin_role > 0;
   }
-
-  openEditPage(id: number): void {
-      this.router.navigate([id, 'rule'],  { relativeTo: this.activeRoute });
-  }
-
-  openCreatePage(): void {
-    this.router.navigate(['new-rule'],  { relativeTo: this.activeRoute });
-  }
 }
diff --git a/src/ui_ng/src/app/shared/new-user-form/new-user-form.component.html b/src/ui_ng/src/app/shared/new-user-form/new-user-form.component.html
index b6a469e64..03f462614 100644
--- a/src/ui_ng/src/app/shared/new-user-form/new-user-form.component.html
+++ b/src/ui_ng/src/app/shared/new-user-form/new-user-form.component.html
@@ -32,7 +32,7 @@
             <div class="form-group form-group-override">
                 <label for="realname" class="required form-group-label-override">{{'PROFILE.FULL_NAME' | translate}}</label>
                 <label for="realname" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left" [class.invalid]='getValidationState("realname")'>
-                      <input type="text" name="realname" #fullNameInput="ngModel" [(ngModel)]="newUser.realname" required maxLengthExt="20" id="realname" size="30"
+                      <input type="text" name="realname" #fullNameInput="ngModel" [(ngModel)]="newUser.realname" required maxLengthExt="80" id="realname" size="30"
                       (input)='handleValidation("realname", false)' 
                 (blur)='handleValidation("realname", true)'>
                       <span class="tooltip-content">
diff --git a/src/ui_ng/src/app/shared/route/leaving-new-rule-deactivate.service.ts b/src/ui_ng/src/app/shared/route/leaving-new-rule-deactivate.service.ts
deleted file mode 100644
index 60ea8de74..000000000
--- a/src/ui_ng/src/app/shared/route/leaving-new-rule-deactivate.service.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-import { Injectable } from '@angular/core';
-import {
-  CanDeactivate, Router,
-  ActivatedRouteSnapshot,
-  RouterStateSnapshot
-} from '@angular/router';
-
-import { ConfirmationDialogService } from '../confirmation-dialog/confirmation-dialog.service';
-
-import { ConfigurationComponent } from '../../config/config.component';
-import { ConfirmationMessage } from '../confirmation-dialog/confirmation-message';
-import { ConfirmationState, ConfirmationTargets } from '../shared.const';
-import {ReplicationRuleComponent} from "../../replication/replication-rule/replication-rule.component";
-
-@Injectable()
-export class LeavingNewRuleRouteDeactivate implements CanDeactivate<ReplicationRuleComponent> {
-  constructor(
-    private router: Router,
-    private confirmation: ConfirmationDialogService) { }
-
-  canDeactivate(
-    replicateRule: ReplicationRuleComponent,
-    route: ActivatedRouteSnapshot,
-    state: RouterStateSnapshot): Promise<boolean> | boolean {
-    //Confirmation before leaving config route
-    return new Promise((resolve, reject) => {
-      if (replicateRule && replicateRule.hasFormChange()) {
-        let msg: ConfirmationMessage = new ConfirmationMessage(
-          "CONFIG.LEAVING_CONFIRMATION_TITLE",
-          "CONFIG.LEAVING_CONFIRMATION_SUMMARY",
-          '',
-          {},
-          ConfirmationTargets.CONFIG_ROUTE
-        );
-        this.confirmation.openComfirmDialog(msg);
-        return this.confirmation.confirmationConfirm$.subscribe(msg => {
-          if (msg && msg.source === ConfirmationTargets.CONFIG_ROUTE) {
-            if (msg.state === ConfirmationState.CONFIRMED) {
-              return resolve(true);
-            } else {
-              return resolve(false);//Prevent leading route
-            }
-          } else {
-            return resolve(true);//Should go on
-          }
-        });
-      } else {
-        return resolve(true);
-      }
-    });
-  }
-}
diff --git a/src/ui_ng/src/app/shared/shared.module.ts b/src/ui_ng/src/app/shared/shared.module.ts
index 8d0e34a13..7de6142ae 100644
--- a/src/ui_ng/src/app/shared/shared.module.ts
+++ b/src/ui_ng/src/app/shared/shared.module.ts
@@ -58,7 +58,6 @@ import {
   ErrorHandler,
   HarborLibraryModule
 } from 'harbor-ui';
-import {LeavingNewRuleRouteDeactivate} from "./route/leaving-new-rule-deactivate.service";
 import { LeavingRepositoryRouteDeactivate } from './route/leaving-repository-deactivate.service';
 
 const uiLibConfig: IServiceConfig = {
@@ -125,7 +124,6 @@ const uiLibConfig: IServiceConfig = {
     AuthCheckGuard,
     SignInGuard,
     LeavingConfigRouteDeactivate,
-    LeavingNewRuleRouteDeactivate,
     LeavingRepositoryRouteDeactivate,
     MemberGuard,
     MessageHandlerService,
diff --git a/src/ui_ng/src/app/user/user.component.ts b/src/ui_ng/src/app/user/user.component.ts
index 48ca425d8..f44b888ae 100644
--- a/src/ui_ng/src/app/user/user.component.ts
+++ b/src/ui_ng/src/app/user/user.component.ts
@@ -167,6 +167,7 @@ export class UserComponent implements OnInit, OnDestroy {
 
   //Filter items by keywords
   doFilter(terms: string): void {
+    this.selectedRow = [];
     this.currentTerm = terms;
     this.originalUsers.then(users => {
       if (terms.trim() === "") {
diff --git a/src/ui_ng/src/i18n/lang/en-us-lang.json b/src/ui_ng/src/i18n/lang/en-us-lang.json
index 0d109d8f5..a8392613d 100644
--- a/src/ui_ng/src/i18n/lang/en-us-lang.json
+++ b/src/ui_ng/src/i18n/lang/en-us-lang.json
@@ -322,8 +322,8 @@
         "PLACEHOLDER": "We couldn't find any replication rules!",
         "JOB_PLACEHOLDER": "We couldn't find any replication jobs!",
         "JOB_LOG_VIEWER": "View Replication Job Log",
-        "NO_ENDPOINT_INFO": "Please go to registries and add an endpoint first",
-        "NO_PROJECT_INFO": "Please go to projects and add a project name first",
+        "NO_ENDPOINT_INFO": "Please add an endpoint first",
+        "NO_PROJECT_INFO": "Please add a project name first",
         "SOURCE_IMAGES_FILTER": "Source images filter",
         "SCHEDULE": "Scheduled",
         "MANUAL": "Manual",
diff --git a/src/ui_ng/src/i18n/lang/es-es-lang.json b/src/ui_ng/src/i18n/lang/es-es-lang.json
index 010f956c6..a7d8ea389 100644
--- a/src/ui_ng/src/i18n/lang/es-es-lang.json
+++ b/src/ui_ng/src/i18n/lang/es-es-lang.json
@@ -322,8 +322,8 @@
         "PLACEHOLDER": "We couldn't find any replication rules!",
         "JOB_PLACEHOLDER": "We couldn't find any replication jobs!",
         "JOB_LOG_VIEWER": "View Replication Job Log",
-        "NO_ENDPOINT_INFO": "Please go to registries and add an endpoint first",
-        "NO_PROJECT_INFO": "Please go to projects and add a project name first",
+        "NO_ENDPOINT_INFO": "Please add an endpoint first",
+        "NO_PROJECT_INFO": "Please add a project name first",
         "SOURCE_IMAGES_FILTER": "Source images filter",
         "SCHEDULE": "Scheduled",
         "MANUAL": "Manual",
diff --git a/src/ui_ng/src/i18n/lang/zh-cn-lang.json b/src/ui_ng/src/i18n/lang/zh-cn-lang.json
index 68e8a7b42..a9464381b 100644
--- a/src/ui_ng/src/i18n/lang/zh-cn-lang.json
+++ b/src/ui_ng/src/i18n/lang/zh-cn-lang.json
@@ -322,8 +322,8 @@
         "PLACEHOLDER": "未发现任何复制规则!",
         "JOB_PLACEHOLDER": "未发现任何复制任务!",
         "JOB_LOG_VIEWER": "查看复制任务日志",
-        "NO_ENDPOINT_INFO": "请先添加目标",
-        "NO_PROJECT_INFO": "请先去项目添加一个新的项目名称",
+        "NO_ENDPOINT_INFO": "请先添加一个目标",
+        "NO_PROJECT_INFO": "请先添加一个项目名称",
         "SOURCE_IMAGES_FILTER": "源镜像过滤器",
         "SCHEDULE": "定时",
         "MANUAL": "手动",