diff --git a/dashboard/src/app/components/config/config-importer/config-importer.component.html b/dashboard/src/app/components/config/config-importer/config-importer.component.html
new file mode 100644
index 00000000..1d433097
--- /dev/null
+++ b/dashboard/src/app/components/config/config-importer/config-importer.component.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click or drag ZIP-file to this area to upload
+
+
+
+
diff --git a/dashboard/src/app/components/config/config-importer/config-importer.component.scss b/dashboard/src/app/components/config/config-importer/config-importer.component.scss
new file mode 100644
index 00000000..d8eb4be1
--- /dev/null
+++ b/dashboard/src/app/components/config/config-importer/config-importer.component.scss
@@ -0,0 +1,5 @@
+nz-select {
+ margin: 0 8px 10px 0;
+ width: 160px;
+ text-align: center
+}
diff --git a/dashboard/src/app/components/config/config-importer/config-importer.component.spec.ts b/dashboard/src/app/components/config/config-importer/config-importer.component.spec.ts
new file mode 100644
index 00000000..3ddde167
--- /dev/null
+++ b/dashboard/src/app/components/config/config-importer/config-importer.component.spec.ts
@@ -0,0 +1,25 @@
+import {ComponentFixture, TestBed} from '@angular/core/testing';
+
+import {ConfigImporterComponent} from './config-importer.component';
+
+describe('ConfigImporterComponent', () => {
+ let component: ConfigImporterComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ConfigImporterComponent]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ConfigImporterComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/dashboard/src/app/components/config/config-importer/config-importer.component.ts b/dashboard/src/app/components/config/config-importer/config-importer.component.ts
new file mode 100644
index 00000000..22899677
--- /dev/null
+++ b/dashboard/src/app/components/config/config-importer/config-importer.component.ts
@@ -0,0 +1,49 @@
+import {Component, EventEmitter, OnInit, Output} from '@angular/core';
+import {ConfigClient, ImportPolicy} from '../../../api/config/ConfigClient';
+import {NzUploadChangeParam, NzUploadFile} from 'ng-zorro-antd/upload';
+import {NamespaceContext} from '../../../core/NamespaceContext';
+import {NzMessageService} from 'ng-zorro-antd/message';
+
+
+@Component({
+ selector: 'app-config-importer',
+ templateUrl: './config-importer.component.html',
+ styleUrls: ['./config-importer.component.scss']
+})
+export class ConfigImporterComponent implements OnInit {
+ @Output() afterImport: EventEmitter = new EventEmitter();
+ importPolicy: ImportPolicy = 'skip';
+
+ constructor(private namespaceContext: NamespaceContext,
+ private configClient: ConfigClient,
+ private messageService: NzMessageService) {
+ }
+
+ ngOnInit(): void {
+ }
+
+ getImportData = (file: NzUploadFile) => {
+ return {
+ policy: this.importPolicy
+ };
+ };
+
+ getImportUrl(): string {
+ return this.configClient.getImportUrl(this.namespaceContext.ensureCurrentNamespace());
+ }
+
+ handleChange({file, fileList}: NzUploadChangeParam): void {
+ const status = file.status;
+ if (status !== 'uploading') {
+ console.log(file, fileList);
+ }
+ if (status === 'done') {
+ this.afterImport.emit(true);
+ this.messageService.success(`${file.name} file uploaded successfully.`);
+ } else if (status === 'error') {
+ this.afterImport.emit(false);
+ this.messageService.error(`${file.name} file upload failed.`);
+ }
+ }
+
+}