Merge branch 'DEVELOP' of ssh://git.eclipse.org:29418/openk-usermodules/org.eclipse.openk-usermodules.contactBaseData.frontend into KON-103-Q-Umgebung-in-CI-aufnehmen
# Conflicts:
# package.json
diff --git a/.gitignore b/.gitignore
index 5d19d9b..a911331 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,3 +36,4 @@
/.scannerwork
/unittests
/coverage
+/config/env.json
diff --git a/angular.json b/angular.json
index 4b95ef6..51b699f 100644
--- a/angular.json
+++ b/angular.json
@@ -97,13 +97,14 @@
"styles": ["src/styles.scss"],
"codeCoverage": true,
"codeCoverageExclude": [
- "applications/*.ts",
+ "src/environments/**",
"e2e/*.ts",
"**/*.action.*",
"**/*.model.*",
"**/*.module.*",
"**/*column-definition*",
"**/*api-client.*",
+ "**/*.animation.*",
"**/lib/**/*",
"**/testing/**/*"
],
diff --git a/config/env.json b/config/env.json
deleted file mode 100644
index 787c328..0000000
--- a/config/env.json
+++ /dev/null
@@ -1 +0,0 @@
-{"env":"development"}
diff --git a/hooks/pre-build.js b/hooks/pre-build.js
index 9aa93c9..8cd3264 100644
--- a/hooks/pre-build.js
+++ b/hooks/pre-build.js
@@ -18,7 +18,11 @@
"./i18n/components.de.json",
"./i18n/contacts.de.json",
"./i18n/persons.de.json",
- "./i18n/salutations.de.json"
+ "./i18n/salutations.de.json",
+ "./i18n/company.de.json",
+ "./i18n/admin.de.json",
+ "./i18n/addresses.de.json",
+ "./i18n/communications-data.de.json"
];
function mergeAndSaveJsonFiles(src, dest) {
diff --git a/hooks/pre-start.js b/hooks/pre-start.js
index b69b91b..2530a4a 100644
--- a/hooks/pre-start.js
+++ b/hooks/pre-start.js
@@ -18,7 +18,11 @@
"./i18n/components.de.json",
"./i18n/contacts.de.json",
"./i18n/persons.de.json",
- "./i18n/salutations.de.json"
+ "./i18n/salutations.de.json",
+ "./i18n/company.de.json",
+ "./i18n/admin.de.json",
+ "./i18n/addresses.de.json",
+ "./i18n/communications-data.de.json"
];
function mergeAndSaveJsonFiles(src, dest) {
diff --git a/i18n/addresses.de.json b/i18n/addresses.de.json
new file mode 100644
index 0000000..1ada076
--- /dev/null
+++ b/i18n/addresses.de.json
@@ -0,0 +1,18 @@
+{
+ "Address": {
+ "AddressType": "Adresstyp",
+ "MainAddress": "Hauptadresse",
+ "Postcode": "Postleitzahl",
+ "Community": "Ort",
+ "CommunitySuffix": "Adresse (Zusatz)",
+ "Street": "Straße",
+ "Housenumber": "Hausnummer",
+ "Note": "Notiz",
+ "NewAddress": "Neue Adresse anlegen",
+ "EditAddress": "Adresse bearbeiten",
+ "Wgs84Zone": "WGS84-Zone",
+ "Longitude": "Längengrad",
+ "Latitude": "Breitengrad",
+ "UrlMap": "Google maps-URL"
+ }
+}
\ No newline at end of file
diff --git a/i18n/admin.de.json b/i18n/admin.de.json
new file mode 100644
index 0000000..b5bb4e7
--- /dev/null
+++ b/i18n/admin.de.json
@@ -0,0 +1,32 @@
+{
+ "Salutations": {
+ "Link": "Anreden verwalten",
+ "Title": "Übersicht Anrede",
+ "DetailsTitle": "Anrede Details",
+ "Type": "Typ",
+ "Description": "Beschreibung"
+ },
+ "CommunicationTypes": {
+ "Link": "Kommunikationstypen verwalten",
+ "Title": "Übersicht Kommunikationstypen",
+ "DetailsTitle": "Kommunikationstypen Details",
+ "Type": "Typ",
+ "Description": "Beschreibung",
+ "Editable": "Editierbar",
+ "MappingLdap": "LDAP Mapping"
+ },
+ "PersonTypes": {
+ "Link": "Personentypen verwalten",
+ "Title": "Übersicht Personentypen",
+ "DetailsTitle": "Personentypen Details",
+ "Type": "Typ",
+ "Description": "Beschreibung"
+ },
+ "AddressTypes": {
+ "Link": "Adresstypen verwalten",
+ "Title": "Übersicht Adresstypen",
+ "DetailsTitle": "Adresstypen Details",
+ "Type": "Typ",
+ "Description": "Beschreibung"
+ }
+}
diff --git a/i18n/communications-data.de.json b/i18n/communications-data.de.json
new file mode 100644
index 0000000..1778db4
--- /dev/null
+++ b/i18n/communications-data.de.json
@@ -0,0 +1,9 @@
+{
+ "CommunicationsData": {
+ "CommunicationType": "Typ",
+ "CommunicationData": "Daten",
+ "Note": "Notiz",
+ "NewCommunicationsData": "Neue Kommunikationsdaten anlegen",
+ "EditCommunicationsData": "Kommunikationsdaten bearbeiten"
+ }
+}
diff --git a/i18n/company.de.json b/i18n/company.de.json
new file mode 100644
index 0000000..e60da94
--- /dev/null
+++ b/i18n/company.de.json
@@ -0,0 +1,9 @@
+{
+ "Company": {
+ "Title": "Firma",
+ "Name": "Name",
+ "CompanyType": "Rechtsform",
+ "HrNumber": "Handelsregisternummer",
+ "Note": "Notiz"
+ }
+}
diff --git a/i18n/components.de.json b/i18n/components.de.json
index 2c37644..646666a 100644
--- a/i18n/components.de.json
+++ b/i18n/components.de.json
@@ -14,5 +14,12 @@
"OrCondition": "ODER",
"Equals": "ist gleich",
"NotEqual": "ist nicht gleich"
+ },
+
+ "Paginator": {
+ "Last": ">>",
+ "First": "<<",
+ "Next": ">",
+ "Previous": "<"
}
}
diff --git a/i18n/contacts.de.json b/i18n/contacts.de.json
index 4229d41..10a6755 100644
--- a/i18n/contacts.de.json
+++ b/i18n/contacts.de.json
@@ -2,12 +2,21 @@
"Contacts": {
"Title": "Übersicht Kontakte",
"Name": "Name",
+ "Mail": "E-Mail",
+ "FirstName": "Vorname",
+ "LastName": "Nachname",
"ContactType": "Kontakttyp",
"Note": "Notiz",
"MainAddress": "Hauptadresse",
- "CreateNewContact": "Neuer Kontakt anlegen",
- "InternContact": "Interner Kontakt",
- "ExternContact": "Externer Kontakt",
- "Company": "Unternehmen"
+ "Street": "Straße",
+ "Community": "Ort",
+ "CreateNewContact": "Neuen Kontakt anlegen",
+ "InternalContact": "Interner Kontakt",
+ "ExternalContact": "Externer Kontakt",
+ "Company": "Unternehmen",
+ "AddressList": "Adressliste",
+ "AllContactTypes": "Alle Kontakttypen",
+ "Department": "Abteilung",
+ "CommunicationsDataList": "Kommunikationskanäle"
}
}
diff --git a/i18n/general.de.json b/i18n/general.de.json
index dec2c0b..9b9b088 100644
--- a/i18n/general.de.json
+++ b/i18n/general.de.json
@@ -2,6 +2,7 @@
"ServerError401": "Zugriff nicht erlaubt.Bitte einloggen",
"ServerError403": "Zugriffe verweigert. Bitte geben Sie korrekte Daten an.",
"ServerError404": "Nicht gefunden. Bitte kontaktieren Sie den Administrator.",
+ "ServerError409": "Die Aktion kann nicht durchgeführt werden, weil eine Abhängigkeit zu einem anderen Datensatz existiert.",
"ServerError500": "Ein Fehler ist aufgetreten. Bitte kontaktieren Sie den Administrator.",
"SuccessNotificationTitle": "Erfolg",
"ErrorNotificationTitle": "Fehler",
@@ -9,12 +10,20 @@
"WarningNotificationTitle": "Warnung",
"SaveBtn": "Speichern",
"EditBtn": "Bearbeiten",
+ "NewBtn": "Neu",
"CancelBtn": "Abbrechen",
"BackBtn": "Zurück",
"GridEmptyLabel": "Keine Daten vorhanden!",
+ "Filtering": "Filterung",
+ "Sorting": "Sortierung",
+ "NoSorting": "Keine Sortierung",
+ "AscendingSorting": "Aufsteigend sortieren",
+ "DescendingSorting": "Absteigend sortieren",
+ "Column": "Spalte",
"MandatoryFieldsNotFilled": "Es ist mindestens ein Pflichtfeld nicht gefüllt.",
"SelectOption": "Bitte auswählen",
+
"ConfirmDialog": {
"Title": "Bitte bestätigen Sie",
"Content": "Möchten Sie das Formular ohne Speichern verlassen?",
diff --git a/i18n/persons.de.json b/i18n/persons.de.json
index 20a0879..c8b733b 100644
--- a/i18n/persons.de.json
+++ b/i18n/persons.de.json
@@ -19,5 +19,9 @@
"Uid": "LDAP User",
"Userref": "KeyCloak User",
"Department": "Abteilung"
+ },
+ "InternalError": {
+ "UniqueUid": "Es gibt bereits eine Interne Person mit der gleichen LDAP User-ID",
+ "UniqueUserref": "Es gibt bereits eine Interne Person mit der gleichen KeyCloak User-ID"
}
}
diff --git a/i18n/salutations.de.json b/i18n/salutations.de.json
deleted file mode 100644
index 07dee7d..0000000
--- a/i18n/salutations.de.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "Salutations": {
- "Title": "Übersicht Anrede",
- "DetailsTitle": "Anrede Details",
- "Type": "Typ",
- "Description": "Beschreibung"
- }
-}
diff --git a/karma.conf.js b/karma.conf.js
index 9156530..c52ff01 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -59,12 +59,16 @@
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['ChromeHeadlessNoSandbox'],
- customLaunchers: {
+ customLaunchers: {
ChromeHeadlessNoSandbox: {
base: 'ChromeHeadless',
- flags: ['--no-sandbox']
+ flags: ['--no-sandbox',
+ '--remote-debugging-port=9223',
+ '--remote-debugging-address=0.0.0.0'
+ ]
}
},
- singleRun: false
+ singleRun: false,
+ concurrency: Infinity
});
};
diff --git a/package-lock.json b/package-lock.json
index da730e9..f3ad92f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3303,11 +3303,6 @@
}
}
},
- "@swimlane/ngx-datatable": {
- "version": "15.0.2",
- "resolved": "https://registry.npmjs.org/@swimlane/ngx-datatable/-/ngx-datatable-15.0.2.tgz",
- "integrity": "sha512-IlUyCs/hLv12hzz2pGugbrdRpBbwE6JUM4Bm4CCqLptmZj+t8pw8Ywthde8yUDdpgGgTJeJ9G5o92QadyGbP3g=="
- },
"@types/events": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
@@ -3686,48 +3681,6 @@
"resolved": "https://registry.npmjs.org/angular2-notifications/-/angular2-notifications-2.0.0.tgz",
"integrity": "sha512-QfMpewj2M1FKKOcZdDTOBo8/TX5K0Ev5p1BdbKPVpzHY9WAKtQa496/FarpoApBN8uPw8og5cEV20IgLbK+b5Q=="
},
- "ansi-align": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
- "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=",
- "dev": true,
- "requires": {
- "string-width": "^2.0.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
- "dev": true
- },
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
- "dev": true
- },
- "string-width": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "dev": true,
- "requires": {
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^4.0.0"
- }
- },
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^3.0.0"
- }
- }
- }
- },
"ansi-colors": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
@@ -3837,12 +3790,6 @@
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
"dev": true
},
- "array-find-index": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
- "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
- "dev": true
- },
"array-flatten": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
@@ -4427,60 +4374,6 @@
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.4.1.tgz",
"integrity": "sha512-tbx5cHubwE6e2ZG7nqM3g/FZ5PQEDMWmMGNrCUBVRPHXTJaH7CBDdsLeu3eCh3B1tzAxTnAbtmrzvWEvT2NNEA=="
},
- "boxen": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
- "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==",
- "dev": true,
- "requires": {
- "ansi-align": "^2.0.0",
- "camelcase": "^4.0.0",
- "chalk": "^2.0.1",
- "cli-boxes": "^1.0.0",
- "string-width": "^2.0.0",
- "term-size": "^1.2.0",
- "widest-line": "^2.0.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
- "dev": true
- },
- "camelcase": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
- "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
- "dev": true
- },
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
- "dev": true
- },
- "string-width": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "dev": true,
- "requires": {
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^4.0.0"
- }
- },
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^3.0.0"
- }
- }
- }
- },
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -4759,22 +4652,6 @@
"integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
"dev": true
},
- "camelcase": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
- "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
- "dev": true
- },
- "camelcase-keys": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
- "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
- "dev": true,
- "requires": {
- "camelcase": "^2.0.0",
- "map-obj": "^1.0.0"
- }
- },
"caniuse-lite": {
"version": "1.0.30000989",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz",
@@ -4787,12 +4664,6 @@
"integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==",
"dev": true
},
- "capture-stack-trace": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
- "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==",
- "dev": true
- },
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
@@ -4847,12 +4718,6 @@
"tslib": "^1.9.0"
}
},
- "ci-info": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz",
- "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==",
- "dev": true
- },
"cipher-base": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
@@ -4914,12 +4779,6 @@
}
}
},
- "cli-boxes": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
- "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=",
- "dev": true
- },
"cli-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
@@ -5151,20 +5010,6 @@
"typedarray": "^0.0.6"
}
},
- "configstore": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz",
- "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==",
- "dev": true,
- "requires": {
- "dot-prop": "^4.1.0",
- "graceful-fs": "^4.1.2",
- "make-dir": "^1.0.0",
- "unique-string": "^1.0.0",
- "write-file-atomic": "^2.0.0",
- "xdg-basedir": "^3.0.0"
- }
- },
"connect": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
@@ -5427,15 +5272,6 @@
"elliptic": "^6.0.0"
}
},
- "create-error-class": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
- "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
- "dev": true,
- "requires": {
- "capture-stack-trace": "^1.0.0"
- }
- },
"create-hash": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
@@ -5495,12 +5331,6 @@
"randomfill": "^1.0.3"
}
},
- "crypto-random-string": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
- "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=",
- "dev": true
- },
"css-parse": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz",
@@ -5533,15 +5363,6 @@
"integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=",
"dev": true
},
- "currently-unhandled": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
- "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
- "dev": true,
- "requires": {
- "array-find-index": "^1.0.1"
- }
- },
"custom-event": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
@@ -5616,12 +5437,6 @@
"regexp.prototype.flags": "^1.2.0"
}
},
- "deep-extend": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
- "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
- "dev": true
- },
"default-gateway": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz",
@@ -5897,36 +5712,12 @@
"void-elements": "^2.0.0"
}
},
- "dom-urls": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/dom-urls/-/dom-urls-1.1.0.tgz",
- "integrity": "sha1-AB3fgWKM0ecGElxxdvU8zsVdkY4=",
- "dev": true,
- "requires": {
- "urijs": "^1.16.1"
- }
- },
"domain-browser": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
"integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
"dev": true
},
- "dot-prop": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
- "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==",
- "dev": true,
- "requires": {
- "is-obj": "^1.0.0"
- }
- },
- "duplexer3": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
- "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
- "dev": true
- },
"duplexify": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
@@ -6268,34 +6059,6 @@
"safe-buffer": "^5.1.1"
}
},
- "execa": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
- "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
- "dev": true,
- "requires": {
- "cross-spawn": "^5.0.1",
- "get-stream": "^3.0.0",
- "is-stream": "^1.1.0",
- "npm-run-path": "^2.0.0",
- "p-finally": "^1.0.0",
- "signal-exit": "^3.0.0",
- "strip-eof": "^1.0.0"
- },
- "dependencies": {
- "cross-spawn": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
- "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
- "dev": true,
- "requires": {
- "lru-cache": "^4.0.1",
- "shebang-command": "^1.2.0",
- "which": "^1.2.9"
- }
- }
- }
- },
"exit": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
@@ -6874,18 +6637,6 @@
"integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
"dev": true
},
- "get-stdin": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
- "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
- "dev": true
- },
- "get-stream": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
- "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
- "dev": true
- },
"get-value": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
@@ -6924,15 +6675,6 @@
"is-glob": "^4.0.1"
}
},
- "global-dirs": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
- "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
- "dev": true,
- "requires": {
- "ini": "^1.3.4"
- }
- },
"globals": {
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
@@ -6953,25 +6695,6 @@
"slash": "^1.0.0"
}
},
- "got": {
- "version": "6.7.1",
- "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
- "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
- "dev": true,
- "requires": {
- "create-error-class": "^3.0.0",
- "duplexer3": "^0.1.4",
- "get-stream": "^3.0.0",
- "is-redirect": "^1.0.0",
- "is-retry-allowed": "^1.0.0",
- "is-stream": "^1.0.0",
- "lowercase-keys": "^1.0.0",
- "safe-buffer": "^5.0.1",
- "timed-out": "^4.0.0",
- "unzip-response": "^2.0.1",
- "url-parse-lax": "^1.0.0"
- }
- },
"graceful-fs": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz",
@@ -7412,12 +7135,6 @@
"resolve-from": "^3.0.0"
}
},
- "import-lazy": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
- "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=",
- "dev": true
- },
"import-local": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
@@ -7434,15 +7151,6 @@
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
"dev": true
},
- "indent-string": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
- "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
- "dev": true,
- "requires": {
- "repeating": "^2.0.0"
- }
- },
"indexof": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
@@ -7679,15 +7387,6 @@
"integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
"dev": true
},
- "is-ci": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
- "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
- "dev": true,
- "requires": {
- "ci-info": "^1.5.0"
- }
- },
"is-data-descriptor": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
@@ -7775,45 +7474,12 @@
"is-extglob": "^2.1.1"
}
},
- "is-installed-globally": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
- "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=",
- "dev": true,
- "requires": {
- "global-dirs": "^0.1.0",
- "is-path-inside": "^1.0.0"
- },
- "dependencies": {
- "is-path-inside": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
- "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
- "dev": true,
- "requires": {
- "path-is-inside": "^1.0.1"
- }
- }
- }
- },
- "is-npm": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
- "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=",
- "dev": true
- },
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true
},
- "is-obj": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
- "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
- "dev": true
- },
"is-path-cwd": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
@@ -7859,12 +7525,6 @@
"integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
"dev": true
},
- "is-redirect": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
- "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=",
- "dev": true
- },
"is-regex": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
@@ -7874,12 +7534,6 @@
"has": "^1.0.1"
}
},
- "is-retry-allowed": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
- "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=",
- "dev": true
- },
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
@@ -7901,12 +7555,6 @@
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
"dev": true
},
- "is-utf8": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
- "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
- "dev": true
- },
"is-windows": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@@ -8525,15 +8173,6 @@
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
"dev": true
},
- "latest-version": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
- "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=",
- "dev": true,
- "requires": {
- "package-json": "^4.0.0"
- }
- },
"lcid": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
@@ -8614,36 +8253,6 @@
"immediate": "~3.0.5"
}
},
- "load-json-file": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
- "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "parse-json": "^2.2.0",
- "pify": "^2.0.0",
- "pinkie-promise": "^2.0.0",
- "strip-bom": "^2.0.0"
- },
- "dependencies": {
- "parse-json": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
- "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
- "dev": true,
- "requires": {
- "error-ex": "^1.2.0"
- }
- },
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
- "dev": true
- }
- }
- },
"loader-runner": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz",
@@ -8677,43 +8286,12 @@
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
},
- "lodash._reinterpolate": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
- "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=",
- "dev": true
- },
"lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
"integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
"dev": true
},
- "lodash.defaults": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
- "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=",
- "dev": true
- },
- "lodash.template": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
- "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==",
- "dev": true,
- "requires": {
- "lodash._reinterpolate": "^3.0.0",
- "lodash.templatesettings": "^4.0.0"
- }
- },
- "lodash.templatesettings": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz",
- "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==",
- "dev": true,
- "requires": {
- "lodash._reinterpolate": "^3.0.0"
- }
- },
"log4js": {
"version": "4.5.1",
"resolved": "https://registry.npmjs.org/log4js/-/log4js-4.5.1.tgz",
@@ -8759,22 +8337,6 @@
"js-tokens": "^3.0.0 || ^4.0.0"
}
},
- "loud-rejection": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
- "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
- "dev": true,
- "requires": {
- "currently-unhandled": "^0.4.1",
- "signal-exit": "^3.0.0"
- }
- },
- "lowercase-keys": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
- "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
- "dev": true
- },
"lru-cache": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
@@ -8794,15 +8356,6 @@
"sourcemap-codec": "^1.4.4"
}
},
- "make-dir": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
- "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
- "dev": true,
- "requires": {
- "pify": "^3.0.0"
- }
- },
"make-error": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz",
@@ -8866,12 +8419,6 @@
"integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
"dev": true
},
- "map-obj": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
- "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
- "dev": true
- },
"map-visit": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
@@ -8919,24 +8466,6 @@
"readable-stream": "^2.0.1"
}
},
- "meow": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
- "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
- "dev": true,
- "requires": {
- "camelcase-keys": "^2.0.0",
- "decamelize": "^1.1.2",
- "loud-rejection": "^1.0.0",
- "map-obj": "^1.0.1",
- "minimist": "^1.1.3",
- "normalize-package-data": "^2.3.4",
- "object-assign": "^4.0.1",
- "read-pkg-up": "^1.0.1",
- "redent": "^1.0.0",
- "trim-newlines": "^1.0.0"
- }
- },
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
@@ -9304,11 +8833,6 @@
"integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
"dev": true
},
- "ng2-popover": {
- "version": "0.0.14",
- "resolved": "https://registry.npmjs.org/ng2-popover/-/ng2-popover-0.0.14.tgz",
- "integrity": "sha1-bK1qZVX9K4F1nz2FtMuMPjcx8pY="
- },
"ngrx-forms": {
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/ngrx-forms/-/ngrx-forms-5.2.3.tgz",
@@ -12946,18 +12470,6 @@
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true
},
- "package-json": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz",
- "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=",
- "dev": true,
- "requires": {
- "got": "^6.7.1",
- "registry-auth-token": "^3.0.1",
- "registry-url": "^3.0.3",
- "semver": "^5.1.0"
- }
- },
"pacote": {
"version": "9.5.5",
"resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.5.tgz",
@@ -13375,12 +12887,6 @@
"integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
"dev": true
},
- "pretty-bytes": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz",
- "integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=",
- "dev": true
- },
"private": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
@@ -13851,18 +13357,6 @@
}
}
},
- "rc": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
- "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
- "dev": true,
- "requires": {
- "deep-extend": "^0.6.0",
- "ini": "~1.3.0",
- "minimist": "^1.2.0",
- "strip-json-comments": "~2.0.1"
- }
- },
"read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -13904,67 +13398,6 @@
"util-promisify": "^2.1.0"
}
},
- "read-pkg": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
- "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
- "dev": true,
- "requires": {
- "load-json-file": "^1.0.0",
- "normalize-package-data": "^2.3.2",
- "path-type": "^1.0.0"
- },
- "dependencies": {
- "path-type": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
- "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "pify": "^2.0.0",
- "pinkie-promise": "^2.0.0"
- }
- },
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
- "dev": true
- }
- }
- },
- "read-pkg-up": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
- "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
- "dev": true,
- "requires": {
- "find-up": "^1.0.0",
- "read-pkg": "^1.0.0"
- },
- "dependencies": {
- "find-up": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
- "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
- "dev": true,
- "requires": {
- "path-exists": "^2.0.0",
- "pinkie-promise": "^2.0.0"
- }
- },
- "path-exists": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
- "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
- "dev": true,
- "requires": {
- "pinkie-promise": "^2.0.0"
- }
- }
- }
- },
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
@@ -14001,16 +13434,6 @@
"picomatch": "^2.0.4"
}
},
- "redent": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
- "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
- "dev": true,
- "requires": {
- "indent-string": "^2.1.0",
- "strip-indent": "^1.0.1"
- }
- },
"reflect-metadata": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
@@ -14157,25 +13580,6 @@
"regjsparser": "^0.1.4"
}
},
- "registry-auth-token": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
- "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==",
- "dev": true,
- "requires": {
- "rc": "^1.1.6",
- "safe-buffer": "^5.0.1"
- }
- },
- "registry-url": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
- "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
- "dev": true,
- "requires": {
- "rc": "^1.0.1"
- }
- },
"regjsgen": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
@@ -14506,15 +13910,6 @@
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
"dev": true
},
- "semver-diff": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
- "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
- "dev": true,
- "requires": {
- "semver": "^5.0.3"
- }
- },
"semver-dsl": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz",
@@ -15417,36 +14812,12 @@
"ansi-regex": "^2.0.0"
}
},
- "strip-bom": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
- "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
- "dev": true,
- "requires": {
- "is-utf8": "^0.2.0"
- }
- },
"strip-eof": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
"dev": true
},
- "strip-indent": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
- "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
- "dev": true,
- "requires": {
- "get-stdin": "^4.0.1"
- }
- },
- "strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
- "dev": true
- },
"style-loader": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.0.0.tgz",
@@ -15528,24 +14899,6 @@
"has-flag": "^2.0.0"
}
},
- "sw-precache": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/sw-precache/-/sw-precache-5.2.1.tgz",
- "integrity": "sha512-8FAy+BP/FXE+ILfiVTt+GQJ6UEf4CVHD9OfhzH0JX+3zoy2uFk7Vn9EfXASOtVmmIVbL3jE/W8Z66VgPSZcMhw==",
- "dev": true,
- "requires": {
- "dom-urls": "^1.1.0",
- "es6-promise": "^4.0.5",
- "glob": "^7.1.1",
- "lodash.defaults": "^4.2.0",
- "lodash.template": "^4.4.0",
- "meow": "^3.7.0",
- "mkdirp": "^0.5.1",
- "pretty-bytes": "^4.0.2",
- "sw-toolbox": "^3.4.0",
- "update-notifier": "^2.3.0"
- }
- },
"sw-toolbox": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/sw-toolbox/-/sw-toolbox-3.6.0.tgz",
@@ -15608,15 +14961,6 @@
}
}
},
- "term-size": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
- "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=",
- "dev": true,
- "requires": {
- "execa": "^0.7.0"
- }
- },
"terser": {
"version": "4.3.9",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.3.9.tgz",
@@ -15710,12 +15054,6 @@
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
"dev": true
},
- "timed-out": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
- "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
- "dev": true
- },
"timers-browserify": {
"version": "2.0.11",
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz",
@@ -15823,23 +15161,12 @@
"integrity": "sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==",
"dev": true
},
- "trim-newlines": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
- "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
- "dev": true
- },
"trim-right": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
"integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
"dev": true
},
- "ts-helpers": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/ts-helpers/-/ts-helpers-1.1.2.tgz",
- "integrity": "sha1-/Gm+nx87rtAfsaDvjUz+dIgU2DU="
- },
"ts-node": {
"version": "8.5.4",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.5.4.tgz",
@@ -16076,15 +15403,6 @@
"imurmurhash": "^0.1.4"
}
},
- "unique-string": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
- "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
- "dev": true,
- "requires": {
- "crypto-random-string": "^1.0.0"
- }
- },
"universal-analytics": {
"version": "0.4.20",
"resolved": "https://registry.npmjs.org/universal-analytics/-/universal-analytics-0.4.20.tgz",
@@ -16165,36 +15483,12 @@
}
}
},
- "unzip-response": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
- "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=",
- "dev": true
- },
"upath": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
"integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
"dev": true
},
- "update-notifier": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz",
- "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==",
- "dev": true,
- "requires": {
- "boxen": "^1.2.1",
- "chalk": "^2.0.1",
- "configstore": "^3.0.0",
- "import-lazy": "^2.1.0",
- "is-ci": "^1.0.10",
- "is-installed-globally": "^0.1.0",
- "is-npm": "^1.0.0",
- "latest-version": "^3.0.0",
- "semver-diff": "^2.0.0",
- "xdg-basedir": "^3.0.0"
- }
- },
"uri-js": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
@@ -16204,12 +15498,6 @@
"punycode": "^2.1.0"
}
},
- "urijs": {
- "version": "1.19.1",
- "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.1.tgz",
- "integrity": "sha512-xVrGVi94ueCJNrBSTjWqjvtgvl3cyOTThp2zaMaFNGp3F542TR6sM3f2o8RqZl+AwteClSVmoCyt0ka4RjQOQg==",
- "dev": true
- },
"urix": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
@@ -16242,15 +15530,6 @@
"requires-port": "^1.0.0"
}
},
- "url-parse-lax": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
- "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
- "dev": true,
- "requires": {
- "prepend-http": "^1.0.1"
- }
- },
"use": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
@@ -18170,48 +17449,6 @@
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
"dev": true
},
- "widest-line": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz",
- "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==",
- "dev": true,
- "requires": {
- "string-width": "^2.1.1"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
- "dev": true
- },
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
- "dev": true
- },
- "string-width": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "dev": true,
- "requires": {
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^4.0.0"
- }
- },
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^3.0.0"
- }
- }
- }
- },
"wordwrap": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
@@ -18274,17 +17511,6 @@
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
},
- "write-file-atomic": {
- "version": "2.4.3",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
- "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.11",
- "imurmurhash": "^0.1.4",
- "signal-exit": "^3.0.2"
- }
- },
"ws": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
@@ -18296,12 +17522,6 @@
"ultron": "~1.1.0"
}
},
- "xdg-basedir": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
- "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=",
- "dev": true
- },
"xml2js": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
diff --git a/package.json b/package.json
index ff90b3d..ab103bc 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "openkonsequenz-contact-base-data-2019",
"version": "1.0.0",
- "description": "Contact Base Datad",
+ "description": "Contact Base Data",
"license": "MIT",
"author": "Martin Gardyan <martin.gardyan@pta.de>",
"angular-cli": {},
@@ -40,7 +40,6 @@
"@ngrx/store-devtools": "^8.6.0",
"@ngx-translate/core": "^11.0.1",
"@ngx-translate/http-loader": "^4.0.0",
- "@swimlane/ngx-datatable": "^15.0.2",
"ag-grid-angular": "^21.2.2",
"ag-grid-community": "^21.2.2",
"angular-font-awesome": "^3.1.2",
@@ -51,7 +50,6 @@
"font-awesome": "^4.7.0",
"jquery": "^3.4.1",
"moment": "^2.24.0",
- "ng2-popover": "0.0.14",
"ngrx-forms": "^5.2.3",
"npm": "^6.13.4",
"npm-install-peers": "^1.2.1",
@@ -59,7 +57,6 @@
"reselect": "^4.0.0",
"rxjs": "^6.5.4",
"rxjs-compat": "^6.5.4",
- "ts-helpers": "1.1.2",
"tslib": "^1.10.0",
"web-animations-js": "^2.3.2",
"zone.js": "^0.10.2"
@@ -83,7 +80,6 @@
"karma-junit-reporter": "1.2.0",
"protractor": "^5.1.1",
"puppeteer": "^2.0.0",
- "sw-precache": "^5.0.0",
"sw-toolbox": "^3.6.0",
"ts-node": "^8.5.4",
"tsconfig-paths": "^3.9.0",
diff --git a/sonar-project.properties b/sonar-project.properties
index 8576441..d679b49 100644
--- a/sonar-project.properties
+++ b/sonar-project.properties
@@ -9,7 +9,7 @@
sonar.sourceEncoding=UTF-8
sonar.sources=src
-sonar.exclusions=**/node_modules/**,**/*.spec.ts,**/test-data/*.ts,**/testing/*.ts,**/assets/js/*.js,**/*.model.*,**/*.action.*,**/*column-definition*,**/*.module.*,**/*column-definition*,**/*api-client.*,**/styles.scss
+sonar.exclusions=**/node_modules/**,src/environments/**,e2e/*.ts,**/*.spec.ts,**/test-data/*.ts,**/testing/*.ts,**/assets/js/*.js,**/*.model.*,**/*.action.*,**/*.module.*,**/*column-definition*,**/*animation*,**/*api-client.*,**/styles.scss
sonar.tests=src
sonar.test.inclusions=**/*.spec.ts
sonar.test.exclusions=
diff --git a/src/app/app-config.service.spec.ts b/src/app/app-config.service.spec.ts
new file mode 100644
index 0000000..ac720f5
--- /dev/null
+++ b/src/app/app-config.service.spec.ts
@@ -0,0 +1,34 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { ConfigService } from '@app/app-config.service';
+
+describe('ConfigService', () => {
+ let component: ConfigService;
+ let http: any;
+
+ beforeEach(async(() => {
+ http = {
+ } as any;
+
+ }));
+
+ beforeEach(() => {
+ component = new ConfigService(http);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+});
diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts
index 3adca07..782f063 100644
--- a/src/app/app.component.spec.ts
+++ b/src/app/app.component.spec.ts
@@ -49,11 +49,6 @@
expect(component).toBeTruthy();
}));
- it('ngOnInit works', () => {
- fakeRoute.params = new Observable();
- component.ngOnInit();
- });
-
it('should extract the user data from the JWT-AccessToken', async(() => {
const accessToken = 'eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJodVl0e' +
'VByUEVLQ1phY3FfMW5sOGZscENETnFHdmZEZHctYUxGQXNoWHZVIn0.eyJqdGkiOiI4ZmY5NTlhZC' +
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 024bd85..dfca123 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -10,7 +10,7 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { AdminModule } from './pages/admin/admin.module';
+import { AdminModule } from '@pages/admin/admin.module';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { HttpModule, Http } from '@angular/http';
// Angular core modules
@@ -21,23 +21,22 @@
import { CommonModule, APP_BASE_HREF, PlatformLocation } from '@angular/common';
// Routes
-import { AppRoutingModule } from './app-routing.module';
+import { AppRoutingModule } from '@app/app-routing.module';
// Modules
-import { AppComponent } from './app.component';
+import { AppComponent } from '@app/app.component';
import { HttpServiceModule } from '@shared/asyncServices/http/http.module';
import { UtilityModule } from '@shared/utility';
+import { AngularFontAwesomeModule } from 'angular-font-awesome'
//Feature Modules
import { ContactsModule } from '@pages/contacts/contacts.module';
import { PersonsModule } from '@pages/persons/persons.module';
+import { CompanyModule } from '@pages/company/company.module';
// Store
import { reducers } from '@shared/store';
-// Effects
-import { ContactsEffects } from '@shared/store/effects/contacts.effect';
-import { AngularFontAwesomeModule } from 'angular-font-awesome';
// Guards
import { AuthGuard } from '@shared/guards/auth.guard';
import { CanDeactivateGuard } from '@shared/guards/canDeactivate.guard';
@@ -54,7 +53,6 @@
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { environment } from 'environments/environment';
import { ContainersModule } from '@shared/containers';
-import { SalutationsEffects } from '@shared/store/effects/salutations.effect';
import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap';
/**
@@ -101,7 +99,7 @@
// App custom dependencies
HttpServiceModule.forRoot(),
UtilityModule.forRoot(),
- EffectsModule.forRoot([ContactsEffects, SalutationsEffects]),
+ EffectsModule.forRoot([]),
StoreModule.forRoot(reducers),
StoreDevtoolsModule.instrument({
maxAge: 25,
@@ -111,6 +109,7 @@
ContainersModule,
ContactsModule,
PersonsModule,
+ CompanyModule,
AdminModule,
AppRoutingModule,
NgbModalModule
diff --git a/src/app/pages/admin/address-types/address-types-api-client.ts b/src/app/pages/admin/address-types/address-types-api-client.ts
new file mode 100644
index 0000000..7c4aab3
--- /dev/null
+++ b/src/app/pages/admin/address-types/address-types-api-client.ts
@@ -0,0 +1,56 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { AddressTypesService } from '@pages/admin/address-types/address-types.service';
+import { Injectable } from '@angular/core';
+import { HttpService, GET, Adapter, DefaultHeaders, Path, PUT, Body, POST, DELETE } from '@shared/asyncServices/http';
+import { Observable } from 'rxjs';
+import { AddressType } from '@shared/models';
+
+@Injectable()
+@DefaultHeaders({
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json',
+})
+export class AddressTypesApiClient extends HttpService {
+
+ @GET('/addressTypes')
+ @Adapter(AddressTypesService.gridAdapter)
+ public getAddressTypes(): Observable<AddressType[]> {
+ return null;
+ }
+
+ @GET('/addressTypes/{id}')
+ @Adapter(AddressTypesService.itemAdapter)
+ public getAddressTypeDetails(@Path('id') id: string): Observable<AddressType> {
+ return null;
+ }
+
+ @PUT('/addressTypes/{id}')
+ @Adapter(AddressTypesService.itemAdapter)
+ public putAddressType(@Path('id') id: string, @Body() item: AddressType): Observable<AddressType> {
+ return null;
+ }
+
+ @POST('/addressTypes')
+ @Adapter(AddressTypesService.itemAdapter)
+ public postAddressType(@Body() newAddressType: AddressType): Observable<AddressType> {
+ return null;
+ }
+
+ @DELETE('/addressTypes/{id}')
+ @Adapter(AddressTypesService.itemAdapter)
+ public deleteAddressType(@Path('id') id: string): Observable<void> {
+ return null;
+ }
+
+}
diff --git a/src/app/pages/admin/address-types/address-types-details/address-types-details.component.html b/src/app/pages/admin/address-types/address-types-details/address-types-details.component.html
new file mode 100644
index 0000000..80ed815
--- /dev/null
+++ b/src/app/pages/admin/address-types/address-types-details/address-types-details.component.html
@@ -0,0 +1,63 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<form [ngrxFormState]="addressTypesSandbox.formState$ | async">
+ <h4>{{ 'AddressTypes.DetailsTitle' | translate }}</h4>
+ <div>
+ <!-- type -->
+ <div class="form-group row">
+ <label for="addressTypesTyp" class="col-sm-2 col-form-label">{{ 'AddressTypes.Type' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ required
+ maxlength="30"
+ class="form-control"
+ id="addressTypesTyp"
+ [ngrxFormControlState]="((addressTypesSandbox.formState$ | async)?.controls)['type']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- description -->
+ <div class="form-group row">
+ <label for="addressTypesDescription" class="col-sm-2 col-form-label">{{ 'AddressTypes.Description' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ required
+ maxlength="255"
+ class="form-control"
+ id="addressTypesDescription"
+ [ngrxFormControlState]="((addressTypesSandbox.formState$ | async)?.controls)['description']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- buttons -->
+ <button
+ type="button"
+ class="btn btn-primary btn-sm btn-success"
+ (click)="addressTypesSandbox.saveAddressType()"
+ >
+ {{ 'SaveBtn' | translate }}
+ </button>
+
+ <button
+ type="button"
+ class="btn btn-primary btn-sm"
+ (click)="addressTypesSandbox.cancel()"
+ >
+ {{ 'CancelBtn' | translate }}
+ </button>
+ </div>
+</form>
diff --git a/src/app/pages/admin/address-types/address-types-details/address-types-details.component.scss b/src/app/pages/admin/address-types/address-types-details/address-types-details.component.scss
new file mode 100644
index 0000000..c9eeb99
--- /dev/null
+++ b/src/app/pages/admin/address-types/address-types-details/address-types-details.component.scss
@@ -0,0 +1,18 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+button {
+ margin: 20px 10px 10px 0;
+}
+h4 {
+ padding-bottom: 15px;
+}
diff --git a/src/app/pages/admin/address-types/address-types-details/address-types-details.component.spec.ts b/src/app/pages/admin/address-types/address-types-details/address-types-details.component.spec.ts
new file mode 100644
index 0000000..1e70ab9
--- /dev/null
+++ b/src/app/pages/admin/address-types/address-types-details/address-types-details.component.spec.ts
@@ -0,0 +1,44 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { AddressTypesDetailsComponent } from '@pages/admin/address-types/address-types-details/address-types-details.component';
+import { AddressTypesSandbox } from '@pages/admin/address-types//address-types.sandbox';
+
+describe('AddressTypesDetailsComponent', () => {
+ let component: AddressTypesDetailsComponent;
+ let sandbox: AddressTypesSandbox;
+
+ beforeEach(() => {
+ sandbox = {
+ registerEvents() {},
+ endSubscriptions() {},
+ clear() {},
+ } as any;
+ component = new AddressTypesDetailsComponent(sandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should registerEvents OnInit', () => {
+ let spy = spyOn(sandbox,'registerEvents');
+ component.ngOnInit();
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should endSubscriptions OnDestroy', () => {
+ let spy = spyOn(sandbox,'endSubscriptions');
+ component.ngOnDestroy();
+ expect(spy).toHaveBeenCalled();
+ });
+});
diff --git a/src/app/pages/admin/address-types/address-types-details/address-types-details.component.ts b/src/app/pages/admin/address-types/address-types-details/address-types-details.component.ts
new file mode 100644
index 0000000..392d26a
--- /dev/null
+++ b/src/app/pages/admin/address-types/address-types-details/address-types-details.component.ts
@@ -0,0 +1,36 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { Component, OnInit, OnDestroy } from '@angular/core';
+import { AddressTypesSandbox } from '@pages/admin/address-types//address-types.sandbox';
+
+@Component({
+ selector: 'app-address-types-details',
+ templateUrl: './address-types-details.component.html',
+ styleUrls: ['./address-types-details.component.scss']
+})
+export class AddressTypesDetailsComponent implements OnInit, OnDestroy {
+
+ constructor(
+ public addressTypesSandbox: AddressTypesSandbox,
+ ) { }
+
+ ngOnInit() {
+ this.addressTypesSandbox.registerEvents();
+ }
+
+ ngOnDestroy() {
+ this.addressTypesSandbox.clear();
+ this.addressTypesSandbox.endSubscriptions();
+ }
+
+}
diff --git a/src/app/pages/admin/address-types/address-types-list/address-types-list-column-definition.ts b/src/app/pages/admin/address-types/address-types-list/address-types-list-column-definition.ts
new file mode 100644
index 0000000..0626998
--- /dev/null
+++ b/src/app/pages/admin/address-types/address-types-list/address-types-list-column-definition.ts
@@ -0,0 +1,41 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { IconCellRendererComponent } from '@shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component';
+
+export const ADDRESS_TYPES_COLDEF = [
+ {
+ field: 'type',
+ headerName: 'AddressTypes.Type',
+ sortable: true,
+ filter: 'setFilterComponent'
+ },
+ {
+ field: 'description',
+ headerName: 'AddressTypes.Description',
+ sortable: true,
+ filter: 'setFilterComponent'
+ },
+ {
+ field: 'tools',
+ headerName: ' ',
+ pinned: 'right',
+ maxWidth: 110,
+ minWidth: 110,
+ lockPosition: true,
+ sortable: false,
+ filter: false,
+ suppressMenu: true,
+ suppressSizeToFit: true,
+ cellRendererFramework: IconCellRendererComponent
+ }
+];
diff --git a/src/app/pages/admin/address-types/address-types-list/address-types-list.component.html b/src/app/pages/admin/address-types/address-types-list/address-types-list.component.html
new file mode 100644
index 0000000..2ae664e
--- /dev/null
+++ b/src/app/pages/admin/address-types/address-types-list/address-types-list.component.html
@@ -0,0 +1,41 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<app-card-layout>
+ <div header>
+ <span>{{ 'AddressTypes.Title' | translate }}</span>
+ <div class="pull-right">
+ <button class="btn btn-primary new-button" (click)="sandbox.setDisplayForm()">
+ {{ 'NewBtn' | translate }}
+ </button>
+ </div>
+ </div>
+ <div class="address-types-grid-wrapper" body>
+ <ag-grid-angular
+ autoresizecolumns
+ class="ag-theme-balham"
+ [ngClass]="sandbox.displayForm ? 'ag-grid-height-edit' : 'ag-grid-height-list'"
+ [class.ag-grid-height-list]="!sandbox.displayForm"
+ [gridOptions]="gridOptions"
+ [columnDefs]="columnDefinition"
+ [rowSelection]="'single'"
+ [frameworkComponents]="frameworkComponents"
+ [rowData]="sandbox.addressTypes$ | async"
+ >
+ </ag-grid-angular>
+ <div *ngIf="sandbox.displayForm" class="address-types-details">
+ <app-address-types-details></app-address-types-details>
+ </div>
+ </div>
+
+</app-card-layout>
+
diff --git a/src/app/pages/admin/address-types/address-types-list/address-types-list.component.scss b/src/app/pages/admin/address-types/address-types-list/address-types-list.component.scss
new file mode 100644
index 0000000..57d69f3
--- /dev/null
+++ b/src/app/pages/admin/address-types/address-types-list/address-types-list.component.scss
@@ -0,0 +1,31 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+.address-types-grid-wrapper {
+ position: relative;
+}
+
+.address-types-details {
+ margin-top: 20px;
+}
+
+.ag-grid-height-edit {
+ height: calc(100vh - 450px);
+}
+
+.ag-grid-height-list {
+ height: calc(100vh - 200px);
+}
+
+.new-button {
+ margin-right: 20px;
+}
diff --git a/src/app/pages/admin/address-types/address-types-list/address-types-list.component.spec.ts b/src/app/pages/admin/address-types/address-types-list/address-types-list.component.spec.ts
new file mode 100644
index 0000000..d11af58
--- /dev/null
+++ b/src/app/pages/admin/address-types/address-types-list/address-types-list.component.spec.ts
@@ -0,0 +1,54 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { AddressTypesListComponent } from '@pages/admin/address-types/address-types-list/address-types-list.component';
+import { AddressType } from '@shared/models';
+
+describe('AddressTypesListComponent', () => {
+ let component: AddressTypesListComponent;
+ const sandbox: any = {
+ setDisplayForm: () => {},
+ loadAddressType: () => {},
+ deleteAddressType: () => {},
+ };
+
+ beforeEach(() => {
+ component = new AddressTypesListComponent(sandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should initialize gridOptions context', () => {
+ component.ngOnInit();
+ expect(component.gridOptions.context.icons.edit).toBeTruthy();
+ expect(component.gridOptions.context.icons.delete).toBeTruthy();
+ });
+
+ it('should call appropriate functions for edit event', () => {
+ const spy1: any = spyOn(sandbox, 'setDisplayForm');
+ const spy2: any = spyOn(sandbox, 'loadAddressType');
+ component.ngOnInit();
+ component.gridOptions.context.eventSubject.next({type: "edit", data: new AddressType()});
+ expect(spy1).toHaveBeenCalled();
+ expect(spy2).toHaveBeenCalled();
+ });
+
+ it('should call appropriate functions for delete event', () => {
+ const spy3: any = spyOn(sandbox, 'deleteAddressType');
+ component.ngOnInit();
+ component.gridOptions.context.eventSubject.next({type: "delete", data: new AddressType()});
+ expect(spy3).toHaveBeenCalled();
+ });
+
+});
diff --git a/src/app/pages/admin/address-types/address-types-list/address-types-list.component.ts b/src/app/pages/admin/address-types/address-types-list/address-types-list.component.ts
new file mode 100644
index 0000000..10fb59e
--- /dev/null
+++ b/src/app/pages/admin/address-types/address-types-list/address-types-list.component.ts
@@ -0,0 +1,56 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { Component, OnInit } from '@angular/core';
+import { BaseList } from '@shared/components/base-components/base.list';
+import { ADDRESS_TYPES_COLDEF } from '@pages/admin/address-types/address-types-list/address-types-list-column-definition';
+import { SetFilterComponent } from '@shared/filters/ag-grid/set-filter/set-filter.component';
+import { AddressTypesSandbox } from '@pages/admin/address-types//address-types.sandbox';
+import { Subscription } from 'rxjs';
+
+@Component({
+ selector: 'app-address-types-list',
+ templateUrl: './address-types-list.component.html',
+ styleUrls: ['./address-types-list.component.scss']
+})
+export class AddressTypesListComponent extends BaseList implements OnInit {
+
+ public columnDefinition: any = ADDRESS_TYPES_COLDEF;
+ public frameworkComponents: { setFilterComponent: any };
+ private _subscription: Subscription;
+
+ constructor(public sandbox: AddressTypesSandbox) {
+ super();
+ this.frameworkComponents = { setFilterComponent: SetFilterComponent };
+ }
+
+ ngOnInit() {
+ this.gridOptions.context = {
+ ...this.gridOptions.context,
+ icons: { edit: true, delete: true }
+ };
+ this._subscription = this.gridOptions.context.eventSubject.subscribe(event => {
+ if (event.type === 'edit') {
+ this.sandbox.setDisplayForm();
+ this.sandbox.loadAddressType(event.data.id);
+ }
+ if (event.type === 'delete') {
+ this.sandbox.deleteAddressType(event.data.id);
+ }
+ });
+ }
+
+ ngOnDestroy() {
+ this._subscription.unsubscribe();
+ }
+
+}
diff --git a/src/app/pages/admin/address-types/address-types.resolver.spec.ts b/src/app/pages/admin/address-types/address-types.resolver.spec.ts
new file mode 100644
index 0000000..59a4545
--- /dev/null
+++ b/src/app/pages/admin/address-types/address-types.resolver.spec.ts
@@ -0,0 +1,41 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { AddressTypesResolver } from '@pages/admin/address-types/address-types.resolver';
+
+describe('AddressTypesResolver', () => {
+ let component: AddressTypesResolver;
+ let sandbox: any;
+
+ beforeEach(async(() => {
+ sandbox = {
+ clear() {},
+ loadAddressTypes() {},
+ } as any;
+ }));
+
+ beforeEach(() => {
+ component = new AddressTypesResolver(sandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call loadAddressTypes', () => {
+ const spy = spyOn(sandbox, 'loadAddressTypes');
+ component.resolve();
+ expect(spy).toHaveBeenCalled();
+ });
+
+});
diff --git a/src/app/pages/admin/address-types/address-types.resolver.ts b/src/app/pages/admin/address-types/address-types.resolver.ts
new file mode 100644
index 0000000..6d2fcfb
--- /dev/null
+++ b/src/app/pages/admin/address-types/address-types.resolver.ts
@@ -0,0 +1,27 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { AddressTypesSandbox } from '@pages/admin/address-types/address-types.sandbox';
+import { Observable } from 'rxjs';
+import { Injectable } from '@angular/core';
+import { Resolve } from '@angular/router';
+import { ILoadAddressTypesSuccess } from '@shared/store/actions/admin/address-types.action';
+
+@Injectable()
+export class AddressTypesResolver implements Resolve<any> {
+
+ constructor(private sandbox: AddressTypesSandbox) {}
+
+ public resolve(): Observable<ILoadAddressTypesSuccess> {
+ return this.sandbox.loadAddressTypes();
+ }
+}
diff --git a/src/app/pages/admin/address-types/address-types.sandbox.spec.ts b/src/app/pages/admin/address-types/address-types.sandbox.spec.ts
new file mode 100644
index 0000000..341f0b2
--- /dev/null
+++ b/src/app/pages/admin/address-types/address-types.sandbox.spec.ts
@@ -0,0 +1,96 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { AddressTypesSandbox } from '@pages/admin/address-types//address-types.sandbox';
+import { Store, ActionsSubject } from '@ngrx/store';
+import { State } from '@shared/store';
+import { UtilService } from '@shared/utility/utility.service';
+import { of } from 'rxjs';
+import { Router } from '@angular/router';
+import * as addressTypesActions from '@shared/store/actions/admin/address-types.action';
+import { AddressType } from '@shared/models';
+
+describe('AddressTypesSandbox', () => {
+ let service: AddressTypesSandbox;
+ let appState: Store<State>;
+ let actionSubject: ActionsSubject;
+ let utilService: UtilService;
+ let router: Router;
+ let modalService: NgbModal;
+
+ beforeEach(() => {
+ appState = { dispatch: () => {}, pipe: () => of(true), select: () => of(true) } as any;
+ actionSubject = { pipe: () => of(true) } as any;
+ utilService = { displayNotification() {} } as any;
+ router = { navigateByUrl() {} } as any;
+ modalService = { open() {} } as any;
+ spyOn(appState, 'dispatch').and.callFake(() => {});
+
+ service = new AddressTypesSandbox(appState, actionSubject, router, utilService, modalService);
+ });
+
+ it('should create AddressTypesSandbox service', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should set DisplayForm property', () => {
+ service.setDisplayForm();
+ expect(service.displayForm).toBeTruthy();
+ });
+
+ it('should dispatch loadAddressTypes Action via loadAddressTypes()', () => {
+ service.loadAddressTypes();
+ expect(appState.dispatch).toHaveBeenCalledWith(addressTypesActions.loadAddressTypes());
+ });
+
+ it('should dispatch loadAddressType Action via loadAddressType(id)', () => {
+ service.loadAddressType('x');
+ expect(appState.dispatch).toHaveBeenCalledWith(addressTypesActions.loadAddressType({ payload: 'x' }));
+ });
+
+ it('should call dispatch for saving an address type', () => {
+ service.currentFormState = {isValid: true} as any;
+ service.saveAddressType();
+ expect(appState.dispatch).toHaveBeenCalledWith(addressTypesActions.saveAddressType({
+ payload: new AddressType()
+ })
+ );
+ });
+
+ it('should clear form via clear()', () => {
+ service['clear']();
+ expect(service.displayForm).toBe(false);
+ });
+
+ it('should open modal before deleting a AddressType', () => {
+ spyOn(service['modalService'], 'open')
+ .and.returnValue({componentInstance: {title: ''}, result: {then: () => of(true)}} as any);
+ service.deleteAddressType('x');
+ expect(modalService.open).toHaveBeenCalled();
+ });
+
+ it('should clear form state when current change is canceled and form state is pristine', () => {
+ let spy = spyOn(service,'clear');
+ service.currentFormState = {isPristine: true} as any;
+ service.cancel();
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should open modal when current change is canceled and form state is not pristine', () => {
+ spyOn(service['modalService'], 'open')
+ .and.returnValue({componentInstance: {title: ''}, result: {then: () => of(true)}} as any);
+ service.currentFormState = {isPristine: false} as any;
+ service.cancel();
+ expect(modalService.open).toHaveBeenCalled();
+ });
+});
diff --git a/src/app/pages/admin/address-types/address-types.sandbox.ts b/src/app/pages/admin/address-types/address-types.sandbox.ts
new file mode 100644
index 0000000..6993ce2
--- /dev/null
+++ b/src/app/pages/admin/address-types/address-types.sandbox.ts
@@ -0,0 +1,132 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { UtilService } from '@shared/utility/utility.service';
+import { Injectable } from '@angular/core';
+import { Store, ActionsSubject } from '@ngrx/store';
+import { Observable } from 'rxjs';
+import { BaseSandbox } from '@shared/sandbox/base.sandbox';
+import * as store from '@shared/store';
+import * as addressTypesActions from '@shared/store/actions/admin/address-types.action';
+import * as addressTypesFormReducer from '@shared/store/reducers/admin/address-types-details-form.reducer';
+import { AddressType } from '@shared/models';
+import { FormGroupState, SetValueAction, ResetAction, MarkAsTouchedAction } from 'ngrx-forms';
+import { ofType } from '@ngrx/effects';
+import { Router } from '@angular/router';
+import { takeUntil, take } from 'rxjs/operators';
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { SafetyQueryDialogComponent } from '@shared/components/dialogs/safety-query-dialog/safety-query-dialog.component';
+import { ILoadAddressTypesSuccess } from '@shared/store/actions/admin/address-types.action';
+
+@Injectable()
+export class AddressTypesSandbox extends BaseSandbox {
+
+ public addressTypes$= this.appState$.select(store.getAddressTypesData);
+ public formState$ = this.appState$.select(store.getAddressTypesDetails);
+ public currentFormState: FormGroupState<AddressType>;
+ public displayForm: boolean = false;
+
+ constructor(
+ protected appState$: Store<store.State>,
+ protected actionsSubject: ActionsSubject,
+ protected router: Router,
+ protected utilService: UtilService,
+ protected modalService: NgbModal
+ ) {
+ super(appState$);
+ }
+
+ public setDisplayForm(): void {
+ this.clear();
+ this.appState$.dispatch(new MarkAsTouchedAction(addressTypesFormReducer.FORM_ID));
+ this.displayForm = true;
+ }
+
+ public loadAddressTypes(): Observable<ILoadAddressTypesSuccess> {
+ this.appState$.dispatch(addressTypesActions.loadAddressTypes());
+ return this.actionsSubject.pipe(ofType(addressTypesActions.loadAddressTypesSuccess), take(1));
+ }
+
+ public loadAddressType(id: string): void {
+ this.appState$.dispatch(
+ addressTypesActions.loadAddressType({ payload: id })
+ );
+ }
+
+ public deleteAddressType(id: string): void {
+ const modalRef = this.modalService.open(SafetyQueryDialogComponent);
+ modalRef.componentInstance.title = 'ConfirmDialog.Action.delete';
+ modalRef.componentInstance.body = 'ConfirmDialog.Deletion';
+ modalRef.result.then(() => {
+ this.appState$.dispatch(
+ addressTypesActions.deleteAddressType({ payload: id })
+ );
+ this.clear();
+ }, () => {
+ });
+ }
+
+ public cancel(): void {
+ if (!this.currentFormState.isPristine) {
+ const modalRef = this.modalService.open(SafetyQueryDialogComponent);
+ modalRef.componentInstance.title = 'ConfirmDialog.Action.edit';
+ modalRef.componentInstance.body = 'ConfirmDialog.Content';
+ modalRef.result.then(() => {
+ this.clear();
+ }, () => {
+ });
+ } else {
+ this.clear();
+ }
+ }
+
+ clear(): void {
+ this.appState$.dispatch(
+ new SetValueAction(
+ addressTypesFormReducer.FORM_ID,
+ addressTypesFormReducer.INITIAL_STATE.value
+ )
+ );
+ this.appState$.dispatch(new ResetAction(addressTypesFormReducer.FORM_ID));
+ this.displayForm = false;
+ }
+
+ public saveAddressType(): void {
+ if (this.currentFormState.isValid) {
+ this.appState$.dispatch(
+ addressTypesActions.saveAddressType({
+ payload: new AddressType(this.currentFormState.value)
+ })
+ );
+ this.actionsSubject
+ .pipe(
+ ofType(addressTypesActions.saveAddressTypeSuccess),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe(() => {
+ this.clear();
+ });
+ } else {
+ this.utilService.displayNotification(
+ 'MandatoryFieldError',
+ 'error'
+ );
+ }
+ }
+
+ public registerEvents(): void {
+ this.formState$.pipe(takeUntil(this._endSubscriptions$)).subscribe(
+ (formState: FormGroupState<AddressType>) =>
+ (this.currentFormState = formState)
+ )
+ }
+}
diff --git a/src/app/pages/admin/address-types/address-types.service.spec.ts b/src/app/pages/admin/address-types/address-types.service.spec.ts
new file mode 100644
index 0000000..ba4fb4a
--- /dev/null
+++ b/src/app/pages/admin/address-types/address-types.service.spec.ts
@@ -0,0 +1,36 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { AddressType } from '@shared/models';
+import { AddressTypesService } from '@pages/admin/address-types/address-types.service';
+
+describe(' AddressTypesService', () => {
+ let service: AddressTypesService;
+
+ beforeEach(() => {
+ });
+
+ it('should transform list', () => {
+ const response = [new AddressType()];
+ response[0].type = 'X';
+
+ expect( AddressTypesService.gridAdapter(response)[0].type).toBe('X');
+ });
+
+
+ it('should transform details', () => {
+ const response: any = { type: 'X'};
+ const item = AddressTypesService.itemAdapter(response);
+
+ expect(item.type).toBe(response.type);
+ });
+});
diff --git a/src/app/pages/admin/address-types/address-types.service.ts b/src/app/pages/admin/address-types/address-types.service.ts
new file mode 100644
index 0000000..d01da90
--- /dev/null
+++ b/src/app/pages/admin/address-types/address-types.service.ts
@@ -0,0 +1,26 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { Injectable } from '@angular/core';
+import { AddressType } from '@shared/models';
+
+@Injectable()
+export class AddressTypesService {
+
+ static gridAdapter(response: any): Array<AddressType> {
+ return response.map(addressType => new AddressType(addressType));
+ }
+
+ static itemAdapter(response: any): AddressType {
+ return new AddressType(response);
+ }
+}
diff --git a/src/app/pages/admin/admin-routing.module.ts b/src/app/pages/admin/admin-routing.module.ts
index 54b7180..caa7df3 100644
--- a/src/app/pages/admin/admin-routing.module.ts
+++ b/src/app/pages/admin/admin-routing.module.ts
@@ -10,8 +10,14 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { SalutationsResolver } from '@pages/admin//salutations/salutations.resolver';
+import { PersonTypesResolver } from '@pages/admin/person-types/person-types.resolver';
+import { PersonTypesListComponent } from '@pages/admin/person-types/person-types-list/person-types-list.component';
+import { SalutationsResolver } from '@pages/admin/salutations/salutations.resolver';
import { SalutationsListComponent } from '@pages/admin/salutations/salutations-list/salutations-list.component';
+import { CommunicationTypesListComponent } from '@pages/admin/communication-types/communication-types-list/communication-types-list.component';
+import { CommunicationTypesResolver } from '@pages/admin/communication-types/communication-types.resolver';
+import { AddressTypesListComponent } from '@pages/admin/address-types/address-types-list/address-types-list.component';
+import { AddressTypesResolver } from '@pages/admin/address-types/address-types.resolver';
import { Routes, RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
@@ -22,6 +28,27 @@
resolve: {
salutationsTable: SalutationsResolver
},
+ },
+ {
+ path: 'communication-types',
+ component: CommunicationTypesListComponent,
+ resolve: {
+ communicationTypesTable: CommunicationTypesResolver
+ },
+ },
+ {
+ path: 'person-types',
+ component: PersonTypesListComponent,
+ resolve: {
+ personTypesTable: PersonTypesResolver
+ },
+ },
+ {
+ path: 'address-types',
+ component: AddressTypesListComponent,
+ resolve: {
+ personTypesTable: AddressTypesResolver
+ },
}
];
diff --git a/src/app/pages/admin/admin.module.ts b/src/app/pages/admin/admin.module.ts
index 8e5154a..6eae4e6 100644
--- a/src/app/pages/admin/admin.module.ts
+++ b/src/app/pages/admin/admin.module.ts
@@ -10,26 +10,49 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { SalutationsDetailsComponent } from '@app/pages/admin/salutations/salutations-details/salutations-details.component';
-import { SalutationsResolver } from '@app/pages/admin/salutations/salutations.resolver';
-import { SalutationsSandbox } from '@app/pages/admin/salutations/salutations.sandbox';
-import { SalutationsApiClient } from '@app/pages/admin/salutations/salutations-api-client';
-import { SalutationsService } from '@app/pages/admin/salutations/salutations.service';
+import { CommunicationTypesApiClient } from '@pages/admin/communication-types/communication-types-api-client';
+import { CommunicationTypesService } from '@pages/admin/communication-types/communication-types.service';
+import { CommunicationTypesSandbox } from '@pages/admin/communication-types/communication-types.sandbox';
+import { CommunicationTypesResolver } from '@pages/admin/communication-types/communication-types.resolver';
+import { CommunicationTypesEffects } from '@shared/store/effects/admin/communication-types.effect';
+import { CommunicationTypesDetailsComponent } from '@pages/admin/communication-types/communication-types-details/communication-types-details.component';
+import { SalutationsDetailsComponent } from '@pages/admin/salutations/salutations-details/salutations-details.component';
+import { SalutationsResolver } from '@pages/admin/salutations/salutations.resolver';
+import { SalutationsSandbox } from '@pages/admin/salutations/salutations.sandbox';
+import { SalutationsApiClient } from '@pages/admin/salutations/salutations-api-client';
+import { SalutationsService } from '@pages/admin/salutations/salutations.service';
+import { SalutationsEffects } from '@shared/store/effects/admin/salutations.effect';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
-import { ComponentsModule } from '@app/shared/components';
-import { ContainersModule } from '@app/shared/containers';
+import { ComponentsModule } from '@shared/components';
+import { ContainersModule } from '@shared/containers';
import { TranslateModule } from '@ngx-translate/core';
-import { DirectivesModule } from '@app/shared/directives';
+import { DirectivesModule } from '@shared/directives';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { StoreModule } from '@ngrx/store';
import { AgGridModule } from 'ag-grid-angular';
import { NgrxFormsModule } from 'ngrx-forms';
+import { EffectsModule } from '@ngrx/effects';
import { AdminRoutingModule } from '@pages/admin/admin-routing.module';
import { SalutationsListComponent } from '@pages/admin/salutations/salutations-list/salutations-list.component';
-import { adminReducers } from '@app/shared/store';
+import { CommunicationTypesListComponent } from '@pages/admin/communication-types/communication-types-list/communication-types-list.component';
+import { adminReducers } from '@shared/store';
+import { PersonTypesListComponent } from '@pages/admin/person-types/person-types-list/person-types-list.component';
+import { PersonTypesSandbox } from '@pages/admin/person-types/person-types.sandbox';
+import { PersonTypesApiClient } from '@pages/admin/person-types/person-types-api-client';
+import { PersonTypesService } from '@pages/admin/person-types/person-types.service';
+import { PersonTypesEffects } from '@shared/store/effects/admin/person-types.effect';
+import { PersonTypesResolver } from '@pages/admin/person-types/person-types.resolver';
+import { PersonTypesDetailsComponent } from '@pages/admin/person-types/person-types-details/person-types-details.component';
+import { AddressTypesListComponent } from '@pages/admin/address-types/address-types-list/address-types-list.component';
+import { AddressTypesDetailsComponent } from '@pages/admin/address-types/address-types-details/address-types-details.component';
+import { AddressTypesSandbox } from '@pages/admin/address-types//address-types.sandbox';
+import { AddressTypesEffects } from '@shared/store/effects/admin/address-types.effect';
+import { AddressTypesApiClient } from '@pages/admin/address-types/address-types-api-client';
+import { AddressTypesService } from '@pages/admin/address-types/address-types.service';
+import { AddressTypesResolver } from '@pages/admin/address-types/address-types.resolver';
@NgModule({
imports: [
@@ -43,18 +66,37 @@
RouterModule,
FormsModule,
StoreModule.forFeature('admin', adminReducers),
+ EffectsModule.forFeature([SalutationsEffects, CommunicationTypesEffects, PersonTypesEffects, AddressTypesEffects]),
AgGridModule.withComponents([]),
AdminRoutingModule,
],
declarations: [
SalutationsListComponent,
- SalutationsDetailsComponent
+ SalutationsDetailsComponent,
+ CommunicationTypesListComponent,
+ CommunicationTypesDetailsComponent,
+ PersonTypesListComponent,
+ PersonTypesDetailsComponent,
+ AddressTypesListComponent,
+ AddressTypesDetailsComponent
],
providers: [
SalutationsService,
SalutationsApiClient,
SalutationsSandbox,
- SalutationsResolver
+ SalutationsResolver,
+ CommunicationTypesSandbox,
+ CommunicationTypesService,
+ CommunicationTypesApiClient,
+ CommunicationTypesResolver,
+ PersonTypesSandbox,
+ PersonTypesService,
+ PersonTypesApiClient,
+ PersonTypesResolver,
+ AddressTypesSandbox,
+ AddressTypesService,
+ AddressTypesApiClient,
+ AddressTypesResolver,
]
})
export class AdminModule { }
diff --git a/src/app/pages/admin/communication-types/communication-types-api-client.ts b/src/app/pages/admin/communication-types/communication-types-api-client.ts
new file mode 100644
index 0000000..b5bfef2
--- /dev/null
+++ b/src/app/pages/admin/communication-types/communication-types-api-client.ts
@@ -0,0 +1,56 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { CommunicationTypesService } from '@pages/admin/communication-types/communication-types.service';
+import { Injectable } from '@angular/core';
+import { HttpService, GET, Adapter, DefaultHeaders, Path, PUT, Body, POST, DELETE } from '@shared/asyncServices/http';
+import { Observable } from 'rxjs';
+import { CommunicationType } from '@shared/models';
+
+@Injectable()
+@DefaultHeaders({
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json',
+})
+export class CommunicationTypesApiClient extends HttpService {
+
+ @GET('/communication-types')
+ @Adapter(CommunicationTypesService.gridAdapter)
+ public getCommunicationTypes(): Observable<Array<CommunicationType>> {
+ return null;
+ }
+
+ @GET('/communication-types/{id}')
+ @Adapter(CommunicationTypesService.responseAdapter)
+ public getCommunicationType(@Path('id') id: string): Observable<CommunicationType> {
+ return null;
+ }
+
+ @PUT('/communication-types/{id}')
+ @Adapter(CommunicationTypesService.responseAdapter)
+ public putCommunicationType(@Path('id') id: string, @Body() item: CommunicationType): Observable<CommunicationType> {
+ return null;
+ }
+
+ @POST('/communication-types')
+ @Adapter(CommunicationTypesService.responseAdapter)
+ public postCommunicationType(@Body() newCommunicationType: CommunicationType): Observable<CommunicationType> {
+ return null;
+ }
+
+ @DELETE('/communication-types/{id}')
+ @Adapter(CommunicationTypesService.responseAdapter)
+ public deleteCommunicationType(@Path('id') id: string): Observable<void> {
+ return null;
+ }
+
+}
diff --git a/src/app/pages/admin/communication-types/communication-types-details/communication-types-details.component.html b/src/app/pages/admin/communication-types/communication-types-details/communication-types-details.component.html
new file mode 100644
index 0000000..e9480a0
--- /dev/null
+++ b/src/app/pages/admin/communication-types/communication-types-details/communication-types-details.component.html
@@ -0,0 +1,87 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<form [ngrxFormState]="communicationTypesSandbox.formState$ | async">
+ <h4>{{ 'CommunicationTypes.DetailsTitle' | translate }}</h4>
+ <div>
+ <!-- type -->
+ <div class="form-group row">
+ <label for="communicationTypesTyp" class="col-sm-2 col-form-label">{{ 'CommunicationTypes.Type' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ required
+ [readonly]="communicationTypesSandbox.formMode==='readonly'"
+ maxlength="30"
+ class="form-control"
+ id="communicationTypesTyp"
+ [ngrxFormControlState]="((communicationTypesSandbox.formState$ | async)?.controls)['type']"
+ autocomplete="off"
+ />
+ </div>
+ <div class="col-sm-1"></div>
+ <div class="col-sm-2">
+ <input type="checkbox"
+ class="form-check-input"
+ id="communicationTypesEditable"
+ [ngrxFormControlState]="((communicationTypesSandbox.formState$ | async)?.controls)['editable']"
+ onclick="return false;"
+ />
+ <label for="communicationTypesEditable" class="form-check-label">{{ 'CommunicationTypes.Editable' | translate }}</label>
+ </div>
+ </div>
+
+ <!-- description -->
+ <div class="form-group row">
+ <label for="communicationTypesDescription" class="col-sm-2 col-form-label">{{ 'CommunicationTypes.Description' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ required
+ [readonly]="communicationTypesSandbox.formMode==='readonly'"
+ maxlength="255"
+ class="form-control"
+ id="communicationTypesDescription"
+ [ngrxFormControlState]="((communicationTypesSandbox.formState$ | async)?.controls)['description']"
+ autocomplete="off"
+ />
+ </div>
+ <div class="col-sm-1"></div>
+ <div class="col-sm-2">
+ <input type="checkbox"
+ class="form-check-input"
+ id="communicationTypesMappingLdap"
+ [ngrxFormControlState]="((communicationTypesSandbox.formState$ | async)?.controls)['mappingLdap']"
+ onclick="return false;"
+ />
+ <label for="communicationTypesMappingLdap" class="form-check-label">{{ 'CommunicationTypes.MappingLdap' | translate }}</label>
+ </div>
+ </div>
+
+ <!-- buttons -->
+ <span *ngIf="!(communicationTypesSandbox.formMode==='readonly')">
+ <button
+ type="button"
+ class="btn btn-primary btn-sm btn-success"
+ (click)="communicationTypesSandbox.saveCommunicationType()"
+ >
+ {{ 'SaveBtn' | translate }}
+ </button>
+ </span>
+
+ <button
+ type="button"
+ class="btn btn-primary btn-sm"
+ (click)="communicationTypesSandbox.cancel()"
+ >
+ {{ 'CancelBtn' | translate }}
+ </button>
+ </div>
+</form>
diff --git a/src/app/pages/admin/communication-types/communication-types-details/communication-types-details.component.scss b/src/app/pages/admin/communication-types/communication-types-details/communication-types-details.component.scss
new file mode 100644
index 0000000..255fbf6
--- /dev/null
+++ b/src/app/pages/admin/communication-types/communication-types-details/communication-types-details.component.scss
@@ -0,0 +1,6 @@
+button {
+ margin: 20px 10px 10px 0;
+}
+h4 {
+ padding-bottom: 15px;
+}
diff --git a/src/app/pages/admin/communication-types/communication-types-details/communication-types-details.component.spec.ts b/src/app/pages/admin/communication-types/communication-types-details/communication-types-details.component.spec.ts
new file mode 100644
index 0000000..16e1092
--- /dev/null
+++ b/src/app/pages/admin/communication-types/communication-types-details/communication-types-details.component.spec.ts
@@ -0,0 +1,33 @@
+import { CommunicationTypesDetailsComponent } from '@pages/admin/communication-types/communication-types-details/communication-types-details.component';
+import { CommunicationTypesSandbox } from '@pages/admin/communication-types/communication-types.sandbox';
+
+describe('CommunicationTypesDetailsComponent', () => {
+ let component: CommunicationTypesDetailsComponent;
+ let sandbox: CommunicationTypesSandbox;
+
+beforeEach(() => {
+ sandbox = {
+ registerEvents() {},
+ endSubscriptions() {},
+ clear() {},
+ } as any;
+ component = new CommunicationTypesDetailsComponent(sandbox);
+});
+
+it('should create', () => {
+ expect(component).toBeTruthy();
+});
+
+it('should registerEvents OnInit', () => {
+ let spy = spyOn(sandbox,'registerEvents');
+ component.ngOnInit();
+ expect(spy).toHaveBeenCalled();
+});
+
+it('should endSubscriptions OnDestroy', () => {
+ let spy = spyOn(sandbox,'endSubscriptions');
+ component.ngOnDestroy();
+ expect(spy).toHaveBeenCalled();
+});
+});
+
diff --git a/src/app/pages/admin/communication-types/communication-types-details/communication-types-details.component.ts b/src/app/pages/admin/communication-types/communication-types-details/communication-types-details.component.ts
new file mode 100644
index 0000000..090205a
--- /dev/null
+++ b/src/app/pages/admin/communication-types/communication-types-details/communication-types-details.component.ts
@@ -0,0 +1,21 @@
+import { Component, OnInit, OnDestroy } from '@angular/core';
+import { CommunicationTypesSandbox } from '@pages/admin/communication-types/communication-types.sandbox';
+
+@Component({
+ selector: 'app-communication-types-details',
+ templateUrl: './communication-types-details.component.html',
+ styleUrls: ['./communication-types-details.component.scss'],
+})
+export class CommunicationTypesDetailsComponent implements OnInit, OnDestroy {
+
+ constructor(public communicationTypesSandbox: CommunicationTypesSandbox) {}
+
+ ngOnInit() {
+ this.communicationTypesSandbox.registerEvents();
+ }
+
+ ngOnDestroy() {
+ this.communicationTypesSandbox.clear();
+ this.communicationTypesSandbox.endSubscriptions();
+ }
+}
diff --git a/src/app/pages/admin/communication-types/communication-types-list/communication-types-list-column-definition.ts b/src/app/pages/admin/communication-types/communication-types-list/communication-types-list-column-definition.ts
new file mode 100644
index 0000000..7dce32f
--- /dev/null
+++ b/src/app/pages/admin/communication-types/communication-types-list/communication-types-list-column-definition.ts
@@ -0,0 +1,57 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { IconCellRendererComponent } from '@shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component';
+import { BoolCellRendererComponent } from '@shared/components/cell-renderer/bool-cell-renderer/bool-cell-renderer.component';
+
+
+export const COMMUNICATION_TYPES_COLDEF = [
+ {
+ field: 'type',
+ headerName: 'CommunicationTypes.Type',
+ sortable: true,
+ filter: 'setFilterComponent'
+ },
+ {
+ field: 'description',
+ headerName: 'CommunicationTypes.Description',
+ sortable: true,
+ filter: 'setFilterComponent'
+ },
+ {
+ field: 'editable',
+ headerName: 'CommunicationTypes.Editable',
+ sortable: true,
+ filter: 'setFilterComponent',
+ cellRendererFramework: BoolCellRendererComponent
+ },
+ {
+ field: 'mappingLdap',
+ headerName: 'CommunicationTypes.MappingLdap',
+ sortable: true,
+ filter: 'setFilterComponent',
+ cellRendererFramework: BoolCellRendererComponent
+ },
+ {
+ field: 'tools',
+ headerName: ' ',
+ pinned: 'right',
+ maxWidth: 110,
+ minWidth: 110,
+ lockPosition: true,
+ sortable: false,
+ filter: false,
+ suppressMenu: true,
+ suppressSizeToFit: true,
+ cellRendererFramework: IconCellRendererComponent
+ }
+];
diff --git a/src/app/pages/admin/communication-types/communication-types-list/communication-types-list.component.html b/src/app/pages/admin/communication-types/communication-types-list/communication-types-list.component.html
new file mode 100644
index 0000000..b32f6fa
--- /dev/null
+++ b/src/app/pages/admin/communication-types/communication-types-list/communication-types-list.component.html
@@ -0,0 +1,41 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<app-card-layout>
+ <div header>
+ <span>{{ 'CommunicationTypes.Title' | translate }}</span>
+ <div class="pull-right">
+ <button class="btn btn-primary new-button" (click)="communicationTypesSandbox.setDisplayForm()">
+ {{ 'NewBtn' | translate }}
+ </button>
+ </div>
+ </div>
+ <div class="communication-types-grid-wrapper" body>
+ <ag-grid-angular
+ autoresizecolumns
+ class="ag-theme-balham ag-grid-height"
+ [ngClass]="communicationTypesSandbox.displayForm ? 'ag-grid-height-edit' : 'ag-grid-height-list'"
+ [gridOptions]="gridOptions"
+ [columnDefs]="columnDefinition"
+ [rowSelection]="'single'"
+ [frameworkComponents]="frameworkComponents"
+ [rowData]="communicationTypesSandbox.communicationTypes$ | async"
+ >
+ </ag-grid-angular>
+ <div *ngIf="communicationTypesSandbox.displayForm" class="communication-types-details">
+ <app-communication-types-details></app-communication-types-details>
+ </div>
+ </div>
+
+</app-card-layout>
+
+
diff --git a/src/app/pages/admin/communication-types/communication-types-list/communication-types-list.component.scss b/src/app/pages/admin/communication-types/communication-types-list/communication-types-list.component.scss
new file mode 100644
index 0000000..ed1ca97
--- /dev/null
+++ b/src/app/pages/admin/communication-types/communication-types-list/communication-types-list.component.scss
@@ -0,0 +1,31 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+ .communication-types-grid-wrapper {
+ position: relative;
+}
+
+.communication-types-details {
+ margin-top: 20px;
+}
+
+.ag-grid-height-edit {
+ height: calc(100vh - 450px);
+}
+
+.ag-grid-height-list {
+ height: calc(100vh - 200px);
+}
+
+.new-button {
+ margin-right: 20px;
+}
diff --git a/src/app/pages/admin/communication-types/communication-types-list/communication-types-list.component.spec.ts b/src/app/pages/admin/communication-types/communication-types-list/communication-types-list.component.spec.ts
new file mode 100644
index 0000000..73402a1
--- /dev/null
+++ b/src/app/pages/admin/communication-types/communication-types-list/communication-types-list.component.spec.ts
@@ -0,0 +1,43 @@
+import { CommunicationType } from '@shared/models';
+import { CommunicationTypesListComponent } from '@pages/admin/communication-types/communication-types-list/communication-types-list.component';
+
+describe('CommunicationTypesListComponent', () => {
+ let component: CommunicationTypesListComponent;
+ const sandbox: any = {
+ setDisplayForm: () => {},
+ loadCommunicationType: () => {},
+ deleteCommunicationType: () => {},
+ };
+
+ beforeEach(() => {
+ component = new CommunicationTypesListComponent(sandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should initialize gridOptions context', () => {
+ component.ngOnInit();
+ expect(component.gridOptions.context.icons.edit).toBeTruthy();
+ expect(component.gridOptions.context.icons.delete).toBeTruthy();
+ expect(component.gridOptions.context.icons.readonly).toBeTruthy();
+ });
+
+ it('should call appropriate functions for edit event', () => {
+ const spy1: any = spyOn(sandbox, 'setDisplayForm');
+ const spy2: any = spyOn(sandbox, 'loadCommunicationType');
+ component.ngOnInit();
+ component.gridOptions.context.eventSubject.next({type: "edit", data: new CommunicationType()});
+ expect(spy1).toHaveBeenCalled();
+ expect(spy2).toHaveBeenCalled();
+ });
+
+ it('should call appropriate functions for delete event', () => {
+ const spy3: any = spyOn(sandbox, 'deleteCommunicationType');
+ component.ngOnInit();
+ component.gridOptions.context.eventSubject.next({type: "delete", data: new CommunicationType()});
+ expect(spy3).toHaveBeenCalled();
+ });
+
+});
diff --git a/src/app/pages/admin/communication-types/communication-types-list/communication-types-list.component.ts b/src/app/pages/admin/communication-types/communication-types-list/communication-types-list.component.ts
new file mode 100644
index 0000000..4fc5e75
--- /dev/null
+++ b/src/app/pages/admin/communication-types/communication-types-list/communication-types-list.component.ts
@@ -0,0 +1,56 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { CommunicationTypesSandbox } from '@pages/admin/communication-types/communication-types.sandbox';
+import { COMMUNICATION_TYPES_COLDEF } from '@pages/admin/communication-types/communication-types-list/communication-types-list-column-definition';
+import { Component, OnInit, OnDestroy } from '@angular/core';
+import { BaseList } from '@shared/components/base-components/base.list';
+import { SetFilterComponent } from '@shared/filters/ag-grid/set-filter/set-filter.component';
+import { Subscription } from 'rxjs';
+
+@Component({
+ selector: 'app-communication-types-list',
+ templateUrl: './communication-types-list.component.html',
+ styleUrls: ['./communication-types-list.component.scss']
+})
+export class CommunicationTypesListComponent extends BaseList implements OnInit, OnDestroy {
+
+ public columnDefinition: any = COMMUNICATION_TYPES_COLDEF;
+ public frameworkComponents: { setFilterComponent: any };
+ private _subscription: Subscription;
+
+ constructor(public communicationTypesSandbox: CommunicationTypesSandbox) {
+ super();
+ this.frameworkComponents = { setFilterComponent: SetFilterComponent };
+ }
+
+ ngOnInit() {
+ this.gridOptions.context = {
+ ...this.gridOptions.context,
+ icons: { edit: true, readonly: true, delete: true }
+ };
+ this._subscription = this.gridOptions.context.eventSubject.subscribe(event => {
+ if (event.type === 'edit' || event.type === 'readonly') {
+ this.communicationTypesSandbox.setDisplayForm(event.type);
+ this.communicationTypesSandbox.loadCommunicationType(event.data.id);
+ }
+ if (event.type === 'delete') {
+ this.communicationTypesSandbox.deleteCommunicationType(event.data.id);
+ }
+ });
+ }
+
+ ngOnDestroy() {
+ this._subscription.unsubscribe();
+ }
+
+}
diff --git a/src/app/pages/admin/communication-types/communication-types.resolver.spec.ts b/src/app/pages/admin/communication-types/communication-types.resolver.spec.ts
new file mode 100644
index 0000000..e7fef93
--- /dev/null
+++ b/src/app/pages/admin/communication-types/communication-types.resolver.spec.ts
@@ -0,0 +1,29 @@
+import { async } from '@angular/core/testing';
+import { CommunicationTypesResolver } from '@pages/admin/communication-types/communication-types.resolver';
+
+describe('CommunicationTypesResolver', () => {
+ let component: CommunicationTypesResolver;
+ let sandbox: any;
+
+ beforeEach(async(() => {
+ sandbox = {
+ clear() {},
+ loadCommunicationTypes() {},
+ } as any;
+ }));
+
+ beforeEach(() => {
+ component = new CommunicationTypesResolver(sandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call loadCommunicationTypes', () => {
+ const spy = spyOn(sandbox, 'loadCommunicationTypes');
+ component.resolve();
+ expect(spy).toHaveBeenCalled();
+ });
+
+});
diff --git a/src/app/pages/admin/communication-types/communication-types.resolver.ts b/src/app/pages/admin/communication-types/communication-types.resolver.ts
new file mode 100644
index 0000000..1a5581a
--- /dev/null
+++ b/src/app/pages/admin/communication-types/communication-types.resolver.ts
@@ -0,0 +1,27 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { CommunicationTypesSandbox } from '@pages/admin/communication-types/communication-types.sandbox';
+import { Observable } from 'rxjs';
+import { Injectable } from '@angular/core';
+import { Resolve } from '@angular/router';
+import { ILoadCommunicationTypesSuccess } from '@shared/store/actions/admin/communication-types.action';
+
+@Injectable()
+export class CommunicationTypesResolver implements Resolve<any> {
+
+ constructor(private communicationTypesSandbox: CommunicationTypesSandbox) {}
+
+ public resolve(): Observable<ILoadCommunicationTypesSuccess> {
+ return this.communicationTypesSandbox.loadCommunicationTypes();
+ }
+}
diff --git a/src/app/pages/admin/communication-types/communication-types.sandbox.spec.ts b/src/app/pages/admin/communication-types/communication-types.sandbox.spec.ts
new file mode 100644
index 0000000..c795141
--- /dev/null
+++ b/src/app/pages/admin/communication-types/communication-types.sandbox.spec.ts
@@ -0,0 +1,86 @@
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { CommunicationTypesSandbox } from '@pages/admin/communication-types/communication-types.sandbox';
+import { Store, ActionsSubject} from '@ngrx/store';
+import { State } from '@shared/store';
+import { UtilService } from '@shared/utility/utility.service';
+import { of } from 'rxjs';
+import { Router } from '@angular/router';
+import * as communicationTypesActions from '@shared/store/actions/admin/communication-types.action';
+import { CommunicationType } from '@shared/models';
+
+describe('CommunicationTypesSandbox', () => {
+ let service: CommunicationTypesSandbox = {} as any;
+ let appState: Store<State>;
+ let actionSubject: ActionsSubject;
+ let utilService: UtilService;
+ let router: Router;
+ let modalService: NgbModal;
+
+ beforeEach(() => {
+ appState = { dispatch:()=> {}, pipe: () => of(true), select:()=> of(true) } as any;
+ actionSubject = { pipe: () => of(true) } as any;
+ utilService = { displayNotification() {} } as any;
+ router = { navigateByUrl() {} } as any;
+ modalService = { open() {} } as any;
+ spyOn(appState, 'dispatch').and.callFake(() => {});
+
+ service = new CommunicationTypesSandbox(appState, actionSubject, router, utilService, modalService);
+ });
+
+ it('should create CommunicationTypesSandbox service', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should set DisplayForm property', () => {
+ service.setDisplayForm('x');
+ expect(service.displayForm).toBeTruthy();
+ expect(service.formMode).toBe('x');
+ });
+
+ it('should dispatch loadCommunicationTypes Action via loadCommunicationTypes()', () => {
+ service.loadCommunicationTypes();
+ expect(appState.dispatch).toHaveBeenCalledWith(communicationTypesActions.loadCommunicationTypes());
+ });
+
+ it('should dispatch loadCommunicationType Action via loadCommunicationType(id)', () => {
+ service.loadCommunicationType('x');
+ expect(appState.dispatch).toHaveBeenCalledWith(communicationTypesActions.loadCommunicationType({ payload: 'x' }));
+ });
+
+ it('should call dispatch for saving an communication type', () => {
+ service.currentFormState = {isValid: true} as any;
+ service.saveCommunicationType();
+ expect(appState.dispatch).toHaveBeenCalledWith(communicationTypesActions.saveCommunicationType({
+ payload: new CommunicationType()
+ })
+ );
+ });
+
+ it('should clear form via clear()', () => {
+ service['clear']();
+ expect(service.displayForm).toBe(false);
+ });
+
+ it('should open modal before deleting a salutation', () => {
+ spyOn(service['modalService'], 'open')
+ .and.returnValue({componentInstance: {title: ''}, result: {then: () => of(true)}} as any);
+ service.deleteCommunicationType('x');
+ expect(modalService.open).toHaveBeenCalled();
+ });
+
+ it('should clear form state when current change is canceled and form state is pristine', () => {
+ let spy = spyOn(service,'clear');
+ service.currentFormState = {isPristine: true} as any;
+ service.cancel();
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should open modal when current change is canceled and form state is not pristine', () => {
+ spyOn(service['modalService'], 'open')
+ .and.returnValue({componentInstance: {title: ''}, result: {then: () => of(true)}} as any);
+ service.currentFormState = {isPristine: false} as any;
+ service.cancel();
+ expect(modalService.open).toHaveBeenCalled();
+ });
+
+});
diff --git a/src/app/pages/admin/communication-types/communication-types.sandbox.ts b/src/app/pages/admin/communication-types/communication-types.sandbox.ts
new file mode 100644
index 0000000..abf11bc
--- /dev/null
+++ b/src/app/pages/admin/communication-types/communication-types.sandbox.ts
@@ -0,0 +1,136 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { UtilService } from '@shared/utility/utility.service';
+import { Injectable } from '@angular/core';
+import { Store, ActionsSubject } from '@ngrx/store';
+import { Observable } from 'rxjs';
+import { BaseSandbox } from '@shared/sandbox/base.sandbox';
+import * as store from '@shared/store';
+import * as communicationTypesActions from '@shared/store/actions/admin/communication-types.action';
+import * as communicationTypesFormReducer from '@shared/store/reducers/admin/communication-types-details-form.reducer';
+import { CommunicationType } from '@shared/models';
+import { FormGroupState, SetValueAction, ResetAction, MarkAsTouchedAction } from 'ngrx-forms';
+import { ofType } from '@ngrx/effects';
+import { Router } from '@angular/router';
+import { takeUntil, take } from 'rxjs/operators';
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { SafetyQueryDialogComponent } from '@shared/components/dialogs/safety-query-dialog/safety-query-dialog.component';
+import { ILoadCommunicationTypesSuccess } from '@shared/store/actions/admin/communication-types.action';
+
+@Injectable()
+export class CommunicationTypesSandbox extends BaseSandbox {
+
+ public communicationTypes$= this.appState$.select(store.getCommunicationTypesData);
+ public formState$ = this.appState$.select(store.getCommunicationTypesDetails);
+
+ public currentFormState: FormGroupState<CommunicationType>;
+ public displayForm: boolean = false;
+ public formMode: string;
+
+ constructor(
+ protected appState$: Store<store.State>,
+ protected actionsSubject: ActionsSubject,
+ protected router: Router,
+ protected utilService: UtilService,
+ protected modalService: NgbModal
+ ) {
+ super(appState$);
+ }
+
+ public setDisplayForm(mode?: string): void {
+ this.clear();
+ this.appState$.dispatch(new MarkAsTouchedAction(communicationTypesFormReducer.FORM_ID));
+ this.displayForm = true;
+ this.formMode = mode;
+ }
+
+ public loadCommunicationTypes(): Observable<ILoadCommunicationTypesSuccess> {
+ this.appState$.dispatch(communicationTypesActions.loadCommunicationTypes());
+ return this.actionsSubject.pipe(ofType(communicationTypesActions.loadCommunicationTypesSuccess), take(1));
+ }
+
+ public loadCommunicationType(id: string): void {
+ this.appState$.dispatch(
+ communicationTypesActions.loadCommunicationType({ payload: id })
+ );
+ }
+
+ public deleteCommunicationType(id: string): void {
+ const modalRef = this.modalService.open(SafetyQueryDialogComponent);
+ modalRef.componentInstance.title = 'ConfirmDialog.Action.delete';
+ modalRef.componentInstance.body = 'ConfirmDialog.Deletion';
+ modalRef.result.then(() => {
+ this.appState$.dispatch(
+ communicationTypesActions.deleteCommunicationType({ payload: id })
+ );
+ this.clear();
+ }, () => {
+ });
+ }
+
+ public cancel(): void {
+ if (!this.currentFormState.isPristine) {
+ const modalRef = this.modalService.open(SafetyQueryDialogComponent);
+ modalRef.componentInstance.title = 'ConfirmDialog.Action.edit';
+ modalRef.componentInstance.body = 'ConfirmDialog.Content';
+ modalRef.result.then(() => {
+ this.clear();
+ }, () => {
+ });
+ } else {
+ this.clear();
+ }
+ }
+
+ clear(): void {
+ this.appState$.dispatch(
+ new SetValueAction(
+ communicationTypesFormReducer.FORM_ID,
+ communicationTypesFormReducer.INITIAL_STATE.value
+ )
+ );
+ this.appState$.dispatch(new ResetAction(communicationTypesFormReducer.FORM_ID));
+ this.displayForm = false;
+ }
+
+ public saveCommunicationType(): void {
+ if (this.currentFormState.isValid) {
+ this.appState$.dispatch(
+ communicationTypesActions.saveCommunicationType({
+ payload: new CommunicationType (this.currentFormState.value)
+ })
+ );
+ this.actionsSubject
+ .pipe(
+ ofType(communicationTypesActions.saveCommunicationTypeSuccess),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe(() => {
+ this.clear();
+ });
+ } else {
+ this.utilService.displayNotification(
+ 'MandatoryFieldError',
+ 'error'
+ );
+ }
+ }
+
+ public registerEvents(): void {
+
+ this.formState$.pipe(takeUntil(this._endSubscriptions$)).subscribe(
+ (formState: FormGroupState<CommunicationType>) =>
+ (this.currentFormState = formState)
+ )
+ }
+}
diff --git a/src/app/pages/admin/communication-types/communication-types.service.spec.ts b/src/app/pages/admin/communication-types/communication-types.service.spec.ts
new file mode 100644
index 0000000..ab8f504
--- /dev/null
+++ b/src/app/pages/admin/communication-types/communication-types.service.spec.ts
@@ -0,0 +1,24 @@
+import { CommunicationType } from '@shared/models';
+import { CommunicationTypesService } from '@pages/admin/communication-types/communication-types.service';
+
+describe('CommunicationTypesService', () => {
+ let service: CommunicationTypesService;
+
+ beforeEach(() => {
+ });
+
+ it('should transform list', () => {
+ const response = [new CommunicationType()];
+ response[0].type = 'X';
+
+ expect(CommunicationTypesService.gridAdapter(response)[0].type).toBe('X');
+ });
+
+
+ it('should transform details', () => {
+ const response: any = { type: 'X'};
+ const item = CommunicationTypesService.responseAdapter(response);
+
+ expect(item.type).toBe(response.type);
+ });
+});
diff --git a/src/app/pages/admin/communication-types/communication-types.service.ts b/src/app/pages/admin/communication-types/communication-types.service.ts
new file mode 100644
index 0000000..6b0db3a
--- /dev/null
+++ b/src/app/pages/admin/communication-types/communication-types.service.ts
@@ -0,0 +1,26 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { Injectable } from '@angular/core';
+import { CommunicationType } from '@shared/models';
+
+@Injectable()
+export class CommunicationTypesService {
+
+ static gridAdapter(response: any): Array<CommunicationType> {
+ return response.map(item => new CommunicationType(item));
+ }
+
+ static responseAdapter(response: any): CommunicationType {
+ return new CommunicationType(response);
+ }
+}
diff --git a/src/app/pages/admin/person-types/person-types-api-client.ts b/src/app/pages/admin/person-types/person-types-api-client.ts
new file mode 100644
index 0000000..7d1e921
--- /dev/null
+++ b/src/app/pages/admin/person-types/person-types-api-client.ts
@@ -0,0 +1,44 @@
+import { PersonTypesService } from '@pages/admin/person-types/person-types.service';
+import { Injectable } from '@angular/core';
+import { HttpService, GET, Adapter, DefaultHeaders, Path, PUT, Body, POST, DELETE } from '@shared/asyncServices/http';
+import { Observable } from 'rxjs';
+import { PersonType } from '@shared/models';
+
+@Injectable()
+@DefaultHeaders({
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json',
+})
+export class PersonTypesApiClient extends HttpService {
+
+ @GET('/personTypes')
+ @Adapter(PersonTypesService.gridAdapter)
+ public getPersonTypes(): Observable<PersonType[]> {
+ return null;
+ }
+
+ @GET('/personTypes/{id}')
+ @Adapter(PersonTypesService.itemAdapter)
+ public getPersonTypeDetails(@Path('id') id: string): Observable<PersonType> {
+ return null;
+ }
+
+ @PUT('/personTypes/{id}')
+ @Adapter(PersonTypesService.itemAdapter)
+ public putPersonType(@Path('id') id: string, @Body() item: PersonType): Observable<PersonType> {
+ return null;
+ }
+
+ @POST('/personTypes')
+ @Adapter(PersonTypesService.itemAdapter)
+ public postPersonType(@Body() newPersonType: PersonType): Observable<PersonType> {
+ return null;
+ }
+
+ @DELETE('/personTypes/{id}')
+ @Adapter(PersonTypesService.itemAdapter)
+ public deletePersonType(@Path('id') id: string): Observable<void> {
+ return null;
+ }
+
+}
diff --git a/src/app/pages/admin/person-types/person-types-details/person-types-details.component.html b/src/app/pages/admin/person-types/person-types-details/person-types-details.component.html
new file mode 100644
index 0000000..7bcc712
--- /dev/null
+++ b/src/app/pages/admin/person-types/person-types-details/person-types-details.component.html
@@ -0,0 +1,63 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<form [ngrxFormState]="personTypesSandbox.formState$ | async">
+ <h4>{{ 'PersonTypes.DetailsTitle' | translate }}</h4>
+ <div>
+ <!-- type -->
+ <div class="form-group row">
+ <label for="personTypesTyp" class="col-sm-2 col-form-label">{{ 'PersonTypes.Type' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ required
+ maxlength="30"
+ class="form-control"
+ id="personTypesTyp"
+ [ngrxFormControlState]="((personTypesSandbox.formState$ | async)?.controls)['type']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- description -->
+ <div class="form-group row">
+ <label for="personTypesDescription" class="col-sm-2 col-form-label">{{ 'PersonTypes.Description' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ required
+ maxlength="255"
+ class="form-control"
+ id="personTypesDescription"
+ [ngrxFormControlState]="((personTypesSandbox.formState$ | async)?.controls)['description']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- buttons -->
+ <button
+ type="button"
+ class="btn btn-primary btn-sm btn-success"
+ (click)="personTypesSandbox.savePersonType()"
+ >
+ {{ 'SaveBtn' | translate }}
+ </button>
+
+ <button
+ type="button"
+ class="btn btn-primary btn-sm"
+ (click)="personTypesSandbox.cancel()"
+ >
+ {{ 'CancelBtn' | translate }}
+ </button>
+ </div>
+</form>
diff --git a/src/app/pages/admin/person-types/person-types-details/person-types-details.component.scss b/src/app/pages/admin/person-types/person-types-details/person-types-details.component.scss
new file mode 100644
index 0000000..255fbf6
--- /dev/null
+++ b/src/app/pages/admin/person-types/person-types-details/person-types-details.component.scss
@@ -0,0 +1,6 @@
+button {
+ margin: 20px 10px 10px 0;
+}
+h4 {
+ padding-bottom: 15px;
+}
diff --git a/src/app/pages/admin/person-types/person-types-details/person-types-details.component.spec.ts b/src/app/pages/admin/person-types/person-types-details/person-types-details.component.spec.ts
new file mode 100644
index 0000000..701062b
--- /dev/null
+++ b/src/app/pages/admin/person-types/person-types-details/person-types-details.component.spec.ts
@@ -0,0 +1,32 @@
+import { PersonTypesDetailsComponent } from '@pages/admin/person-types/person-types-details/person-types-details.component';
+import { PersonTypesSandbox } from '@pages/admin/person-types/person-types.sandbox';
+
+describe('PersonTypesDetailsComponent', () => {
+ let component: PersonTypesDetailsComponent;
+ let sandbox: PersonTypesSandbox;
+
+beforeEach(() => {
+ sandbox = {
+ registerEvents() {},
+ endSubscriptions() {},
+ clear() {},
+ } as any;
+ component = new PersonTypesDetailsComponent(sandbox);
+});
+
+it('should create', () => {
+ expect(component).toBeTruthy();
+});
+
+it('should registerEvents OnInit', () => {
+ let spy = spyOn(sandbox,'registerEvents');
+ component.ngOnInit();
+ expect(spy).toHaveBeenCalled();
+});
+
+it('should endSubscriptions OnDestroy', () => {
+ let spy = spyOn(sandbox,'endSubscriptions');
+ component.ngOnDestroy();
+ expect(spy).toHaveBeenCalled();
+});
+});
diff --git a/src/app/pages/admin/person-types/person-types-details/person-types-details.component.ts b/src/app/pages/admin/person-types/person-types-details/person-types-details.component.ts
new file mode 100644
index 0000000..0f572d0
--- /dev/null
+++ b/src/app/pages/admin/person-types/person-types-details/person-types-details.component.ts
@@ -0,0 +1,24 @@
+import { Component, OnInit, OnDestroy } from '@angular/core';
+import { PersonTypesSandbox } from '@pages/admin/person-types/person-types.sandbox';
+
+@Component({
+ selector: 'app-person-types-details',
+ templateUrl: './person-types-details.component.html',
+ styleUrls: ['./person-types-details.component.scss']
+})
+export class PersonTypesDetailsComponent implements OnInit, OnDestroy {
+
+ constructor(
+ public personTypesSandbox: PersonTypesSandbox,
+ ) { }
+
+ ngOnInit() {
+ this.personTypesSandbox.registerEvents();
+ }
+
+ ngOnDestroy() {
+ this.personTypesSandbox.clear();
+ this.personTypesSandbox.endSubscriptions();
+ }
+
+}
diff --git a/src/app/pages/admin/person-types/person-types-list/person-types-list-column-definition.ts b/src/app/pages/admin/person-types/person-types-list/person-types-list-column-definition.ts
new file mode 100644
index 0000000..e23c5f5
--- /dev/null
+++ b/src/app/pages/admin/person-types/person-types-list/person-types-list-column-definition.ts
@@ -0,0 +1,41 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { IconCellRendererComponent } from '@shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component';
+
+export const PERSON_TYPES_COLDEF = [
+ {
+ field: 'type',
+ headerName: 'PersonTypes.Type',
+ sortable: true,
+ filter: 'setFilterComponent'
+ },
+ {
+ field: 'description',
+ headerName: 'PersonTypes.Description',
+ sortable: true,
+ filter: 'setFilterComponent'
+ },
+ {
+ field: 'tools',
+ headerName: ' ',
+ pinned: 'right',
+ maxWidth: 110,
+ minWidth: 110,
+ lockPosition: true,
+ sortable: false,
+ filter: false,
+ suppressMenu: true,
+ suppressSizeToFit: true,
+ cellRendererFramework: IconCellRendererComponent
+ }
+];
diff --git a/src/app/pages/admin/person-types/person-types-list/person-types-list.component.html b/src/app/pages/admin/person-types/person-types-list/person-types-list.component.html
new file mode 100644
index 0000000..df3092e
--- /dev/null
+++ b/src/app/pages/admin/person-types/person-types-list/person-types-list.component.html
@@ -0,0 +1,39 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<app-card-layout>
+ <div header>
+ <span>{{ 'PersonTypes.Title' | translate }}</span>
+ <div class="pull-right">
+ <button class="btn btn-primary new-button" (click)="sandbox.setDisplayForm()">
+ {{ 'NewBtn' | translate }}
+ </button>
+ </div>
+ </div>
+ <div class="person-types-grid-wrapper" body>
+ <ag-grid-angular
+ autoresizecolumns
+ class="ag-theme-balham ag-grid-height"
+ [ngClass]="sandbox.displayForm ? 'ag-grid-height-edit' : 'ag-grid-height-list'"
+ [gridOptions]="gridOptions"
+ [columnDefs]="columnDefinition"
+ [rowSelection]="'single'"
+ [frameworkComponents]="frameworkComponents"
+ [rowData]="sandbox.personTypes$ | async"
+ >
+ </ag-grid-angular>
+ <div *ngIf="sandbox.displayForm" class="person-types-details">
+ <app-person-types-details></app-person-types-details>
+ </div>
+ </div>
+
+</app-card-layout>
diff --git a/src/app/pages/admin/person-types/person-types-list/person-types-list.component.scss b/src/app/pages/admin/person-types/person-types-list/person-types-list.component.scss
new file mode 100644
index 0000000..d08bd75
--- /dev/null
+++ b/src/app/pages/admin/person-types/person-types-list/person-types-list.component.scss
@@ -0,0 +1,19 @@
+.person-types-grid-wrapper {
+ position: relative;
+}
+
+.person-types-details {
+ margin-top: 20px;
+}
+
+.ag-grid-height-edit {
+ height: calc(100vh - 450px);
+}
+
+.ag-grid-height-list {
+ height: calc(100vh - 200px);
+}
+
+.new-button {
+ margin-right: 20px;
+}
diff --git a/src/app/pages/admin/person-types/person-types-list/person-types-list.component.spec.ts b/src/app/pages/admin/person-types/person-types-list/person-types-list.component.spec.ts
new file mode 100644
index 0000000..ae6cc76
--- /dev/null
+++ b/src/app/pages/admin/person-types/person-types-list/person-types-list.component.spec.ts
@@ -0,0 +1,42 @@
+import { PersonType } from '@shared/models';
+import { PersonTypesListComponent } from '@pages/admin/person-types/person-types-list/person-types-list.component';
+
+describe('PersonTypesListComponent', () => {
+ let component: PersonTypesListComponent;
+ const sandbox: any = {
+ setDisplayForm: () => {},
+ loadPersonType: () => {},
+ deletePersonType: () => {},
+ };
+
+ beforeEach(() => {
+ component = new PersonTypesListComponent(sandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should initialize gridOptions context', () => {
+ component.ngOnInit();
+ expect(component.gridOptions.context.icons.edit).toBeTruthy();
+ expect(component.gridOptions.context.icons.delete).toBeTruthy();
+ });
+
+ it('should call appropriate functions for edit event', () => {
+ const spy1: any = spyOn(sandbox, 'setDisplayForm');
+ const spy2: any = spyOn(sandbox, 'loadPersonType');
+ component.ngOnInit();
+ component.gridOptions.context.eventSubject.next({type: "edit", data: new PersonType()});
+ expect(spy1).toHaveBeenCalled();
+ expect(spy2).toHaveBeenCalled();
+ });
+
+ it('should call appropriate functions for delete event', () => {
+ const spy3: any = spyOn(sandbox, 'deletePersonType');
+ component.ngOnInit();
+ component.gridOptions.context.eventSubject.next({type: "delete", data: new PersonType()});
+ expect(spy3).toHaveBeenCalled();
+ });
+
+});
diff --git a/src/app/pages/admin/person-types/person-types-list/person-types-list.component.ts b/src/app/pages/admin/person-types/person-types-list/person-types-list.component.ts
new file mode 100644
index 0000000..985bdc2
--- /dev/null
+++ b/src/app/pages/admin/person-types/person-types-list/person-types-list.component.ts
@@ -0,0 +1,45 @@
+import { PERSON_TYPES_COLDEF } from '@pages/admin/person-types/person-types-list/person-types-list-column-definition';
+import { Component, OnInit, OnDestroy } from '@angular/core';
+import { BaseList } from '@shared/components/base-components/base.list';
+import { SetFilterComponent } from '@shared/filters/ag-grid/set-filter/set-filter.component';
+import { PersonTypesSandbox } from '@pages/admin/person-types/person-types.sandbox';
+import { Subscription } from 'rxjs';
+
+@Component({
+ selector: 'app-person-types-list',
+ templateUrl: './person-types-list.component.html',
+ styleUrls: ['./person-types-list.component.scss']
+})
+export class PersonTypesListComponent extends BaseList implements OnInit, OnDestroy {
+
+ public columnDefinition: any = PERSON_TYPES_COLDEF;
+ public frameworkComponents: { setFilterComponent: any };
+ private _subscription: Subscription;
+
+ constructor(public sandbox: PersonTypesSandbox) {
+ super();
+ this.frameworkComponents = { setFilterComponent: SetFilterComponent };
+ }
+
+ ngOnInit() {
+ this.gridOptions.context = {
+ ...this.gridOptions.context,
+ icons: { edit: true, delete: true }
+ };
+ this._subscription = this.gridOptions.context.eventSubject.subscribe(event => {
+ if (event.type === 'edit') {
+ this.sandbox.setDisplayForm();
+ this.sandbox.loadPersonType(event.data.id);
+ }
+ if (event.type === 'delete') {
+ this.sandbox.deletePersonType(event.data.id);
+ }
+ });
+ }
+
+ ngOnDestroy() {
+ this._subscription.unsubscribe();
+ }
+
+}
+
diff --git a/src/app/pages/admin/person-types/person-types.resolver.spec.ts b/src/app/pages/admin/person-types/person-types.resolver.spec.ts
new file mode 100644
index 0000000..4138387
--- /dev/null
+++ b/src/app/pages/admin/person-types/person-types.resolver.spec.ts
@@ -0,0 +1,29 @@
+import { async } from '@angular/core/testing';
+import { PersonTypesResolver } from '@pages/admin/person-types/person-types.resolver';
+
+describe('PersonTypesResolver', () => {
+ let component: PersonTypesResolver;
+ let sandbox: any;
+
+ beforeEach(async(() => {
+ sandbox = {
+ clear() {},
+ loadPersonTypes() {},
+ } as any;
+ }));
+
+ beforeEach(() => {
+ component = new PersonTypesResolver(sandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call loadPersonTypes', () => {
+ const spy = spyOn(sandbox, 'loadPersonTypes');
+ component.resolve();
+ expect(spy).toHaveBeenCalled();
+ });
+
+});
diff --git a/src/app/pages/admin/person-types/person-types.resolver.ts b/src/app/pages/admin/person-types/person-types.resolver.ts
new file mode 100644
index 0000000..e68f6c9
--- /dev/null
+++ b/src/app/pages/admin/person-types/person-types.resolver.ts
@@ -0,0 +1,15 @@
+import { PersonTypesSandbox } from '@pages/admin/person-types/person-types.sandbox';
+import { Observable } from 'rxjs';
+import { Injectable } from '@angular/core';
+import { Resolve } from '@angular/router';
+import { ILoadPersonTypesSuccess } from '@shared/store/actions/admin/person-types.action';
+
+@Injectable()
+export class PersonTypesResolver implements Resolve<any> {
+
+ constructor(private sandbox: PersonTypesSandbox) {}
+
+ public resolve(): Observable<ILoadPersonTypesSuccess> {
+ return this.sandbox.loadPersonTypes();
+ }
+}
diff --git a/src/app/pages/admin/person-types/person-types.sandbox.spec.ts b/src/app/pages/admin/person-types/person-types.sandbox.spec.ts
new file mode 100644
index 0000000..97efced
--- /dev/null
+++ b/src/app/pages/admin/person-types/person-types.sandbox.spec.ts
@@ -0,0 +1,84 @@
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { PersonTypesSandbox } from '@pages/admin/person-types/person-types.sandbox';
+import { Store, ActionsSubject } from '@ngrx/store';
+import { State } from '@shared/store';
+import { UtilService } from '@shared/utility/utility.service';
+import { of } from 'rxjs';
+import { Router } from '@angular/router';
+import * as personTypesActions from '@shared/store/actions/admin/person-types.action';
+import { PersonType } from '@shared/models';
+
+describe('PersonTypesSandbox', () => {
+ let service: PersonTypesSandbox;
+ let appState: Store<State>;
+ let actionSubject: ActionsSubject;
+ let utilService: UtilService;
+ let router: Router;
+ let modalService: NgbModal;
+
+ beforeEach(() => {
+ appState = { dispatch: () => {}, pipe: () => of(true), select: () => of(true) } as any;
+ actionSubject = { pipe: () => of(true) } as any;
+ utilService = { displayNotification() {} } as any;
+ router = { navigateByUrl() {} } as any;
+ modalService = { open() {} } as any;
+ spyOn(appState, 'dispatch').and.callFake(() => {});
+
+ service = new PersonTypesSandbox(appState, actionSubject, router, utilService, modalService);
+ });
+
+ it('should create PersonTypesSandbox service', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should set DisplayForm property', () => {
+ service.setDisplayForm();
+ expect(service.displayForm).toBeTruthy();
+ });
+
+ it('should dispatch loadPersonTypes Action via loadPersonTypes()', () => {
+ service.loadPersonTypes();
+ expect(appState.dispatch).toHaveBeenCalledWith(personTypesActions.loadPersonTypes());
+ });
+
+ it('should dispatch loadPersonType Action via loadPersonType(id)', () => {
+ service.loadPersonType('x');
+ expect(appState.dispatch).toHaveBeenCalledWith(personTypesActions.loadPersonType({ payload: 'x' }));
+ });
+
+ it('should call dispatch for saving an person type', () => {
+ service.currentFormState = {isValid: true} as any;
+ service.savePersonType();
+ expect(appState.dispatch).toHaveBeenCalledWith(personTypesActions.savePersonType({
+ payload: new PersonType()
+ })
+ );
+ });
+
+ it('should clear form via clear()', () => {
+ service['clear']();
+ expect(service.displayForm).toBe(false);
+ });
+
+ it('should open modal before deleting a PersonType', () => {
+ spyOn(service['modalService'], 'open')
+ .and.returnValue({componentInstance: {title: ''}, result: {then: () => of(true)}} as any);
+ service.deletePersonType('x');
+ expect(modalService.open).toHaveBeenCalled();
+ });
+
+ it('should clear form state when current change is canceled and form state is pristine', () => {
+ let spy = spyOn(service,'clear');
+ service.currentFormState = {isPristine: true} as any;
+ service.cancel();
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should open modal when current change is canceled and form state is not pristine', () => {
+ spyOn(service['modalService'], 'open')
+ .and.returnValue({componentInstance: {title: ''}, result: {then: () => of(true)}} as any);
+ service.currentFormState = {isPristine: false} as any;
+ service.cancel();
+ expect(modalService.open).toHaveBeenCalled();
+ });
+});
diff --git a/src/app/pages/admin/person-types/person-types.sandbox.ts b/src/app/pages/admin/person-types/person-types.sandbox.ts
new file mode 100644
index 0000000..77909dd
--- /dev/null
+++ b/src/app/pages/admin/person-types/person-types.sandbox.ts
@@ -0,0 +1,132 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { UtilService } from '@shared/utility/utility.service';
+import { Injectable } from '@angular/core';
+import { Store, ActionsSubject } from '@ngrx/store';
+import { Observable } from 'rxjs';
+import { BaseSandbox } from '@shared/sandbox/base.sandbox';
+import * as store from '@shared/store';
+import * as personTypesActions from '@shared/store/actions/admin/person-types.action';
+import * as personTypesFormReducer from '@shared/store/reducers/admin/person-types-details-form.reducer';
+import { PersonType } from '@shared/models';
+import { FormGroupState, SetValueAction, ResetAction, MarkAsTouchedAction } from 'ngrx-forms';
+import { ofType } from '@ngrx/effects';
+import { Router } from '@angular/router';
+import { takeUntil, take } from 'rxjs/operators';
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { SafetyQueryDialogComponent } from '@shared/components/dialogs/safety-query-dialog/safety-query-dialog.component';
+import { ILoadPersonTypesSuccess } from '@shared/store/actions/admin/person-types.action';
+
+@Injectable()
+export class PersonTypesSandbox extends BaseSandbox {
+
+ public personTypes$ = this.appState$.select(store.getPersonTypesData);
+ public formState$ = this.appState$.select(store.getPersonTypesDetails);
+ public currentFormState: FormGroupState<PersonType>;
+ public displayForm: boolean = false;
+
+ constructor(
+ protected appState$: Store<store.State>,
+ protected actionsSubject: ActionsSubject,
+ protected router: Router,
+ protected utilService: UtilService,
+ protected modalService: NgbModal
+ ) {
+ super(appState$);
+ }
+
+ public setDisplayForm(): void {
+ this.clear();
+ this.appState$.dispatch(new MarkAsTouchedAction(personTypesFormReducer.FORM_ID));
+ this.displayForm = true;
+ }
+
+ public loadPersonTypes(): Observable<ILoadPersonTypesSuccess> {
+ this.appState$.dispatch(personTypesActions.loadPersonTypes());
+ return this.actionsSubject.pipe(ofType(personTypesActions.loadPersonTypesSuccess), take(1));
+ }
+
+ public loadPersonType(id: string): void {
+ this.appState$.dispatch(
+ personTypesActions.loadPersonType({ payload: id })
+ );
+ }
+
+ public deletePersonType(id: string): void {
+ const modalRef = this.modalService.open(SafetyQueryDialogComponent);
+ modalRef.componentInstance.title = 'ConfirmDialog.Action.delete';
+ modalRef.componentInstance.body = 'ConfirmDialog.Deletion';
+ modalRef.result.then(() => {
+ this.appState$.dispatch(
+ personTypesActions.deletePersonType({ payload: id })
+ );
+ this.clear();
+ }, () => {
+ });
+ }
+
+ public cancel(): void {
+ if (!this.currentFormState.isPristine) {
+ const modalRef = this.modalService.open(SafetyQueryDialogComponent);
+ modalRef.componentInstance.title = 'ConfirmDialog.Action.edit';
+ modalRef.componentInstance.body = 'ConfirmDialog.Content';
+ modalRef.result.then(() => {
+ this.clear();
+ }, () => {
+ });
+ } else {
+ this.clear();
+ }
+ }
+
+ clear(): void {
+ this.appState$.dispatch(
+ new SetValueAction(
+ personTypesFormReducer.FORM_ID,
+ personTypesFormReducer.INITIAL_STATE.value
+ )
+ );
+ this.appState$.dispatch(new ResetAction(personTypesFormReducer.FORM_ID));
+ this.displayForm = false;
+ }
+
+ public savePersonType(): void {
+ if (this.currentFormState.isValid) {
+ this.appState$.dispatch(
+ personTypesActions.savePersonType({
+ payload: new PersonType(this.currentFormState.value)
+ })
+ );
+ this.actionsSubject
+ .pipe(
+ ofType(personTypesActions.savePersonTypeSuccess),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe(() => {
+ this.clear();
+ });
+ } else {
+ this.utilService.displayNotification(
+ 'MandatoryFieldError',
+ 'error'
+ );
+ }
+ }
+
+ public registerEvents(): void {
+ this.formState$.pipe(takeUntil(this._endSubscriptions$)).subscribe(
+ (formState: FormGroupState<PersonType>) =>
+ (this.currentFormState = formState)
+ )
+ }
+}
diff --git a/src/app/pages/admin/person-types/person-types.service.spec.ts b/src/app/pages/admin/person-types/person-types.service.spec.ts
new file mode 100644
index 0000000..bb99613
--- /dev/null
+++ b/src/app/pages/admin/person-types/person-types.service.spec.ts
@@ -0,0 +1,24 @@
+import { PersonType } from '@shared/models';
+import { PersonTypesService } from '@pages/admin/person-types/person-types.service';
+
+describe('PersonTypesService', () => {
+ let service: PersonTypesService;
+
+ beforeEach(() => {
+ });
+
+ it('should transform list', () => {
+ const response = [new PersonType()];
+ response[0].type = 'Herr';
+
+ expect(PersonTypesService.gridAdapter(response)[0].type).toBe('Herr');
+ });
+
+
+ it('should transform details', () => {
+ const response: any = { type: 'Herr'};
+ const item = PersonTypesService.itemAdapter(response);
+
+ expect(item.type).toBe(response.type);
+ });
+});
diff --git a/src/app/pages/admin/person-types/person-types.service.ts b/src/app/pages/admin/person-types/person-types.service.ts
new file mode 100644
index 0000000..99e5a39
--- /dev/null
+++ b/src/app/pages/admin/person-types/person-types.service.ts
@@ -0,0 +1,14 @@
+import { Injectable } from '@angular/core';
+import { PersonType } from '@shared/models';
+
+@Injectable()
+export class PersonTypesService {
+
+ static gridAdapter(response: any): Array<PersonType> {
+ return response.map(personType => new PersonType(personType));
+ }
+
+ static itemAdapter(response: any): PersonType {
+ return new PersonType(response);
+ }
+}
diff --git a/src/app/pages/admin/salutations/salutations-api-client.ts b/src/app/pages/admin/salutations/salutations-api-client.ts
index 54f0d04..21ac21f 100644
--- a/src/app/pages/admin/salutations/salutations-api-client.ts
+++ b/src/app/pages/admin/salutations/salutations-api-client.ts
@@ -14,7 +14,7 @@
import { Injectable } from '@angular/core';
import { HttpService, GET, Adapter, DefaultHeaders, Path, PUT, Body, POST, DELETE } from '@shared/asyncServices/http';
import { Observable } from 'rxjs';
-import { Salutation } from '@app/shared/models';
+import { Salutation } from '@shared/models';
@Injectable()
@DefaultHeaders({
@@ -22,63 +22,35 @@
'Content-Type': 'application/json',
})
export class SalutationsApiClient extends HttpService {
- public getSalutations(): Observable<any> {
- return this._getSalutations();
- }
- /**
- * Retrieves all salutations
- */
@GET('/salutations')
@Adapter(SalutationsService.gridAdapter)
- private _getSalutations(): Observable<any> {
+ public getSalutations(): Observable<Array<Salutation>> {
return null;
}
- /**
- * Retrieves salutation details by id
- *
- * @param id
- */
@GET('/salutations/{id}')
@Adapter(SalutationsService.salutationAdapter)
- public getSalutationDetails(@Path('id') id: string): Observable<any> {
+ public getSalutationDetails(@Path('id') id: string): Observable<Salutation> {
return null;
}
- /**
- * Saves edited salutation by id
- *
- * @param id
- */
@PUT('/salutations/{id}')
@Adapter(SalutationsService.salutationAdapter)
public putSalutation(@Path('id') id: string, @Body() salutation: Salutation): Observable<Salutation> {
return null;
}
- /**
- * Saves new salutation
- *
- * @param id
- */
@POST('/salutations')
@Adapter(SalutationsService.salutationAdapter)
public postSalutation(@Body() newSalutation: Salutation): Observable<Salutation> {
return null;
}
- /**
- * Deletes by a given id
- *
- * @param id
- */
@DELETE('/salutations/{id}')
@Adapter(SalutationsService.salutationAdapter)
public deleteSalutation(@Path('id') id: string): Observable<void> {
return null;
}
-
-
}
diff --git a/src/app/pages/admin/salutations/salutations-details/salutations-details.component.html b/src/app/pages/admin/salutations/salutations-details/salutations-details.component.html
index 46595d8..2c4a6e7 100644
--- a/src/app/pages/admin/salutations/salutations-details/salutations-details.component.html
+++ b/src/app/pages/admin/salutations/salutations-details/salutations-details.component.html
@@ -13,58 +13,51 @@
<form [ngrxFormState]="salutationsSandbox.formState$ | async">
<h4>{{ 'Salutations.DetailsTitle' | translate }}</h4>
<div>
- <div class="logCodeDetails-contentWrapper">
-
- <!-- type -->
- <div class="form-group row">
- <label for="salutationTyp" class="col-sm-2 col-form-label">{{ 'Salutations.Type' | translate }}</label>
- <div class="col-sm-6">
- <input type="text"
- required
- maxlength="30"
- class="form-control"
- id="salutationTyp"
- [ngrxFormControlState]="((salutationsSandbox.formState$ | async)?.controls)['type']"
- autocomplete="off"
- />
- </div>
- </div>
-
- <!-- description -->
- <div class="form-group row">
- <label for="salutationDescription" class="col-sm-2 col-form-label">{{ 'Salutations.Description' | translate }}</label>
- <div class="col-sm-6">
- <input type="text"
- required
- maxlength="255"
- class="form-control"
- id="salutationDescription"
- [ngrxFormControlState]="((salutationsSandbox.formState$ | async)?.controls)['description']"
- autocomplete="off"
- />
- </div>
- </div>
-
- <!-- buttons -->
- <button
- type="button"
- class="btn btn-primary btn-sm btn-success"
- (click)="salutationsSandbox.persistSalutation()"
- >
- {{ 'SaveBtn' | translate }}
- </button>
-
- <button
- type="button"
- class="btn btn-primary btn-sm"
- (click)="salutationsSandbox.cancel()"
- >
- {{ 'CancelBtn' | translate }}
- </button>
+ <!-- type -->
+ <div class="form-group row">
+ <label for="salutationTyp" class="col-sm-2 col-form-label">{{ 'Salutations.Type' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ required
+ maxlength="30"
+ class="form-control"
+ id="salutationTyp"
+ [ngrxFormControlState]="((salutationsSandbox.formState$ | async)?.controls)['type']"
+ autocomplete="off"
+ />
</div>
+ </div>
- <app-spinner
- [isRunning]="salutationsSandbox.salutationsLoading$ | async"
- ></app-spinner>
+ <!-- description -->
+ <div class="form-group row">
+ <label for="salutationDescription" class="col-sm-2 col-form-label">{{ 'Salutations.Description' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ required
+ maxlength="255"
+ class="form-control"
+ id="salutationDescription"
+ [ngrxFormControlState]="((salutationsSandbox.formState$ | async)?.controls)['description']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- buttons -->
+ <button
+ type="button"
+ class="btn btn-primary btn-sm btn-success"
+ (click)="salutationsSandbox.saveSalutation()"
+ >
+ {{ 'SaveBtn' | translate }}
+ </button>
+
+ <button
+ type="button"
+ class="btn btn-primary btn-sm"
+ (click)="salutationsSandbox.cancel()"
+ >
+ {{ 'CancelBtn' | translate }}
+ </button>
</div>
</form>
diff --git a/src/app/pages/admin/salutations/salutations-details/salutations-details.component.scss b/src/app/pages/admin/salutations/salutations-details/salutations-details.component.scss
index cebbf45..5562616 100644
--- a/src/app/pages/admin/salutations/salutations-details/salutations-details.component.scss
+++ b/src/app/pages/admin/salutations/salutations-details/salutations-details.component.scss
@@ -10,11 +10,9 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
- .logCodeDetails-contentWrapper {
- margin-top: 20px;
- position: relative;
+ button {
+ margin: 20px 10px 10px 0;
}
-
-button {
- margin: 10px 10px 10px 0;
+h4 {
+ padding-bottom: 15px;
}
diff --git a/src/app/pages/admin/salutations/salutations-details/salutations-details.component.spec.ts b/src/app/pages/admin/salutations/salutations-details/salutations-details.component.spec.ts
index 4d076ac..595b4de 100644
--- a/src/app/pages/admin/salutations/salutations-details/salutations-details.component.spec.ts
+++ b/src/app/pages/admin/salutations/salutations-details/salutations-details.component.spec.ts
@@ -10,17 +10,35 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { SalutationsDetailsComponent } from '@app/pages/admin/salutations/salutations-details/salutations-details.component';
+import { SalutationsDetailsComponent } from '@pages/admin/salutations/salutations-details/salutations-details.component';
+import { SalutationsSandbox } from '@pages/admin/salutations/salutations.sandbox';
describe('SalutationsDetailsComponent', () => {
let component: SalutationsDetailsComponent;
- const sandbox: any = {};
+ let sandbox: SalutationsSandbox;
- beforeEach(() => {
- component = new SalutationsDetailsComponent(sandbox);
- });
+beforeEach(() => {
+ sandbox = {
+ registerEvents() {},
+ endSubscriptions() {},
+ clear() {},
+ } as any;
+ component = new SalutationsDetailsComponent(sandbox);
+});
- it('should create', () => {
- expect(component).toBeTruthy();
- });
+it('should create', () => {
+ expect(component).toBeTruthy();
+});
+
+it('should registerEvents OnInit', () => {
+ let spy = spyOn(sandbox,'registerEvents');
+ component.ngOnInit();
+ expect(spy).toHaveBeenCalled();
+});
+
+it('should endSubscriptions OnDestroy', () => {
+ let spy = spyOn(sandbox,'endSubscriptions');
+ component.ngOnDestroy();
+ expect(spy).toHaveBeenCalled();
+});
});
diff --git a/src/app/pages/admin/salutations/salutations-details/salutations-details.component.ts b/src/app/pages/admin/salutations/salutations-details/salutations-details.component.ts
index 14eaa63..fb0c0ac 100644
--- a/src/app/pages/admin/salutations/salutations-details/salutations-details.component.ts
+++ b/src/app/pages/admin/salutations/salutations-details/salutations-details.component.ts
@@ -10,18 +10,27 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { SalutationsSandbox } from '@app/pages/admin/salutations/salutations.sandbox';
-import { Component } from '@angular/core';
+import { SalutationsSandbox } from '@pages/admin/salutations/salutations.sandbox';
+import { Component, OnInit, OnDestroy } from '@angular/core';
@Component({
selector: 'app-salutations-details',
templateUrl: './salutations-details.component.html',
styleUrls: ['./salutations-details.component.scss']
})
-export class SalutationsDetailsComponent {
+export class SalutationsDetailsComponent implements OnInit, OnDestroy {
constructor(
public salutationsSandbox: SalutationsSandbox,
) { }
+ ngOnInit() {
+ this.salutationsSandbox.registerEvents();
+ }
+
+ ngOnDestroy() {
+ this.salutationsSandbox.clear();
+ this.salutationsSandbox.endSubscriptions();
+ }
+
}
diff --git a/src/app/pages/admin/salutations/salutations-list/salutations-list-column-definition.ts b/src/app/pages/admin/salutations/salutations-list/salutations-list-column-definition.ts
index b3549e6..cdd1b05 100644
--- a/src/app/pages/admin/salutations/salutations-list/salutations-list-column-definition.ts
+++ b/src/app/pages/admin/salutations/salutations-list/salutations-list-column-definition.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -10,31 +10,32 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { IconCellRendererComponent } from '@app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component';
+import { IconCellRendererComponent } from '@shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component';
export const SALUTATIONS_COLDEF = [
{
field: 'type',
headerName: 'Salutations.Type',
sortable: true,
- filter: 'setFilterComponent'
+ filter: 'setFilterComponent',
},
{
field: 'description',
headerName: 'Salutations.Description',
sortable: true,
- filter: 'setFilterComponent'
+ filter: 'setFilterComponent',
},
{
field: 'tools',
- headerName: 'Tools',
+ headerName: ' ',
pinned: 'right',
- maxWidth: 100,
+ maxWidth: 110,
+ minWidth: 110,
lockPosition: true,
sortable: false,
filter: false,
suppressMenu: true,
suppressSizeToFit: true,
- cellRendererFramework: IconCellRendererComponent
- }
+ cellRendererFramework: IconCellRendererComponent,
+ },
];
diff --git a/src/app/pages/admin/salutations/salutations-list/salutations-list.component.html b/src/app/pages/admin/salutations/salutations-list/salutations-list.component.html
index b57f930..b464c08 100644
--- a/src/app/pages/admin/salutations/salutations-list/salutations-list.component.html
+++ b/src/app/pages/admin/salutations/salutations-list/salutations-list.component.html
@@ -15,7 +15,7 @@
<span>{{ 'Salutations.Title' | translate }}</span>
<div class="pull-right">
<button class="btn btn-primary new-button" (click)="salutationsSandbox.setDisplayForm()">
- Neu
+ {{ 'NewBtn' | translate }}
</button>
</div>
</div>
@@ -23,6 +23,7 @@
<ag-grid-angular
autoresizecolumns
class="ag-theme-balham ag-grid-height"
+ [ngClass]="salutationsSandbox.displayForm ? 'ag-grid-height-edit' : 'ag-grid-height-list'"
[gridOptions]="gridOptions"
[columnDefs]="columnDefinition"
[rowSelection]="'single'"
diff --git a/src/app/pages/admin/salutations/salutations-list/salutations-list.component.scss b/src/app/pages/admin/salutations/salutations-list/salutations-list.component.scss
index b71958d..f493401 100644
--- a/src/app/pages/admin/salutations/salutations-list/salutations-list.component.scss
+++ b/src/app/pages/admin/salutations/salutations-list/salutations-list.component.scss
@@ -18,10 +18,14 @@
margin-top: 20px;
}
-.ag-grid-height {
+.ag-grid-height-edit {
height: calc(100vh - 450px);
}
+.ag-grid-height-list {
+ height: calc(100vh - 200px);
+}
+
.new-button {
margin-right: 20px;
}
diff --git a/src/app/pages/admin/salutations/salutations-list/salutations-list.component.ts b/src/app/pages/admin/salutations/salutations-list/salutations-list.component.ts
index 5d23807..449d191 100644
--- a/src/app/pages/admin/salutations/salutations-list/salutations-list.component.ts
+++ b/src/app/pages/admin/salutations/salutations-list/salutations-list.component.ts
@@ -12,19 +12,22 @@
********************************************************************************/
import { SalutationsSandbox } from '@pages/admin/salutations/salutations.sandbox';
import { SALUTATIONS_COLDEF } from '@pages/admin/salutations/salutations-list/salutations-list-column-definition';
-import { Component, OnInit } from '@angular/core';
-import { BaseList } from '@app/shared/components/base-components/base.list';
-import { SetFilterComponent } from '@app/shared/filters/ag-grid/set-filter/set-filter.component';
+import { Component, OnInit, OnDestroy } from '@angular/core';
+import { BaseList } from '@shared/components/base-components/base.list';
+import { SetFilterComponent } from '@shared/filters/ag-grid/set-filter/set-filter.component';
+import { Subscription } from 'rxjs';
+
@Component({
selector: 'app-salutations-list',
templateUrl: './salutations-list.component.html',
styleUrls: ['./salutations-list.component.scss']
})
-export class SalutationsListComponent extends BaseList implements OnInit {
+export class SalutationsListComponent extends BaseList implements OnInit, OnDestroy {
public columnDefinition: any = SALUTATIONS_COLDEF;
public frameworkComponents: { setFilterComponent: any };
+ private _subscription: Subscription;
constructor(public salutationsSandbox: SalutationsSandbox) {
super();
@@ -32,13 +35,11 @@
}
ngOnInit() {
-
this.gridOptions.context = {
...this.gridOptions.context,
icons: { edit: true, delete: true }
};
-
- this.gridOptions.context.eventSubject.subscribe(event => {
+ this._subscription = this.gridOptions.context.eventSubject.subscribe(event => {
if (event.type === 'edit') {
this.salutationsSandbox.setDisplayForm();
this.salutationsSandbox.loadSalutation(event.data.id);
@@ -47,6 +48,10 @@
this.salutationsSandbox.deleteSalutation(event.data.id);
}
});
-
}
+
+ ngOnDestroy() {
+ this._subscription.unsubscribe();
+ }
+
}
diff --git a/src/app/pages/admin/salutations/salutations.resolver.spec.ts b/src/app/pages/admin/salutations/salutations.resolver.spec.ts
new file mode 100644
index 0000000..ad69846
--- /dev/null
+++ b/src/app/pages/admin/salutations/salutations.resolver.spec.ts
@@ -0,0 +1,29 @@
+import { async } from '@angular/core/testing';
+import { SalutationsResolver } from '@pages/admin/salutations/salutations.resolver';
+
+describe('SalutationsResolver', () => {
+ let component: SalutationsResolver;
+ let salutationsSandbox: any;
+
+ beforeEach(async(() => {
+ salutationsSandbox = {
+ clear() {},
+ loadSalutations() {},
+ } as any;
+ }));
+
+ beforeEach(() => {
+ component = new SalutationsResolver(salutationsSandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call loadSalutations', () => {
+ const spy = spyOn(salutationsSandbox, 'loadSalutations');
+ component.resolve();
+ expect(spy).toHaveBeenCalled();
+ });
+
+});
diff --git a/src/app/pages/admin/salutations/salutations.resolver.ts b/src/app/pages/admin/salutations/salutations.resolver.ts
index 3895eff..78538c2 100644
--- a/src/app/pages/admin/salutations/salutations.resolver.ts
+++ b/src/app/pages/admin/salutations/salutations.resolver.ts
@@ -14,16 +14,14 @@
import { Observable } from 'rxjs';
import { Injectable } from '@angular/core';
import { Resolve } from '@angular/router';
+import { ILoadSalutationsSuccess } from '@shared/store/actions/admin/salutations.action';
@Injectable()
-export class SalutationsResolver implements Resolve<any> {
+export class SalutationsResolver implements Resolve<ILoadSalutationsSuccess> {
- constructor(private redispatchMonitoringSandbox: SalutationsSandbox) {}
+ constructor(private salutationsSandbox: SalutationsSandbox) {}
- /**
- * Resolver
- */
public resolve(): Observable<any> {
- return this.redispatchMonitoringSandbox.loadSalutations();
+ return this.salutationsSandbox.loadSalutations();
}
}
diff --git a/src/app/pages/admin/salutations/salutations.sandbox.spec.ts b/src/app/pages/admin/salutations/salutations.sandbox.spec.ts
index 24ce1fe..5e5a70d 100644
--- a/src/app/pages/admin/salutations/salutations.sandbox.spec.ts
+++ b/src/app/pages/admin/salutations/salutations.sandbox.spec.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -12,15 +12,16 @@
********************************************************************************/
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { SalutationsSandbox } from '@pages/admin/salutations/salutations.sandbox';
-import { Store, ActionsSubject} from '@ngrx/store';
+import { Store, ActionsSubject } from '@ngrx/store';
import { State } from '@shared/store';
import { UtilService } from '@shared/utility/utility.service';
import { of } from 'rxjs';
import { Router } from '@angular/router';
-import * as salutationsActions from '@shared/store/actions/salutations.action';
+import * as salutationsActions from '@shared/store/actions/admin/salutations.action';
+import { Salutation } from '@shared/models';
describe('SalutationsSandbox', () => {
- let service: SalutationsSandbox = {} as any;
+ let service: SalutationsSandbox;
let appState: Store<State>;
let actionSubject: ActionsSubject;
let utilService: UtilService;
@@ -28,8 +29,9 @@
let modalService: NgbModal;
beforeEach(() => {
- appState = { dispatch:()=> {}, pipe: () => of(true), select:()=> of(true) } as any;
- actionSubject = { pipe: () => of(true) } as any;
+ appState = { dispatch: () => {}, pipe: () => of(true), select: () => of(true) } as any;
+ actionSubject = { pipe: () => of(true) } as any;
+ utilService = { displayNotification() {} } as any;
router = { navigateByUrl() {} } as any;
modalService = { open() {} } as any;
spyOn(appState, 'dispatch').and.callFake(() => {});
@@ -56,9 +58,39 @@
expect(appState.dispatch).toHaveBeenCalledWith(salutationsActions.loadSalutation({ payload: 'x' }));
});
- // it('should xxx', () => {
- // spyOn(modalService, 'open');
- // service.deleteSalutation('x');
- // expect(appState.dispatch).toHaveBeenCalledWith(salutationsActions.deleteSalutation({ payload: 'x' }));
- // });
+ it('should call dispatch for saving an salutation', () => {
+ service.currentFormState = {isValid: true} as any;
+ service.saveSalutation();
+ expect(appState.dispatch).toHaveBeenCalledWith(salutationsActions.saveSalutation({
+ payload: new Salutation()
+ })
+ );
+ });
+
+ it('should clear form via clear()', () => {
+ service['clear']();
+ expect(service.displayForm).toBe(false);
+ });
+
+ it('should open modal before deleting a salutation', () => {
+ spyOn(service['modalService'], 'open')
+ .and.returnValue({componentInstance: {title: ''}, result: {then: () => of(true)}} as any);
+ service.deleteSalutation('x');
+ expect(modalService.open).toHaveBeenCalled();
+ });
+
+ it('should clear form state when current change is canceled and form state is pristine', () => {
+ let spy = spyOn(service,'clear');
+ service.currentFormState = {isPristine: true} as any;
+ service.cancel();
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should open modal when current change is canceled and form state is not pristine', () => {
+ spyOn(service['modalService'], 'open')
+ .and.returnValue({componentInstance: {title: ''}, result: {then: () => of(true)}} as any);
+ service.currentFormState = {isPristine: false} as any;
+ service.cancel();
+ expect(modalService.open).toHaveBeenCalled();
+ });
});
diff --git a/src/app/pages/admin/salutations/salutations.sandbox.ts b/src/app/pages/admin/salutations/salutations.sandbox.ts
index 7126752..49e1db4 100644
--- a/src/app/pages/admin/salutations/salutations.sandbox.ts
+++ b/src/app/pages/admin/salutations/salutations.sandbox.ts
@@ -16,29 +16,26 @@
import { Observable } from 'rxjs';
import { BaseSandbox } from '@shared/sandbox/base.sandbox';
import * as store from '@shared/store';
-import * as salutationsActions from '@shared/store/actions/salutations.action';
-import * as salutationFormReducer from '@shared/store/reducers/salutations/salutations-details-form.reducer';
+import * as salutationsActions from '@shared/store/actions/admin/salutations.action';
+import * as salutationFormReducer from '@shared/store/reducers/admin/salutations-details-form.reducer';
import { Salutation } from '@shared/models';
import { FormGroupState, SetValueAction, ResetAction, MarkAsTouchedAction } from 'ngrx-forms';
import { ofType } from '@ngrx/effects';
import { Router } from '@angular/router';
import { takeUntil, take } from 'rxjs/operators';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
-import { SafetyQueryDialogComponent } from '@app/shared/components/dialogs/safety-query-dialog/safety-query-dialog.component';
+import { SafetyQueryDialogComponent } from '@shared/components/dialogs/safety-query-dialog/safety-query-dialog.component';
+import { ILoadSalutationsSuccess } from '@shared/store/actions/admin/salutations.action';
@Injectable()
export class SalutationsSandbox extends BaseSandbox {
public salutations$ = this.appState$.select(store.getSalutationsData);
- public salutationsLoading$ = this.appState$.select(store.getSalutationsLoading);
public formState$ = this.appState$.select(store.getSalutationDetails);
public currentFormState: FormGroupState<Salutation>;
public displayForm: boolean = false;
- /**
- * Sandbox constructor
- */
constructor(
protected appState$: Store<store.State>,
protected actionsSubject: ActionsSubject,
@@ -47,36 +44,25 @@
protected modalService: NgbModal
) {
super(appState$);
- this._registerEvents();
}
- /**
- * Display form
- */
public setDisplayForm(): void {
+ this.clear();
+ this.appState$.dispatch(new MarkAsTouchedAction(salutationFormReducer.FORM_ID));
this.displayForm = true;
}
- /**
- * Loads list from the server
- */
- public loadSalutations(): Observable<any> {
+ public loadSalutations(): Observable<ILoadSalutationsSuccess> {
this.appState$.dispatch(salutationsActions.loadSalutations());
return this.actionsSubject.pipe(ofType(salutationsActions.loadSalutationsSuccess), take(1));
}
- /**
- * Loads salutation from the server
- */
public loadSalutation(id: string): void {
this.appState$.dispatch(
salutationsActions.loadSalutation({ payload: id })
);
}
- /**
- * Deletes salutation
- */
public deleteSalutation(id: string): void {
const modalRef = this.modalService.open(SafetyQueryDialogComponent);
modalRef.componentInstance.title = 'ConfirmDialog.Action.delete';
@@ -85,13 +71,11 @@
this.appState$.dispatch(
salutationsActions.deleteSalutation({ payload: id })
);
+ this.clear();
}, () => {
});
}
- /**
- * Cancel
- */
public cancel(): void {
if (!this.currentFormState.isPristine) {
const modalRef = this.modalService.open(SafetyQueryDialogComponent);
@@ -106,9 +90,6 @@
}
}
- /**
- * Clear
- */
clear(): void {
this.appState$.dispatch(
new SetValueAction(
@@ -120,20 +101,16 @@
this.displayForm = false;
}
- /**
- * Persist
- */
- public persistSalutation(): void {
- this.appState$.dispatch(new MarkAsTouchedAction(salutationFormReducer.FORM_ID));
+ public saveSalutation(): void {
if (this.currentFormState.isValid) {
this.appState$.dispatch(
- salutationsActions.persistSalutation({
+ salutationsActions.saveSalutation({
payload: new Salutation(this.currentFormState.value)
})
);
this.actionsSubject
.pipe(
- ofType(salutationsActions.persistSalutationSuccess),
+ ofType(salutationsActions.saveSalutationSuccess),
takeUntil(this._endSubscriptions$)
)
.subscribe(() => {
@@ -147,10 +124,7 @@
}
}
- /**
- * subscribes to formState
- */
- private _registerEvents(): void {
+ public registerEvents(): void {
this.formState$.pipe(takeUntil(this._endSubscriptions$)).subscribe(
(formState: FormGroupState<Salutation>) =>
diff --git a/src/app/pages/admin/salutations/salutations.service.ts b/src/app/pages/admin/salutations/salutations.service.ts
index 5bb6a52..91ea398 100644
--- a/src/app/pages/admin/salutations/salutations.service.ts
+++ b/src/app/pages/admin/salutations/salutations.service.ts
@@ -13,27 +13,13 @@
import { Injectable } from '@angular/core';
import { Salutation } from '@shared/models';
-/**
- * Used to retrieve salutations
- *
- * @export
- * @class SalutationsService
- */
@Injectable()
export class SalutationsService {
- /**
- * Transforms grid data recieved from the API into array of model instances
- *
- * @param response
- */
+
static gridAdapter(response: any): Array<Salutation> {
return response.map(salutation => new Salutation(salutation));
}
- /**
- * Transforms api reponse into model instance
- *
- * @param response
- */
+
static salutationAdapter(response: any): Salutation {
return new Salutation(response);
}
diff --git a/src/app/pages/company/company-api-client.ts b/src/app/pages/company/company-api-client.ts
new file mode 100644
index 0000000..13b6d1b
--- /dev/null
+++ b/src/app/pages/company/company-api-client.ts
@@ -0,0 +1,174 @@
+/********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/
+import { Injectable } from '@angular/core';
+import { HttpService, GET, Path, Adapter, PUT, Body, DefaultHeaders, POST, DELETE } from '@shared/asyncServices/http';
+import { Observable } from 'rxjs';
+import { CompanyService } from '@pages/company/company.service';
+import { Company, CommunicationsData, Address } from '@shared/models';
+
+@Injectable()
+@DefaultHeaders({
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json',
+})
+export class CompanyApiClient extends HttpService {
+ /**
+ * Retrieves company details by a given contactId
+ *
+ * @param contactId
+ */
+ @GET('/companies/{contactId}')
+ @Adapter(CompanyService.companyDetailsAdapter)
+ public getCompanyDetails(@Path('contactId') contactId: string): Observable<Company> {
+ return null;
+ }
+
+ /**
+ * Change the company details by a given contactId
+ *
+ * @param contactId
+ * @param editedCompany
+ */
+ @PUT('/companies/{contactId}')
+ @Adapter(CompanyService.companyDetailsAdapter)
+ public putCompanyDetails(@Path('contactId') contactId: string, @Body() editedCompany: Company): Observable<Company> {
+ return null;
+ }
+
+ /**
+ * Saves new company details.
+ *
+ * @param newCompany
+ */
+ @POST('/companies')
+ @Adapter(CompanyService.companyDetailsAdapter)
+ public postCompanyDetails(@Body() newCompany: Company): Observable<Company> {
+ return null;
+ }
+
+ /**
+ * Retrieves communications data by a given contactId
+ *
+ * @param contactId
+ */
+ @GET('/contacts/{contactId}/communications')
+ @Adapter(CompanyService.communicationsDataAdapter)
+ public getCommunicationsData(@Path('contactId') contactId: string): Observable<CommunicationsData[]> {
+ return null;
+ }
+
+ /**
+ * Retrieves communications data details by a given contactId and communicationId
+ *
+ * @param contactId
+ * @param communicationId
+ */
+ @GET('/contacts/{contactId}/communications/{communicationId}')
+ @Adapter(CompanyService.communicationsDataDetailsAdapter)
+ public getCommunicationsDataDetails(@Path('contactId') contactId: string, @Path('communicationId') communicationId: string): Observable<CommunicationsData> {
+ return null;
+ }
+
+ /**
+ * Change the communications data details by a given communicationId
+ *
+ * @param contactId
+ * @param communicationId
+ * @param editedCommunicationsData
+ */
+ @PUT('/contacts/{contactId}/communications/{communicationId}')
+ @Adapter(CompanyService.communicationsDataDetailsAdapter)
+ public putCommunicationsDataDetails(@Path('contactId') contactId: string, @Path('communicationId') communicationId: string, @Body() editedCommunicationsData: CommunicationsData): Observable<CommunicationsData> {
+ return null;
+ }
+
+ /**
+ * Saves new communications details.
+ *
+ * @param contactId
+ * @param newcommunicationsData
+ */
+ @POST('/contacts/{contactId}/communications')
+ @Adapter(CompanyService.communicationsDataDetailsAdapter)
+ public postCommunicationsDataDetails(@Path('contactId') contactId: string, @Body() newcommunicationsData: CommunicationsData): Observable<CommunicationsData> {
+ return null;
+ }
+
+ /**
+ * Deletes by a given id
+ *
+ * @param contactId
+ * @param communicationId
+ */
+ @DELETE('/contacts/{contactId}/communications/{communicationId}')
+ @Adapter(CompanyService.communicationsDataDetailsAdapter)
+ public deleteCommunicationsData(@Path('contactId') contactId: string, @Path('communicationId') communicationId: string): Observable<void> {
+ return null;
+ }
+
+ /**
+* Retrieves contact details addresses by a given contactId
+*
+* @param contactId
+*/
+ @GET('/contacts/{contactId}/addresses')
+ @Adapter(CompanyService.addressesAdapter)
+ public getAddresses(@Path('contactId') contactId: string): Observable<Address[]> {
+ return null;
+ }
+
+ /**
+* Retrieves contact details addresses details by a given contactId and addressId
+*
+* @param contactId
+*/
+ @GET('/contacts/{contactId}/addresses/{addressId}')
+ @Adapter(CompanyService.addressesDetailsAdapter)
+ public getAddressesDetails(@Path('contactId') contactId: string, @Path('addressId') addressId: string): Observable<Address> {
+ return null;
+ }
+
+ /**
+ * Change the address details by a given addressId
+ *
+ * @param addressId
+ * @param editedAddress
+ */
+ @PUT('/contacts/{contactId}/addresses/{addressId}')
+ @Adapter(CompanyService.addressesDetailsAdapter)
+ public putAddressDetails(@Path('contactId') contactId: string, @Path('addressId') addressId: string, @Body() editedAdress: Address): Observable<Address> {
+ return null;
+ }
+
+ /**
+ * Saves new address details.
+ *
+ * @param newAddress
+ */
+ @POST('/contacts/{contactId}/addresses')
+ @Adapter(CompanyService.addressesDetailsAdapter)
+ public postAddressDetails(@Path('contactId') contactId: string, @Body() newExternalPersonAddress: Address): Observable<Address> {
+ return null;
+ }
+
+ /**
+ * Deletes by a given id
+ *
+ * @param id
+ */
+ @DELETE('/contacts/{contactId}/addresses/{addressId}')
+ @Adapter(CompanyService.addressesDetailsAdapter)
+ public deleteAddress(@Path('contactId') contactId: string, @Path('addressId') addressId: string): Observable<void> {
+ return null;
+ }
+}
diff --git a/src/app/pages/company/company-details/address-details/address-details.component.html b/src/app/pages/company/company-details/address-details/address-details.component.html
new file mode 100644
index 0000000..0ca3a88
--- /dev/null
+++ b/src/app/pages/company/company-details/address-details/address-details.component.html
@@ -0,0 +1,202 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<form [ngrxFormState]="companyDetailsSandbox.addressDetailsFormState$ | async">
+ <h4>{{createOrEditAddressData}}</h4>
+ <div>
+ <!-- type -->
+ <div class="form-group row">
+ <label for="addressTypeId" class="col-sm-5 col-form-label">{{ 'Address.AddressType' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ required
+ maxlength="255"
+ class="form-control"
+ id="addressTypeId"
+ [ngrxFormControlState]="((companyDetailsSandbox.addressDetailsFormState$ | async)?.controls)['addressTypeId']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- MainAddress -->
+ <div class="form-group row">
+ <label for="isMainAddress" class="col-sm-5 col-form-label">{{ 'Address.MainAddress' | translate }}</label>
+ <div class="col-sm-6" style="align-self: center;">
+ <input *ngIf="!companyDetailsSandbox.existMainAddress || companyDetailsSandbox.isCurrentAddressMainAddress"
+ type="checkbox"
+ class="form-check-input"
+ id="isMainAddress"
+ [ngrxFormControlState]="((companyDetailsSandbox.addressDetailsFormState$ | async)?.controls)['isMainAddress']"
+ />
+ <span *ngIf="companyDetailsSandbox.existMainAddress && !companyDetailsSandbox.isCurrentAddressMainAddress">(vorhanden)</span>
+ </div>
+ </div>
+
+ <!-- postCard -->
+ <div class="form-group row">
+ <label for="postcode" class="col-sm-5 col-form-label">{{ 'Address.Postcode' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="30"
+ class="form-control"
+ id="postcode"
+ [ngrxFormControlState]="((companyDetailsSandbox.addressDetailsFormState$ | async)?.controls)['postcode']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- community -->
+ <div class="form-group row">
+ <label for="community" class="col-sm-5 col-form-label">{{ 'Address.Community' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="community"
+ [ngrxFormControlState]="((companyDetailsSandbox.addressDetailsFormState$ | async)?.controls)['community']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- community-suffix -->
+ <div class="form-group row">
+ <label for="communitySuffix" class="col-sm-5 col-form-label">{{ 'Address.CommunitySuffix' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="communitySuffix"
+ [ngrxFormControlState]="((companyDetailsSandbox.addressDetailsFormState$ | async)?.controls)['communitySuffix']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- street -->
+ <div class="form-group row">
+ <label for="street" class="col-sm-5 col-form-label">{{ 'Address.Street' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="street"
+ [ngrxFormControlState]="((companyDetailsSandbox.addressDetailsFormState$ | async)?.controls)['street']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- housenumber -->
+ <div class="form-group row">
+ <label for="housenumber" class="col-sm-5 col-form-label">{{ 'Address.Housenumber' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="30"
+ class="form-control"
+ id="housenumber"
+ [ngrxFormControlState]="((companyDetailsSandbox.addressDetailsFormState$ | async)?.controls)['housenumber']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- wgs_84_zone -->
+ <div class="form-group row">
+ <label for="wgs84Zone" class="col-sm-5 col-form-label">{{ 'Address.Wgs84Zone' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="wgs84Zone"
+ [ngrxFormControlState]="((companyDetailsSandbox.addressDetailsFormState$ | async)?.controls)['wgs84Zone']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- longitude -->
+ <div class="form-group row">
+ <label for="longitude" class="col-sm-5 col-form-label">{{ 'Address.Longitude' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="longitude"
+ [ngrxFormControlState]="((companyDetailsSandbox.addressDetailsFormState$ | async)?.controls)['longitude']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- latitude -->
+ <div class="form-group row">
+ <label for="latitude" class="col-sm-5 col-form-label">{{ 'Address.Latitude' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="latitude"
+ [ngrxFormControlState]="((companyDetailsSandbox.addressDetailsFormState$ | async)?.controls)['latitude']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- url_map -->
+ <div class="form-group row">
+ <label for="urlMap" class="col-sm-5 col-form-label">{{ 'Address.UrlMap' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="urlMap"
+ [ngrxFormControlState]="((companyDetailsSandbox.addressDetailsFormState$ | async)?.controls)['urlMap']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- note -->
+ <div class="form-group row">
+ <label for="note" class="col-sm-5 col-form-label">{{ 'Address.Note' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="note"
+ [ngrxFormControlState]="((companyDetailsSandbox.addressDetailsFormState$ | async)?.controls)['note']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- buttons -->
+ <button
+ type="button"
+ class="btn btn-primary btn-sm btn-success"
+ (click)="companyDetailsSandbox.persistAddress()"
+ >
+ {{ 'SaveBtn' | translate }}
+ </button>
+
+ <button
+ type="button"
+ class="btn btn-primary btn-sm"
+ (click)="companyDetailsSandbox.closeAddressDataDetail()"
+ >
+ {{ 'CancelBtn' | translate }}
+ </button>
+ </div>
+</form >
diff --git a/src/app/pages/company/company-details/address-details/address-details.component.scss b/src/app/pages/company/company-details/address-details/address-details.component.scss
new file mode 100644
index 0000000..3ef9f91
--- /dev/null
+++ b/src/app/pages/company/company-details/address-details/address-details.component.scss
@@ -0,0 +1,27 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+button {
+ margin: 14px 0px 10px 15px;
+}
+h4 {
+ padding: 15px;
+ padding-top: 18px;
+}
+div.form-group.row {
+ padding-left: 15px;
+}
+
+#isMainAddress{
+ margin-left: 0px;
+ margin-top: 14px;
+}
diff --git a/src/app/pages/company/company-details/address-details/address-details.component.spec.ts b/src/app/pages/company/company-details/address-details/address-details.component.spec.ts
new file mode 100644
index 0000000..9da4223
--- /dev/null
+++ b/src/app/pages/company/company-details/address-details/address-details.component.spec.ts
@@ -0,0 +1,44 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { CompanyAddressDetailsComponent } from '@pages/company/company-details/address-details/address-details.component';
+
+describe('AddressDetailsComponent', () => {
+ let component: CompanyAddressDetailsComponent;
+ let companySandbox: any;
+
+ beforeEach(async(() => {
+ companySandbox = {
+ registerAddressEvents() {},
+ registerCompanyEvents() {},
+ endSubscriptions() {},
+ clearAddressData() {},
+ } as any;
+ }));
+
+ beforeEach(() => {
+ component = new CompanyAddressDetailsComponent(companySandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call registerAddressEvents and clearAddress onInit', () => {
+ const spy1 = spyOn(companySandbox, 'registerAddressEvents');
+ const spy2 = spyOn(companySandbox, 'clearAddressData');
+ component.ngOnInit();
+ expect(spy1).toHaveBeenCalled();
+ expect(spy2).toHaveBeenCalled();
+ });
+});
diff --git a/src/app/pages/company/company-details/address-details/address-details.component.ts b/src/app/pages/company/company-details/address-details/address-details.component.ts
new file mode 100644
index 0000000..ca3e88c
--- /dev/null
+++ b/src/app/pages/company/company-details/address-details/address-details.component.ts
@@ -0,0 +1,34 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { CompanyDetailsSandBox } from '@pages/company/company-details/company-details.sandbox';
+import { Component, OnInit, Input } from '@angular/core';
+
+@Component({
+ selector: 'app-company-address-details',
+ templateUrl: './address-details.component.html',
+ styleUrls: ['./address-details.component.scss']
+})
+export class CompanyAddressDetailsComponent implements OnInit {
+
+ @Input() createOrEditAddressData: string;
+
+ constructor(
+ public companyDetailsSandbox: CompanyDetailsSandBox,
+ ) { }
+
+ ngOnInit() {
+ this.companyDetailsSandbox.registerAddressEvents();
+ this.companyDetailsSandbox.clearAddressData();
+ }
+
+}
diff --git a/src/app/pages/company/company-details/address-list/address-list.component.html b/src/app/pages/company/company-details/address-list/address-list.component.html
new file mode 100644
index 0000000..9f167e5
--- /dev/null
+++ b/src/app/pages/company/company-details/address-list/address-list.component.html
@@ -0,0 +1,36 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<div class="diverse-options">
+ <div class="new-address">
+ <button class="btn btn-sm btn-primary" (click)="createNewAddressForm()">
+ {{ 'Address.NewAddress' | translate }}
+ </button>
+ </div>
+</div>
+
+
+<ag-grid-angular
+ autoresizecolumns
+ class="ag-theme-balham ag-grid-height"
+ style="width: 100%; height: 100%;"
+ [gridOptions]="gridOptions"
+ [rowData]="companyDetailsSandBox.addressList$ | async"
+ [columnDefs]="columnDefinition"
+ [rowSelection]="'single'"
+ [frameworkComponents]="frameworkComponents"
+>
+</ag-grid-angular>
+<app-spinner [isRunning]="companyDetailsSandBox.addressListLoading$ | async"></app-spinner>
+
+
+
diff --git a/src/app/pages/company/company-details/address-list/address-list.component.scss b/src/app/pages/company/company-details/address-list/address-list.component.scss
new file mode 100644
index 0000000..63a5ad3
--- /dev/null
+++ b/src/app/pages/company/company-details/address-list/address-list.component.scss
@@ -0,0 +1,27 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+ .diverse-options {
+ display: flex;
+ justify-content: flex-end;
+ align-content: center;
+ background-color: #f5f7f7;
+ border: 1px solid rgb(189, 195, 199);
+ padding: 7px 7px 5px 7px;
+ margin-bottom: 1px;
+}
+
+.diverse-options-item {
+ width: 400px;
+ padding-right: 7px;
+ border-right: solid 1px #ddd;
+}
diff --git a/src/app/pages/company/company-details/address-list/address-list.component.spec.ts b/src/app/pages/company/company-details/address-list/address-list.component.spec.ts
new file mode 100644
index 0000000..67ce5e6
--- /dev/null
+++ b/src/app/pages/company/company-details/address-list/address-list.component.spec.ts
@@ -0,0 +1,73 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { CompanyAddressListComponent } from '@pages/company/company-details/address-list/address-list.component';
+import { of } from 'rxjs/observable/of';
+
+describe('AddressListComponent', () => {
+ let component: CompanyAddressListComponent;
+ let companySandbox: any;
+
+ beforeEach(async(() => {
+ companySandbox = {
+ registerAddressEvents() {},
+ registerCompanyEvents() {},
+ endSubscriptions() {},
+ deleteAddress() {},
+ clearAddressData() {},
+ } as any;
+ }));
+
+ beforeEach(() => {
+ component = new CompanyAddressListComponent(companySandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should define gridOptions onInit', () => {
+ component.ngOnInit();
+
+ expect(component.gridOptions).toBeDefined();
+ expect(component.gridOptions.context).toBeDefined();
+ });
+
+ it('should emit if BusEvents is edit ', () => {
+ const spy = spyOn(component.companyDetailsIdLoaded, 'emit');
+ const event: any = {type: 'edit', data: {id: 'id'}};
+ component.gridOptions.context.eventSubject = of(event);
+ component.ngOnInit();
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should deleteAddress if BusEvents is delete', () => {
+ const spy = spyOn(companySandbox, 'deleteAddress');
+ const event: any = {type: 'delete', data: {id: 'id'}};
+ component.gridOptions.context.eventSubject = of(event);
+ component.ngOnInit();
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should clearAddressData and close edit area if callcreateNewAddressForm', () => {
+ const spy = spyOn(companySandbox, 'clearAddressData');
+ const spyEmit = spyOn(component.createNewCompany, 'emit');
+ component.createNewAddressForm();
+
+ expect(spy).toHaveBeenCalled();
+ expect(spyEmit).toHaveBeenCalled();
+ });
+});
+
diff --git a/src/app/pages/company/company-details/address-list/address-list.component.ts b/src/app/pages/company/company-details/address-list/address-list.component.ts
new file mode 100644
index 0000000..110bf50
--- /dev/null
+++ b/src/app/pages/company/company-details/address-list/address-list.component.ts
@@ -0,0 +1,62 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { CompanyDetailsSandBox } from '@pages/company/company-details/company-details.sandbox';
+import { BaseList } from '@shared/components/base-components/base.list';
+import { Component, EventEmitter, Output } from '@angular/core';
+import { ADDRESS_LIST_COLDEF } from '@shared/components/column-definitions/addresses-data-list-column-definition';
+import { Globals } from '@shared/constants/globals';
+
+
+@Component({
+ selector: 'app-company-address-list',
+ templateUrl: './address-list.component.html',
+ styleUrls: ['./address-list.component.scss']
+})
+export class CompanyAddressListComponent extends BaseList {
+
+ @Output() companyDetailsIdLoaded: EventEmitter<string> = new EventEmitter();
+ @Output() createNewCompany: EventEmitter<string> = new EventEmitter();
+
+ public columnDefinition = ADDRESS_LIST_COLDEF;
+
+
+ constructor(public companyDetailsSandBox: CompanyDetailsSandBox) {
+ super();
+ }
+
+ ngOnInit() {
+ this.gridOptions = {
+ ...this.gridOptions,
+ localeText: Globals.LOCALE_TEXT
+ };
+ this.gridOptions.context = {
+ ...this.gridOptions.context,
+ icons: { edit: true, delete: true }
+ };
+
+ this.gridOptions.context.eventSubject.subscribe(event => {
+ if (event.type === 'edit') {
+ this.companyDetailsIdLoaded.emit(event.data.id);
+ }
+ if (event.type === 'delete') {
+ this.companyDetailsSandBox.deleteAddress(event.data);
+ }
+ });
+ }
+
+ public createNewAddressForm(){
+ this.companyDetailsSandBox.clearAddressData();
+ this.createNewCompany.emit(null);
+ }
+
+}
diff --git a/src/app/pages/company/company-details/communications-data-details/communications-data-details.component.html b/src/app/pages/company/company-details/communications-data-details/communications-data-details.component.html
new file mode 100644
index 0000000..009f395
--- /dev/null
+++ b/src/app/pages/company/company-details/communications-data-details/communications-data-details.component.html
@@ -0,0 +1,75 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<form [ngrxFormState]="companyDetailsSandbox.communicationsDataDetailsFormState$ | async">
+ <h4>{{createOrEditCommunicationsData}}</h4>
+ <div>
+ <!-- type -->
+ <div class="form-group row">
+ <label for="communicationType" class="col-sm-4 col-form-label">{{ 'CommunicationsData.CommunicationType' | translate }}</label>
+ <div class="col-sm-7">
+ <select
+ type="text"
+ class="form-control"
+ [ngrxFormControlState]="((companyDetailsSandbox.communicationsDataDetailsFormState$ | async)?.controls)['communicationTypeId']">
+ <option [value]="">{{ 'SelectOption' | translate }}</option> -->
+ <option *ngFor="let communicationType of communicationTypesSandbox.communicationTypes$ | async" [disabled]="communicationType.isDisabled" [value]="communicationType.id">{{communicationType.type}}</option>
+ </select>
+ </div>
+ </div>
+
+ <!-- communicationData -->
+ <div class="form-group row">
+ <label for="communicationData" class="col-sm-4 col-form-label">{{ 'CommunicationsData.CommunicationData' | translate }}</label>
+ <div class="col-sm-7">
+ <input type="text"
+ maxlength="1024"
+ class="form-control"
+ id="communicationData"
+ [ngrxFormControlState]="((companyDetailsSandbox.communicationsDataDetailsFormState$ | async)?.controls)['communicationData']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- note -->
+ <div class="form-group row">
+ <label for="note" class="col-sm-4 col-form-label">{{ 'CommunicationsData.Note' | translate }}</label>
+ <div class="col-sm-7">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="note"
+ [ngrxFormControlState]="((companyDetailsSandbox.communicationsDataDetailsFormState$ | async)?.controls)['note']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- buttons -->
+ <button
+ type="button"
+ class="btn btn-primary btn-sm btn-success"
+ (click)="companyDetailsSandbox.persistCommunicationsData()"
+ >
+ {{ 'SaveBtn' | translate }}
+ </button>
+
+ <button
+ type="button"
+ class="btn btn-primary btn-sm"
+ (click)="companyDetailsSandbox.closeCommunicationsDataDetail()"
+ >
+ {{ 'CancelBtn' | translate }}
+ </button>
+ </div>
+</form >
diff --git a/src/app/pages/company/company-details/communications-data-details/communications-data-details.component.scss b/src/app/pages/company/company-details/communications-data-details/communications-data-details.component.scss
new file mode 100644
index 0000000..b959869
--- /dev/null
+++ b/src/app/pages/company/company-details/communications-data-details/communications-data-details.component.scss
@@ -0,0 +1,25 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+button {
+ margin: 14px 0px 10px 15px;
+}
+h4 {
+ padding: 15px;
+ padding-top: 18px;
+}
+div.form-group.row {
+ padding-left: 15px;
+}
+select option[disabled]{
+ background-color: rgb(160, 164, 168);
+}
diff --git a/src/app/pages/company/company-details/communications-data-details/communications-data-details.component.spec.ts b/src/app/pages/company/company-details/communications-data-details/communications-data-details.component.spec.ts
new file mode 100644
index 0000000..f4c15c2
--- /dev/null
+++ b/src/app/pages/company/company-details/communications-data-details/communications-data-details.component.spec.ts
@@ -0,0 +1,48 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { CompanyCommunicationsDataDetailsComponent } from '@pages/company/company-details/communications-data-details/communications-data-details.component';
+
+describe('CompanyCommunicationsDataDetailsComponent', () => {
+ let component: CompanyCommunicationsDataDetailsComponent;
+ let companySandbox: any;
+ let communicationTypesSandbox: any;
+
+ beforeEach(async(() => {
+ companySandbox = {
+ registerCommunicationsDataEvents() {},
+ registerCompanyEvents() {},
+ endSubscriptions() {},
+ clearCommunicationsData() {},
+ } as any;
+
+ communicationTypesSandbox = {
+ } as any;
+ }));
+
+ beforeEach(() => {
+ component = new CompanyCommunicationsDataDetailsComponent(companySandbox, communicationTypesSandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call registerCommunicationsDataEvents and clearCommunicationsData onInit', () => {
+ const spy1 = spyOn(companySandbox, 'registerCommunicationsDataEvents');
+ const spy2 = spyOn(companySandbox, 'clearCommunicationsData');
+ component.ngOnInit();
+ expect(spy1).toHaveBeenCalled();
+ expect(spy2).toHaveBeenCalled();
+ });
+});
diff --git a/src/app/pages/company/company-details/communications-data-details/communications-data-details.component.ts b/src/app/pages/company/company-details/communications-data-details/communications-data-details.component.ts
new file mode 100644
index 0000000..2d4c0e4
--- /dev/null
+++ b/src/app/pages/company/company-details/communications-data-details/communications-data-details.component.ts
@@ -0,0 +1,35 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { CompanyDetailsSandBox } from '@pages/company/company-details/company-details.sandbox';
+import { Component, OnInit, Input } from '@angular/core';
+import { CommunicationTypesSandbox } from '@pages/admin/communication-types/communication-types.sandbox';
+
+@Component({
+ selector: 'app-company-communications-data-details',
+ templateUrl: './communications-data-details.component.html',
+ styleUrls: ['./communications-data-details.component.scss']
+})
+export class CompanyCommunicationsDataDetailsComponent implements OnInit {
+
+ @Input() createOrEditCommunicationsData: string;
+
+ constructor(
+ public companyDetailsSandbox: CompanyDetailsSandBox,
+ public communicationTypesSandbox: CommunicationTypesSandbox
+ ) { }
+
+ ngOnInit() {
+ this.companyDetailsSandbox.registerCommunicationsDataEvents();
+ this.companyDetailsSandbox.clearCommunicationsData();
+ }
+}
diff --git a/src/app/pages/company/company-details/communications-data-list/communications-data-list.component.html b/src/app/pages/company/company-details/communications-data-list/communications-data-list.component.html
new file mode 100644
index 0000000..1c8b0ee
--- /dev/null
+++ b/src/app/pages/company/company-details/communications-data-list/communications-data-list.component.html
@@ -0,0 +1,36 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<div class="diverse-options">
+ <div class="new-communicationsData">
+ <button class="btn btn-sm btn-primary" (click)="createNewCommunicationsDataForm()">
+ {{ 'CommunicationsData.NewCommunicationsData' | translate }}
+ </button>
+ </div>
+</div>
+
+
+<ag-grid-angular
+ autoresizecolumns
+ class="ag-theme-balham ag-grid-height"
+ style="width: 100%; height: 100%;"
+ [gridOptions]="gridOptions"
+ [rowData]="companyDetailsSandBox.communicationsDataList$ | async"
+ [columnDefs]="columnDefinition"
+ [rowSelection]="'single'"
+ [frameworkComponents]="frameworkComponents"
+>
+</ag-grid-angular>
+<app-spinner [isRunning]="companyDetailsSandBox.communicationsDataListLoading$ | async"></app-spinner>
+
+
+
diff --git a/src/app/pages/company/company-details/communications-data-list/communications-data-list.component.scss b/src/app/pages/company/company-details/communications-data-list/communications-data-list.component.scss
new file mode 100644
index 0000000..63a5ad3
--- /dev/null
+++ b/src/app/pages/company/company-details/communications-data-list/communications-data-list.component.scss
@@ -0,0 +1,27 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+ .diverse-options {
+ display: flex;
+ justify-content: flex-end;
+ align-content: center;
+ background-color: #f5f7f7;
+ border: 1px solid rgb(189, 195, 199);
+ padding: 7px 7px 5px 7px;
+ margin-bottom: 1px;
+}
+
+.diverse-options-item {
+ width: 400px;
+ padding-right: 7px;
+ border-right: solid 1px #ddd;
+}
diff --git a/src/app/pages/company/company-details/communications-data-list/communications-data-list.component.spec.ts b/src/app/pages/company/company-details/communications-data-list/communications-data-list.component.spec.ts
new file mode 100644
index 0000000..a1c7aac
--- /dev/null
+++ b/src/app/pages/company/company-details/communications-data-list/communications-data-list.component.spec.ts
@@ -0,0 +1,73 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { CompanyCommunicationsDataListComponent } from '@pages/company/company-details/communications-data-list/communications-data-list.component';
+import { of } from 'rxjs/observable/of';
+
+describe('CompanyCommunicationsDataListComponent', () => {
+ let component: CompanyCommunicationsDataListComponent;
+ let companySandbox: any;
+
+ beforeEach(async(() => {
+ companySandbox = {
+ registerCommunicationsDataEvents() {},
+ registerCompanyEvents() {},
+ endSubscriptions() {},
+ deleteCommunicationsData() {},
+ clearCommunicationsData() {},
+ } as any;
+ }));
+
+ beforeEach(() => {
+ component = new CompanyCommunicationsDataListComponent(companySandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should define gridOptions onInit', () => {
+ component.ngOnInit();
+
+ expect(component.gridOptions).toBeDefined();
+ expect(component.gridOptions.context).toBeDefined();
+ });
+
+ it('should emit if BusEvents is edit ', () => {
+ const spy = spyOn(component.companyDetailsIdLoaded, 'emit');
+ const event: any = {type: 'edit', data: {id: 'id'}};
+ component.gridOptions.context.eventSubject = of(event);
+ component.ngOnInit();
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should deleteCommunicationsData if BusEvents is delete', () => {
+ const spy = spyOn(companySandbox, 'deleteCommunicationsData');
+ const event: any = {type: 'delete', data: {id: 'id'}};
+ component.gridOptions.context.eventSubject = of(event);
+ component.ngOnInit();
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should clearCommunicationsData and close edit area if callcreateNewCommunicationsDataForm', () => {
+ const spy = spyOn(companySandbox, 'clearCommunicationsData');
+ const spyEmit = spyOn(component.createNewCompany, 'emit');
+ component.createNewCommunicationsDataForm();
+
+ expect(spy).toHaveBeenCalled();
+ expect(spyEmit).toHaveBeenCalled();
+ });
+});
+
diff --git a/src/app/pages/company/company-details/communications-data-list/communications-data-list.component.ts b/src/app/pages/company/company-details/communications-data-list/communications-data-list.component.ts
new file mode 100644
index 0000000..56e4c81
--- /dev/null
+++ b/src/app/pages/company/company-details/communications-data-list/communications-data-list.component.ts
@@ -0,0 +1,61 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { CompanyDetailsSandBox } from '@pages/company/company-details/company-details.sandbox';
+import { BaseList } from '@shared/components/base-components/base.list';
+import { Component, EventEmitter, Output } from '@angular/core';
+import { COMMUNICATIONS_DATA_LIST_COLDEF } from '@shared/components/column-definitions/communications-data-list-column-definition';
+import { Globals } from '@shared/constants/globals';
+
+@Component({
+ selector: 'app-company-communications-data-list',
+ templateUrl: './communications-data-list.component.html',
+ styleUrls: ['./communications-data-list.component.scss']
+})
+export class CompanyCommunicationsDataListComponent extends BaseList {
+
+ @Output() companyDetailsIdLoaded: EventEmitter<string> = new EventEmitter();
+ @Output() createNewCompany: EventEmitter<string> = new EventEmitter();
+
+ public columnDefinition = COMMUNICATIONS_DATA_LIST_COLDEF;
+
+
+ constructor(public companyDetailsSandBox: CompanyDetailsSandBox) {
+ super();
+ }
+
+ ngOnInit() {
+ this.gridOptions = {
+ ...this.gridOptions,
+ localeText: Globals.LOCALE_TEXT
+ };
+ this.gridOptions.context = {
+ ...this.gridOptions.context,
+ icons: { edit: true, delete: true }
+ };
+
+ this.gridOptions.context.eventSubject.subscribe(event => {
+ if (event.type === 'edit') {
+ this.companyDetailsIdLoaded.emit(event.data.id);
+ }
+ if (event.type === 'delete') {
+ this.companyDetailsSandBox.deleteCommunicationsData(event.data);
+ }
+ });
+ }
+
+ public createNewCommunicationsDataForm(){
+ this.companyDetailsSandBox.clearCommunicationsData();
+ this.createNewCompany.emit(null);
+ }
+
+}
diff --git a/src/app/pages/company/company-details/company-details.component.html b/src/app/pages/company/company-details/company-details.component.html
new file mode 100644
index 0000000..0ceaf40
--- /dev/null
+++ b/src/app/pages/company/company-details/company-details.component.html
@@ -0,0 +1,114 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<app-card-layout>
+ <div header>
+ <span>{{ 'Company.Title' | translate }}</span>
+ </div>
+ <div class="contacts-grid-wrapper" body>
+ <form [ngrxFormState]="companyDetailsSandBox.companyFormState$ | async">
+ <div>
+ <!-- companyName -->
+ <div class="form-group row">
+ <label for="companyName" class="col-sm-2 col-form-label">{{ 'Company.Name' | translate }}</label>
+ <div class="col-sm-4">
+ <input
+ required
+ type="text"
+ maxlength="255"
+ class="form-control"
+ id="companyName"
+ [ngrxFormControlState]="((companyDetailsSandBox.companyFormState$ | async)?.controls)['companyName']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- CompanyType -->
+ <div class="form-group row">
+ <label for="companyType" class="col-sm-2 col-form-label">{{ 'Company.CompanyType' | translate }}</label>
+ <div class="col-sm-4">
+ <input
+ type="text"
+ maxlength="30"
+ class="form-control"
+ id="companyType"
+ [ngrxFormControlState]="((companyDetailsSandBox.companyFormState$ | async)?.controls)['companyType']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- HrNumber -->
+ <div class="form-group row">
+ <label for="hrNumber" class="col-sm-2 col-form-label">{{ 'Company.HrNumber' | translate }}</label>
+ <div class="col-sm-4">
+ <input
+ type="text"
+ maxlength="255"
+ class="form-control"
+ id="hrNumber"
+ [ngrxFormControlState]="((companyDetailsSandBox.companyFormState$ | async)?.controls)['hrNumber']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- contactNote -->
+ <div class="form-group row">
+ <label for="contactNote" class="col-sm-2 col-form-label">{{ 'Company.Note' | translate }}</label>
+ <div class="col-sm-4">
+ <input
+ type="text"
+ maxlength="255"
+ class="form-control"
+ id="contactNote"
+ [ngrxFormControlState]="((companyDetailsSandBox.companyFormState$ | async)?.controls)['contactNote']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- buttons -->
+ <button type="button" class="btn btn-success" (click)="companyDetailsSandBox.persistCompany()">{{ 'SaveBtn' | translate }}</button>
+ <button type="button" class="btn btn-primary cancel-button" routerLink="/overview">
+ {{ 'CancelBtn' | translate }}
+ </button>
+ </div>
+ </form>
+
+ <app-expandable class="expandable-address" *ngIf="isexpandableVisible">
+ <span header>{{ 'Contacts.AddressList' | translate }}</span>
+ <div class="expandable-body-container" body>
+ <div class="table-detail-view-address" *ngIf="companyDetailsSandBox.isAddressDataDetailViewVisible">
+ <app-company-address-details [createOrEditAddressData]="createOrEditAddressData"></app-company-address-details>
+ </div>
+ <div class="table-view-address">
+ <app-company-address-list (companyDetailsIdLoaded)="loadAddressDetail($event)" (createNewCompany)="loadAddressDetail($event)"></app-company-address-list>
+ </div>
+ </div>
+ </app-expandable>
+
+ <app-expandable class="expandable-communication" *ngIf="isexpandableVisible">
+ <span header>{{ 'Contacts.CommunicationsDataList' | translate }}</span>
+ <div class="expandable-body-container" body>
+ <div class="table-detail-view-communication" *ngIf="companyDetailsSandBox.isCommunicationsDataDetailViewVisible">
+ <app-company-communications-data-details [createOrEditCommunicationsData]="createOrEditCommunicationsData"></app-company-communications-data-details>
+ </div>
+ <div class="table-view-communication">
+ <app-company-communications-data-list (companyDetailsIdLoaded)="loadCommunicationsDataDetail($event)" (createNewCompany)="loadCommunicationsDataDetail($event)"></app-company-communications-data-list>
+ </div>
+ </div>
+ </app-expandable>
+
+ </div>
+</app-card-layout>
diff --git a/src/app/pages/company/company-details/company-details.component.scss b/src/app/pages/company/company-details/company-details.component.scss
new file mode 100644
index 0000000..7ae29d0
--- /dev/null
+++ b/src/app/pages/company/company-details/company-details.component.scss
@@ -0,0 +1,42 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+ .cancel-button {
+ margin-left: 16px;
+ }
+.expandable-body-container {
+ display: flex;
+ flex-direction: row;
+ height: 100%;
+}
+.table-detail-view-address {
+ height: 756px;
+ width: 461px;
+}
+.table-view-address {
+ height: 711px;
+ flex-grow: 1;
+}
+.expandable-address ::ng-deep .collapse5 {
+ height: 758px;
+}
+.table-detail-view-communication {
+ height: 296px;
+ width: 461px;
+}
+.table-view-communication {
+ height: 250px;
+ flex-grow: 1;
+}
+.expandable-communication ::ng-deep .collapse5 {
+ height: 297px;
+}
diff --git a/src/app/pages/company/company-details/company-details.component.spec.ts b/src/app/pages/company/company-details/company-details.component.spec.ts
new file mode 100644
index 0000000..3144c26
--- /dev/null
+++ b/src/app/pages/company/company-details/company-details.component.spec.ts
@@ -0,0 +1,110 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { CompanyDetailsComponent } from '@pages/company/company-details/company-details.component';
+
+describe('CompanyDetailsComponent', () => {
+ let component: CompanyDetailsComponent;
+ let companyDetailsSandBox: any;
+ let translate: any;
+
+ beforeEach(() => {
+
+ companyDetailsSandBox = {
+ registerAddressEvents() {},
+ registerCompanyEvents() {},
+ endSubscriptions() {},
+ loadCompanyDetailsAddressDetails() {},
+ updatingState() {},
+ currentFormState: { isValid: true },
+ persistCompany() {},
+ loadCommunicationsDataDetails() {},
+ utilService: { displayNotification: () => {} }
+ } as any;
+
+ translate = {
+ instant() {},
+ } as any;
+
+ component = new CompanyDetailsComponent(companyDetailsSandBox, translate);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call translate instant if no communications data id', () => {
+ const spy = spyOn(translate, 'instant');
+ component.loadCommunicationsDataDetail(null);
+
+ expect(spy).toHaveBeenCalledWith('CommunicationsData.NewCommunicationsData');
+ });
+
+ it('should call translate instant if there is an communications data id', () => {
+ const id = 'id';
+ const spy = spyOn(translate, 'instant');
+ const spy1 = spyOn(companyDetailsSandBox, 'loadCommunicationsDataDetails');
+ component.loadCommunicationsDataDetail(id);
+
+ expect(spy).toHaveBeenCalledWith('CommunicationsData.EditCommunicationsData');
+ expect(spy1).toHaveBeenCalledWith(id);
+ });
+
+ it('should call translate instant if there is an communications data id', () => {
+ component.companyDetailsSandBox.isCommunicationsDataDetailViewVisible = false;
+ component.loadCommunicationsDataDetail(null);
+ expect(component.companyDetailsSandBox.isCommunicationsDataDetailViewVisible).toBeTruthy();
+ });
+
+ it('should loadCompanies on init', () => {
+ const spy = spyOn(companyDetailsSandBox, 'registerCompanyEvents');
+ component.ngOnInit();
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should end all subscriptions for this sandbox onDestroy', () => {
+ const spy = spyOn(companyDetailsSandBox, 'endSubscriptions');
+ component.ngOnDestroy();
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should call translate instant if no id', () => {
+ const spy = spyOn(translate, 'instant');
+ component.loadAddressDetail(null);
+
+ expect(spy).toHaveBeenCalledWith('Address.NewAddress');
+ });
+
+ it('should call translate instant if there is id', () => {
+ const id = 'id';
+ const spy = spyOn(translate, 'instant');
+ const spy1 = spyOn(companyDetailsSandBox, 'loadCompanyDetailsAddressDetails');
+ component.loadAddressDetail(id);
+
+ expect(spy).toHaveBeenCalledWith('Address.EditAddress');
+ expect(spy1).toHaveBeenCalledWith(id);
+ });
+
+ it('should call translate instant if there is id', () => {
+ component.companyDetailsSandBox.isAddressDataDetailViewVisible = false;
+ component.loadAddressDetail(null);
+ expect(component.companyDetailsSandBox.isAddressDataDetailViewVisible).toBeTruthy();
+ });
+
+ it('should set expandableVisible to "true" if companyContactId is defined', () => {
+ component.companyDetailsSandBox.companyContactId = 'test';
+ (component as any)._hideExpandable();
+ expect(component.isexpandableVisible).toBeTruthy();
+ });
+});
diff --git a/src/app/pages/company/company-details/company-details.component.ts b/src/app/pages/company/company-details/company-details.component.ts
new file mode 100644
index 0000000..374783b
--- /dev/null
+++ b/src/app/pages/company/company-details/company-details.component.ts
@@ -0,0 +1,71 @@
+/********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/
+import { CompanyDetailsSandBox } from '@pages/company/company-details/company-details.sandbox';
+import { Component } from '@angular/core';
+import { OnDestroy, OnInit } from '@angular/core';
+import { TranslateService } from '@ngx-translate/core';
+
+@Component({
+ selector: 'app-company-details',
+ templateUrl: './company-details.component.html',
+ styleUrls: ['./company-details.component.scss']
+})
+export class CompanyDetailsComponent implements OnInit, OnDestroy {
+
+ public createOrEditCommunicationsData = '';
+
+ public createOrEditAddressData = '';
+ public isexpandableVisible = true;
+
+ constructor(
+ public companyDetailsSandBox: CompanyDetailsSandBox,
+ private _translate: TranslateService
+ ) { }
+
+ ngOnInit() {
+ this.companyDetailsSandBox.registerCompanyEvents();
+ this._hideExpandable();
+ }
+
+ ngOnDestroy() {
+ this.companyDetailsSandBox.endSubscriptions();
+ }
+
+ public loadCommunicationsDataDetail(detailId: string) {
+ if (detailId == null) {
+ this.createOrEditCommunicationsData = this._translate.instant('CommunicationsData.NewCommunicationsData');
+ } else {
+ this.createOrEditCommunicationsData = this._translate.instant('CommunicationsData.EditCommunicationsData');
+ this.companyDetailsSandBox.loadCommunicationsDataDetails(detailId);
+ }
+ this.companyDetailsSandBox.isCommunicationsDataDetailViewVisible = true;
+ }
+
+ public loadAddressDetail(detailId: string) {
+ if (detailId == null) {
+ this.createOrEditAddressData = this._translate.instant('Address.NewAddress');
+ } else {
+ this.createOrEditAddressData = this._translate.instant('Address.EditAddress');
+ this.companyDetailsSandBox.loadCompanyDetailsAddressDetails(detailId);
+ }
+ this.companyDetailsSandBox.isAddressDataDetailViewVisible = true;
+ }
+
+ private _hideExpandable() {
+ if (!this.companyDetailsSandBox.companyContactId) {
+ this.isexpandableVisible = false;
+ } else {
+ this.isexpandableVisible = true;
+ }
+ }
+}
diff --git a/src/app/pages/company/company-details/company-details.resolver.spec.ts b/src/app/pages/company/company-details/company-details.resolver.spec.ts
new file mode 100644
index 0000000..c95e717
--- /dev/null
+++ b/src/app/pages/company/company-details/company-details.resolver.spec.ts
@@ -0,0 +1,77 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { CompanyDetailsResolver } from '@pages/company/company-details/company-details.resolver';
+
+describe('CompanyDetailsResolver', () => {
+ let component: CompanyDetailsResolver;
+ let companyDetailsSandbox: any;
+ let communicationTypesSandbox: any;
+
+ beforeEach(async(() => {
+ companyDetailsSandbox = {
+ clearCompany() {},
+ loadCompany() {},
+ loadCommunicationsData() {},
+ loadCompanyAddresses() {},
+ } as any;
+
+ communicationTypesSandbox = {
+ loadCommunicationTypes() {}
+ } as any;
+ }));
+
+ beforeEach(() => {
+ component = new CompanyDetailsResolver(companyDetailsSandbox, communicationTypesSandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call loadCompany if edit a company', () => {
+ const spy = spyOn(companyDetailsSandbox, 'loadCompany');
+ let ar: any = {params: {contactId: 'ID'}};
+ component.resolve(ar);
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should call clear if create a new company', () => {
+ const spy = spyOn(companyDetailsSandbox, 'clearCompany');
+ let ar: any = {params: {contactId: undefined}};
+ component.resolve(ar);
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should loadCommunicationTypes on resolve', () => {
+ const spy = spyOn(communicationTypesSandbox, 'loadCommunicationTypes');
+ let ar: any = {params: {contactId: undefined}};
+ component.resolve(ar);
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should set isCommunicationsDataDetailViewVisible true on resolve', () => {
+ let ar: any = {params: {contactId: undefined}};
+ component.resolve(ar);
+
+ expect(companyDetailsSandbox.isCommunicationsDataDetailViewVisible).toBeFalsy();
+ });
+
+ it('should set isDetailViewVisible true on resolve', () => {
+ let ar: any = {params: {contactId: undefined}};
+ component.resolve(ar);
+
+ expect(companyDetailsSandbox.isDetailViewVisible).toBeFalsy();
+ });
+});
diff --git a/src/app/pages/company/company-details/company-details.resolver.ts b/src/app/pages/company/company-details/company-details.resolver.ts
new file mode 100644
index 0000000..143d681
--- /dev/null
+++ b/src/app/pages/company/company-details/company-details.resolver.ts
@@ -0,0 +1,43 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { CompanyDetailsSandBox } from '@pages/company/company-details/company-details.sandbox';
+import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
+import { Injectable } from '@angular/core';
+import { CommunicationTypesSandbox } from '@pages/admin/communication-types/communication-types.sandbox';
+
+@Injectable()
+export class CompanyDetailsResolver implements Resolve<any>{
+
+ constructor(
+ private companySandbox: CompanyDetailsSandBox,
+ private communicationTypesSandbox: CommunicationTypesSandbox
+ ) { }
+
+ /**
+ * @param route
+ */
+ public resolve(route: ActivatedRouteSnapshot): void {
+ const contactId: string = route.params['contactId'];
+ if (contactId && (contactId !== 'new')) {
+ this.companySandbox.loadCompany(contactId);
+ this.companySandbox.loadCommunicationsData(contactId);
+ this.companySandbox.loadCompanyAddresses(contactId);
+ } else {
+ this.companySandbox.clearCompany();
+ }
+
+ this.communicationTypesSandbox.loadCommunicationTypes();
+ this.companySandbox.isCommunicationsDataDetailViewVisible = false;
+ }
+
+}
diff --git a/src/app/pages/company/company-details/company-details.sandbox.spec.ts b/src/app/pages/company/company-details/company-details.sandbox.spec.ts
new file mode 100644
index 0000000..c4feaa6
--- /dev/null
+++ b/src/app/pages/company/company-details/company-details.sandbox.spec.ts
@@ -0,0 +1,195 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { CompanyDetailsSandBox } from '@pages/company/company-details/company-details.sandbox';
+import { of } from 'rxjs';
+import * as companyActions from '@shared/store/actions/company/company.action';
+import { Company, CommunicationsData, Address } from '@shared/models';
+
+describe('CompanyDetailsSandBox', () => {
+ let component: CompanyDetailsSandBox;
+ let utilService: any;
+ let appState: any;
+ let actionSubject: any;
+ let router: any;
+ let modalService: any;
+
+ beforeEach(async(() => {
+ router = { navigateByUrl() {} } as any;
+ appState = { dispatch:()=> {}, pipe: () => of(true), select:()=> of(true) } as any;
+ actionSubject = { pipe: () => of(true) } as any;
+ utilService = { displayNotification: () => {} } as any;
+ modalService = { open() {} } as any;
+ }));
+
+ beforeEach(() => {
+ component = new CompanyDetailsSandBox(appState, actionSubject, utilService, router, modalService);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call dispatch if load a company', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.loadCompany('ID');
+ expect(spy).toHaveBeenCalledWith( Object({ payload: 'ID', type: companyActions.loadCompanyDetail.type }));
+ });
+
+ it('should call dispatch if persist a company', () => {
+ const spy = spyOn(appState, 'dispatch');
+ const routerSpy = spyOn(router, 'navigateByUrl');
+ const company = new Company;
+ company.companyName = 'test';
+ component.companyCurrentFormState = {...component.companyCurrentFormState, isValid: true, value: company};
+ component.persistCompany();
+ expect(spy).toHaveBeenCalledWith( Object({ payload: company, type: companyActions.persistCompanyDetail.type }));
+ expect(routerSpy).toHaveBeenCalled();
+ });
+
+ it('should call error with displayNotification if for not valid', () => {
+ const utilSpy = spyOn(utilService, 'displayNotification');
+ component.companyCurrentFormState = {...component.companyCurrentFormState, isValid: false};
+ component.persistCompany();
+ expect(utilSpy).toHaveBeenCalled();
+ });
+
+ it('should can register events and set the currentFormState', () => {
+ component.registerCompanyEvents();
+ expect(component.companyCurrentFormState).toBeDefined();
+ });
+
+ it('should call dispatch if load a company communications Data', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.loadCommunicationsData('ID');
+ expect(spy).toHaveBeenCalledWith( Object({ payload: 'ID', type: companyActions.loadCompanyDetailCommunicationsData.type }));
+ });
+
+ it('should call dispatch if load a company communicationsData details', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.companyContactId = 'contactId'
+ component.loadCommunicationsDataDetails('ID');
+ expect(spy).toHaveBeenCalledWith( Object({ payload_contactId: 'contactId', payload_communicationsId: 'ID', type: companyActions.loadCompanyDetailCommunicationsDataDetails.type }));
+ });
+
+ it('should can register communicationsData events and set the communicationsDataDetailsCurrentFormState', () => {
+ component.registerCommunicationsDataEvents();
+ expect(component.communicationsDataDetailsCurrentFormState).toBeDefined();
+ });
+
+ it('should call dispatch if clearCommunicationsData', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.clearCommunicationsData();
+ expect(spy).toHaveBeenCalledTimes(2);
+ });
+
+ it('should call dispatch if persist an external person communicationsData', () => {
+ const spy = spyOn(appState, 'dispatch');
+ const spy1 = spyOn(component, 'clearCommunicationsData');
+ const companyCommunicationsData = new CommunicationsData();
+ companyCommunicationsData.communicationTypeType = 'test';
+ companyCommunicationsData.contactId = 'id';
+
+ component.communicationsDataDetailsCurrentFormState = {...component.communicationsDataDetailsCurrentFormState, isValid: true, value: companyCommunicationsData};
+ component.persistCommunicationsData();
+ expect(spy).toHaveBeenCalledWith( Object({ payload: companyCommunicationsData, type: companyActions.persistCommunicationsDataDetail.type }));
+ expect(spy1).toHaveBeenCalled();
+ });
+
+ it('should call error with displayNotification if communicationsData form not valid', () => {
+ const utilSpy = spyOn(utilService, 'displayNotification');
+ component.communicationsDataDetailsCurrentFormState = {...component.communicationsDataDetailsCurrentFormState, isValid: false};
+ component.persistCommunicationsData();
+ expect(utilSpy).toHaveBeenCalled();
+ });
+
+ it('should call clearCommunicationsData and negate isCommunicationsDataDetailViewVisible after call closeCommunicationsDataDetail', () => {
+ const spy = spyOn(component, 'clearCommunicationsData');
+ component.isCommunicationsDataDetailViewVisible = true;
+ component.closeCommunicationsDataDetail();
+ expect(spy).toHaveBeenCalled();
+ expect(component.isCommunicationsDataDetailViewVisible).toBe(false);
+ });
+
+ it('should open modal before deleting an communicationsData', () => {
+ spyOn(component['modalService'], 'open')
+ .and.returnValue({componentInstance: {title: ''}, result: {then: () => of(true)}} as any);
+ component.deleteCommunicationsData(new CommunicationsData());
+ expect(modalService.open).toHaveBeenCalled();
+ });
+
+ it('should call dispatch if load a company addresses', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.loadCompanyAddresses('ID');
+ expect(spy).toHaveBeenCalledWith( Object({ payload: 'ID', type: companyActions.loadCompanyDetailAddresses.type }));
+ });
+
+ it('should call dispatch if load a company address details', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.companyContactId = 'contactId';
+ component.loadCompanyDetailsAddressDetails('ID');
+ expect(spy).toHaveBeenCalledWith( Object({ payload_contactId: 'contactId', payload_addressId: 'ID', type: companyActions.loadCompanyDetailAddressDetails.type }));
+ });
+
+ it('should can register address events and set the addressDetailsCurrentFormState', () => {
+ component.registerAddressEvents();
+ expect(component.addressDetailsCurrentFormState).toBeDefined();
+ });
+
+ it('should call dispatch if clearCompany', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.clearCompany();
+ expect(spy).toHaveBeenCalledTimes(3);
+ });
+
+ it('should call dispatch if clearAddressData', () => {
+ const spy = spyOn(appState, 'dispatch');
+ (component as any).clearAddressData();
+ expect(spy).toHaveBeenCalledTimes(2);
+ });
+
+ it('should call dispatch if persist a company address', () => {
+ const spy = spyOn(appState, 'dispatch');
+ const spy1 = spyOn(component, 'clearAddressData');
+ const companyAddress = new Address();
+ companyAddress.addressTypeType = 'test';
+ companyAddress.contactId = 'id';
+
+ component.addressDetailsCurrentFormState = {...component.addressDetailsCurrentFormState, isValid: true, value: companyAddress};
+ component.persistAddress();
+ expect(spy).toHaveBeenCalledWith( Object({ payload: companyAddress, type: companyActions.persistAddressDetail.type }));
+ expect(spy1).toHaveBeenCalled();
+ });
+
+ it('should call error with displayNotification if address form not valid', () => {
+ const utilSpy = spyOn(utilService, 'displayNotification');
+ component.addressDetailsCurrentFormState = {...component.addressDetailsCurrentFormState, isValid: false};
+ component.persistAddress();
+ expect(utilSpy).toHaveBeenCalled();
+ });
+
+ it('should call clearAddressData and negate isDetailViewVisible after call closeAddressDataDetail', () => {
+ const spy = spyOn(component, 'clearAddressData');
+ component.isAddressDataDetailViewVisible = true;
+ component.closeAddressDataDetail();
+ expect(spy).toHaveBeenCalled();
+ expect(component.isAddressDataDetailViewVisible).toBe(false);
+ });
+
+ it('should open modal before deleting an address', () => {
+ spyOn(component['modalService'], 'open')
+ .and.returnValue({componentInstance: {title: ''}, result: {then: () => of(true)}} as any);
+ component.deleteAddress(new Address());
+ expect(modalService.open).toHaveBeenCalled();
+ });
+});
diff --git a/src/app/pages/company/company-details/company-details.sandbox.ts b/src/app/pages/company/company-details/company-details.sandbox.ts
new file mode 100644
index 0000000..61c918a
--- /dev/null
+++ b/src/app/pages/company/company-details/company-details.sandbox.ts
@@ -0,0 +1,316 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { BaseSandbox } from '@shared/sandbox/base.sandbox';
+import { Injectable } from '@angular/core';
+import * as companyActions from '@shared/store/actions/company/company.action';
+import { FormGroupState, SetValueAction, ResetAction } from 'ngrx-forms';
+import { Company, CommunicationsData, CommunicationType, Address } from '@shared/models';
+import { Observable } from 'rxjs';
+import * as store from '@shared/store';
+import { Store, ActionsSubject } from '@ngrx/store';
+import * as companyDetailsFormReducer from '@shared/store/reducers/company/company-details-form.reducer';
+import * as companyAddressDetailsFormReducer from '@shared/store/reducers/company/addresses-details-form.reducer';
+import { ofType } from '@ngrx/effects';
+import { UtilService } from '@shared/utility';
+import { takeUntil, take, map } from 'rxjs/operators';
+import { Router } from '@angular/router';
+import { SafetyQueryDialogComponent } from '@shared/components/dialogs/safety-query-dialog/safety-query-dialog.component';
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import * as companyCommunicationsDataDetailsFormReducer from '@shared/store/reducers/company/communications-data-details-form.reducer';
+import * as communicationTypesActions from '@shared/store/actions/admin/communication-types.action';
+import { MarkAsTouchedAction } from 'ngrx-forms';
+
+
+@Injectable()
+export class CompanyDetailsSandBox extends BaseSandbox {
+ public companyCurrentFormState: FormGroupState<Company>;
+ public companyFormState$: Observable<FormGroupState<Company>> = this.appState$.select(store.getCompanyDetails);
+ public communicationsDataDetailsFormState$: Observable<FormGroupState<CommunicationsData>> = this.appState$.select(store.getCompanyCommunicationsDataDetails);
+ public communicationsDataDetailsCurrentFormState: FormGroupState<CommunicationsData>;
+ public communicationsDataList$: Observable<Array<CommunicationsData>> = this.appState$.select(store.getCompanyCommunicationsDataData);
+ public communicationsDataListLoading$: Observable<boolean> = this.appState$.select(store.getCompanyCommunicationsDataLoading);
+ public addressDetailsFormState$: Observable<FormGroupState<Address>> = this.appState$.select(store.getCompanyAddressesDetails);
+ public addressDetailsCurrentFormState: FormGroupState<Address>;
+ public addressList$: Observable<Array<Address>> = this.appState$.select(store.getCompanyAddressesData);
+ public addressListLoading$: Observable<boolean> = this.appState$.select(store.getCompanyAddressesLoading);
+
+ public isCommunicationsDataDetailViewVisible: boolean = false;
+ public isAddressDataDetailViewVisible: boolean = false;
+ public existMainAddress = false;
+ public isCurrentAddressMainAddress = false;
+ public companyContactId: string;
+
+ private _communicationTypes: Array<CommunicationType> = new Array<CommunicationType>();
+
+ /**
+ * Company Sandbox constructor
+ */
+ constructor(
+ protected appState$: Store<store.State>,
+ protected actionsSubject: ActionsSubject,
+ protected utilService: UtilService,
+ protected router: Router,
+ protected modalService: NgbModal
+ ) {
+ super(appState$);
+
+ this.addressList$.subscribe(addresses => {
+ this._checkIfMainAddressExist(addresses);
+ });
+
+ this.actionsSubject
+ .pipe(
+ ofType(companyActions.loadCompanyDetailAddressDetailsSuccess),
+ map((action: { payload: Address }) => action.payload),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe((address: Address) => {
+ this._checkIfCurrentAddressIsMainAddress(address);
+ });
+ }
+
+ public loadCompany(id: string): void {
+ this.companyContactId = id;
+ this.appState$.dispatch(
+ companyActions.loadCompanyDetail({ payload: id })
+ );
+ }
+
+ public loadCompanyAddresses(companyId: string): void {
+ this.appState$.dispatch(
+ companyActions.loadCompanyDetailAddresses({ payload: companyId })
+ );
+ }
+
+ public loadCompanyDetailsAddressDetails(addressId: string): void {
+ this.appState$.dispatch(
+ companyActions.loadCompanyDetailAddressDetails({ payload_contactId: this.companyContactId, payload_addressId: addressId })
+ );
+ }
+
+ public persistCompany(): void {
+ if (this.companyCurrentFormState.isValid) {
+ const newCompany = new Company(this.companyCurrentFormState.value);
+
+ this.appState$.dispatch(
+ companyActions.persistCompanyDetail({
+ payload: newCompany,
+ })
+ );
+ this.actionsSubject
+ .pipe(
+ ofType(companyActions.persistCompanyDetailSuccess),
+ take(1),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe(() => {
+ this.clearCompany();
+ this.router.navigateByUrl(`/overview`);
+ });
+ } else {
+ this.utilService.displayNotification('MandatoryFieldsNotFilled', 'error');
+ }
+ }
+
+ public clearCompany(): void {
+ this.appState$.dispatch(new SetValueAction(companyDetailsFormReducer.FORM_ID, companyDetailsFormReducer.INITIAL_STATE.value));
+ this.appState$.dispatch(new ResetAction(companyDetailsFormReducer.FORM_ID));
+
+ this.appState$.dispatch(new MarkAsTouchedAction(companyDetailsFormReducer.FORM_ID));
+ }
+
+ public loadCommunicationsData(companyId: string): void {
+ this.actionsSubject
+ .pipe(
+ ofType(communicationTypesActions.loadCommunicationTypesSuccess),
+ map((action: communicationTypesActions.ILoadCommunicationTypesSuccess) => action.payload),
+ take(1),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe((payload: Array<CommunicationType>) => {
+ this._communicationTypes = payload;
+ this.appState$.dispatch(companyActions.loadCompanyDetailCommunicationsData({ payload: companyId }));
+ });
+
+ this.actionsSubject
+ .pipe(
+ ofType(companyActions.loadCompanyDetailCommunicationsDataSuccess),
+ map((action: companyActions.ILoadCompanyCommunicationsDataSuccess) => action.payload),
+ take(1),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe((communicationsData: Array<CommunicationsData>) => {
+ if (this._communicationTypes) {
+ for (let i = 0; i < this._communicationTypes.length; i++) {
+ const ct = this._communicationTypes[i];
+ const existingCommunicationsData: CommunicationsData = communicationsData.find(cd => cd.communicationTypeId == ct.id);
+ ct.isDisabled = existingCommunicationsData ? true : false;
+ }
+ }
+ });
+ }
+
+ public loadCommunicationsDataDetails(communicationsDataId: string): void {
+ this.appState$.dispatch(
+ companyActions.loadCompanyDetailCommunicationsDataDetails({ payload_contactId: this.companyContactId, payload_communicationsId: communicationsDataId })
+ );
+ }
+
+ public persistCommunicationsData(): void {
+ if (this.communicationsDataDetailsCurrentFormState.isValid) {
+ const newCommunicationsData = new CommunicationsData(this.communicationsDataDetailsCurrentFormState.value);
+ newCommunicationsData.contactId = newCommunicationsData.contactId !== null ? newCommunicationsData.contactId : this.companyContactId;
+
+ this.appState$.dispatch(
+ companyActions.persistCommunicationsDataDetail({payload: newCommunicationsData})
+ );
+ this.actionsSubject
+ .pipe(
+ ofType(companyActions.persistCommunicationsDataDetailSuccess),
+ take(1),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe(() => {
+ this.closeCommunicationsDataDetail();
+ });
+ } else {
+ this.utilService.displayNotification(
+ 'MandatoryFieldsNotFilled',
+ 'error'
+ );
+ }
+ }
+
+ public deleteCommunicationsData(communicationsData: CommunicationsData): void {
+ const modalRef = this.modalService.open(SafetyQueryDialogComponent);
+ modalRef.componentInstance.title = 'ConfirmDialog.Action.delete';
+ modalRef.componentInstance.body = 'ConfirmDialog.Deletion';
+ modalRef.result.then(() => {
+ this.appState$.dispatch(companyActions.deleteCommunicationsData({ payload: communicationsData }));
+ this.closeCommunicationsDataDetail();
+ }, () => {
+ });
+ }
+
+ public closeCommunicationsDataDetail(): void {
+ this.loadCommunicationsData(this.companyContactId);
+ this.clearCommunicationsData();
+ this.isCommunicationsDataDetailViewVisible = false;
+ }
+
+ public clearCommunicationsData(): void {
+ this.appState$.dispatch(
+ new SetValueAction(
+ companyCommunicationsDataDetailsFormReducer.FORM_ID,
+ companyCommunicationsDataDetailsFormReducer.INITIAL_STATE.value
+ )
+ );
+ this.appState$.dispatch(new ResetAction(companyCommunicationsDataDetailsFormReducer.FORM_ID));
+ }
+
+ public persistAddress(): void {
+ if (this.addressDetailsCurrentFormState.isValid) {
+ const newAddress = new Address(this.addressDetailsCurrentFormState.value);
+ newAddress.contactId = newAddress.contactId !== null ? newAddress.contactId : this.companyContactId;
+
+ this.appState$.dispatch(
+ companyActions.persistAddressDetail({payload: newAddress})
+ );
+ this.actionsSubject
+ .pipe(
+ ofType(companyActions.persistAddressDetailSuccess),
+ take(1),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe(() => {
+ this.closeAddressDataDetail();
+ this.isAddressDataDetailViewVisible = false
+ });
+ } else {
+ this.utilService.displayNotification(
+ 'MandatoryFieldsNotFilled',
+ 'error'
+ );
+ }
+ }
+
+ public deleteAddress(address: Address): void {
+ const modalRef = this.modalService.open(SafetyQueryDialogComponent);
+ modalRef.componentInstance.title = 'ConfirmDialog.Action.delete';
+ modalRef.componentInstance.body = 'ConfirmDialog.Deletion';
+ modalRef.result.then(() => {
+ this.appState$.dispatch(companyActions.deleteAddress({ payload: address }));
+ if(address.isMainAddress){
+ this.existMainAddress = false;
+ }
+ this.closeAddressDataDetail();
+ }, () => {
+ });
+ }
+
+ public closeAddressDataDetail(): void {
+ this.clearAddressData();
+ this.isAddressDataDetailViewVisible = false;
+ }
+
+ public clearAddressData(): void {
+ this.isCurrentAddressMainAddress = false;
+ this.appState$.dispatch(
+ new SetValueAction(
+ companyAddressDetailsFormReducer.FORM_ID,
+ companyAddressDetailsFormReducer.INITIAL_STATE.value
+ )
+ );
+ this.appState$.dispatch(new ResetAction(companyAddressDetailsFormReducer.FORM_ID));
+ }
+
+ public registerCompanyEvents(): void {
+ // subscribes to formState
+ this.companyFormState$.pipe(takeUntil(this._endSubscriptions$)).subscribe(
+ (formState: FormGroupState<Company>) =>
+ (this.companyCurrentFormState = formState)
+ );
+ }
+
+ public registerCommunicationsDataEvents(): void {
+ // subscribes to formState
+ this.communicationsDataDetailsFormState$.pipe(takeUntil(this._endSubscriptions$)).subscribe(
+ (formState: FormGroupState<CommunicationsData>) =>
+ (this.communicationsDataDetailsCurrentFormState = formState)
+ );
+ }
+
+ public registerAddressEvents(): void {
+ // subscribes to formState
+ this.addressDetailsFormState$.pipe(takeUntil(this._endSubscriptions$)).subscribe(
+ (formState: FormGroupState<Address>) =>
+ (this.addressDetailsCurrentFormState = formState)
+ );
+ }
+
+ private _checkIfMainAddressExist(addresses: Array<Address>){
+ for (let i = 0; i < addresses.length; i++) {
+ const address = addresses[i];
+ if(address.isMainAddress){
+ this.existMainAddress = true;
+ break;
+ }
+ this.existMainAddress = false;
+ }
+ };
+
+ private _checkIfCurrentAddressIsMainAddress(address: Address){
+ this.isCurrentAddressMainAddress = address.isMainAddress ? true : false;
+ };
+
+}
diff --git a/src/app/pages/company/company.module.ts b/src/app/pages/company/company.module.ts
new file mode 100644
index 0000000..b3995da
--- /dev/null
+++ b/src/app/pages/company/company.module.ts
@@ -0,0 +1,74 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterModule } from '@angular/router';
+import { ComponentsModule } from '@shared/components';
+import { TranslateModule } from '@ngx-translate/core';
+import { NgrxFormsModule } from 'ngrx-forms';
+import { FormsModule } from '@angular/forms';
+import { AgGridModule } from 'ag-grid-angular';
+import { DirectivesModule } from '@shared/directives';
+import { FiltersModule } from '@shared/filters/index.module';
+import { ContainersModule } from '@shared/containers';
+import { SetFilterComponent } from '@shared/filters/ag-grid/set-filter/set-filter.component';
+import { CompanyApiClient } from '@pages/company/company-api-client';
+import { CompanyDetailsComponent } from '@pages/company/company-details/company-details.component';
+import { CompanyService } from '@pages/company/company.service';
+import { CompanyDetailsSandBox } from '@pages/company/company-details/company-details.sandbox';
+import { StoreModule } from '@ngrx/store';
+import { companyReducers } from '@shared/store';
+import { CompanyDetailsResolver } from '@pages/company/company-details/company-details.resolver';
+import { CompanyRoutingModule } from '@pages/company/company.routing.module';
+import { EffectsModule } from '@ngrx/effects';
+import { CompanyEffect } from '@shared/store/effects/company/company.effect';
+import { CompanyCommunicationsDataListComponent } from '@pages/company/company-details/communications-data-list/communications-data-list.component';
+import { CompanyCommunicationsDataDetailsComponent } from '@pages/company/company-details/communications-data-details/communications-data-details.component';
+import { CompanyAddressDetailsComponent } from '@pages/company/company-details/address-details/address-details.component';
+import { CompanyAddressListComponent } from '@pages/company/company-details/address-list/address-list.component';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ ComponentsModule,
+ TranslateModule,
+ DirectivesModule,
+ FiltersModule,
+ ReactiveFormsModule,
+ RouterModule,
+ NgrxFormsModule,
+ FormsModule,
+ StoreModule.forFeature('companyData', companyReducers),
+ AgGridModule.withComponents([SetFilterComponent]),
+ ContainersModule,
+ CompanyRoutingModule,
+ EffectsModule.forFeature([
+ CompanyEffect
+ ]),
+ ],
+ declarations: [
+ CompanyDetailsComponent,
+ CompanyCommunicationsDataListComponent,
+ CompanyCommunicationsDataDetailsComponent,
+ CompanyAddressDetailsComponent,
+ CompanyAddressListComponent
+ ],
+ providers: [
+ CompanyService,
+ CompanyApiClient,
+ CompanyDetailsSandBox,
+ CompanyDetailsResolver
+ ],
+})
+export class CompanyModule {}
diff --git a/src/app/pages/company/company.routing.module.ts b/src/app/pages/company/company.routing.module.ts
new file mode 100644
index 0000000..bc5ad6b
--- /dev/null
+++ b/src/app/pages/company/company.routing.module.ts
@@ -0,0 +1,45 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { NgModule } from '@angular/core';
+import { RouterModule, Routes } from '@angular/router';
+import { Globals } from '@shared/constants/globals';
+import { CompanyDetailsComponent } from '@pages/company/company-details/company-details.component';
+import { CompanyDetailsResolver } from '@pages/company/company-details/company-details.resolver';
+
+const PATH = Globals.PATH;
+
+const addNewCompanyRoutes: Routes = [
+ {
+ path: `${PATH.COMPANY}/:contactId`,
+ component: CompanyDetailsComponent,
+ resolve: {
+ company: CompanyDetailsResolver,
+ },
+ }
+];
+
+const editCompanyRoutes: Routes = [
+ {
+ path: `${PATH.COMPANY}/${PATH.NEW}`,
+ component: CompanyDetailsComponent,
+ resolve: {
+ externalPerson: CompanyDetailsResolver
+ },
+ }
+];
+
+@NgModule({
+ imports: [RouterModule.forChild([...addNewCompanyRoutes,...editCompanyRoutes])],
+ exports: [RouterModule]
+})
+export class CompanyRoutingModule { }
diff --git a/src/app/pages/company/company.service.spec.ts b/src/app/pages/company/company.service.spec.ts
new file mode 100644
index 0000000..d5da466
--- /dev/null
+++ b/src/app/pages/company/company.service.spec.ts
@@ -0,0 +1,55 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { CompanyService } from '@pages/company/company.service';
+import { CommunicationsData, Address } from '@shared/models';
+
+describe('CompanyService', () => {
+
+ beforeEach(() => {
+ });
+
+ it('should transform company details', () => {
+ const company: any = { companyName: 'Heysterkamp'};
+ const transContact = CompanyService.companyDetailsAdapter(company);
+
+ expect(transContact.companyName).toBe(company.companyName);
+ });
+
+ it('should transform communicationa data details', () => {
+ const communicationsData: any = { communicationTypeId: 'Heysterkamp'};
+ const transContact = CompanyService.communicationsDataDetailsAdapter(communicationsData);
+
+ expect(transContact.communicationTypeId).toBe(communicationsData.communicationTypeId);
+ });
+
+ it('should transform communicationa data list', () => {
+ const response = [new CommunicationsData()];
+ response[0].communicationTypeId = 'Herr';
+
+ expect(CompanyService.communicationsDataAdapter(response)[0].communicationTypeId).toBe('Herr');
+ });
+
+ it('should transform address data details', () => {
+ const addressData: any = { addressTypeId: 'Heysterkamp'};
+ const transContact = CompanyService.addressesDetailsAdapter(addressData);
+
+ expect(transContact.addressTypeId).toBe(addressData.addressTypeId);
+ });
+
+ it('should transform address data list', () => {
+ const response = [new Address()];
+ response[0].addressTypeId = 'Herr';
+
+ expect(CompanyService.addressesAdapter(response)[0].addressTypeId).toBe('Herr');
+ });
+});
diff --git a/src/app/pages/company/company.service.ts b/src/app/pages/company/company.service.ts
new file mode 100644
index 0000000..9cbcc80
--- /dev/null
+++ b/src/app/pages/company/company.service.ts
@@ -0,0 +1,68 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { Company, CommunicationsData, Address } from '@shared/models';
+import { Injectable } from '@angular/core';
+
+/**
+ * Used to retrieve company
+ *
+ * @export
+ * @class CompanyService
+ */
+@Injectable()
+export class CompanyService {
+ /**
+ * Transforms company details recieved from the API into instance of 'Company'
+ *
+ * @param company
+ */
+ static companyDetailsAdapter(company: any): Company {
+ return new Company(company);
+ }
+
+ /**
+ * Transforms communications data received from the API into instance of 'CommunicationsData[]'
+ *
+ * @param communicationsData
+ */
+ static communicationsDataAdapter(communicationsData: any): Array<CommunicationsData> {
+ return communicationsData.map(communicationsData => new CommunicationsData(communicationsData));
+ }
+
+ /**
+ * Transforms communications data details received from the API into instance of 'CommunicationsData'
+ *
+ * @param response
+ */
+ static communicationsDataDetailsAdapter(communicationsData: CommunicationsData): CommunicationsData {
+ return new CommunicationsData(communicationsData);
+ }
+
+ /**
+ * Transforms company's details addresses received from the API into instance of 'address[]'
+ *
+ * @param addresses
+ */
+ static addressesAdapter(addresses: any): Array<Address> {
+ return addresses.map(address => new Address(address));
+ }
+
+ /**
+ * Transforms company's details addresses details recieved from the API into instance of 'address'
+ *
+ * @param response
+ */
+ static addressesDetailsAdapter(address: Address): Address {
+ return new Address(address);
+ }
+}
diff --git a/src/app/pages/contacts/contacts-api-client.ts b/src/app/pages/contacts/contacts-api-client.ts
index a302b6d..e431d36 100644
--- a/src/app/pages/contacts/contacts-api-client.ts
+++ b/src/app/pages/contacts/contacts-api-client.ts
@@ -10,13 +10,15 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
+import { ModifiedContacts } from '@shared/models/modifiedContacts.model';
+import { Action } from '@ngrx/store';
import { Injectable } from '@angular/core';
import { HttpService, Query, GET, Path, Adapter, PUT, Body, DefaultHeaders } from '@shared/asyncServices/http';
import { Observable } from 'rxjs';
import { ContactsService } from '@pages/contacts/contacts.service';
import { Contact } from '@shared/models';
import { PageRequestInterface } from '@shared/models/page/page-request.interface';
-import { PageModel } from '@app/shared/models/page/page.model';
+import { PageModel } from '@shared/models/page/page.model';
@Injectable()
@DefaultHeaders({
@@ -25,7 +27,14 @@
})
export class ContactsApiClient extends HttpService {
public getContacts(request: PageRequestInterface = null): Observable<PageModel<Contact>> {
- return request !== null ? this._getContactsPage(request.pageNumber ? (request.pageNumber-1) : 0, request.pageSize) : this._getContacts();
+ let modifiedContacts: ModifiedContacts = null;
+ if(request != null){
+ modifiedContacts = request.queryParameter || {};
+ return this._getContactsPage(modifiedContacts.searchText, modifiedContacts.contactTypeId, modifiedContacts.sort, request.pageNumber ? (request.pageNumber - 1) : 0, request.pageSize);
+ } else {
+ return this._getContactsPage(modifiedContacts.searchText, modifiedContacts.contactTypeId, modifiedContacts.sort, 1, 3);
+ }
+
}
/**
@@ -33,19 +42,12 @@
*/
@GET('/contacts')
@Adapter(ContactsService.gridPageAdapter)
- private _getContactsPage(@Query('page') pageNumber: number, @Query('size') pageSize: number): Observable<any> {
+ private _getContactsPage(@Query('searchText') searchtext: string, @Query('contactType') contactTypeId: string, @Query('sort') sort: string, @Query('page') pageNumber: number, @Query('size') pageSize: number): Observable<any> {
return null;
}
+
/**
- * Retrieves all non-paged contacts
- */
- @GET('/contacts')
- @Adapter(ContactsService.gridAdapter)
- private _getContacts(): Observable<any> {
- return null;
- }
- /**
- * Retrieves product details by a given id
+ * Retrieves contacts details by a given id
*
* @param id
*/
diff --git a/src/app/pages/contacts/contacts-list/contacts-list-column-definition.ts b/src/app/pages/contacts/contacts-list/contacts-list-column-definition.ts
index e75a7fb..8772095 100644
--- a/src/app/pages/contacts/contacts-list/contacts-list-column-definition.ts
+++ b/src/app/pages/contacts/contacts-list/contacts-list-column-definition.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -10,40 +10,76 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { ContactTypeCellRendererComponent } from '@app/shared/components/cell-renderer/contact-type-cell-renderer/contact-type-cell-renderer.component';
-import { IconCellRendererComponent } from '@app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component';
+import { ContactTypeCellRendererComponent } from '@shared/components/cell-renderer/contact-type-cell-renderer/contact-type-cell-renderer.component';
+import { IconCellRendererComponent } from '@shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component';
export const CONTACTS_COLDEF = [
{
field: 'name',
+ colId: 'name',
headerName: 'Contacts.Name',
sortable: true,
- filter: 'agTextColumnFilter',
+ filter: true,
+ filterParams: {
+ debounceMs: 1000,
+ },
+ },
+ {
+ field: 'email',
+ colId: 'email',
+ headerName: 'Contacts.Mail',
+ sortable: true,
+ filter: true,
+ filterParams: {
+ debounceMs: 1000,
+ },
},
{
field: 'contactType',
+ colId: 'contactType',
headerName: 'Contacts.ContactType',
sortable: true,
filter: 'agTextColumnFilter',
- cellRendererFramework: ContactTypeCellRendererComponent
+ filterParams: {
+ debounceMs: 1000,
+ },
+ cellRendererFramework: ContactTypeCellRendererComponent,
},
{
field: 'note',
+ colId: 'note',
headerName: 'Contacts.Note',
sortable: true,
filter: 'agTextColumnFilter',
+ filterParams: {
+ debounceMs: 1000,
+ },
},
{
valueGetter: function(params) {
if (params.data.community || params.data.street || params.data.housenumber) {
- return (`${params.data.community}, ${params.data.street} ${params.data.housenumber}`);
+ return `${params.data.community}, ${params.data.street} ${params.data.housenumber}`;
} else {
return '';
}
},
+ colId: 'mainaddress',
headerName: 'Contacts.MainAddress',
sortable: true,
filter: 'agTextColumnFilter',
+ filterParams: {
+ debounceMs: 1000,
+ },
+ },
+ {
+ field: 'department',
+ colId: 'department',
+ headerName: 'Contacts.Department',
+ sortable: true,
+ filter: true,
+ filterParams: {
+ debounceMs: 1000,
+ },
},
{
field: 'tools',
@@ -56,5 +92,5 @@
suppressMenu: true,
suppressSizeToFit: true,
cellRendererFramework: IconCellRendererComponent,
- }
+ },
];
diff --git a/src/app/pages/contacts/contacts-list/contacts-list.component.html b/src/app/pages/contacts/contacts-list/contacts-list.component.html
index 38b992b..ea8880e 100644
--- a/src/app/pages/contacts/contacts-list/contacts-list.component.html
+++ b/src/app/pages/contacts/contacts-list/contacts-list.component.html
@@ -15,12 +15,49 @@
<span>{{ 'Contacts.Title' | translate }}</span>
</div>
<div class="contacts-grid-wrapper" body>
- <div class="diverse-btn">
- <div class="select-type-of-new-contact">
+ <div class="diverse-options">
+ <div class="searching diverse-options-item">
+ <div class="search-options">
+ <input type="text" class="item" id="searchText" placeholder="Suche" (change)="setModifiedContactsSearchText($event.target.value)">
+
+ <select [required]="false" type="text" class="form-control item" (change)="setModifiedContactsContactTypeId($event.target.value)">
+ <option value="{{INTERNAL_PERSON}}">{{ 'Contacts.InternalContact' | translate }}</option>
+ <option value="{{EXTERNAL_PERSON}}">{{ 'Contacts.ExternalContact' | translate }}</option>
+ <option value="{{COMPANY}}">{{ 'Contacts.Company' | translate }}</option>
+ <option value="" selected>{{ 'Contacts.AllContactTypes' | translate }}</option>
+ </select>
+
+ <div class="search-btn">
+ <button type="button" class="btn btn-default btn-sm" (click)="searchContacts()"
+ title="suchen">
+ <em class="fa fa-search fa-lg " aria-hidden="true "></em>
+ </button>
+ </div>
+ </div>
+ </div>
+
+ <div class="sorting-options diverse-options-item">
+ <select [required]="false" type="text" class="form-control item" (change)="setSortingContactType($event.target.value); sortContacts()">
+ <option value="name">{{ 'Contacts.Name' | translate }}</option>
+ <option value="contactType">{{ 'Contacts.ContactType' | translate }}</option>
+ <option value="note">{{ 'Contacts.Note' | translate }}</option>
+ <option value="street">{{ 'Contacts.Street' | translate }}</option>
+ <option value="community">{{ 'Contacts.Community' | translate }}</option>
+ <option value="department">{{ 'Contacts.Department' | translate }}</option>
+ <option value="" selected>{{ 'NoSorting' | translate }}</option>
+ </select>
+
+ <select [required]="false" type="text" class="form-control item" (change)="setSortingOrder($event.target.value); sortContacts()">
+ <option value="asc" selected>{{ 'AscendingSorting' | translate }}</option>
+ <option value="desc">{{ 'DescendingSorting' | translate }}</option>
+ </select>
+ </div>
+
+ <div class="select-type-of-new-contact item">
<select type="text" class="form-control" (change)="navigateTo($event.target.value)">
<option value="" disabled selected>{{ 'Contacts.CreateNewContact' | translate }}</option>
- <option [value]='NEW_INTERNAL_PERSON_PATH'>{{ 'Contacts.InternContact' | translate }}</option>
- <option [value]='NEW_EXTERNAL_PERSON_PATH'>{{ 'Contacts.ExternContact' | translate }}</option>
+ <option [value]='NEW_INTERNAL_PERSON_PATH'>{{ 'Contacts.InternalContact' | translate }}</option>
+ <option [value]='NEW_EXTERNAL_PERSON_PATH'>{{ 'Contacts.ExternalContact' | translate }}</option>
<option [value]='NEW_COMPANY_PATH'>{{ 'Contacts.Company' | translate }}</option>
</select>
</div>
@@ -28,6 +65,7 @@
<ag-grid-angular
[serverside]="contactsSandbox.serversideModel"
+ [queryParameter]="modifiedContacts"
autoresizecolumns
class="ag-theme-balham ag-grid-height"
[gridOptions]="gridOptions"
@@ -36,7 +74,8 @@
[frameworkComponents]="frameworkComponents"
>
</ag-grid-angular>
- <app-spinner [isRunning]="contactsSandbox.contactsLoading$ | async"></app-spinner>
+
+ <app-spinner [isRunning]="contactsSandbox.contactListLoading$ | async"></app-spinner>
</div>
</app-card-layout>
diff --git a/src/app/pages/contacts/contacts-list/contacts-list.component.scss b/src/app/pages/contacts/contacts-list/contacts-list.component.scss
index 46a84d2..582c6ed 100644
--- a/src/app/pages/contacts/contacts-list/contacts-list.component.scss
+++ b/src/app/pages/contacts/contacts-list/contacts-list.component.scss
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -10,35 +10,104 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
- .contacts-grid-wrapper {
- position: relative;
+.contacts-grid-wrapper {
+ position: relative;
}
.dropdown-open:hover {
- background-color: transparent;
+ background-color: transparent;
}
-.diverse-btn{
- display: flex;
- justify-content: flex-end;
- background-color: #f5f7f7;
- border: 1px solid rgb(189, 195, 199);
- padding: 7px 7px 5px 0px;
- margin-bottom: 1px;
+.diverse-options {
+ display: flex;
+ justify-content: space-between;
+ align-content: center;
+ min-width: 982px;
+ background-color: #f5f7f7;
+ border: 1px solid rgb(189, 195, 199);
+ padding: 7px 7px 5px 7px;
+ margin-bottom: 1px;
}
-.ag-grid-height{
- height: calc(100vh - 275px);
+.diverse-options-item {
+ padding-right: 7px;
+ border-right: solid 1px #ddd;
+}
+
+ag-grid-angular {
+ min-width: 982px;
+ height: calc(100vh - 276px);
}
.form-field-label {
- width: 100%;
- font-size: 14px;
- font-weight: bold;
- margin-bottom: 5px;
+ width: 100%;
+ font-size: 13px;
+ font-weight: bold;
+ margin-bottom: 5px;
}
-.select-type-of-new-contact{
- margin-right: 2px;
- margin-bottom: 2px;
+.select-type-of-new-contact {
+ align-self: center;
+ margin-right: 2px;
+}
+
+.searching {
+ display: flex;
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+}
+
+.search-options {
+ display: flex;
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+ align-items: center;
+}
+
+.item {
+ min-width: 170px;
+ margin: 5px;
+}
+
+.search-btn {
+ display: flex;
+ align-items: center;
+}
+
+.search-btn button {
+ margin: 0 5px;
+ background-color: #fff;
+ border: 1px solid #ccc;
+}
+
+.sorting-options {
+ display: flex;
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+ align-items: center;
+}
+
+.diverse-btn {
+ display: flex;
+ justify-content: flex-end;
+ background-color: #f5f7f7;
+ border: 1px solid rgb(189, 195, 199);
+ padding: 7px 7px 5px 0px;
+ margin-bottom: 1px;
+}
+
+.ag-grid-height {
+ height: calc(100vh - 275px);
+}
+
+.form-field-label {
+ width: 100%;
+ font-size: 14px;
+ font-weight: bold;
+ margin-bottom: 5px;
+}
+
+.selectTypeOfNewContact {
+ margin-right: 2px;
+ margin-bottom: 2px;
}
diff --git a/src/app/pages/contacts/contacts-list/contacts-list.component.spec.ts b/src/app/pages/contacts/contacts-list/contacts-list.component.spec.ts
index 065f597..8dc29ae 100644
--- a/src/app/pages/contacts/contacts-list/contacts-list.component.spec.ts
+++ b/src/app/pages/contacts/contacts-list/contacts-list.component.spec.ts
@@ -11,17 +11,16 @@
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
import { ContactsListComponent } from '@pages/contacts/contacts-list/contacts-list.component';
-import { Globals } from '@app/shared/constants/globals';
+import { Globals } from '@shared/constants/globals';
+import { ModifiedContacts } from '@shared/models/modifiedContacts.model';
describe('ContactsListComponent', () => {
let component: ContactsListComponent;
-
let contactsSandbox: any = {};
let router: any = {};
beforeEach(() => {
router = { navigateByUrl() {}, navigate() {} } as any;
-
component = new ContactsListComponent(contactsSandbox, router);
});
@@ -29,7 +28,7 @@
expect(component).toBeTruthy();
});
- it('should create', () => {
+ it('should define gridOptions onInit', () => {
component.ngOnInit();
expect(component.gridOptions).toBeDefined();
@@ -125,4 +124,52 @@
expect(spy).toHaveBeenCalledWith([url]);
});
+
+ it('checks if function searchContacts() would be called and works', () => {
+ const modificationContacts = new ModifiedContacts();
+ component.modifiedContacts = modificationContacts;
+ component.searchContacts();
+ expect(component.modifiedContacts).not.toEqual(modificationContacts);
+ });
+
+ it('checks if function sortContacts() works', () => {
+ const setModifiedContactsSortSpy = spyOn((component as any), '_setModifiedContactsSort');
+ component.sortContacts();
+ expect(setModifiedContactsSortSpy).toHaveBeenCalledTimes(1);
+ });
+
+ it('checks if function setModifiedContactsSearchText() works', () => {
+ component.setModifiedContactsSearchText('big');
+ expect(component.modifiedContacts.searchText).toBe('big');
+ });
+
+ it('checks if function setModifiedContactsContactTypeId() works', () => {
+ component.setModifiedContactsContactTypeId('I_P');
+ expect(component.modifiedContacts.contactTypeId).toBe('I_P');
+ });
+
+ it('checks if function setSortingContactType() works', () => {
+ component.setSortingContactType('name');
+ expect((component as any)._sortingContactType).toBe('name');
+ });
+
+ it('checks if function setSortingOrder() works', () => {
+ component.setSortingOrder('asc');
+ expect((component as any)._sortingOrder).toBe('asc');
+ });
+
+ it('checks if function _setModifiedContactsSortProperty() works', () => {
+ component.setSortingContactType('name');
+ (component as any)._setModifiedContactsSort();
+ expect(component.modifiedContacts.sort).toBe('name,asc');
+
+ (component as any)._sortingOrder = null;
+ (component as any)._setModifiedContactsSort();
+ expect(component.modifiedContacts.sort).toBe(null);
+
+ (component as any)._sortingContactType = null;
+ (component as any)._setModifiedContactsSort();
+ expect(component.modifiedContacts.sort).toBe(null);
+ });
});
+
diff --git a/src/app/pages/contacts/contacts-list/contacts-list.component.ts b/src/app/pages/contacts/contacts-list/contacts-list.component.ts
index fcd9ff1..1d1c3f4 100644
--- a/src/app/pages/contacts/contacts-list/contacts-list.component.ts
+++ b/src/app/pages/contacts/contacts-list/contacts-list.component.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -10,14 +10,14 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { TranslateService } from '@ngx-translate/core';
import { Component } from '@angular/core';
import { ContactsSandbox } from '@pages/contacts/contacts.sandbox';
import { CONTACTS_COLDEF } from '@pages/contacts/contacts-list/contacts-list-column-definition';
import { BaseList } from '@shared/components/base-components/base.list';
-import { SetFilterComponent } from '@app/shared/filters/ag-grid/set-filter/set-filter.component';
+import { SetFilterComponent } from '@shared/filters/ag-grid/set-filter/set-filter.component';
import { Router } from '@angular/router';
-import { Globals } from '@app/shared/constants/globals';
+import { Globals } from '@shared/constants/globals';
+import { ModifiedContacts } from '@shared/models/modifiedContacts.model';
@Component({
selector: 'app-contacts-list',
@@ -25,12 +25,20 @@
styleUrls: ['./contacts-list.component.scss'],
})
export class ContactsListComponent extends BaseList {
- public NEW_EXTERNAL_PERSON_PATH = `/${Globals.PATH.PERSONS}/${Globals.PATH.EXTERNAL}/${Globals.PATH.NEW}`;
- public NEW_INTERNAL_PERSON_PATH = `/${Globals.PATH.PERSONS}/${Globals.PATH.INTERNAL}/${Globals.PATH.NEW}`;
- public NEW_COMPANY_PATH = `/${Globals.PATH.COMPANY}/${Globals.PATH.NEW}`;
+ public readonly NEW_EXTERNAL_PERSON_PATH = `/${Globals.PATH.PERSONS}/${Globals.PATH.EXTERNAL}/${Globals.PATH.NEW}`;
+ public readonly NEW_INTERNAL_PERSON_PATH = `/${Globals.PATH.PERSONS}/${Globals.PATH.INTERNAL}/${Globals.PATH.NEW}`;
+ public readonly NEW_COMPANY_PATH = `/${Globals.PATH.COMPANY}/${Globals.PATH.NEW}`;
+
+ public readonly INTERNAL_PERSON = Globals.CONTACT_TYPE_ID.INTERNAL_PERSON;
+ public readonly EXTERNAL_PERSON = Globals.CONTACT_TYPE_ID.EXTERNAL_PERSON;
+ public readonly COMPANY = Globals.CONTACT_TYPE_ID.COMPANY;
public columnDefinition: any = CONTACTS_COLDEF;
- public frameworkComponents: { setFilterComponent: any };
+ public frameworkComponents: { setFilterComponent: any };
+ public modifiedContacts: ModifiedContacts = new ModifiedContacts();
+
+ private _sortingOrder: string = 'asc';
+ private _sortingContactType: string = '';
constructor(
public contactsSandbox: ContactsSandbox,
@@ -43,16 +51,7 @@
ngOnInit() {
this.gridOptions = {
...this.gridOptions,
- localeText: {
- contains: 'enthält',
- notContains: 'enthält nicht',
- startsWith: 'beginnt mit',
- endsWith: 'endet mit',
- andCondition: 'UND',
- orCondition: 'ODER',
- equals: 'ist gleich',
- notEqual: 'ist nicht gleich',
- }
+ localeText: Globals.LOCALE_TEXT
};
this.gridOptions.context = {
...this.gridOptions.context,
@@ -98,7 +97,41 @@
break;
}
-
this.router.navigate(route !== '/overview' ? [route, event.data.uuid] : [route]);
}
+
+ public setModifiedContactsSearchText(searchText: string){
+ this.modifiedContacts.searchText = searchText;
+ }
+
+ public setModifiedContactsContactTypeId(contactTypeId: string){
+ this.modifiedContacts.contactTypeId = contactTypeId;
+ }
+
+ public setSortingContactType(sortingContactType: string){
+ this._sortingContactType = sortingContactType;
+ }
+
+ public setSortingOrder(sortingOrder: string){
+ this._sortingOrder = sortingOrder;
+ }
+
+ public searchContacts() {
+ this.modifiedContacts = { ...this.modifiedContacts };
+ }
+
+ public sortContacts() {
+ this._setModifiedContactsSort();
+ this.modifiedContacts = { ...this.modifiedContacts };
+ }
+
+ private _setModifiedContactsSort() {
+ if (this._sortingOrder && this._sortingContactType) {
+ const sort = this._sortingContactType + ',' + this._sortingOrder;
+ this.modifiedContacts.sort = sort;
+ }
+ else {
+ this.modifiedContacts.sort = null;
+ }
+ }
}
diff --git a/src/app/pages/contacts/contacts-routing.module.ts b/src/app/pages/contacts/contacts-routing.module.ts
index 6151fe5..f738158 100644
--- a/src/app/pages/contacts/contacts-routing.module.ts
+++ b/src/app/pages/contacts/contacts-routing.module.ts
@@ -18,7 +18,7 @@
{
path: 'overview',
component: ContactsListComponent
- },
+ }
];
@NgModule({
diff --git a/src/app/pages/contacts/contacts.module.ts b/src/app/pages/contacts/contacts.module.ts
index 4e1f579..771f2a4 100644
--- a/src/app/pages/contacts/contacts.module.ts
+++ b/src/app/pages/contacts/contacts.module.ts
@@ -21,17 +21,17 @@
import { ComponentsModule } from '@shared/components';
import { TranslateModule } from '@ngx-translate/core';
-import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import { NgrxFormsModule } from 'ngrx-forms';
import { FormsModule } from '@angular/forms';
import { AgGridModule } from 'ag-grid-angular';
import { DirectivesModule } from '@shared/directives';
import { FiltersModule } from '@shared/filters/index.module';
import { ContainersModule } from '@shared/containers';
-import { SetFilterComponent } from '@app/shared/filters/ag-grid/set-filter/set-filter.component';
-import { ContactsService } from './contacts.service';
-import { ContactsApiClient } from './contacts-api-client';
-// import { ContactsResolver } from './contacts.resolver';
+import { SetFilterComponent } from '@shared/filters/ag-grid/set-filter/set-filter.component';
+import { ContactsService } from '@pages/contacts/contacts.service';
+import { ContactsApiClient } from '@pages/contacts/contacts-api-client';
+import { EffectsModule } from '@ngrx/effects';
+import { ContactsEffects } from '@shared/store/effects/contacts.effect';
@NgModule({
@@ -43,10 +43,10 @@
FiltersModule,
ReactiveFormsModule,
RouterModule,
- NgxDatatableModule,
NgrxFormsModule,
FormsModule,
AgGridModule.withComponents([SetFilterComponent]),
+ EffectsModule.forFeature([ContactsEffects]),
ContainersModule,
ContactsRoutingModule,
],
diff --git a/src/app/pages/contacts/contacts.sandbox.spec.ts b/src/app/pages/contacts/contacts.sandbox.spec.ts
index f619baa..0151399 100644
--- a/src/app/pages/contacts/contacts.sandbox.spec.ts
+++ b/src/app/pages/contacts/contacts.sandbox.spec.ts
@@ -20,20 +20,16 @@
describe('ContactsSandbox', () => {
let service: ContactsSandbox = {} as any;
let appState: Store<State>;
- let actionSubject: ActionsSubject;
- let utilService: UtilService;
- let router: Router;
beforeEach(() => {
appState = { dispatch:()=> {}, pipe: () => of(true), select:()=> of(true) } as any;
- actionSubject = {} as any;
- router = { navigateByUrl() {} } as any;
- service = new ContactsSandbox(appState, actionSubject, router, utilService);
+ service = new ContactsSandbox(appState);
});
it('should create ContactsSandbox service', () => {
expect(service).toBeTruthy();
expect(service).toBeDefined();
});
+
});
diff --git a/src/app/pages/contacts/contacts.sandbox.ts b/src/app/pages/contacts/contacts.sandbox.ts
index 1f55c86..4bce18f 100644
--- a/src/app/pages/contacts/contacts.sandbox.ts
+++ b/src/app/pages/contacts/contacts.sandbox.ts
@@ -1,30 +1,28 @@
- /********************************************************************************
- * Copyright (c) 2020 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- ********************************************************************************/
+/********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/
import { BaseListSandbox } from '@shared/sandbox/base-list.sandbox';
-import { UtilService } from '@shared/utility/utility.service';
-import { Injectable, OnInit } from '@angular/core';
-import { Store, ActionsSubject } from '@ngrx/store';
+import { Injectable } from '@angular/core';
+import { Store } from '@ngrx/store';
import * as store from '@shared/store';
import * as contactsActions from '@shared/store/actions/contacts.action';
-import { Router } from '@angular/router';
import { ServerSideModel } from '@shared/models/server-side.model';
+import { Observable } from 'rxjs';
@Injectable()
export class ContactsSandbox extends BaseListSandbox {
- public contacts$ = this.appState$.select(store.getContactsData);
- public contactsLoading$ = this.appState$.select(store.getContactsLoading);
public serversideModel: ServerSideModel;
+ public contactListLoading$: Observable<boolean> = this.appState$.select(store.getContactsPageLoading);
/**
* Creates an instance of ContactsSandbox.
@@ -36,13 +34,13 @@
* @param {UtilService} utilService
* @memberof ContactsSandbox
*/
- constructor(protected appState$: Store<store.State>, protected actionsSubject: ActionsSubject, protected router: Router, protected utilService: UtilService) {
+ constructor(protected appState$: Store<store.State>) {
super(appState$);
- // this.registerEvents();
this.serversideModel = {
loadAction: contactsActions.loadContactsPage,
successAction: contactsActions.loadContactsPageSuccess,
pageSize: this.pageSize,
};
}
+
}
diff --git a/src/app/pages/contacts/contacts.service.ts b/src/app/pages/contacts/contacts.service.ts
index 6c63989..776626b 100644
--- a/src/app/pages/contacts/contacts.service.ts
+++ b/src/app/pages/contacts/contacts.service.ts
@@ -31,14 +31,6 @@
return response;
}
/**
- * Transforms grid data recieved from the API into array of Model instances
- *
- * @param contacts
- */
- static gridAdapter(response: any): Array<Contact> {
- return response.map(contact => new Contact(contact));
- }
- /**
* Transforms contact details recieved from the API into instance of 'Contact'
*
* @param contact
diff --git a/src/app/pages/persons/external-person/external-person-details/address-details/address-details.component.html b/src/app/pages/persons/external-person/external-person-details/address-details/address-details.component.html
new file mode 100644
index 0000000..7e99d2f
--- /dev/null
+++ b/src/app/pages/persons/external-person/external-person-details/address-details/address-details.component.html
@@ -0,0 +1,202 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<form [ngrxFormState]="externalPersonDetailsSandbox.addressDetailsFormState$ | async">
+ <h4>{{createOrEditAddressData}}</h4>
+ <div>
+ <!-- type -->
+ <div class="form-group row">
+ <label for="addressTypeId" class="col-sm-5 col-form-label">{{ 'Address.AddressType' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ required
+ maxlength="255"
+ class="form-control"
+ id="addressTypeId"
+ [ngrxFormControlState]="((externalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['addressTypeId']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- MainAddress -->
+ <div class="form-group row">
+ <label for="isMainAddress" class="col-sm-5 col-form-label">{{ 'Address.MainAddress' | translate }}</label>
+ <div class="col-sm-6" style="align-self: center;">
+ <input *ngIf="!externalPersonDetailsSandbox.existMainAddress || externalPersonDetailsSandbox.isCurrentAddressMainAddress"
+ type="checkbox"
+ class="form-check-input"
+ id="isMainAddress"
+ [ngrxFormControlState]="((externalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['isMainAddress']"
+ />
+ <span *ngIf="externalPersonDetailsSandbox.existMainAddress && !externalPersonDetailsSandbox.isCurrentAddressMainAddress">(vorhanden)</span>
+ </div>
+ </div>
+
+ <!-- postCard -->
+ <div class="form-group row">
+ <label for="postcode" class="col-sm-5 col-form-label">{{ 'Address.Postcode' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="30"
+ class="form-control"
+ id="postcode"
+ [ngrxFormControlState]="((externalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['postcode']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- community -->
+ <div class="form-group row">
+ <label for="community" class="col-sm-5 col-form-label">{{ 'Address.Community' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="community"
+ [ngrxFormControlState]="((externalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['community']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- community-suffix -->
+ <div class="form-group row">
+ <label for="communitySuffix" class="col-sm-5 col-form-label">{{ 'Address.CommunitySuffix' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="communitySuffix"
+ [ngrxFormControlState]="((externalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['communitySuffix']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- street -->
+ <div class="form-group row">
+ <label for="street" class="col-sm-5 col-form-label">{{ 'Address.Street' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="street"
+ [ngrxFormControlState]="((externalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['street']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- housenumber -->
+ <div class="form-group row">
+ <label for="housenumber" class="col-sm-5 col-form-label">{{ 'Address.Housenumber' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="30"
+ class="form-control"
+ id="housenumber"
+ [ngrxFormControlState]="((externalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['housenumber']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- wgs_84_zone -->
+ <div class="form-group row">
+ <label for="wgs84Zone" class="col-sm-5 col-form-label">{{ 'Address.Wgs84Zone' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="wgs84Zone"
+ [ngrxFormControlState]="((externalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['wgs84Zone']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- longitude -->
+ <div class="form-group row">
+ <label for="longitude" class="col-sm-5 col-form-label">{{ 'Address.Longitude' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="longitude"
+ [ngrxFormControlState]="((externalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['longitude']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- latitude -->
+ <div class="form-group row">
+ <label for="latitude" class="col-sm-5 col-form-label">{{ 'Address.Latitude' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="latitude"
+ [ngrxFormControlState]="((externalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['latitude']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- url_map -->
+ <div class="form-group row">
+ <label for="urlMap" class="col-sm-5 col-form-label">{{ 'Address.UrlMap' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="urlMap"
+ [ngrxFormControlState]="((externalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['urlMap']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- note -->
+ <div class="form-group row">
+ <label for="note" class="col-sm-5 col-form-label">{{ 'Address.Note' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="note"
+ [ngrxFormControlState]="((externalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['note']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- buttons -->
+ <button
+ type="button"
+ class="btn btn-primary btn-sm btn-success"
+ (click)="externalPersonDetailsSandbox.persistAddress()"
+ >
+ {{ 'SaveBtn' | translate }}
+ </button>
+
+ <button
+ type="button"
+ class="btn btn-primary btn-sm"
+ (click)="externalPersonDetailsSandbox.closeAddressDataDetail()"
+ >
+ {{ 'CancelBtn' | translate }}
+ </button>
+ </div>
+</form >
diff --git a/src/app/pages/persons/external-person/external-person-details/address-details/address-details.component.scss b/src/app/pages/persons/external-person/external-person-details/address-details/address-details.component.scss
new file mode 100644
index 0000000..a43bd94
--- /dev/null
+++ b/src/app/pages/persons/external-person/external-person-details/address-details/address-details.component.scss
@@ -0,0 +1,26 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+button {
+ margin: 14px 0px 10px 15px;
+}
+h4 {
+ padding: 15px;
+ padding-top: 18px;
+}
+div.form-group.row {
+ padding-left: 15px;
+}
+
+#isMainAddress{
+ margin-left: 0px;
+}
diff --git a/src/app/pages/persons/external-person/external-person-details/address-details/address-details.component.spec.ts b/src/app/pages/persons/external-person/external-person-details/address-details/address-details.component.spec.ts
new file mode 100644
index 0000000..9c168df
--- /dev/null
+++ b/src/app/pages/persons/external-person/external-person-details/address-details/address-details.component.spec.ts
@@ -0,0 +1,44 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { ExternalPersonAddressDetailsComponent } from '@pages/persons/external-person/external-person-details/address-details/address-details.component';
+
+describe('AddressDetailsComponent', () => {
+ let component: ExternalPersonAddressDetailsComponent;
+ let externalPersonSandbox: any;
+
+ beforeEach(async(() => {
+ externalPersonSandbox = {
+ registerAddressEvents() {},
+ registerExternalPersonEvents() {},
+ endSubscriptions() {},
+ clearAddressData() {},
+ } as any;
+ }));
+
+ beforeEach(() => {
+ component = new ExternalPersonAddressDetailsComponent(externalPersonSandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call registerAddressEvents and clearAddressData onInit', () => {
+ const spy1 = spyOn(externalPersonSandbox, 'registerAddressEvents');
+ const spy2 = spyOn(externalPersonSandbox, 'clearAddressData');
+ component.ngOnInit();
+ expect(spy1).toHaveBeenCalled();
+ expect(spy2).toHaveBeenCalled();
+ });
+});
diff --git a/src/app/pages/persons/external-person/external-person-details/address-details/address-details.component.ts b/src/app/pages/persons/external-person/external-person-details/address-details/address-details.component.ts
new file mode 100644
index 0000000..e5c1b26
--- /dev/null
+++ b/src/app/pages/persons/external-person/external-person-details/address-details/address-details.component.ts
@@ -0,0 +1,33 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { ExternalPersonDetailsSandBox } from '@pages/persons/external-person/external-person-details/external-person-details.sandbox';
+import { Component, OnInit, Input } from '@angular/core';
+
+@Component({
+ selector: 'app-external-person-address-details',
+ templateUrl: './address-details.component.html',
+ styleUrls: ['./address-details.component.scss']
+})
+export class ExternalPersonAddressDetailsComponent implements OnInit {
+
+ @Input() createOrEditAddressData: string;
+
+ constructor(
+ public externalPersonDetailsSandbox: ExternalPersonDetailsSandBox,
+ ) { }
+
+ ngOnInit() {
+ this.externalPersonDetailsSandbox.registerAddressEvents();
+ this.externalPersonDetailsSandbox.clearAddressData();
+ }
+}
diff --git a/src/app/pages/persons/external-person/external-person-details/address-list/address-list.component.html b/src/app/pages/persons/external-person/external-person-details/address-list/address-list.component.html
new file mode 100644
index 0000000..1bef1d3
--- /dev/null
+++ b/src/app/pages/persons/external-person/external-person-details/address-list/address-list.component.html
@@ -0,0 +1,36 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<div class="diverse-options">
+ <div class="new-address">
+ <button class="btn btn-sm btn-primary" (click)="createNewAddressForm()">
+ {{ 'Address.NewAddress' | translate }}
+ </button>
+ </div>
+</div>
+
+
+<ag-grid-angular
+ autoresizecolumns
+ class="ag-theme-balham"
+ style="width: 100%; height: 100%;"
+ [gridOptions]="gridOptions"
+ [rowData]="externalPersonDetailsSandBox.addressList$ | async"
+ [columnDefs]="columnDefinition"
+ [rowSelection]="'single'"
+ [frameworkComponents]="frameworkComponents"
+>
+</ag-grid-angular>
+<app-spinner [isRunning]="externalPersonDetailsSandBox.addressListLoading$ | async"></app-spinner>
+
+
+
diff --git a/src/app/pages/persons/external-person/external-person-details/address-list/address-list.component.scss b/src/app/pages/persons/external-person/external-person-details/address-list/address-list.component.scss
new file mode 100644
index 0000000..63a5ad3
--- /dev/null
+++ b/src/app/pages/persons/external-person/external-person-details/address-list/address-list.component.scss
@@ -0,0 +1,27 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+ .diverse-options {
+ display: flex;
+ justify-content: flex-end;
+ align-content: center;
+ background-color: #f5f7f7;
+ border: 1px solid rgb(189, 195, 199);
+ padding: 7px 7px 5px 7px;
+ margin-bottom: 1px;
+}
+
+.diverse-options-item {
+ width: 400px;
+ padding-right: 7px;
+ border-right: solid 1px #ddd;
+}
diff --git a/src/app/pages/persons/external-person/external-person-details/address-list/address-list.component.spec.ts b/src/app/pages/persons/external-person/external-person-details/address-list/address-list.component.spec.ts
new file mode 100644
index 0000000..2f71fcf
--- /dev/null
+++ b/src/app/pages/persons/external-person/external-person-details/address-list/address-list.component.spec.ts
@@ -0,0 +1,73 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { ExternalPersonAddressListComponent } from '@pages/persons/external-person/external-person-details/address-list/address-list.component';
+import { of } from 'rxjs/observable/of';
+
+describe('AddressListComponent', () => {
+ let component: ExternalPersonAddressListComponent;
+ let externalPersonSandbox: any;
+
+ beforeEach(async(() => {
+ externalPersonSandbox = {
+ registerAddressEvents() {},
+ registerExternalPersonEvents() {},
+ endSubscriptions() {},
+ deleteAddress() {},
+ clearAddressData() {},
+ } as any;
+ }));
+
+ beforeEach(() => {
+ component = new ExternalPersonAddressListComponent(externalPersonSandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should define gridOptions onInit', () => {
+ component.ngOnInit();
+
+ expect(component.gridOptions).toBeDefined();
+ expect(component.gridOptions.context).toBeDefined();
+ });
+
+ it('should emit if BusEvents is edit ', () => {
+ const spy = spyOn(component.externalPersonDetailsIdLoaded, 'emit');
+ const event: any = {type: 'edit', data: {id: 'id'}};
+ component.gridOptions.context.eventSubject = of(event);
+ component.ngOnInit();
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should deleteAddress if BusEvents is delete', () => {
+ const spy = spyOn(externalPersonSandbox, 'deleteAddress');
+ const event: any = {type: 'delete', data: {id: 'id'}};
+ component.gridOptions.context.eventSubject = of(event);
+ component.ngOnInit();
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should clearAddress and close edit area if callcreateNewAddressForm', () => {
+ const spy = spyOn(externalPersonSandbox, 'clearAddressData');
+ const spyEmit = spyOn(component.createNewExternalPerson, 'emit');
+ component.createNewAddressForm();
+
+ expect(spy).toHaveBeenCalled();
+ expect(spyEmit).toHaveBeenCalled();
+ });
+});
+
diff --git a/src/app/pages/persons/external-person/external-person-details/address-list/address-list.component.ts b/src/app/pages/persons/external-person/external-person-details/address-list/address-list.component.ts
new file mode 100644
index 0000000..61d3a58
--- /dev/null
+++ b/src/app/pages/persons/external-person/external-person-details/address-list/address-list.component.ts
@@ -0,0 +1,62 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { ExternalPersonDetailsSandBox } from '@pages/persons/external-person/external-person-details/external-person-details.sandbox';
+import { BaseList } from '@shared/components/base-components/base.list';
+import { Component, EventEmitter, Output } from '@angular/core';
+import { ADDRESS_LIST_COLDEF } from '@shared/components/column-definitions/addresses-data-list-column-definition';
+import { Globals } from '@shared/constants/globals';
+
+
+@Component({
+ selector: 'app-external-person-address-list',
+ templateUrl: './address-list.component.html',
+ styleUrls: ['./address-list.component.scss']
+})
+export class ExternalPersonAddressListComponent extends BaseList {
+
+ @Output() externalPersonDetailsIdLoaded: EventEmitter<string> = new EventEmitter();
+ @Output() createNewExternalPerson: EventEmitter<string> = new EventEmitter();
+
+ public columnDefinition = ADDRESS_LIST_COLDEF;
+
+
+ constructor(public externalPersonDetailsSandBox: ExternalPersonDetailsSandBox) {
+ super();
+ }
+
+ ngOnInit() {
+ this.gridOptions = {
+ ...this.gridOptions,
+ localeText: Globals.LOCALE_TEXT
+ };
+ this.gridOptions.context = {
+ ...this.gridOptions.context,
+ icons: { edit: true, delete: true }
+ };
+
+ this.gridOptions.context.eventSubject.subscribe(event => {
+ if (event.type === 'edit') {
+ this.externalPersonDetailsIdLoaded.emit(event.data.id);
+ }
+ if (event.type === 'delete') {
+ this.externalPersonDetailsSandBox.deleteAddress(event.data);
+ }
+ });
+ }
+
+ public createNewAddressForm(){
+ this.externalPersonDetailsSandBox.clearAddressData();
+ this.createNewExternalPerson.emit(null);
+ }
+
+}
diff --git a/src/app/pages/persons/external-person/external-person-details/communications-data-details/communications-data-details.component.html b/src/app/pages/persons/external-person/external-person-details/communications-data-details/communications-data-details.component.html
new file mode 100644
index 0000000..c5dbac6
--- /dev/null
+++ b/src/app/pages/persons/external-person/external-person-details/communications-data-details/communications-data-details.component.html
@@ -0,0 +1,75 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<form [ngrxFormState]="externalPersonDetailsSandbox.communicationsDataDetailsFormState$ | async">
+ <h4>{{createOrEditCommunicationsData}}</h4>
+ <div>
+ <!-- type -->
+ <div class="form-group row">
+ <label for="communicationType" class="col-sm-4 col-form-label">{{ 'CommunicationsData.CommunicationType' | translate }}</label>
+ <div class="col-sm-7">
+ <select
+ type="text"
+ class="form-control"
+ [ngrxFormControlState]="((externalPersonDetailsSandbox.communicationsDataDetailsFormState$ | async)?.controls)['communicationTypeId']">
+ <option [value]="">{{ 'SelectOption' | translate }}</option> -->
+ <option *ngFor="let communicationType of communicationTypesSandbox.communicationTypes$ | async" [disabled]="communicationType.isDisabled" [value]="communicationType.id">{{communicationType.type}}</option>
+ </select>
+ </div>
+ </div>
+
+ <!-- communicationData -->
+ <div class="form-group row">
+ <label for="communicationData" class="col-sm-4 col-form-label">{{ 'CommunicationsData.CommunicationData' | translate }}</label>
+ <div class="col-sm-7">
+ <input type="text"
+ maxlength="1024"
+ class="form-control"
+ id="communicationData"
+ [ngrxFormControlState]="((externalPersonDetailsSandbox.communicationsDataDetailsFormState$ | async)?.controls)['communicationData']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- note -->
+ <div class="form-group row">
+ <label for="note" class="col-sm-4 col-form-label">{{ 'CommunicationsData.Note' | translate }}</label>
+ <div class="col-sm-7">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="note"
+ [ngrxFormControlState]="((externalPersonDetailsSandbox.communicationsDataDetailsFormState$ | async)?.controls)['note']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- buttons -->
+ <button
+ type="button"
+ class="btn btn-primary btn-sm btn-success"
+ (click)="externalPersonDetailsSandbox.persistCommunicationsData()"
+ >
+ {{ 'SaveBtn' | translate }}
+ </button>
+
+ <button
+ type="button"
+ class="btn btn-primary btn-sm"
+ (click)="externalPersonDetailsSandbox.closeCommunicationsDataDetail()"
+ >
+ {{ 'CancelBtn' | translate }}
+ </button>
+ </div>
+</form >
diff --git a/src/app/pages/persons/external-person/external-person-details/communications-data-details/communications-data-details.component.scss b/src/app/pages/persons/external-person/external-person-details/communications-data-details/communications-data-details.component.scss
new file mode 100644
index 0000000..b959869
--- /dev/null
+++ b/src/app/pages/persons/external-person/external-person-details/communications-data-details/communications-data-details.component.scss
@@ -0,0 +1,25 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+button {
+ margin: 14px 0px 10px 15px;
+}
+h4 {
+ padding: 15px;
+ padding-top: 18px;
+}
+div.form-group.row {
+ padding-left: 15px;
+}
+select option[disabled]{
+ background-color: rgb(160, 164, 168);
+}
diff --git a/src/app/pages/persons/external-person/external-person-details/communications-data-details/communications-data-details.component.spec.ts b/src/app/pages/persons/external-person/external-person-details/communications-data-details/communications-data-details.component.spec.ts
new file mode 100644
index 0000000..aa4e1d5
--- /dev/null
+++ b/src/app/pages/persons/external-person/external-person-details/communications-data-details/communications-data-details.component.spec.ts
@@ -0,0 +1,48 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { ExternalPersonCommunicationsDataDetailsComponent } from '@pages/persons/external-person/external-person-details/communications-data-details/communications-data-details.component';
+
+describe('ExternalPersonCommunicationsDataDetailsComponent', () => {
+ let component: ExternalPersonCommunicationsDataDetailsComponent;
+ let externalPersonSandbox: any;
+ let communicationTypesSandbox: any;
+
+ beforeEach(async(() => {
+ externalPersonSandbox = {
+ registerCommunicationsDataEvents() {},
+ registerExternalPersonEvents() {},
+ endSubscriptions() {},
+ clearCommunicationsData() {},
+ } as any;
+
+ communicationTypesSandbox = {
+ } as any;
+ }));
+
+ beforeEach(() => {
+ component = new ExternalPersonCommunicationsDataDetailsComponent(externalPersonSandbox, communicationTypesSandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call registerCommunicationsDataEvents and clearCommunicationsData onInit', () => {
+ const spy1 = spyOn(externalPersonSandbox, 'registerCommunicationsDataEvents');
+ const spy2 = spyOn(externalPersonSandbox, 'clearCommunicationsData');
+ component.ngOnInit();
+ expect(spy1).toHaveBeenCalled();
+ expect(spy2).toHaveBeenCalled();
+ });
+});
diff --git a/src/app/pages/persons/external-person/external-person-details/communications-data-details/communications-data-details.component.ts b/src/app/pages/persons/external-person/external-person-details/communications-data-details/communications-data-details.component.ts
new file mode 100644
index 0000000..1626508
--- /dev/null
+++ b/src/app/pages/persons/external-person/external-person-details/communications-data-details/communications-data-details.component.ts
@@ -0,0 +1,36 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { ExternalPersonDetailsSandBox } from '@pages/persons/external-person/external-person-details/external-person-details.sandbox';
+import { Component, OnInit, Input } from '@angular/core';
+import { CommunicationTypesSandbox } from '@pages/admin/communication-types/communication-types.sandbox';
+
+@Component({
+ selector: 'app-external-person-communications-data-details',
+ templateUrl: './communications-data-details.component.html',
+ styleUrls: ['./communications-data-details.component.scss']
+})
+export class ExternalPersonCommunicationsDataDetailsComponent implements OnInit {
+
+ @Input() createOrEditCommunicationsData: string;
+
+ constructor(
+ public externalPersonDetailsSandbox: ExternalPersonDetailsSandBox,
+ public communicationTypesSandbox: CommunicationTypesSandbox
+ ) { }
+
+ ngOnInit() {
+ this.externalPersonDetailsSandbox.registerCommunicationsDataEvents();
+ this.externalPersonDetailsSandbox.clearCommunicationsData();
+ }
+
+}
diff --git a/src/app/pages/persons/external-person/external-person-details/communications-data-list/communications-data-list.component.html b/src/app/pages/persons/external-person/external-person-details/communications-data-list/communications-data-list.component.html
new file mode 100644
index 0000000..d1f9827
--- /dev/null
+++ b/src/app/pages/persons/external-person/external-person-details/communications-data-list/communications-data-list.component.html
@@ -0,0 +1,36 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<div class="diverse-options">
+ <div class="new-communicationsData">
+ <button class="btn btn-sm btn-primary" (click)="createNewCommunicationsDataForm()">
+ {{ 'CommunicationsData.NewCommunicationsData' | translate }}
+ </button>
+ </div>
+</div>
+
+
+<ag-grid-angular
+ autoresizecolumns
+ class="ag-theme-balham ag-grid-height"
+ style="width: 100%; height: 100%;"
+ [gridOptions]="gridOptions"
+ [rowData]="externalPersonDetailsSandBox.communicationsDataList$ | async"
+ [columnDefs]="columnDefinition"
+ [rowSelection]="'single'"
+ [frameworkComponents]="frameworkComponents"
+>
+</ag-grid-angular>
+<app-spinner [isRunning]="externalPersonDetailsSandBox.communicationsDataListLoading$ | async"></app-spinner>
+
+
+
diff --git a/src/app/pages/persons/external-person/external-person-details/communications-data-list/communications-data-list.component.scss b/src/app/pages/persons/external-person/external-person-details/communications-data-list/communications-data-list.component.scss
new file mode 100644
index 0000000..63a5ad3
--- /dev/null
+++ b/src/app/pages/persons/external-person/external-person-details/communications-data-list/communications-data-list.component.scss
@@ -0,0 +1,27 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+ .diverse-options {
+ display: flex;
+ justify-content: flex-end;
+ align-content: center;
+ background-color: #f5f7f7;
+ border: 1px solid rgb(189, 195, 199);
+ padding: 7px 7px 5px 7px;
+ margin-bottom: 1px;
+}
+
+.diverse-options-item {
+ width: 400px;
+ padding-right: 7px;
+ border-right: solid 1px #ddd;
+}
diff --git a/src/app/pages/persons/external-person/external-person-details/communications-data-list/communications-data-list.component.spec.ts b/src/app/pages/persons/external-person/external-person-details/communications-data-list/communications-data-list.component.spec.ts
new file mode 100644
index 0000000..e813b1f
--- /dev/null
+++ b/src/app/pages/persons/external-person/external-person-details/communications-data-list/communications-data-list.component.spec.ts
@@ -0,0 +1,73 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { ExternalPersonCommunicationsDataListComponent } from '@pages/persons/external-person/external-person-details/communications-data-list/communications-data-list.component';
+import { of } from 'rxjs/observable/of';
+
+describe('ExternalPersonCommunicationsDataListComponent', () => {
+ let component: ExternalPersonCommunicationsDataListComponent;
+ let externalPersonSandbox: any;
+
+ beforeEach(async(() => {
+ externalPersonSandbox = {
+ registerCommunicationsDataEvents() {},
+ registerExternalPersonEvents() {},
+ endSubscriptions() {},
+ deleteCommunicationsData() {},
+ clearCommunicationsData() {},
+ } as any;
+ }));
+
+ beforeEach(() => {
+ component = new ExternalPersonCommunicationsDataListComponent(externalPersonSandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should define gridOptions onInit', () => {
+ component.ngOnInit();
+
+ expect(component.gridOptions).toBeDefined();
+ expect(component.gridOptions.context).toBeDefined();
+ });
+
+ it('should emit if BusEvents is edit ', () => {
+ const spy = spyOn(component.externalPersonDetailsIdLoaded, 'emit');
+ const event: any = {type: 'edit', data: {id: 'id'}};
+ component.gridOptions.context.eventSubject = of(event);
+ component.ngOnInit();
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should deleteCommunicationsData if BusEvents is delete', () => {
+ const spy = spyOn(externalPersonSandbox, 'deleteCommunicationsData');
+ const event: any = {type: 'delete', data: {id: 'id'}};
+ component.gridOptions.context.eventSubject = of(event);
+ component.ngOnInit();
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should clearCommunicationsData and close edit area if callcreateNewCommunicationsDataForm', () => {
+ const spy = spyOn(externalPersonSandbox, 'clearCommunicationsData');
+ const spyEmit = spyOn(component.createNewExternalPerson, 'emit');
+ component.createNewCommunicationsDataForm();
+
+ expect(spy).toHaveBeenCalled();
+ expect(spyEmit).toHaveBeenCalled();
+ });
+});
+
diff --git a/src/app/pages/persons/external-person/external-person-details/communications-data-list/communications-data-list.component.ts b/src/app/pages/persons/external-person/external-person-details/communications-data-list/communications-data-list.component.ts
new file mode 100644
index 0000000..3493a92
--- /dev/null
+++ b/src/app/pages/persons/external-person/external-person-details/communications-data-list/communications-data-list.component.ts
@@ -0,0 +1,61 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { ExternalPersonDetailsSandBox } from '@pages/persons/external-person/external-person-details/external-person-details.sandbox';
+import { BaseList } from '@shared/components/base-components/base.list';
+import { Component, EventEmitter, Output } from '@angular/core';
+import { COMMUNICATIONS_DATA_LIST_COLDEF } from '@shared/components/column-definitions/communications-data-list-column-definition';
+import { Globals } from '@shared/constants/globals';
+
+@Component({
+ selector: 'app-external-person-communications-data-list',
+ templateUrl: './communications-data-list.component.html',
+ styleUrls: ['./communications-data-list.component.scss']
+})
+export class ExternalPersonCommunicationsDataListComponent extends BaseList {
+
+ @Output() externalPersonDetailsIdLoaded: EventEmitter<string> = new EventEmitter();
+ @Output() createNewExternalPerson: EventEmitter<string> = new EventEmitter();
+
+ public columnDefinition = COMMUNICATIONS_DATA_LIST_COLDEF;
+
+
+ constructor(public externalPersonDetailsSandBox: ExternalPersonDetailsSandBox) {
+ super();
+ }
+
+ ngOnInit() {
+ this.gridOptions = {
+ ...this.gridOptions,
+ localeText: Globals.LOCALE_TEXT
+ };
+ this.gridOptions.context = {
+ ...this.gridOptions.context,
+ icons: { edit: true, delete: true }
+ };
+
+ this.gridOptions.context.eventSubject.subscribe(event => {
+ if (event.type === 'edit') {
+ this.externalPersonDetailsIdLoaded.emit(event.data.id);
+ }
+ if (event.type === 'delete') {
+ this.externalPersonDetailsSandBox.deleteCommunicationsData(event.data);
+ }
+ });
+ }
+
+ public createNewCommunicationsDataForm(){
+ this.externalPersonDetailsSandBox.clearCommunicationsData();
+ this.createNewExternalPerson.emit(null);
+ }
+
+}
diff --git a/src/app/pages/persons/external-person/external-person-details/external-person-details.component.html b/src/app/pages/persons/external-person/external-person-details/external-person-details.component.html
index 597dc67..624356f 100644
--- a/src/app/pages/persons/external-person/external-person-details/external-person-details.component.html
+++ b/src/app/pages/persons/external-person/external-person-details/external-person-details.component.html
@@ -15,7 +15,7 @@
<span>{{ 'External.Title' | translate }}</span>
</div>
<div class="contacts-grid-wrapper" body>
- <form [ngrxFormState]="externalPersonSandBox.formState$ | async">
+ <form [ngrxFormState]="externalPersonSandBox.externPersonDetailsFormState$ | async">
<div>
<!-- firstName -->
<div class="form-group row">
@@ -23,9 +23,10 @@
<div class="col-sm-4">
<input
type="text"
+ maxlength="255"
class="form-control"
id="firstName"
- [ngrxFormControlState]="((externalPersonSandBox.formState$ | async)?.controls)['firstName']"
+ [ngrxFormControlState]="((externalPersonSandBox.externPersonDetailsFormState$ | async)?.controls)['firstName']"
autocomplete="off"
/>
</div>
@@ -36,11 +37,12 @@
<label for="lastName" class="col-sm-2 col-form-label">{{ 'External.LastName' | translate }}</label>
<div class="col-sm-4">
<input
- [required]="true"
+ required
type="text"
+ maxlength="255"
class="form-control"
id="lastName"
- [ngrxFormControlState]="((externalPersonSandBox.formState$ | async)?.controls)['lastName']"
+ [ngrxFormControlState]="((externalPersonSandBox.externPersonDetailsFormState$ | async)?.controls)['lastName']"
autocomplete="off"
/>
</div>
@@ -52,9 +54,10 @@
<div class="col-sm-4">
<input
type="text"
+ maxlength="255"
class="form-control"
id="title"
- [ngrxFormControlState]="((externalPersonSandBox.formState$ | async)?.controls)['title']"
+ [ngrxFormControlState]="((externalPersonSandBox.externPersonDetailsFormState$ | async)?.controls)['title']"
autocomplete="off"
/>
</div>
@@ -67,33 +70,24 @@
<select
type="text"
class="form-control"
- [ngrxFormControlState]="((externalPersonSandBox.formState$ | async)?.controls)['salutationId']">
+ [ngrxFormControlState]="((externalPersonSandBox.externPersonDetailsFormState$ | async)?.controls)['salutationId']">
<option [value]="">{{ 'SelectOption' | translate }}</option> -->
- <option *ngFor="let salutation of externalPersonSandBox.salutations$ | async" [value]="salutation.id">{{salutation.type}}</option>
+ <option *ngFor="let salutation of salutationSandBox.salutations$ | async" [value]="salutation.id">{{salutation.type}}</option>
</select>
</div>
</div>
- <!-- personType -->
- <div class="form-group row">
- <label for="personType" class="col-sm-2 col-form-label">{{ 'External.PersonType' | translate }}</label>
- <!-- <div class="col-sm-4">
+ <!-- personType -->
+ <div class="form-group row">
+ <label for="personType" class="col-sm-2 col-form-label">{{ 'External.PersonType' | translate }}</label>
+ <div class="col-sm-4">
<select
type="text"
class="form-control"
- [ngrxFormControlState]="((externalPersonSandBox.formState$ | async)?.controls)['personTypeId']">
+ [ngrxFormControlState]="((externalPersonSandBox.externPersonDetailsFormState$ | async)?.controls)['personTypeId']">
<option [value]="">{{ 'SelectOption' | translate }}</option>
<option *ngFor="let personType of externalPersonSandBox.personTypes$ | async" [value]="personType.id">{{personType.type}}</option>
</select>
- </div> -->
- <div class="col-sm-4">
- <input
- type="text"
- class="form-control"
- id="personType"
- [ngrxFormControlState]="((externalPersonSandBox.formState$ | async)?.controls)['personType']"
- autocomplete="off"
- />
</div>
</div>
@@ -103,17 +97,47 @@
<div class="col-sm-4">
<input
type="text"
+ maxlength="255"
class="form-control"
id="contactNote"
- [ngrxFormControlState]="((externalPersonSandBox.formState$ | async)?.controls)['contactNote']"
+ [ngrxFormControlState]="((externalPersonSandBox.externPersonDetailsFormState$ | async)?.controls)['contactNote']"
autocomplete="off"
/>
</div>
</div>
- <!-- buttons -->
- <button type="button" class="btn btn-success" (click)="save()">{{ 'SaveBtn' | translate }}</button>
+ <!-- buttons -->
+ <button type="button" class="btn btn-success" (click)="externalPersonSandBox.persistExternalPerson()">{{ 'SaveBtn' | translate }}</button>
+ <button type="button" class="btn btn-primary cancel-button" routerLink="/overview">
+ {{ 'CancelBtn' | translate }}
+ </button>
</div>
</form>
+
+ <app-expandable class="expandable-address" *ngIf="isExpandableVisible">
+ <span header>{{ 'Contacts.AddressList' | translate }}</span>
+ <div class="expandable-body-container" body>
+ <div class="table-detail-view-address" *ngIf="externalPersonSandBox.isAddressDataDetailViewVisible">
+ <app-external-person-address-details [createOrEditAddressData]="createOrEditAddressData"></app-external-person-address-details>
+ </div>
+ <div class="table-view-address">
+ <app-external-person-address-list (externalPersonDetailsIdLoaded)="loadAddressDetail($event)" (createNewExternalPerson)="loadAddressDetail($event)"></app-external-person-address-list>
+ </div>
+ </div>
+ </app-expandable>
+
+ <app-expandable class="expandable-communication" *ngIf="isExpandableVisible">
+ <span header>{{ 'Contacts.CommunicationsDataList' | translate }}</span>
+ <div class="expandable-body-container" body>
+ <div class="table-detail-view-communication" *ngIf="externalPersonSandBox.isCommunicationsDataDetailViewVisible">
+ <app-external-person-communications-data-details [createOrEditCommunicationsData]="createOrEditCommunicationsData"></app-external-person-communications-data-details>
+ </div>
+ <div class="table-view-communication">
+ <app-external-person-communications-data-list (externalPersonDetailsIdLoaded)="loadCommunicationsDataDetail($event)" (createNewExternalPerson)="loadCommunicationsDataDetail($event)"></app-external-person-communications-data-list>
+ </div>
+ </div>
+ </app-expandable>
+
</div>
+
</app-card-layout>
diff --git a/src/app/pages/persons/external-person/external-person-details/external-person-details.component.scss b/src/app/pages/persons/external-person/external-person-details/external-person-details.component.scss
index 46dc5b1..c7186fc 100644
--- a/src/app/pages/persons/external-person/external-person-details/external-person-details.component.scss
+++ b/src/app/pages/persons/external-person/external-person-details/external-person-details.component.scss
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -10,3 +10,33 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
+.cancel-button {
+ margin-left: 16px;
+}
+.expandable-body-container {
+ display: flex;
+ flex-direction: row;
+ height: 100%;
+}
+.table-detail-view-address {
+ height: 756px;
+ width: 461px;
+}
+.table-view-address {
+ height: 711px;
+ flex-grow: 1;
+}
+.expandable-address ::ng-deep .collapse5 {
+ height: 758px;
+}
+.table-detail-view-communication {
+ height: 296px;
+ width: 461px;
+}
+.table-view-communication {
+ height: 250px;
+ flex-grow: 1;
+}
+.expandable-communication ::ng-deep .collapse5 {
+ height: 297px;
+}
diff --git a/src/app/pages/persons/external-person/external-person-details/external-person-details.component.spec.ts b/src/app/pages/persons/external-person/external-person-details/external-person-details.component.spec.ts
index a2e0832..9ceb60b 100644
--- a/src/app/pages/persons/external-person/external-person-details/external-person-details.component.spec.ts
+++ b/src/app/pages/persons/external-person/external-person-details/external-person-details.component.spec.ts
@@ -10,30 +10,31 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { ExternalPersonDetailsComponent } from '@app/pages/persons/external-person/external-person-details/external-person-details.component';
+import { ExternalPersonDetailsComponent } from '@pages/persons/external-person/external-person-details/external-person-details.component';
describe('ExternalPersonDetailsComponent', () => {
let component: ExternalPersonDetailsComponent;
- let router: any;
let externalPersonSandbox: any;
+ let translate: any;
let salutationsSandbox: any;
beforeEach(() => {
- router = { navigateByUrl() {} } as any;
-
externalPersonSandbox = {
- updatingState() {},
- currentFormState: { isValid: true },
- persistExternalPerson() {},
- utilService: { displayNotification: () => {} }
+ registerExternalPersonEvents() {},
+ endSubscriptions() {},
+ loadCommunicationsDataDetails() {},
+ loadExternalPersonDetailsAddressDetails() {},
} as any;
salutationsSandbox = {
- loadSalutations() {}
} as any;
- component = new ExternalPersonDetailsComponent(externalPersonSandbox, salutationsSandbox);
+ translate = {
+ instant() {},
+ } as any;
+
+ component = new ExternalPersonDetailsComponent(externalPersonSandbox, salutationsSandbox, translate);
});
it('should create', () => {
@@ -41,17 +42,74 @@
});
it('should loadSalutations on init', () => {
- const spy = spyOn(salutationsSandbox, 'loadSalutations');
+ const spy = spyOn(externalPersonSandbox, 'registerExternalPersonEvents');
component.ngOnInit();
expect(spy).toHaveBeenCalled();
});
- it('should call persist if form valid', () => {
- const persistSpy = spyOn(externalPersonSandbox, 'persistExternalPerson');
- component.save();
+ it('should end all subscriptions for this sandbox onDestroy', () => {
+ const spy = spyOn(externalPersonSandbox, 'endSubscriptions');
+ component.ngOnDestroy();
- expect(persistSpy).toHaveBeenCalled();
+ expect(spy).toHaveBeenCalled();
+ });
+ it('should call translate instant if no adress id', () => {
+ const spy = spyOn(translate, 'instant');
+ component.loadAddressDetail(null);
+
+ expect(spy).toHaveBeenCalledWith('Address.NewAddress');
+ });
+
+ it('should call translate instant if there is an adress id', () => {
+ const id = 'id';
+ const spy = spyOn(translate, 'instant');
+ const spy1 = spyOn(externalPersonSandbox, 'loadExternalPersonDetailsAddressDetails');
+ component.loadAddressDetail(id);
+
+ expect(spy).toHaveBeenCalledWith('Address.EditAddress');
+ expect(spy1).toHaveBeenCalledWith(id);
+ });
+
+ it('should call translate instant if there is an adress id', () => {
+ component.externalPersonSandBox.isCommunicationsDataDetailViewVisible = false;
+ component.loadCommunicationsDataDetail(null);
+ expect(component.externalPersonSandBox.isCommunicationsDataDetailViewVisible).toBeTruthy();
+ });
+
+ it('should call translate instant if there is id', () => {
+ component.externalPersonSandBox.isAddressDataDetailViewVisible = false;
+ component.loadAddressDetail(null);
+ expect(component.externalPersonSandBox.isAddressDataDetailViewVisible).toBeTruthy();
+ });
+
+ it('should call translate instant if no communications data id', () => {
+ const spy = spyOn(translate, 'instant');
+ component.loadCommunicationsDataDetail(null);
+
+ expect(spy).toHaveBeenCalledWith('CommunicationsData.NewCommunicationsData');
+ });
+
+ it('should call translate instant if there is an communications data id', () => {
+ const id = 'id';
+ const spy = spyOn(translate, 'instant');
+ const spy1 = spyOn(externalPersonSandbox, 'loadCommunicationsDataDetails');
+ component.loadCommunicationsDataDetail(id);
+
+ expect(spy).toHaveBeenCalledWith('CommunicationsData.EditCommunicationsData');
+ expect(spy1).toHaveBeenCalledWith(id);
+ });
+
+ it('should call translate instant if there is an communications data id', () => {
+ component.externalPersonSandBox.isCommunicationsDataDetailViewVisible = false;
+ component.loadCommunicationsDataDetail(null);
+ expect(component.externalPersonSandBox.isCommunicationsDataDetailViewVisible).toBeTruthy();
+ });
+
+ it('should set expandableVisible to "true" if externalPersonContactId is defined', () => {
+ component.externalPersonSandBox.externalPersonContactId = 'test';
+ (component as any)._hideExpandable();
+ expect(component.isExpandableVisible).toBeTruthy();
});
});
diff --git a/src/app/pages/persons/external-person/external-person-details/external-person-details.component.ts b/src/app/pages/persons/external-person/external-person-details/external-person-details.component.ts
index 6fc5efc..36bb45c 100644
--- a/src/app/pages/persons/external-person/external-person-details/external-person-details.component.ts
+++ b/src/app/pages/persons/external-person/external-person-details/external-person-details.component.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -10,37 +10,63 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { ExternalPersonDetailsSandBox } from '@app/pages/persons/external-person/external-person-details/external-person-details.sandbox';
-import { Component, OnInit } from '@angular/core';
-import { ExternalPerson } from '@app/shared/models';
-import { SalutationsSandbox } from '@app/pages/admin/salutations/salutations.sandbox';
+import { ExternalPersonDetailsSandBox } from '@pages/persons/external-person/external-person-details/external-person-details.sandbox';
+import { SalutationsSandbox } from '@pages/admin/salutations/salutations.sandbox';
+import { Component, OnInit, OnDestroy } from '@angular/core';
+import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'app-external-person-details',
templateUrl: './external-person-details.component.html',
- styleUrls: ['./external-person-details.component.scss']
+ styleUrls: ['./external-person-details.component.scss'],
})
-export class ExternalPersonDetailsComponent implements OnInit {
+export class ExternalPersonDetailsComponent implements OnInit, OnDestroy {
+
+ public createOrEditAddressData = '';
+ public isExpandableVisible = true;
+ public createOrEditCommunicationsData = '';
constructor(
public externalPersonSandBox: ExternalPersonDetailsSandBox,
- private salutationsSandbox: SalutationsSandbox,
+ public salutationSandBox: SalutationsSandbox,
+ private _translate: TranslateService
) { }
ngOnInit() {
- this.salutationsSandbox.loadSalutations();
+ this.externalPersonSandBox.registerExternalPersonEvents();
+ this._hideExpandable();
}
- public save() {
- this.externalPersonSandBox.updatingState();
- if (this.externalPersonSandBox.currentFormState.isValid) {
- const newExternalPerson = new ExternalPerson(this.externalPersonSandBox.currentFormState.value);
- this.externalPersonSandBox.persistExternalPerson(newExternalPerson);
+ ngOnDestroy() {
+ this.externalPersonSandBox.endSubscriptions();
+ }
+
+ public loadAddressDetail(detailId: string) {
+ if(detailId == null){
+ this.createOrEditAddressData = this._translate.instant('Address.NewAddress');
} else {
- this.externalPersonSandBox.utilService.displayNotification(
- 'MandatoryFieldsNotFilled',
- 'error'
- );
+ this.createOrEditAddressData = this._translate.instant('Address.EditAddress');
+ this.externalPersonSandBox.loadExternalPersonDetailsAddressDetails(detailId);
+ }
+
+ this.externalPersonSandBox.isAddressDataDetailViewVisible = true;
+ }
+
+ public loadCommunicationsDataDetail(detailId: string) {
+ if(detailId == null){
+ this.createOrEditCommunicationsData = this._translate.instant('CommunicationsData.NewCommunicationsData');
+ } else {
+ this.createOrEditCommunicationsData = this._translate.instant('CommunicationsData.EditCommunicationsData');
+ this.externalPersonSandBox.loadCommunicationsDataDetails(detailId);
+ }
+ this.externalPersonSandBox.isCommunicationsDataDetailViewVisible = true;
+ }
+
+ private _hideExpandable() {
+ if(!this.externalPersonSandBox.externalPersonContactId){
+ this.isExpandableVisible = false;
+ } else {
+ this.isExpandableVisible = true;
}
}
}
diff --git a/src/app/pages/persons/external-person/external-person-details/external-person-details.sandbox.spec.ts b/src/app/pages/persons/external-person/external-person-details/external-person-details.sandbox.spec.ts
index fdea3a8..094789d 100644
--- a/src/app/pages/persons/external-person/external-person-details/external-person-details.sandbox.spec.ts
+++ b/src/app/pages/persons/external-person/external-person-details/external-person-details.sandbox.spec.ts
@@ -11,10 +11,10 @@
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
import { async } from '@angular/core/testing';
-import { ExternalPersonDetailsSandBox } from '@app/pages/persons/external-person/external-person-details/external-person-details.sandbox';
+import { ExternalPersonDetailsSandBox } from '@pages/persons/external-person/external-person-details/external-person-details.sandbox';
import { of } from 'rxjs';
-import * as externalPersonActions from '@app/shared/store/actions/persons/external-person.action';
-import { ExternalPerson } from '@app/shared/models';
+import * as externalPersonActions from '@shared/store/actions/persons/external-person.action';
+import { ExternalPerson, Address, CommunicationsData } from '@shared/models';
describe('ExternalPersonDetailsSandBox', () => {
let component: ExternalPersonDetailsSandBox;
@@ -22,16 +22,18 @@
let appState: any;
let actionSubject: any;
let router: any;
+ let modalService: any;
beforeEach(async(() => {
router = { navigateByUrl() {} } as any;
appState = { dispatch:()=> {}, pipe: () => of(true), select:()=> of(true) } as any;
actionSubject = { pipe: () => of(true) } as any;
utilService = { displayNotification: () => {} } as any;
+ modalService = { open() {} } as any;
}));
beforeEach(() => {
- component = new ExternalPersonDetailsSandBox(appState, utilService, actionSubject, router);
+ component = new ExternalPersonDetailsSandBox(appState, utilService, actionSubject, router, modalService);
});
it('should create', () => {
@@ -48,20 +50,150 @@
const spy = spyOn(appState, 'dispatch');
const routerSpy = spyOn(router, 'navigateByUrl');
const externalPerson = new ExternalPerson;
- component.persistExternalPerson(externalPerson);
+ externalPerson.lastName = 'test';
+ component.externPersonDetailsCurrentFormState = {...component.externPersonDetailsCurrentFormState, isValid: true, value: externalPerson};
+ component.persistExternalPerson();
expect(spy).toHaveBeenCalledWith( Object({ payload: externalPerson, type: externalPersonActions.persistExternalPersonDetail.type }));
expect(routerSpy).toHaveBeenCalled();
});
- it('should call dispatch if updatingState', () => {
- const spy = spyOn(appState, 'dispatch');
- component.updatingState();
- expect(spy).toHaveBeenCalled();
+ it('should call error with displayNotification if form not valid', () => {
+ const utilSpy = spyOn(utilService, 'displayNotification');
+ component.externPersonDetailsCurrentFormState = {...component.externPersonDetailsCurrentFormState, isValid: false};
+ component.persistExternalPerson();
+ expect(utilSpy).toHaveBeenCalled();
});
- it('should call unregister subscibtions if call ngOnDestroy', () => {
- const spy = spyOn(component as any, 'unregisterEvents');
- component.ngOnDestroy();
+ it('should can register events and set the currentFormState', () => {
+ component.registerExternalPersonEvents();
+ expect(component.externPersonDetailsCurrentFormState).toBeDefined();
+ });
+
+ it('should call dispatch if load an external person addresses', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.loadExternalPersonAddresses('ID');
+ expect(spy).toHaveBeenCalledWith( Object({ payload: 'ID', type: externalPersonActions.loadExternalPersonDetailAddresses.type }));
+ });
+
+ it('should call dispatch if load an external person address details', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.externalPersonContactId = 'contactId';
+ component.loadExternalPersonDetailsAddressDetails('ID');
+ expect(spy).toHaveBeenCalledWith( Object({ payload_contactId: 'contactId', payload_addressId: 'ID', type: externalPersonActions.loadExternalPersonDetailAddressDetails.type }));
+ });
+
+ it('should can register address events and set the addressDetailsCurrentFormState', () => {
+ component.registerAddressEvents();
+ expect(component.addressDetailsCurrentFormState).toBeDefined();
+ });
+
+ it('should call dispatch if clearExternalPerson', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.clearExternalPerson();
+ expect(spy).toHaveBeenCalledTimes(3);
+ });
+
+ it('should call dispatch if clearAddressData', () => {
+ const spy = spyOn(appState, 'dispatch');
+ (component as any).clearAddressData();
+ expect(spy).toHaveBeenCalledTimes(2);
+ });
+
+ it('should call dispatch if persist an external person address', () => {
+ const spy = spyOn(appState, 'dispatch');
+ const spy1 = spyOn(component, 'clearAddressData');
+ const externalPersonAddress = new Address();
+ externalPersonAddress.addressTypeType = 'test';
+ externalPersonAddress.contactId = 'id';
+
+ component.addressDetailsCurrentFormState = {...component.addressDetailsCurrentFormState, isValid: true, value: externalPersonAddress};
+ component.persistAddress();
+ expect(spy).toHaveBeenCalledWith( Object({ payload: externalPersonAddress, type: externalPersonActions.persistAddressDetail.type }));
+ expect(spy1).toHaveBeenCalled();
+ });
+
+ it('should call error with displayNotification if address form not valid', () => {
+ const utilSpy = spyOn(utilService, 'displayNotification');
+ component.addressDetailsCurrentFormState = {...component.addressDetailsCurrentFormState, isValid: false};
+ component.persistAddress();
+ expect(utilSpy).toHaveBeenCalled();
+ });
+
+ it('should call clearAddressData and negate isDetailViewVisible after call closeAddressDataDetail', () => {
+ const spy = spyOn(component, 'clearAddressData');
+ component.isAddressDataDetailViewVisible = true;
+ component.closeAddressDataDetail();
expect(spy).toHaveBeenCalled();
+ expect(component.isAddressDataDetailViewVisible).toBe(false);
+ });
+
+ it('should open modal before deleting an address', () => {
+ spyOn(component['modalService'], 'open')
+ .and.returnValue({componentInstance: {title: ''}, result: {then: () => of(true)}} as any);
+ // (component as any)._communicationTypes = [new CommunicationType];
+ component.deleteAddress(new Address());
+ expect(modalService.open).toHaveBeenCalled();
+ });
+
+ it('should call dispatch if load an external person communications Data', () => {
+ const spy = spyOn(appState, 'dispatch');
+ // (component as any)._communicationTypes = [new CommunicationType];
+ component.loadCommunicationsData('ID');
+ expect(spy).toHaveBeenCalledWith( Object({ payload: 'ID', type: externalPersonActions.loadExternalPersonDetailCommunicationsData.type }));
+ });
+
+ it('should call dispatch if load an external person communicationsData details', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.externalPersonContactId = 'contactId'
+ component.loadCommunicationsDataDetails('ID');
+ expect(spy).toHaveBeenCalledWith( Object({ payload_contactId: 'contactId', payload_communicationsId: 'ID', type: externalPersonActions.loadExternalPersonDetailCommunicationsDataDetails.type }));
+ });
+
+ it('should can register communicationsData events and set the communicationsDataDetailsCurrentFormState', () => {
+ component.registerCommunicationsDataEvents();
+ expect(component.communicationsDataDetailsCurrentFormState).toBeDefined();
+ });
+
+ it('should call dispatch if clearCommunicationsData', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.clearCommunicationsData();
+ expect(spy).toHaveBeenCalledTimes(2);
+ });
+
+ it('should call dispatch if persist an external person communicationsData', () => {
+ const spy = spyOn(appState, 'dispatch');
+ const spy1 = spyOn(component, 'clearCommunicationsData');
+ const externalPersonCommunicationsData = new CommunicationsData();
+ externalPersonCommunicationsData.communicationTypeType = 'test';
+ externalPersonCommunicationsData.contactId = 'id';
+
+ component.communicationsDataDetailsCurrentFormState = {...component.communicationsDataDetailsCurrentFormState, isValid: true, value: externalPersonCommunicationsData};
+ component.persistCommunicationsData();
+ expect(spy).toHaveBeenCalledWith( Object({ payload: externalPersonCommunicationsData, type: externalPersonActions.persistCommunicationsDataDetail.type }));
+ expect(spy1).toHaveBeenCalled();
+ });
+
+ it('should call error with displayNotification if communicationsData form not valid', () => {
+ const utilSpy = spyOn(utilService, 'displayNotification');
+ component.communicationsDataDetailsCurrentFormState = {...component.communicationsDataDetailsCurrentFormState, isValid: false};
+ component.persistCommunicationsData();
+ expect(utilSpy).toHaveBeenCalled();
+ });
+
+ it('should call clearCommunicationsData and negate isCommunicationsDataDetailViewVisible after call closeCommunicationsDataDetail', () => {
+ const spy = spyOn(component, 'clearCommunicationsData');
+ const spy1 = spyOn(component, 'loadCommunicationsData');
+ component.isCommunicationsDataDetailViewVisible = true;
+ component.closeCommunicationsDataDetail();
+ expect(spy).toHaveBeenCalled();
+ expect(spy1).toHaveBeenCalled();
+ expect(component.isCommunicationsDataDetailViewVisible).toBe(false);
+ });
+
+ it('should open modal before deleting an communicationsData', () => {
+ spyOn(component['modalService'], 'open')
+ .and.returnValue({componentInstance: {title: ''}, result: {then: () => of(true)}} as any);
+ component.deleteCommunicationsData(new CommunicationsData());
+ expect(modalService.open).toHaveBeenCalled();
});
});
diff --git a/src/app/pages/persons/external-person/external-person-details/external-person-details.sandbox.ts b/src/app/pages/persons/external-person/external-person-details/external-person-details.sandbox.ts
index d919d5d..4721b6d 100644
--- a/src/app/pages/persons/external-person/external-person-details/external-person-details.sandbox.ts
+++ b/src/app/pages/persons/external-person/external-person-details/external-person-details.sandbox.ts
@@ -1,38 +1,58 @@
- /********************************************************************************
- * Copyright (c) 2020 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- ********************************************************************************/
+/********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/
import { BaseSandbox } from '@shared/sandbox/base.sandbox';
-import { Injectable, OnDestroy } from '@angular/core';
-import * as externalPersonActions from '@app/shared/store/actions/persons/external-person.action';
-import { FormGroupState, MarkAsTouchedAction, SetValueAction, ResetAction, MarkAsUntouchedAction } from 'ngrx-forms';
-import { ExternalPerson } from '@app/shared/models';
-import { Observable, Subscription } from 'rxjs';
+import { Injectable } from '@angular/core';
+import * as externalPersonActions from '@shared/store/actions/persons/external-person.action';
+import { FormGroupState, SetValueAction, ResetAction, MarkAsTouchedAction } from 'ngrx-forms';
+import { ExternalPerson, CommunicationsData, Address, CommunicationType } from '@shared/models';
+import { Observable } from 'rxjs';
import * as store from '@shared/store';
import { Store, ActionsSubject } from '@ngrx/store';
import * as externalPersonDetailsFormReducer from '@shared/store/reducers/persons/external-person/external-person-details-form.reducer';
+import * as externalPersonAddressDetailsFormReducer from '@shared/store/reducers/persons/external-person/addresses-details-form.reducer';
import { ofType } from '@ngrx/effects';
-import { UtilService } from '@app/shared/utility';
-import { takeUntil } from 'rxjs/operators';
+import { UtilService } from '@shared/utility';
+import { takeUntil, take, map } from 'rxjs/operators';
import { Router } from '@angular/router';
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { SafetyQueryDialogComponent } from '@shared/components/dialogs/safety-query-dialog/safety-query-dialog.component';
+import * as externalCommunicationsDataDetailsFormReducer from '@shared/store/reducers/persons/external-person/communications-data-details-form.reducer';
+import * as communicationTypesActions from '@shared/store/actions/admin/communication-types.action';
@Injectable()
-export class ExternalPersonDetailsSandBox extends BaseSandbox implements OnDestroy {
+export class ExternalPersonDetailsSandBox extends BaseSandbox {
- public formState$: Observable<FormGroupState<ExternalPerson>> = this.appState$.select(store.getExternalPersonDetails);
+ public externPersonDetailsFormState$: Observable<FormGroupState<ExternalPerson>> = this.appState$.select(store.getExternalPersonDetails);
+ public externPersonDetailsCurrentFormState: FormGroupState<ExternalPerson>;
+ public addressDetailsFormState$: Observable<FormGroupState<Address>> = this.appState$.select(store.getExternalPersonAddressesDetails);
+ public addressDetailsCurrentFormState: FormGroupState<Address>;
+ public addressList$: Observable<Array<Address>> = this.appState$.select(store.getExternalPersonAddressesData);
+ public addressListLoading$: Observable<boolean> = this.appState$.select(store.getExternalPersonAddressesLoading);
+ public communicationsDataDetailsFormState$: Observable<FormGroupState<CommunicationsData>> = this.appState$.select(store.getExternalPersonCommunicationsDataDetails);
+ public communicationsDataDetailsCurrentFormState: FormGroupState<CommunicationsData>;
+ public communicationsDataList$: Observable<Array<CommunicationsData>> = this.appState$.select(store.getExternalCommunicationsDataData);
+ public communicationsDataListLoading$: Observable<boolean> = this.appState$.select(store.getExternalCommunicationsDataLoading);
- public currentFormState: FormGroupState<ExternalPerson>;
- private subscriptions: Array<Subscription> = [];
+ public isAddressDataDetailViewVisible: boolean = false;
+ public existMainAddress = false;
+ public isCurrentAddressMainAddress = false;
+ public externalPersonContactId: string;
+ public isAddressDetailViewVisible: boolean = false;
+ public isCommunicationsDataDetailViewVisible: boolean = false;
+ private _communicationTypes: Array<CommunicationType> = new Array<CommunicationType>();
- public salutations$ = this.appState$.select(store.getSalutationsData);
+ public personTypes$ = this.appState$.select(store.getPersonTypesData);
+
/**
* ExternalPerson Sandbox constructor
@@ -42,50 +62,115 @@
public utilService: UtilService,
protected actionsSubject: ActionsSubject,
protected router: Router,
+ protected modalService: NgbModal
) {
super(appState$);
- this.registerEvents();
- }
+ this.addressList$.subscribe(addresses => {
+ this._checkIfMainAddressExist(addresses);
+ });
- /**
- * Loads external person from the server
- */
- public loadExternalPerson(id: string): void {
- this.appState$.dispatch(
- externalPersonActions.loadExternalPersonDetail({ payload: id })
- );
- }
-
- /**
- * Persists an external person
- */
- public persistExternalPerson(newExternalPerson: ExternalPerson): void {
- this.appState$.dispatch(
- externalPersonActions.persistExternalPersonDetail({
- payload: newExternalPerson
- })
- );
this.actionsSubject
+ .pipe(
+ ofType(externalPersonActions.loadExternalPersonDetailAddressDetailsSuccess),
+ map((action: { payload: Address }) => action.payload),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe((address: Address) => {
+ this._checkIfCurrentAddressIsMainAddress(address);
+ });
+ }
+
+ public loadExternalPerson(externalPersonId: string): void {
+ this.externalPersonContactId = externalPersonId;
+ this.appState$.dispatch(
+ externalPersonActions.loadExternalPersonDetail({ payload: externalPersonId })
+ );
+ }
+
+ public loadExternalPersonAddresses(externalPersonId: string): void {
+ this.appState$.dispatch(
+ externalPersonActions.loadExternalPersonDetailAddresses({ payload: externalPersonId })
+ );
+ }
+
+ public loadExternalPersonDetailsAddressDetails(addressId: string): void {
+ this.appState$.dispatch(
+ externalPersonActions.loadExternalPersonDetailAddressDetails({ payload_contactId: this.externalPersonContactId, payload_addressId: addressId })
+ );
+ }
+
+ public persistExternalPerson(): void {
+ if (this.externPersonDetailsCurrentFormState.isValid) {
+ const newExternalPerson = new ExternalPerson(this.externPersonDetailsCurrentFormState.value);
+
+ this.appState$.dispatch(
+ externalPersonActions.persistExternalPersonDetail({
+ payload: newExternalPerson
+ })
+ );
+ this.actionsSubject
.pipe(
ofType(externalPersonActions.persistExternalPersonDetailSuccess),
+ take(1),
takeUntil(this._endSubscriptions$)
)
.subscribe(() => {
+ this.clearExternalPerson();
this.router.navigateByUrl(`/overview`);
});
- this.subscriptions.push(
- this.actionsSubject
- .pipe(ofType(externalPersonActions.persistExternalPersonDetailSuccess))
- .subscribe(() => {
- this.clear();
- })
- );
+ } else {
+ this.utilService.displayNotification(
+ 'MandatoryFieldsNotFilled',
+ 'error'
+ );
+ }
}
- /**
- * Clear
- */
- clear(): void {
+ public persistAddress(): void {
+ if (this.addressDetailsCurrentFormState.isValid) {
+ const newAddress = new Address(this.addressDetailsCurrentFormState.value);
+ newAddress.contactId = newAddress.contactId !== null ? newAddress.contactId : this.externalPersonContactId;
+
+ this.appState$.dispatch(
+ externalPersonActions.persistAddressDetail({ payload: newAddress })
+ );
+ this.actionsSubject
+ .pipe(
+ ofType(externalPersonActions.persistAddressDetailSuccess),
+ take(1),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe(() => {
+ this.closeAddressDataDetail();
+ });
+ } else {
+ this.utilService.displayNotification(
+ 'MandatoryFieldsNotFilled',
+ 'error'
+ );
+ }
+ }
+
+ public deleteAddress(address: Address): void {
+ const modalRef = this.modalService.open(SafetyQueryDialogComponent);
+ modalRef.componentInstance.title = 'ConfirmDialog.Action.delete';
+ modalRef.componentInstance.body = 'ConfirmDialog.Deletion';
+ modalRef.result.then(() => {
+ this.appState$.dispatch(externalPersonActions.deleteAddress({ payload: address }));
+ if(address.isMainAddress){
+ this.existMainAddress = false;
+ }
+ this.closeAddressDataDetail();
+ }, () => {
+ });
+ }
+
+ public closeAddressDataDetail(): void {
+ this.clearAddressData();
+ this.isAddressDataDetailViewVisible = false;
+ }
+
+ public clearExternalPerson(): void {
this.appState$.dispatch(
new SetValueAction(
externalPersonDetailsFormReducer.FORM_ID,
@@ -93,37 +178,146 @@
)
);
this.appState$.dispatch(new ResetAction(externalPersonDetailsFormReducer.FORM_ID));
- }
-
- /**
- * Clean up before leaving
- */
- public ngOnDestroy() {
- this.unregisterEvents();
- }
-
- /**
- * Unsubscribes from events
- */
- private unregisterEvents() {
- this.subscriptions.forEach(sub => sub.unsubscribe());
- }
-
- public updatingState() {
this.appState$.dispatch(new MarkAsTouchedAction(externalPersonDetailsFormReducer.FORM_ID));
}
- /**
- * Subscribes to events
- */
- private registerEvents(): void {
-
- // subscribes to formState
- this.subscriptions.push(
- this.formState$.subscribe(
- (formState: FormGroupState<ExternalPerson>) =>
- (this.currentFormState = formState)
+ public clearAddressData(): void {
+ this.isCurrentAddressMainAddress = false;
+ this.appState$.dispatch(
+ new SetValueAction(
+ externalPersonAddressDetailsFormReducer.FORM_ID,
+ externalPersonAddressDetailsFormReducer.INITIAL_STATE.value
)
);
+ this.appState$.dispatch(new ResetAction(externalPersonAddressDetailsFormReducer.FORM_ID));
}
+
+ public registerExternalPersonEvents(): void {
+ // subscribes to formState
+ this.externPersonDetailsFormState$.pipe(takeUntil(this._endSubscriptions$)).subscribe(
+ (formState: FormGroupState<ExternalPerson>) =>
+ (this.externPersonDetailsCurrentFormState = formState)
+ );
+ }
+
+ public registerAddressEvents(): void {
+ // subscribes to formState
+ this.addressDetailsFormState$.pipe(takeUntil(this._endSubscriptions$)).subscribe(
+ (formState: FormGroupState<Address>) =>
+ (this.addressDetailsCurrentFormState = formState)
+ );
+ }
+
+ public loadCommunicationsData(externalPersonId: string): void {
+ this.actionsSubject
+ .pipe(
+ ofType(communicationTypesActions.loadCommunicationTypesSuccess),
+ map((action: communicationTypesActions.ILoadCommunicationTypesSuccess) => action.payload),
+ take(1),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe((payload: Array<CommunicationType>) => {
+ this._communicationTypes = payload;
+ this.appState$.dispatch(externalPersonActions.loadExternalPersonDetailCommunicationsData({ payload: externalPersonId }));
+ });
+
+ this.actionsSubject
+ .pipe(
+ ofType(externalPersonActions.loadExternalPersonDetailCommunicationsDataSuccess),
+ map((action: externalPersonActions.ILoadExternalPersonCommunicationsDataSuccess) => action.payload),
+ take(1),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe((communicationsData: Array<CommunicationsData>) => {
+ if (this._communicationTypes) {
+ for (let i = 0; i < this._communicationTypes.length; i++) {
+ const ct = this._communicationTypes[i];
+ const existingCommunicationsData: CommunicationsData = communicationsData.find(cd => cd.communicationTypeId == ct.id);
+ ct.isDisabled = existingCommunicationsData ? true : false;
+ }
+ }
+ });
+ }
+
+ public loadCommunicationsDataDetails(communicationsDataId: string): void {
+ this.appState$.dispatch(
+ externalPersonActions.loadExternalPersonDetailCommunicationsDataDetails({ payload_contactId: this.externalPersonContactId, payload_communicationsId: communicationsDataId })
+ );
+ }
+
+ public persistCommunicationsData(): void {
+ if (this.communicationsDataDetailsCurrentFormState.isValid) {
+ const newCommunicationsData = new CommunicationsData(this.communicationsDataDetailsCurrentFormState.value);
+ newCommunicationsData.contactId = newCommunicationsData.contactId !== null ? newCommunicationsData.contactId : this.externalPersonContactId;
+
+ this.appState$.dispatch(
+ externalPersonActions.persistCommunicationsDataDetail({ payload: newCommunicationsData })
+ );
+ this.actionsSubject
+ .pipe(
+ ofType(externalPersonActions.persistCommunicationsDataDetailSuccess),
+ take(1),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe(() => {
+ this.closeCommunicationsDataDetail();
+ });
+ } else {
+ this.utilService.displayNotification(
+ 'MandatoryFieldsNotFilled',
+ 'error'
+ );
+ }
+ }
+
+ public deleteCommunicationsData(communicationsData: CommunicationsData): void {
+ const modalRef = this.modalService.open(SafetyQueryDialogComponent);
+ modalRef.componentInstance.title = 'ConfirmDialog.Action.delete';
+ modalRef.componentInstance.body = 'ConfirmDialog.Deletion';
+ modalRef.result.then(() => {
+ this.appState$.dispatch(externalPersonActions.deleteCommunicationsData({ payload: communicationsData }));
+ this.closeCommunicationsDataDetail();
+ }, () => {
+ });
+ }
+
+ public closeCommunicationsDataDetail(): void {
+ this.loadCommunicationsData(this.externalPersonContactId);
+ this.clearCommunicationsData();
+ this.isCommunicationsDataDetailViewVisible = false;
+ }
+
+ public clearCommunicationsData(): void {
+ this.appState$.dispatch(
+ new SetValueAction(
+ externalCommunicationsDataDetailsFormReducer.FORM_ID,
+ externalCommunicationsDataDetailsFormReducer.INITIAL_STATE.value
+ )
+ );
+ this.appState$.dispatch(new ResetAction(externalCommunicationsDataDetailsFormReducer.FORM_ID));
+ }
+
+ public registerCommunicationsDataEvents(): void {
+ // subscribes to formState
+ this.communicationsDataDetailsFormState$.pipe(takeUntil(this._endSubscriptions$)).subscribe(
+ (formState: FormGroupState<CommunicationsData>) =>
+ (this.communicationsDataDetailsCurrentFormState = formState)
+ );
+ }
+
+ private _checkIfMainAddressExist(addresses: Array<Address>) {
+ for (let i = 0; i < addresses.length; i++) {
+ const address = addresses[i];
+ if (address.isMainAddress) {
+ this.existMainAddress = true;
+ break;
+ }
+ this.existMainAddress = false;
+ }
+ };
+
+ private _checkIfCurrentAddressIsMainAddress(address: Address) {
+ this.isCurrentAddressMainAddress = address.isMainAddress ? true : false;
+ };
+
}
diff --git a/src/app/pages/persons/external-person/external-person.resolver.spec.ts b/src/app/pages/persons/external-person/external-person.resolver.spec.ts
index 34ad2d7..2d19b18 100644
--- a/src/app/pages/persons/external-person/external-person.resolver.spec.ts
+++ b/src/app/pages/persons/external-person/external-person.resolver.spec.ts
@@ -16,33 +16,92 @@
describe('ExternalPersonResolver', () => {
let component: ExternalPersonResolver;
let externalPersonSandbox: any;
+ let salutationsSandbox: any;
+ let communicationTypesSandbox: any;
+ let personTypesSandbox: any;
beforeEach(async(() => {
externalPersonSandbox = {
- clear() {},
+ clearExternalPerson() {},
loadExternalPerson() {},
+ loadExternalPersonAddresses() {},
+ loadCommunicationsData() {},
+ } as any;
+
+ salutationsSandbox = {
+ loadSalutations() {}
+ } as any;
+
+ personTypesSandbox = {
+ loadPersonTypes() {}
+ } as any;
+
+ communicationTypesSandbox = {
+ loadCommunicationTypes() {}
} as any;
}));
beforeEach(() => {
- component = new ExternalPersonResolver(externalPersonSandbox);
+ component = new ExternalPersonResolver(externalPersonSandbox, salutationsSandbox, communicationTypesSandbox, personTypesSandbox);
});
it('should create', () => {
expect(component).toBeTruthy();
});
- it('should call loadExternalPerson if edit a external person', () => {
+ it('should call loadExternalPerson, loadExternalPersonAddresses, loadCommunicationsData if edit a external person', () => {
const spy = spyOn(externalPersonSandbox, 'loadExternalPerson');
+ const spy1 = spyOn(externalPersonSandbox, 'loadExternalPersonAddresses');
+ const spy2 = spyOn(externalPersonSandbox, 'loadCommunicationsData');
let ar: any = {params: {contactId: 'ID'}};
component.resolve(ar);
expect(spy).toHaveBeenCalled();
+ expect(spy1).toHaveBeenCalled();
+ expect(spy2).toHaveBeenCalled();
+ });
+
+ it('should call clearExternalPerson if create a new external person', () => {
+ const spy = spyOn(externalPersonSandbox, 'clearExternalPerson');
+ let ar: any = {params: {contactId: undefined}};
+ component.resolve(ar);
+ expect(spy).toHaveBeenCalled();
});
- it('should call clear if edit a external person', () => {
- const spy = spyOn(externalPersonSandbox, 'clear');
+ it('should loadSalutations on resolve', () => {
+ const spy = spyOn(salutationsSandbox, 'loadSalutations');
let ar: any = {params: {contactId: undefined}};
component.resolve(ar);
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should set isAddressDetailViewVisible true on resolve', () => {
+ let ar: any = {params: {contactId: undefined}};
+ component.resolve(ar);
+
+ expect(externalPersonSandbox.isAddressDetailViewVisible).toBeFalsy();
+ });
+
+ it('should loadCommunicationTypes on resolve', () => {
+ const spy = spyOn(communicationTypesSandbox, 'loadCommunicationTypes');
+ let ar: any = {params: {contactId: undefined}};
+ component.resolve(ar);
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should set isCommunicationsDataDetailViewVisible true on resolve', () => {
+ let ar: any = {params: {contactId: undefined}};
+ component.resolve(ar);
+
+ expect(externalPersonSandbox.isCommunicationsDataDetailViewVisible).toBeFalsy();
+ });
+
+ it('should loadPersonTypes on resolve', () => {
+ const spy = spyOn(personTypesSandbox, 'loadPersonTypes');
+ let ar: any = {params: {contactId: undefined}};
+ component.resolve(ar);
+
expect(spy).toHaveBeenCalled();
});
});
diff --git a/src/app/pages/persons/external-person/external-person.resolver.ts b/src/app/pages/persons/external-person/external-person.resolver.ts
index f658414..3352204 100644
--- a/src/app/pages/persons/external-person/external-person.resolver.ts
+++ b/src/app/pages/persons/external-person/external-person.resolver.ts
@@ -1,3 +1,4 @@
+import { PersonTypesSandbox } from '@pages/admin/person-types/person-types.sandbox';
/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
@@ -10,30 +11,40 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { ExternalPersonDetailsSandBox } from '@app/pages/persons/external-person/external-person-details/external-person-details.sandbox';
+import { ExternalPersonDetailsSandBox } from '@pages/persons/external-person/external-person-details/external-person-details.sandbox';
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
import { Injectable } from '@angular/core';
+import { SalutationsSandbox } from '@pages/admin/salutations/salutations.sandbox';
+import { CommunicationTypesSandbox } from '@pages/admin/communication-types/communication-types.sandbox';
-@Injectable({
- providedIn: 'root'
-})
+@Injectable()
export class ExternalPersonResolver implements Resolve<any>{
constructor(
private externalPersonSandbox: ExternalPersonDetailsSandBox,
+ private salutationsSandbox: SalutationsSandbox,
+ private communicationTypesSandbox: CommunicationTypesSandbox,
+ private personTypesSandbox: PersonTypesSandbox
) { }
/**
- * Triggered when application hits code table details or code value details route.
* @param route
*/
public resolve(route: ActivatedRouteSnapshot): void {
const contactId: string = route.params['contactId'];
if (contactId && (contactId !== 'new')) {
this.externalPersonSandbox.loadExternalPerson(contactId);
+ this.externalPersonSandbox.loadExternalPersonAddresses(contactId);
+ this.externalPersonSandbox.loadCommunicationsData(contactId);
} else {
- this.externalPersonSandbox.clear();
+ this.externalPersonSandbox.clearExternalPerson();
}
+
+ this.salutationsSandbox.loadSalutations();
+ this.personTypesSandbox.loadPersonTypes();
+ this.communicationTypesSandbox.loadCommunicationTypes();
+ this.externalPersonSandbox.isAddressDataDetailViewVisible = false;
+ this.externalPersonSandbox.isCommunicationsDataDetailViewVisible = false;
}
}
diff --git a/src/app/pages/persons/internal-person/internal-person-details/address-details/address-details.component.html b/src/app/pages/persons/internal-person/internal-person-details/address-details/address-details.component.html
new file mode 100644
index 0000000..def1a59
--- /dev/null
+++ b/src/app/pages/persons/internal-person/internal-person-details/address-details/address-details.component.html
@@ -0,0 +1,202 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<form [ngrxFormState]="internalPersonDetailsSandbox.addressDetailsFormState$ | async">
+ <h4>{{createOrEditAddressData}}</h4>
+ <div>
+ <!-- type -->
+ <div class="form-group row">
+ <label for="addressTypeId" class="col-sm-5 col-form-label">{{ 'Address.AddressType' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ required
+ maxlength="255"
+ class="form-control"
+ id="addressTypeId"
+ [ngrxFormControlState]="((internalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['addressTypeId']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- MainAddress -->
+ <div class="form-group row">
+ <label for="isMainAddress" class="col-sm-5 col-form-label">{{ 'Address.MainAddress' | translate }}</label>
+ <div class="col-sm-6" style="align-self: center;">
+ <input *ngIf="!internalPersonDetailsSandbox.existMainAddress || internalPersonDetailsSandbox.isCurrentAddressMainAddress"
+ type="checkbox"
+ class="form-check-input"
+ id="isMainAddress"
+ [ngrxFormControlState]="((internalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['isMainAddress']"
+ />
+ <span *ngIf="internalPersonDetailsSandbox.existMainAddress && !internalPersonDetailsSandbox.isCurrentAddressMainAddress">(vorhanden)</span>
+ </div>
+ </div>
+
+ <!-- postCard -->
+ <div class="form-group row">
+ <label for="postcode" class="col-sm-5 col-form-label">{{ 'Address.Postcode' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="30"
+ class="form-control"
+ id="postcode"
+ [ngrxFormControlState]="((internalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['postcode']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- community -->
+ <div class="form-group row">
+ <label for="community" class="col-sm-5 col-form-label">{{ 'Address.Community' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="community"
+ [ngrxFormControlState]="((internalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['community']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- community-suffix -->
+ <div class="form-group row">
+ <label for="communitySuffix" class="col-sm-5 col-form-label">{{ 'Address.CommunitySuffix' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="communitySuffix"
+ [ngrxFormControlState]="((internalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['communitySuffix']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- street -->
+ <div class="form-group row">
+ <label for="street" class="col-sm-5 col-form-label">{{ 'Address.Street' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="street"
+ [ngrxFormControlState]="((internalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['street']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- housenumber -->
+ <div class="form-group row">
+ <label for="housenumber" class="col-sm-5 col-form-label">{{ 'Address.Housenumber' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="30"
+ class="form-control"
+ id="housenumber"
+ [ngrxFormControlState]="((internalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['housenumber']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- wgs_84_zone -->
+ <div class="form-group row">
+ <label for="wgs84Zone" class="col-sm-5 col-form-label">{{ 'Address.Wgs84Zone' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="wgs84Zone"
+ [ngrxFormControlState]="((internalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['wgs84Zone']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- longitude -->
+ <div class="form-group row">
+ <label for="longitude" class="col-sm-5 col-form-label">{{ 'Address.Longitude' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="longitude"
+ [ngrxFormControlState]="((internalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['longitude']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- latitude -->
+ <div class="form-group row">
+ <label for="latitude" class="col-sm-5 col-form-label">{{ 'Address.Latitude' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="latitude"
+ [ngrxFormControlState]="((internalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['latitude']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- url_map -->
+ <div class="form-group row">
+ <label for="urlMap" class="col-sm-5 col-form-label">{{ 'Address.UrlMap' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="urlMap"
+ [ngrxFormControlState]="((internalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['urlMap']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- note -->
+ <div class="form-group row">
+ <label for="note" class="col-sm-5 col-form-label">{{ 'Address.Note' | translate }}</label>
+ <div class="col-sm-6">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="note"
+ [ngrxFormControlState]="((internalPersonDetailsSandbox.addressDetailsFormState$ | async)?.controls)['note']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- buttons -->
+ <button
+ type="button"
+ class="btn btn-primary btn-sm btn-success"
+ (click)="internalPersonDetailsSandbox.persistAddress()"
+ >
+ {{ 'SaveBtn' | translate }}
+ </button>
+
+ <button
+ type="button"
+ class="btn btn-primary btn-sm"
+ (click)="internalPersonDetailsSandbox.closeAddressDataDetail()"
+ >
+ {{ 'CancelBtn' | translate }}
+ </button>
+ </div>
+</form >
diff --git a/src/app/pages/persons/internal-person/internal-person-details/address-details/address-details.component.scss b/src/app/pages/persons/internal-person/internal-person-details/address-details/address-details.component.scss
new file mode 100644
index 0000000..a43bd94
--- /dev/null
+++ b/src/app/pages/persons/internal-person/internal-person-details/address-details/address-details.component.scss
@@ -0,0 +1,26 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+button {
+ margin: 14px 0px 10px 15px;
+}
+h4 {
+ padding: 15px;
+ padding-top: 18px;
+}
+div.form-group.row {
+ padding-left: 15px;
+}
+
+#isMainAddress{
+ margin-left: 0px;
+}
diff --git a/src/app/pages/persons/internal-person/internal-person-details/address-details/address-details.component.spec.ts b/src/app/pages/persons/internal-person/internal-person-details/address-details/address-details.component.spec.ts
new file mode 100644
index 0000000..e71f704
--- /dev/null
+++ b/src/app/pages/persons/internal-person/internal-person-details/address-details/address-details.component.spec.ts
@@ -0,0 +1,44 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { InternalPersonAddressDetailsComponent } from '@pages/persons/internal-person/internal-person-details/address-details/address-details.component';
+
+describe('AddressDetailsComponent', () => {
+ let component: InternalPersonAddressDetailsComponent;
+ let internalPersonSandbox: any;
+
+ beforeEach(async(() => {
+ internalPersonSandbox = {
+ registerAddressEvents() {},
+ registerExternalPersonEvents() {},
+ endSubscriptions() {},
+ clearAddressData() {},
+ } as any;
+ }));
+
+ beforeEach(() => {
+ component = new InternalPersonAddressDetailsComponent(internalPersonSandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call registerAddressEvents and clearAddressData onInit', () => {
+ const spy1 = spyOn(internalPersonSandbox, 'registerAddressEvents');
+ const spy2 = spyOn(internalPersonSandbox, 'clearAddressData');
+ component.ngOnInit();
+ expect(spy1).toHaveBeenCalled();
+ expect(spy2).toHaveBeenCalled();
+ });
+});
diff --git a/src/app/pages/persons/internal-person/internal-person-details/address-details/address-details.component.ts b/src/app/pages/persons/internal-person/internal-person-details/address-details/address-details.component.ts
new file mode 100644
index 0000000..6b54544
--- /dev/null
+++ b/src/app/pages/persons/internal-person/internal-person-details/address-details/address-details.component.ts
@@ -0,0 +1,34 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { InternalPersonDetailsSandBox } from '@pages/persons/internal-person/internal-person-details/internal-person-details.sandbox';
+import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
+
+@Component({
+ selector: 'app-internal-person-address-details',
+ templateUrl: './address-details.component.html',
+ styleUrls: ['./address-details.component.scss']
+})
+export class InternalPersonAddressDetailsComponent implements OnInit {
+
+ @Input() createOrEditAddressData: string;
+
+ constructor(
+ public internalPersonDetailsSandbox: InternalPersonDetailsSandBox,
+ ) { }
+
+ ngOnInit() {
+ this.internalPersonDetailsSandbox.registerAddressEvents();
+ this.internalPersonDetailsSandbox.clearAddressData();
+ }
+
+}
diff --git a/src/app/pages/persons/internal-person/internal-person-details/address-list/address-list.component.html b/src/app/pages/persons/internal-person/internal-person-details/address-list/address-list.component.html
new file mode 100644
index 0000000..0fc21c2
--- /dev/null
+++ b/src/app/pages/persons/internal-person/internal-person-details/address-list/address-list.component.html
@@ -0,0 +1,37 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<div class="diverse-options">
+ <div class="new-address">
+ <button class="btn btn-sm btn-primary" (click)="createNewAddressForm()">
+ {{ 'Address.NewAddress' | translate }}
+ </button>
+ </div>
+</div>
+
+
+<ag-grid-angular
+ autoresizecolumns
+ class="ag-theme-balham ag-grid-height"
+ style="width: 100%; height: 100%;"
+ [gridOptions]="gridOptions"
+ [rowData]="internalPersonDetailsSandBox.addressList$ | async"
+ [columnDefs]="columnDefinition"
+ [rowSelection]="'single'"
+ [frameworkComponents]="frameworkComponents"
+>
+</ag-grid-angular>
+
+<app-spinner [isRunning]="internalPersonDetailsSandBox.addressListLoading$ | async"></app-spinner>
+
+
+
diff --git a/src/app/pages/persons/internal-person/internal-person-details/address-list/address-list.component.scss b/src/app/pages/persons/internal-person/internal-person-details/address-list/address-list.component.scss
new file mode 100644
index 0000000..63a5ad3
--- /dev/null
+++ b/src/app/pages/persons/internal-person/internal-person-details/address-list/address-list.component.scss
@@ -0,0 +1,27 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+ .diverse-options {
+ display: flex;
+ justify-content: flex-end;
+ align-content: center;
+ background-color: #f5f7f7;
+ border: 1px solid rgb(189, 195, 199);
+ padding: 7px 7px 5px 7px;
+ margin-bottom: 1px;
+}
+
+.diverse-options-item {
+ width: 400px;
+ padding-right: 7px;
+ border-right: solid 1px #ddd;
+}
diff --git a/src/app/pages/persons/internal-person/internal-person-details/address-list/address-list.component.spec.ts b/src/app/pages/persons/internal-person/internal-person-details/address-list/address-list.component.spec.ts
new file mode 100644
index 0000000..adc088c
--- /dev/null
+++ b/src/app/pages/persons/internal-person/internal-person-details/address-list/address-list.component.spec.ts
@@ -0,0 +1,73 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { InternalPersonAddressListComponent } from '@pages/persons/internal-person/internal-person-details/address-list/address-list.component';
+import { of } from 'rxjs/observable/of';
+
+describe('AddressListComponent', () => {
+ let component: InternalPersonAddressListComponent;
+ let internalPersonSandbox: any;
+
+ beforeEach(async(() => {
+ internalPersonSandbox = {
+ registerAddressEvents() {},
+ registerExternalPersonEvents() {},
+ endSubscriptions() {},
+ deleteAddress() {},
+ clearAddressData() {},
+ } as any;
+ }));
+
+ beforeEach(() => {
+ component = new InternalPersonAddressListComponent(internalPersonSandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should define gridOptions onInit', () => {
+ component.ngOnInit();
+
+ expect(component.gridOptions).toBeDefined();
+ expect(component.gridOptions.context).toBeDefined();
+ });
+
+ it('should emit if BusEvents is edit ', () => {
+ const spy = spyOn(component.internalPersonDetailsId, 'emit');
+ const event: any = {type: 'edit', data: {id: 'id'}};
+ component.gridOptions.context.eventSubject = of(event);
+ component.ngOnInit();
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should deleteAddress if BusEvents is delete', () => {
+ const spy = spyOn(internalPersonSandbox, 'deleteAddress');
+ const event: any = {type: 'delete', data: {id: 'id'}};
+ component.gridOptions.context.eventSubject = of(event);
+ component.ngOnInit();
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should clearAddressData and close edit area if callcreateNewAddressForm', () => {
+ const spy = spyOn(internalPersonSandbox, 'clearAddressData');
+ const spyEmit = spyOn(component.createNewInternalPerson, 'emit');
+ component.createNewAddressForm();
+
+ expect(spy).toHaveBeenCalled();
+ expect(spyEmit).toHaveBeenCalled();
+ });
+});
+
diff --git a/src/app/pages/persons/internal-person/internal-person-details/address-list/address-list.component.ts b/src/app/pages/persons/internal-person/internal-person-details/address-list/address-list.component.ts
new file mode 100644
index 0000000..3ed447f
--- /dev/null
+++ b/src/app/pages/persons/internal-person/internal-person-details/address-list/address-list.component.ts
@@ -0,0 +1,63 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { InternalPersonDetailsSandBox } from '@pages/persons/internal-person/internal-person-details/internal-person-details.sandbox';
+import { BaseList } from '@shared/components/base-components/base.list';
+import { Component, EventEmitter, Output } from '@angular/core';
+import { ADDRESS_LIST_COLDEF } from '@shared/components/column-definitions/addresses-data-list-column-definition';
+import { Globals } from '@shared/constants/globals';
+
+
+@Component({
+ selector: 'app-internal-person-address-list',
+ templateUrl: './address-list.component.html',
+ styleUrls: ['./address-list.component.scss']
+})
+
+export class InternalPersonAddressListComponent extends BaseList {
+
+ @Output() internalPersonDetailsId: EventEmitter<string> = new EventEmitter();
+ @Output() createNewInternalPerson: EventEmitter<string> = new EventEmitter();
+
+ public columnDefinition = ADDRESS_LIST_COLDEF;
+
+
+ constructor(public internalPersonDetailsSandBox: InternalPersonDetailsSandBox) {
+ super();
+ }
+
+ ngOnInit() {
+ this.gridOptions = {
+ ...this.gridOptions,
+ localeText: Globals.LOCALE_TEXT
+ };
+ this.gridOptions.context = {
+ ...this.gridOptions.context,
+ icons: { edit: true, delete: true }
+ };
+
+ this.gridOptions.context.eventSubject.subscribe(event => {
+ if (event.type === 'edit') {
+ this.internalPersonDetailsId.emit(event.data.id);
+ }
+ if (event.type === 'delete') {
+ this.internalPersonDetailsSandBox.deleteAddress(event.data);
+ }
+ });
+ }
+
+ public createNewAddressForm() {
+ this.internalPersonDetailsSandBox.clearAddressData();
+ this.createNewInternalPerson.emit(null);
+ }
+
+}
diff --git a/src/app/pages/persons/internal-person/internal-person-details/communications-data-details/communications-data-details.component.html b/src/app/pages/persons/internal-person/internal-person-details/communications-data-details/communications-data-details.component.html
new file mode 100644
index 0000000..9cde522
--- /dev/null
+++ b/src/app/pages/persons/internal-person/internal-person-details/communications-data-details/communications-data-details.component.html
@@ -0,0 +1,75 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<form [ngrxFormState]="internalPersonDetailsSandbox.communicationsDataDetailsFormState$ | async">
+ <h4>{{createOrEditCommunicationsData}}</h4>
+ <div>
+ <!-- type -->
+ <div class="form-group row">
+ <label for="communicationType" class="col-sm-4 col-form-label">{{ 'CommunicationsData.CommunicationType' | translate }}</label>
+ <div class="col-sm-7">
+ <select
+ type="text"
+ class="form-control"
+ [ngrxFormControlState]="((internalPersonDetailsSandbox.communicationsDataDetailsFormState$ | async)?.controls)['communicationTypeId']">
+ <option [value]="">{{ 'SelectOption' | translate }}</option> -->
+ <option *ngFor="let communicationType of communicationTypesSandbox.communicationTypes$ | async" [disabled]="communicationType.isDisabled" [value]="communicationType.id">{{communicationType.type}}</option>
+ </select>
+ </div>
+ </div>
+
+ <!-- communicationData -->
+ <div class="form-group row">
+ <label for="communicationData" class="col-sm-4 col-form-label">{{ 'CommunicationsData.CommunicationData' | translate }}</label>
+ <div class="col-sm-7">
+ <input type="text"
+ maxlength="1024"
+ class="form-control"
+ id="communicationData"
+ [ngrxFormControlState]="((internalPersonDetailsSandbox.communicationsDataDetailsFormState$ | async)?.controls)['communicationData']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- note -->
+ <div class="form-group row">
+ <label for="note" class="col-sm-4 col-form-label">{{ 'CommunicationsData.Note' | translate }}</label>
+ <div class="col-sm-7">
+ <input type="text"
+ maxlength="255"
+ class="form-control"
+ id="note"
+ [ngrxFormControlState]="((internalPersonDetailsSandbox.communicationsDataDetailsFormState$ | async)?.controls)['note']"
+ autocomplete="off"
+ />
+ </div>
+ </div>
+
+ <!-- buttons -->
+ <button
+ type="button"
+ class="btn btn-primary btn-sm btn-success"
+ (click)="internalPersonDetailsSandbox.persistCommunicationsData()"
+ >
+ {{ 'SaveBtn' | translate }}
+ </button>
+
+ <button
+ type="button"
+ class="btn btn-primary btn-sm"
+ (click)="internalPersonDetailsSandbox.closeCommunicationsDataDetail()"
+ >
+ {{ 'CancelBtn' | translate }}
+ </button>
+ </div>
+</form >
diff --git a/src/app/pages/persons/internal-person/internal-person-details/communications-data-details/communications-data-details.component.scss b/src/app/pages/persons/internal-person/internal-person-details/communications-data-details/communications-data-details.component.scss
new file mode 100644
index 0000000..b959869
--- /dev/null
+++ b/src/app/pages/persons/internal-person/internal-person-details/communications-data-details/communications-data-details.component.scss
@@ -0,0 +1,25 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+button {
+ margin: 14px 0px 10px 15px;
+}
+h4 {
+ padding: 15px;
+ padding-top: 18px;
+}
+div.form-group.row {
+ padding-left: 15px;
+}
+select option[disabled]{
+ background-color: rgb(160, 164, 168);
+}
diff --git a/src/app/pages/persons/internal-person/internal-person-details/communications-data-details/communications-data-details.component.spec.ts b/src/app/pages/persons/internal-person/internal-person-details/communications-data-details/communications-data-details.component.spec.ts
new file mode 100644
index 0000000..b02a3bd
--- /dev/null
+++ b/src/app/pages/persons/internal-person/internal-person-details/communications-data-details/communications-data-details.component.spec.ts
@@ -0,0 +1,48 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { InternalPersonCommunicationsDataDetailsComponent } from '@pages/persons/internal-person/internal-person-details/communications-data-details/communications-data-details.component';
+
+describe('InternalPersonCommunicationsDataDetailsComponent', () => {
+ let component: InternalPersonCommunicationsDataDetailsComponent;
+ let internalPersonSandbox: any;
+ let communicationTypesSandbox: any;
+
+ beforeEach(() => {
+ internalPersonSandbox = {
+ registerCommunicationsDataEvents() {},
+ registerInternalPersonEvents() {},
+ endSubscriptions() {},
+ clearCommunicationsData() {},
+ } as any;
+
+ communicationTypesSandbox = {
+ } as any;
+ });
+
+ beforeEach(() => {
+ component = new InternalPersonCommunicationsDataDetailsComponent(internalPersonSandbox, communicationTypesSandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call registerCommunicationsDataEvents and clearCommunicationsData onInit', () => {
+ const spy1 = spyOn(internalPersonSandbox, 'registerCommunicationsDataEvents');
+ const spy2 = spyOn(internalPersonSandbox, 'clearCommunicationsData');
+ component.ngOnInit();
+ expect(spy1).toHaveBeenCalled();
+ expect(spy2).toHaveBeenCalled();
+ });
+});
diff --git a/src/app/pages/persons/internal-person/internal-person-details/communications-data-details/communications-data-details.component.ts b/src/app/pages/persons/internal-person/internal-person-details/communications-data-details/communications-data-details.component.ts
new file mode 100644
index 0000000..3f7b1fd
--- /dev/null
+++ b/src/app/pages/persons/internal-person/internal-person-details/communications-data-details/communications-data-details.component.ts
@@ -0,0 +1,36 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { InternalPersonDetailsSandBox } from '@pages/persons/internal-person/internal-person-details/internal-person-details.sandbox';
+import { Component, OnInit, Input } from '@angular/core';
+import { CommunicationTypesSandbox } from '@pages/admin/communication-types/communication-types.sandbox';
+
+@Component({
+ selector: 'app-internal-person-communications-data-details',
+ templateUrl: './communications-data-details.component.html',
+ styleUrls: ['./communications-data-details.component.scss']
+})
+export class InternalPersonCommunicationsDataDetailsComponent implements OnInit {
+
+ @Input() createOrEditCommunicationsData: string;
+
+ constructor(
+ public internalPersonDetailsSandbox: InternalPersonDetailsSandBox,
+ public communicationTypesSandbox: CommunicationTypesSandbox
+ ) { }
+
+ ngOnInit() {
+ this.internalPersonDetailsSandbox.registerCommunicationsDataEvents();
+ this.internalPersonDetailsSandbox.clearCommunicationsData();
+ }
+
+}
diff --git a/src/app/pages/persons/internal-person/internal-person-details/communications-data-list/communications-data-list-column-definition.ts b/src/app/pages/persons/internal-person/internal-person-details/communications-data-list/communications-data-list-column-definition.ts
new file mode 100644
index 0000000..8f9c2b6
--- /dev/null
+++ b/src/app/pages/persons/internal-person/internal-person-details/communications-data-list/communications-data-list-column-definition.ts
@@ -0,0 +1,49 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { IconCellRendererComponent } from '@shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component';
+
+export const COMMUNICATIONS_DATA_LIST_COLDEF = [
+ {
+ field: 'communicationTypeType',
+ colId: 'communicationTypeType',
+ headerName: 'CommunicationsData.CommunicationType',
+ sortable: true,
+ filter: true,
+ },
+ {
+ field: 'communicationData',
+ colId: 'communicationData',
+ headerName: 'CommunicationsData.CommunicationData',
+ sortable: true,
+ filter: true
+ },
+ {
+ field: 'note',
+ colId: 'note',
+ headerName: 'CommunicationsData.Note',
+ sortable: true,
+ filter: true
+ },
+ {
+ field: 'tools',
+ headerName: ' ',
+ pinned: 'right',
+ maxWidth: 100,
+ lockPosition: true,
+ sortable: false,
+ filter: false,
+ suppressMenu: true,
+ suppressSizeToFit: true,
+ cellRendererFramework: IconCellRendererComponent,
+ }
+];
diff --git a/src/app/pages/persons/internal-person/internal-person-details/communications-data-list/communications-data-list.component.html b/src/app/pages/persons/internal-person/internal-person-details/communications-data-list/communications-data-list.component.html
new file mode 100644
index 0000000..42b739b
--- /dev/null
+++ b/src/app/pages/persons/internal-person/internal-person-details/communications-data-list/communications-data-list.component.html
@@ -0,0 +1,36 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<div class="diverse-options">
+ <div class="new-communicationsData">
+ <button class="btn btn-sm btn-primary" (click)="createNewCommunicationsDataForm()">
+ {{ 'CommunicationsData.NewCommunicationsData' | translate }}
+ </button>
+ </div>
+</div>
+
+
+<ag-grid-angular
+ autoresizecolumns
+ class="ag-theme-balham ag-grid-height"
+ style="width: 100%; height: 100%;"
+ [gridOptions]="gridOptions"
+ [rowData]="internalPersonDetailsSandBox.communicationsDataList$ | async"
+ [columnDefs]="columnDefinition"
+ [rowSelection]="'single'"
+ [frameworkComponents]="frameworkComponents"
+>
+</ag-grid-angular>
+<app-spinner [isRunning]="internalPersonDetailsSandBox.communicationsDataListLoading$ | async"></app-spinner>
+
+
+
diff --git a/src/app/pages/persons/internal-person/internal-person-details/communications-data-list/communications-data-list.component.scss b/src/app/pages/persons/internal-person/internal-person-details/communications-data-list/communications-data-list.component.scss
new file mode 100644
index 0000000..63a5ad3
--- /dev/null
+++ b/src/app/pages/persons/internal-person/internal-person-details/communications-data-list/communications-data-list.component.scss
@@ -0,0 +1,27 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+ .diverse-options {
+ display: flex;
+ justify-content: flex-end;
+ align-content: center;
+ background-color: #f5f7f7;
+ border: 1px solid rgb(189, 195, 199);
+ padding: 7px 7px 5px 7px;
+ margin-bottom: 1px;
+}
+
+.diverse-options-item {
+ width: 400px;
+ padding-right: 7px;
+ border-right: solid 1px #ddd;
+}
diff --git a/src/app/pages/persons/internal-person/internal-person-details/communications-data-list/communications-data-list.component.spec.ts b/src/app/pages/persons/internal-person/internal-person-details/communications-data-list/communications-data-list.component.spec.ts
new file mode 100644
index 0000000..aea25b6
--- /dev/null
+++ b/src/app/pages/persons/internal-person/internal-person-details/communications-data-list/communications-data-list.component.spec.ts
@@ -0,0 +1,73 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { InternalPersonCommunicationsDataListComponent } from '@pages/persons/internal-person/internal-person-details/communications-data-list/communications-data-list.component';
+import { of } from 'rxjs/observable/of';
+
+describe('InternalPersonCommunicationsDataListComponent', () => {
+ let component: InternalPersonCommunicationsDataListComponent;
+ let internalPersonSandbox: any;
+
+ beforeEach(async(() => {
+ internalPersonSandbox = {
+ registerCommunicationsDataEvents() {},
+ registerInternalPersonEvents() {},
+ endSubscriptions() {},
+ deleteCommunicationsData() {},
+ clearCommunicationsData() {},
+ } as any;
+ }));
+
+ beforeEach(() => {
+ component = new InternalPersonCommunicationsDataListComponent(internalPersonSandbox);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should define gridOptions onInit', () => {
+ component.ngOnInit();
+
+ expect(component.gridOptions).toBeDefined();
+ expect(component.gridOptions.context).toBeDefined();
+ });
+
+ it('should emit if BusEvents is edit ', () => {
+ const spy = spyOn(component.internalPersonDetailsId, 'emit');
+ const event: any = {type: 'edit', data: {id: 'id'}};
+ component.gridOptions.context.eventSubject = of(event);
+ component.ngOnInit();
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should deleteCommunicationsData if BusEvents is delete', () => {
+ const spy = spyOn(internalPersonSandbox, 'deleteCommunicationsData');
+ const event: any = {type: 'delete', data: {id: 'id'}};
+ component.gridOptions.context.eventSubject = of(event);
+ component.ngOnInit();
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should clearCommunicationsData and close edit area if callcreateNewCommunicationsDataForm', () => {
+ const spy = spyOn(internalPersonSandbox, 'clearCommunicationsData');
+ const spyEmit = spyOn(component.createNewInternalPerson, 'emit');
+ component.createNewCommunicationsDataForm();
+
+ expect(spy).toHaveBeenCalled();
+ expect(spyEmit).toHaveBeenCalled();
+ });
+});
+
diff --git a/src/app/pages/persons/internal-person/internal-person-details/communications-data-list/communications-data-list.component.ts b/src/app/pages/persons/internal-person/internal-person-details/communications-data-list/communications-data-list.component.ts
new file mode 100644
index 0000000..1cea223
--- /dev/null
+++ b/src/app/pages/persons/internal-person/internal-person-details/communications-data-list/communications-data-list.component.ts
@@ -0,0 +1,61 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { InternalPersonDetailsSandBox } from '@pages/persons/internal-person/internal-person-details/internal-person-details.sandbox';
+import { BaseList } from '@shared/components/base-components/base.list';
+import { Component, EventEmitter, Output } from '@angular/core';
+import { COMMUNICATIONS_DATA_LIST_COLDEF } from '@shared/components/column-definitions/communications-data-list-column-definition';
+import { Globals } from '@shared/constants/globals';
+
+@Component({
+ selector: 'app-internal-person-communications-data-list',
+ templateUrl: './communications-data-list.component.html',
+ styleUrls: ['./communications-data-list.component.scss']
+})
+export class InternalPersonCommunicationsDataListComponent extends BaseList {
+
+ @Output() internalPersonDetailsId: EventEmitter<string> = new EventEmitter();
+ @Output() createNewInternalPerson: EventEmitter<string> = new EventEmitter();
+
+ public columnDefinition = COMMUNICATIONS_DATA_LIST_COLDEF;
+
+
+ constructor(public internalPersonDetailsSandBox: InternalPersonDetailsSandBox) {
+ super();
+ }
+
+ ngOnInit() {
+ this.gridOptions = {
+ ...this.gridOptions,
+ localeText: Globals.LOCALE_TEXT
+ };
+ this.gridOptions.context = {
+ ...this.gridOptions.context,
+ icons: { edit: true, delete: true }
+ };
+
+ this.gridOptions.context.eventSubject.subscribe(event => {
+ if (event.type === 'edit') {
+ this.internalPersonDetailsId.emit(event.data.id);
+ }
+ if (event.type === 'delete') {
+ this.internalPersonDetailsSandBox.deleteCommunicationsData(event.data);
+ }
+ });
+ }
+
+ public createNewCommunicationsDataForm(){
+ this.internalPersonDetailsSandBox.clearCommunicationsData();
+ this.createNewInternalPerson.emit(null);
+ }
+
+}
diff --git a/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.component.html b/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.component.html
index 5656491..004138d 100644
--- a/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.component.html
+++ b/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.component.html
@@ -15,147 +15,173 @@
<span>{{ 'Internal.Title' | translate }}</span>
</div>
<div class="contacts-grid-wrapper" body>
- <form [ngrxFormState]="internalPersonSandBox.formState$ | async">
+ <form [ngrxFormState]="internalPersonSandBox.internalPersonDetailsFormState$ | async">
<div>
- <!-- firstName -->
- <div class="form-group row">
- <label for="firstName" class="col-sm-2 col-form-label">{{ 'Internal.FirstName' | translate }}</label>
- <div class="col-sm-4">
- <input
- type="text"
- class="form-control"
- id="firstName"
- [ngrxFormControlState]="((internalPersonSandBox.formState$ | async)?.controls)['firstName']"
- autocomplete="off"
- />
- </div>
+ <!-- firstName -->
+ <div class="form-group row">
+ <label for="firstName" class="col-sm-2 col-form-label">{{ 'Internal.FirstName' | translate }}</label>
+ <div class="col-sm-4">
+ <input
+ type="text"
+ maxlength="255"
+ class="form-control"
+ id="firstName"
+ [ngrxFormControlState]="((internalPersonSandBox.internalPersonDetailsFormState$ | async)?.controls)['firstName']"
+ autocomplete="off"
+ />
</div>
+ </div>
- <!-- lastName -->
- <div class="form-group row">
- <label for="lastName" class="col-sm-2 col-form-label">{{ 'Internal.LastName' | translate }}</label>
- <div class="col-sm-4">
- <input
- [required]="true"
- type="text"
- class="form-control"
- id="lastName"
- [ngrxFormControlState]="((internalPersonSandBox.formState$ | async)?.controls)['lastName']"
- autocomplete="off"
- />
- </div>
+ <!-- lastName -->
+ <div class="form-group row">
+ <label for="lastName" class="col-sm-2 col-form-label">{{ 'Internal.LastName' | translate }}</label>
+ <div class="col-sm-4">
+ <input
+ required
+ type="text"
+ maxlength="255"
+ class="form-control"
+ id="lastName"
+ [ngrxFormControlState]="((internalPersonSandBox.internalPersonDetailsFormState$ | async)?.controls)['lastName']"
+ autocomplete="off"
+ />
</div>
+ </div>
- <!-- title -->
- <div class="form-group row">
- <label for="title" class="col-sm-2 col-form-label">{{ 'Internal.PersonTitle' | translate }}</label>
- <div class="col-sm-4">
- <input
- type="text"
- class="form-control"
- id="title"
- [ngrxFormControlState]="((internalPersonSandBox.formState$ | async)?.controls)['title']"
- autocomplete="off"
- />
- </div>
+ <!-- title -->
+ <div class="form-group row">
+ <label for="title" class="col-sm-2 col-form-label">{{ 'Internal.PersonTitle' | translate }}</label>
+ <div class="col-sm-4">
+ <input
+ type="text"
+ maxlength="255"
+ class="form-control"
+ id="title"
+ [ngrxFormControlState]="((internalPersonSandBox.internalPersonDetailsFormState$ | async)?.controls)['title']"
+ autocomplete="off"
+ />
</div>
+ </div>
- <!-- salutation -->
- <div class="form-group row">
- <label for="salutationType" class="col-sm-2 col-form-label">{{ 'Internal.Salutation' | translate }}</label>
- <div class="col-sm-4">
+ <!-- salutation -->
+ <div class="form-group row">
+ <label for="salutationType" class="col-sm-2 col-form-label">{{ 'Internal.Salutation' | translate }}</label>
+ <div class="col-sm-4">
+ <select type="text" class="form-control" [ngrxFormControlState]="((internalPersonSandBox.internalPersonDetailsFormState$ | async)?.controls)['salutationId']">
+ <option [value]="">{{ 'SelectOption' | translate }}</option>
+ -->
+ <option *ngFor="let salutation of internalPersonSandBox.salutations$ | async" [value]="salutation.id">{{ salutation.type }}</option>
+ </select>
+ </div>
+ </div>
+
+ <!-- personType -->
+ <div class="form-group row">
+ <label for="personType" class="col-sm-2 col-form-label">{{ 'Internal.PersonType' | translate }}</label>
+ <div class="col-sm-4">
<select
type="text"
class="form-control"
- [ngrxFormControlState]="((internalPersonSandBox.formState$ | async)?.controls)['salutationId']">
- <option [value]="">{{ 'SelectOption' | translate }}</option> -->
- <option *ngFor="let salutation of internalPersonSandBox.salutations$ | async" [value]="salutation.id">{{salutation.type}}</option>
- </select>
- </div>
- </div>
-
- <!-- personType -->
- <div class="form-group row">
- <label for="personType" class="col-sm-2 col-form-label">{{ 'Internal.PersonType' | translate }}</label>
- <!-- <div class="col-sm-4">
- <select
- type="text"
- class="form-control"
- [ngrxFormControlState]="((internalPersonSandBox.formState$ | async)?.controls)['personTypeId']">
+ [ngrxFormControlState]="((internalPersonSandBox.internalPersonDetailsFormState$ | async)?.controls)['personTypeId']">
<option [value]="">{{ 'SelectOption' | translate }}</option>
<option *ngFor="let personType of internalPersonSandBox.personTypes$ | async" [value]="personType.id">{{personType.type}}</option>
</select>
- </div> -->
- <div class="col-sm-4">
- <input
- type="text"
- class="form-control"
- id="personType"
- [ngrxFormControlState]="((internalPersonSandBox.formState$ | async)?.controls)['personType']"
- autocomplete="off"
- />
</div>
- </div>
+ </div>
- <!-- Uid -->
- <div class="form-group row">
- <label for="uid" class="col-sm-2 col-form-label">{{ 'Internal.Uid' | translate }}</label>
- <div class="col-sm-4">
- <input
- type="text"
- class="form-control"
- id="uid"
- [ngrxFormControlState]="((internalPersonSandBox.formState$ | async)?.controls)['uid']"
- autocomplete="off"
- />
- </div>
+ <!-- Uid -->
+ <div class="form-group row">
+ <label for="uid" class="col-sm-2 col-form-label">{{ 'Internal.Uid' | translate }}</label>
+ <div class="col-sm-4">
+ <input
+ type="text"
+ maxlength="255"
+ class="form-control"
+ id="uid"
+ [ngrxFormControlState]="((internalPersonSandBox.internalPersonDetailsFormState$ | async)?.controls)['uid']"
+ autocomplete="off"
+ />
</div>
+ </div>
- <!-- Userref -->
- <div class="form-group row">
- <label for="userRef" class="col-sm-2 col-form-label">{{ 'Internal.Userref' | translate }}</label>
- <div class="col-sm-4">
- <input
- type="text"
- class="form-control"
- id="userRef"
- [ngrxFormControlState]="((internalPersonSandBox.formState$ | async)?.controls)['userRef']"
- autocomplete="off"
- />
- </div>
+ <!-- Userref -->
+ <div class="form-group row">
+ <label for="userRef" class="col-sm-2 col-form-label">{{ 'Internal.Userref' | translate }}</label>
+ <div class="col-sm-4">
+ <input
+ type="text"
+ maxlength="255"
+ class="form-control"
+ id="userRef"
+ [ngrxFormControlState]="((internalPersonSandBox.internalPersonDetailsFormState$ | async)?.controls)['userRef']"
+ autocomplete="off"
+ />
</div>
+ </div>
- <!-- Department -->
- <div class="form-group row">
- <label for="department" class="col-sm-2 col-form-label">{{ 'Internal.Department' | translate }}</label>
- <div class="col-sm-4">
- <input
- type="text"
- class="form-control"
- id="department"
- [ngrxFormControlState]="((internalPersonSandBox.formState$ | async)?.controls)['department']"
- autocomplete="off"
- />
- </div>
+ <!-- Department -->
+ <div class="form-group row">
+ <label for="department" class="col-sm-2 col-form-label">{{ 'Internal.Department' | translate }}</label>
+ <div class="col-sm-4">
+ <input
+ type="text"
+ maxlength="255"
+ class="form-control"
+ id="department"
+ [ngrxFormControlState]="((internalPersonSandBox.internalPersonDetailsFormState$ | async)?.controls)['department']"
+ autocomplete="off"
+ />
</div>
+ </div>
- <!-- contactNote -->
- <div class="form-group row">
- <label for="contactNote" class="col-sm-2 col-form-label">{{ 'Internal.Note' | translate }}</label>
- <div class="col-sm-4">
- <input
- type="text"
- class="form-control"
- id="contactNote"
- [ngrxFormControlState]="((internalPersonSandBox.formState$ | async)?.controls)['contactNote']"
- autocomplete="off"
- />
- </div>
+ <!-- contactNote -->
+ <div class="form-group row">
+ <label for="contactNote" class="col-sm-2 col-form-label">{{ 'Internal.Note' | translate }}</label>
+ <div class="col-sm-4">
+ <input
+ type="text"
+ maxlength="255"
+ class="form-control"
+ id="contactNote"
+ [ngrxFormControlState]="((internalPersonSandBox.internalPersonDetailsFormState$ | async)?.controls)['contactNote']"
+ autocomplete="off"
+ />
</div>
+ </div>
- <!-- buttons -->
- <button type="button" class="btn btn-success" (click)="save()">{{ 'SaveBtn' | translate }}</button>
+ <!-- buttons -->
+ <button type="button" class="btn btn-success" (click)="internalPersonSandBox.persistInternalPerson()">{{ 'SaveBtn' | translate }}</button>
+ <button type="button" class="btn btn-primary cancel-button" routerLink="/overview">
+ {{ 'CancelBtn' | translate }}
+ </button>
</div>
</form>
+
+
+ <app-expandable class="expandable-address" *ngIf="isExpandableVisible" >
+ <span header>{{ 'Contacts.AddressList' | translate }}</span>
+ <div class="expandable-body-container" body>
+ <div class="table-detail-view-address" *ngIf="internalPersonSandBox.isAddressDataDetailViewVisible">
+ <app-internal-person-address-details [createOrEditAddressData]="createOrEditAddressData"></app-internal-person-address-details>
+ </div>
+ <div class="table-view-address">
+ <app-internal-person-address-list (internalPersonDetailsId)="loadAddressDetail($event)" (createNewInternalPerson)="loadAddressDetail($event)"></app-internal-person-address-list>
+ </div>
+ </div>
+ </app-expandable>
+
+
+ <app-expandable class="expandable-communication" *ngIf="isExpandableVisible">
+ <span header>{{ 'Contacts.CommunicationsDataList' | translate }}</span>
+ <div class="expandable-body-container" body>
+ <div class="table-detail-view-communication" *ngIf="internalPersonSandBox.isCommunicationsDataDetailViewVisible">
+ <app-internal-person-communications-data-details [createOrEditCommunicationsData]="createOrEditCommunicationsData"></app-internal-person-communications-data-details>
+ </div>
+ <div class="table-view-communication">
+ <app-internal-person-communications-data-list (internalPersonDetailsId)="loadCommunicationsDataDetail($event)" (createNewInternalPerson)="loadCommunicationsDataDetail($event)"></app-internal-person-communications-data-list>
+ </div>
+ </div>
+ </app-expandable>
+
</div>
</app-card-layout>
diff --git a/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.component.scss b/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.component.scss
index 46dc5b1..7ae29d0 100644
--- a/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.component.scss
+++ b/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.component.scss
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -10,3 +10,33 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
+ .cancel-button {
+ margin-left: 16px;
+ }
+.expandable-body-container {
+ display: flex;
+ flex-direction: row;
+ height: 100%;
+}
+.table-detail-view-address {
+ height: 756px;
+ width: 461px;
+}
+.table-view-address {
+ height: 711px;
+ flex-grow: 1;
+}
+.expandable-address ::ng-deep .collapse5 {
+ height: 758px;
+}
+.table-detail-view-communication {
+ height: 296px;
+ width: 461px;
+}
+.table-view-communication {
+ height: 250px;
+ flex-grow: 1;
+}
+.expandable-communication ::ng-deep .collapse5 {
+ height: 297px;
+}
diff --git a/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.component.spec.ts b/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.component.spec.ts
index 1cfa23c..e43a462 100644
--- a/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.component.spec.ts
+++ b/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.component.spec.ts
@@ -10,29 +10,29 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { InternalPersonDetailsComponent } from '@app/pages/persons/internal-person/internal-person-details/internal-person-details.component';
+import { InternalPersonDetailsComponent } from '@pages/persons/internal-person/internal-person-details/internal-person-details.component';
describe('InternalPersonDetailsComponent', () => {
let component: InternalPersonDetailsComponent;
- let router: any;
let internalPersonSandbox: any;
- let salutationsSandbox: any;
+ let translate: any;
beforeEach(() => {
internalPersonSandbox = {
- updatingState() {},
- currentFormState: { isValid: true },
- persistInternalPerson() {},
- utilService: { displayNotification: () => {} }
+ registerAddressEvents() {},
+ registerInternalPersonEvents() {},
+ endSubscriptions() {},
+ loadCommunicationsDataDetails() {},
+ loadInternalPersonDetailsAddressDetails() {},
} as any;
- salutationsSandbox = {
- loadSalutations() {}
+ translate = {
+ instant() {},
} as any;
- component = new InternalPersonDetailsComponent(internalPersonSandbox, salutationsSandbox);
+ component = new InternalPersonDetailsComponent(internalPersonSandbox, translate);
});
it('should create', () => {
@@ -40,17 +40,68 @@
});
it('should loadSalutations on init', () => {
- const spy = spyOn(salutationsSandbox, 'loadSalutations');
+ const spy = spyOn(internalPersonSandbox, 'registerInternalPersonEvents');
component.ngOnInit();
expect(spy).toHaveBeenCalled();
});
- it('should call persist if form valid', () => {
- const persistSpy = spyOn(internalPersonSandbox, 'persistInternalPerson');
- component.save();
+ it('should end all subscriptions for this sandbox onDestroy', () => {
+ const spy = spyOn(internalPersonSandbox, 'endSubscriptions');
+ component.ngOnDestroy();
- expect(persistSpy).toHaveBeenCalled();
+ expect(spy).toHaveBeenCalled();
+ });
+ it('should call translate instant if no communications data id', () => {
+ const spy = spyOn(translate, 'instant');
+ component.loadCommunicationsDataDetail(null);
+
+ expect(spy).toHaveBeenCalledWith('CommunicationsData.NewCommunicationsData');
+ });
+
+ it('should call translate instant if there is an communications data id', () => {
+ const id = 'id';
+ const spy = spyOn(translate, 'instant');
+ const spy1 = spyOn(internalPersonSandbox, 'loadCommunicationsDataDetails');
+ component.loadCommunicationsDataDetail(id);
+
+ expect(spy).toHaveBeenCalledWith('CommunicationsData.EditCommunicationsData');
+ expect(spy1).toHaveBeenCalledWith(id);
+ });
+
+ it('should call translate instant if there is an communications data id', () => {
+ component.internalPersonSandBox.isCommunicationsDataDetailViewVisible = false;
+ component.loadCommunicationsDataDetail(null);
+ expect(component.internalPersonSandBox.isCommunicationsDataDetailViewVisible).toBeTruthy();
+ });
+
+ it('should call translate instant if no id', () => {
+ const spy = spyOn(translate, 'instant');
+ component.loadAddressDetail(null);
+
+ expect(spy).toHaveBeenCalledWith('Address.NewAddress');
+ });
+
+ it('should call translate instant if there is id', () => {
+ const id = 'id';
+ const spy = spyOn(translate, 'instant');
+ const spy1 = spyOn(internalPersonSandbox, 'loadInternalPersonDetailsAddressDetails');
+ component.loadAddressDetail(id);
+
+ expect(spy).toHaveBeenCalledWith('Address.EditAddress');
+ expect(spy1).toHaveBeenCalledWith(id);
+ });
+
+ it('should call translate instant if there is id', () => {
+ component.internalPersonSandBox.isAddressDataDetailViewVisible = false;
+ component.loadAddressDetail(null);
+ expect(component.internalPersonSandBox.isAddressDataDetailViewVisible).toBeTruthy();
+ });
+
+ it('should set expandableVisible to "true" if internalPersonContactId is defined', () => {
+ component.internalPersonSandBox.internalPersonContactId = 'test';
+ (component as any)._hideExpandable();
+ expect(component.isExpandableVisible).toBeTruthy();
});
});
diff --git a/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.component.ts b/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.component.ts
index c5a1d16..37d9be7 100644
--- a/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.component.ts
+++ b/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.component.ts
@@ -1,46 +1,72 @@
- /********************************************************************************
- * Copyright (c) 2020 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- ********************************************************************************/
-import { InternalPersonDetailsSandBox } from '@app/pages/persons/internal-person/internal-person-details/internal-person-details.sandbox';
-import { Component, OnInit } from '@angular/core';
-import { InternalPerson } from '@app/shared/models';
-import { SalutationsSandbox } from '@app/pages/admin/salutations/salutations.sandbox';
+/********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/
+import { InternalPersonDetailsSandBox } from '@pages/persons/internal-person/internal-person-details/internal-person-details.sandbox';
+import { Component, OnInit, OnDestroy } from '@angular/core';
+import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'app-internal-person-details',
templateUrl: './internal-person-details.component.html',
styleUrls: ['./internal-person-details.component.scss']
})
-export class InternalPersonDetailsComponent implements OnInit {
+export class InternalPersonDetailsComponent implements OnInit, OnDestroy {
+
+ public createOrEditCommunicationsData = '';
+ public createOrEditAddressData = '';
+ public isExpandableVisible = true;
constructor(
public internalPersonSandBox: InternalPersonDetailsSandBox,
- private salutationsSandbox: SalutationsSandbox,
- ) { }
+ private _translate: TranslateService
+ ) { }
ngOnInit() {
- this.salutationsSandbox.loadSalutations();
+ this.internalPersonSandBox.registerInternalPersonEvents();
+ this._hideExpandable();
+
}
- public save() {
- this.internalPersonSandBox.updatingState();
- if (this.internalPersonSandBox.currentFormState.isValid) {
- const newInternalPerson = new InternalPerson(this.internalPersonSandBox.currentFormState.value);
- this.internalPersonSandBox.persistInternalPerson(newInternalPerson);
+ ngOnDestroy() {
+ this.internalPersonSandBox.endSubscriptions();
+ }
+
+ public loadCommunicationsDataDetail(detailId: string) {
+ if (detailId == null) {
+ this.createOrEditCommunicationsData = this._translate.instant('CommunicationsData.NewCommunicationsData');
} else {
- this.internalPersonSandBox.utilService.displayNotification(
- 'MandatoryFieldsNotFilled',
- 'error'
- );
+ this.createOrEditCommunicationsData = this._translate.instant('CommunicationsData.EditCommunicationsData');
+ this.internalPersonSandBox.loadCommunicationsDataDetails(detailId);
+ }
+
+ this.internalPersonSandBox.isCommunicationsDataDetailViewVisible = true;
+ }
+
+ public loadAddressDetail(detailId: string) {
+ if (detailId == null) {
+ this.createOrEditAddressData = this._translate.instant('Address.NewAddress');
+ } else {
+ this.createOrEditAddressData = this._translate.instant('Address.EditAddress');
+ this.internalPersonSandBox.loadInternalPersonDetailsAddressDetails(detailId);
+ }
+
+ this.internalPersonSandBox.isAddressDataDetailViewVisible = true;
+ }
+
+ private _hideExpandable() {
+ if (!this.internalPersonSandBox.internalPersonContactId) {
+ this.isExpandableVisible = false;
+ } else {
+ this.isExpandableVisible = true;
}
}
}
diff --git a/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.sandbox.spec.ts b/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.sandbox.spec.ts
index 0aa0ef0..d4a115c 100644
--- a/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.sandbox.spec.ts
+++ b/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.sandbox.spec.ts
@@ -11,10 +11,10 @@
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
import { async } from '@angular/core/testing';
-import { InternalPersonDetailsSandBox } from '@app/pages/persons/internal-person/internal-person-details/internal-person-details.sandbox';
+import { InternalPersonDetailsSandBox } from '@pages/persons/internal-person/internal-person-details/internal-person-details.sandbox';
import { of } from 'rxjs';
-import * as internalPersonActions from '@app/shared/store/actions/persons/internal-person.action';
-import { InternalPerson } from '@app/shared/models';
+import * as internalPersonActions from '@shared/store/actions/persons/internal-person.action';
+import { InternalPerson, CommunicationsData, Address } from '@shared/models';
describe('InternalPersonDetailsSandBox', () => {
let component: InternalPersonDetailsSandBox;
@@ -22,16 +22,18 @@
let appState: any;
let actionSubject: any;
let router: any;
+ let modalService: any;
beforeEach(async(() => {
router = { navigateByUrl() {} } as any;
appState = { dispatch:()=> {}, pipe: () => of(true), select:()=> of(true) } as any;
- actionSubject = { pipe: () => of(true) } as any;
+ actionSubject = { pipe: () => of([]) } as any;
utilService = { displayNotification: () => {} } as any;
+ modalService = { open() {} } as any;
}));
beforeEach(() => {
- component = new InternalPersonDetailsSandBox(appState, utilService, actionSubject, router);
+ component = new InternalPersonDetailsSandBox(appState, utilService, actionSubject, router, modalService);
});
it('should create', () => {
@@ -44,24 +46,214 @@
expect(spy).toHaveBeenCalledWith( Object({ payload: 'ID', type: internalPersonActions.loadInternalPersonDetail.type }));
});
- it('should call dispatch if persist an internal person', () => {
+ it('should call dispatch 5 times if persist an existing internal person with unique uid and no userref', () => {
const spy = spyOn(appState, 'dispatch');
const routerSpy = spyOn(router, 'navigateByUrl');
- const internalPerson = new InternalPerson;
- component.persistInternalPerson(internalPerson);
- expect(spy).toHaveBeenCalledWith( Object({ payload: internalPerson, type: internalPersonActions.persistInternalPersonDetail.type }));
+ const notificationSpy = spyOn(utilService, 'displayNotification');
+ const actionSubjectSpy = spyOn(actionSubject, 'pipe').and.callThrough();
+
+ const internalPerson = new InternalPerson();
+ // its in edit mode because an existing id
+ internalPerson.contactId = 'id';
+ internalPerson.lastName = 'test';
+ internalPerson.uid = 'uid';
+ internalPerson.userRef = undefined;
+ component.internalPersonDetailsCurrentFormState = {...component.internalPersonDetailsCurrentFormState, isValid: true, value: internalPerson};
+ component.persistInternalPerson();
+ expect(spy).toHaveBeenCalledTimes(6);
expect(routerSpy).toHaveBeenCalled();
+ expect(notificationSpy).toHaveBeenCalledTimes(0);
+ expect(actionSubjectSpy).toHaveBeenCalledTimes(3);
});
- it('should call dispatch if updatingState', () => {
+ it('should call dispatch 4 times if persist an existing internal person with unique userref and no uid', () => {
const spy = spyOn(appState, 'dispatch');
- component.updatingState();
- expect(spy).toHaveBeenCalled();
+ const routerSpy = spyOn(router, 'navigateByUrl');
+ const notificationSpy = spyOn(utilService, 'displayNotification');
+ const actionSubjectSpy = spyOn(actionSubject, 'pipe').and.callThrough();
+
+ const internalPerson = new InternalPerson();
+ // its in edit mode because an existing id
+ internalPerson.contactId = 'id';
+ internalPerson.lastName = 'test';
+ internalPerson.uid = undefined;
+ internalPerson.userRef = 'userref';
+ component.internalPersonDetailsCurrentFormState = {...component.internalPersonDetailsCurrentFormState, isValid: true, value: internalPerson};
+ component.persistInternalPerson();
+ expect(spy).toHaveBeenCalledTimes(5);
+ expect(routerSpy).toHaveBeenCalled();
+ expect(notificationSpy).toHaveBeenCalledTimes(0);
+ expect(actionSubjectSpy).toHaveBeenCalledTimes(3);
});
- it('should call unregister subscibtions if call ngOnDestroy', () => {
- const spy = spyOn(component as any, 'unregisterEvents');
- component.ngOnDestroy();
+ it('should call error with displayNotification if for not valid', () => {
+ const utilSpy = spyOn(utilService, 'displayNotification');
+ component.internalPersonDetailsCurrentFormState = {...component.internalPersonDetailsCurrentFormState, isValid: false};
+ component.persistInternalPerson();
+ expect(utilSpy).toHaveBeenCalled();
+ });
+
+ it('should can register events and set the currentFormState', () => {
+ component.registerInternalPersonEvents();
+ expect(component.internalPersonDetailsCurrentFormState).toBeDefined();
+ });
+
+ it('should call dispatch if load an internal person communications Data', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.loadCommunicationsData('ID');
+ expect(spy).toHaveBeenCalledWith( Object({ payload: 'ID', type: internalPersonActions.loadInternalPersonDetailCommunicationsData.type }));
+ });
+
+ it('should call dispatch if load an internal person communicationsData details', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.internalPersonContactId = 'contactId'
+ component.loadCommunicationsDataDetails('ID');
+ expect(spy).toHaveBeenCalledWith( Object({ payload_contactId: 'contactId', payload_communicationsId: 'ID', type: internalPersonActions.loadInternalPersonDetailCommunicationsDataDetails.type }));
+ });
+
+ it('should can register communicationsData events and set the communicationsDataDetailsCurrentFormState', () => {
+ component.registerCommunicationsDataEvents();
+ expect(component.communicationsDataDetailsCurrentFormState).toBeDefined();
+ });
+
+ it('should call dispatch if clearInternalPerson', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.clearInternalPerson();
+ expect(spy).toHaveBeenCalledTimes(3);
+ });
+
+ it('should call dispatch if clearCommunicationsData', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.clearCommunicationsData();
+ expect(spy).toHaveBeenCalledTimes(2);
+ });
+
+ it('should call dispatch if persist an internal person communicationsData', () => {
+ const spy = spyOn(appState, 'dispatch');
+ const spy1 = spyOn(component, 'clearCommunicationsData');
+ const internalPersonCommunicationsData = new CommunicationsData();
+ internalPersonCommunicationsData.communicationTypeType = 'test';
+ internalPersonCommunicationsData.contactId = 'id';
+
+ component.communicationsDataDetailsCurrentFormState = {...component.communicationsDataDetailsCurrentFormState, isValid: true, value: internalPersonCommunicationsData};
+ component.persistCommunicationsData();
+ expect(spy).toHaveBeenCalledWith( Object({ payload: internalPersonCommunicationsData, type: internalPersonActions.persistCommunicationsDataDetail.type }));
+ expect(spy1).toHaveBeenCalled();
+ });
+
+ it('should call error with displayNotification if communicationsData form not valid', () => {
+ const utilSpy = spyOn(utilService, 'displayNotification');
+ component.communicationsDataDetailsCurrentFormState = {...component.communicationsDataDetailsCurrentFormState, isValid: false};
+ component.persistCommunicationsData();
+ expect(utilSpy).toHaveBeenCalled();
+ });
+
+ it('should call clearCommunicationsData and negate isCommunicationsDataDetailViewVisible after call closeCommunicationsDataDetail', () => {
+ const spy = spyOn(component, 'clearCommunicationsData');
+ component.isCommunicationsDataDetailViewVisible = true;
+ component.closeCommunicationsDataDetail();
expect(spy).toHaveBeenCalled();
+ expect(component.isCommunicationsDataDetailViewVisible).toBe(false);
+ });
+
+ it('should open modal before deleting an communicationsData', () => {
+ spyOn(component['modalService'], 'open')
+ .and.returnValue({componentInstance: {title: ''}, result: {then: () => of(true)}} as any);
+ component.deleteCommunicationsData(new CommunicationsData());
+ expect(modalService.open).toHaveBeenCalled();
+ });
+
+ it('should call dispatch if load an internal person addresses', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.loadInternalPersonAddresses('ID');
+ expect(spy).toHaveBeenCalledWith( Object({ payload: 'ID', type: internalPersonActions.loadInternalPersonDetailAddresses.type }));
+ });
+
+ it('should call dispatch if load an internal person address details', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.internalPersonContactId = 'contactId';
+ component.loadInternalPersonDetailsAddressDetails('ID');
+ expect(spy).toHaveBeenCalledWith( Object({ payload_contactId: 'contactId', payload_addressId: 'ID', type: internalPersonActions.loadInternalPersonDetailAddressDetails.type }));
+ });
+
+ it('should can register address events and set the addressDetailsCurrentFormState', () => {
+ component.registerAddressEvents();
+ expect(component.addressDetailsCurrentFormState).toBeDefined();
+ });
+
+ it('should call dispatch if clearInternalPerson', () => {
+ const spy = spyOn(appState, 'dispatch');
+ component.clearInternalPerson();
+ expect(spy).toHaveBeenCalledTimes(3);
+ });
+
+ it('should call dispatch if clearAddressData', () => {
+ const spy = spyOn(appState, 'dispatch');
+ (component as any).clearAddressData();
+ expect(spy).toHaveBeenCalledTimes(2);
+ });
+
+ it('should call dispatch if persist an internal person address', () => {
+ const spy = spyOn(appState, 'dispatch');
+ const spy1 = spyOn(component, 'clearAddressData');
+ const internalPersonAddress = new Address();
+ internalPersonAddress.addressTypeType = 'test';
+ internalPersonAddress.contactId = 'id';
+
+ component.addressDetailsCurrentFormState = {...component.addressDetailsCurrentFormState, isValid: true, value: internalPersonAddress};
+ component.persistAddress();
+ expect(spy).toHaveBeenCalledWith( Object({ payload: internalPersonAddress, type: internalPersonActions.persistAddressDetail.type }));
+ expect(spy1).toHaveBeenCalled();
+ });
+
+ it('should call error with displayNotification if address form not valid', () => {
+ const utilSpy = spyOn(utilService, 'displayNotification');
+ component.addressDetailsCurrentFormState = {...component.addressDetailsCurrentFormState, isValid: false};
+ component.persistAddress();
+ expect(utilSpy).toHaveBeenCalled();
+ });
+
+ it('should call clearAddressData and negate isDetailViewVisible after call closeAddressDataDetail', () => {
+ const spy = spyOn(component, 'clearAddressData');
+ component.isAddressDataDetailViewVisible = true;
+ component.closeAddressDataDetail();
+ expect(spy).toHaveBeenCalled();
+ expect(component.isAddressDataDetailViewVisible).toBe(false);
+ });
+
+ it('should open modal before deleting an address', () => {
+ spyOn(component['modalService'], 'open')
+ .and.returnValue({componentInstance: {title: ''}, result: {then: () => of(true)}} as any);
+ component.deleteAddress(new Address());
+ expect(modalService.open).toHaveBeenCalled();
+ });
+
+ it('should go in for-loop and set property "existMainAddress"', () => {
+ let address: Address = {
+ id: '',
+ contactId: '',
+ isMainAddress: false,
+ addressTypeId: '',
+ addressTypeType: '',
+ addressTypeDescription: '',
+ postcode: '',
+ community: '',
+ communitySuffix: '',
+ street: '',
+ housenumber: '',
+ wgs84Zone: '',
+ latitude: '',
+ longitude: '',
+ urlMap: '',
+ note: ''
+ };
+ const addresses: Array<Address> = [address];
+ (component as any)._checkIfMainAddressExist(addresses);
+ expect(component.existMainAddress).toBeFalsy();
+
+ address.isMainAddress = true;
+ addresses.push(address);
+ (component as any)._checkIfMainAddressExist(addresses);
+ expect(component.existMainAddress).toBeTruthy();
});
});
diff --git a/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.sandbox.ts b/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.sandbox.ts
index 46f6080..c577afd 100644
--- a/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.sandbox.ts
+++ b/src/app/pages/persons/internal-person/internal-person-details/internal-person-details.sandbox.ts
@@ -1,39 +1,58 @@
- /********************************************************************************
- * Copyright (c) 2020 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- ********************************************************************************/
+/********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/
import { BaseSandbox } from '@shared/sandbox/base.sandbox';
-import { Injectable, OnDestroy } from '@angular/core';
-import * as internalPersonActions from '@app/shared/store/actions/persons/internal-person.action';
-import { FormGroupState, MarkAsTouchedAction, SetValueAction, ResetAction, MarkAsUntouchedAction } from 'ngrx-forms';
-import { InternalPerson } from '@app/shared/models';
-import { Observable, Subscription } from 'rxjs';
+import { Injectable } from '@angular/core';
+import * as internalPersonActions from '@shared/store/actions/persons/internal-person.action';
+import { FormGroupState, SetValueAction, ResetAction, MarkAsTouchedAction } from 'ngrx-forms';
+import { InternalPerson, CommunicationsData, CommunicationType, Address } from '@shared/models';
+import { Observable } from 'rxjs';
import * as store from '@shared/store';
import { Store, ActionsSubject } from '@ngrx/store';
import * as internalPersonDetailsFormReducer from '@shared/store/reducers/persons/internal-person/internal-person-details-form.reducer';
+import * as internalAddressDetailsFormReducer from '@shared/store/reducers/persons/internal-person/addresses-details-form.reducer';
import { ofType } from '@ngrx/effects';
-import { UtilService } from '@app/shared/utility';
-import { takeUntil } from 'rxjs/operators';
+import { UtilService } from '@shared/utility';
+import { takeUntil, take, map } from 'rxjs/operators';
import { Router } from '@angular/router';
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { SafetyQueryDialogComponent } from '@shared/components/dialogs/safety-query-dialog/safety-query-dialog.component';
+import * as internalCommunicationsDataDetailsFormReducer from '@shared/store/reducers/persons/internal-person/communications-data-details-form.reducer';
+import * as communicationTypesActions from '@shared/store/actions/admin/communication-types.action';
@Injectable()
-export class InternalPersonDetailsSandBox extends BaseSandbox implements OnDestroy {
+export class InternalPersonDetailsSandBox extends BaseSandbox {
- public formState$: Observable<FormGroupState<InternalPerson>> = this.appState$.select(store.getInternalPersonDetails);
-
- public currentFormState: FormGroupState<InternalPerson>;
- private subscriptions: Array<Subscription> = [];
-
+ public internalPersonDetailsFormState$: Observable<FormGroupState<InternalPerson>> = this.appState$.select(store.getInternalPersonDetails);
+ public internalPersonDetailsCurrentFormState: FormGroupState<InternalPerson>;
public salutations$ = this.appState$.select(store.getSalutationsData);
+ public communicationsDataDetailsFormState$: Observable<FormGroupState<CommunicationsData>> = this.appState$.select(store.getInternalPersonCommunicationsDataDetails);
+ public communicationsDataDetailsCurrentFormState: FormGroupState<CommunicationsData>;
+ public communicationsDataList$: Observable<Array<CommunicationsData>> = this.appState$.select(store.getInternalCommunicationsDataData);
+ public communicationsDataListLoading$: Observable<boolean> = this.appState$.select(store.getInternalCommunicationsDataLoading);
+ public addressDetailsFormState$: Observable<FormGroupState<Address>> = this.appState$.select(store.getInternalPersonAddressesDetails);
+ public addressDetailsCurrentFormState: FormGroupState<Address>;
+ public addressList$: Observable<Array<Address>> = this.appState$.select(store.getInternalAddressesData);
+ public addressListLoading$: Observable<boolean> = this.appState$.select(store.getInternalAddressesLoading);
+ public isCommunicationsDataDetailViewVisible: boolean = false;
+ public isAddressDataDetailViewVisible: boolean = false;
+ public existMainAddress = false;
+ public isCurrentAddressMainAddress = false;
+ public internalPersonContactId: string;
+ private _currentInternalPerson: InternalPerson = null;
+ private _communicationTypes: Array<CommunicationType> = new Array<CommunicationType>();
+
+ public personTypes$ = this.appState$.select(store.getPersonTypesData);
/**
* InternalPerson Sandbox constructor
*/
@@ -42,50 +61,169 @@
public utilService: UtilService,
protected actionsSubject: ActionsSubject,
protected router: Router,
+ protected modalService: NgbModal
) {
super(appState$);
- this.registerEvents();
- }
+ this.addressList$.subscribe(addresses => {
+ this._checkIfMainAddressExist(addresses);
+ });
- /**
- * Loads internal person from the server
- */
- public loadInternalPerson(id: string): void {
- this.appState$.dispatch(
- internalPersonActions.loadInternalPersonDetail({ payload: id })
- );
- }
-
- /**
- * Persists an internal person
- */
- public persistInternalPerson(newInternalPerson: InternalPerson): void {
- this.appState$.dispatch(
- internalPersonActions.persistInternalPersonDetail({
- payload: newInternalPerson
- })
- );
this.actionsSubject
+ .pipe(
+ ofType(internalPersonActions.loadInternalPersonDetailAddressDetailsSuccess),
+ map((action: { payload: Address }) => action.payload),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe((address: Address) => {
+ this._checkIfCurrentAddressIsMainAddress(address);
+ });
+ }
+
+ public loadInternalPerson(id: string): void {
+ this.internalPersonContactId = id;
+ this.appState$.dispatch(internalPersonActions.loadInternalPersonDetail({ payload: id }));
+
+ this.actionsSubject
+ .pipe(
+ ofType(internalPersonActions.loadInternalPersonDetailSuccess),
+ map((action: internalPersonActions.ILoadInternalPersonDetailsSuccess) => action.payload),
+ take(1),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe((payload: InternalPerson) => {
+ this._currentInternalPerson = payload;
+ });
+ }
+
+ public loadInternalPersonAddresses(internalPersonId: string): void {
+ this.appState$.dispatch(
+ internalPersonActions.loadInternalPersonDetailAddresses({ payload: internalPersonId })
+ );
+ }
+
+ public loadInternalPersonDetailsAddressDetails(addressId: string): void {
+ this.appState$.dispatch(
+ internalPersonActions.loadInternalPersonDetailAddressDetails({ payload_contactId: this.internalPersonContactId, payload_addressId: addressId })
+ );
+ }
+
+ public persistInternalPerson(): void {
+ if (this.internalPersonDetailsCurrentFormState.isValid) {
+
+ let isUidUnique: boolean = null;
+ let isUserrefUnique: boolean = null;
+ const isNew: boolean = this.internalPersonDetailsCurrentFormState.value.contactId === null;
+
+ if (this.internalPersonDetailsCurrentFormState.value.uid) {
+ this.appState$.dispatch(internalPersonActions.loadInternalPersonsForUid({ payload: { uid: this.internalPersonDetailsCurrentFormState.value.uid } }));
+ }
+ if (this.internalPersonDetailsCurrentFormState.value.userRef) {
+ this.appState$.dispatch(internalPersonActions.loadInternalPersonsForUserref({ payload: { userRef: this.internalPersonDetailsCurrentFormState.value.userRef } }));
+ }
+ if (!this.internalPersonDetailsCurrentFormState.value.uid && !this.internalPersonDetailsCurrentFormState.value.userRef) {
+ this.appState$.dispatch(internalPersonActions.persistInternalPersonDetail({ payload: this.internalPersonDetailsCurrentFormState.value }));
+ }
+
+ this.actionsSubject
+ .pipe(
+ ofType(internalPersonActions.loadInternalPersonsForUidSuccess),
+ map((action: internalPersonActions.ILoadInternalPersonsForUidSuccess) => action.payload),
+ take(1),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe((payload: Array<InternalPerson>) => {
+
+ isUidUnique = payload.length == 0 || (!isNew && payload.length == 1 && payload[0].uid === this._currentInternalPerson.uid);
+
+ if (!isUidUnique) {
+ this.utilService.displayNotification('InternalError.UniqueUid', 'error');
+ } else {
+ if ((isUidUnique && this.internalPersonDetailsCurrentFormState.value.userRef && isUserrefUnique) || (isUidUnique && !this.internalPersonDetailsCurrentFormState.value.userRef)) {
+ this.appState$.dispatch(internalPersonActions.persistInternalPersonDetail({ payload: this.internalPersonDetailsCurrentFormState.value }));
+ }
+ }
+ });
+
+ this.actionsSubject
+ .pipe(
+ ofType(internalPersonActions.loadInternalPersonsForUserrefSuccess),
+ map((action: internalPersonActions.ILoadInternalPersonsForUserrefSuccess) => action.payload),
+ take(1),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe((payload: Array<InternalPerson>) => {
+
+ isUserrefUnique = payload.length == 0 || (!isNew && payload.length == 1 && payload[0].userRef === this._currentInternalPerson.userRef);
+
+ if (!isUserrefUnique) {
+ this.utilService.displayNotification('InternalError.UniqueUserref', 'error');
+ } else {
+ if ((isUserrefUnique && this.internalPersonDetailsCurrentFormState.value.uid && isUidUnique) || (isUserrefUnique && !this.internalPersonDetailsCurrentFormState.value.uid)) {
+ this.appState$.dispatch(internalPersonActions.persistInternalPersonDetail({ payload: this.internalPersonDetailsCurrentFormState.value }));
+ }
+ }
+ });
+
+ this.actionsSubject
.pipe(
ofType(internalPersonActions.persistInternalPersonDetailSuccess),
+ take(1),
takeUntil(this._endSubscriptions$)
)
.subscribe(() => {
+ this.clearInternalPerson();
this.router.navigateByUrl(`/overview`);
});
- this.subscriptions.push(
- this.actionsSubject
- .pipe(ofType(internalPersonActions.persistInternalPersonDetailSuccess))
- .subscribe(() => {
- this.clear();
- })
- );
+ } else {
+ this.utilService.displayNotification('MandatoryFieldsNotFilled', 'error');
+ }
}
- /**
- * Clear
- */
- clear(): void {
+ public persistAddress(): void {
+ if (this.addressDetailsCurrentFormState.isValid) {
+ const newAddress = new Address(this.addressDetailsCurrentFormState.value);
+ newAddress.contactId = newAddress.contactId !== null ? newAddress.contactId : this.internalPersonContactId;
+
+ this.appState$.dispatch(
+ internalPersonActions.persistAddressDetail({ payload: newAddress })
+ );
+ this.actionsSubject
+ .pipe(
+ ofType(internalPersonActions.persistAddressDetailSuccess),
+ take(1),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe(() => {
+ this.closeAddressDataDetail();
+ });
+ } else {
+ this.utilService.displayNotification(
+ 'MandatoryFieldsNotFilled',
+ 'error'
+ );
+ }
+ }
+
+ public deleteAddress(address: Address): void {
+ const modalRef = this.modalService.open(SafetyQueryDialogComponent);
+ modalRef.componentInstance.title = 'ConfirmDialog.Action.delete';
+ modalRef.componentInstance.body = 'ConfirmDialog.Deletion';
+ modalRef.result.then(() => {
+ this.appState$.dispatch(internalPersonActions.deleteAddress({ payload: address }));
+ if (address.isMainAddress) {
+ this.existMainAddress = false;
+ }
+ this.closeAddressDataDetail();
+ }, () => {
+ });
+ }
+
+ public closeAddressDataDetail(): void {
+ this.clearAddressData();
+ this.isAddressDataDetailViewVisible = false;
+ }
+
+ public clearInternalPerson(): void {
this.appState$.dispatch(
new SetValueAction(
internalPersonDetailsFormReducer.FORM_ID,
@@ -93,37 +231,145 @@
)
);
this.appState$.dispatch(new ResetAction(internalPersonDetailsFormReducer.FORM_ID));
- }
-
- /**
- * Clean up before leaving
- */
- public ngOnDestroy() {
- this.unregisterEvents();
- }
-
- /**
- * Unsubscribes from events
- */
- private unregisterEvents() {
- this.subscriptions.forEach(sub => sub.unsubscribe());
- }
-
- public updatingState() {
this.appState$.dispatch(new MarkAsTouchedAction(internalPersonDetailsFormReducer.FORM_ID));
}
- /**
- * Subscribes to events
- */
- private registerEvents(): void {
-
- // subscribes to formState
- this.subscriptions.push(
- this.formState$.subscribe(
- (formState: FormGroupState<InternalPerson>) =>
- (this.currentFormState = formState)
+ public clearAddressData(): void {
+ this.isCurrentAddressMainAddress = false;
+ this.appState$.dispatch(
+ new SetValueAction(
+ internalAddressDetailsFormReducer.FORM_ID,
+ internalAddressDetailsFormReducer.INITIAL_STATE.value
)
);
+ this.appState$.dispatch(new ResetAction(internalAddressDetailsFormReducer.FORM_ID));
}
+
+ public registerInternalPersonEvents(): void {
+ // subscribes to formState
+ this.internalPersonDetailsFormState$.pipe(takeUntil(this._endSubscriptions$)).subscribe(
+ (formState: FormGroupState<InternalPerson>) =>
+ (this.internalPersonDetailsCurrentFormState = formState)
+ );
+ }
+
+ public loadCommunicationsData(internalPersonId: string): void {
+ this.actionsSubject
+ .pipe(
+ ofType(communicationTypesActions.loadCommunicationTypesSuccess),
+ map((action: communicationTypesActions.ILoadCommunicationTypesSuccess) => action.payload),
+ take(1),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe((payload: Array<CommunicationType>) => {
+ this._communicationTypes = payload;
+ this.appState$.dispatch(internalPersonActions.loadInternalPersonDetailCommunicationsData({ payload: internalPersonId }));
+ });
+
+ this.actionsSubject
+ .pipe(
+ ofType(internalPersonActions.loadInternalPersonDetailCommunicationsDataSuccess),
+ map((action: internalPersonActions.ILoadInternalPersonCommunicationsDataSuccess) => action.payload),
+ take(1),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe((communicationsData: Array<CommunicationsData>) => {
+ if (this._communicationTypes) {
+ for (let i = 0; i < this._communicationTypes.length; i++) {
+ const ct = this._communicationTypes[i];
+ const existingCommunicationsData: CommunicationsData = communicationsData.find(cd => cd.communicationTypeId == ct.id);
+ ct.isDisabled = existingCommunicationsData ? true : false;
+ }
+ }
+ });
+ }
+
+ public loadCommunicationsDataDetails(communicationsDataId: string): void {
+ this.appState$.dispatch(
+ internalPersonActions.loadInternalPersonDetailCommunicationsDataDetails({ payload_contactId: this.internalPersonContactId, payload_communicationsId: communicationsDataId })
+ );
+ }
+
+ public persistCommunicationsData(): void {
+ if (this.communicationsDataDetailsCurrentFormState.isValid) {
+ const newCommunicationsData = new CommunicationsData(this.communicationsDataDetailsCurrentFormState.value);
+ newCommunicationsData.contactId = newCommunicationsData.contactId !== null ? newCommunicationsData.contactId : this.internalPersonContactId;
+
+ this.appState$.dispatch(
+ internalPersonActions.persistCommunicationsDataDetail({ payload: newCommunicationsData })
+ );
+ this.actionsSubject
+ .pipe(
+ ofType(internalPersonActions.persistCommunicationsDataDetailSuccess),
+ take(1),
+ takeUntil(this._endSubscriptions$)
+ )
+ .subscribe(() => {
+ this.closeCommunicationsDataDetail();
+ });
+ } else {
+ this.utilService.displayNotification(
+ 'MandatoryFieldsNotFilled',
+ 'error'
+ );
+ }
+ }
+
+ public deleteCommunicationsData(communicationsData: CommunicationsData): void {
+ const modalRef = this.modalService.open(SafetyQueryDialogComponent);
+ modalRef.componentInstance.title = 'ConfirmDialog.Action.delete';
+ modalRef.componentInstance.body = 'ConfirmDialog.Deletion';
+ modalRef.result.then(() => {
+ this.appState$.dispatch(internalPersonActions.deleteCommunicationsData({ payload: communicationsData }));
+ this.closeCommunicationsDataDetail();
+ }, () => {
+ });
+ }
+
+ public closeCommunicationsDataDetail(): void {
+ this.loadCommunicationsData(this.internalPersonContactId);
+ this.clearCommunicationsData();
+ this.isCommunicationsDataDetailViewVisible = false;
+ }
+
+ public clearCommunicationsData(): void {
+ this.appState$.dispatch(
+ new SetValueAction(
+ internalCommunicationsDataDetailsFormReducer.FORM_ID,
+ internalCommunicationsDataDetailsFormReducer.INITIAL_STATE.value
+ )
+ );
+ this.appState$.dispatch(new ResetAction(internalCommunicationsDataDetailsFormReducer.FORM_ID));
+ }
+
+ public registerCommunicationsDataEvents(): void {
+ // subscribes to formState
+ this.communicationsDataDetailsFormState$.pipe(takeUntil(this._endSubscriptions$)).subscribe(
+ (formState: FormGroupState<CommunicationsData>) =>
+ (this.communicationsDataDetailsCurrentFormState = formState)
+ );
+ }
+
+ public registerAddressEvents(): void {
+ // subscribes to formState
+ this.addressDetailsFormState$.pipe(takeUntil(this._endSubscriptions$)).subscribe(
+ (formState: FormGroupState<Address>) =>
+ (this.addressDetailsCurrentFormState = formState)
+ );
+ }
+
+ private _checkIfMainAddressExist(addresses: Array<Address>) {
+ for (let i = 0; i < addresses.length; i++) {
+ const address = addresses[i];
+ if (address.isMainAddress) {
+ this.existMainAddress = true;
+ break;
+ }
+ this.existMainAddress = false;
+ }
+ };
+
+ private _checkIfCurrentAddressIsMainAddress(address: Address) {
+ this.isCurrentAddressMainAddress = address.isMainAddress ? true : false;
+ };
}
diff --git a/src/app/pages/persons/internal-person/internal-person.resolver.spec.ts b/src/app/pages/persons/internal-person/internal-person.resolver.spec.ts
index 9ba8998..2d71c18 100644
--- a/src/app/pages/persons/internal-person/internal-person.resolver.spec.ts
+++ b/src/app/pages/persons/internal-person/internal-person.resolver.spec.ts
@@ -16,16 +16,33 @@
describe('InternalPersonResolver', () => {
let component: InternalPersonResolver;
let internalPersonSandbox: any;
+ let salutationsSandbox: any;
+ let communicationTypesSandbox: any;
+ let personTypesSandbox: any;
beforeEach(async(() => {
internalPersonSandbox = {
- clear() {},
+ clearInternalPerson() {},
loadInternalPerson() {},
+ loadCommunicationsData() {},
+ loadInternalPersonAddresses() {},
+ } as any;
+
+ salutationsSandbox = {
+ loadSalutations() {}
+ } as any;
+
+ personTypesSandbox = {
+ loadPersonTypes() {}
+ } as any;
+
+ communicationTypesSandbox = {
+ loadCommunicationTypes() {}
} as any;
}));
beforeEach(() => {
- component = new InternalPersonResolver(internalPersonSandbox);
+ component = new InternalPersonResolver(internalPersonSandbox, salutationsSandbox, communicationTypesSandbox, personTypesSandbox);
});
it('should create', () => {
@@ -39,10 +56,48 @@
expect(spy).toHaveBeenCalled();
});
- it('should call clear if edit a internal person', () => {
- const spy = spyOn(internalPersonSandbox, 'clear');
+ it('should call clear if create a new internal person', () => {
+ const spy = spyOn(internalPersonSandbox, 'clearInternalPerson');
let ar: any = {params: {contactId: undefined}};
component.resolve(ar);
expect(spy).toHaveBeenCalled();
});
+
+ it('should loadSalutations on resolve', () => {
+ const spy = spyOn(salutationsSandbox, 'loadSalutations');
+ let ar: any = {params: {contactId: undefined}};
+ component.resolve(ar);
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should loadCommunicationTypes on resolve', () => {
+ const spy = spyOn(communicationTypesSandbox, 'loadCommunicationTypes');
+ let ar: any = {params: {contactId: undefined}};
+ component.resolve(ar);
+
+ expect(spy).toHaveBeenCalled();
+ });
+
+ it('should set isCommunicationsDataDetailViewVisible true on resolve', () => {
+ let ar: any = {params: {contactId: undefined}};
+ component.resolve(ar);
+
+ expect(internalPersonSandbox.isCommunicationsDataDetailViewVisible).toBeFalsy();
+ });
+
+ it('should set isDetailViewVisible true on resolve', () => {
+ let ar: any = {params: {contactId: undefined}};
+ component.resolve(ar);
+
+ expect(internalPersonSandbox.isDetailViewVisible).toBeFalsy();
+ });
+
+ it('should loadPersonTypes on resolve', () => {
+ const spy = spyOn(personTypesSandbox, 'loadPersonTypes');
+ let ar: any = {params: {contactId: undefined}};
+ component.resolve(ar);
+
+ expect(spy).toHaveBeenCalled();
+ });
});
diff --git a/src/app/pages/persons/internal-person/internal-person.resolver.ts b/src/app/pages/persons/internal-person/internal-person.resolver.ts
index 88a1aeb..a6af19e 100644
--- a/src/app/pages/persons/internal-person/internal-person.resolver.ts
+++ b/src/app/pages/persons/internal-person/internal-person.resolver.ts
@@ -10,30 +10,40 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { InternalPersonDetailsSandBox } from '@app/pages/persons/internal-person/internal-person-details/internal-person-details.sandbox';
+import { InternalPersonDetailsSandBox } from '@pages/persons/internal-person/internal-person-details/internal-person-details.sandbox';
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
import { Injectable } from '@angular/core';
+import { SalutationsSandbox } from '@pages/admin/salutations/salutations.sandbox';
+import { CommunicationTypesSandbox } from '@pages/admin/communication-types/communication-types.sandbox';
+import { PersonTypesSandbox } from '@pages/admin/person-types/person-types.sandbox';
-@Injectable({
- providedIn: 'root'
-})
+@Injectable()
export class InternalPersonResolver implements Resolve<any>{
constructor(
private internalPersonSandbox: InternalPersonDetailsSandBox,
+ private salutationsSandbox: SalutationsSandbox,
+ private communicationTypesSandbox: CommunicationTypesSandbox,
+ private personTypesSandbox: PersonTypesSandbox
) { }
/**
- * Triggered when application hits code table details or code value details route.
* @param route
*/
public resolve(route: ActivatedRouteSnapshot): void {
const contactId: string = route.params['contactId'];
if (contactId && (contactId !== 'new')) {
this.internalPersonSandbox.loadInternalPerson(contactId);
+ this.internalPersonSandbox.loadCommunicationsData(contactId);
+ this.internalPersonSandbox.loadInternalPersonAddresses(contactId);
} else {
- this.internalPersonSandbox.clear();
+ this.internalPersonSandbox.clearInternalPerson();
}
+
+ this.salutationsSandbox.loadSalutations();
+ this.personTypesSandbox.loadPersonTypes();
+ this.communicationTypesSandbox.loadCommunicationTypes();
+ this.internalPersonSandbox.isCommunicationsDataDetailViewVisible = false;
}
}
diff --git a/src/app/pages/persons/persons-api-client.ts b/src/app/pages/persons/persons-api-client.ts
index 9f3afab..c51efca 100644
--- a/src/app/pages/persons/persons-api-client.ts
+++ b/src/app/pages/persons/persons-api-client.ts
@@ -1,20 +1,21 @@
- /********************************************************************************
- * Copyright (c) 2020 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- ********************************************************************************/
+/********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/
import { Injectable } from '@angular/core';
-import { HttpService, GET, Path, Adapter, PUT, Body, DefaultHeaders, POST } from '@shared/asyncServices/http';
+import { HttpService, GET, Path, Adapter, PUT, Body, DefaultHeaders, POST, DELETE, Query } from '@shared/asyncServices/http';
import { Observable } from 'rxjs';
import { PersonsService } from '@pages/persons/persons.service';
-import { ExternalPerson, InternalPerson } from '@shared/models';
+import { ExternalPerson, InternalPerson, Address, CommunicationsData } from '@shared/models';
+import { InternalPersonInterface } from '@shared/models/persons/internal-person-arguments.interface';
@Injectable()
@DefaultHeaders({
@@ -34,6 +35,28 @@
}
/**
+ * Retrieves contact details addresses by a given contactId
+ *
+ * @param contactId
+ */
+ @GET('/contacts/{contactId}/addresses')
+ @Adapter(PersonsService.addressesAdapter)
+ public getAddresses(@Path('contactId') contactId: string): Observable<Address[]> {
+ return null;
+ }
+
+ /**
+* Retrieves contact details addresses details by a given contactId and addressId
+*
+* @param contactId
+*/
+ @GET('/contacts/{contactId}/addresses/{addressId}')
+ @Adapter(PersonsService.addressesDetailsAdapter)
+ public getAddressesDetails(@Path('contactId') contactId: string, @Path('addressId') addressId: string): Observable<Address> {
+ return null;
+ }
+
+ /**
* Change the external person details by a given contactId
*
* @param contactId
@@ -89,4 +112,117 @@
public postInternalPersonDetails(@Body() newInternalPerson: InternalPerson): Observable<InternalPerson> {
return null;
}
+
+ /**
+ * Get internal persons.
+ *
+ * @param uid
+ * @param userRef
+ */
+ @GET('/internal-persons')
+ @Adapter(PersonsService.internalPersonsAdapter)
+ private _getInternalPersons(@Query('uid') uid?: string, @Query('userRef') userRef?: string): Observable<Array<InternalPerson>> {
+ return null;
+ }
+
+ public getInternalPersons(request: InternalPersonInterface): Observable<Array<InternalPerson>> {
+ if(request != null){
+ return this._getInternalPersons(request.uid, request.userRef);
+ }
+
+ }
+
+ /**
+ * Change the address details by a given addressId
+ *
+ * @param addressId
+ * @param editedAddress
+ */
+ @PUT('/contacts/{contactId}/addresses/{addressId}')
+ @Adapter(PersonsService.addressesDetailsAdapter)
+ public putAddressDetails(@Path('contactId') contactId: string, @Path('addressId') addressId: string, @Body() editedAdress: Address): Observable<Address> {
+ return null;
+ }
+
+ /**
+ * Saves new address details.
+ *
+ * @param newAddress
+ */
+ @POST('/contacts/{contactId}/addresses')
+ @Adapter(PersonsService.addressesDetailsAdapter)
+ public postAddressDetails(@Path('contactId') contactId: string, @Body() newExternalPersonAddress: Address): Observable<Address> {
+ return null;
+ }
+
+ /**
+ * Deletes by a given id
+ *
+ * @param id
+ */
+ @DELETE('/contacts/{contactId}/addresses/{addressId}')
+ @Adapter(PersonsService.addressesDetailsAdapter)
+ public deleteAddress(@Path('contactId') contactId: string, @Path('addressId') addressId: string): Observable<void> {
+ return null;
+ }
+
+ /**
+ * Retrieves communications data by a given contactId
+ *
+ * @param contactId
+ */
+ @GET('/contacts/{contactId}/communications')
+ @Adapter(PersonsService.communicationsDataAdapter)
+ public getCommunicationsData(@Path('contactId') contactId: string): Observable<CommunicationsData[]> {
+ return null;
+ }
+
+ /**
+ * Retrieves communications data details by a given contactId and communicationId
+ *
+ * @param contactId
+ * @param communicationId
+ */
+ @GET('/contacts/{contactId}/communications/{communicationId}')
+ @Adapter(PersonsService.communicationsDataDetailsAdapter)
+ public getCommunicationsDataDetails(@Path('contactId') contactId: string, @Path('communicationId') communicationId: string): Observable<CommunicationsData> {
+ return null;
+ }
+
+ /**
+ * Change the communications data details by a given communicationId
+ *
+ * @param contactId
+ * @param communicationId
+ * @param editedCommunicationsData
+ */
+ @PUT('/contacts/{contactId}/communications/{communicationId}')
+ @Adapter(PersonsService.communicationsDataDetailsAdapter)
+ public putCommunicationsDataDetails(@Path('contactId') contactId: string, @Path('communicationId') communicationId: string, @Body() editedCommunicationsData: CommunicationsData): Observable<CommunicationsData> {
+ return null;
+ }
+
+ /**
+ * Saves new address details.
+ *
+ * @param contactId
+ * @param newcommunicationsData
+ */
+ @POST('/contacts/{contactId}/communications')
+ @Adapter(PersonsService.communicationsDataDetailsAdapter)
+ public postCommunicationsDataDetails(@Path('contactId') contactId: string, @Body() newcommunicationsData: CommunicationsData): Observable<CommunicationsData> {
+ return null;
+ }
+
+ /**
+ * Deletes by a given id
+ *
+ * @param contactId
+ * @param communicationId
+ */
+ @DELETE('/contacts/{contactId}/communications/{communicationId}')
+ @Adapter(PersonsService.communicationsDataDetailsAdapter)
+ public deleteCommunicationsData(@Path('contactId') contactId: string, @Path('communicationId') communicationId: string): Observable<void> {
+ return null;
+ }
}
diff --git a/src/app/pages/persons/persons.module.ts b/src/app/pages/persons/persons.module.ts
index 370f7a2..92076b8 100644
--- a/src/app/pages/persons/persons.module.ts
+++ b/src/app/pages/persons/persons.module.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -16,28 +16,36 @@
import { RouterModule } from '@angular/router';
import { ComponentsModule } from '@shared/components';
import { TranslateModule } from '@ngx-translate/core';
-import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import { NgrxFormsModule } from 'ngrx-forms';
import { FormsModule } from '@angular/forms';
import { AgGridModule } from 'ag-grid-angular';
import { DirectivesModule } from '@shared/directives';
import { FiltersModule } from '@shared/filters/index.module';
import { ContainersModule } from '@shared/containers';
-import { SetFilterComponent } from '@app/shared/filters/ag-grid/set-filter/set-filter.component';
+import { SetFilterComponent } from '@shared/filters/ag-grid/set-filter/set-filter.component';
import { PersonsApiClient } from '@pages/persons/persons-api-client';
-import { ExternalPersonDetailsComponent } from '@app/pages/persons/external-person/external-person-details/external-person-details.component';
+import { ExternalPersonDetailsComponent } from '@pages/persons/external-person/external-person-details/external-person-details.component';
import { PersonsService } from '@pages/persons/persons.service';
-import { ExternalPersonDetailsSandBox } from '@app/pages/persons/external-person/external-person-details/external-person-details.sandbox';
+import { ExternalPersonDetailsSandBox } from '@pages/persons/external-person/external-person-details/external-person-details.sandbox';
import { StoreModule } from '@ngrx/store';
-import { personsReducers } from '@app/shared/store';
+import { personsReducers } from '@shared/store';
import { ExternalPersonResolver } from '@pages/persons/external-person/external-person.resolver';
import { PersonsRoutingModule } from '@pages/persons/persons.routing.module';
import { EffectsModule } from '@ngrx/effects';
-import { ExternalPersonEffect } from '@app/shared/store/effects/persons/external-person.effect';
-import { InternalPersonDetailsComponent } from '@app/pages/persons/internal-person/internal-person-details/internal-person-details.component';
-import { InternalPersonEffect } from '@app/shared/store/effects/persons/internal-person.effect';
-import { InternalPersonDetailsSandBox } from '@app/pages/persons/internal-person/internal-person-details/internal-person-details.sandbox';
+import { ExternalPersonEffect } from '@shared/store/effects/persons/external-person.effect';
+import { InternalPersonDetailsComponent } from '@pages/persons/internal-person/internal-person-details/internal-person-details.component';
+import { InternalPersonEffect } from '@shared/store/effects/persons/internal-person.effect';
+import { InternalPersonDetailsSandBox } from '@pages/persons/internal-person/internal-person-details/internal-person-details.sandbox';
import { InternalPersonResolver } from '@pages/persons/internal-person/internal-person.resolver';
+import { ExternalPersonAddressListComponent } from '@pages/persons/external-person/external-person-details/address-list/address-list.component';
+import { ExternalPersonAddressDetailsComponent } from '@pages/persons/external-person/external-person-details/address-details/address-details.component';
+import { InternalPersonAddressListComponent } from '@pages/persons/internal-person/internal-person-details/address-list/address-list.component';
+import { InternalPersonAddressDetailsComponent } from '@pages/persons/internal-person/internal-person-details/address-details/address-details.component';
+import { ExternalPersonCommunicationsDataDetailsComponent } from '@pages/persons/external-person/external-person-details/communications-data-details/communications-data-details.component';
+import { ExternalPersonCommunicationsDataListComponent } from '@pages/persons/external-person/external-person-details/communications-data-list/communications-data-list.component';
+import { InternalPersonCommunicationsDataDetailsComponent } from '@pages/persons/internal-person/internal-person-details/communications-data-details/communications-data-details.component';
+import { InternalPersonCommunicationsDataListComponent } from '@pages/persons/internal-person/internal-person-details/communications-data-list/communications-data-list.component';
+
@NgModule({
imports: [
@@ -48,7 +56,6 @@
FiltersModule,
ReactiveFormsModule,
RouterModule,
- NgxDatatableModule,
NgrxFormsModule,
FormsModule,
StoreModule.forFeature('personsData', personsReducers),
@@ -62,7 +69,16 @@
],
declarations: [
ExternalPersonDetailsComponent,
- InternalPersonDetailsComponent
+ InternalPersonDetailsComponent,
+
+ ExternalPersonCommunicationsDataListComponent,
+ ExternalPersonCommunicationsDataDetailsComponent,
+ InternalPersonCommunicationsDataListComponent,
+ InternalPersonCommunicationsDataDetailsComponent,
+ ExternalPersonAddressListComponent,
+ InternalPersonAddressListComponent,
+ ExternalPersonAddressDetailsComponent,
+ InternalPersonAddressDetailsComponent
],
providers: [
PersonsService,
diff --git a/src/app/pages/persons/persons.routing.module.ts b/src/app/pages/persons/persons.routing.module.ts
index 60dc3f4..a5eb379 100644
--- a/src/app/pages/persons/persons.routing.module.ts
+++ b/src/app/pages/persons/persons.routing.module.ts
@@ -10,12 +10,12 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { ExternalPersonDetailsComponent } from '@app/pages/persons/external-person/external-person-details/external-person-details.component';
+import { ExternalPersonDetailsComponent } from '@pages/persons/external-person/external-person-details/external-person-details.component';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ExternalPersonResolver } from '@pages/persons/external-person/external-person.resolver';
-import { Globals } from '@app/shared/constants/globals';
-import { InternalPersonDetailsComponent } from '@app/pages/persons/internal-person/internal-person-details/internal-person-details.component';
+import { Globals } from '@shared/constants/globals';
+import { InternalPersonDetailsComponent } from '@pages/persons/internal-person/internal-person-details/internal-person-details.component';
import { InternalPersonResolver } from '@pages/persons/internal-person/internal-person.resolver';
const PATH = Globals.PATH;
diff --git a/src/app/pages/persons/persons.service.spec.ts b/src/app/pages/persons/persons.service.spec.ts
index 74caf9b..dcfd2ac 100644
--- a/src/app/pages/persons/persons.service.spec.ts
+++ b/src/app/pages/persons/persons.service.spec.ts
@@ -11,6 +11,7 @@
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
import { PersonsService } from '@pages/persons/persons.service';
+import { Address, CommunicationsData } from '@shared/models';
describe('PersonsService', () => {
@@ -30,4 +31,39 @@
expect(transContact.lastName).toBe(internalPerson.lastName);
});
+
+ it('should transform internalPersons', () => {
+ const internalPersons: any = {content: [{ lastName: 'Heysterkamp'}] };
+ const transContact = PersonsService.internalPersonsAdapter(internalPersons);
+
+ expect(transContact[0].lastName).toBe(internalPersons.content[0].lastName);
+ });
+
+ it('should transform externalPerson addresss details', () => {
+ const externalPersonAddress: any = { addressTypeType: 'Heysterkamp'};
+ const transContact = PersonsService.addressesDetailsAdapter(externalPersonAddress);
+
+ expect(transContact.addressTypeType).toBe(externalPersonAddress.addressTypeType);
+ });
+
+ it('should transform addressses list', () => {
+ const response = [new Address()];
+ response[0].addressTypeType = 'Herr';
+
+ expect(PersonsService.addressesAdapter(response)[0].addressTypeType).toBe('Herr');
+ });
+
+ it('should transform communicationa data details', () => {
+ const communicationsData: any = { communicationTypeId: 'Heysterkamp'};
+ const transContact = PersonsService.communicationsDataDetailsAdapter(communicationsData);
+
+ expect(transContact.communicationTypeId).toBe(communicationsData.communicationTypeId);
+ });
+
+ it('should transform communicationa data list', () => {
+ const response = [new CommunicationsData()];
+ response[0].communicationTypeId = 'Herr';
+
+ expect(PersonsService.communicationsDataAdapter(response)[0].communicationTypeId).toBe('Herr');
+ });
});
diff --git a/src/app/pages/persons/persons.service.ts b/src/app/pages/persons/persons.service.ts
index 0c79fe3..b6d30cd 100644
--- a/src/app/pages/persons/persons.service.ts
+++ b/src/app/pages/persons/persons.service.ts
@@ -1,17 +1,19 @@
- /********************************************************************************
- * Copyright (c) 2020 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- ********************************************************************************/
-import { ExternalPerson, InternalPerson } from '@app/shared/models';
+/********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/
+import { ExternalPerson, InternalPerson } from '@shared/models';
+import { Address, CommunicationsData } from '@shared/models';
import { Injectable } from '@angular/core';
+import { PageModel } from '@shared/models/page/page.model';
/**
* Used to retrieve persons
@@ -31,6 +33,24 @@
}
/**
+ * Transforms person's details addresses received from the API into instance of 'address[]'
+ *
+ * @param addresses
+ */
+ static addressesAdapter(addresses: any): Array<Address> {
+ return addresses.map(address => new Address(address));
+ }
+
+/**
+ * Transforms person's details addresses details recieved from the API into instance of 'address'
+ *
+ * @param response
+ */
+static addressesDetailsAdapter(address: Address): Address {
+ return new Address(address);
+}
+
+ /**
* Transforms internal person details recieved from the API into instance of 'InternalPerson'
*
* @param internalPerson
@@ -38,4 +58,31 @@
static internalPersonDetailsAdapter(internalPerson: InternalPerson): InternalPerson {
return new InternalPerson(internalPerson);
}
+
+ /**
+ * Transforms grid data received from the API into array of PageModel instances
+ *
+ * @param response
+ */
+ static internalPersonsAdapter(response: PageModel<InternalPerson>): Array<InternalPerson> {
+ return response != null ? response.content : null;
+ }
+
+ /**
+ * Transforms communications data received from the API into instance of 'CommunicationsData[]'
+ *
+ * @param communicationsData
+ */
+ static communicationsDataAdapter(communicationsData: any): Array<CommunicationsData> {
+ return communicationsData.map(communicationsData => new CommunicationsData(communicationsData));
+}
+
+/**
+ * Transforms communications data details recieved from the API into instance of 'CommunicationsData'
+ *
+ * @param response
+ */
+static communicationsDataDetailsAdapter(communicationsData: CommunicationsData): CommunicationsData {
+ return new CommunicationsData(communicationsData);
+}
}
diff --git a/src/app/shared/asyncServices/http/http.adapter.spec.ts b/src/app/shared/asyncServices/http/http.adapter.spec.ts
new file mode 100644
index 0000000..f2a301a
--- /dev/null
+++ b/src/app/shared/asyncServices/http/http.adapter.spec.ts
@@ -0,0 +1,53 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+/* import { async, TestBed } from '@angular/core/testing';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { ConfigService } from '@app/app-config.service';
+import { of } from 'rxjs/observable/of';
+import { HttpAdapter } from './http.adapter';
+import { Response } from '@angular/http';
+
+describe('HttpAdapter', () => {
+
+
+ let responseHandlerMock: any;
+ let httpMock: any;
+ let configserviceMock: any;
+
+ beforeEach(() => {
+
+
+ });
+
+ it('should call getBaseUrl', () => {
+ const spy1 = spyOn(configserviceMock, 'get').and.callThrough();
+ (httpService as any).getBaseUrl();
+ expect(spy1).toHaveBeenCalled();
+ });
+
+ it('should call getDefaultHeaders', () => {
+ const spy1 = spyOn((httpService as any), 'getDefaultHeaders').and.callThrough();
+ let response = (httpService as any).getDefaultHeaders();
+ expect(response).toBeNull();
+ expect(spy1).toHaveBeenCalled();
+ });
+
+ it('should call getDefaultHeaders', () => {
+ const observableRes = of( {} as any );
+ const spy1 = spyOn((httpService as any), 'responseInterceptor').and.callThrough();
+ const spy2 = spyOn(HttpAdapter, 'baseAdapter');
+ let observable = (httpService as any).responseInterceptor(observableRes);
+ expect(spy1).toHaveBeenCalled();
+ });
+
+}); */
diff --git a/src/app/shared/asyncServices/http/http.service.spec.ts b/src/app/shared/asyncServices/http/http.service.spec.ts
new file mode 100644
index 0000000..4ee0741
--- /dev/null
+++ b/src/app/shared/asyncServices/http/http.service.spec.ts
@@ -0,0 +1,56 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { HttpService } from '.';
+import { async, TestBed } from '@angular/core/testing';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { ConfigService } from '@app/app-config.service';
+import { of } from 'rxjs/observable/of';
+import { HttpAdapter } from './http.adapter';
+
+describe('HttpService', () => {
+
+
+ let responseHandlerMock: any;
+ let httpMock: any;
+ let configserviceMock: any;
+
+ let httpService: HttpService;
+ beforeEach(() => {
+
+ configserviceMock = { get:()=> ( { baseUrl: 'testBaseUrl'} ) } as any;
+ httpService = new HttpService(httpMock, configserviceMock, responseHandlerMock);
+
+ });
+
+ it('should call getBaseUrl', () => {
+ const spy1 = spyOn(configserviceMock, 'get').and.callThrough();
+ (httpService as any).getBaseUrl();
+ expect(spy1).toHaveBeenCalled();
+ });
+
+ it('should call getDefaultHeaders', () => {
+ const spy1 = spyOn((httpService as any), 'getDefaultHeaders').and.callThrough();
+ let response = (httpService as any).getDefaultHeaders();
+ expect(response).toBeNull();
+ expect(spy1).toHaveBeenCalled();
+ });
+
+ it('should call getDefaultHeaders', () => {
+ const observableRes = of( {} as any );
+ const spy1 = spyOn((httpService as any), 'responseInterceptor').and.callThrough();
+ const spy2 = spyOn(HttpAdapter, 'baseAdapter');
+ let observable = (httpService as any).responseInterceptor(observableRes);
+ expect(spy1).toHaveBeenCalled();
+ });
+
+});
diff --git a/src/app/shared/asyncServices/http/httpResponseHandler.service.ts b/src/app/shared/asyncServices/http/httpResponseHandler.service.ts
index f021a02..eb5da94 100644
--- a/src/app/shared/asyncServices/http/httpResponseHandler.service.ts
+++ b/src/app/shared/asyncServices/http/httpResponseHandler.service.ts
@@ -51,6 +51,10 @@
this.handleNotFound(response);
break;
+ case 409:
+ this.handleRefExists();
+ break;
+
case 500:
this.handleServerError();
break;
@@ -119,6 +123,16 @@
}
/**
+ * Shows notification errors when server response status is 409
+ */
+ private handleRefExists(): void {
+ const message: any = this.translateService.instant('ServerError409'),
+ title = this.translateService.instant('ErrorNotificationTitle');
+
+ this.showNotificationError(title, message);
+ }
+
+ /**
* Shows notification errors when server response status is 500
*/
private handleServerError(): void {
diff --git a/src/app/shared/asyncServices/http/utils.service.ts b/src/app/shared/asyncServices/http/utils.service.ts
index 0f41f52..39e8b03 100644
--- a/src/app/shared/asyncServices/http/utils.service.ts
+++ b/src/app/shared/asyncServices/http/utils.service.ts
@@ -107,7 +107,7 @@
if (value instanceof Object) {
value = JSON.stringify(value);
}
- search.set(encodeURIComponent(key), encodeURIComponent(value));
+ search.set(encodeURIComponent(key), (value));
});
}
diff --git a/src/app/shared/components/cell-renderer/bool-cell-renderer/bool-cell-renderer.component.html b/src/app/shared/components/cell-renderer/bool-cell-renderer/bool-cell-renderer.component.html
new file mode 100644
index 0000000..32f1e17
--- /dev/null
+++ b/src/app/shared/components/cell-renderer/bool-cell-renderer/bool-cell-renderer.component.html
@@ -0,0 +1 @@
+<input type="checkbox" [checked]="params.value" onclick="return false;">
diff --git a/src/app/shared/components/cell-renderer/bool-cell-renderer/bool-cell-renderer.component.scss b/src/app/shared/components/cell-renderer/bool-cell-renderer/bool-cell-renderer.component.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/app/shared/components/cell-renderer/bool-cell-renderer/bool-cell-renderer.component.scss
diff --git a/src/app/shared/components/cell-renderer/bool-cell-renderer/bool-cell-renderer.component.spec.ts b/src/app/shared/components/cell-renderer/bool-cell-renderer/bool-cell-renderer.component.spec.ts
new file mode 100644
index 0000000..88a7df6
--- /dev/null
+++ b/src/app/shared/components/cell-renderer/bool-cell-renderer/bool-cell-renderer.component.spec.ts
@@ -0,0 +1,26 @@
+import { BoolCellRendererComponent } from './bool-cell-renderer.component';
+import { ICellRendererParams } from 'ag-grid-community';
+
+describe('BoolCellRendererComponent', () => {
+ let component: BoolCellRendererComponent;
+
+ beforeEach(() => {
+ component = new BoolCellRendererComponent();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should return false when calling refesh', () => {
+ expect(component.refresh()).toBeFalsy();
+ });
+
+ it('should set params', () => {
+ let p: ICellRendererParams = {data: 'x'} as any;
+ component.agInit(p);
+ expect(component.params).toBe(p);
+ });
+
+});
+
diff --git a/src/app/shared/components/cell-renderer/bool-cell-renderer/bool-cell-renderer.component.ts b/src/app/shared/components/cell-renderer/bool-cell-renderer/bool-cell-renderer.component.ts
new file mode 100644
index 0000000..9b823a3
--- /dev/null
+++ b/src/app/shared/components/cell-renderer/bool-cell-renderer/bool-cell-renderer.component.ts
@@ -0,0 +1,21 @@
+import { Component } from '@angular/core';
+import { AgRendererComponent } from 'ag-grid-angular';
+import { ICellRendererParams } from 'ag-grid-community';
+
+@Component({
+ selector: 'app-bool-cell-renderer',
+ templateUrl: './bool-cell-renderer.component.html',
+ styleUrls: ['./bool-cell-renderer.component.scss']
+})
+export class BoolCellRendererComponent implements AgRendererComponent {
+
+ public params: ICellRendererParams;
+
+ public agInit(params: ICellRendererParams): void {
+ this.params = params;
+ }
+
+ public refresh(): boolean {
+ return false;
+ }
+}
diff --git a/src/app/shared/components/cell-renderer/contact-type-cell-renderer/contact-type-cell-renderer.component.spec.ts b/src/app/shared/components/cell-renderer/contact-type-cell-renderer/contact-type-cell-renderer.component.spec.ts
index 6c285d6..bc7abcf 100644
--- a/src/app/shared/components/cell-renderer/contact-type-cell-renderer/contact-type-cell-renderer.component.spec.ts
+++ b/src/app/shared/components/cell-renderer/contact-type-cell-renderer/contact-type-cell-renderer.component.spec.ts
@@ -13,7 +13,7 @@
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
-import { Globals } from '@app/shared/constants/globals';
+import { Globals } from '@shared/constants/globals';
import { ContactTypeCellRendererComponent } from './contact-type-cell-renderer.component';
describe('ContactTypeCellRendererComponent', () => {
diff --git a/src/app/shared/components/cell-renderer/contact-type-cell-renderer/contact-type-cell-renderer.component.ts b/src/app/shared/components/cell-renderer/contact-type-cell-renderer/contact-type-cell-renderer.component.ts
index ea11441..6b23437 100644
--- a/src/app/shared/components/cell-renderer/contact-type-cell-renderer/contact-type-cell-renderer.component.ts
+++ b/src/app/shared/components/cell-renderer/contact-type-cell-renderer/contact-type-cell-renderer.component.ts
@@ -11,7 +11,7 @@
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
import { Component, OnInit } from '@angular/core';
-import { Globals } from '@app/shared/constants/globals';
+import { Globals } from '@shared/constants/globals';
@Component({
selector: 'app-contact-type-cell-renderer',
@@ -20,12 +20,10 @@
})
export class ContactTypeCellRendererComponent {
- private params: any;
public contactType: string;
agInit(params: any): void {
- this.params = params;
switch(params.value) {
case Globals.CONTACT_TYPE_ID.EXTERNAL_PERSON:
this.contactType = Globals.CONTACT_TYPE.EXTERNAL_PERSON;
diff --git a/src/app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component.html b/src/app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component.html
index ee57bdd..46cbc8c 100644
--- a/src/app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component.html
+++ b/src/app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component.html
@@ -10,16 +10,13 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/ -->
-<div class="flex-container">
- <div>
- <button *ngIf="editIcon" (click)="clicked('edit')" class="tool-icon">
- <fa name="edit"></fa>
- </button>
- </div>
- <div>
- <button *ngIf="deleteIcon" (click)="clicked('delete')" class="tool-icon">
- <fa name="trash"></fa>
- </button>
- </div>
-</div>
+<button *ngIf="editIcon" (click)="clicked('edit')" class="tool-icon">
+ <fa name="edit"></fa>
+</button>
+<button *ngIf="readonlyIcon" (click)="clicked('readonly')" class="tool-icon">
+ <fa name="eye"></fa>
+</button>
+<button *ngIf="deleteIcon" (click)="clicked('delete')" class="tool-icon">
+ <fa name="trash"></fa>
+</button>
diff --git a/src/app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component.scss b/src/app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component.scss
index 9d1e44d..9804385 100644
--- a/src/app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component.scss
+++ b/src/app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component.scss
@@ -14,10 +14,4 @@
background-color: rgba(0, 0, 0, 0);
border-style: none;
font-size: 130%;
-}
-
-.flex-container {
- display: flex;
- flex-wrap: nowrap;
- justify-content: center;
-}
+}
\ No newline at end of file
diff --git a/src/app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component.spec.ts b/src/app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component.spec.ts
index 00014e8..8626b9e 100644
--- a/src/app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component.spec.ts
+++ b/src/app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component.spec.ts
@@ -1,3 +1,4 @@
+import { CommunicationType } from '@shared/models';
/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
@@ -10,9 +11,10 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { IconCellRendererComponent } from './icon-cell-renderer.component';
+import { IconCellRendererComponent } from '@shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component';
+import { ICellRendererParams } from 'ag-grid-community';
-describe('ToolCellRendererComponent', () => {
+describe('IconCellRendererComponent', () => {
let component: IconCellRendererComponent;
beforeEach(() => {
@@ -22,4 +24,58 @@
it('should create', () => {
expect(component).toBeTruthy();
});
+
+ it('should return false when calling refesh', () => {
+ expect(component.refresh()).toBeFalsy();
+ });
+
+ it('should set icon properties appropriate when calling agInit with default params + icons undefined', () => {
+ let p: ICellRendererParams = {data: {editable: true},
+ context: {icons: {}}
+ } as any;
+ component.agInit(p);
+ expect(component.editIcon).toBeFalsy();
+ expect(component.readonlyIcon).toBeFalsy();
+ expect(component.deleteIcon).toBeFalsy();
+ });
+
+ it('should set icon properties appropriate when calling agInit with default params + icons true', () => {
+ let p: ICellRendererParams = {data: {editable: true},
+ context: {icons: {edit: true, readonly: true, delete: true}}
+ } as any;
+ component.agInit(p);
+ expect(component.editIcon).toBeTruthy();
+ expect(component.readonlyIcon).toBeTruthy();
+ expect(component.deleteIcon).toBeTruthy();
+ });
+
+ it('should set icon properties appropriate when calling agInit with CommunicationType params + icons undefined', () => {
+ let p: ICellRendererParams = {data: new CommunicationType({editable: true}),
+ context: {icons: {}}
+ } as any;
+ component.agInit(p);
+ expect(component.editIcon).toBeFalsy();
+ expect(component.readonlyIcon).toBeFalsy();
+ expect(component.deleteIcon).toBeFalsy();
+ });
+
+ it('should set icon properties appropriate when calling agInit with CommunicationType params + editable true', () => {
+ let p: ICellRendererParams = {data: new CommunicationType({editable: true}),
+ context: {icons: {edit: true, readonly: true, delete: true}}
+ } as any;
+ component.agInit(p);
+ expect(component.editIcon).toBeTruthy();
+ expect(component.readonlyIcon).toBeFalsy();
+ expect(component.deleteIcon).toBeTruthy();
+ });
+
+ it('should set icon properties appropriate when calling agInit with CommunicationType params + editable false', () => {
+ let p: ICellRendererParams = {data: new CommunicationType({editable: false}),
+ context: {icons: {edit: true, readonly: true, delete: true}}
+ } as any;
+ component.agInit(p);
+ expect(component.editIcon).toBeFalsy();
+ expect(component.readonlyIcon).toBeTruthy();
+ });
+
});
diff --git a/src/app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component.ts b/src/app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component.ts
index 8c06671..29f4db1 100644
--- a/src/app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component.ts
+++ b/src/app/shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component.ts
@@ -1,3 +1,4 @@
+import { CommunicationType } from '@shared/models';
/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
@@ -12,6 +13,7 @@
********************************************************************************/
import { Component } from '@angular/core';
import { AgRendererComponent } from 'ag-grid-angular';
+import { ICellRendererParams } from 'ag-grid-community';
@Component({
selector: 'app-icon-cell-renderer',
@@ -22,15 +24,25 @@
public editIcon = null;
public deleteIcon = null;
+ public readonlyIcon = null;
+ public editFlag = null;
public params: any;
- public agInit(params: any): void {
+ public agInit(params: ICellRendererParams): void {
this.params = params;
+ this.editFlag = params.data['editable'];
if (params.context && params.context.icons) {
const contextIcons = params.context.icons;
- this.editIcon = !contextIcons || contextIcons.edit === undefined ? false : !!contextIcons.edit;
- this.deleteIcon = !contextIcons || contextIcons.delete === undefined ? false : !!contextIcons.delete;
+ if (params.data instanceof CommunicationType && this.editFlag !== null) { // communication types
+ this.editIcon = (!contextIcons || !this.editFlag) ? false : !!contextIcons.edit;
+ this.readonlyIcon = (!contextIcons || this.editFlag) ? false : !!contextIcons.readonly;
+ this.deleteIcon = (!contextIcons || !this.editFlag) ? false : !!contextIcons.delete;
+ } else { // default case
+ this.editIcon = !!contextIcons && !!contextIcons.edit;
+ this.readonlyIcon = !!contextIcons && !!contextIcons.readonly;
+ this.deleteIcon = !!contextIcons && !!contextIcons.delete;
+ }
}
}
diff --git a/src/app/shared/components/column-definitions/addresses-data-list-column-definition.ts b/src/app/shared/components/column-definitions/addresses-data-list-column-definition.ts
new file mode 100644
index 0000000..6bcda91
--- /dev/null
+++ b/src/app/shared/components/column-definitions/addresses-data-list-column-definition.ts
@@ -0,0 +1,86 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { IconCellRendererComponent } from '@shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component';
+import { BoolCellRendererComponent } from '@shared/components/cell-renderer/bool-cell-renderer/bool-cell-renderer.component';
+
+export const ADDRESS_LIST_COLDEF = [
+ {
+ field: 'addressTypeType',
+ colId: 'addressTypeType',
+ headerName: 'Address.AddressType',
+ sortable: true,
+ filter: true,
+ },
+ {
+ field: 'isMainAddress',
+ colId: 'isMainAddress',
+ headerName: 'Address.MainAddress',
+ sortable: true,
+ filter: true,
+ cellRendererFramework: BoolCellRendererComponent
+ },
+ {
+ field: 'postcode',
+ colId: 'postcode',
+ headerName: 'Address.Postcode',
+ sortable: true,
+ filter: true
+ },
+ {
+ field: 'community',
+ colId: 'community',
+ headerName: 'Address.Community',
+ sortable: true,
+ filter: true
+ },
+ {
+ field: 'communitySuffix',
+ colId: 'communitySuffix',
+ headerName: 'Address.CommunitySuffix',
+ sortable: true,
+ filter: true
+ },
+ {
+ field: 'street',
+ colId: 'street',
+ headerName: 'Address.Street',
+ sortable: true,
+ filter: true
+ },
+ {
+ field: 'housenumber',
+ colId: 'housenumber',
+ headerName: 'Address.Housenumber',
+ sortable: true,
+ filter: true
+ },
+ {
+ field: 'note',
+ colId: 'note',
+ headerName: 'Address.Note',
+ sortable: true,
+ filter: true
+ },
+ {
+ field: 'tools',
+ headerName: ' ',
+ pinned: 'right',
+ maxWidth: 100,
+ lockPosition: true,
+ sortable: false,
+ filter: false,
+ suppressMenu: true,
+ suppressSizeToFit: true,
+ cellRendererFramework: IconCellRendererComponent,
+ }
+];
diff --git a/src/app/shared/components/column-definitions/communications-data-list-column-definition.ts b/src/app/shared/components/column-definitions/communications-data-list-column-definition.ts
new file mode 100644
index 0000000..8f9c2b6
--- /dev/null
+++ b/src/app/shared/components/column-definitions/communications-data-list-column-definition.ts
@@ -0,0 +1,49 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { IconCellRendererComponent } from '@shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component';
+
+export const COMMUNICATIONS_DATA_LIST_COLDEF = [
+ {
+ field: 'communicationTypeType',
+ colId: 'communicationTypeType',
+ headerName: 'CommunicationsData.CommunicationType',
+ sortable: true,
+ filter: true,
+ },
+ {
+ field: 'communicationData',
+ colId: 'communicationData',
+ headerName: 'CommunicationsData.CommunicationData',
+ sortable: true,
+ filter: true
+ },
+ {
+ field: 'note',
+ colId: 'note',
+ headerName: 'CommunicationsData.Note',
+ sortable: true,
+ filter: true
+ },
+ {
+ field: 'tools',
+ headerName: ' ',
+ pinned: 'right',
+ maxWidth: 100,
+ lockPosition: true,
+ sortable: false,
+ filter: false,
+ suppressMenu: true,
+ suppressSizeToFit: true,
+ cellRendererFramework: IconCellRendererComponent,
+ }
+];
diff --git a/src/app/shared/components/expandable/expandable.component.html b/src/app/shared/components/expandable/expandable.component.html
new file mode 100644
index 0000000..10b141f
--- /dev/null
+++ b/src/app/shared/components/expandable/expandable.component.html
@@ -0,0 +1,29 @@
+<!-- /********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/ -->
+<div class="panel panel-default" style="width:100%;">
+ <div class="panel-heading">
+ <h4 class="panel-title">
+ <a data-toggle="collapse">
+ <i *ngIf="isExpandedStatus" class="fa fa-chevron-up" aria-hidden="true"></i>
+ <i *ngIf="!isExpandedStatus" class="fa fa-chevron-down" aria-hidden="true"></i>
+ </a>
+ <a data-toggle="collapse" href="#{{collapseId}}" (click)="isExpandedStatus = !isExpandedStatus">
+ <ng-content select="[header]"></ng-content>
+ </a>
+
+ </h4>
+ </div>
+ <div *ngIf="isExpandedStatus" id="{{collapseId}}" class="collapse5 panel-collapse collapse in" [ngClass]="{'in': !isStatusCollapsed }">
+ <ng-content class="bodyContent" select="[body]"></ng-content>
+ </div>
+</div>
\ No newline at end of file
diff --git a/src/app/shared/components/expandable/expandable.component.scss b/src/app/shared/components/expandable/expandable.component.scss
new file mode 100644
index 0000000..f177f7e
--- /dev/null
+++ b/src/app/shared/components/expandable/expandable.component.scss
@@ -0,0 +1,48 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+ .panel-default{
+ margin-top: 15px;
+ margin-bottom: 15px;
+}
+
+.panel-heading{
+ display: inline-flex;
+ width: 100%;
+ padding: 0px;
+ margin: 5px 5px 0px 0px;
+ color: #333;
+ border: 1px solid #ddd;
+ background-color: #f5f8fc;
+}
+
+h4{
+ font-size: 16px;
+}
+
+.panel-title{
+ width: 100%;
+ padding: 10px;
+ margin: 0px;
+}
+
+.fa-chevron-down:before, .fa-chevron-up:before{
+ margin: 5px;
+}
+
+.collapse5{
+ border: 1px solid #ddd;
+}
+
+.panel-body{
+ padding: 16px;
+}
\ No newline at end of file
diff --git a/src/app/shared/components/expandable/expandable.component.spec.ts b/src/app/shared/components/expandable/expandable.component.spec.ts
new file mode 100644
index 0000000..591a001
--- /dev/null
+++ b/src/app/shared/components/expandable/expandable.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ExpandableComponent } from './expandable.component';
+
+describe('ExpandableComponent', () => {
+ let component: ExpandableComponent;
+ let fixture: ComponentFixture<ExpandableComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ExpandableComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ExpandableComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/shared/components/expandable/expandable.component.ts b/src/app/shared/components/expandable/expandable.component.ts
new file mode 100644
index 0000000..68b03a2
--- /dev/null
+++ b/src/app/shared/components/expandable/expandable.component.ts
@@ -0,0 +1,25 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'app-expandable',
+ templateUrl: './expandable.component.html',
+ styleUrls: ['./expandable.component.scss']
+})
+
+export class ExpandableComponent implements OnInit {
+
+ static count : number = 0;
+
+ public isStatusCollapsed = true;
+ public isExpandedStatus = false;
+ public collapseId: string = null;
+
+ constructor() {
+ this.collapseId = 'collapse' + ExpandableComponent.count;
+ ExpandableComponent.count++;
+ }
+
+ ngOnInit() {
+ }
+
+}
diff --git a/src/app/shared/components/header/header.component.html b/src/app/shared/components/header/header.component.html
index 1bc1a6b..0b440f2 100644
--- a/src/app/shared/components/header/header.component.html
+++ b/src/app/shared/components/header/header.component.html
@@ -13,7 +13,7 @@
<nav class="navbar navbar-default navbar-fixed-top masthead overview-navbar" role="banner">
<div class="container-fluid">
<div class="navbar-header">
- <a href="#/overview" class="navbar-brand">
+ <a href="/overview" class="navbar-brand">
<span class="open">Open</span>
<span class="konsequenz">KONSEQUENZ</span>
</a>
@@ -33,8 +33,10 @@
<fa name="server"></fa>
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
- <a class="dropdown-item" routerLink="/admin/salutations">Anreden verwalten</a>
- <a class="dropdown-item" href="#">Kommunikationstypen verwalten (geplant)</a>
+ <a class="dropdown-item" routerLink="/admin/salutations">{{ 'Salutations.Link' | translate }}</a>
+ <a class="dropdown-item" routerLink="/admin/communication-types">{{ 'CommunicationTypes.Link' | translate }}</a>
+ <a class="dropdown-item" routerLink="/admin/person-types">{{ 'PersonTypes.Link' | translate }}</a>
+ <a class="dropdown-item" routerLink="/admin/address-types">{{ 'AddressTypes.Link' | translate }}</a>
</div>
</div>
<span class="divider"></span>
diff --git a/src/app/shared/components/index.ts b/src/app/shared/components/index.ts
index c43e961..733c441 100644
--- a/src/app/shared/components/index.ts
+++ b/src/app/shared/components/index.ts
@@ -1,3 +1,4 @@
+import { ExpandableComponent } from './expandable/expandable.component';
/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
@@ -11,6 +12,7 @@
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
import { SafetyQueryDialogComponent } from '@shared/components/dialogs/safety-query-dialog/safety-query-dialog.component';
+import { BoolCellRendererComponent } from '@shared/components/cell-renderer/bool-cell-renderer/bool-cell-renderer.component';
import { IconCellRendererComponent } from '@shared/components/cell-renderer/icon-cell-renderer/icon-cell-renderer.component';
import { ContactTypeCellRendererComponent } from '@shared/components/cell-renderer/contact-type-cell-renderer/contact-type-cell-renderer.component';
import { PaginatorComponent } from '@shared/components/paginator/paginator.component';
@@ -23,7 +25,6 @@
import { TranslateModule } from '@ngx-translate/core';
import { SpinnerComponent } from '@shared/components/spinner/spinner.component';
import { HeaderComponent } from '@shared/components/header/header.component';
-import { LanguageSelectorComponent } from '@shared/components/languageSelector/languageSelector.component';
import { PageNotFoundComponent } from '@shared/components/pageNotFound/pageNotFound.component';
import { LoadingPlaceholderComponent } from '@shared/components/loadingPlaceholder/loadingPlaceholder.component';
import { VersionInfo } from '@shared/components/version-info/version-info.component';
@@ -33,7 +34,6 @@
export const COMPONENTS = [
SpinnerComponent,
HeaderComponent,
- LanguageSelectorComponent,
PageNotFoundComponent,
LoadingPlaceholderComponent,
VersionInfo,
@@ -41,7 +41,10 @@
PaginatorComponent,
ContactTypeCellRendererComponent,
IconCellRendererComponent,
- SafetyQueryDialogComponent
+ SafetyQueryDialogComponent,
+ ExpandableComponent,
+ SafetyQueryDialogComponent,
+ BoolCellRendererComponent
];
@NgModule({
@@ -52,7 +55,8 @@
PaginatorComponent,
ContactTypeCellRendererComponent,
IconCellRendererComponent,
- SafetyQueryDialogComponent
+ SafetyQueryDialogComponent,
+ BoolCellRendererComponent
],
})
export class ComponentsModule {}
diff --git a/src/app/shared/components/languageSelector/languageSelector.component.html b/src/app/shared/components/languageSelector/languageSelector.component.html
deleted file mode 100644
index 9adcb06..0000000
--- a/src/app/shared/components/languageSelector/languageSelector.component.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- /********************************************************************************
-* Copyright (c) 2020 Contributors to the Eclipse Foundation
-*
-* See the NOTICE file(s) distributed with this work for additional
-* information regarding copyright ownership.
-*
-* This program and the accompanying materials are made available under the
-* terms of the Eclipse Public License v. 2.0 which is available at
-* http://www.eclipse.org/legal/epl-2.0.
-*
-* SPDX-License-Identifier: EPL-2.0
-********************************************************************************/ -->
-
-<!-- <button class="language-selector-anchor" [matMenuTriggerFor]="menu">{{ selectedLanguage }}</button> -->
-<!-- <mat-menu #menu="matMenu">
- <button class="dropdown-pane" mat-menu-item *ngFor="let lang of availableLanguages" (click)="selectLanguage(lang)">
- {{ lang.name }}
- </button>
-</mat-menu> -->
diff --git a/src/app/shared/components/languageSelector/languageSelector.component.scss b/src/app/shared/components/languageSelector/languageSelector.component.scss
deleted file mode 100644
index 7cf3704..0000000
--- a/src/app/shared/components/languageSelector/languageSelector.component.scss
+++ /dev/null
@@ -1,43 +0,0 @@
- /********************************************************************************
- * Copyright (c) 2020 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- ********************************************************************************/
- @import "variables.scss";
-
-:host {
- position: relative;
- float: left;
- width: 100%;
-}
-
-.language-selector-anchor {
- display: block;
- background-color: $color-white;
- color: $color-grey;
- padding: 0px 20px;
- outline: none;
- width: 65px;
- height: 40px;
- text-transform: uppercase;
- font-size: 16px;
- margin-bottom:0;
-
- &:hover,
- &:active,
- &:focus {
- text-decoration:none;
- background-color: rgb(220,220,220);
- }
-}
-
-.dropdown-pane {
- margin: 0px;
-}
diff --git a/src/app/shared/components/languageSelector/languageSelector.component.ts b/src/app/shared/components/languageSelector/languageSelector.component.ts
deleted file mode 100644
index a2bbeed..0000000
--- a/src/app/shared/components/languageSelector/languageSelector.component.ts
+++ /dev/null
@@ -1,53 +0,0 @@
- /********************************************************************************
- * Copyright (c) 2020 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- ********************************************************************************/
-import {
- Component,
- Output,
- Input,
- EventEmitter,
- ChangeDetectionStrategy,
- ElementRef,
- HostListener
-} from '@angular/core';
-
-@Component({
- selector: 'app-language-selector',
- templateUrl: './languageSelector.component.html',
- styleUrls: ['./languageSelector.component.scss'],
- changeDetection: ChangeDetectionStrategy.OnPush
-})
-export class LanguageSelectorComponent {
- @Input() selectedLanguage: string;
- @Input() availableLanguages: Array<any>;
- @Output() select: EventEmitter<any> = new EventEmitter();
-
- public show = false;
-
- constructor(private elementRef: ElementRef) {}
-
- @HostListener('click', ['$event'])
- public onDocumentClick(event): void {
- if (!this.elementRef.nativeElement.contains(event.target)) {
- this.show = false;
- }
- }
-
- public onToggle(): void {
- this.show = !this.show;
- }
-
- public selectLanguage(lang: any) {
- this.show = false;
- this.select.emit({ code: lang.code, culture: lang.culture });
- }
-}
diff --git a/src/app/shared/components/pageNotFound/pageNotFound.component.spec.ts b/src/app/shared/components/pageNotFound/pageNotFound.component.spec.ts
new file mode 100644
index 0000000..fad076b
--- /dev/null
+++ b/src/app/shared/components/pageNotFound/pageNotFound.component.spec.ts
@@ -0,0 +1,38 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { PageNotFoundComponent } from '@shared/components/pageNotFound/pageNotFound.component';
+
+describe('PageNotFoundComponent', () => {
+ let component: PageNotFoundComponent;
+ let location: any;
+
+ beforeEach(async(() => {
+ location = { back() {} } as any;
+ }));
+
+ beforeEach(() => {
+ component = new PageNotFoundComponent(location);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call back', () => {
+ const spy = spyOn(location, 'back');
+ component.goBack();
+ expect(spy).toHaveBeenCalled();
+ });
+
+});
diff --git a/src/app/shared/components/paginator/paginator.component.html b/src/app/shared/components/paginator/paginator.component.html
index 6c5184b..5052af4 100644
--- a/src/app/shared/components/paginator/paginator.component.html
+++ b/src/app/shared/components/paginator/paginator.component.html
@@ -10,10 +10,20 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/ -->
-<ul class="pagination justify-content-end">
- <li class="page-item" (click)="setPreviousPage()" [ngClass]="{ disabled: isFirstPage() }"><a class="page-link">Previous</a></li>
- <li class="page-item" [ngClass]="{ active: activeEventItem?.pageIndex === pageEventItem?.pageIndex }" *ngFor="let pageEventItem of pageEventItems">
- <a class="page-link" (click)="setSelectedPage(pageEventItem)">{{ pageEventItem.pageIndex }}</a>
+<ul class="pagination justify-content-end" *ngIf="isPagingActive">
+ <li class="page-item" (click)="setFirstPage()" [ngClass]="{ disabled: isFirstPage() }">
+ <a class="page-link">{{ 'Paginator.First' | translate }}</a>
</li>
- <li class="page-item" (click)="setNextPage()" [ngClass]="{ disabled: isLastPage() }"><a class="page-link">Next</a></li>
+ <li class="page-item" (click)="setPreviousPage()" [ngClass]="{ disabled: isFirstPage() }">
+ <a class="page-link">{{ 'Paginator.Previous' | translate }}</a>
+ </li>
+ <li *ngFor="let pageEventItem of pageEventItems" class="page-item" [ngClass]="{ active: activeEventItem?.pageIndex === pageEventItem?.pageIndex }">
+ <a class="page-link" (click)="setSelectedPage(pageEventItem)">{{ pageEventItem?.pageIndex }}</a>
+ </li>
+ <li class="page-item" (click)="setNextPage()" [ngClass]="{ disabled: isLastPage() }">
+ <a class="page-link">{{ 'Paginator.Next' | translate }}</a>
+ </li>
+ <li class="page-item" (click)="setLastPage()" [ngClass]="{ disabled: isLastPageLastIcon() }">
+ <a class="page-link">{{ 'Paginator.Last' | translate }}</a>
+ </li>
</ul>
diff --git a/src/app/shared/components/paginator/paginator.component.scss b/src/app/shared/components/paginator/paginator.component.scss
index 46dc5b1..a97c086 100644
--- a/src/app/shared/components/paginator/paginator.component.scss
+++ b/src/app/shared/components/paginator/paginator.component.scss
@@ -10,3 +10,10 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
+ .page-item,.page-link {
+ cursor: pointer;
+ }
+
+ .page-item:hover,.page-link:hover {
+ color: lightseagreen;
+}
diff --git a/src/app/shared/components/paginator/paginator.component.spec.ts b/src/app/shared/components/paginator/paginator.component.spec.ts
index d579fcb..626b959 100644
--- a/src/app/shared/components/paginator/paginator.component.spec.ts
+++ b/src/app/shared/components/paginator/paginator.component.spec.ts
@@ -10,26 +10,111 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-import { PaginatorComponent } from './paginator.component';
+import { async } from '@angular/core/testing';
+import { PaginatorComponent } from '@shared/components/paginator/paginator.component';
describe('PaginatorComponent', () => {
let component: PaginatorComponent;
- let fixture: ComponentFixture<PaginatorComponent>;
beforeEach(async(() => {
- TestBed.configureTestingModule({
- declarations: [PaginatorComponent],
- }).compileComponents();
}));
beforeEach(() => {
- fixture = TestBed.createComponent(PaginatorComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
+ component = new PaginatorComponent();
});
- it('should create', () => {
+ it('should create', () => {
expect(component).toBeTruthy();
+ expect(component).toBeDefined();
});
+
+ it('checks if setter and getter visibleItemsAmount is called and works', () => {
+ component.visibleItemsAmount = 10;
+ expect(component.visibleItemsAmount).toBe(10);
+ });
+
+ it('checks if setter and getter totalPages is called and works', () => {
+ component.totalPages = 15;
+ expect(component.totalPages).toBe(15);
+ });
+
+ it('return totalPages if totalPages are lesser then visibleItemsAmount', () => {
+ component.visibleItemsAmount = 15;
+ component.totalPages = 10;
+ expect(component.visibleItemsAmount).toBe(10);
+ });
+
+ it('check if isPagingActive works', () => {
+ component.totalPages = 1;
+ expect(component.isPagingActive).toBeFalsy();
+ component.totalPages = 2;
+ expect(component.isPagingActive).toBeTruthy();
+ });
+
+ it('check if setNextPage works', () => {
+ component.totalPages = 5;
+ expect(component.pageEventItems[component.currentPageIndex].pageIndex).toBe(1);
+ component.setNextPage();
+ expect(component.pageEventItems[component.currentPageIndex].pageIndex).toBe(2);
+ });
+
+ it('check if setPreviousPage works', () => {
+ component.totalPages = 5;
+ component.setNextPage();
+ component.setPreviousPage();
+ expect(component.pageEventItems[component.currentPageIndex].pageIndex).toBe(1);
+ });
+
+ it('check if setPreviousPage works on page 1', () => {
+ component.totalPages = 5;
+ expect(component.pageEventItems[component.currentPageIndex].pageIndex).toBe(1);
+ component.setPreviousPage();
+ expect(component.pageEventItems[component.currentPageIndex].pageIndex).toBe(1);
+ });
+
+ xit('check if setLastPage works', () => {
+ component.totalPages = 10;
+ component.setLastPage();
+ // console.log(component.currentPageIndex);
+ // console.log(component.pageEventItems[0]);
+ // console.log(component.pageEventItems[component.currentPageIndex].pageIndex);
+ expect(component.currentPageIndex).toBe(5);
+ });
+
+ it('check if setFirstPage works on first page', () => {
+ component.totalPages = 10;
+ component.setFirstPage();
+ expect(component.pageEventItems[component.currentPageIndex].pageIndex).toBe(1);
+ });
+
+ it('check if setFirstPage works on <> first page', () => {
+ component.totalPages = 10;
+ component.setNextPage();
+ component.setFirstPage();
+ expect(component.pageEventItems[component.currentPageIndex].pageIndex).toBe(1);
+ });
+
+ it('check if isLastPageLastIcon works', () => {
+ component.totalPages = 2;
+ component.setNextPage();
+ let isLastPageLastIcon = component.isLastPageLastIcon();
+ expect(isLastPageLastIcon).toBeTruthy();
+ });
+
+ xit('check if isLastPageLastIcon works', () => {
+ component.totalPages = 6;
+ component.setNextPage();
+ let isLastPageLastIcon = component.isLastPageLastIcon();
+ // console.log(component.pageEventItems[component.currentPageIndex].pageIndex);
+ expect(isLastPageLastIcon).toBeFalsy();
+ });
+
+
+
+
+
+
+
+
+
});
diff --git a/src/app/shared/components/paginator/paginator.component.ts b/src/app/shared/components/paginator/paginator.component.ts
index af34311..fa7c87d 100644
--- a/src/app/shared/components/paginator/paginator.component.ts
+++ b/src/app/shared/components/paginator/paginator.component.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -10,16 +10,19 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { PageEvent } from '@app/shared/models/PageEvent';
+import { PageEvent } from '@shared/models/PageEvent';
-import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
+import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-paginator',
templateUrl: './paginator.component.html',
styleUrls: ['./paginator.component.scss'],
})
-export class PaginatorComponent implements OnInit {
+export class PaginatorComponent {
+ private _totalPages: number;
+ private _visibleItemsAmount: number = 5;
+
@Input()
length: number;
@@ -27,10 +30,23 @@
pageSize: number;
@Input()
- totalPages: number;
+ public set visibleItemsAmount(visibleItemsAmount: number) {
+ this._visibleItemsAmount = visibleItemsAmount;
+ }
+
+ public get visibleItemsAmount(): number {
+ if (this.totalPages < this._visibleItemsAmount) {
+ return this.totalPages;
+ } else {
+ return this._visibleItemsAmount;
+ }
+ }
@Input()
- subscribe: number;
+ public set totalPages(totalPages: number) {
+ this._totalPages = totalPages;
+ this._init(1);
+ }
@Input()
hidePageSize: boolean;
@@ -38,29 +54,24 @@
@Output()
page: EventEmitter<PageEvent> = new EventEmitter();
- public pageEventItems: PageEvent[] = new Array<PageEvent>();
+ public get totalPages(): number {
+ return this._totalPages;
+ }
+
+ public pageEventItems: PageEvent[];
public activeEventItem: PageEvent;
public currentPageIndex: number = 0;
- /**
- * Creates an instance of PaginatorComponent.
- *
- * @author Martin Gardyan <martin.gardyan@pta.de>
- * @memberof PaginatorComponent
- */
- constructor() {}
- ngOnInit() {
- for (let index = 1; index <= this.totalPages; ++index) {
- this.pageEventItems.push({ pageIndex: index });
- }
- if (this.totalPages > 0) {
- this._setActivePage(this.pageEventItems[0]);
- }
+ public get isPagingActive(): boolean {
+ return this.totalPages > 1;
}
public setSelectedPage(pageEvent: PageEvent): void {
+ if (this._setPagesRange(pageEvent)) {
+ return;
+ }
this._setActivePage(pageEvent);
this.page.emit(pageEvent);
}
@@ -70,27 +81,75 @@
return;
}
const nextActiveItem = this.pageEventItems[this.currentPageIndex + 1];
+ if (this._setPagesRange(nextActiveItem)) {
+ return;
+ }
this.setSelectedPage(nextActiveItem);
}
+ public setLastPage(): void {
+ if (this.isLastPage()) {
+ return;
+ }
+ this._init(this._totalPages);
+ }
+
public setPreviousPage(): void {
if (this.isFirstPage()) {
return;
}
const previousActiveItem = this.pageEventItems[this.currentPageIndex - 1];
+ if (this._setPagesRange(previousActiveItem, false)) {
+ return;
+ }
this.setSelectedPage(previousActiveItem);
}
+ public setFirstPage(): void {
+ if (this.isFirstPage()) {
+ return;
+ }
+ this._init(1);
+ }
+
public isLastPage(): boolean {
- return this.currentPageIndex === this.pageEventItems.length - 1;
+ const activeItem = this.pageEventItems[this.currentPageIndex];
+ return !!activeItem && activeItem.pageIndex == this.totalPages;
+ }
+ public isLastPageLastIcon(): boolean {
+ const activeItem = this.pageEventItems[this.currentPageIndex];
+ return !!activeItem && activeItem.pageIndex >= this.totalPages - this.visibleItemsAmount;
}
public isFirstPage(): boolean {
- return this.currentPageIndex === 0;
+ const activeItem = this.pageEventItems[this.currentPageIndex];
+ return !!activeItem && activeItem.pageIndex === 1;
}
-
private _setActivePage(pageEvent: PageEvent): void {
this.currentPageIndex = this.pageEventItems.indexOf(pageEvent);
this.activeEventItem = pageEvent;
}
+
+ private _init(index: number, setNextRange: boolean = true) {
+ this.currentPageIndex = 0;
+ if (index === this.totalPages) {
+ index = index - (this.visibleItemsAmount - 1);
+ } else {
+ index = setNextRange ? index : index - (this.visibleItemsAmount - 2);
+ }
+
+ this.pageEventItems = new Array<PageEvent>();
+ for (let i = 0; this.visibleItemsAmount > i; i++) {
+ this.pageEventItems.push({ pageIndex: index++ });
+ }
+ this._setActivePage(this.pageEventItems[this.currentPageIndex]);
+ }
+
+ private _setPagesRange(pageEvent: PageEvent, nextPage: boolean = true) {
+ if (!pageEvent) {
+ const currentIndex = nextPage ? this.pageEventItems[this.currentPageIndex].pageIndex + 2 : this.pageEventItems[this.currentPageIndex].pageIndex - 2;
+ this._init(currentIndex, nextPage);
+ return true;
+ }
+ }
}
diff --git a/src/app/shared/components/version-info/version-info.component.spec.ts b/src/app/shared/components/version-info/version-info.component.spec.ts
index 8ac620c..16f93fe 100644
--- a/src/app/shared/components/version-info/version-info.component.spec.ts
+++ b/src/app/shared/components/version-info/version-info.component.spec.ts
@@ -10,68 +10,31 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
+import { async } from '@angular/core/testing';
+import { VersionInfo } from '@shared/components/version-info/version-info.component';
-// import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-// import { By } from '@angular/platform-browser';
-// import { DebugElement } from '@angular/core';
+describe('VersionInfo', () => {
+ let component: VersionInfo;
-// import { AbstractMockObservableService } from '../../testing/abstract-mock-observable.service';
-// import { VersionInfoComponent } from './version-info.component';
-// import { VersionInfo } from '../../model/version-info';
-// import { VersionInfoService } from '../../services/version-info.service';
-// import { Globals } from '../../common/globals';
+ beforeEach(async(() => {
+ }));
+ beforeEach(() => {
+ component = new VersionInfo();
+ });
-// describe('VersionInfoComponent', () => {
-// let component: VersionInfoComponent;
-// let fixture: ComponentFixture<VersionInfoComponent>;
-// let de: DebugElement; // the DebugElement with the welcome message
-// let el: HTMLElement; // the DOM element with the welcome message
-// class MockService extends AbstractMockObservableService {
-// loadBackendServerInfo() {
-// return this;
-// }
-// }
-// let mockService;
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
-// beforeEach(async(() => {
-// mockService = new MockService();
+ it('should call back', () => {
+ const currVersion: any = {
+ frontendVersion: '1.0',
+ backendVersion: '1.0',
+ dbVersion: '1.0',
+ };
+ (component as any).setVersionInfo(currVersion);
+ expect(component.currVersion).toBe(currVersion);
+ });
-// TestBed.configureTestingModule({
-// declarations: [VersionInfoComponent],
-// providers: [{ provide: VersionInfoService, useValue: mockService }],
-// })
-// .compileComponents();
-// }));
-
-// beforeEach(() => {
-// fixture = TestBed.createComponent(VersionInfoComponent);
-// component = fixture.componentInstance;
-
-// });
-
-// it('should show VersionString after loadBackendServerInfo', () => {
-// const vinfo = { frontendVersion: 'AVersion', backendVersion: '1.0', dbVersion: '2.0' };
-// mockService.content = vinfo;
-// de = fixture.debugElement.query(By.css('.version-info'));
-// el = de.nativeElement;
-
-// fixture.detectChanges();
-
-// const targetString = Globals.FRONTEND_VERSION + ' / ' + vinfo.backendVersion + ' / ' + vinfo.dbVersion;
-// expect(el.textContent).toContain(targetString);
-// });
-
-// it('should show ??? while not init', () => {
-// mockService.error = 'any Error';
-// de = fixture.debugElement.query(By.css('.version-info'));
-// el = de.nativeElement;
-
-// fixture.detectChanges();
-
-// const targetString = '? / ? / ?';
-// expect(el.textContent).toContain(targetString);
-// });
-
-
-// });
+});
diff --git a/src/app/shared/components/version-info/version-info.sandbox.spec.ts b/src/app/shared/components/version-info/version-info.sandbox.spec.ts
new file mode 100644
index 0000000..2b3b2a1
--- /dev/null
+++ b/src/app/shared/components/version-info/version-info.sandbox.spec.ts
@@ -0,0 +1,29 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { VersionInfoSandbox } from '@shared/components/version-info/version-info.sandbox';
+
+describe('VersionInfoSandbox', () => {
+ let component: VersionInfoSandbox;
+
+ beforeEach(async(() => {
+ }));
+
+ beforeEach(() => {
+ component = new VersionInfoSandbox();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/shared/constants/globals.ts b/src/app/shared/constants/globals.ts
index f7aceca..5efb084 100644
--- a/src/app/shared/constants/globals.ts
+++ b/src/app/shared/constants/globals.ts
@@ -34,4 +34,15 @@
static COMPANY = 'company';
static NEW = 'new';
}
+
+ static LOCALE_TEXT = {
+ contains: 'enthält',
+ notContains: 'enthält nicht',
+ startsWith: 'beginnt mit',
+ endsWith: 'endet mit',
+ andCondition: 'UND',
+ orCondition: 'ODER',
+ equals: 'ist gleich',
+ notEqual: 'ist nicht gleich',
+ }
}
diff --git a/src/app/shared/containers/card-layout/card-layout.component.scss b/src/app/shared/containers/card-layout/card-layout.component.scss
index b53f191..2bebdd9 100644
--- a/src/app/shared/containers/card-layout/card-layout.component.scss
+++ b/src/app/shared/containers/card-layout/card-layout.component.scss
@@ -11,12 +11,11 @@
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
.card {
- height: calc(100vh - 145px);
+ height: calc(100vh - 144px);
overflow: auto;
border: none;
}
.card-title {
font-size: 30px;
- margin-top: 16px;
margin-bottom: 8px;
}
diff --git a/src/app/shared/containers/layout/layout.container.ts b/src/app/shared/containers/layout/layout.container.ts
index e15163d..52fa09c 100644
--- a/src/app/shared/containers/layout/layout.container.ts
+++ b/src/app/shared/containers/layout/layout.container.ts
@@ -15,7 +15,7 @@
import { Subscription, Observable } from 'rxjs';
import { LayoutSandbox } from '@shared/containers/layout/layout.sandbox';
import { Store } from '@ngrx/store';
-import { User } from '@app/shared/models/user';
+import { User } from '@shared/models/user';
import * as store from '@shared/store';
@Component({
diff --git a/src/app/shared/containers/layout/layout.sandbox.spec.ts b/src/app/shared/containers/layout/layout.sandbox.spec.ts
index 299da03..e950833 100644
--- a/src/app/shared/containers/layout/layout.sandbox.spec.ts
+++ b/src/app/shared/containers/layout/layout.sandbox.spec.ts
@@ -19,19 +19,37 @@
describe('LayoutSandbox', () => {
let service: LayoutSandbox = {} as any;
- let translationService: TranslateService;
+ let translateService: TranslateService;
let appState: Store<store.State>;
let router: Router;
beforeEach(() => {
appState = { dispatch:()=> {}, pipe: () => of(true), select:()=> of(true) } as any;
router = { navigateByUrl() {} } as any;
+ translateService = { addLangs() {}, setDefaultLang() {}, use() {} } as any;
- service = new LayoutSandbox(appState, translationService, router);
+ service = new LayoutSandbox(appState, translateService, router);
});
it('should create LayoutSandbox service', () => {
expect(service).toBeTruthy();
expect(service).toBeDefined();
});
+
+ it('should call clearStorage and removeUser on logout', () => {
+ const spy1 = spyOn(service, 'clearStorage');
+ const spy2 = spyOn(service, 'removeUser');
+ service.logout();
+ expect(spy1).toHaveBeenCalled();
+ expect(spy2).toHaveBeenCalled();
+ });
+
+ it('should call dispatch and translateService.use on selectLanguage', () => {
+ const spy1 = spyOn(appState, 'dispatch');
+ const spy2 = spyOn(translateService, 'use');
+ service.selectLanguage({});
+ expect(spy1).toHaveBeenCalled();
+ expect(spy2).toHaveBeenCalled();
+ });
+
});
diff --git a/src/app/shared/directives/agGrid/auto-resize-columns.directive.ts b/src/app/shared/directives/agGrid/auto-resize-columns.directive.ts
index 16c7657..1589b5e 100644
--- a/src/app/shared/directives/agGrid/auto-resize-columns.directive.ts
+++ b/src/app/shared/directives/agGrid/auto-resize-columns.directive.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -55,22 +55,20 @@
allColumns = columnApi.getAllColumns() || allColumns;
allColumns = allColumns.filter((column: Column) => column.isVisible());
+ columnApi.sizeColumnsToFit(allColumns);
+ columnApi.autoSizeColumns(allColumns);
+ allOffsetColumns = allColumns.filter((column: Column) => !column.getMaxWidth() && column.isVisible());
- setTimeout(() => {
- columnApi.autoSizeColumns(allColumns);
- allOffsetColumns = allColumns.filter((column: Column) => !column.getMaxWidth() && column.isVisible());
-
- allColumns.forEach((column: Column) => {
- totalColumnsWidth += column.getActualWidth() + 1;
- });
- divider = allOffsetColumns.length || 1;
-
- if (totalColumnsWidth < this._gridWidth) {
- const columnOffset: number = (this._gridWidth - totalColumnsWidth) / divider;
- allOffsetColumns.forEach((column: Column) => {
- columnApi.setColumnWidth(column.getId(), column.getActualWidth() + columnOffset);
- });
- }
+ allColumns.forEach((column: Column) => {
+ totalColumnsWidth += column.getActualWidth();
});
+ divider = allOffsetColumns.length || 1;
+
+ if (totalColumnsWidth < this._gridWidth) {
+ const columnOffset: number = (this._gridWidth - 3 - totalColumnsWidth) / divider;
+ allOffsetColumns.forEach((column: Column) => {
+ columnApi.setColumnWidth(column.getId(), column.getActualWidth() + columnOffset);
+ });
+ }
}
}
diff --git a/src/app/shared/directives/agGrid/server-side.directive.ts b/src/app/shared/directives/agGrid/server-side.directive.ts
index 1db2c13..9087173 100644
--- a/src/app/shared/directives/agGrid/server-side.directive.ts
+++ b/src/app/shared/directives/agGrid/server-side.directive.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -11,7 +11,7 @@
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
import { PaginatorComponent } from '@shared/components/paginator/paginator.component';
-import { PageEvent } from '@app/shared/models/PageEvent';
+import { PageEvent } from '@shared/models/PageEvent';
import { PageModel } from './../../models/page/page.model';
import { AgGridAngular } from 'ag-grid-angular';
import { take, map } from 'rxjs/operators';
@@ -36,12 +36,28 @@
host: {},
})
export class ServerSideDirective implements OnInit {
+ private _queryParameter: any;
+
+ private _matPaginator: PaginatorComponent;
@Input()
public serverside: ServerSideModel;
+ @Input()
+ public set queryParameter(query: any) {
+ if (!!query) {
+ this.appState$.dispatch(
+ this.serverside.loadAction({
+ payload: {
+ queryParameter: query,
+ pageSize: this.serverside.pageSize,
+ } as PageRequestInterface,
+ })
+ );
+ }
+ this._queryParameter = query;
+ }
+
/**
- * Creates an instance of ServerSideDirective.
- *
* @author Martin Gardyan <martin.gardyan@pta.de>
* @param {Store<store.State>} appState$
* @param {ComponentFactoryResolver} _resolver
@@ -59,8 +75,6 @@
) {}
/**
- * Initiates component
- *
* @author Martin Gardyan <martin.gardyan@pta.de>
* @memberof ServerSideDirective
*/
@@ -68,27 +82,37 @@
this._actionsSubject
.pipe(
ofType(this.serverside.successAction.type),
- take(1),
map(item => item.payload)
)
- .subscribe((pagedItem:PageModel<any>) => {
- const paginator: ComponentFactory<PaginatorComponent> = this._resolver.resolveComponentFactory(PaginatorComponent);
- const matPaginator: PaginatorComponent = this._viewContainerRef.createComponent(paginator).instance;
- matPaginator.length = pagedItem.totalElements;
- matPaginator.totalPages = pagedItem.totalPages || 1;
- matPaginator.pageSize = pagedItem.pageable.pageSize || 1;
- matPaginator.hidePageSize = false;
- matPaginator.page.subscribe((event: PageEvent) => {
- this._retrievePage(event);
+ .subscribe((pagedItem: PageModel<any>) => {
+ if (!this._matPaginator) {
+ const paginator: ComponentFactory<PaginatorComponent> = this._resolver.resolveComponentFactory(PaginatorComponent);
+ this._matPaginator = this._viewContainerRef.createComponent(paginator).instance;
+
+ }
+ if( this._matPaginator.totalPages !== pagedItem.totalPages){
+ this._matPaginator.totalPages = pagedItem.totalPages;
+ }
+
+ this._matPaginator.length = pagedItem.totalElements;
+ this._matPaginator.pageSize = pagedItem.pageable.pageSize || 1;
+ this._matPaginator.hidePageSize = false;
+
+ this._matPaginator.page.subscribe((selectedpage: PageEvent) => {
+ this._retrievePage(selectedpage);
});
+
+ if (!!this._agGrid.api) {
+ this._agGrid.api.setRowData(pagedItem.content);
+ } else {
+ this._agGrid.rowData = pagedItem.content;
+ }
});
this._retrievePage();
}
/**
- * Retrieves paged data
- *
* @author Martin Gardyan <martin.gardyan@pta.de>
* @private
* @param {PageEvent} [event]
@@ -100,17 +124,9 @@
payload: {
pageNumber: (event && event.pageIndex) || 0,
pageSize: this.serverside.pageSize,
+ queryParameter: this._queryParameter,
} as PageRequestInterface,
})
);
- this._actionsSubject
- .pipe(
- ofType(this.serverside.successAction.type),
- take(1),
- map(item => item.payload)
- )
- .subscribe(pagedItem => {
- this._agGrid.api.setRowData(pagedItem.content);
- });
}
}
diff --git a/src/app/shared/filters/ag-grid/set-filter/set-filter.component.spec.ts b/src/app/shared/filters/ag-grid/set-filter/set-filter.component.spec.ts
index 5f6e61a..513822b 100644
--- a/src/app/shared/filters/ag-grid/set-filter/set-filter.component.spec.ts
+++ b/src/app/shared/filters/ag-grid/set-filter/set-filter.component.spec.ts
@@ -10,28 +10,57 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
- // import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+ import { SetFilterComponent } from './set-filter.component';
+import { SystemIntegratorERPPage } from '../../../../../../e2e/app.po';
-// import { SetFilterComponent } from './set-filter.component';
+ describe('SetFilterComponent', () => {
+ let component: SetFilterComponent;
-// describe('SetFilterComponent', () => {
-// let component: SetFilterComponent;
-// let fixture: ComponentFixture<SetFilterComponent>;
-// beforeEach(async(() => {
-// TestBed.configureTestingModule({
-// declarations: [ SetFilterComponent ]
-// })
-// .compileComponents();
-// }));
+ beforeEach(() => {
+ component = new SetFilterComponent();
-// beforeEach(() => {
-// fixture = TestBed.createComponent(SetFilterComponent);
-// component = fixture.componentInstance;
-// fixture.detectChanges();
-// });
+ });
-// it('should create', () => {
-// expect(component).toBeTruthy();
-// });
-// });
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should filterCheckboxList with setItems', () => {
+ component.setItems = ['AAA', 'BBB'];
+ const compAnonym = component as any;
+ compAnonym._params = { filterChangedCallback() { }};
+ component.filterCheckboxList('X');
+
+ expect(compAnonym.filtererdItems[0]).toBe('AAA');
+
+ component.setItems = ['AAA', 'BBB'];
+ component.filterCheckboxList('0 b');
+ expect(compAnonym.filtererdItems[0]).toBe('AAA');
+
+ });
+
+ it('should return isFilterActive', () => {
+ component.selectAllChecked = false;
+ expect(component.isFilterActive()).toBeTruthy();
+ });
+
+ it('should return model', () => {
+ component.setItems = 666;
+ expect(component.getModel().values).toBe( 666 );
+ });
+
+ it('should set model 1', () => {
+ component.setItems = 666;
+ component.setModel(null);
+ expect(component.setItems).toEqual( [] );
+ });
+
+ it('should set model 2', () => {
+ component.setItems = 666;
+ component.setModel( { values: 333 });
+ expect(component.setItems).toEqual( 333 );
+ });
+
+ });
diff --git a/src/app/shared/guards/auth.guard.spec.ts b/src/app/shared/guards/auth.guard.spec.ts
new file mode 100644
index 0000000..0a461f2
--- /dev/null
+++ b/src/app/shared/guards/auth.guard.spec.ts
@@ -0,0 +1,40 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { AuthGuard } from '@shared/guards/auth.guard';
+
+describe('AuthGuard', () => {
+ let component: AuthGuard;
+ let router: any;
+
+ beforeEach(() => {
+
+ router = {
+ navigate() {},
+ } as any;
+
+ component = new AuthGuard(router);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call checkLogin if call canActivate', () => {
+ const route = {} as any;
+ const state = {url: 'test.url'} as any;
+ const spy = spyOn(component, 'checkLogin');
+ component.canActivate(route, state);
+
+ expect(spy).toHaveBeenCalledWith(state.url);
+ });
+});
diff --git a/src/app/shared/models/address/address.model.ts b/src/app/shared/models/address/address.model.ts
new file mode 100644
index 0000000..dd97d67
--- /dev/null
+++ b/src/app/shared/models/address/address.model.ts
@@ -0,0 +1,40 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+export class Address {
+
+ public id: string = null;
+ public contactId: string = null;
+ public isMainAddress: boolean = null;
+ public addressTypeId: string = null;
+ public addressTypeType: string = null;
+ public addressTypeDescription: string = null;
+ public postcode: string = null;
+ public community: string = null;
+ public communitySuffix: string = null;
+ public street: string = null;
+ public housenumber: string = null;
+ public wgs84Zone: string = null;
+ public latitude: string = null;
+ public longitude: string = null;
+ public urlMap: string = null;
+ public note: string = null;
+
+
+ public constructor(data: any = null) {
+ Object.keys(data || {})
+ .filter(property => this.hasOwnProperty(property))
+ .forEach(property => (this[property] = data[property]));
+ }
+
+ }
+
\ No newline at end of file
diff --git a/src/app/shared/models/admin/address-type.model.ts b/src/app/shared/models/admin/address-type.model.ts
new file mode 100644
index 0000000..751e4f0
--- /dev/null
+++ b/src/app/shared/models/admin/address-type.model.ts
@@ -0,0 +1,24 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+export class AddressType {
+
+ public id: string = null;
+ public type: string = null;
+ public description: string = null;
+
+ public constructor(data: any = null) {
+ Object.keys(data || {})
+ .filter(property => this.hasOwnProperty(property))
+ .forEach(property => (this[property] = data[property]));
+ }
+}
diff --git a/src/app/shared/models/admin/communication-type.model.ts b/src/app/shared/models/admin/communication-type.model.ts
new file mode 100644
index 0000000..b5f46aa
--- /dev/null
+++ b/src/app/shared/models/admin/communication-type.model.ts
@@ -0,0 +1,27 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+export class CommunicationType {
+
+ public id: string = null;
+ public type: string = null;
+ public description: string = null;
+ public editable: boolean = null;
+ public mappingLdap: boolean = null;
+ public isDisabled: boolean = null;
+
+ public constructor(data: any = null) {
+ Object.keys(data || {})
+ .filter(property => this.hasOwnProperty(property))
+ .forEach(property => (this[property] = data[property]));
+ }
+}
diff --git a/src/app/shared/models/admin/person-type.model.ts b/src/app/shared/models/admin/person-type.model.ts
new file mode 100644
index 0000000..d9dbf1d
--- /dev/null
+++ b/src/app/shared/models/admin/person-type.model.ts
@@ -0,0 +1,24 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+export class PersonType {
+
+ public id: string = null;
+ public type: string = null;
+ public description: string = null;
+
+ public constructor(data: any = null) {
+ Object.keys(data || {})
+ .filter(property => this.hasOwnProperty(property))
+ .forEach(property => (this[property] = data[property]));
+ }
+}
diff --git a/src/app/shared/models/salutation.model.ts b/src/app/shared/models/admin/salutation.model.ts
similarity index 100%
rename from src/app/shared/models/salutation.model.ts
rename to src/app/shared/models/admin/salutation.model.ts
diff --git a/src/app/shared/models/communication/communications-data.model.ts b/src/app/shared/models/communication/communications-data.model.ts
new file mode 100644
index 0000000..464be3e
--- /dev/null
+++ b/src/app/shared/models/communication/communications-data.model.ts
@@ -0,0 +1,29 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+export class CommunicationsData {
+
+ public id: string = null;
+ public contactId: string = null;
+ public communicationData: string = null;
+ public communicationTypeDescription: string = null;
+ public communicationTypeId: string = null;
+ public communicationTypeType: string = null;
+ public note: string = null;
+
+ public constructor(data: any = null) {
+ Object.keys(data || {})
+ .filter(property => this.hasOwnProperty(property))
+ .forEach(property => (this[property] = data[property]));
+ }
+
+ }
diff --git a/src/app/shared/models/company/company.model.ts b/src/app/shared/models/company/company.model.ts
new file mode 100644
index 0000000..a5f4700
--- /dev/null
+++ b/src/app/shared/models/company/company.model.ts
@@ -0,0 +1,29 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+export class Company {
+
+ public id: string = null;
+ public contactId: string = null;
+ public contactType: string = null;
+ public companyName: string = null;
+ public companyType: string = null;
+ public hrNumber: string = null;
+ public contactNote: string = null;
+
+ public constructor(data: any = null) {
+ Object.keys(data || {})
+ .filter(property => this.hasOwnProperty(property))
+ .forEach(property => (this[property] = data[property]));
+ }
+
+}
diff --git a/src/app/shared/models/contact.model.ts b/src/app/shared/models/contact.model.ts
index af34289..203ccc9 100644
--- a/src/app/shared/models/contact.model.ts
+++ b/src/app/shared/models/contact.model.ts
@@ -16,6 +16,7 @@
public name: string = null;
public firstName: string = null;
public lastName: string = null;
+ public email: string = null;
public contactType: string = null;
public note: string = null;
public street: string = null;
@@ -26,6 +27,7 @@
public fkContactId: number = null;
public fkSalutationId: number = null;
public salutationType: string = null;
+ public department: string = null;
public constructor(data: any = null) {
Object.keys(data || {})
diff --git a/src/app/shared/models/index.ts b/src/app/shared/models/index.ts
index 24bf51e..27c1590 100644
--- a/src/app/shared/models/index.ts
+++ b/src/app/shared/models/index.ts
@@ -14,4 +14,10 @@
export * from './contact.model';
export * from './persons/external-person.model';
export * from './persons/internal-person.model';
-export * from './salutation.model';
+export * from './company/company.model';
+export * from './admin/salutation.model';
+export * from './admin/communication-type.model';
+export * from './admin/person-type.model';
+export * from './admin/address-type.model';
+export * from './address/address.model';
+export * from './communication/communications-data.model';
diff --git a/src/app/shared/models/modifiedContacts.model.ts b/src/app/shared/models/modifiedContacts.model.ts
new file mode 100644
index 0000000..886e071
--- /dev/null
+++ b/src/app/shared/models/modifiedContacts.model.ts
@@ -0,0 +1,15 @@
+import { Contact } from '@shared/models';
+
+export class ModifiedContacts {
+
+ public searchText: string = null;
+ public contactTypeId: string = '';
+ public sort: string = null;
+
+ public constructor(data: any = null) {
+ Object.keys(data || {})
+ .filter(property => this.hasOwnProperty(property))
+ .forEach(property => (this[property] = data[property]));
+ }
+ }
+
\ No newline at end of file
diff --git a/src/app/shared/models/page/page-request.interface.ts b/src/app/shared/models/page/page-request.interface.ts
index 98c4896..26938d4 100644
--- a/src/app/shared/models/page/page-request.interface.ts
+++ b/src/app/shared/models/page/page-request.interface.ts
@@ -11,33 +11,42 @@
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
export interface PageRequestInterface {
- /**
- * The index number of the page requested.
- *
- * @type {number}
- * @memberof PageRequestInterface
- */
- pageNumber?: number;
- /**
- * The number of items present on a single page.
- *
- * @type {number}
- * @memberof PageRequestInterface
- */
- pageSize?: number;
- /**
- * The number of items to skip when determining the item that the first page starts with.
- *
- * @type {number}
- * @memberof PageRequestInterface
- */
- offset?: number;
- /**
- * Should the result be paged?
- *
- * @type {boolean}
- * @memberof PageRequestInterface
- */
- paged?: boolean;
- }
+ /**
+ * Used to define any query paramter
+ *
+ * @type {*}
+ * @memberof PageRequestInterface
+ */
+ queryParameter?: any;
+
+ /**
+ * The index number of the page requested.
+ *
+ * @type {number}
+ * @memberof PageRequestInterface
+ */
+ pageNumber?: number;
+ /**
+ * The number of items present on a single page.
+ *
+ * @type {number}
+ * @memberof PageRequestInterface
+ */
+ pageSize?: number;
+ /**
+ * The number of items to skip when determining the item that the first page starts with.
+ *
+ * @type {number}
+ * @memberof PageRequestInterface
+ */
+ offset?: number;
+
+ /**
+ * Should the result be paged?
+ *
+ * @type {boolean}
+ * @memberof PageRequestInterface
+ */
+ paged?: boolean;
+}
\ No newline at end of file
diff --git a/src/app/shared/models/persons/internal-person-arguments.interface.ts b/src/app/shared/models/persons/internal-person-arguments.interface.ts
new file mode 100644
index 0000000..9f93370
--- /dev/null
+++ b/src/app/shared/models/persons/internal-person-arguments.interface.ts
@@ -0,0 +1,19 @@
+
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { PageRequestInterface } from '@shared/models/page/page-request.interface';
+
+export interface InternalPersonInterface extends PageRequestInterface {
+ uid?: string;
+ userRef?: string;
+}
diff --git a/src/app/shared/models/server-side.model.ts b/src/app/shared/models/server-side.model.ts
index 66b504a..4085140 100644
--- a/src/app/shared/models/server-side.model.ts
+++ b/src/app/shared/models/server-side.model.ts
@@ -16,8 +16,7 @@
loadAction: any;
successAction?: any;
pageSize?: number;
- /**
- *
- */
+ filter?:any;
+
constructor() {}
}
diff --git a/src/app/shared/sandbox/base.sandbox.ts b/src/app/shared/sandbox/base.sandbox.ts
index c2c5c5e..93ff99c 100644
--- a/src/app/shared/sandbox/base.sandbox.ts
+++ b/src/app/shared/sandbox/base.sandbox.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -14,11 +14,10 @@
import { Observable, Subject } from 'rxjs';
import * as store from '@shared/store';
import { localeDateString } from '@shared/utility';
-import { OnDestroy } from '@angular/core';
import * as settingsActions from '@shared/store/actions/settings.action';
-export abstract class BaseSandbox implements OnDestroy {
+export abstract class BaseSandbox {
protected _endSubscriptions$: Subject<boolean> = new Subject();
public culture$: Observable<string> = this.appState$.select(store.getSelectedCulture);
@@ -27,7 +26,7 @@
constructor(protected appState$: Store<store.State>) {}
- public ngOnDestroy() {
+ public endSubscriptions(): void {
this._endSubscriptions$.next(true);
}
diff --git a/src/app/shared/store/actions/admin/address-types.action.ts b/src/app/shared/store/actions/admin/address-types.action.ts
new file mode 100644
index 0000000..23c06a5
--- /dev/null
+++ b/src/app/shared/store/actions/admin/address-types.action.ts
@@ -0,0 +1,68 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { createAction, props } from '@ngrx/store';
+import { AddressType } from '@shared/models';
+
+export interface ILoadAddressTypesSuccess {
+ payload: Array<AddressType>;
+}
+
+export interface ILoadAddressTypesFail {
+ payload: string;
+}
+
+export const loadAddressTypes = createAction('[AddressTypes] Load');
+export const loadAddressTypesSuccess = createAction(
+ '[AddressTypes] Load Success',
+ props<ILoadAddressTypesSuccess>());
+export const loadAddressTypesFail = createAction(
+ '[AddressTypes] Load Fail',
+ props<ILoadAddressTypesFail>());
+
+export const loadAddressType = createAction(
+ '[AddressType Details] Load',
+ props<{ payload: string }>()
+);
+export const loadAddressTypeSuccess = createAction(
+ '[AddressType Details] Load Success',
+ props<{ payload: AddressType }>()
+);
+export const loadAddressTypeFail = createAction(
+ '[AddressType Details] Load Fail',
+ props<{ payload: string }>()
+);
+
+export const saveAddressType = createAction(
+ '[AddressType Details] Save',
+ props<{ payload: AddressType }>()
+);
+export const saveAddressTypeSuccess = createAction(
+ '[AddressType Details] Save Success',
+ props<{ payload: AddressType }>()
+);
+export const saveAddressTypeFail = createAction(
+ '[AddressType Details] Save Fail',
+ props<{ payload: string }>()
+);
+
+export const deleteAddressType = createAction(
+ '[AddressType Details] Delete',
+ props<{ payload: string }>()
+);
+export const deleteAddressTypeSuccess = createAction(
+ '[AddressType Details] Delete Success'
+);
+export const deleteAddressTypeFail = createAction(
+ '[AddressType Details] Delete Fail',
+ props<{ payload: string }>()
+);
diff --git a/src/app/shared/store/actions/admin/communication-types.action.ts b/src/app/shared/store/actions/admin/communication-types.action.ts
new file mode 100644
index 0000000..3c7c9a1
--- /dev/null
+++ b/src/app/shared/store/actions/admin/communication-types.action.ts
@@ -0,0 +1,67 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { createAction, props } from '@ngrx/store';
+import { CommunicationType } from '@shared/models';
+
+export interface ILoadCommunicationTypesSuccess {
+ payload: Array<CommunicationType>;
+}
+export interface ILoadCommunicationTypesFail {
+ payload: string;
+}
+
+export const loadCommunicationTypes = createAction('[CommunicationTypes] Load');
+export const loadCommunicationTypesSuccess = createAction(
+ '[CommunicationTypes] Load Success',
+ props<ILoadCommunicationTypesSuccess>());
+export const loadCommunicationTypesFail = createAction(
+ '[CommunicationTypes] Load Fail',
+ props<ILoadCommunicationTypesFail>());
+
+export const loadCommunicationType = createAction(
+ '[CommunicationType] Load',
+ props<{ payload: string }>()
+);
+export const loadCommunicationTypeSuccess = createAction(
+ '[CommunicationType] Load Success',
+ props<{ payload: CommunicationType }>()
+);
+export const loadCommunicationTypeFail = createAction(
+ '[CommunicationType] Load Fail',
+ props<{ payload: string }>()
+);
+
+export const saveCommunicationType = createAction(
+ '[CommunicationType Details] Save',
+ props<{ payload: CommunicationType }>()
+);
+export const saveCommunicationTypeSuccess = createAction(
+ '[CommunicationType Details] Save Success',
+ props<{ payload: CommunicationType }>()
+);
+export const saveCommunicationTypeFail = createAction(
+ '[CommunicationType Details] Save Fail',
+ props<{ payload: string }>()
+);
+
+export const deleteCommunicationType = createAction(
+ '[CommunicationType Details] Delete',
+ props<{ payload: string }>()
+);
+export const deleteCommunicationTypeSuccess = createAction(
+ '[CommunicationType Details] Delete Success'
+);
+export const deleteCommunicationTypeFail = createAction(
+ '[CommunicationType Details] Delete Fail',
+ props<{ payload: string }>()
+);
diff --git a/src/app/shared/store/actions/admin/person-types.action.ts b/src/app/shared/store/actions/admin/person-types.action.ts
new file mode 100644
index 0000000..5845d0c
--- /dev/null
+++ b/src/app/shared/store/actions/admin/person-types.action.ts
@@ -0,0 +1,67 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { createAction, props } from '@ngrx/store';
+import { PersonType } from '@shared/models';
+
+export interface ILoadPersonTypesSuccess {
+ payload: Array< PersonType>;
+}
+export interface ILoadPersonTypesFail {
+ payload: string;
+}
+
+export const loadPersonTypes = createAction('[PersonTypes] Load');
+export const loadPersonTypesSuccess = createAction(
+ '[PersonTypes] Load Success',
+ props<ILoadPersonTypesSuccess>());
+export const loadPersonTypesFail = createAction(
+ '[PersonTypes] Load Fail',
+ props<ILoadPersonTypesFail>());
+
+export const loadPersonType = createAction(
+ '[PersonType Details] Load',
+ props<{ payload: string }>()
+);
+export const loadPersonTypeSuccess = createAction(
+ '[PersonType Details] Load Success',
+ props<{ payload: PersonType }>()
+);
+export const loadPersonTypeFail = createAction(
+ '[PersonType Details] Load Fail',
+ props<{ payload: string }>()
+);
+
+export const savePersonType = createAction(
+ '[PersonType Details] Save',
+ props<{ payload: PersonType }>()
+);
+export const savePersonTypeSuccess = createAction(
+ '[PersonType Details] Save Success',
+ props<{ payload: PersonType }>()
+);
+export const savePersonTypeFail = createAction(
+ '[PersonType Details] Save Fail',
+ props<{ payload: string }>()
+);
+
+export const deletePersonType = createAction(
+ '[PersonType Details] Delete',
+ props<{ payload: string }>()
+);
+export const deletePersonTypeSuccess = createAction(
+ '[PersonType Details] Delete Success'
+);
+export const deletePersonTypeFail = createAction(
+ '[PersonType Details] Delete Fail',
+ props<{ payload: string }>()
+);
diff --git a/src/app/shared/store/actions/salutations.action.ts b/src/app/shared/store/actions/admin/salutations.action.ts
similarity index 82%
rename from src/app/shared/store/actions/salutations.action.ts
rename to src/app/shared/store/actions/admin/salutations.action.ts
index 694eeee..3f1d28c 100644
--- a/src/app/shared/store/actions/salutations.action.ts
+++ b/src/app/shared/store/actions/admin/salutations.action.ts
@@ -16,14 +16,10 @@
export interface ILoadSalutationsSuccess {
payload: Array<Salutation>;
}
-
export interface ILoadSalutationsFail {
payload: string;
}
-/**
- * Loads salutation list
- */
export const loadSalutations = createAction('[Salutations] Load');
export const loadSalutationsSuccess = createAction(
'[Salutations] Load Success',
@@ -32,9 +28,6 @@
'[Salutations] Load Fail',
props<ILoadSalutationsFail>());
-/**
- * Loads single salutation
- */
export const loadSalutation = createAction(
'[Salutation Details] Load',
props<{ payload: string }>()
@@ -47,24 +40,20 @@
'[Salutation Details] Load Fail',
props<{ payload: string }>()
);
-/**
- * Save edited salutation
- */
-export const persistSalutation = createAction(
- '[Salutation Details] Persist',
+
+export const saveSalutation = createAction(
+ '[Salutation Details] Save',
props<{ payload: Salutation }>()
);
-export const persistSalutationSuccess = createAction(
- '[Salutation Details] Persist Success',
+export const saveSalutationSuccess = createAction(
+ '[Salutation Details] Save Success',
props<{ payload: Salutation }>()
);
-export const persistSalutationFail = createAction(
- '[Salutation Details] Persist Fail',
+export const saveSalutationFail = createAction(
+ '[Salutation Details] Save Fail',
props<{ payload: string }>()
);
-/**
- * Delete salutation
- */
+
export const deleteSalutation = createAction(
'[Salutation Details] Delete',
props<{ payload: string }>()
diff --git a/src/app/shared/store/actions/company/company.action.ts b/src/app/shared/store/actions/company/company.action.ts
new file mode 100644
index 0000000..633f7ce
--- /dev/null
+++ b/src/app/shared/store/actions/company/company.action.ts
@@ -0,0 +1,176 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { createAction, props } from '@ngrx/store';
+import { Company, CommunicationsData, Address } from '@shared/models';
+
+export interface ILoadCompanyCommunicationsDataSuccess {
+ payload: Array<CommunicationsData>;
+}
+
+export interface ILoadCompanyCommunicationsDataFail {
+ payload: string;
+}
+
+export interface ILoadCompanyAddressesSuccess {
+ payload: Array<Address>;
+}
+
+export interface ILoadCompanyAddressesFail {
+ payload: string;
+}
+
+export const loadCompanyDetail = createAction(
+ '[Company Details] Load',
+ props<{ payload: string }>()
+);
+
+export const loadCompanyDetailSuccess = createAction(
+ '[Company Details] Load Success',
+ props<{ payload: Company }>()
+);
+
+export const loadCompanyDetailFail = createAction(
+ '[Company Details] Load Fail',
+ props<{ payload: string }>()
+);
+
+export const persistCompanyDetail = createAction(
+ '[Company Details] Persist',
+ props<{ payload: Company }>()
+);
+
+export const persistCompanyDetailSuccess = createAction(
+ '[Company Details] Persist Success',
+ props<{ payload: Company }>()
+);
+
+export const persistCompanyDetailFail = createAction(
+ '[Company Details] Persist Fail',
+ props<{ payload: string }>()
+);
+
+export const loadCompanyDetailCommunicationsData = createAction(
+ '[Company CommunicationsData] Load',
+ props<{ payload: string }>()
+);
+
+export const loadCompanyDetailCommunicationsDataSuccess = createAction(
+ '[Company CommunicationsData] Load Success',
+ props<ILoadCompanyCommunicationsDataSuccess>()
+);
+
+export const loadCompanyDetailCommunicationsDataFail = createAction(
+ '[Company CommunicationsData] Load Fail',
+ props<ILoadCompanyCommunicationsDataFail>()
+);
+
+export const loadCompanyDetailCommunicationsDataDetails = createAction(
+ '[Company CommunicationsData Details] Load',
+ props<{ payload_contactId: string, payload_communicationsId: string }>()
+);
+
+export const loadCompanyDetailCommunicationsDataDetailsSuccess = createAction(
+ '[Company CommunicationsData Details] Load Success',
+ props<{ payload: CommunicationsData }>()
+);
+
+export const loadCompanyDetailCommunicationsDataDetailsFail = createAction(
+ '[Company CommunicationsData Details] Load Fail',
+ props<{ payload: string }>()
+);
+
+export const persistCommunicationsDataDetail = createAction(
+ '[Company CommunicationsData Details] Persist',
+ props<{ payload: CommunicationsData }>()
+);
+
+export const persistCommunicationsDataDetailSuccess = createAction(
+ '[Company CommunicationsData Details] Persist Success',
+ props<{ payload: CommunicationsData }>()
+);
+
+export const persistCommunicationsDataDetailFail = createAction(
+ '[Company CommunicationsData Details] Persist Fail',
+ props<{ payload: string }>()
+);
+
+export const deleteCommunicationsData = createAction(
+ '[Company CommunicationsData Details] Delete',
+ props<{ payload: CommunicationsData }>()
+);
+export const deleteCommunicationsDataSuccess = createAction(
+ '[Company CommunicationsData Details] Delete Success'
+);
+export const deleteCommunicationsDataFail = createAction(
+ '[Company CommunicationsData Details] Delete Fail',
+ props<{ payload: string }>()
+);
+
+export const loadCompanyDetailAddresses = createAction(
+ '[CompanyAddresses] Load',
+ props<{ payload: string }>()
+);
+
+export const loadCompanyDetailAddressesSuccess = createAction(
+ '[CompanyAddresses] Load Success',
+ props<ILoadCompanyAddressesSuccess>()
+);
+
+export const loadCompanyDetailAddressesFail = createAction(
+ '[CompanyAddresses] Load Fail',
+ props<ILoadCompanyAddressesFail>()
+);
+
+export const loadCompanyDetailAddressDetails = createAction(
+ '[CompanyAddresses Details] Load',
+ props<{ payload_contactId: string, payload_addressId: string }>()
+);
+
+export const loadCompanyDetailAddressDetailsSuccess = createAction(
+ '[CompanyAddresses Details] Load Success',
+ props<{ payload: Address }>()
+);
+
+export const loadCompanyDetailAddressDetailsFail = createAction(
+ '[CompanyAddresses Details] Load Fail',
+ props<{ payload: string }>()
+);
+
+export const persistAddressDetail = createAction(
+ '[CompanyAddress Details] Persist',
+ props<{ payload: Address }>()
+);
+
+export const persistAddressDetailSuccess = createAction(
+ '[CompanyAddress Details] Persist Success',
+ props<{ payload: Address }>()
+);
+
+export const persistAddressDetailFail = createAction(
+ '[CompanyAddress Details] Persist Fail',
+ props<{ payload: string }>()
+);
+
+export const deleteAddress = createAction(
+ '[CompanyAddress Details] Delete',
+ props<{ payload: Address }>()
+);
+export const deleteAddressSuccess = createAction(
+ '[CompanyAddress Details] Delete Success'
+);
+export const deleteAddressFail = createAction(
+ '[CompanyAddress Details] Delete Fail',
+ props<{ payload: string }>()
+);
+
+
diff --git a/src/app/shared/store/actions/contacts.action.ts b/src/app/shared/store/actions/contacts.action.ts
index f540202..e9ca365 100644
--- a/src/app/shared/store/actions/contacts.action.ts
+++ b/src/app/shared/store/actions/contacts.action.ts
@@ -15,17 +15,6 @@
import { PageRequestInterface } from '@shared/models/page/page-request.interface';
import { PageModel } from '@shared/models/page/page.model';
-export interface ILoadContactsSuccess {
- payload: Array<Contact>;
-}
-
-export interface ILoadContactsFail {
- payload: string;
-}
-export const loadContacts = createAction('[Contacts] Load');
-export const loadContactsSuccess = createAction('[Contacts] Load Success', props<ILoadContactsSuccess>());
-export const loadContactsFail = createAction('[Contacts] Load Fail', props<ILoadContactsFail>());
-
export interface ILoadContactsPage {
payload: PageRequestInterface;
}
diff --git a/src/app/shared/store/actions/persons/external-person.action.ts b/src/app/shared/store/actions/persons/external-person.action.ts
index ca35e95..f12261e 100644
--- a/src/app/shared/store/actions/persons/external-person.action.ts
+++ b/src/app/shared/store/actions/persons/external-person.action.ts
@@ -1,17 +1,30 @@
- /********************************************************************************
- * Copyright (c) 2020 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- ********************************************************************************/
+/********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/
import { createAction, props } from '@ngrx/store';
-import { ExternalPerson } from '@shared/models';
+import { ExternalPerson, CommunicationsData, Address } from '@shared/models';
+
+export interface ILoadExternalPersonAddressesSuccess {
+ payload: Array<Address>;
+}
+export interface ILoadExternalPersonAddressesFail {
+ payload: string;
+}
+export interface ILoadExternalPersonCommunicationsDataSuccess {
+ payload: Array<CommunicationsData>;
+}
+export interface ILoadExternalPersonCommunicationsDataFail {
+ payload: string;
+}
export const loadExternalPersonDetail = createAction(
'[ExternalPerson Details] Load',
@@ -42,3 +55,117 @@
'[ExternalPerson Details] Persist Fail',
props<{ payload: string }>()
);
+
+export const loadExternalPersonDetailAddresses = createAction(
+ '[ExternalPersonAddresses] Load',
+ props<{ payload: string }>()
+);
+
+export const loadExternalPersonDetailAddressesSuccess = createAction(
+ '[ExternalPersonAddresses] Load Success',
+ props<ILoadExternalPersonAddressesSuccess>()
+);
+
+export const loadExternalPersonDetailAddressesFail = createAction(
+ '[ExternalPersonAddresses] Load Fail',
+ props<ILoadExternalPersonAddressesFail>()
+);
+
+export const loadExternalPersonDetailAddressDetails = createAction(
+ '[ExternalPersonAddresses Details] Load',
+ props<{ payload_contactId: string, payload_addressId: string }>()
+);
+
+export const loadExternalPersonDetailAddressDetailsSuccess = createAction(
+ '[ExternalPersonAddresses Details] Load Success',
+ props<{ payload: Address }>()
+);
+
+export const loadExternalPersonDetailAddressDetailsFail = createAction(
+ '[ExternalPersonAddresses Details] Load Fail',
+ props<{ payload: string }>()
+);
+
+export const persistAddressDetail = createAction(
+ '[ExternalPersonAddress Details] Persist',
+ props<{ payload: Address }>()
+);
+
+export const persistAddressDetailSuccess = createAction(
+ '[ExternalPersonAddress Details] Persist Success',
+ props<{ payload: Address }>()
+);
+
+export const persistAddressDetailFail = createAction(
+ '[ExternalPersonAddress Details] Persist Fail',
+ props<{ payload: string }>()
+);
+
+export const deleteAddress = createAction(
+ '[ExternalPersonAddress Details] Delete',
+ props<{ payload: Address }>()
+);
+export const deleteAddressSuccess = createAction(
+ '[ExternalPersonAddress Details] Delete Success'
+);
+export const deleteAddressFail = createAction(
+ '[ExternalPersonAddress Details] Delete Fail',
+ props<{ payload: string }>()
+);
+
+export const loadExternalPersonDetailCommunicationsData = createAction(
+ '[ExternalPerson CommunicationsData] Load',
+ props<{ payload: string }>()
+);
+
+export const loadExternalPersonDetailCommunicationsDataSuccess = createAction(
+ '[ExternalPerson CommunicationsData] Load Success',
+ props<ILoadExternalPersonCommunicationsDataSuccess>()
+);
+
+export const loadExternalPersonDetailCommunicationsDataFail = createAction(
+ '[ExternalPerson CommunicationsData] Load Fail',
+ props<ILoadExternalPersonCommunicationsDataFail>()
+);
+
+export const loadExternalPersonDetailCommunicationsDataDetails = createAction(
+ '[ExternalPerson CommunicationsData Details] Load',
+ props<{ payload_contactId: string, payload_communicationsId: string }>()
+);
+
+export const loadExternalPersonDetailCommunicationsDataDetailsSuccess = createAction(
+ '[ExternalPerson CommunicationsData Details] Load Success',
+ props<{ payload: CommunicationsData }>()
+);
+
+export const loadExternalPersonDetailCommunicationsDataDetailsFail = createAction(
+ '[ExternalPerson CommunicationsData Details] Load Fail',
+ props<{ payload: string }>()
+);
+
+export const persistCommunicationsDataDetail = createAction(
+ '[ExternalPerson CommunicationsData Details] Persist',
+ props<{ payload: CommunicationsData }>()
+);
+
+export const persistCommunicationsDataDetailSuccess = createAction(
+ '[ExternalPerson CommunicationsData Details] Persist Success',
+ props<{ payload: CommunicationsData }>()
+);
+
+export const persistCommunicationsDataDetailFail = createAction(
+ '[ExternalPerson CommunicationsData Details] Persist Fail',
+ props<{ payload: string }>()
+);
+
+export const deleteCommunicationsData = createAction(
+ '[ExternalPerson CommunicationsData Details] Delete',
+ props<{ payload: CommunicationsData }>()
+);
+export const deleteCommunicationsDataSuccess = createAction(
+ '[ExternalPerson CommunicationsData Details] Delete Success'
+);
+export const deleteCommunicationsDataFail = createAction(
+ '[ExternalPerson CommunicationsData Details] Delete Fail',
+ props<{ payload: string }>()
+);
diff --git a/src/app/shared/store/actions/persons/internal-person.action.ts b/src/app/shared/store/actions/persons/internal-person.action.ts
index d668c6e..e4ec283 100644
--- a/src/app/shared/store/actions/persons/internal-person.action.ts
+++ b/src/app/shared/store/actions/persons/internal-person.action.ts
@@ -1,3 +1,4 @@
+import { Address } from '@shared/models';
/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
@@ -11,7 +12,47 @@
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
import { createAction, props } from '@ngrx/store';
-import { InternalPerson } from '@shared/models';
+import { InternalPerson, CommunicationsData } from '@shared/models';
+import { InternalPersonInterface } from '@shared/models/persons/internal-person-arguments.interface';
+
+export interface ILoadInternalPersonsForUidSuccess {
+ payload: Array<InternalPerson>;
+}
+
+export interface ILoadInternalPersonsForUidFail {
+ payload: string;
+}
+
+export interface ILoadInternalPersonsForUserrefSuccess {
+ payload: Array<InternalPerson>;
+}
+
+export interface ILoadInternalPersonsForUserrefFail {
+ payload: string;
+}
+
+export interface ILoadInternalPersonDetailsSuccess {
+ payload: InternalPerson;
+}
+
+export interface ILoadInternalPersonDetailsFail {
+ payload: string;
+}
+
+export interface ILoadInternalPersonCommunicationsDataSuccess {
+ payload: Array<CommunicationsData>;
+}
+
+export interface ILoadInternalPersonCommunicationsDataFail {
+ payload: string;
+}
+
+export interface ILoadInternalPersonAddressesSuccess {
+ payload: Array<Address>;
+}
+export interface ILoadInternalPersonAddressesFail {
+ payload: string;
+}
export const loadInternalPersonDetail = createAction(
'[InternalPerson Details] Load',
@@ -20,12 +61,12 @@
export const loadInternalPersonDetailSuccess = createAction(
'[InternalPerson Details] Load Success',
- props<{ payload: InternalPerson }>()
+ props<ILoadInternalPersonDetailsSuccess>()
);
export const loadInternalPersonDetailFail = createAction(
'[InternalPerson Details] Load Fail',
- props<{ payload: string }>()
+ props<ILoadInternalPersonDetailsFail>()
);
export const persistInternalPersonDetail = createAction(
@@ -42,3 +83,150 @@
'[InternalPerson Details] Persist Fail',
props<{ payload: string }>()
);
+
+export const loadInternalPersonsForUid = createAction(
+ '[InternalPersons For Uid] Load',
+ props<{ payload: InternalPersonInterface }>()
+);
+
+export const loadInternalPersonsForUidSuccess = createAction(
+ '[InternalPersons For Uid] Load Success',
+ props<ILoadInternalPersonsForUidSuccess>()
+);
+
+export const loadInternalPersonsForUidFail = createAction(
+ '[InternalPersons For Uid] Load Fail',
+ props<ILoadInternalPersonsForUidFail>()
+);
+
+export const loadInternalPersonsForUserref = createAction(
+ '[InternalPersons For Userref] Load',
+ props<{ payload: InternalPersonInterface }>()
+);
+
+export const loadInternalPersonsForUserrefSuccess = createAction(
+ '[InternalPersons For Userref] Load Success',
+ props<ILoadInternalPersonsForUserrefSuccess>()
+);
+
+export const loadInternalPersonsForUserrefFail = createAction(
+ '[InternalPersons For Userref] Load Fail',
+ props<ILoadInternalPersonsForUserrefFail>()
+);
+
+export const loadInternalPersonDetailCommunicationsData = createAction(
+ '[InternalPerson CommunicationsData] Load',
+ props<{ payload: string }>()
+);
+
+export const loadInternalPersonDetailCommunicationsDataSuccess = createAction(
+ '[InternalPerson CommunicationsData] Load Success',
+ props<ILoadInternalPersonCommunicationsDataSuccess>()
+);
+
+export const loadInternalPersonDetailCommunicationsDataFail = createAction(
+ '[InternalPerson CommunicationsData] Load Fail',
+ props<ILoadInternalPersonCommunicationsDataFail>()
+);
+
+export const loadInternalPersonDetailCommunicationsDataDetails = createAction(
+ '[InternalPerson CommunicationsData Details] Load',
+ props<{ payload_contactId: string, payload_communicationsId: string }>()
+);
+
+export const loadInternalPersonDetailCommunicationsDataDetailsSuccess = createAction(
+ '[InternalPerson CommunicationsData Details] Load Success',
+ props<{ payload: CommunicationsData }>()
+);
+
+export const loadInternalPersonDetailCommunicationsDataDetailsFail = createAction(
+ '[InternalPerson CommunicationsData Details] Load Fail',
+ props<{ payload: string }>()
+);
+
+export const persistCommunicationsDataDetail = createAction(
+ '[InternalPerson CommunicationsData Details] Persist',
+ props<{ payload: CommunicationsData }>()
+);
+
+export const persistCommunicationsDataDetailSuccess = createAction(
+ '[InternalPerson CommunicationsData Details] Persist Success',
+ props<{ payload: CommunicationsData }>()
+);
+
+export const persistCommunicationsDataDetailFail = createAction(
+ '[InternalPerson CommunicationsData Details] Persist Fail',
+ props<{ payload: string }>()
+);
+
+export const deleteCommunicationsData = createAction(
+ '[InternalPerson CommunicationsData Details] Delete',
+ props<{ payload: CommunicationsData }>()
+);
+export const deleteCommunicationsDataSuccess = createAction(
+ '[InternalPerson CommunicationsData Details] Delete Success'
+);
+export const deleteCommunicationsDataFail = createAction(
+ '[InternalPerson CommunicationsData Details] Delete Fail',
+ props<{ payload: string }>()
+);
+
+export const loadInternalPersonDetailAddresses = createAction(
+ '[InternalPersonAddresses] Load',
+ props<{ payload: string }>()
+);
+
+export const loadInternalPersonDetailAddressesSuccess = createAction(
+ '[InternalPersonAddresses] Load Success',
+ props<ILoadInternalPersonAddressesSuccess>()
+);
+
+export const loadInternalPersonDetailAddressesFail = createAction(
+ '[InternalPersonAddresses] Load Fail',
+ props<ILoadInternalPersonAddressesFail>()
+);
+
+
+export const loadInternalPersonDetailAddressDetails = createAction(
+ '[InternalPersonAddresses Details] Load',
+ props<{ payload_contactId: string, payload_addressId: string }>()
+);
+
+export const loadInternalPersonDetailAddressDetailsSuccess = createAction(
+ '[InternalPersonAddresses Details] Load Success',
+ props<{ payload: Address }>()
+);
+
+export const loadInternalPersonDetailAddressDetailsFail = createAction(
+ '[InternalPersonAddresses Details] Load Fail',
+ props<{ payload: string }>()
+);
+
+export const persistAddressDetail = createAction(
+ '[InternalPersonAddress Details] Persist',
+ props<{ payload: Address }>()
+);
+
+export const persistAddressDetailSuccess = createAction(
+ '[InternalPersonAddress Details] Persist Success',
+ props<{ payload: Address }>()
+);
+
+export const persistAddressDetailFail = createAction(
+ '[InternalPersonAddress Details] Persist Fail',
+ props<{ payload: string }>()
+);
+
+export const deleteAddress = createAction(
+ '[InternalPersonAddress Details] Delete',
+ props<{ payload: Address }>()
+);
+export const deleteAddressSuccess = createAction(
+ '[InternalPersonAddress Details] Delete Success'
+);
+export const deleteAddressFail = createAction(
+ '[InternalPersonAddress Details] Delete Fail',
+ props<{ payload: string }>()
+);
+
+
diff --git a/src/app/shared/store/effects/admin/address-types.effect.spec.ts b/src/app/shared/store/effects/admin/address-types.effect.spec.ts
new file mode 100644
index 0000000..7731497
--- /dev/null
+++ b/src/app/shared/store/effects/admin/address-types.effect.spec.ts
@@ -0,0 +1,115 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { take } from 'rxjs/operators';
+import { AddressTypesEffects } from '@shared/store/effects/admin/address-types.effect';
+import { Subject, of, throwError } from 'rxjs';
+import { AddressType } from '@shared/models';
+import * as addressTypesActions from '@shared/store/actions/admin/address-types.action';
+import { AddressTypesApiClient } from '@pages/admin/address-types/address-types-api-client';
+import { Store } from '@ngrx/store';
+
+describe('AddressTypes Effects', () => {
+
+ let effects: AddressTypesEffects;
+ let actions$: Subject<any>;
+ let apiClient: AddressTypesApiClient;
+ let store: Store<any>;
+ let apiResponse: any = null;
+
+ beforeEach(() => {
+ apiClient = {
+ getAddressTypes() {},
+ getAddressTypeDetails() {},
+ putAddressType() {},
+ postAddressType() {},
+ deleteAddressType() {}
+ } as any;
+ store = {
+ dispatch() {}
+ } as any;
+ actions$ = new Subject();
+ effects = new AddressTypesEffects(actions$, apiClient, store);
+ });
+
+ it('should be truthy', () => {
+ expect(effects).toBeTruthy();
+ });
+
+ it('should equal loadAddressTypesSuccess after getAddressTypes', (done) => {
+ apiResponse = [new AddressType({id: "1"})];
+ spyOn(apiClient, 'getAddressTypes').and.returnValue(of(apiResponse));
+ effects.getAddressTypes$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(addressTypesActions.loadAddressTypesSuccess({payload: apiResponse}));
+ });
+ done();
+ actions$.next(addressTypesActions.loadAddressTypes());
+ });
+
+ it('should equal loadAddressTypesFail after getAddressType Error', (done) => {
+ spyOn(apiClient, 'getAddressTypes').and.returnValue(throwError('x'));
+ effects.getAddressTypes$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(addressTypesActions.loadAddressTypesFail({payload: 'x'}));
+ });
+ done();
+ actions$.next(addressTypesActions.loadAddressTypes());
+ });
+
+ it('should equal loadAddressTypeSuccess after getAddressType', (done) => {
+ apiResponse = new AddressType({id: "1"});
+ spyOn(apiClient, 'getAddressTypeDetails').and.returnValue(of(apiResponse));
+ effects.getAddressType$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(addressTypesActions.loadAddressTypeSuccess({payload: apiResponse}));
+ });
+ done();
+ actions$.next(addressTypesActions.loadAddressType({payload: "1"}));
+ });
+
+ it('should equal loadAddressTypeFail after getAddressType Error', (done) => {
+ spyOn(apiClient, 'getAddressTypeDetails').and.returnValue(throwError('x'));
+ effects.getAddressType$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(addressTypesActions.loadAddressTypeFail({payload: 'x'}));
+ });
+ done();
+ actions$.next(addressTypesActions.loadAddressType({payload: "1"}));
+ });
+
+ it('should equal saveAddressTypeSuccess after saveAddressType', (done) => {
+ apiResponse = new AddressType({id: "1"});
+ spyOn(apiClient, 'putAddressType').and.returnValue(of(apiResponse));
+ effects.saveAddressType$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(addressTypesActions.saveAddressTypeSuccess({payload: new AddressType({id: "1"})}));
+ });
+ done();
+ actions$.next(addressTypesActions.saveAddressType({payload: new AddressType({id: "1"})}));
+ });
+
+ it('should equal saveAddressTypeFail after saveAddressType Error', (done) => {
+ spyOn(apiClient, 'putAddressType').and.returnValue(throwError('x'));
+ effects.saveAddressType$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(addressTypesActions.saveAddressTypeFail({payload: 'x'}));
+ });
+ done();
+ actions$.next(addressTypesActions.saveAddressType({payload: new AddressType({id: "1"})}));
+ });
+
+ it('should equal deleteAddressTypeSuccess after deleteAddressType', (done) => {
+ apiResponse = new AddressType({id: "1"});
+ spyOn(apiClient, 'deleteAddressType').and.returnValue(of(null));
+ effects.deleteAddressType$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(addressTypesActions.deleteAddressTypeSuccess());
+ });
+ done();
+ actions$.next(addressTypesActions.deleteAddressType({payload: "1"}));
+ });
+
+});
diff --git a/src/app/shared/store/effects/admin/address-types.effect.ts b/src/app/shared/store/effects/admin/address-types.effect.ts
new file mode 100644
index 0000000..09fb9dc
--- /dev/null
+++ b/src/app/shared/store/effects/admin/address-types.effect.ts
@@ -0,0 +1,98 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import 'rxjs/add/operator/catch';
+import 'rxjs/add/operator/map';
+import 'rxjs/add/operator/switchMap';
+import { Injectable } from '@angular/core';
+import { createEffect, Actions, ofType } from '@ngrx/effects';
+import { of } from 'rxjs/observable/of';
+import * as addressTypesActions from '@shared/store/actions/admin/address-types.action';
+import { AddressTypesApiClient } from '@pages/admin/address-types/address-types-api-client';
+import { catchError, map, switchMap } from 'rxjs/operators';
+import { AddressType } from '@shared/models';
+import { Store } from '@ngrx/store';
+
+@Injectable()
+export class AddressTypesEffects {
+
+ getAddressTypes$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(addressTypesActions.loadAddressTypes),
+ switchMap(() => {
+ return this._addressTypesApiClient.getAddressTypes().pipe(
+ map(item => addressTypesActions.loadAddressTypesSuccess({ payload: item })),
+ catchError(error => of(addressTypesActions.loadAddressTypesFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ getAddressType$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(addressTypesActions.loadAddressType),
+ switchMap(action => {
+ return this._addressTypesApiClient
+ .getAddressTypeDetails(action['payload'])
+ .map((item: AddressType) =>
+ addressTypesActions.loadAddressTypeSuccess({ payload: item })
+ )
+ .catch(error =>
+ of(addressTypesActions.loadAddressTypeFail({ payload: error }))
+ );
+ })
+ )
+ );
+
+ saveAddressType$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(addressTypesActions.saveAddressType),
+ map(action => action['payload']),
+ switchMap((payload: AddressType) => {
+ return (payload.id ?
+ this._addressTypesApiClient.putAddressType(payload.id, payload) :
+ this._addressTypesApiClient.postAddressType(payload)
+ ).pipe(
+ map((item: AddressType) => {
+ this._store.dispatch(addressTypesActions.loadAddressTypes());
+ return addressTypesActions.saveAddressTypeSuccess({ payload: item });
+ }),
+ catchError(error =>
+ of(addressTypesActions.saveAddressTypeFail({ payload: error }))
+ )
+ );
+ })
+ )
+ );
+
+ deleteAddressType$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(addressTypesActions.deleteAddressType),
+ map((action) => action['payload']),
+ switchMap((id: string) => {
+ return this._addressTypesApiClient.deleteAddressType(id).pipe(
+ map(() => {
+ this._store.dispatch(addressTypesActions.loadAddressTypes());
+ return addressTypesActions.deleteAddressTypeSuccess();
+ }),
+ catchError(error => of(addressTypesActions.deleteAddressTypeFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ constructor(
+ private _actions$: Actions,
+ private _addressTypesApiClient: AddressTypesApiClient,
+ private _store: Store<any>
+ ) {}
+}
diff --git a/src/app/shared/store/effects/admin/communication-types.effect.spec.ts b/src/app/shared/store/effects/admin/communication-types.effect.spec.ts
new file mode 100644
index 0000000..895b402
--- /dev/null
+++ b/src/app/shared/store/effects/admin/communication-types.effect.spec.ts
@@ -0,0 +1,115 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { take } from 'rxjs/operators';
+import { CommunicationTypesEffects } from '@shared/store/effects/admin/communication-types.effect';
+import { Subject, of, throwError } from 'rxjs';
+import { CommunicationType } from '@shared/models';
+import * as communicationTypesActions from '@shared/store/actions/admin/communication-types.action';
+import { CommunicationTypesApiClient } from '@pages/admin/communication-types/communication-types-api-client';
+import { Store } from '@ngrx/store';
+
+describe('CommunicationTypes Effects', () => {
+
+ let effects: CommunicationTypesEffects;
+ let actions$: Subject<any>;
+ let apiClient: CommunicationTypesApiClient;
+ let store: Store<any>;
+ let apiResponse: any = null;
+
+ beforeEach(() => {
+ apiClient = {
+ getCommunicationTypes() {},
+ getCommunicationType() {},
+ putCommunicationType() {},
+ postCommunicationType() {},
+ deleteCommunicationType() {}
+ } as any;
+ store = {
+ dispatch() {}
+ } as any;
+ actions$ = new Subject();
+ effects = new CommunicationTypesEffects(actions$, apiClient, store);
+ });
+
+ it('should be truthy', () => {
+ expect(effects).toBeTruthy();
+ });
+
+ it('should equal loadCommunicationTypesSuccess after getCommunicationTypes', (done) => {
+ apiResponse = [new CommunicationType({id: "1"})];
+ spyOn(apiClient, 'getCommunicationTypes').and.returnValue(of(apiResponse));
+ effects.getCommunicationTypes$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(communicationTypesActions.loadCommunicationTypesSuccess({payload: apiResponse}));
+ });
+ done();
+ actions$.next(communicationTypesActions.loadCommunicationTypes());
+ });
+
+ it('should equal loadCommunicationTypesFail after getCommunicationTypes Error', (done) => {
+ spyOn(apiClient, 'getCommunicationTypes').and.returnValue(throwError('x'));
+ effects.getCommunicationTypes$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(communicationTypesActions.loadCommunicationTypesFail({payload: 'x'}));
+ });
+ done();
+ actions$.next(communicationTypesActions.loadCommunicationTypes());
+ });
+
+ it('should equal loadCommunicationTypeSuccess after getCommunicationType', (done) => {
+ apiResponse = new CommunicationType({id: "1"});
+ spyOn(apiClient, 'getCommunicationType').and.returnValue(of(apiResponse));
+ effects.getCommunicationType$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(communicationTypesActions.loadCommunicationTypeSuccess({payload: apiResponse}));
+ });
+ done();
+ actions$.next(communicationTypesActions.loadCommunicationType({payload: "1"}));
+ });
+
+ it('should equal loadCommunicationTypeFail after getCommunicationType Error', (done) => {
+ spyOn(apiClient, 'getCommunicationType').and.returnValue(throwError('x'));
+ effects.getCommunicationType$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(communicationTypesActions.loadCommunicationTypeFail({payload: 'x'}));
+ });
+ done();
+ actions$.next(communicationTypesActions.loadCommunicationType({payload: "1"}));
+ });
+
+ it('should equal saveCommunicationTypeSuccess after saveCommunicationType', (done) => {
+ apiResponse = new CommunicationType({id: "1"});
+ spyOn(apiClient, 'putCommunicationType').and.returnValue(of(apiResponse));
+ effects.saveCommunicationType$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(communicationTypesActions.saveCommunicationTypeSuccess({payload: new CommunicationType({id: "1"})}));
+ });
+ done();
+ actions$.next(communicationTypesActions.saveCommunicationType({payload: new CommunicationType({id: "1"})}));
+ });
+
+ it('should equal saveCommunicationTypeFail after saveCommunicationType Error', (done) => {
+ spyOn(apiClient, 'putCommunicationType').and.returnValue(throwError('x'));
+ effects.saveCommunicationType$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(communicationTypesActions.saveCommunicationTypeFail({payload: 'x'}));
+ });
+ done();
+ actions$.next(communicationTypesActions.saveCommunicationType({payload: new CommunicationType({id: "1"})}));
+ });
+
+ it('should equal deleteCommunicationTypeSuccess after deleteCommunicationType', (done) => {
+ apiResponse = new CommunicationType({id: "1"});
+ spyOn(apiClient, 'deleteCommunicationType').and.returnValue(of(null));
+ effects.deleteCommunicationType$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(communicationTypesActions.deleteCommunicationTypeSuccess());
+ });
+ done();
+ actions$.next(communicationTypesActions.deleteCommunicationType({payload: "1"}));
+ });
+
+});
diff --git a/src/app/shared/store/effects/admin/communication-types.effect.ts b/src/app/shared/store/effects/admin/communication-types.effect.ts
new file mode 100644
index 0000000..b57e0a7
--- /dev/null
+++ b/src/app/shared/store/effects/admin/communication-types.effect.ts
@@ -0,0 +1,98 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import 'rxjs/add/operator/catch';
+import 'rxjs/add/operator/map';
+import 'rxjs/add/operator/switchMap';
+import { Injectable } from '@angular/core';
+import { createEffect, Actions, ofType } from '@ngrx/effects';
+import { of } from 'rxjs/observable/of';
+import * as communicationTypesActions from '@shared/store/actions/admin/communication-types.action';
+import { CommunicationTypesApiClient } from '@pages/admin/communication-types/communication-types-api-client';
+import { catchError, map, switchMap } from 'rxjs/operators';
+import { CommunicationType } from '@shared/models';
+import { Store } from '@ngrx/store';
+
+@Injectable()
+export class CommunicationTypesEffects {
+
+ getCommunicationTypes$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(communicationTypesActions.loadCommunicationTypes),
+ switchMap(() => {
+ return this._communicationTypesApiClient.getCommunicationTypes().pipe(
+ map(commTypes => communicationTypesActions.loadCommunicationTypesSuccess({ payload: commTypes })),
+ catchError(error => of(communicationTypesActions.loadCommunicationTypesFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ getCommunicationType$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(communicationTypesActions.loadCommunicationType),
+ switchMap(action => {
+ return this._communicationTypesApiClient
+ .getCommunicationType(action['payload'])
+ .map((item: CommunicationType ) =>
+ communicationTypesActions.loadCommunicationTypeSuccess({ payload: item })
+ )
+ .catch(error =>
+ of(communicationTypesActions.loadCommunicationTypeFail({ payload: error }))
+ );
+ })
+ )
+ );
+
+ saveCommunicationType$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(communicationTypesActions.saveCommunicationType),
+ map(action => action['payload']),
+ switchMap((payload: CommunicationType) => {
+ return (payload.id ?
+ this._communicationTypesApiClient.putCommunicationType(payload.id, payload) :
+ this._communicationTypesApiClient.postCommunicationType(payload)
+ ).pipe(
+ map((item: CommunicationType) => {
+ this._store.dispatch(communicationTypesActions.loadCommunicationTypes());
+ return communicationTypesActions.saveCommunicationTypeSuccess({ payload: item });
+ }),
+ catchError(error =>
+ of(communicationTypesActions.saveCommunicationTypeFail({ payload: error }))
+ )
+ );
+ })
+ )
+ );
+
+ deleteCommunicationType$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(communicationTypesActions.deleteCommunicationType),
+ map((action) => action['payload']),
+ switchMap((id: string) => {
+ return this._communicationTypesApiClient.deleteCommunicationType(id).pipe(
+ map(() => {
+ this._store.dispatch(communicationTypesActions.loadCommunicationTypes());
+ return communicationTypesActions.deleteCommunicationTypeSuccess();
+ }),
+ catchError(error => of(communicationTypesActions.deleteCommunicationTypeFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ constructor(
+ private _actions$: Actions,
+ private _communicationTypesApiClient: CommunicationTypesApiClient,
+ private _store: Store<any>
+ ) {}
+}
diff --git a/src/app/shared/store/effects/admin/person-types.effect.spec.ts b/src/app/shared/store/effects/admin/person-types.effect.spec.ts
new file mode 100644
index 0000000..029995b
--- /dev/null
+++ b/src/app/shared/store/effects/admin/person-types.effect.spec.ts
@@ -0,0 +1,115 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { take } from 'rxjs/operators';
+import { PersonTypesEffects } from '@shared/store/effects/admin/person-types.effect';
+import { Subject, of, throwError } from 'rxjs';
+import { PersonType } from '@shared/models';
+import * as personTypesActions from '@shared/store/actions/admin/person-types.action';
+import { PersonTypesApiClient } from '@pages/admin/person-types/person-types-api-client';
+import { Store } from '@ngrx/store';
+
+describe('PersonTypes Effects', () => {
+
+ let effects: PersonTypesEffects;
+ let actions$: Subject<any>;
+ let apiClient: PersonTypesApiClient;
+ let store: Store<any>;
+ let apiResponse: any = null;
+
+ beforeEach(() => {
+ apiClient = {
+ getPersonTypes() {},
+ getPersonTypeDetails() {},
+ putPersonType() {},
+ postPersonType() {},
+ deletePersonType() {}
+ } as any;
+ store = {
+ dispatch() {}
+ } as any;
+ actions$ = new Subject();
+ effects = new PersonTypesEffects(actions$, apiClient, store);
+ });
+
+ it('should be truthy', () => {
+ expect(effects).toBeTruthy();
+ });
+
+ it('should equal loadPersonTypesSuccess after getPersonTypes', (done) => {
+ apiResponse = [new PersonType({id: "1"})];
+ spyOn(apiClient, 'getPersonTypes').and.returnValue(of(apiResponse));
+ effects.getPersonTypes$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(personTypesActions.loadPersonTypesSuccess({payload: apiResponse}));
+ });
+ done();
+ actions$.next(personTypesActions.loadPersonTypes());
+ });
+
+ it('should equal loadPersonTypesFail after getPersonTypes Error', (done) => {
+ spyOn(apiClient, 'getPersonTypes').and.returnValue(throwError('x'));
+ effects.getPersonTypes$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(personTypesActions.loadPersonTypesFail({payload: 'x'}));
+ });
+ done();
+ actions$.next(personTypesActions.loadPersonTypes());
+ });
+
+ it('should equal loadPersonTypeSuccess after getPersonType', (done) => {
+ apiResponse = new PersonType({id: "1"});
+ spyOn(apiClient, 'getPersonTypeDetails').and.returnValue(of(apiResponse));
+ effects.getPersonType$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(personTypesActions.loadPersonTypeSuccess({payload: apiResponse}));
+ });
+ done();
+ actions$.next(personTypesActions.loadPersonType({payload: "1"}));
+ });
+
+ it('should equal loadPersonTypeFail after getPersonType Error', (done) => {
+ spyOn(apiClient, 'getPersonTypeDetails').and.returnValue(throwError('x'));
+ effects.getPersonType$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(personTypesActions.loadPersonTypeFail({payload: 'x'}));
+ });
+ done();
+ actions$.next(personTypesActions.loadPersonType({payload: "1"}));
+ });
+
+ it('should equal persistPersonTypeSuccess after persistPersonType', (done) => {
+ apiResponse = new PersonType({id: "1"});
+ spyOn(apiClient, 'putPersonType').and.returnValue(of(apiResponse));
+ effects.savePersonType$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(personTypesActions.savePersonTypeSuccess({payload: new PersonType({id: "1"})}));
+ });
+ done();
+ actions$.next(personTypesActions.savePersonType({payload: new PersonType({id: "1"})}));
+ });
+
+ it('should equal saveCommunicationTypeFail after saveCommunicationType Error', (done) => {
+ spyOn(apiClient, 'putPersonType').and.returnValue(throwError('x'));
+ effects.savePersonType$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(personTypesActions.savePersonTypeFail({payload: 'x'}));
+ });
+ done();
+ actions$.next(personTypesActions.savePersonType({payload: new PersonType({id: "1"})}));
+ });
+
+ it('should equal deletePersonTypeSuccess after deletePersonType', (done) => {
+ apiResponse = new PersonType({id: "1"});
+ spyOn(apiClient, 'deletePersonType').and.returnValue(of(null));
+ effects.deletePersonType$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(personTypesActions.deletePersonTypeSuccess());
+ });
+ done();
+ actions$.next(personTypesActions.deletePersonType({payload: "1"}));
+ });
+
+});
diff --git a/src/app/shared/store/effects/admin/person-types.effect.ts b/src/app/shared/store/effects/admin/person-types.effect.ts
new file mode 100644
index 0000000..ae828ef
--- /dev/null
+++ b/src/app/shared/store/effects/admin/person-types.effect.ts
@@ -0,0 +1,98 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import 'rxjs/add/operator/catch';
+import 'rxjs/add/operator/map';
+import 'rxjs/add/operator/switchMap';
+import { Injectable } from '@angular/core';
+import { createEffect, Actions, ofType } from '@ngrx/effects';
+import { of } from 'rxjs/observable/of';
+import * as personTypesActions from '@app/shared/store/actions/admin/person-types.action';
+import { PersonTypesApiClient } from '@pages/admin/person-types/person-types-api-client';
+import { catchError, map, switchMap } from 'rxjs/operators';
+import { PersonType } from '@shared/models';
+import { Store } from '@ngrx/store';
+
+@Injectable()
+export class PersonTypesEffects {
+
+ getPersonTypes$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(personTypesActions.loadPersonTypes),
+ switchMap(() => {
+ return this._personTypesApiClient.getPersonTypes().pipe(
+ map(item => personTypesActions.loadPersonTypesSuccess({ payload: item })),
+ catchError(error => of(personTypesActions.loadPersonTypesFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ getPersonType$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(personTypesActions.loadPersonType),
+ switchMap(action => {
+ return this._personTypesApiClient
+ .getPersonTypeDetails(action['payload'])
+ .map((item: PersonType) =>
+ personTypesActions.loadPersonTypeSuccess({ payload: item })
+ )
+ .catch(error =>
+ of(personTypesActions.loadPersonTypeFail({ payload: error }))
+ );
+ })
+ )
+ );
+
+ savePersonType$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(personTypesActions.savePersonType),
+ map(action => action['payload']),
+ switchMap((payload: PersonType) => {
+ return (payload.id ?
+ this._personTypesApiClient.putPersonType(payload.id, payload) :
+ this._personTypesApiClient.postPersonType(payload)
+ ).pipe(
+ map((item: PersonType) => {
+ this._store.dispatch(personTypesActions.loadPersonTypes());
+ return personTypesActions.savePersonTypeSuccess({ payload: item });
+ }),
+ catchError(error =>
+ of(personTypesActions.savePersonTypeFail({ payload: error }))
+ )
+ );
+ })
+ )
+ );
+
+ deletePersonType$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(personTypesActions.deletePersonType),
+ map((action) => action['payload']),
+ switchMap((id: string) => {
+ return this._personTypesApiClient.deletePersonType(id).pipe(
+ map(() => {
+ this._store.dispatch(personTypesActions.loadPersonTypes());
+ return personTypesActions.deletePersonTypeSuccess();
+ }),
+ catchError(error => of(personTypesActions.deletePersonTypeFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ constructor(
+ private _actions$: Actions,
+ private _personTypesApiClient: PersonTypesApiClient,
+ private _store: Store<any>
+ ) {}
+}
diff --git a/src/app/shared/store/effects/admin/salutations.effect.spec.ts b/src/app/shared/store/effects/admin/salutations.effect.spec.ts
new file mode 100644
index 0000000..ba74261
--- /dev/null
+++ b/src/app/shared/store/effects/admin/salutations.effect.spec.ts
@@ -0,0 +1,115 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { take } from 'rxjs/operators';
+import { SalutationsEffects } from '@shared/store/effects/admin/salutations.effect';
+import { Subject, of, throwError } from 'rxjs';
+import { Salutation } from '@shared/models';
+import * as salutationsActions from '@shared/store/actions/admin/salutations.action';
+import { SalutationsApiClient } from '@pages/admin/salutations/salutations-api-client';
+import { Store } from '@ngrx/store';
+
+describe('Salutations Effects', () => {
+
+ let effects: SalutationsEffects;
+ let actions$: Subject<any>;
+ let apiClient: SalutationsApiClient;
+ let store: Store<any>;
+ let apiResponse: any = null;
+
+ beforeEach(() => {
+ apiClient = {
+ getSalutations() {},
+ getSalutationDetails() {},
+ putSalutation() {},
+ postSalutation() {},
+ deleteSalutation() {}
+ } as any;
+ store = {
+ dispatch() {}
+ } as any;
+ actions$ = new Subject();
+ effects = new SalutationsEffects(actions$, apiClient, store);
+ });
+
+ it('should be truthy', () => {
+ expect(effects).toBeTruthy();
+ });
+
+ it('should equal loadSalutationsSuccess after getSalutations', (done) => {
+ apiResponse = [new Salutation({id: "1"})];
+ spyOn(apiClient, 'getSalutations').and.returnValue(of(apiResponse));
+ effects.getSalutations$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(salutationsActions.loadSalutationsSuccess({payload: apiResponse}));
+ });
+ done();
+ actions$.next(salutationsActions.loadSalutations());
+ });
+
+ it('should equal loadSalutationsFail after getSalutations Error', (done) => {
+ spyOn(apiClient, 'getSalutations').and.returnValue(throwError('x'));
+ effects.getSalutations$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(salutationsActions.loadSalutationsFail({payload: 'x'}));
+ });
+ done();
+ actions$.next(salutationsActions.loadSalutations());
+ });
+
+ it('should equal loadSalutationSuccess after getSalutation', (done) => {
+ apiResponse = new Salutation({id: "1"});
+ spyOn(apiClient, 'getSalutationDetails').and.returnValue(of(apiResponse));
+ effects.getSalutation$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(salutationsActions.loadSalutationSuccess({payload: apiResponse}));
+ });
+ done();
+ actions$.next(salutationsActions.loadSalutation({payload: "1"}));
+ });
+
+ it('should equal loadSalutationFail after getSalutation Error', (done) => {
+ spyOn(apiClient, 'getSalutationDetails').and.returnValue(throwError('x'));
+ effects.getSalutation$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(salutationsActions.loadSalutationFail({payload: 'x'}));
+ });
+ done();
+ actions$.next(salutationsActions.loadSalutation({payload: "1"}));
+ });
+
+ it('should equal saveSalutationSuccess after saveSalutation', (done) => {
+ apiResponse = new Salutation({id: "1"});
+ spyOn(apiClient, 'putSalutation').and.returnValue(of(apiResponse));
+ effects.saveSalutation$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(salutationsActions.saveSalutationSuccess({payload: new Salutation({id: "1"})}));
+ });
+ done();
+ actions$.next(salutationsActions.saveSalutation({payload: new Salutation({id: "1"})}));
+ });
+
+ it('should equal saveSalutationFail after saveSalutation Error', (done) => {
+ spyOn(apiClient, 'putSalutation').and.returnValue(throwError('x'));
+ effects.saveSalutation$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(salutationsActions.saveSalutationFail({payload: 'x'}));
+ });
+ done();
+ actions$.next(salutationsActions.saveSalutation({payload: new Salutation({id: "1"})}));
+ });
+
+ it('should equal deleteSalutationSuccess after deleteSalutation', (done) => {
+ apiResponse = new Salutation({id: "1"});
+ spyOn(apiClient, 'deleteSalutation').and.returnValue(of(null));
+ effects.deleteSalutation$.pipe(take(1)).subscribe(result => {
+ expect(result).toEqual(salutationsActions.deleteSalutationSuccess());
+ });
+ done();
+ actions$.next(salutationsActions.deleteSalutation({payload: "1"}));
+ });
+
+});
diff --git a/src/app/shared/store/effects/salutations.effect.ts b/src/app/shared/store/effects/admin/salutations.effect.ts
similarity index 62%
rename from src/app/shared/store/effects/salutations.effect.ts
rename to src/app/shared/store/effects/admin/salutations.effect.ts
index 6e3cd54..9e02692 100644
--- a/src/app/shared/store/effects/salutations.effect.ts
+++ b/src/app/shared/store/effects/admin/salutations.effect.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -16,22 +16,20 @@
import { Injectable } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';
import { of } from 'rxjs/observable/of';
-import * as salutationsActions from '@shared/store/actions/salutations.action';
-import { SalutationsApiClient } from '@app/pages/admin/salutations/salutations-api-client';
+import * as salutationsActions from '@shared/store/actions/admin/salutations.action';
+import { SalutationsApiClient } from '@pages/admin/salutations/salutations-api-client';
import { catchError, map, switchMap } from 'rxjs/operators';
-import { Salutation } from '@app/shared/models';
+import { Salutation } from '@shared/models';
import { Store } from '@ngrx/store';
@Injectable()
export class SalutationsEffects {
- /**
- * Salutations list
- */
+
getSalutations$: any = createEffect(() =>
- this.actions$.pipe(
+ this._actions$.pipe(
ofType(salutationsActions.loadSalutations),
switchMap(() => {
- return this.salutationsApiClient.getSalutations().pipe(
+ return this._salutationsApiClient.getSalutations().pipe(
map(salutations => salutationsActions.loadSalutationsSuccess({ payload: salutations })),
catchError(error => of(salutationsActions.loadSalutationsFail({ payload: error })))
);
@@ -39,14 +37,11 @@
)
);
- /**
- * Load salutation details
- */
getSalutation$: any = createEffect(() =>
- this.actions$.pipe(
+ this._actions$.pipe(
ofType(salutationsActions.loadSalutation),
switchMap(action => {
- return this.salutationsApiClient
+ return this._salutationsApiClient
.getSalutationDetails(action['payload'])
.map((salutation: Salutation) =>
salutationsActions.loadSalutationSuccess({ payload: salutation })
@@ -58,41 +53,35 @@
)
);
- /**
- * persist new or edited salutation
- */
- persistLog$: any = createEffect(() =>
- this.actions$.pipe(
- ofType(salutationsActions.persistSalutation),
+ saveSalutation$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(salutationsActions.saveSalutation),
map(action => action['payload']),
switchMap((payloadSalutation: Salutation) => {
return (payloadSalutation.id ?
- this.salutationsApiClient.putSalutation(payloadSalutation.id, payloadSalutation) :
- this.salutationsApiClient.postSalutation(payloadSalutation)
+ this._salutationsApiClient.putSalutation(payloadSalutation.id, payloadSalutation) :
+ this._salutationsApiClient.postSalutation(payloadSalutation)
).pipe(
map((salutation: Salutation) => {
- this.store.dispatch(salutationsActions.loadSalutations());
- return salutationsActions.persistSalutationSuccess({ payload: salutation });
+ this._store.dispatch(salutationsActions.loadSalutations());
+ return salutationsActions.saveSalutationSuccess({ payload: salutation });
}),
catchError(error =>
- of(salutationsActions.persistSalutationFail({ payload: error }))
+ of(salutationsActions.saveSalutationFail({ payload: error }))
)
);
})
)
);
- /**
- * delete salutation
- */
deleteSalutation$: any = createEffect(() =>
- this.actions$.pipe(
+ this._actions$.pipe(
ofType(salutationsActions.deleteSalutation),
map((action) => action['payload']),
switchMap((id: string) => {
- return this.salutationsApiClient.deleteSalutation(id).pipe(
+ return this._salutationsApiClient.deleteSalutation(id).pipe(
map(() => {
- this.store.dispatch(salutationsActions.loadSalutations());
+ this._store.dispatch(salutationsActions.loadSalutations());
return salutationsActions.deleteSalutationSuccess();
}),
catchError(error => of(salutationsActions.deleteSalutationFail({ payload: error })))
@@ -102,8 +91,8 @@
);
constructor(
- private actions$: Actions,
- private salutationsApiClient: SalutationsApiClient,
- private store: Store<any>
+ private _actions$: Actions,
+ private _salutationsApiClient: SalutationsApiClient,
+ private _store: Store<any>
) {}
}
diff --git a/src/app/shared/store/effects/company/company.effect.spec.ts b/src/app/shared/store/effects/company/company.effect.spec.ts
new file mode 100644
index 0000000..730bf44
--- /dev/null
+++ b/src/app/shared/store/effects/company/company.effect.spec.ts
@@ -0,0 +1,225 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { CompanyApiClient } from '@pages/company/company-api-client';
+import { CompanyEffect } from "@shared/store/effects/company/company.effect";
+import { Subject, of, throwError } from 'rxjs';
+import * as companyActions from '@shared/store/actions/company/company.action';
+import { Company, CommunicationsData, Address } from '@shared/models';
+
+describe('Company Effects', () => {
+ let effects: CompanyEffect;
+ let actions$: Subject<any>;
+ let apiClient: CompanyApiClient;
+ let apiResponse: any = null;
+ let store: any;
+
+ beforeEach(() => {
+ apiClient = {
+ getCompanyDetails() {},
+ putCompanyDetails: () => {},
+ postCompanyDetails: () => {},
+ getCompanyDetailsAddresses: () => {},
+ getCompanyDetailsAddressesDetails: () => {},
+ putAddressDetails: () => {},
+ postAddressDetails: () => {},
+ deleteAddress: () => {},
+ putCommunicationsDataDetails: () => {},
+ postCommunicationsDataDetails: () => {},
+ deleteCommunicationsData: () => {},
+ } as any;
+
+ actions$ = new Subject();
+
+ store = {
+ dispatch() {}
+ }
+
+
+ effects = new CompanyEffect(actions$, apiClient, store);
+ });
+
+ it('should be truthy', () => {
+ expect(effects).toBeTruthy();
+ });
+
+ it('should equal loadCompanyDetail after getCompany', (done) => {
+ apiResponse = new Company({id: "1"});
+ spyOn(apiClient, 'getCompanyDetails').and.returnValue(of(apiResponse));
+ effects.getCompany$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.loadCompanyDetailSuccess({payload: new Company({id: "1"})}));
+ });
+ done();
+ actions$.next(companyActions.loadCompanyDetail({payload: "1"}));
+ });
+
+ it('should equal loadCompanyDetailFail after getCompany', (done) => {
+ spyOn(apiClient, 'getCompanyDetails').and.returnValue(throwError('error'));
+ effects.getCompany$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.loadCompanyDetailFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(companyActions.loadCompanyDetail({payload: "1"}));
+ });
+
+ it('should equal putCompanyDetails after persistCompany with given contactId', (done) => {
+ apiResponse = new Company({contactId: "1"});
+ spyOn(apiClient, 'putCompanyDetails').and.returnValue(of(apiResponse));
+ effects.persistCompany$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.persistCompanyDetailSuccess({payload: new Company({contactId: "1"})}));
+ });
+ done();
+ actions$.next(companyActions.persistCompanyDetail({payload: new Company({contactId: "1"})}));
+ });
+
+ it('should equal postCompanyDetails after persistCompany a new company', (done) => {
+ apiResponse = new Company();
+ spyOn(apiClient, 'postCompanyDetails').and.returnValue(of(apiResponse));
+ effects.persistCompany$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.persistCompanyDetailSuccess({payload: new Company()}));
+ });
+ done();
+ actions$.next(companyActions.persistCompanyDetail({payload: new Company()}));
+ });
+
+ it('should equal persistCompanyDetailFail after putCompanyDetails', (done) => {
+ spyOn(apiClient, 'putCompanyDetails').and.returnValue(throwError('error'));
+ effects.persistCompany$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.persistCompanyDetailFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(companyActions.persistCompanyDetail({payload: new Company({contactId: "1"})}));
+ });
+
+ it('should equal persistCompanyDetailFail after postCompanyDetails', (done) => {
+ spyOn(apiClient, 'postCompanyDetails').and.returnValue(throwError('error'));
+ effects.persistCompany$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.persistCompanyDetailFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(companyActions.persistCompanyDetail({payload: new Company()}));
+ });
+
+ it('should equal persistCommunicationsDataDetailSuccess after persistCommunicationsDataDetail with given contactId', (done) => {
+ apiResponse = new CommunicationsData({contactId: "1", id: "1"});
+ spyOn(apiClient, 'putCommunicationsDataDetails').and.returnValue(of(apiResponse));
+ effects.persistCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.persistCommunicationsDataDetailSuccess({payload: new CommunicationsData({contactId: "1", id: "1"})}));
+ });
+ done();
+ actions$.next(companyActions.persistCommunicationsDataDetail({payload: new CommunicationsData({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal persistCommunicationsDataDetailSuccess after persistCommunicationsDataDetail a new internal person', (done) => {
+ apiResponse = new CommunicationsData();
+ spyOn(apiClient, 'postCommunicationsDataDetails').and.returnValue(of(apiResponse));
+ effects.persistCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.persistCommunicationsDataDetailSuccess({payload: new CommunicationsData()}));
+ });
+ done();
+ actions$.next(companyActions.persistCommunicationsDataDetail({payload: new CommunicationsData()}));
+ });
+
+ it('should equal persistCommunicationsDataDetailFail after putCommunicationsDataDetails', (done) => {
+ spyOn(apiClient, 'putCommunicationsDataDetails').and.returnValue(throwError('error'));
+ effects.persistCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.persistCommunicationsDataDetailFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(companyActions.persistCommunicationsDataDetail({payload: new CommunicationsData({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal persistCommunicationsDataDetailFail after postCommunicationsDataDetails', (done) => {
+ spyOn(apiClient, 'postCommunicationsDataDetails').and.returnValue(throwError('error'));
+ effects.persistCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.persistCommunicationsDataDetailFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(companyActions.persistCommunicationsDataDetail({payload: new CommunicationsData ()}));
+ });
+
+ it('should equal deleteCommunicationsDataSuccess after deleteCommunicationsData', (done) => {
+ apiResponse = new CommunicationsData({contactId: "1", id: "1"});
+ spyOn(apiClient, 'deleteCommunicationsData').and.returnValue(of(apiResponse));
+ effects.deleteCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.deleteCommunicationsDataSuccess());
+ });
+ done();
+ actions$.next(companyActions.deleteCommunicationsData({payload: new CommunicationsData ({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal deleteCommunicationsDataFail after deleteCommunicationsData', (done) => {
+ spyOn(apiClient, 'deleteCommunicationsData').and.returnValue(throwError('error'));
+ effects.deleteCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.deleteCommunicationsDataFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(companyActions.deleteCommunicationsData({payload: new CommunicationsData ({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal persistAddressDetailSuccess after persistAddressDetail with given contactId', (done) => {
+ apiResponse = new Address({contactId: "1", id: "1"});
+ spyOn(apiClient, 'putAddressDetails').and.returnValue(of(apiResponse));
+ effects.persistAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.persistAddressDetailSuccess({payload: new Address({contactId: "1", id: "1"})}));
+ });
+ done();
+ actions$.next(companyActions.persistAddressDetail({payload: new Address({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal persistAddressDetailSuccess after persistAddressDetail a new company', (done) => {
+ apiResponse = new Address();
+ spyOn(apiClient, 'postAddressDetails').and.returnValue(of(apiResponse));
+ effects.persistAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.persistAddressDetailSuccess({payload: new Address()}));
+ });
+ done();
+ actions$.next(companyActions.persistAddressDetail({payload: new Address()}));
+ });
+
+ it('should equal persistAddressDetailFail after putAddressDetails', (done) => {
+ spyOn(apiClient, 'putAddressDetails').and.returnValue(throwError('error'));
+ effects.persistAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.persistAddressDetailFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(companyActions.persistAddressDetail({payload: new Address({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal persistAddressDetailFail after postAddressDetails', (done) => {
+ spyOn(apiClient, 'postAddressDetails').and.returnValue(throwError('error'));
+ effects.persistAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.persistAddressDetailFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(companyActions.persistAddressDetail({payload: new Address ()}));
+ });
+
+ it('should equal deleteAddressSuccess after deleteAddress', (done) => {
+ apiResponse = new Address({contactId: "1", id: "1"});
+ spyOn(apiClient, 'deleteAddress').and.returnValue(of(apiResponse));
+ effects.deleteAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.deleteAddressSuccess());
+ });
+ done();
+ actions$.next(companyActions.deleteAddress({payload: new Address ({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal deleteAddressFail after deleteAddress', (done) => {
+ spyOn(apiClient, 'deleteAddress').and.returnValue(throwError('error'));
+ effects.deleteAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(companyActions.deleteAddressFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(companyActions.deleteAddress({payload: new Address ({contactId: "1", id: "1"})}));
+ });
+});
diff --git a/src/app/shared/store/effects/company/company.effect.ts b/src/app/shared/store/effects/company/company.effect.ts
new file mode 100644
index 0000000..5a2fce9
--- /dev/null
+++ b/src/app/shared/store/effects/company/company.effect.ts
@@ -0,0 +1,227 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import 'rxjs/add/operator/catch';
+import 'rxjs/add/operator/map';
+import 'rxjs/add/operator/switchMap';
+import { of } from 'rxjs/observable/of';
+import { Injectable } from '@angular/core';
+import { catchError, map, switchMap } from 'rxjs/operators';
+import { createEffect, ofType, Actions } from '@ngrx/effects';
+import * as companyActions from '@shared/store/actions/company/company.action';
+import { CompanyApiClient } from '@pages/company/company-api-client';
+import { Company, CommunicationsData, Address } from '@shared/models';
+import { Store } from '@ngrx/store';
+import { State } from '@shared/store';
+
+@Injectable()
+export class CompanyEffect {
+
+ /**
+ * load external company details
+ */
+ getCompany$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(companyActions.loadCompanyDetail),
+ switchMap(action => {
+ return this._companyApiClient
+ .getCompanyDetails(action['payload'])
+ .map((company: Company) => companyActions.loadCompanyDetailSuccess({ payload: company }))
+ .catch(error => of(companyActions.loadCompanyDetailFail({ payload: error })));
+ })
+ )
+ );
+
+ /**
+ * Load company's addresses details
+ */
+ getCompanyAddressDetails$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(companyActions.loadCompanyDetailAddressDetails),
+ switchMap(action => {
+ return this._companyApiClient
+ .getAddressesDetails(action.payload_contactId, action.payload_addressId)
+ .map((companyAdressDetails: Address) =>
+ companyActions.loadCompanyDetailAddressDetailsSuccess({ payload: companyAdressDetails })
+ )
+ .catch(error =>
+ of(companyActions.loadCompanyDetailAddressDetailsFail({ payload: error }))
+ );
+ })
+ )
+ );
+
+
+ /**
+ * load company details Addresses
+ */
+ getCompanyAddresses$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(companyActions.loadCompanyDetailAddresses),
+ switchMap((action: any) => {
+ return this._companyApiClient
+ .getAddresses(action['payload']).pipe(
+ map((companyAddresses: Array<Address>) =>
+ companyActions.loadCompanyDetailAddressesSuccess({ payload: companyAddresses })
+ ),
+ catchError(error =>
+ of(companyActions.loadCompanyDetailAddressesFail({ payload: error }))
+ )
+ );
+ })
+ )
+ );
+
+ /**
+ * persist new or edited company
+ */
+ persistCompany$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(companyActions.persistCompanyDetail),
+ map(action => action['payload']),
+ switchMap((companyDetails: Company) => {
+ return (companyDetails.contactId
+ ? this._companyApiClient.putCompanyDetails(companyDetails.contactId, companyDetails)
+ : this._companyApiClient.postCompanyDetails(companyDetails)
+ ).pipe(
+ map((company: Company) => {
+ return companyActions.persistCompanyDetailSuccess({ payload: company });
+ }),
+ catchError(error => of(companyActions.persistCompanyDetailFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ /**
+ * persist new or edited address
+ */
+ persistAddress$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(companyActions.persistAddressDetail),
+ map(action => action['payload']),
+ switchMap((address: Address) => {
+ return (address.id
+ ? this._companyApiClient.putAddressDetails(address.contactId, address.id, address)
+ : this._companyApiClient.postAddressDetails(address.contactId, address)
+ ).pipe(
+ map(() => {
+ this.store.dispatch(companyActions.loadCompanyDetailAddresses({ payload: address.contactId }));
+ return companyActions.persistAddressDetailSuccess({ payload: address });
+ }),
+ catchError(error => of(companyActions.persistAddressDetailFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ /**
+ * delete address
+ */
+ deleteAddress$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(companyActions.deleteAddress),
+ map((action) => action['payload']),
+ switchMap((address: Address) => {
+ return this._companyApiClient.deleteAddress(address.contactId, address.id).pipe(
+ map(() => {
+ this.store.dispatch(companyActions.loadCompanyDetailAddresses({ payload: address.contactId }));
+ return companyActions.deleteAddressSuccess();
+ }),
+ catchError(error => of(companyActions.deleteAddressFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ /**
+ * load internal company details communications data
+ */
+ getCompanyCommunicationsData$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(companyActions.loadCompanyDetailCommunicationsData),
+ switchMap((action: any) => {
+ return this._companyApiClient
+ .getCommunicationsData(action['payload']).pipe(
+ map((CompanyCommunicationsData: Array<CommunicationsData>) =>
+ companyActions.loadCompanyDetailCommunicationsDataSuccess({ payload: CompanyCommunicationsData })
+ ),
+ catchError(error =>
+ of(companyActions.loadCompanyDetailCommunicationsDataFail({ payload: error }))
+ )
+ );
+ })
+ )
+ );
+
+ /**
+ * Load internal company's communications data details
+ */
+ getCompanyCommunicationsDataDetails$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(companyActions.loadCompanyDetailCommunicationsDataDetails),
+ switchMap(action => {
+ return this._companyApiClient
+ .getCommunicationsDataDetails(action.payload_contactId, action.payload_communicationsId)
+ .map((extcompanyCommunicationsDataDetails: CommunicationsData) =>
+ companyActions.loadCompanyDetailCommunicationsDataDetailsSuccess({ payload: extcompanyCommunicationsDataDetails })
+ )
+ .catch(error =>
+ of(companyActions.loadCompanyDetailCommunicationsDataDetailsFail({ payload: error }))
+ );
+ })
+ )
+ );
+
+ /**
+ * persist new or edited communications data
+ */
+ persistCommunicationsData$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(companyActions.persistCommunicationsDataDetail),
+ map(action => action['payload']),
+ switchMap((address: CommunicationsData) => {
+ return (address.id
+ ? this._companyApiClient.putCommunicationsDataDetails(address.contactId, address.id, address)
+ : this._companyApiClient.postCommunicationsDataDetails(address.contactId, address)
+ ).pipe(
+ map(() => {
+ this.store.dispatch(companyActions.loadCompanyDetailCommunicationsData({ payload: address.contactId }));
+ return companyActions.persistCommunicationsDataDetailSuccess({ payload: address });
+ }),
+ catchError(error => of(companyActions.persistCommunicationsDataDetailFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ /**
+ * delete communications data
+ */
+ deleteCommunicationsData$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(companyActions.deleteCommunicationsData),
+ map((action) => action['payload']),
+ switchMap((address: CommunicationsData) => {
+ return this._companyApiClient.deleteCommunicationsData(address.contactId, address.id).pipe(
+ map(() => {
+ this.store.dispatch(companyActions.loadCompanyDetailCommunicationsData({ payload: address.contactId }));
+ return companyActions.deleteCommunicationsDataSuccess();
+ }),
+ catchError(error => of(companyActions.deleteCommunicationsDataFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ constructor(private _actions$: Actions, private _companyApiClient: CompanyApiClient, private store: Store<State>) { }
+}
diff --git a/src/app/shared/store/effects/contacts.effect.ts b/src/app/shared/store/effects/contacts.effect.ts
index 0e6e112..c0021c5 100644
--- a/src/app/shared/store/effects/contacts.effect.ts
+++ b/src/app/shared/store/effects/contacts.effect.ts
@@ -17,24 +17,12 @@
import { createEffect, Actions, ofType } from '@ngrx/effects';
import { of } from 'rxjs/observable/of';
import * as contactsActions from '@shared/store/actions/contacts.action';
-import { ContactsApiClient } from '@app/pages/contacts/contacts-api-client';
+import { ContactsApiClient } from '@pages/contacts/contacts-api-client';
import { catchError, map, switchMap } from 'rxjs/operators';
import { PageRequestInterface } from '@shared/models/page/page-request.interface';
@Injectable()
export class ContactsEffects {
- /* plain list */
- getContacts$: any = createEffect(() =>
- this.actions$.pipe(
- ofType(contactsActions.loadContacts),
- switchMap(() => {
- return this.contactsApiClient.getContacts().pipe(
- map(contacts => contactsActions.loadContactsSuccess({ payload: contacts.content })),
- catchError(error => of(contactsActions.loadContactsFail({ payload: error })))
- );
- })
- )
- );
/* paged list */
getContactsPage$: any = createEffect(() =>
this.actions$.pipe(
diff --git a/src/app/shared/store/effects/contacts.effects.spec.ts b/src/app/shared/store/effects/contacts.effects.spec.ts
index bd7156f..681a430 100644
--- a/src/app/shared/store/effects/contacts.effects.spec.ts
+++ b/src/app/shared/store/effects/contacts.effects.spec.ts
@@ -14,10 +14,10 @@
import { take } from 'rxjs/operators';
import { ContactsEffects } from '@shared/store/effects/contacts.effect';
import { Subject, of, throwError } from 'rxjs';
-import { Contact } from '@app/shared/models';
+import { Contact } from '@shared/models';
import * as contactsActions from '@shared/store/actions/contacts.action';
-import { ContactsApiClient } from '@app/pages/contacts/contacts-api-client';
-import { PageModel } from '@app/shared/models/page/page.model';
+import { ContactsApiClient } from '@pages/contacts/contacts-api-client';
+import { PageModel } from '@shared/models/page/page.model';
describe('Contacts Effects', () => {
@@ -43,26 +43,6 @@
expect(effects).toBeTruthy();
});
- it('should equal loadContactsSuccess after getContacts', (done) => {
- spyOn(apiClient, 'getContacts').and.returnValue(of(apiResponse));
- effects.getContacts$.pipe(take(1)).subscribe(result => {
- expect(result).toEqual(contactsActions.loadContactsSuccess({payload: apiResponse.content}));
- });
- done();
- actions$.next(contactsActions.loadContacts());
- });
-
- it('should equal loadContactsFail after getContacts Error', (done) => {
- spyOn(apiClient, 'getContacts').and.returnValue(throwError('x'));
-
- effects.getContacts$.pipe(take(1)).subscribe(result => {
- expect(result).toEqual(contactsActions.loadContactsFail({payload: 'x'}));
- });
- done();
-
- actions$.next(contactsActions.loadContacts());
- });
-
it('should equal loadContactsPageSuccess after getContactsPage', (done) => {
let request = {payload: {
pageNumber: 1,
diff --git a/src/app/shared/store/effects/persons/external-person.effect.spec.ts b/src/app/shared/store/effects/persons/external-person.effect.spec.ts
index d7e252a..eda38ea 100644
--- a/src/app/shared/store/effects/persons/external-person.effect.spec.ts
+++ b/src/app/shared/store/effects/persons/external-person.effect.spec.ts
@@ -10,26 +10,41 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { PersonsApiClient } from '@app/pages/persons/persons-api-client';
-import { ExternalPersonEffect } from "./external-person.effect";
+import { PersonsApiClient } from '@pages/persons/persons-api-client';
+import { ExternalPersonEffect } from "@shared/store/effects/persons/external-person.effect";
import { Subject, of, throwError } from 'rxjs';
-import * as externalPersonActions from '@app/shared/store/actions/persons/external-person.action';
-import { ExternalPerson } from '@app/shared/models';
+import * as externalPersonActions from '@shared/store/actions/persons/external-person.action';
+import { ExternalPerson, Address, CommunicationsData } from '@shared/models';
describe('ExternalPerson Effects', () => {
let effects: ExternalPersonEffect;
let actions$: Subject<any>;
let apiClient: PersonsApiClient;
let apiResponse: any = null;
+ let store: any;
beforeEach(() => {
apiClient = {
getExternalPersonDetails() {},
putExternalPersonDetails: () => {},
postExternalPersonDetails: () => {},
+ putAddressDetails: () => {},
+ postAddressDetails: () => {},
+ deleteAddress: () => {},
+ putCommunicationsDataDetails: () => {},
+ postCommunicationsDataDetails: () => {},
+ deleteCommunicationsData: () => {},
+ getAddressesDetails: () => {},
+ getAddresses: () => {},
} as any;
+
actions$ = new Subject();
- effects = new ExternalPersonEffect(actions$, apiClient);
+
+ store = {
+ dispatch() {}
+ }
+
+ effects = new ExternalPersonEffect(actions$, apiClient, store);
});
it('should be truthy', () => {
@@ -92,4 +107,156 @@
done();
actions$.next(externalPersonActions.persistExternalPersonDetail({payload: new ExternalPerson()}));
});
+
+ it('should equal loadAddressDetail after getAddresses', (done) => {
+ apiResponse = [new Address({contactId: "1"})];
+ spyOn(apiClient, 'getAddresses').and.returnValue(of(apiResponse));
+ effects.getExternalPersonAddresses$.pipe().subscribe(result => {
+ expect(result).toEqual(externalPersonActions.loadExternalPersonDetailAddressesSuccess({payload: [new Address({contactId: "1"})]}));
+ });
+ done();
+ actions$.next(externalPersonActions.loadExternalPersonDetailAddresses({payload: "1"}));
+ });
+
+ it('should equal loadExternalPersonDetailFail after getAddresses', (done) => {
+ spyOn(apiClient, 'getAddresses').and.returnValue(throwError('error'));
+ effects.getExternalPersonAddresses$.pipe().subscribe(result => {
+ expect(result).toEqual(externalPersonActions.loadExternalPersonDetailAddressesFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(externalPersonActions.loadExternalPersonDetailAddresses({payload: "1"}));
+ });
+
+ it('should equal loadAddressDetail after getAddressesDetails', (done) => {
+ apiResponse = new Address({contactId: "1", id: "1"});
+ spyOn(apiClient, 'getAddressesDetails').and.returnValue(of(apiResponse));
+ effects.getExternalPersonAddressDetails$.pipe().subscribe(result => {
+ expect(result).toEqual(externalPersonActions.loadExternalPersonDetailAddressDetailsSuccess({payload: new Address({contactId: "1", id: "1"})}));
+ });
+ done();
+ actions$.next(externalPersonActions.loadExternalPersonDetailAddressDetails({payload_contactId: "1", payload_addressId: "1"}));
+ });
+
+ it('should equal loadExternalPersonDetailFail after getAddressesDetails', (done) => {
+ spyOn(apiClient, 'getAddressesDetails').and.returnValue(throwError('error'));
+ effects.getExternalPersonAddressDetails$.pipe().subscribe(result => {
+ expect(result).toEqual(externalPersonActions.loadExternalPersonDetailAddressDetailsFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(externalPersonActions.loadExternalPersonDetailAddressDetails({payload_contactId: "1", payload_addressId: "1"}));
+ });
+
+ it('should equal persistAddressDetailSuccess after persistAddressDetail with given contactId', (done) => {
+ apiResponse = new Address({contactId: "1", id: "1"});
+ spyOn(apiClient, 'putAddressDetails').and.returnValue(of(apiResponse));
+ effects.persistAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(externalPersonActions.persistAddressDetailSuccess({payload: new Address({contactId: "1", id: "1"})}));
+ });
+ done();
+ actions$.next(externalPersonActions.persistAddressDetail({payload: new Address({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal persistAddressDetailSuccess after persistAddressDetail a new external person', (done) => {
+ apiResponse = new Address();
+ spyOn(apiClient, 'postAddressDetails').and.returnValue(of(apiResponse));
+ effects.persistAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(externalPersonActions.persistAddressDetailSuccess({payload: new Address()}));
+ });
+ done();
+ actions$.next(externalPersonActions.persistAddressDetail({payload: new Address()}));
+ });
+
+ it('should equal persistAddressDetailFail after putAddressDetails', (done) => {
+ spyOn(apiClient, 'putAddressDetails').and.returnValue(throwError('error'));
+ effects.persistAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(externalPersonActions.persistAddressDetailFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(externalPersonActions.persistAddressDetail({payload: new Address({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal persistAddressDetailFail after postAddressDetails', (done) => {
+ spyOn(apiClient, 'postAddressDetails').and.returnValue(throwError('error'));
+ effects.persistAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(externalPersonActions.persistAddressDetailFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(externalPersonActions.persistAddressDetail({payload: new Address ()}));
+ });
+
+ it('should equal deleteAddressSuccess after deleteAddress', (done) => {
+ apiResponse = new Address({contactId: "1", id: "1"});
+ spyOn(apiClient, 'deleteAddress').and.returnValue(of(apiResponse));
+ effects.deleteAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(externalPersonActions.deleteAddressSuccess());
+ });
+ done();
+ actions$.next(externalPersonActions.deleteAddress({payload: new Address ({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal deleteAddressFail after deleteAddress', (done) => {
+ spyOn(apiClient, 'deleteAddress').and.returnValue(throwError('error'));
+ effects.deleteAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(externalPersonActions.deleteAddressFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(externalPersonActions.deleteAddress({payload: new Address ({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal persistCommunicationsDataDetailSuccess after persistCommunicationsDataDetail with given contactId', (done) => {
+ apiResponse = new CommunicationsData({contactId: "1", id: "1"});
+ spyOn(apiClient, 'putCommunicationsDataDetails').and.returnValue(of(apiResponse));
+ effects.persistCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(externalPersonActions.persistCommunicationsDataDetailSuccess({payload: new CommunicationsData({contactId: "1", id: "1"})}));
+ });
+ done();
+ actions$.next(externalPersonActions.persistCommunicationsDataDetail({payload: new CommunicationsData({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal persistCommunicationsDataDetailSuccess after persistCommunicationsDataDetail a new external person', (done) => {
+ apiResponse = new CommunicationsData();
+ spyOn(apiClient, 'postCommunicationsDataDetails').and.returnValue(of(apiResponse));
+ effects.persistCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(externalPersonActions.persistCommunicationsDataDetailSuccess({payload: new CommunicationsData()}));
+ });
+ done();
+ actions$.next(externalPersonActions.persistCommunicationsDataDetail({payload: new CommunicationsData()}));
+ });
+
+ it('should equal persistCommunicationsDataDetailFail after putCommunicationsDataDetails', (done) => {
+ spyOn(apiClient, 'putCommunicationsDataDetails').and.returnValue(throwError('error'));
+ effects.persistCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(externalPersonActions.persistCommunicationsDataDetailFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(externalPersonActions.persistCommunicationsDataDetail({payload: new CommunicationsData({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal persistCommunicationsDataDetailFail after postCommunicationsDataDetails', (done) => {
+ spyOn(apiClient, 'postCommunicationsDataDetails').and.returnValue(throwError('error'));
+ effects.persistCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(externalPersonActions.persistCommunicationsDataDetailFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(externalPersonActions.persistCommunicationsDataDetail({payload: new CommunicationsData ()}));
+ });
+
+ it('should equal deleteCommunicationsDataSuccess after deleteCommunicationsData', (done) => {
+ apiResponse = new CommunicationsData({contactId: "1", id: "1"});
+ spyOn(apiClient, 'deleteCommunicationsData').and.returnValue(of(apiResponse));
+ effects.deleteCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(externalPersonActions.deleteCommunicationsDataSuccess());
+ });
+ done();
+ actions$.next(externalPersonActions.deleteCommunicationsData({payload: new CommunicationsData ({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal deleteCommunicationsDataFail after deleteCommunicationsData', (done) => {
+ spyOn(apiClient, 'deleteCommunicationsData').and.returnValue(throwError('error'));
+ effects.deleteCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(externalPersonActions.deleteCommunicationsDataFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(externalPersonActions.deleteCommunicationsData({payload: new CommunicationsData ({contactId: "1", id: "1"})}));
+ });
});
diff --git a/src/app/shared/store/effects/persons/external-person.effect.ts b/src/app/shared/store/effects/persons/external-person.effect.ts
index dae30f9..f7d05fb 100644
--- a/src/app/shared/store/effects/persons/external-person.effect.ts
+++ b/src/app/shared/store/effects/persons/external-person.effect.ts
@@ -1,15 +1,15 @@
- /********************************************************************************
- * Copyright (c) 2020 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- ********************************************************************************/
+/********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
@@ -17,9 +17,11 @@
import { Injectable } from '@angular/core';
import { catchError, map, switchMap } from 'rxjs/operators';
import { createEffect, ofType, Actions } from '@ngrx/effects';
-import * as externalPersonActions from '@app/shared/store/actions/persons/external-person.action';
-import { PersonsApiClient } from '@app/pages/persons/persons-api-client';
-import { ExternalPerson } from '@shared/models';
+import * as externalPersonActions from '@shared/store/actions/persons/external-person.action';
+import { PersonsApiClient } from '@pages/persons/persons-api-client';
+import { ExternalPerson, Address, CommunicationsData } from '@shared/models';
+import { Store } from '@ngrx/store';
+import { State } from '@shared/store';
@Injectable()
export class ExternalPersonEffect {
@@ -31,7 +33,7 @@
this.actions$.pipe(
ofType(externalPersonActions.loadExternalPersonDetail),
switchMap(action => {
- return this.personsApiClient
+ return this._personsApiClient
.getExternalPersonDetails(action['payload'])
.map((externalPerson: ExternalPerson) => externalPersonActions.loadExternalPersonDetailSuccess({ payload: externalPerson }))
.catch(error => of(externalPersonActions.loadExternalPersonDetailFail({ payload: error })));
@@ -40,6 +42,45 @@
);
/**
+ * load external person details Addresses
+ */
+ getExternalPersonAddresses$: any = createEffect(() =>
+ this.actions$.pipe(
+ ofType(externalPersonActions.loadExternalPersonDetailAddresses),
+ switchMap((action: any) => {
+ return this._personsApiClient
+ .getAddresses(action['payload']).pipe(
+ map((externalPersonAddresses: Array<Address>) =>
+ externalPersonActions.loadExternalPersonDetailAddressesSuccess({ payload: externalPersonAddresses })
+ ),
+ catchError(error =>
+ of(externalPersonActions.loadExternalPersonDetailAddressesFail({ payload: error }))
+ )
+ );
+ })
+ )
+ );
+
+ /**
+ * Load external person's addresses details
+ */
+ getExternalPersonAddressDetails$: any = createEffect(() =>
+ this.actions$.pipe(
+ ofType(externalPersonActions.loadExternalPersonDetailAddressDetails),
+ switchMap(action => {
+ return this._personsApiClient
+ .getAddressesDetails(action.payload_contactId, action.payload_addressId)
+ .map((extPersonAdressDetails: Address) =>
+ externalPersonActions.loadExternalPersonDetailAddressDetailsSuccess({ payload: extPersonAdressDetails })
+ )
+ .catch(error =>
+ of(externalPersonActions.loadExternalPersonDetailAddressDetailsFail({ payload: error }))
+ );
+ })
+ )
+ );
+
+ /**
* persist new or edited external person
*/
persistExternalPerson$: any = createEffect(() =>
@@ -48,8 +89,8 @@
map(action => action['payload']),
switchMap((externalPersonDetails: ExternalPerson) => {
return (externalPersonDetails.contactId
- ? this.personsApiClient.putExternalPersonDetails(externalPersonDetails.contactId, externalPersonDetails)
- : this.personsApiClient.postExternalPersonDetails(externalPersonDetails)
+ ? this._personsApiClient.putExternalPersonDetails(externalPersonDetails.contactId, externalPersonDetails)
+ : this._personsApiClient.postExternalPersonDetails(externalPersonDetails)
).pipe(
map((externalPerson: ExternalPerson) => {
return externalPersonActions.persistExternalPersonDetailSuccess({ payload: externalPerson });
@@ -60,5 +101,127 @@
)
);
- constructor(private actions$: Actions, private personsApiClient: PersonsApiClient) {}
+ /**
+ * persist new or edited address
+ */
+ persistAddress$: any = createEffect(() =>
+ this.actions$.pipe(
+ ofType(externalPersonActions.persistAddressDetail),
+ map(action => action['payload']),
+ switchMap((address: Address) => {
+ return (address.id
+ ? this._personsApiClient.putAddressDetails(address.contactId, address.id, address)
+ : this._personsApiClient.postAddressDetails(address.contactId, address)
+ ).pipe(
+ map(() => {
+ this.store.dispatch(externalPersonActions.loadExternalPersonDetailAddresses({payload: address.contactId}));
+ return externalPersonActions.persistAddressDetailSuccess({ payload: address });
+ }),
+ catchError(error => of(externalPersonActions.persistAddressDetailFail({ payload: error })))
+ );
+ })
+ )
+);
+
+ /**
+ * delete address
+ */
+ deleteAddress$: any = createEffect(() =>
+ this.actions$.pipe(
+ ofType(externalPersonActions.deleteAddress),
+ map((action) => action['payload']),
+ switchMap((address: Address) => {
+ return this._personsApiClient.deleteAddress(address.contactId, address.id).pipe(
+ map(() => {
+ this.store.dispatch(externalPersonActions.loadExternalPersonDetailAddresses({payload: address.contactId}));
+ return externalPersonActions.deleteAddressSuccess();
+ }),
+ catchError(error => of(externalPersonActions.deleteAddressFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ /**
+ * load external person details communications data
+ */
+ getExternalPersonCommunicationsData$: any = createEffect(() =>
+ this.actions$.pipe(
+ ofType(externalPersonActions.loadExternalPersonDetailCommunicationsData),
+ switchMap((action: any) => {
+ return this._personsApiClient
+ .getCommunicationsData(action['payload']).pipe(
+ map((externalPersonCommunicationsData: Array<CommunicationsData>) =>
+ externalPersonActions.loadExternalPersonDetailCommunicationsDataSuccess({ payload: externalPersonCommunicationsData })
+ ),
+ catchError(error =>
+ of(externalPersonActions.loadExternalPersonDetailCommunicationsDataFail({ payload: error }))
+ )
+ );
+ })
+ )
+);
+
+/**
+* Load external person's communications data details
+*/
+getExternalPersonCommunicationsDataDetails$: any = createEffect(() =>
+ this.actions$.pipe(
+ ofType(externalPersonActions.loadExternalPersonDetailCommunicationsDataDetails),
+ switchMap(action => {
+ return this._personsApiClient
+ .getCommunicationsDataDetails(action.payload_contactId, action.payload_communicationsId)
+ .map((extPersonCommunicationsDataDetails: CommunicationsData) =>
+ externalPersonActions.loadExternalPersonDetailCommunicationsDataDetailsSuccess({ payload: extPersonCommunicationsDataDetails })
+ )
+ .catch(error =>
+ of(externalPersonActions.loadExternalPersonDetailCommunicationsDataDetailsFail({ payload: error }))
+ );
+ })
+ )
+);
+
+/**
+ * persist new or edited communications data
+ */
+persistCommunicationsData$: any = createEffect(() =>
+ this.actions$.pipe(
+ ofType(externalPersonActions.persistCommunicationsDataDetail),
+ map(action => action['payload']),
+ switchMap((address: CommunicationsData) => {
+ return (address.id
+ ? this._personsApiClient.putCommunicationsDataDetails(address.contactId, address.id, address)
+ : this._personsApiClient.postCommunicationsDataDetails(address.contactId, address)
+ ).pipe(
+ map(() => {
+ this.store.dispatch(externalPersonActions.loadExternalPersonDetailCommunicationsData({payload: address.contactId}));
+ return externalPersonActions.persistCommunicationsDataDetailSuccess({ payload: address });
+ }),
+ catchError(error => of(externalPersonActions.persistCommunicationsDataDetailFail({ payload: error })))
+ );
+ })
+ )
+);
+
+/**
+ * delete communications data
+ */
+deleteCommunicationsData$: any = createEffect(() =>
+ this.actions$.pipe(
+ ofType(externalPersonActions.deleteCommunicationsData),
+ map((action) => action['payload']),
+ switchMap((address: CommunicationsData) => {
+ return this._personsApiClient.deleteCommunicationsData(address.contactId, address.id).pipe(
+ map(() => {
+ this.store.dispatch(externalPersonActions.loadExternalPersonDetailCommunicationsData({payload: address.contactId}));
+ return externalPersonActions.deleteCommunicationsDataSuccess();
+ }),
+ catchError(error => of(externalPersonActions.deleteCommunicationsDataFail({ payload: error })))
+ );
+ })
+ )
+);
+
+
+ constructor(private actions$: Actions, private _personsApiClient: PersonsApiClient, private store: Store<State>) { }
}
diff --git a/src/app/shared/store/effects/persons/internal-person.effect.spec.ts b/src/app/shared/store/effects/persons/internal-person.effect.spec.ts
index 6335f39..a2c274b 100644
--- a/src/app/shared/store/effects/persons/internal-person.effect.spec.ts
+++ b/src/app/shared/store/effects/persons/internal-person.effect.spec.ts
@@ -10,26 +10,41 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { PersonsApiClient } from '@app/pages/persons/persons-api-client';
-import { InternalPersonEffect } from "@app/shared/store/effects/persons/internal-person.effect";
+import { PersonsApiClient } from '@pages/persons/persons-api-client';
+import { InternalPersonEffect } from "@shared/store/effects/persons/internal-person.effect";
import { Subject, of, throwError } from 'rxjs';
-import * as internalPersonActions from '@app/shared/store/actions/persons/internal-person.action';
-import { InternalPerson } from '@app/shared/models';
+import * as internalPersonActions from '@shared/store/actions/persons/internal-person.action';
+import { InternalPerson, CommunicationsData, Address } from '@shared/models';
describe('InternalPerson Effects', () => {
let effects: InternalPersonEffect;
let actions$: Subject<any>;
let apiClient: PersonsApiClient;
let apiResponse: any = null;
+ let store: any;
beforeEach(() => {
apiClient = {
getInternalPersonDetails() {},
putInternalPersonDetails: () => {},
postInternalPersonDetails: () => {},
+ getInternalPersons: () => {},
+ getAddressesDetails: () => {},
+ putAddressDetails: () => {},
+ postAddressDetails: () => {},
+ deleteAddress: () => {},
+ putCommunicationsDataDetails: () => {},
+ postCommunicationsDataDetails: () => {},
+ deleteCommunicationsData: () => {},
} as any;
+
actions$ = new Subject();
- effects = new InternalPersonEffect(actions$, apiClient);
+
+ store = {
+ dispatch() {}
+ }
+
+ effects = new InternalPersonEffect(actions$, apiClient, store);
});
it('should be truthy', () => {
@@ -65,7 +80,7 @@
actions$.next(internalPersonActions.persistInternalPersonDetail({payload: new InternalPerson({contactId: "1"})}));
});
- it('should equal postInternalPersonDetails after persistInternalPerson a new external person', (done) => {
+ it('should equal postInternalPersonDetails after persistInternalPerson a new internal person', (done) => {
apiResponse = new InternalPerson();
spyOn(apiClient, 'postInternalPersonDetails').and.returnValue(of(apiResponse));
effects.persistInternalPerson$.pipe().subscribe(result => {
@@ -92,4 +107,156 @@
done();
actions$.next(internalPersonActions.persistInternalPersonDetail({payload: new InternalPerson()}));
});
+
+ it('should equal loadInternalPersonsForUidSuccess after loadInternalPersonsForUid', (done) => {
+ apiResponse = [new InternalPerson()];
+ spyOn(apiClient, 'getInternalPersons').and.returnValue(of(apiResponse));
+ effects.getInternalPersonsForUid$.pipe().subscribe(result => {
+ expect(result).toEqual(internalPersonActions.loadInternalPersonsForUidSuccess({payload: [new InternalPerson()]}));
+ });
+ done();
+ actions$.next(internalPersonActions.loadInternalPersonsForUid({payload: new InternalPerson()}));
+ });
+
+ it('should equal loadInternalPersonsForUidFail after loadInternalPersonsForUid', (done) => {
+ spyOn(apiClient, 'getInternalPersons').and.returnValue(throwError('error'));
+ effects.getInternalPersonsForUid$.pipe().subscribe(result => {
+ expect(result).toEqual(internalPersonActions.loadInternalPersonsForUidFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(internalPersonActions.loadInternalPersonsForUid({payload: new InternalPerson()}));
+ });
+
+ it('should equal loadInternalPersonsForUserrefSuccess after loadInternalPersonsForUserref', (done) => {
+ apiResponse = [new InternalPerson()];
+ spyOn(apiClient, 'getInternalPersons').and.returnValue(of(apiResponse));
+ effects.getInternalPersonsForUserref$.pipe().subscribe(result => {
+ expect(result).toEqual(internalPersonActions.loadInternalPersonsForUserrefSuccess({payload: [new InternalPerson()]}));
+ });
+ done();
+ actions$.next(internalPersonActions.loadInternalPersonsForUserref({payload: new InternalPerson()}));
+ });
+
+ it('should equal loadInternalPersonsForUserrefFail after loadInternalPersonsForUserref', (done) => {
+ spyOn(apiClient, 'getInternalPersons').and.returnValue(throwError('error'));
+ effects.getInternalPersonsForUserref$.pipe().subscribe(result => {
+ expect(result).toEqual(internalPersonActions.loadInternalPersonsForUserrefFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(internalPersonActions.loadInternalPersonsForUserref({payload: new InternalPerson()}));
+ });
+
+ it('should equal persistAddressDetailSuccess after persistAddressDetail with given contactId', (done) => {
+ apiResponse = new Address({contactId: "1", id: "1"});
+ spyOn(apiClient, 'putAddressDetails').and.returnValue(of(apiResponse));
+ effects.persistAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(internalPersonActions.persistAddressDetailSuccess({payload: new Address({contactId: "1", id: "1"})}));
+ });
+ done();
+ actions$.next(internalPersonActions.persistAddressDetail({payload: new Address({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal persistAddressDetailSuccess after persistAddressDetail a new external person', (done) => {
+ apiResponse = new Address();
+ spyOn(apiClient, 'postAddressDetails').and.returnValue(of(apiResponse));
+ effects.persistAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(internalPersonActions.persistAddressDetailSuccess({payload: new Address()}));
+ });
+ done();
+ actions$.next(internalPersonActions.persistAddressDetail({payload: new Address()}));
+ });
+
+ it('should equal persistAddressDetailFail after putAddressDetails', (done) => {
+ spyOn(apiClient, 'putAddressDetails').and.returnValue(throwError('error'));
+ effects.persistAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(internalPersonActions.persistAddressDetailFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(internalPersonActions.persistAddressDetail({payload: new Address({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal persistAddressDetailFail after postAddressDetails', (done) => {
+ spyOn(apiClient, 'postAddressDetails').and.returnValue(throwError('error'));
+ effects.persistAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(internalPersonActions.persistAddressDetailFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(internalPersonActions.persistAddressDetail({payload: new Address ()}));
+ });
+
+ it('should equal deleteAddressSuccess after deleteAddress', (done) => {
+ apiResponse = new Address({contactId: "1", id: "1"});
+ spyOn(apiClient, 'deleteAddress').and.returnValue(of(apiResponse));
+ effects.deleteAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(internalPersonActions.deleteAddressSuccess());
+ });
+ done();
+ actions$.next(internalPersonActions.deleteAddress({payload: new Address ({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal deleteAddressFail after deleteAddress', (done) => {
+ spyOn(apiClient, 'deleteAddress').and.returnValue(throwError('error'));
+ effects.deleteAddress$.pipe().subscribe(result => {
+ expect(result).toEqual(internalPersonActions.deleteAddressFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(internalPersonActions.deleteAddress({payload: new Address ({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal persistCommunicationsDataDetailSuccess after persistCommunicationsDataDetail with given contactId', (done) => {
+ apiResponse = new CommunicationsData({contactId: "1", id: "1"});
+ spyOn(apiClient, 'putCommunicationsDataDetails').and.returnValue(of(apiResponse));
+ effects.persistCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(internalPersonActions.persistCommunicationsDataDetailSuccess({payload: new CommunicationsData({contactId: "1", id: "1"})}));
+ });
+ done();
+ actions$.next(internalPersonActions.persistCommunicationsDataDetail({payload: new CommunicationsData({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal persistCommunicationsDataDetailSuccess after persistCommunicationsDataDetail a new internal person', (done) => {
+ apiResponse = new CommunicationsData();
+ spyOn(apiClient, 'postCommunicationsDataDetails').and.returnValue(of(apiResponse));
+ effects.persistCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(internalPersonActions.persistCommunicationsDataDetailSuccess({payload: new CommunicationsData()}));
+ });
+ done();
+ actions$.next(internalPersonActions.persistCommunicationsDataDetail({payload: new CommunicationsData()}));
+ });
+
+ it('should equal persistCommunicationsDataDetailFail after putCommunicationsDataDetails', (done) => {
+ spyOn(apiClient, 'putCommunicationsDataDetails').and.returnValue(throwError('error'));
+ effects.persistCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(internalPersonActions.persistCommunicationsDataDetailFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(internalPersonActions.persistCommunicationsDataDetail({payload: new CommunicationsData({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal persistCommunicationsDataDetailFail after postCommunicationsDataDetails', (done) => {
+ spyOn(apiClient, 'postCommunicationsDataDetails').and.returnValue(throwError('error'));
+ effects.persistCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(internalPersonActions.persistCommunicationsDataDetailFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(internalPersonActions.persistCommunicationsDataDetail({payload: new CommunicationsData ()}));
+ });
+
+ it('should equal deleteCommunicationsDataSuccess after deleteCommunicationsData', (done) => {
+ apiResponse = new CommunicationsData({contactId: "1", id: "1"});
+ spyOn(apiClient, 'deleteCommunicationsData').and.returnValue(of(apiResponse));
+ effects.deleteCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(internalPersonActions.deleteCommunicationsDataSuccess());
+ });
+ done();
+ actions$.next(internalPersonActions.deleteCommunicationsData({payload: new CommunicationsData ({contactId: "1", id: "1"})}));
+ });
+
+ it('should equal deleteCommunicationsDataFail after deleteCommunicationsData', (done) => {
+ spyOn(apiClient, 'deleteCommunicationsData').and.returnValue(throwError('error'));
+ effects.deleteCommunicationsData$.pipe().subscribe(result => {
+ expect(result).toEqual(internalPersonActions.deleteCommunicationsDataFail({payload: 'error'}));
+ });
+ done();
+ actions$.next(internalPersonActions.deleteCommunicationsData({payload: new CommunicationsData ({contactId: "1", id: "1"})}));
+ });
});
diff --git a/src/app/shared/store/effects/persons/internal-person.effect.ts b/src/app/shared/store/effects/persons/internal-person.effect.ts
index 4c3af4b..116d40d 100644
--- a/src/app/shared/store/effects/persons/internal-person.effect.ts
+++ b/src/app/shared/store/effects/persons/internal-person.effect.ts
@@ -1,15 +1,15 @@
- /********************************************************************************
- * Copyright (c) 2020 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- ********************************************************************************/
+/********************************************************************************
+* Copyright (c) 2020 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+********************************************************************************/
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
@@ -17,21 +17,23 @@
import { Injectable } from '@angular/core';
import { catchError, map, switchMap } from 'rxjs/operators';
import { createEffect, ofType, Actions } from '@ngrx/effects';
-import * as internalPersonActions from '@app/shared/store/actions/persons/internal-person.action';
-import { PersonsApiClient } from '@app/pages/persons/persons-api-client';
-import { InternalPerson } from '@shared/models';
+import * as internalPersonActions from '@shared/store/actions/persons/internal-person.action';
+import { PersonsApiClient } from '@pages/persons/persons-api-client';
+import { InternalPerson, CommunicationsData, Address } from '@shared/models';
+import { InternalPersonInterface } from '@shared/models/persons/internal-person-arguments.interface';
+import { Store } from '@ngrx/store';
+import { State } from '@shared/store';
@Injectable()
export class InternalPersonEffect {
-
/**
- * load external person details
+ * load internal person details
*/
getInternalPerson$: any = createEffect(() =>
- this.actions$.pipe(
+ this._actions$.pipe(
ofType(internalPersonActions.loadInternalPersonDetail),
switchMap(action => {
- return this.personsApiClient
+ return this._personsApiClient
.getInternalPersonDetails(action['payload'])
.map((internalPerson: InternalPerson) => internalPersonActions.loadInternalPersonDetailSuccess({ payload: internalPerson }))
.catch(error => of(internalPersonActions.loadInternalPersonDetailFail({ payload: error })));
@@ -40,16 +42,35 @@
);
/**
- * persist new or edited external person
+ * Load internal person's addresses details
+ */
+ getInternalPersonAddressDetails$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(internalPersonActions.loadInternalPersonDetailAddressDetails),
+ switchMap(action => {
+ return this._personsApiClient
+ .getAddressesDetails(action.payload_contactId, action.payload_addressId)
+ .map((internalPersonAdressDetails: Address) =>
+ internalPersonActions.loadInternalPersonDetailAddressDetailsSuccess({ payload: internalPersonAdressDetails })
+ )
+ .catch(error =>
+ of(internalPersonActions.loadInternalPersonDetailAddressDetailsFail({ payload: error }))
+ );
+ })
+ )
+ );
+
+ /**
+ * persist new or edited internal person
*/
persistInternalPerson$: any = createEffect(() =>
- this.actions$.pipe(
+ this._actions$.pipe(
ofType(internalPersonActions.persistInternalPersonDetail),
map(action => action['payload']),
switchMap((internalPersonDetails: InternalPerson) => {
return (internalPersonDetails.contactId
- ? this.personsApiClient.putInternalPersonDetails(internalPersonDetails.contactId, internalPersonDetails)
- : this.personsApiClient.postInternalPersonDetails(internalPersonDetails)
+ ? this._personsApiClient.putInternalPersonDetails(internalPersonDetails.contactId, internalPersonDetails)
+ : this._personsApiClient.postInternalPersonDetails(internalPersonDetails)
).pipe(
map((internalPerson: InternalPerson) => {
return internalPersonActions.persistInternalPersonDetailSuccess({ payload: internalPerson });
@@ -60,5 +81,178 @@
)
);
- constructor(private actions$: Actions, private personsApiClient: PersonsApiClient) {}
+ /**
+ * load internal persons for uid
+ */
+ getInternalPersonsForUid$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(internalPersonActions.loadInternalPersonsForUid),
+ map(action => action['payload']),
+ switchMap((request: InternalPersonInterface) => {
+ return this._personsApiClient.getInternalPersons(request).pipe(
+ map(persons => internalPersonActions.loadInternalPersonsForUidSuccess({ payload: persons })),
+ catchError(error => of(internalPersonActions.loadInternalPersonsForUidFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ /**
+ * load internal persons for userref
+ */
+ getInternalPersonsForUserref$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(internalPersonActions.loadInternalPersonsForUserref),
+ map(action => action['payload']),
+ switchMap((request: InternalPersonInterface) => {
+ return this._personsApiClient.getInternalPersons(request).pipe(
+ map(persons => internalPersonActions.loadInternalPersonsForUserrefSuccess({ payload: persons })),
+ catchError(error => of(internalPersonActions.loadInternalPersonsForUserrefFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ /**
+ * load internal person details Addresses
+ */
+ getInternalPersonAddresses$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(internalPersonActions.loadInternalPersonDetailAddresses),
+ switchMap((action: any) => {
+ return this._personsApiClient
+ .getAddresses(action['payload']).pipe(
+ map((internalPersonAddresses: Array<Address>) =>
+ internalPersonActions.loadInternalPersonDetailAddressesSuccess({ payload: internalPersonAddresses })
+ ),
+ catchError(error =>
+ of(internalPersonActions.loadInternalPersonDetailAddressesFail({ payload: error }))
+ )
+ );
+ })
+ )
+ );
+
+ /**
+ * persist new or edited address
+ */
+ persistAddress$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(internalPersonActions.persistAddressDetail),
+ map(action => action['payload']),
+ switchMap((address: Address) => {
+ return (address.id
+ ? this._personsApiClient.putAddressDetails(address.contactId, address.id, address)
+ : this._personsApiClient.postAddressDetails(address.contactId, address)
+ ).pipe(
+ map(() => {
+ this.store.dispatch(internalPersonActions.loadInternalPersonDetailAddresses({ payload: address.contactId }));
+ return internalPersonActions.persistAddressDetailSuccess({ payload: address });
+ }),
+ catchError(error => of(internalPersonActions.persistAddressDetailFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ /**
+ * delete address
+ */
+ deleteAddress$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(internalPersonActions.deleteAddress),
+ map((action) => action['payload']),
+ switchMap((address: Address) => {
+ return this._personsApiClient.deleteAddress(address.contactId, address.id).pipe(
+ map(() => {
+ this.store.dispatch(internalPersonActions.loadInternalPersonDetailAddresses({ payload: address.contactId }));
+ return internalPersonActions.deleteAddressSuccess();
+ }),
+ catchError(error => of(internalPersonActions.deleteAddressFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ /**
+ * load internal person details communications data
+ */
+ getInternalPersonCommunicationsData$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(internalPersonActions.loadInternalPersonDetailCommunicationsData),
+ switchMap((action: any) => {
+ return this._personsApiClient
+ .getCommunicationsData(action['payload']).pipe(
+ map((internalPersonCommunicationsData: Array<CommunicationsData>) =>
+ internalPersonActions.loadInternalPersonDetailCommunicationsDataSuccess({ payload: internalPersonCommunicationsData })
+ ),
+ catchError(error =>
+ of(internalPersonActions.loadInternalPersonDetailCommunicationsDataFail({ payload: error }))
+ )
+ );
+ })
+ )
+ );
+
+ /**
+ * Load internal person's communications data details
+ */
+ getInternalPersonCommunicationsDataDetails$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(internalPersonActions.loadInternalPersonDetailCommunicationsDataDetails),
+ switchMap(action => {
+ return this._personsApiClient
+ .getCommunicationsDataDetails(action.payload_contactId, action.payload_communicationsId)
+ .map((extPersonCommunicationsDataDetails: CommunicationsData) =>
+ internalPersonActions.loadInternalPersonDetailCommunicationsDataDetailsSuccess({ payload: extPersonCommunicationsDataDetails })
+ )
+ .catch(error =>
+ of(internalPersonActions.loadInternalPersonDetailCommunicationsDataDetailsFail({ payload: error }))
+ );
+ })
+ )
+ );
+
+ /**
+ * persist new or edited communications data
+ */
+ persistCommunicationsData$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(internalPersonActions.persistCommunicationsDataDetail),
+ map(action => action['payload']),
+ switchMap((address: CommunicationsData) => {
+ return (address.id
+ ? this._personsApiClient.putCommunicationsDataDetails(address.contactId, address.id, address)
+ : this._personsApiClient.postCommunicationsDataDetails(address.contactId, address)
+ ).pipe(
+ map(() => {
+ this.store.dispatch(internalPersonActions.loadInternalPersonDetailCommunicationsData({ payload: address.contactId }));
+ return internalPersonActions.persistCommunicationsDataDetailSuccess({ payload: address });
+ }),
+ catchError(error => of(internalPersonActions.persistCommunicationsDataDetailFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ /**
+ * delete communications data
+ */
+ deleteCommunicationsData$: any = createEffect(() =>
+ this._actions$.pipe(
+ ofType(internalPersonActions.deleteCommunicationsData),
+ map((action) => action['payload']),
+ switchMap((address: CommunicationsData) => {
+ return this._personsApiClient.deleteCommunicationsData(address.contactId, address.id).pipe(
+ map(() => {
+ this.store.dispatch(internalPersonActions.loadInternalPersonDetailCommunicationsData({ payload: address.contactId }));
+ return internalPersonActions.deleteCommunicationsDataSuccess();
+ }),
+ catchError(error => of(internalPersonActions.deleteCommunicationsDataFail({ payload: error })))
+ );
+ })
+ )
+ );
+
+ constructor(private _actions$: Actions, private _personsApiClient: PersonsApiClient, private store: Store<State>) { }
}
diff --git a/src/app/shared/store/effects/salutations.effects.spec.ts b/src/app/shared/store/effects/salutations.effects.spec.ts
deleted file mode 100644
index 81f1932..0000000
--- a/src/app/shared/store/effects/salutations.effects.spec.ts
+++ /dev/null
@@ -1,81 +0,0 @@
- /********************************************************************************
- * Copyright (c) 2020 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- ********************************************************************************/
-import { take } from 'rxjs/operators';
-import { SalutationsEffects } from '@shared/store/effects/salutations.effect';
-import { Subject, of, throwError } from 'rxjs';
-import { Salutation } from '@app/shared/models';
-import * as salutationsActions from '@shared/store/actions/salutations.action';
-import { SalutationsApiClient } from '@app/pages/admin/salutations/salutations-api-client';
-import { Store } from '@ngrx/store';
-
-
-describe('Salutations Effects', () => {
-
- let effects: SalutationsEffects;
- let actions$: Subject<any>;
- let apiClient: SalutationsApiClient;
- let store: Store<any>;
- let apiResponse: any = null;
-
- beforeEach(() => {
- apiClient = {
- getSalutations() {},
- getSalutationDetails() {}
- } as any;
- actions$ = new Subject();
- effects = new SalutationsEffects(actions$, apiClient, store);
- });
-
- it('should be truthy', () => {
- expect(effects).toBeTruthy();
- });
-
- it('should equal loadSalutationsSuccess after getSalutations', (done) => {
- apiResponse = [new Salutation({id: "1"})];
- spyOn(apiClient, 'getSalutations').and.returnValue(of(apiResponse));
- effects.getSalutations$.pipe(take(1)).subscribe(result => {
- expect(result).toEqual(salutationsActions.loadSalutationsSuccess({payload: apiResponse}));
- });
- done();
- actions$.next(salutationsActions.loadSalutations());
- });
-
- it('should equal loadSalutationsFail after getSalutations Error', (done) => {
- spyOn(apiClient, 'getSalutations').and.returnValue(throwError('x'));
- effects.getSalutations$.pipe(take(1)).subscribe(result => {
- expect(result).toEqual(salutationsActions.loadSalutationsFail({payload: 'x'}));
- });
- done();
- actions$.next(salutationsActions.loadSalutations());
- });
-
- it('should equal loadSalutationSuccess after getSalutation', (done) => {
- apiResponse = new Salutation({id: "1"});
- spyOn(apiClient, 'getSalutationDetails').and.returnValue(of(apiResponse));
- effects.getSalutation$.pipe(take(1)).subscribe(result => {
- expect(result).toEqual(salutationsActions.loadSalutationSuccess({payload: apiResponse}));
- });
- done();
- actions$.next(salutationsActions.loadSalutation({payload: "1"}));
- });
-
- it('should equal loadSalutationFail after getSalutation Error', (done) => {
- spyOn(apiClient, 'getSalutationDetails').and.returnValue(throwError('x'));
- effects.getSalutation$.pipe(take(1)).subscribe(result => {
- expect(result).toEqual(salutationsActions.loadSalutationFail({payload: 'x'}));
- });
- done();
- actions$.next(salutationsActions.loadSalutation({payload: "1"}));
- });
-
-});
diff --git a/src/app/shared/store/index.ts b/src/app/shared/store/index.ts
index 50d1280..fe9121d 100644
--- a/src/app/shared/store/index.ts
+++ b/src/app/shared/store/index.ts
@@ -10,8 +10,6 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { Salutation } from '@shared/models/salutation.model';
-import { createSelector } from 'reselect';
/**
* Every reducer module's default export is the reducer function itself. In
* addition, each module should export a type or interface that describes
@@ -19,16 +17,35 @@
* notation packages up all of the exports into a single object.
*/
import * as fromSettings from '@shared/store/reducers/settings.reducer';
-import * as fromContacts from '@shared/store/reducers/contacts/contacts.reducer';
import * as fromContactsPage from '@shared/store/reducers/contacts/contacts-page.reducer';
-import * as fromExternalPersonForm from '@app/shared/store/reducers/persons/external-person/external-person-details-form.reducer';
-import * as fromInternalPersonForm from '@app/shared/store/reducers/persons/internal-person/internal-person-details-form.reducer';
-import { ExternalPerson, InternalPerson } from '@shared/models';
+import * as fromExternalPersonForm from '@shared/store/reducers/persons/external-person/external-person-details-form.reducer';
+import * as fromInternalPersonForm from '@shared/store/reducers/persons/internal-person/internal-person-details-form.reducer';
+import { CommunicationType, ExternalPerson, InternalPerson,Address, Company, Salutation, CommunicationsData, PersonType, AddressType } from '@shared/models';
import { FormGroupState } from 'ngrx-forms';
import { createFeatureSelector } from '@ngrx/store';
-import * as fromSalutations from '@shared/store/reducers/salutations/salutations.reducer';
-import * as fromSalutationsDetailForm from '@shared/store/reducers/salutations/salutations-details-form.reducer';
-
+import { createSelector } from 'reselect';
+/* admin imports */
+import * as fromSalutations from '@shared/store/reducers/admin/salutations.reducer';
+import * as fromSalutationsDetailForm from '@shared/store/reducers/admin/salutations-details-form.reducer';
+import * as fromCommunicationTypes from '@shared/store/reducers/admin/communication-types.reducer';
+import * as fromCommunicationTypesDetailForm from '@shared/store/reducers/admin/communication-types-details-form.reducer';
+import * as fromExternalPersonDetailsAddressesDetailsForm from '@shared/store/reducers/persons/external-person/addresses-details-form.reducer';
+import * as fromInternalPersonDetailsAddressesDetailsForm from '@shared/store/reducers/persons/internal-person/addresses-details-form.reducer';
+import * as fromCompanyDetailsAddressesDetailsForm from '@shared/store/reducers/company/addresses-details-form.reducer';
+import * as fromCompanyDetailForm from '@shared/store/reducers/company/company-details-form.reducer';
+import * as fromPersonTypes from '@shared/store/reducers/admin/person-types.reducer';
+import * as fromPersonTypesDetailForm from '@shared/store/reducers/admin/person-types-details-form.reducer';
+import * as fromAddressTypes from '@shared/store/reducers/admin/address-types.reducer';
+import * as fromAddressTypesDetailForm from '@shared/store/reducers/admin/address-types-details-form.reducer';
+import * as fromExternalPersonDetailsAddresses from '@shared/store/reducers/persons/external-person/addresses.reducer';
+import * as fromExternalPersonDetailsCommunicationsData from '@shared/store/reducers/persons/external-person/communications-data.reducer';
+import * as fromExternalPersonDetailsCommunicationsDataDetailsForm from '@shared/store/reducers/persons/external-person/communications-data-details-form.reducer';
+import * as fromInternalPersonDetailsCommunicationsData from '@shared/store/reducers/persons/internal-person/communications-data.reducer';
+import * as fromInternalPersonDetailsCommunicationsDataDetailsForm from '@shared/store/reducers/persons/internal-person/communications-data-details-form.reducer';
+import * as fromCompanyDetailsCommunicationsData from '@shared/store/reducers/company/communications-data.reducer';
+import * as fromCompanyDetailsCommunicationsDataDetailsForm from '@shared/store/reducers/company/communications-data-details-form.reducer';
+import * as fromInternalPersonDetailsAddresses from '@shared/store/reducers/persons/internal-person/addresses.reducer';
+import * as fromCompanyDetailsAddresses from '@shared/store/reducers/company/addresses.reducer';
/**
* We treat each reducer like a table in a database. This means
@@ -36,25 +53,39 @@
*/
export interface State {
settings: fromSettings.State;
- contacts: fromContacts.State;
contactsPage: fromContactsPage.State;
}
export interface PersonState {
externalPersonDetailsForm: FormGroupState<ExternalPerson>;
+ externalPersonDetailsAddresses: fromExternalPersonDetailsAddresses.State;
+ internalPersonDetailsAddresses: fromInternalPersonDetailsAddresses.State;
+ externalPersonDetailsAddressesDetailsForm: FormGroupState<Address>;
+ internalPersonDetailsAddressesDetailsForm: FormGroupState<Address>;
internalPersonDetailsForm: FormGroupState<InternalPerson>;
-}
-
-export const selectPersonState = createFeatureSelector<PersonState>('personsData');
-
-export const personsReducers = {
- externalPersonDetailsForm: fromExternalPersonForm.reducer,
- internalPersonDetailsForm: fromInternalPersonForm.reducer,
+ externalPersonDetailsCommunicationsData: fromExternalPersonDetailsCommunicationsData.State;
+ externalPersonDetailsCommunicationsDataDetailsForm: FormGroupState<CommunicationsData>;
+ internalPersonDetailsCommunicationsData: fromInternalPersonDetailsCommunicationsData.State;
+ internalPersonDetailsCommunicationsDataDetailsForm: FormGroupState<CommunicationsData>;
}
export interface AdminState {
salutations: fromSalutations.State;
salutationsDetailForm: FormGroupState<Salutation>;
+ communicationTypes: fromCommunicationTypes.State;
+ communicationTypesDetailForm: FormGroupState<CommunicationType>;
+ personTypes: fromPersonTypes.State;
+ personTypesDetailForm: FormGroupState<PersonType>;
+ addressTypes: fromAddressTypes.State;
+ addressTypesDetailForm: FormGroupState<AddressType>;
+}
+
+export interface CompanyState {
+ companyDetailsForm: FormGroupState<Company>;
+ companyDetailsCommunicationsData: fromCompanyDetailsCommunicationsData.State;
+ companyDetailsCommunicationsDataDetailsForm: FormGroupState<CommunicationsData>;
+ companyDetailsAddresses: fromCompanyDetailsAddresses.State;
+ companyDetailsAddressesDetailsForm: FormGroupState<Address>;
}
/**
@@ -66,15 +97,42 @@
*/
export const reducers = {
settings: fromSettings.reducer,
- contacts: fromContacts.reducer,
contactsPage: fromContactsPage.reducer,
};
export const adminReducers = {
salutations: fromSalutations.reducer,
- salutationsDetailForm: fromSalutationsDetailForm.reducer
+ salutationsDetailForm: fromSalutationsDetailForm.reducer,
+ communicationTypes: fromCommunicationTypes.reducer,
+ communicationTypesDetailForm: fromCommunicationTypesDetailForm.reducer,
+ personTypes: fromPersonTypes.reducer,
+ personTypesDetailForm: fromPersonTypesDetailForm.reducer,
+ addressTypes: fromAddressTypes.reducer,
+ addressTypesDetailForm: fromAddressTypesDetailForm.reducer,
};
+export const personsReducers = {
+ externalPersonDetailsForm: fromExternalPersonForm.reducer,
+ externalPersonDetailsAddresses: fromExternalPersonDetailsAddresses.reducer,
+ internalPersonDetailsAddresses: fromInternalPersonDetailsAddresses.reducer,
+ externalPersonDetailsAddressesDetailsForm: fromExternalPersonDetailsAddressesDetailsForm.reducer,
+ internalPersonDetailsAddressesDetailsForm: fromInternalPersonDetailsAddressesDetailsForm.reducer,
+ internalPersonDetailsForm: fromInternalPersonForm.reducer,
+ externalPersonDetailsCommunicationsData: fromExternalPersonDetailsCommunicationsData.reducer,
+ externalPersonDetailsCommunicationsDataDetailsForm: fromExternalPersonDetailsCommunicationsDataDetailsForm.reducer,
+ internalPersonDetailsCommunicationsData: fromInternalPersonDetailsCommunicationsData.reducer,
+ internalPersonDetailsCommunicationsDataDetailsForm: fromInternalPersonDetailsCommunicationsDataDetailsForm.reducer,
+}
+
+export const companyReducers = {
+ companyDetailsForm: fromCompanyDetailForm.reducer,
+ companyDetailsCommunicationsData: fromCompanyDetailsCommunicationsData.reducer,
+ companyDetailsCommunicationsDataDetailsForm: fromCompanyDetailsCommunicationsDataDetailsForm.reducer,
+ companyDetailsAddresses: fromCompanyDetailsAddresses.reducer,
+ companyDetailsAddressesDetailsForm: fromCompanyDetailsAddressesDetailsForm.reducer,
+
+}
+
/**
* Every reducer module exports selector functions, however child reducers
* have no knowledge of the overall state tree. To make them useable, we
@@ -91,14 +149,6 @@
export const getAvailableLanguages = createSelector(getSettingsState, fromSettings.getAvailableLanguages);
/**
- * Contacts store functions
- */
-export const getContactsState = (state: State) => state.contacts;
-export const getContactsLoaded = createSelector(getContactsState, fromContacts.getLoaded);
-export const getContactsLoading = createSelector(getContactsState, fromContacts.getLoading);
-export const getContactsFailed = createSelector(getContactsState, fromContacts.getFailed);
-export const getContactsData = createSelector(getContactsState, fromContacts.getData);
-/**
* Contacts Page store functions
*/
export const getContactsPageState = (state: State) => state.contactsPage;
@@ -111,13 +161,10 @@
*/
export const getUser = createSelector(getSettingsState, fromSettings.getUser);
/**
- * Admin store functions
+ * Persons store functions
*/
-export const selectAdminState = createFeatureSelector<AdminState>('admin');
+export const selectPersonState = createFeatureSelector<PersonState>('personsData');
-/**
- * ExternalPersonDetails store functions
- */
export const selectExternalPersonDetails = createSelector(
selectPersonState,
(state: PersonState) => state.externalPersonDetailsForm
@@ -126,9 +173,7 @@
selectExternalPersonDetails,
fromExternalPersonForm.getFormState
);
-/**
- * InternalPersonDetails store functions
- */
+
export const selectInternalPersonDetails = createSelector(
selectPersonState,
(state: PersonState) => state.internalPersonDetailsForm
@@ -137,9 +182,72 @@
selectInternalPersonDetails,
fromInternalPersonForm.getFormState
);
+
/**
- * SalutationDetails store functions
+ * External Persons Addresses store functions
*/
+export const selectExternalPersonAddresses = createSelector(
+ selectPersonState,
+ (state: PersonState) => state.externalPersonDetailsAddresses
+);
+export const getExternalPersonAddressesLoaded = createSelector(
+ selectExternalPersonAddresses,
+ fromExternalPersonDetailsAddresses.getLoaded
+);
+export const getExternalPersonAddressesLoading = createSelector(
+ selectExternalPersonAddresses,
+ fromExternalPersonDetailsAddresses.getLoading
+);
+export const getExternalPersonAddressesFailed = createSelector(
+ selectExternalPersonAddresses,
+ fromExternalPersonDetailsAddresses.getFailed
+);
+export const getExternalPersonAddressesData = createSelector(
+ selectExternalPersonAddresses,
+ fromExternalPersonDetailsAddresses.getData
+);
+
+/**
+ * External Person Addresses Details store functions
+ */
+export const selectExternalPersonAddressesDetails = createSelector(
+ selectPersonState,
+ (state: PersonState) => state.externalPersonDetailsAddressesDetailsForm
+);
+export const getExternalPersonAddressesDetails = createSelector(
+ selectExternalPersonAddressesDetails,
+ fromExternalPersonDetailsAddressesDetailsForm.getFormState
+);
+
+/**
+ * Company store functions
+ */
+export const selectCompanyState = createFeatureSelector<CompanyState>('companyData');
+
+export const selectCompanyDetails = createSelector(
+ selectCompanyState,
+ (state: CompanyState) => state.companyDetailsForm
+);
+export const getCompanyDetails = createSelector(
+ selectCompanyDetails,
+ fromCompanyDetailForm.getFormState
+);
+
+/**
+ * Admin store functions
+ */
+export const selectAdminState = createFeatureSelector<AdminState>('admin');
+
+// salutations list
+export const selectSalutations = createSelector(
+ selectAdminState,
+ (state: AdminState) => state.salutations
+);
+export const getSalutationsLoaded = createSelector(selectSalutations, fromSalutations.getLoaded);
+export const getSalutationsLoading = createSelector(selectSalutations, fromSalutations.getLoading);
+export const getSalutationsFailed = createSelector(selectSalutations, fromSalutations.getFailed);
+export const getSalutationsData = createSelector(selectSalutations, fromSalutations.getData);
+// salutations details
export const selectSalutationDetails = createSelector(
selectAdminState,
(state: AdminState) => state.salutationsDetailForm
@@ -148,13 +256,238 @@
selectSalutationDetails,
fromSalutationsDetailForm.getFormState
);
-
-export const selectSalutations = createSelector(
+// communication types list
+export const selectCommunicationTypes = createSelector(
selectAdminState,
- (state: AdminState) => state.salutations
+ (state: AdminState) => state.communicationTypes
);
-// export const getSalutationsState = (state: State) => state.salutations;
-export const getSalutationsLoaded = createSelector(selectSalutations, fromSalutations.getLoaded);
-export const getSalutationsLoading = createSelector(selectSalutations, fromSalutations.getLoading);
-export const getSalutationsFailed = createSelector(selectSalutations, fromSalutations.getFailed);
-export const getSalutationsData = createSelector(selectSalutations, fromSalutations.getData);
+
+export const getCommunicationTypesLoaded = createSelector(selectCommunicationTypes, fromCommunicationTypes.getLoaded);
+export const getCommunicationTypesLoading = createSelector(selectCommunicationTypes, fromCommunicationTypes.getLoading);
+export const getCommunicationTypesFailed = createSelector(selectCommunicationTypes, fromCommunicationTypes.getFailed);
+export const getCommunicationTypesData = createSelector(selectCommunicationTypes, fromCommunicationTypes.getData);
+// communication types details
+export const selectCommunicationTypesDetails = createSelector(
+ selectAdminState,
+ (state: AdminState) => state.communicationTypesDetailForm
+);
+export const getCommunicationTypesDetails = createSelector(
+ selectCommunicationTypesDetails,
+ fromCommunicationTypesDetailForm.getFormState
+);
+// person types list
+export const selectPersonTypes = createSelector(
+ selectAdminState,
+ (state: AdminState) => state.personTypes
+);
+export const getPersonTypesLoaded = createSelector(selectPersonTypes, fromPersonTypes.getLoaded);
+export const getPersonTypesLoading = createSelector(selectPersonTypes, fromPersonTypes.getLoading);
+export const getPersonTypesFailed = createSelector(selectPersonTypes, fromPersonTypes.getFailed);
+export const getPersonTypesData = createSelector(selectPersonTypes, fromPersonTypes.getData);
+// person types details
+export const selectPersonTypesDetails = createSelector(
+ selectAdminState,
+ (state: AdminState) => state.personTypesDetailForm
+);
+export const getPersonTypesDetails = createSelector(
+ selectPersonTypesDetails,
+ fromPersonTypesDetailForm.getFormState
+);
+// address types list
+export const selectAddressTypes = createSelector(
+ selectAdminState,
+ (state: AdminState) => state.addressTypes
+);
+export const getAddressTypesLoaded = createSelector(selectAddressTypes, fromAddressTypes.getLoaded);
+export const getAddressTypesLoading = createSelector(selectAddressTypes, fromAddressTypes.getLoading);
+export const getAddressTypesFailed = createSelector(selectAddressTypes, fromAddressTypes.getFailed);
+export const getAddressTypesData = createSelector(selectAddressTypes, fromAddressTypes.getData);
+// address types details
+export const selectAddressTypesDetails = createSelector(
+ selectAdminState,
+ (state: AdminState) => state.addressTypesDetailForm
+);
+export const getAddressTypesDetails = createSelector(
+ selectAddressTypesDetails,
+ fromAddressTypesDetailForm.getFormState
+);
+
+/**
+ * External Persons communications data store functions
+ */
+export const selectExternalPersonCommunicationsData = createSelector(
+ selectPersonState,
+ (state: PersonState) => state.externalPersonDetailsCommunicationsData
+);
+export const getExternalCommunicationsDataLoaded = createSelector(
+ selectExternalPersonCommunicationsData,
+ fromExternalPersonDetailsCommunicationsData.getLoaded
+);
+export const getExternalCommunicationsDataLoading = createSelector(
+ selectExternalPersonCommunicationsData,
+ fromExternalPersonDetailsCommunicationsData.getLoading
+);
+export const getExternalCommunicationsDataFailed = createSelector(
+ selectExternalPersonCommunicationsData,
+ fromExternalPersonDetailsCommunicationsData.getFailed
+);
+export const getExternalCommunicationsDataData = createSelector(
+ selectExternalPersonCommunicationsData,
+ fromExternalPersonDetailsCommunicationsData.getData
+);
+
+/**
+ * External Person CommunicationsData Details store functions
+ */
+export const selectExternalPersonCommunicationsDataDetails = createSelector(
+ selectPersonState,
+ (state: PersonState) => state.externalPersonDetailsCommunicationsDataDetailsForm
+);
+export const getExternalPersonCommunicationsDataDetails = createSelector(
+ selectExternalPersonCommunicationsDataDetails,
+ fromExternalPersonDetailsCommunicationsDataDetailsForm.getFormState
+);
+
+/**
+ * Internal Persons communications data store functions
+ */
+export const selectInternalPersonCommunicationsData = createSelector(
+ selectPersonState,
+ (state: PersonState) => state.internalPersonDetailsCommunicationsData
+);
+export const getInternalCommunicationsDataLoaded = createSelector(
+ selectInternalPersonCommunicationsData,
+ fromInternalPersonDetailsCommunicationsData.getLoaded
+);
+export const getInternalCommunicationsDataLoading = createSelector(
+ selectInternalPersonCommunicationsData,
+ fromInternalPersonDetailsCommunicationsData.getLoading
+);
+export const getInternalCommunicationsDataFailed = createSelector(
+ selectInternalPersonCommunicationsData,
+ fromInternalPersonDetailsCommunicationsData.getFailed
+);
+export const getInternalCommunicationsDataData = createSelector(
+ selectInternalPersonCommunicationsData,
+ fromInternalPersonDetailsCommunicationsData.getData
+);
+
+/**
+ * Internal Person CommunicationsData Details store functions
+ */
+export const selectInternalPersonCommunicationsDataDetails = createSelector(
+ selectPersonState,
+ (state: PersonState) => state.internalPersonDetailsCommunicationsDataDetailsForm
+);
+export const getInternalPersonCommunicationsDataDetails = createSelector(
+ selectInternalPersonCommunicationsDataDetails,
+ fromInternalPersonDetailsCommunicationsDataDetailsForm.getFormState
+);
+
+/**
+ * Company communications data store functions
+ */
+export const selectCompanyCommunicationsData = createSelector(
+ selectCompanyState,
+ (state: CompanyState) => state.companyDetailsCommunicationsData
+);
+export const getCompanyCommunicationsDataLoaded = createSelector(
+ selectCompanyCommunicationsData,
+ fromCompanyDetailsCommunicationsData.getLoaded
+);
+export const getCompanyCommunicationsDataLoading = createSelector(
+ selectCompanyCommunicationsData,
+ fromCompanyDetailsCommunicationsData.getLoading
+);
+export const getCompanyCommunicationsDataFailed = createSelector(
+ selectCompanyCommunicationsData,
+ fromCompanyDetailsCommunicationsData.getFailed
+);
+export const getCompanyCommunicationsDataData = createSelector(
+ selectCompanyCommunicationsData,
+ fromCompanyDetailsCommunicationsData.getData
+);
+
+/**
+ * Company CommunicationsData Details store functions
+ */
+export const selectCompanyCommunicationsDataDetails = createSelector(
+ selectCompanyState,
+ (state: CompanyState) => state.companyDetailsCommunicationsDataDetailsForm
+);
+export const getCompanyCommunicationsDataDetails = createSelector(
+ selectCompanyCommunicationsDataDetails,
+ fromCompanyDetailsCommunicationsDataDetailsForm.getFormState
+);
+/**
+ * Internal Persons Addresses store functions
+ */
+export const selectInternalPersonAddresses = createSelector(
+ selectPersonState,
+ (state: PersonState) => state.internalPersonDetailsAddresses
+);
+export const getInternalAddressesLoaded = createSelector(
+ selectInternalPersonAddresses,
+ fromInternalPersonDetailsAddresses.getLoaded
+);
+export const getInternalAddressesLoading = createSelector(
+ selectInternalPersonAddresses,
+ fromInternalPersonDetailsAddresses.getLoading
+);
+export const getInternalAddressesFailed = createSelector(
+ selectInternalPersonAddresses,
+ fromInternalPersonDetailsAddresses.getFailed
+);
+export const getInternalAddressesData = createSelector(
+ selectInternalPersonAddresses,
+ fromInternalPersonDetailsAddresses.getData
+);
+
+/**
+ * Internal Person Addresses Details store functions
+ */
+export const selectInternalPersonAddressesDetails = createSelector(
+ selectPersonState,
+ (state: PersonState) => state.internalPersonDetailsAddressesDetailsForm
+);
+export const getInternalPersonAddressesDetails = createSelector(
+ selectInternalPersonAddressesDetails,
+ fromInternalPersonDetailsAddressesDetailsForm.getFormState
+);
+
+/**
+ * Company Addresses store functions
+ */
+export const selectCompanyAddresses = createSelector(
+ selectCompanyState,
+ (state: CompanyState) => state.companyDetailsAddresses
+);
+export const getCompanyAddressesLoaded = createSelector(
+ selectCompanyAddresses,
+ fromCompanyDetailsAddresses.getLoaded
+);
+export const getCompanyAddressesLoading = createSelector(
+ selectCompanyAddresses,
+ fromCompanyDetailsAddresses.getLoading
+);
+export const getCompanyAddressesFailed = createSelector(
+ selectCompanyAddresses,
+ fromCompanyDetailsAddresses.getFailed
+);
+export const getCompanyAddressesData = createSelector(
+ selectCompanyAddresses,
+ fromCompanyDetailsAddresses.getData
+);
+
+/**
+ * Company Addresses Details store functions
+ */
+export const selectCompanyAddressesDetails = createSelector(
+ selectCompanyState,
+ (state: CompanyState) => state.companyDetailsAddressesDetailsForm
+);
+export const getCompanyAddressesDetails = createSelector(
+ selectCompanyAddressesDetails,
+ fromCompanyDetailsAddressesDetailsForm.getFormState
+);
+
diff --git a/src/app/shared/store/reducers/admin/address-types-details-form.reducer.spec.ts b/src/app/shared/store/reducers/admin/address-types-details-form.reducer.spec.ts
new file mode 100644
index 0000000..8e424e3
--- /dev/null
+++ b/src/app/shared/store/reducers/admin/address-types-details-form.reducer.spec.ts
@@ -0,0 +1,56 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import * as fromReducer from '@shared/store/reducers/admin/address-types-details-form.reducer';
+import { AddressType } from '@shared/models';
+import { Action } from '@ngrx/store';
+import { FormGroupState } from 'ngrx-forms';
+import * as addressTypesActions from '@shared/store/actions/admin/address-types.action';
+
+describe('AddressType Detail Form reducer', () => {
+ const { INITIAL_STATE } = fromReducer;
+
+ it('should return the default state when no state is given', () => {
+ const action: Action = { type: '' };
+ const state: FormGroupState<AddressType> = fromReducer.reducer(undefined, action);
+
+ expect(state).toBe(INITIAL_STATE);
+ });
+
+ it('should return the initial state when action is not found', () => {
+ const action: Action = { type: '' };
+ const state: FormGroupState<AddressType> = fromReducer.reducer(INITIAL_STATE, action);
+
+ expect(state).toBe(INITIAL_STATE);
+ });
+
+ it('should return the initial state when no action set', () => {
+ const action: Action = null;
+ const state: FormGroupState<AddressType> = fromReducer.reducer(INITIAL_STATE, action);
+
+ expect(state).toBe(INITIAL_STATE);
+ });
+
+ it('should return state via getFormState', () => {
+ const action: Action = null;
+ const state: FormGroupState<AddressType> = fromReducer.reducer(INITIAL_STATE, action);
+ expect(fromReducer.getFormState(state)).toBe(state);
+ });
+
+ it('should set id', () => {
+ const action: Action = { type: addressTypesActions.loadAddressTypeSuccess.type };
+ action['payload']={id: 'x'};
+ const state: FormGroupState<AddressType> = fromReducer.reducer(INITIAL_STATE, action);
+ expect(state.controls.id).toBeDefined();
+ });
+
+});
diff --git a/src/app/shared/store/reducers/admin/address-types-details-form.reducer.ts b/src/app/shared/store/reducers/admin/address-types-details-form.reducer.ts
new file mode 100644
index 0000000..92b8c25
--- /dev/null
+++ b/src/app/shared/store/reducers/admin/address-types-details-form.reducer.ts
@@ -0,0 +1,59 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { Action, ActionReducer, INIT } from '@ngrx/store';
+import * as addressTypesActions from '@shared/store/actions/admin/address-types.action';
+import {
+ createFormGroupState,
+ createFormStateReducerWithUpdate,
+ updateGroup,
+ FormGroupState,
+ FormState,
+ SetValueAction,
+ validate,
+} from 'ngrx-forms';
+import { AddressType } from '@shared/models';
+import { required } from 'ngrx-forms/validation';
+
+export const FORM_ID = 'addressTypeDetailForm';
+
+export const INITIAL_STATE: FormGroupState<AddressType> = createFormGroupState<
+ AddressType
+>(FORM_ID, new AddressType());
+
+export const validateForm: ActionReducer<FormState<AddressType>> = createFormStateReducerWithUpdate<AddressType>(
+ updateGroup<AddressType>(
+ {
+ type: validate(required),
+ description: validate(required),
+ }
+ )
+);
+
+export function reducer(
+ state: FormGroupState<AddressType> = INITIAL_STATE,
+ action: Action
+): FormGroupState<AddressType> {
+ if (!action || action.type === INIT) {
+ return INITIAL_STATE;
+ }
+ if (action.type === addressTypesActions.loadAddressTypeSuccess.type) {
+ const item: AddressType = <AddressType>action['payload'];
+ const setValueAction: SetValueAction<any> = new SetValueAction<any>(FORM_ID, item);
+
+ return validateForm(state, setValueAction);
+ }
+
+ return validateForm(state, action);
+}
+export const getFormState = (state: FormGroupState<AddressType>) => state;
+
diff --git a/src/app/shared/store/reducers/contacts/contacts.reducer.spec.ts b/src/app/shared/store/reducers/admin/address-types.reducer.spec.ts
similarity index 60%
copy from src/app/shared/store/reducers/contacts/contacts.reducer.spec.ts
copy to src/app/shared/store/reducers/admin/address-types.reducer.spec.ts
index d814929..835af4e 100644
--- a/src/app/shared/store/reducers/contacts/contacts.reducer.spec.ts
+++ b/src/app/shared/store/reducers/admin/address-types.reducer.spec.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -10,12 +10,11 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import {ContactsReducer, INITIAL_STATE, getData, getLoading, getLoaded, getFailed, reducer} from '@shared/store/reducers/contacts/contacts.reducer';
-import * as contactsActions from '@shared/store/actions/contacts.action';
-import { Contact } from '@shared/models';
+import { AddressTypesReducer, INITIAL_STATE, getData, getLoading, getLoaded, getFailed, reducer} from '@app/shared/store/reducers/admin/address-types.reducer';
+import * as addressTypesActions from '@shared/store/actions/admin/address-types.action';
+import { AddressType } from '@shared/models';
-
-describe('Contacts reducer', () => {
+describe('AddressTypes reducer', () => {
it('should return the initial state', () => {
const action = { type: 'NOOP' } as any;
@@ -24,14 +23,9 @@
expect(result).toBe(INITIAL_STATE);
});
- it('should return initial state in case of missing action', () => {
- const result = reducer(undefined, null);
- expect(result).toBe(INITIAL_STATE);
- });
-
it('should trigger loading state', () => {
- const action = contactsActions.loadContacts();
- const result = ContactsReducer(INITIAL_STATE, action);
+ const action = addressTypesActions.loadAddressTypes();
+ const result = AddressTypesReducer(INITIAL_STATE, action);
expect(result).toEqual({
...INITIAL_STATE,
@@ -40,18 +34,18 @@
});
it('should trigger loaded state', () => {
- const contacts: contactsActions.ILoadContactsSuccess = {payload: [new Contact()]};
- contacts.payload[0].name = 'testme';
- const action = contactsActions.loadContactsSuccess(contacts);
- const result = ContactsReducer(INITIAL_STATE, action);
+ const items: addressTypesActions.ILoadAddressTypesSuccess = {payload: [new AddressType()]};
+ items.payload[0].type = 'testme';
+ const action = addressTypesActions.loadAddressTypesSuccess(items);
+ const result = AddressTypesReducer(INITIAL_STATE, action);
expect(result.loaded).toBe(true);
});
it('should trigger failed state', () => {
- const error: contactsActions.ILoadContactsFail = {payload: 'err_msg'};
- const action = contactsActions.loadContactsFail(error);
- const result = ContactsReducer(INITIAL_STATE, action);
+ const error: addressTypesActions.ILoadAddressTypesFail = {payload: 'err_msg'};
+ const action = addressTypesActions.loadAddressTypesFail(error);
+ const result = AddressTypesReducer(INITIAL_STATE, action);
expect(result).toEqual({
...INITIAL_STATE,
diff --git a/src/app/shared/store/reducers/contacts/contacts.reducer.ts b/src/app/shared/store/reducers/admin/address-types.reducer.ts
similarity index 70%
copy from src/app/shared/store/reducers/contacts/contacts.reducer.ts
copy to src/app/shared/store/reducers/admin/address-types.reducer.ts
index 8ddc539..00a2320 100644
--- a/src/app/shared/store/reducers/contacts/contacts.reducer.ts
+++ b/src/app/shared/store/reducers/admin/address-types.reducer.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -10,15 +10,15 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as contactsActions from '@shared/store/actions/contacts.action';
-import { Contact } from '@shared/models';
+import * as addressTypesActions from '@shared/store/actions/admin/address-types.action';
+import { AddressType } from '@shared/models';
import { createReducer, on } from '@ngrx/store';
export interface State {
loading: boolean;
loaded: boolean;
failed: boolean;
- data: Array<Contact>;
+ data: Array<AddressType>;
}
export const INITIAL_STATE: State = {
@@ -27,9 +27,10 @@
failed: false,
data: []
};
-export const ContactsReducer = createReducer(
+
+export const AddressTypesReducer = createReducer(
INITIAL_STATE,
- on(contactsActions.loadContacts, (state: any, action: any) => {
+ on(addressTypesActions.loadAddressTypes, (state: any, action: any) => {
return {
...state,
loading: true,
@@ -38,7 +39,7 @@
data: []
};
}),
- on(contactsActions.loadContactsSuccess, (state: any, action: any) => {
+ on(addressTypesActions.loadAddressTypesSuccess, (state: any, action: any) => {
return {
...state,
loading: false,
@@ -47,7 +48,7 @@
data: action['payload']
};
}),
- on(contactsActions.loadContactsFail, (state: any, action: any) => {
+ on(addressTypesActions.loadAddressTypesFail, (state: any, action: any) => {
return {
...state,
loaded: false,
@@ -57,12 +58,9 @@
};
})
);
-export function reducer(state = INITIAL_STATE, action: any): State {
- if (!action) {
- return state;
- }
- return ContactsReducer(state, action);
+export function reducer(state = INITIAL_STATE, action: any): State {
+ return AddressTypesReducer(state, action);
}
export const getData = (state: State) => state.data;
diff --git a/src/app/shared/store/reducers/admin/communication-types-details-form.reducer.spec.ts b/src/app/shared/store/reducers/admin/communication-types-details-form.reducer.spec.ts
new file mode 100644
index 0000000..00d5640
--- /dev/null
+++ b/src/app/shared/store/reducers/admin/communication-types-details-form.reducer.spec.ts
@@ -0,0 +1,56 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import * as fromReducer from '@shared/store/reducers/admin/communication-types-details-form.reducer';
+import { CommunicationType } from '@shared/models';
+import { Action } from '@ngrx/store';
+import { FormGroupState } from 'ngrx-forms';
+import * as communicationTypesActions from '@shared/store/actions/admin/communication-types.action';
+
+describe('Salutation Detail Form reducer', () => {
+ const { INITIAL_STATE } = fromReducer;
+
+ it('should return the default state when no state is given', () => {
+ const action: Action = { type: '' };
+ const state: FormGroupState<CommunicationType> = fromReducer.reducer(undefined, action);
+
+ expect(state).toBe(INITIAL_STATE);
+ });
+
+ it('should return the initial state when action is not found', () => {
+ const action: Action = { type: '' };
+ const state: FormGroupState<CommunicationType> = fromReducer.reducer(INITIAL_STATE, action);
+
+ expect(state).toBe(INITIAL_STATE);
+ });
+
+ it('should return the initial state when no action set', () => {
+ const action: Action = null;
+ const state: FormGroupState<CommunicationType> = fromReducer.reducer(INITIAL_STATE, action);
+
+ expect(state).toBe(INITIAL_STATE);
+ });
+
+ it('should return state via getFormState', () => {
+ const action: Action = null;
+ const state: FormGroupState<CommunicationType> = fromReducer.reducer(INITIAL_STATE, action);
+ expect(fromReducer.getFormState(state)).toBe(state);
+ });
+
+ it('should set id', () => {
+ const action: Action = { type: communicationTypesActions.loadCommunicationTypeSuccess.type };
+ action['payload']={id: 'x'};
+ const state: FormGroupState<CommunicationType> = fromReducer.reducer(INITIAL_STATE, action);
+ expect(state.controls.id).toBeDefined();
+ });
+
+});
diff --git a/src/app/shared/store/reducers/admin/communication-types-details-form.reducer.ts b/src/app/shared/store/reducers/admin/communication-types-details-form.reducer.ts
new file mode 100644
index 0000000..1b8979e
--- /dev/null
+++ b/src/app/shared/store/reducers/admin/communication-types-details-form.reducer.ts
@@ -0,0 +1,59 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { Action, ActionReducer, INIT } from '@ngrx/store';
+import * as communicationTypesActions from '@shared/store/actions/admin/communication-types.action';
+import {
+ createFormGroupState,
+ createFormStateReducerWithUpdate,
+ updateGroup,
+ FormGroupState,
+ FormState,
+ SetValueAction,
+ validate,
+} from 'ngrx-forms';
+import { CommunicationType } from '@shared/models';
+import { required } from 'ngrx-forms/validation';
+
+export const FORM_ID = 'communicationTypesDetailForm';
+
+export const INITIAL_STATE: FormGroupState<CommunicationType> = createFormGroupState<
+ CommunicationType
+>(FORM_ID, new CommunicationType({editable: true}));
+
+export const validateForm: ActionReducer<FormState<CommunicationType>> = createFormStateReducerWithUpdate<CommunicationType>(
+ updateGroup<CommunicationType>(
+ {
+ type: validate(required),
+ description: validate(required),
+ }
+ )
+);
+
+export function reducer(
+ state: FormGroupState<CommunicationType> = INITIAL_STATE,
+ action: Action
+): FormGroupState<CommunicationType> {
+ if (!action || action.type === INIT) {
+ return INITIAL_STATE;
+ }
+ if (action.type === communicationTypesActions.loadCommunicationTypeSuccess.type) {
+ const CommunicationType: CommunicationType = <CommunicationType>action['payload'];
+ const setValueAction: SetValueAction<any> = new SetValueAction<any>(FORM_ID, CommunicationType);
+
+ return validateForm(state, setValueAction);
+ }
+
+ return validateForm(state, action);
+}
+export const getFormState = (state: FormGroupState<CommunicationType>) => state;
+
diff --git a/src/app/shared/store/reducers/admin/communication-types.reducer.spec.ts b/src/app/shared/store/reducers/admin/communication-types.reducer.spec.ts
new file mode 100644
index 0000000..9bbb41c
--- /dev/null
+++ b/src/app/shared/store/reducers/admin/communication-types.reducer.spec.ts
@@ -0,0 +1,80 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import {CommunicationTypesReducer, INITIAL_STATE, getData, getLoading, getLoaded, getFailed, reducer} from '@app/shared/store/reducers/admin/communication-types.reducer';
+import * as communicationTypesActions from '@app/shared/store/actions/admin/communication-types.action';
+import { CommunicationType } from '@shared/models';
+
+describe('CommunicationTypes reducer', () => {
+
+ it('should return the initial state', () => {
+ const action = { type: 'NOOP' } as any;
+ const result = reducer(undefined, action);
+
+ expect(result).toBe(INITIAL_STATE);
+ });
+
+ it('should trigger loading state', () => {
+ const action = communicationTypesActions.loadCommunicationTypes();
+ const result = CommunicationTypesReducer(INITIAL_STATE, action);
+
+ expect(result).toEqual({
+ ...INITIAL_STATE,
+ loading: true,
+ });
+ });
+
+ it('should trigger loaded state', () => {
+ const list: communicationTypesActions.ILoadCommunicationTypesSuccess = {payload: [new CommunicationType()]};
+ list.payload[0].type = 'testme';
+ const action = communicationTypesActions.loadCommunicationTypesSuccess(list);
+ const result = CommunicationTypesReducer(INITIAL_STATE, action);
+
+ expect(result.loaded).toBe(true);
+ });
+
+ it('should trigger failed state', () => {
+ const error: communicationTypesActions.ILoadCommunicationTypesFail = {payload: 'err_msg'};
+ const action = communicationTypesActions.loadCommunicationTypesFail(error);
+ const result = CommunicationTypesReducer(INITIAL_STATE, action);
+
+ expect(result).toEqual({
+ ...INITIAL_STATE,
+ failed: true,
+ });
+ });
+
+ it('getData return state.data', () => {
+ const state = { ...INITIAL_STATE };
+ const result = getData(state);
+ expect(result).toBe(state.data);
+ });
+
+ it('getLoading return state.loading', () => {
+ const state = { ...INITIAL_STATE };
+ const result = getLoading(state);
+ expect(result).toBe(state.loading);
+ });
+
+ it('getLoaded return state.loaded', () => {
+ const state = { ...INITIAL_STATE };
+ const result = getLoaded(state);
+ expect(result).toBe(state.loaded);
+ });
+
+ it('getFailed return state.failed', () => {
+ const state = { ...INITIAL_STATE };
+ const result = getFailed(state);
+ expect(result).toBe(state.failed);
+ });
+
+});
diff --git a/src/app/shared/store/reducers/contacts/contacts.reducer.ts b/src/app/shared/store/reducers/admin/communication-types.reducer.ts
similarity index 72%
copy from src/app/shared/store/reducers/contacts/contacts.reducer.ts
copy to src/app/shared/store/reducers/admin/communication-types.reducer.ts
index 8ddc539..84c3012 100644
--- a/src/app/shared/store/reducers/contacts/contacts.reducer.ts
+++ b/src/app/shared/store/reducers/admin/communication-types.reducer.ts
@@ -10,15 +10,15 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as contactsActions from '@shared/store/actions/contacts.action';
-import { Contact } from '@shared/models';
+import * as communicationTypesActions from '@shared/store/actions/admin/communication-types.action';
+import { CommunicationType } from '@shared/models';
import { createReducer, on } from '@ngrx/store';
export interface State {
loading: boolean;
loaded: boolean;
failed: boolean;
- data: Array<Contact>;
+ data: Array<CommunicationType>;
}
export const INITIAL_STATE: State = {
@@ -27,9 +27,10 @@
failed: false,
data: []
};
-export const ContactsReducer = createReducer(
+
+export const CommunicationTypesReducer = createReducer(
INITIAL_STATE,
- on(contactsActions.loadContacts, (state: any, action: any) => {
+ on(communicationTypesActions.loadCommunicationTypes, (state: any, action: any) => {
return {
...state,
loading: true,
@@ -38,7 +39,7 @@
data: []
};
}),
- on(contactsActions.loadContactsSuccess, (state: any, action: any) => {
+ on(communicationTypesActions.loadCommunicationTypesSuccess, (state: any, action: any) => {
return {
...state,
loading: false,
@@ -47,7 +48,7 @@
data: action['payload']
};
}),
- on(contactsActions.loadContactsFail, (state: any, action: any) => {
+ on(communicationTypesActions.loadCommunicationTypesFail, (state: any, action: any) => {
return {
...state,
loaded: false,
@@ -57,12 +58,9 @@
};
})
);
-export function reducer(state = INITIAL_STATE, action: any): State {
- if (!action) {
- return state;
- }
- return ContactsReducer(state, action);
+export function reducer(state = INITIAL_STATE, action: any): State {
+ return CommunicationTypesReducer(state, action);
}
export const getData = (state: State) => state.data;
diff --git a/src/app/shared/store/reducers/admin/person-types-details-form.reducer.spec.ts b/src/app/shared/store/reducers/admin/person-types-details-form.reducer.spec.ts
new file mode 100644
index 0000000..c296674
--- /dev/null
+++ b/src/app/shared/store/reducers/admin/person-types-details-form.reducer.spec.ts
@@ -0,0 +1,56 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import * as fromReducer from '@shared/store/reducers/admin/person-types-details-form.reducer';
+import { PersonType } from '@shared/models';
+import { Action } from '@ngrx/store';
+import { FormGroupState } from 'ngrx-forms';
+import * as personTypesActions from '@shared/store/actions/admin/person-types.action';
+
+describe('PersonType Detail Form reducer', () => {
+ const { INITIAL_STATE } = fromReducer;
+
+ it('should return the default state when no state is given', () => {
+ const action: Action = { type: '' };
+ const state: FormGroupState<PersonType> = fromReducer.reducer(undefined, action);
+
+ expect(state).toBe(INITIAL_STATE);
+ });
+
+ it('should return the initial state when action is not found', () => {
+ const action: Action = { type: '' };
+ const state: FormGroupState<PersonType> = fromReducer.reducer(INITIAL_STATE, action);
+
+ expect(state).toBe(INITIAL_STATE);
+ });
+
+ it('should return the initial state when no action set', () => {
+ const action: Action = null;
+ const state: FormGroupState<PersonType> = fromReducer.reducer(INITIAL_STATE, action);
+
+ expect(state).toBe(INITIAL_STATE);
+ });
+
+ it('should return state via getFormState', () => {
+ const action: Action = null;
+ const state: FormGroupState<PersonType> = fromReducer.reducer(INITIAL_STATE, action);
+ expect(fromReducer.getFormState(state)).toBe(state);
+ });
+
+ it('should set id', () => {
+ const action: Action = { type: personTypesActions.loadPersonTypeSuccess.type };
+ action['payload']={id: 'x'};
+ const state: FormGroupState<PersonType> = fromReducer.reducer(INITIAL_STATE, action);
+ expect(state.controls.id).toBeDefined();
+ });
+
+});
diff --git a/src/app/shared/store/reducers/admin/person-types-details-form.reducer.ts b/src/app/shared/store/reducers/admin/person-types-details-form.reducer.ts
new file mode 100644
index 0000000..3448158
--- /dev/null
+++ b/src/app/shared/store/reducers/admin/person-types-details-form.reducer.ts
@@ -0,0 +1,59 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { Action, ActionReducer, INIT } from '@ngrx/store';
+import * as personTypesActions from '@shared/store/actions/admin/person-types.action';
+import {
+ createFormGroupState,
+ createFormStateReducerWithUpdate,
+ updateGroup,
+ FormGroupState,
+ FormState,
+ SetValueAction,
+ validate,
+} from 'ngrx-forms';
+import { PersonType } from '@shared/models';
+import { required } from 'ngrx-forms/validation';
+
+export const FORM_ID = 'personTypeDetailForm';
+
+export const INITIAL_STATE: FormGroupState<PersonType> = createFormGroupState<
+ PersonType
+>(FORM_ID, new PersonType());
+
+export const validateForm: ActionReducer<FormState<PersonType>> = createFormStateReducerWithUpdate<PersonType>(
+ updateGroup<PersonType>(
+ {
+ type: validate(required),
+ description: validate(required),
+ }
+ )
+);
+
+export function reducer(
+ state: FormGroupState<PersonType> = INITIAL_STATE,
+ action: Action
+): FormGroupState<PersonType> {
+ if (!action || action.type === INIT) {
+ return INITIAL_STATE;
+ }
+ if (action.type === personTypesActions.loadPersonTypeSuccess.type) {
+ const item: PersonType = <PersonType>action['payload'];
+ const setValueAction: SetValueAction<any> = new SetValueAction<any>(FORM_ID, item);
+
+ return validateForm(state, setValueAction);
+ }
+
+ return validateForm(state, action);
+}
+export const getFormState = (state: FormGroupState<PersonType>) => state;
+
diff --git a/src/app/shared/store/reducers/contacts/contacts.reducer.spec.ts b/src/app/shared/store/reducers/admin/person-types.reducer.spec.ts
similarity index 60%
copy from src/app/shared/store/reducers/contacts/contacts.reducer.spec.ts
copy to src/app/shared/store/reducers/admin/person-types.reducer.spec.ts
index d814929..068d5ef 100644
--- a/src/app/shared/store/reducers/contacts/contacts.reducer.spec.ts
+++ b/src/app/shared/store/reducers/admin/person-types.reducer.spec.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -10,12 +10,11 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import {ContactsReducer, INITIAL_STATE, getData, getLoading, getLoaded, getFailed, reducer} from '@shared/store/reducers/contacts/contacts.reducer';
-import * as contactsActions from '@shared/store/actions/contacts.action';
-import { Contact } from '@shared/models';
+import { PersonTypesReducer, INITIAL_STATE, getData, getLoading, getLoaded, getFailed, reducer} from '@app/shared/store/reducers/admin/person-types.reducer';
+import * as personTypesActions from '@shared/store/actions/admin/person-types.action';
+import { PersonType } from '@shared/models';
-
-describe('Contacts reducer', () => {
+describe('PersonTypes reducer', () => {
it('should return the initial state', () => {
const action = { type: 'NOOP' } as any;
@@ -24,14 +23,9 @@
expect(result).toBe(INITIAL_STATE);
});
- it('should return initial state in case of missing action', () => {
- const result = reducer(undefined, null);
- expect(result).toBe(INITIAL_STATE);
- });
-
it('should trigger loading state', () => {
- const action = contactsActions.loadContacts();
- const result = ContactsReducer(INITIAL_STATE, action);
+ const action = personTypesActions.loadPersonTypes();
+ const result = PersonTypesReducer(INITIAL_STATE, action);
expect(result).toEqual({
...INITIAL_STATE,
@@ -40,18 +34,18 @@
});
it('should trigger loaded state', () => {
- const contacts: contactsActions.ILoadContactsSuccess = {payload: [new Contact()]};
- contacts.payload[0].name = 'testme';
- const action = contactsActions.loadContactsSuccess(contacts);
- const result = ContactsReducer(INITIAL_STATE, action);
+ const items: personTypesActions.ILoadPersonTypesSuccess = {payload: [new PersonType()]};
+ items.payload[0].type = 'testme';
+ const action = personTypesActions.loadPersonTypesSuccess(items);
+ const result = PersonTypesReducer(INITIAL_STATE, action);
expect(result.loaded).toBe(true);
});
it('should trigger failed state', () => {
- const error: contactsActions.ILoadContactsFail = {payload: 'err_msg'};
- const action = contactsActions.loadContactsFail(error);
- const result = ContactsReducer(INITIAL_STATE, action);
+ const error: personTypesActions.ILoadPersonTypesFail = {payload: 'err_msg'};
+ const action = personTypesActions.loadPersonTypesFail(error);
+ const result = PersonTypesReducer(INITIAL_STATE, action);
expect(result).toEqual({
...INITIAL_STATE,
diff --git a/src/app/shared/store/reducers/contacts/contacts.reducer.ts b/src/app/shared/store/reducers/admin/person-types.reducer.ts
similarity index 71%
copy from src/app/shared/store/reducers/contacts/contacts.reducer.ts
copy to src/app/shared/store/reducers/admin/person-types.reducer.ts
index 8ddc539..86d9df5 100644
--- a/src/app/shared/store/reducers/contacts/contacts.reducer.ts
+++ b/src/app/shared/store/reducers/admin/person-types.reducer.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -10,15 +10,15 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as contactsActions from '@shared/store/actions/contacts.action';
-import { Contact } from '@shared/models';
+import * as personTypesActions from '@shared/store/actions/admin/person-types.action';
+import { PersonType } from '@shared/models';
import { createReducer, on } from '@ngrx/store';
export interface State {
loading: boolean;
loaded: boolean;
failed: boolean;
- data: Array<Contact>;
+ data: Array<PersonType>;
}
export const INITIAL_STATE: State = {
@@ -27,9 +27,10 @@
failed: false,
data: []
};
-export const ContactsReducer = createReducer(
+
+export const PersonTypesReducer = createReducer(
INITIAL_STATE,
- on(contactsActions.loadContacts, (state: any, action: any) => {
+ on(personTypesActions.loadPersonTypes, (state: any, action: any) => {
return {
...state,
loading: true,
@@ -38,7 +39,7 @@
data: []
};
}),
- on(contactsActions.loadContactsSuccess, (state: any, action: any) => {
+ on(personTypesActions.loadPersonTypesSuccess, (state: any, action: any) => {
return {
...state,
loading: false,
@@ -47,7 +48,7 @@
data: action['payload']
};
}),
- on(contactsActions.loadContactsFail, (state: any, action: any) => {
+ on(personTypesActions.loadPersonTypesFail, (state: any, action: any) => {
return {
...state,
loaded: false,
@@ -57,12 +58,9 @@
};
})
);
-export function reducer(state = INITIAL_STATE, action: any): State {
- if (!action) {
- return state;
- }
- return ContactsReducer(state, action);
+export function reducer(state = INITIAL_STATE, action: any): State {
+ return PersonTypesReducer(state, action);
}
export const getData = (state: State) => state.data;
diff --git a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts b/src/app/shared/store/reducers/admin/salutations-details-form.reducer.spec.ts
similarity index 75%
rename from src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts
rename to src/app/shared/store/reducers/admin/salutations-details-form.reducer.spec.ts
index e6cdffb..ed99d74 100644
--- a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts
+++ b/src/app/shared/store/reducers/admin/salutations-details-form.reducer.spec.ts
@@ -10,24 +10,24 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as fromReducer from '@shared/store/reducers/salutations/salutations-details-form.reducer';
+import * as fromReducer from '@shared/store/reducers/admin/salutations-details-form.reducer';
import { Salutation } from '@shared/models';
import { Action } from '@ngrx/store';
import { FormGroupState } from 'ngrx-forms';
-
+import * as salutationActions from '@shared/store/actions/admin/salutations.action';
describe('Salutation Detail Form reducer', () => {
const { INITIAL_STATE } = fromReducer;
it('should return the default state when no state is given', () => {
- const action: Action = { type: 'testAction' };
+ const action: Action = { type: '' };
const state: FormGroupState<Salutation> = fromReducer.reducer(undefined, action);
expect(state).toBe(INITIAL_STATE);
});
it('should return the initial state when action is not found', () => {
- const action: Action = { type: 'testAction' };
+ const action: Action = { type: '' };
const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
expect(state).toBe(INITIAL_STATE);
@@ -46,4 +46,12 @@
expect(fromReducer.getFormState(state)).toBe(state);
});
+ it('should set id', () => {
+ const action: Action = { type: salutationActions.loadSalutationSuccess.type };
+ action['payload']={id: 'x'};
+ const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
+ expect(state.controls.id).toBeDefined();
+ });
+
+
});
diff --git a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.ts b/src/app/shared/store/reducers/admin/salutations-details-form.reducer.ts
similarity index 79%
rename from src/app/shared/store/reducers/salutations/salutations-details-form.reducer.ts
rename to src/app/shared/store/reducers/admin/salutations-details-form.reducer.ts
index 2338b96..b550329 100644
--- a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.ts
+++ b/src/app/shared/store/reducers/admin/salutations-details-form.reducer.ts
@@ -11,7 +11,7 @@
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
import { Action, ActionReducer, INIT } from '@ngrx/store';
-import * as salutationActions from '@shared/store/actions/salutations.action';
+import * as salutationActions from '@shared/store/actions/admin/salutations.action';
import {
createFormGroupState,
createFormStateReducerWithUpdate,
@@ -26,21 +26,10 @@
export const FORM_ID = 'salutationDetailForm';
-/**
- * The initial state of the details form.
- *
- * @author Peter Buschmann <peter.buschmann@pta.de>
- */
export const INITIAL_STATE: FormGroupState<Salutation> = createFormGroupState<
Salutation
>(FORM_ID, new Salutation());
-/**
- * Validation function.
- *
- * @author Peter Buschmann <peter.buschmann@pta.de>
- * @export
- */
export const validateForm: ActionReducer<FormState<Salutation>> = createFormStateReducerWithUpdate<Salutation>(
updateGroup<Salutation>(
{
@@ -50,14 +39,6 @@
)
);
-/**
- * The reducer function.
- *
- * @author Peter Buschmann <peter.buschmann@pta.de>
- * @export
- * @param {FormGroupState<LogProcessModel>} state FormGroupState
- * @param {Action} action Action
- */
export function reducer(
state: FormGroupState<Salutation> = INITIAL_STATE,
action: Action
@@ -65,7 +46,6 @@
if (!action || action.type === INIT) {
return INITIAL_STATE;
}
-
if (action.type === salutationActions.loadSalutationSuccess.type) {
const salutation: Salutation = <Salutation>action['payload'];
const setValueAction: SetValueAction<any> = new SetValueAction<any>(FORM_ID, salutation);
diff --git a/src/app/shared/store/reducers/salutations/salutations.reducer.spec.ts b/src/app/shared/store/reducers/admin/salutations.reducer.spec.ts
similarity index 88%
rename from src/app/shared/store/reducers/salutations/salutations.reducer.spec.ts
rename to src/app/shared/store/reducers/admin/salutations.reducer.spec.ts
index 4ceddff..bfaf386 100644
--- a/src/app/shared/store/reducers/salutations/salutations.reducer.spec.ts
+++ b/src/app/shared/store/reducers/admin/salutations.reducer.spec.ts
@@ -10,8 +10,8 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import {SalutationsReducer, INITIAL_STATE, getData, getLoading, getLoaded, getFailed, reducer} from '@shared/store/reducers/salutations/salutations.reducer';
-import * as salutationsActions from '@shared/store/actions/salutations.action';
+import {SalutationsReducer, INITIAL_STATE, getData, getLoading, getLoaded, getFailed, reducer} from '@shared/store/reducers/admin/salutations.reducer';
+import * as salutationsActions from '@shared/store/actions/admin/salutations.action';
import { Salutation } from '@shared/models';
describe('Salutations reducer', () => {
@@ -23,11 +23,6 @@
expect(result).toBe(INITIAL_STATE);
});
- it('should return initial state in case of missing action', () => {
- const result = reducer(undefined, null);
- expect(result).toBe(INITIAL_STATE);
- });
-
it('should trigger loading state', () => {
const action = salutationsActions.loadSalutations();
const result = SalutationsReducer(INITIAL_STATE, action);
diff --git a/src/app/shared/store/reducers/salutations/salutations.reducer.ts b/src/app/shared/store/reducers/admin/salutations.reducer.ts
similarity index 93%
rename from src/app/shared/store/reducers/salutations/salutations.reducer.ts
rename to src/app/shared/store/reducers/admin/salutations.reducer.ts
index e6458ae..091c163 100644
--- a/src/app/shared/store/reducers/salutations/salutations.reducer.ts
+++ b/src/app/shared/store/reducers/admin/salutations.reducer.ts
@@ -10,7 +10,7 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as salutationsActions from '@shared/store/actions/salutations.action';
+import * as salutationsActions from '@shared/store/actions/admin/salutations.action';
import { Salutation } from '@shared/models';
import { createReducer, on } from '@ngrx/store';
@@ -60,10 +60,6 @@
);
export function reducer(state = INITIAL_STATE, action: any): State {
- if (!action) {
- return state;
- }
-
return SalutationsReducer(state, action);
}
diff --git a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts b/src/app/shared/store/reducers/company/addresses-details-form.reducer.spec.ts
similarity index 62%
copy from src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts
copy to src/app/shared/store/reducers/company/addresses-details-form.reducer.spec.ts
index e6cdffb..a3e8c2c 100644
--- a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts
+++ b/src/app/shared/store/reducers/company/addresses-details-form.reducer.spec.ts
@@ -10,40 +10,32 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as fromReducer from '@shared/store/reducers/salutations/salutations-details-form.reducer';
-import { Salutation } from '@shared/models';
+import * as fromReducer from '@shared/store/reducers/company/addresses-details-form.reducer';
+import { Address } from '@shared/models';
import { Action } from '@ngrx/store';
import { FormGroupState } from 'ngrx-forms';
-
-describe('Salutation Detail Form reducer', () => {
+describe('Company Addresses Form reducer', () => {
const { INITIAL_STATE } = fromReducer;
it('should return the default state when no state is given', () => {
const action: Action = { type: 'testAction' };
- const state: FormGroupState<Salutation> = fromReducer.reducer(undefined, action);
+ const state: FormGroupState<Address> = fromReducer.reducer(undefined, action);
expect(state).toBe(INITIAL_STATE);
});
it('should return the initial state when action is not found', () => {
const action: Action = { type: 'testAction' };
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
+ const state: FormGroupState<Address> = fromReducer.reducer(INITIAL_STATE, action);
expect(state).toBe(INITIAL_STATE);
});
it('should return the initial state when no action set', () => {
const action: Action = null;
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
+ const state: FormGroupState<Address> = fromReducer.reducer(INITIAL_STATE, action);
expect(state).toBe(INITIAL_STATE);
});
-
- it('should return state via getFormState', () => {
- const action: Action = null;
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
- expect(fromReducer.getFormState(state)).toBe(state);
- });
-
});
diff --git a/src/app/shared/store/reducers/company/addresses-details-form.reducer.ts b/src/app/shared/store/reducers/company/addresses-details-form.reducer.ts
new file mode 100644
index 0000000..71e6e5f
--- /dev/null
+++ b/src/app/shared/store/reducers/company/addresses-details-form.reducer.ts
@@ -0,0 +1,61 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { Action, ActionReducer, INIT } from '@ngrx/store';
+import * as companyActions from '@shared/store/actions/company/company.action';
+import {
+ createFormGroupState,
+ createFormStateReducerWithUpdate,
+ updateGroup,
+ FormGroupState,
+ FormState,
+ SetValueAction,
+ validate,
+} from 'ngrx-forms';
+import { Address } from '@app/shared/models/address/address.model';
+import { required } from 'ngrx-forms/validation';
+
+export const FORM_ID = 'companyAddressDetailForm';
+
+export const INITIAL_STATE: FormGroupState<Address> = createFormGroupState<
+Address
+>(FORM_ID, new Address());
+
+
+export const validateForm: ActionReducer<FormState<Address>> = createFormStateReducerWithUpdate<Address>(
+ updateGroup<Address>(
+ {
+ addressTypeId: validate(required),
+ }
+ )
+);
+
+
+export function reducer(
+ state: FormGroupState<Address> = INITIAL_STATE,
+ action: Action
+): FormGroupState<Address> {
+ if (!action || action.type === INIT) {
+ return INITIAL_STATE;
+ }
+
+ if (action.type === companyActions.loadCompanyDetailAddressDetailsSuccess.type) {
+ const companyAddress: Address = <Address>action['payload'];
+ const setValueAction: SetValueAction<any> = new SetValueAction<any>(FORM_ID, companyAddress);
+
+ return validateForm(state, setValueAction);
+ }
+
+ return validateForm(state, action);
+}
+export const getFormState = (state: FormGroupState<Address>) => state;
+
diff --git a/src/app/shared/store/reducers/contacts/contacts.reducer.spec.ts b/src/app/shared/store/reducers/company/addresses.reducer.spec.ts
similarity index 63%
rename from src/app/shared/store/reducers/contacts/contacts.reducer.spec.ts
rename to src/app/shared/store/reducers/company/addresses.reducer.spec.ts
index d814929..241de9b 100644
--- a/src/app/shared/store/reducers/contacts/contacts.reducer.spec.ts
+++ b/src/app/shared/store/reducers/company/addresses.reducer.spec.ts
@@ -10,12 +10,11 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import {ContactsReducer, INITIAL_STATE, getData, getLoading, getLoaded, getFailed, reducer} from '@shared/store/reducers/contacts/contacts.reducer';
-import * as contactsActions from '@shared/store/actions/contacts.action';
-import { Contact } from '@shared/models';
+import {companyAddressesReducer, INITIAL_STATE, getData, getLoading, getLoaded, getFailed, reducer} from '@shared/store/reducers/company/addresses.reducer';
+import * as addressActions from '@shared/store/actions/company/company.action';
+import { Address } from '@shared/models';
-
-describe('Contacts reducer', () => {
+describe('CompanyAddress reducer', () => {
it('should return the initial state', () => {
const action = { type: 'NOOP' } as any;
@@ -24,14 +23,9 @@
expect(result).toBe(INITIAL_STATE);
});
- it('should return initial state in case of missing action', () => {
- const result = reducer(undefined, null);
- expect(result).toBe(INITIAL_STATE);
- });
-
it('should trigger loading state', () => {
- const action = contactsActions.loadContacts();
- const result = ContactsReducer(INITIAL_STATE, action);
+ const action = addressActions.loadCompanyDetailAddresses({payload: 'id'});
+ const result = companyAddressesReducer(INITIAL_STATE, action);
expect(result).toEqual({
...INITIAL_STATE,
@@ -40,18 +34,18 @@
});
it('should trigger loaded state', () => {
- const contacts: contactsActions.ILoadContactsSuccess = {payload: [new Contact()]};
- contacts.payload[0].name = 'testme';
- const action = contactsActions.loadContactsSuccess(contacts);
- const result = ContactsReducer(INITIAL_STATE, action);
+ const addresses: addressActions.ILoadCompanyAddressesSuccess = {payload: [new Address()]};
+ addresses.payload[0].addressTypeId = 'testme';
+ const action = addressActions.loadCompanyDetailAddressesSuccess(addresses);
+ const result = companyAddressesReducer(INITIAL_STATE, action);
expect(result.loaded).toBe(true);
});
it('should trigger failed state', () => {
- const error: contactsActions.ILoadContactsFail = {payload: 'err_msg'};
- const action = contactsActions.loadContactsFail(error);
- const result = ContactsReducer(INITIAL_STATE, action);
+ const error: addressActions.ILoadCompanyAddressesFail = {payload: 'err_msg'};
+ const action = addressActions.loadCompanyDetailAddressesFail(error);
+ const result = companyAddressesReducer(INITIAL_STATE, action);
expect(result).toEqual({
...INITIAL_STATE,
diff --git a/src/app/shared/store/reducers/salutations/salutations.reducer.ts b/src/app/shared/store/reducers/company/addresses.reducer.ts
similarity index 74%
copy from src/app/shared/store/reducers/salutations/salutations.reducer.ts
copy to src/app/shared/store/reducers/company/addresses.reducer.ts
index e6458ae..90335d8 100644
--- a/src/app/shared/store/reducers/salutations/salutations.reducer.ts
+++ b/src/app/shared/store/reducers/company/addresses.reducer.ts
@@ -10,15 +10,15 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as salutationsActions from '@shared/store/actions/salutations.action';
-import { Salutation } from '@shared/models';
+import { Address } from '@app/shared/models/address/address.model';
+import * as companyActions from '@shared/store/actions/company/company.action';
import { createReducer, on } from '@ngrx/store';
export interface State {
loading: boolean;
loaded: boolean;
failed: boolean;
- data: Array<Salutation>;
+ data: Array<Address>;
}
export const INITIAL_STATE: State = {
@@ -27,10 +27,9 @@
failed: false,
data: []
};
-
-export const SalutationsReducer = createReducer(
+export const companyAddressesReducer = createReducer(
INITIAL_STATE,
- on(salutationsActions.loadSalutations, (state: any, action: any) => {
+ on(companyActions.loadCompanyDetailAddresses, (state: any, action: any) => {
return {
...state,
loading: true,
@@ -39,7 +38,7 @@
data: []
};
}),
- on(salutationsActions.loadSalutationsSuccess, (state: any, action: any) => {
+ on(companyActions.loadCompanyDetailAddressesSuccess, (state: any, action: any) => {
return {
...state,
loading: false,
@@ -48,7 +47,7 @@
data: action['payload']
};
}),
- on(salutationsActions.loadSalutationsFail, (state: any, action: any) => {
+ on(companyActions.loadCompanyDetailAddressesFail, (state: any, action: any) => {
return {
...state,
loaded: false,
@@ -58,13 +57,8 @@
};
})
);
-
export function reducer(state = INITIAL_STATE, action: any): State {
- if (!action) {
- return state;
- }
-
- return SalutationsReducer(state, action);
+ return companyAddressesReducer(state, action);
}
export const getData = (state: State) => state.data;
diff --git a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts b/src/app/shared/store/reducers/company/communications-data-details-form.reducer.spec.ts
similarity index 62%
copy from src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts
copy to src/app/shared/store/reducers/company/communications-data-details-form.reducer.spec.ts
index e6cdffb..fc42bd7 100644
--- a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts
+++ b/src/app/shared/store/reducers/company/communications-data-details-form.reducer.spec.ts
@@ -10,40 +10,32 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as fromReducer from '@shared/store/reducers/salutations/salutations-details-form.reducer';
-import { Salutation } from '@shared/models';
+import * as fromReducer from '@shared/store/reducers/company/communications-data-details-form.reducer';
+import { CommunicationsData } from '@shared/models';
import { Action } from '@ngrx/store';
import { FormGroupState } from 'ngrx-forms';
-
-describe('Salutation Detail Form reducer', () => {
+describe('External Person CommunicationsData Form reducer', () => {
const { INITIAL_STATE } = fromReducer;
it('should return the default state when no state is given', () => {
const action: Action = { type: 'testAction' };
- const state: FormGroupState<Salutation> = fromReducer.reducer(undefined, action);
+ const state: FormGroupState<CommunicationsData> = fromReducer.reducer(undefined, action);
expect(state).toBe(INITIAL_STATE);
});
it('should return the initial state when action is not found', () => {
const action: Action = { type: 'testAction' };
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
+ const state: FormGroupState<CommunicationsData> = fromReducer.reducer(INITIAL_STATE, action);
expect(state).toBe(INITIAL_STATE);
});
it('should return the initial state when no action set', () => {
const action: Action = null;
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
+ const state: FormGroupState<CommunicationsData> = fromReducer.reducer(INITIAL_STATE, action);
expect(state).toBe(INITIAL_STATE);
});
-
- it('should return state via getFormState', () => {
- const action: Action = null;
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
- expect(fromReducer.getFormState(state)).toBe(state);
- });
-
});
diff --git a/src/app/shared/store/reducers/company/communications-data-details-form.reducer.ts b/src/app/shared/store/reducers/company/communications-data-details-form.reducer.ts
new file mode 100644
index 0000000..7795e0b
--- /dev/null
+++ b/src/app/shared/store/reducers/company/communications-data-details-form.reducer.ts
@@ -0,0 +1,61 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { Action, ActionReducer, INIT } from '@ngrx/store';
+import * as companyActions from '@shared/store/actions/company/company.action';
+import {
+ createFormGroupState,
+ createFormStateReducerWithUpdate,
+ updateGroup,
+ FormGroupState,
+ FormState,
+ SetValueAction,
+ validate,
+} from 'ngrx-forms';
+import { CommunicationsData } from '@shared/models';
+import { required } from 'ngrx-forms/validation';
+
+export const FORM_ID = 'companyCommunicationsDataDetailForm';
+
+export const INITIAL_STATE: FormGroupState<CommunicationsData> = createFormGroupState<
+CommunicationsData
+>(FORM_ID, new CommunicationsData());
+
+
+export const validateForm: ActionReducer<FormState<CommunicationsData>> = createFormStateReducerWithUpdate<CommunicationsData>(
+ updateGroup<CommunicationsData>(
+ {
+ communicationTypeId: validate(required),
+ }
+ )
+);
+
+
+export function reducer(
+ state: FormGroupState<CommunicationsData> = INITIAL_STATE,
+ action: Action
+): FormGroupState<CommunicationsData> {
+ if (!action || action.type === INIT) {
+ return INITIAL_STATE;
+ }
+
+ if (action.type === companyActions.loadCompanyDetailCommunicationsDataDetailsSuccess.type) {
+ const companyCommunicationsData: CommunicationsData = <CommunicationsData>action['payload'];
+ const setValueAction: SetValueAction<any> = new SetValueAction<any>(FORM_ID, companyCommunicationsData);
+
+ return validateForm(state, setValueAction);
+ }
+
+ return validateForm(state, action);
+}
+export const getFormState = (state: FormGroupState<CommunicationsData>) => state;
+
diff --git a/src/app/shared/store/reducers/contacts/contacts.reducer.spec.ts b/src/app/shared/store/reducers/company/communications-data.reducer.spec.ts
similarity index 61%
copy from src/app/shared/store/reducers/contacts/contacts.reducer.spec.ts
copy to src/app/shared/store/reducers/company/communications-data.reducer.spec.ts
index d814929..ac16458 100644
--- a/src/app/shared/store/reducers/contacts/contacts.reducer.spec.ts
+++ b/src/app/shared/store/reducers/company/communications-data.reducer.spec.ts
@@ -10,12 +10,11 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import {ContactsReducer, INITIAL_STATE, getData, getLoading, getLoaded, getFailed, reducer} from '@shared/store/reducers/contacts/contacts.reducer';
-import * as contactsActions from '@shared/store/actions/contacts.action';
-import { Contact } from '@shared/models';
+import {companyCommunicationsDataReducer, INITIAL_STATE, getData, getLoading, getLoaded, getFailed, reducer} from '@shared/store/reducers/company/communications-data.reducer';
+import * as addressActions from '@shared/store/actions/company/company.action';
+import { CommunicationsData } from '@shared/models';
-
-describe('Contacts reducer', () => {
+describe('CompanyCommunicationsData reducer', () => {
it('should return the initial state', () => {
const action = { type: 'NOOP' } as any;
@@ -24,14 +23,9 @@
expect(result).toBe(INITIAL_STATE);
});
- it('should return initial state in case of missing action', () => {
- const result = reducer(undefined, null);
- expect(result).toBe(INITIAL_STATE);
- });
-
it('should trigger loading state', () => {
- const action = contactsActions.loadContacts();
- const result = ContactsReducer(INITIAL_STATE, action);
+ const action = addressActions.loadCompanyDetailCommunicationsData({payload: 'id'});
+ const result = companyCommunicationsDataReducer(INITIAL_STATE, action);
expect(result).toEqual({
...INITIAL_STATE,
@@ -40,18 +34,18 @@
});
it('should trigger loaded state', () => {
- const contacts: contactsActions.ILoadContactsSuccess = {payload: [new Contact()]};
- contacts.payload[0].name = 'testme';
- const action = contactsActions.loadContactsSuccess(contacts);
- const result = ContactsReducer(INITIAL_STATE, action);
+ const addresses: addressActions.ILoadCompanyCommunicationsDataSuccess = {payload: [new CommunicationsData()]};
+ addresses.payload[0].communicationTypeId = 'testme';
+ const action = addressActions.loadCompanyDetailCommunicationsDataSuccess(addresses);
+ const result = companyCommunicationsDataReducer(INITIAL_STATE, action);
expect(result.loaded).toBe(true);
});
it('should trigger failed state', () => {
- const error: contactsActions.ILoadContactsFail = {payload: 'err_msg'};
- const action = contactsActions.loadContactsFail(error);
- const result = ContactsReducer(INITIAL_STATE, action);
+ const error: addressActions.ILoadCompanyCommunicationsDataFail = {payload: 'err_msg'};
+ const action = addressActions.loadCompanyDetailCommunicationsDataFail(error);
+ const result = companyCommunicationsDataReducer(INITIAL_STATE, action);
expect(result).toEqual({
...INITIAL_STATE,
diff --git a/src/app/shared/store/reducers/contacts/contacts.reducer.ts b/src/app/shared/store/reducers/company/communications-data.reducer.ts
similarity index 72%
rename from src/app/shared/store/reducers/contacts/contacts.reducer.ts
rename to src/app/shared/store/reducers/company/communications-data.reducer.ts
index 8ddc539..6953e70 100644
--- a/src/app/shared/store/reducers/contacts/contacts.reducer.ts
+++ b/src/app/shared/store/reducers/company/communications-data.reducer.ts
@@ -10,15 +10,15 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as contactsActions from '@shared/store/actions/contacts.action';
-import { Contact } from '@shared/models';
+import * as companyActions from '@shared/store/actions/company/company.action';
import { createReducer, on } from '@ngrx/store';
+import { CommunicationsData } from '@shared/models';
export interface State {
loading: boolean;
loaded: boolean;
failed: boolean;
- data: Array<Contact>;
+ data: Array<CommunicationsData>;
}
export const INITIAL_STATE: State = {
@@ -27,9 +27,9 @@
failed: false,
data: []
};
-export const ContactsReducer = createReducer(
+export const companyCommunicationsDataReducer = createReducer(
INITIAL_STATE,
- on(contactsActions.loadContacts, (state: any, action: any) => {
+ on(companyActions.loadCompanyDetailCommunicationsData, (state: any, action: any) => {
return {
...state,
loading: true,
@@ -38,7 +38,7 @@
data: []
};
}),
- on(contactsActions.loadContactsSuccess, (state: any, action: any) => {
+ on(companyActions.loadCompanyDetailCommunicationsDataSuccess, (state: any, action: any) => {
return {
...state,
loading: false,
@@ -47,7 +47,7 @@
data: action['payload']
};
}),
- on(contactsActions.loadContactsFail, (state: any, action: any) => {
+ on(companyActions.loadCompanyDetailCommunicationsDataFail, (state: any, action: any) => {
return {
...state,
loaded: false,
@@ -58,11 +58,7 @@
})
);
export function reducer(state = INITIAL_STATE, action: any): State {
- if (!action) {
- return state;
- }
-
- return ContactsReducer(state, action);
+ return companyCommunicationsDataReducer(state, action);
}
export const getData = (state: State) => state.data;
diff --git a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts b/src/app/shared/store/reducers/company/company-details-form.reducer.spec.ts
similarity index 62%
copy from src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts
copy to src/app/shared/store/reducers/company/company-details-form.reducer.spec.ts
index e6cdffb..43c811f 100644
--- a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts
+++ b/src/app/shared/store/reducers/company/company-details-form.reducer.spec.ts
@@ -10,40 +10,32 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as fromReducer from '@shared/store/reducers/salutations/salutations-details-form.reducer';
-import { Salutation } from '@shared/models';
+import * as fromReducer from '@shared/store/reducers/company/company-details-form.reducer';
+import { Company } from '@shared/models';
import { Action } from '@ngrx/store';
import { FormGroupState } from 'ngrx-forms';
-
-describe('Salutation Detail Form reducer', () => {
+describe('Company Form reducer', () => {
const { INITIAL_STATE } = fromReducer;
it('should return the default state when no state is given', () => {
const action: Action = { type: 'testAction' };
- const state: FormGroupState<Salutation> = fromReducer.reducer(undefined, action);
+ const state: FormGroupState<Company> = fromReducer.reducer(undefined, action);
expect(state).toBe(INITIAL_STATE);
});
it('should return the initial state when action is not found', () => {
const action: Action = { type: 'testAction' };
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
+ const state: FormGroupState<Company> = fromReducer.reducer(INITIAL_STATE, action);
expect(state).toBe(INITIAL_STATE);
});
it('should return the initial state when no action set', () => {
const action: Action = null;
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
+ const state: FormGroupState<Company> = fromReducer.reducer(INITIAL_STATE, action);
expect(state).toBe(INITIAL_STATE);
});
-
- it('should return state via getFormState', () => {
- const action: Action = null;
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
- expect(fromReducer.getFormState(state)).toBe(state);
- });
-
});
diff --git a/src/app/shared/store/reducers/company/company-details-form.reducer.ts b/src/app/shared/store/reducers/company/company-details-form.reducer.ts
new file mode 100644
index 0000000..398bfce
--- /dev/null
+++ b/src/app/shared/store/reducers/company/company-details-form.reducer.ts
@@ -0,0 +1,57 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { Action, ActionReducer, INIT } from '@ngrx/store';
+import * as companyActions from '@shared/store/actions/company/company.action';
+import {
+ createFormGroupState,
+ createFormStateReducerWithUpdate,
+ updateGroup,
+ FormGroupState,
+ FormState,
+ SetValueAction,
+ validate,
+} from 'ngrx-forms';
+import { Company } from '@shared/models';
+import { required } from 'ngrx-forms/validation';
+
+export const FORM_ID = 'companyDetailsForm';
+
+export const INITIAL_STATE: FormGroupState<Company> = createFormGroupState<Company>(FORM_ID, new Company());
+
+export const validateForm: ActionReducer<FormState<Company>> = createFormStateReducerWithUpdate<Company>(
+ updateGroup<Company>(
+ {
+ companyName: validate(required),
+ }
+ )
+);
+
+export function reducer(
+ state: FormGroupState<Company> = INITIAL_STATE,
+ action: Action
+): FormGroupState<Company> {
+ if (!action || action.type === INIT) {
+ return INITIAL_STATE;
+ }
+
+ if (action.type === companyActions.loadCompanyDetailSuccess.type) {
+ const company: Company = <Company>action['payload'];
+ const setValueAction: SetValueAction<any> = new SetValueAction<any>(FORM_ID, company);
+
+ return validateForm(state, setValueAction);
+ }
+
+ return validateForm(state, action);
+}
+
+export const getFormState = (state: FormGroupState<Company>) => state;
diff --git a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts b/src/app/shared/store/reducers/persons/external-person/addresses-details-form.reducer.spec.ts
similarity index 62%
copy from src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts
copy to src/app/shared/store/reducers/persons/external-person/addresses-details-form.reducer.spec.ts
index e6cdffb..cbb34f3 100644
--- a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts
+++ b/src/app/shared/store/reducers/persons/external-person/addresses-details-form.reducer.spec.ts
@@ -10,40 +10,32 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as fromReducer from '@shared/store/reducers/salutations/salutations-details-form.reducer';
-import { Salutation } from '@shared/models';
+import * as fromReducer from '@shared/store/reducers/persons/external-person/addresses-details-form.reducer';
+import { Address } from '@shared/models';
import { Action } from '@ngrx/store';
import { FormGroupState } from 'ngrx-forms';
-
-describe('Salutation Detail Form reducer', () => {
+describe('External Person Addresses Form reducer', () => {
const { INITIAL_STATE } = fromReducer;
it('should return the default state when no state is given', () => {
const action: Action = { type: 'testAction' };
- const state: FormGroupState<Salutation> = fromReducer.reducer(undefined, action);
+ const state: FormGroupState<Address> = fromReducer.reducer(undefined, action);
expect(state).toBe(INITIAL_STATE);
});
it('should return the initial state when action is not found', () => {
const action: Action = { type: 'testAction' };
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
+ const state: FormGroupState<Address> = fromReducer.reducer(INITIAL_STATE, action);
expect(state).toBe(INITIAL_STATE);
});
it('should return the initial state when no action set', () => {
const action: Action = null;
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
+ const state: FormGroupState<Address> = fromReducer.reducer(INITIAL_STATE, action);
expect(state).toBe(INITIAL_STATE);
});
-
- it('should return state via getFormState', () => {
- const action: Action = null;
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
- expect(fromReducer.getFormState(state)).toBe(state);
- });
-
});
diff --git a/src/app/shared/store/reducers/persons/external-person/addresses-details-form.reducer.ts b/src/app/shared/store/reducers/persons/external-person/addresses-details-form.reducer.ts
new file mode 100644
index 0000000..f4e245a
--- /dev/null
+++ b/src/app/shared/store/reducers/persons/external-person/addresses-details-form.reducer.ts
@@ -0,0 +1,61 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { Action, ActionReducer, INIT } from '@ngrx/store';
+import * as externalPersonActions from '@shared/store/actions/persons/external-person.action';
+import {
+ createFormGroupState,
+ createFormStateReducerWithUpdate,
+ updateGroup,
+ FormGroupState,
+ FormState,
+ SetValueAction,
+ validate,
+} from 'ngrx-forms';
+import { Address } from '@app/shared/models/address/address.model';
+import { required } from 'ngrx-forms/validation';
+
+export const FORM_ID = 'externalPersonAddressDetailForm';
+
+export const INITIAL_STATE: FormGroupState<Address> = createFormGroupState<
+Address
+>(FORM_ID, new Address());
+
+
+export const validateForm: ActionReducer<FormState<Address>> = createFormStateReducerWithUpdate<Address>(
+ updateGroup<Address>(
+ {
+ addressTypeId: validate(required),
+ }
+ )
+);
+
+
+export function reducer(
+ state: FormGroupState<Address> = INITIAL_STATE,
+ action: Action
+): FormGroupState<Address> {
+ if (!action || action.type === INIT) {
+ return INITIAL_STATE;
+ }
+
+ if (action.type === externalPersonActions.loadExternalPersonDetailAddressDetailsSuccess.type) {
+ const externalPersonAddress: Address = <Address>action['payload'];
+ const setValueAction: SetValueAction<any> = new SetValueAction<any>(FORM_ID, externalPersonAddress);
+
+ return validateForm(state, setValueAction);
+ }
+
+ return validateForm(state, action);
+}
+export const getFormState = (state: FormGroupState<Address>) => state;
+
diff --git a/src/app/shared/store/reducers/contacts/contacts.reducer.spec.ts b/src/app/shared/store/reducers/persons/external-person/addresses.reducer.spec.ts
similarity index 62%
copy from src/app/shared/store/reducers/contacts/contacts.reducer.spec.ts
copy to src/app/shared/store/reducers/persons/external-person/addresses.reducer.spec.ts
index d814929..1460ddb 100644
--- a/src/app/shared/store/reducers/contacts/contacts.reducer.spec.ts
+++ b/src/app/shared/store/reducers/persons/external-person/addresses.reducer.spec.ts
@@ -10,12 +10,11 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import {ContactsReducer, INITIAL_STATE, getData, getLoading, getLoaded, getFailed, reducer} from '@shared/store/reducers/contacts/contacts.reducer';
-import * as contactsActions from '@shared/store/actions/contacts.action';
-import { Contact } from '@shared/models';
+import {externalPersonAddressesReducer, INITIAL_STATE, getData, getLoading, getLoaded, getFailed, reducer} from '@shared/store/reducers/persons/external-person/addresses.reducer';
+import * as addressActions from '@shared/store/actions/persons/external-person.action';
+import { Address } from '@shared/models';
-
-describe('Contacts reducer', () => {
+describe('ExternalPersonAddress reducer', () => {
it('should return the initial state', () => {
const action = { type: 'NOOP' } as any;
@@ -24,14 +23,9 @@
expect(result).toBe(INITIAL_STATE);
});
- it('should return initial state in case of missing action', () => {
- const result = reducer(undefined, null);
- expect(result).toBe(INITIAL_STATE);
- });
-
it('should trigger loading state', () => {
- const action = contactsActions.loadContacts();
- const result = ContactsReducer(INITIAL_STATE, action);
+ const action = addressActions.loadExternalPersonDetailAddresses({payload: 'id'});
+ const result = externalPersonAddressesReducer(INITIAL_STATE, action);
expect(result).toEqual({
...INITIAL_STATE,
@@ -40,18 +34,18 @@
});
it('should trigger loaded state', () => {
- const contacts: contactsActions.ILoadContactsSuccess = {payload: [new Contact()]};
- contacts.payload[0].name = 'testme';
- const action = contactsActions.loadContactsSuccess(contacts);
- const result = ContactsReducer(INITIAL_STATE, action);
+ const addresses: addressActions.ILoadExternalPersonAddressesSuccess = {payload: [new Address()]};
+ addresses.payload[0].addressTypeId = 'testme';
+ const action = addressActions.loadExternalPersonDetailAddressesSuccess(addresses);
+ const result = externalPersonAddressesReducer(INITIAL_STATE, action);
expect(result.loaded).toBe(true);
});
it('should trigger failed state', () => {
- const error: contactsActions.ILoadContactsFail = {payload: 'err_msg'};
- const action = contactsActions.loadContactsFail(error);
- const result = ContactsReducer(INITIAL_STATE, action);
+ const error: addressActions.ILoadExternalPersonAddressesFail = {payload: 'err_msg'};
+ const action = addressActions.loadExternalPersonDetailAddressesFail(error);
+ const result = externalPersonAddressesReducer(INITIAL_STATE, action);
expect(result).toEqual({
...INITIAL_STATE,
diff --git a/src/app/shared/store/reducers/contacts/contacts.reducer.ts b/src/app/shared/store/reducers/persons/external-person/addresses.reducer.ts
similarity index 71%
copy from src/app/shared/store/reducers/contacts/contacts.reducer.ts
copy to src/app/shared/store/reducers/persons/external-person/addresses.reducer.ts
index 8ddc539..c1588b2 100644
--- a/src/app/shared/store/reducers/contacts/contacts.reducer.ts
+++ b/src/app/shared/store/reducers/persons/external-person/addresses.reducer.ts
@@ -10,15 +10,15 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as contactsActions from '@shared/store/actions/contacts.action';
-import { Contact } from '@shared/models';
+import { Address } from '@app/shared/models/address/address.model';
+import * as externalPersonActions from '@shared/store/actions/persons/external-person.action';
import { createReducer, on } from '@ngrx/store';
export interface State {
loading: boolean;
loaded: boolean;
failed: boolean;
- data: Array<Contact>;
+ data: Array<Address>;
}
export const INITIAL_STATE: State = {
@@ -27,9 +27,9 @@
failed: false,
data: []
};
-export const ContactsReducer = createReducer(
+export const externalPersonAddressesReducer = createReducer(
INITIAL_STATE,
- on(contactsActions.loadContacts, (state: any, action: any) => {
+ on(externalPersonActions.loadExternalPersonDetailAddresses, (state: any, action: any) => {
return {
...state,
loading: true,
@@ -38,7 +38,7 @@
data: []
};
}),
- on(contactsActions.loadContactsSuccess, (state: any, action: any) => {
+ on(externalPersonActions.loadExternalPersonDetailAddressesSuccess, (state: any, action: any) => {
return {
...state,
loading: false,
@@ -47,7 +47,7 @@
data: action['payload']
};
}),
- on(contactsActions.loadContactsFail, (state: any, action: any) => {
+ on(externalPersonActions.loadExternalPersonDetailAddressesFail, (state: any, action: any) => {
return {
...state,
loaded: false,
@@ -58,11 +58,7 @@
})
);
export function reducer(state = INITIAL_STATE, action: any): State {
- if (!action) {
- return state;
- }
-
- return ContactsReducer(state, action);
+ return externalPersonAddressesReducer(state, action);
}
export const getData = (state: State) => state.data;
diff --git a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts b/src/app/shared/store/reducers/persons/external-person/communications-data-details-form.reducer.spec.ts
similarity index 62%
copy from src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts
copy to src/app/shared/store/reducers/persons/external-person/communications-data-details-form.reducer.spec.ts
index e6cdffb..6d865af 100644
--- a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts
+++ b/src/app/shared/store/reducers/persons/external-person/communications-data-details-form.reducer.spec.ts
@@ -10,40 +10,32 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as fromReducer from '@shared/store/reducers/salutations/salutations-details-form.reducer';
-import { Salutation } from '@shared/models';
+import * as fromReducer from '@shared/store/reducers/persons/external-person/communications-data-details-form.reducer';
+import { CommunicationsData } from '@shared/models';
import { Action } from '@ngrx/store';
import { FormGroupState } from 'ngrx-forms';
-
-describe('Salutation Detail Form reducer', () => {
+describe('CommunicationsData Form reducer', () => {
const { INITIAL_STATE } = fromReducer;
it('should return the default state when no state is given', () => {
const action: Action = { type: 'testAction' };
- const state: FormGroupState<Salutation> = fromReducer.reducer(undefined, action);
+ const state: FormGroupState<CommunicationsData> = fromReducer.reducer(undefined, action);
expect(state).toBe(INITIAL_STATE);
});
it('should return the initial state when action is not found', () => {
const action: Action = { type: 'testAction' };
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
+ const state: FormGroupState<CommunicationsData> = fromReducer.reducer(INITIAL_STATE, action);
expect(state).toBe(INITIAL_STATE);
});
it('should return the initial state when no action set', () => {
const action: Action = null;
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
+ const state: FormGroupState<CommunicationsData> = fromReducer.reducer(INITIAL_STATE, action);
expect(state).toBe(INITIAL_STATE);
});
-
- it('should return state via getFormState', () => {
- const action: Action = null;
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
- expect(fromReducer.getFormState(state)).toBe(state);
- });
-
});
diff --git a/src/app/shared/store/reducers/persons/external-person/communications-data-details-form.reducer.ts b/src/app/shared/store/reducers/persons/external-person/communications-data-details-form.reducer.ts
new file mode 100644
index 0000000..52f3a56
--- /dev/null
+++ b/src/app/shared/store/reducers/persons/external-person/communications-data-details-form.reducer.ts
@@ -0,0 +1,61 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { Action, ActionReducer, INIT } from '@ngrx/store';
+import * as externalPersonActions from '@shared/store/actions/persons/external-person.action';
+import {
+ createFormGroupState,
+ createFormStateReducerWithUpdate,
+ updateGroup,
+ FormGroupState,
+ FormState,
+ SetValueAction,
+ validate,
+} from 'ngrx-forms';
+import { CommunicationsData } from '@shared/models';
+import { required } from 'ngrx-forms/validation';
+
+export const FORM_ID = 'externalPersonCommunicationsDataDetailForm';
+
+export const INITIAL_STATE: FormGroupState<CommunicationsData> = createFormGroupState<
+CommunicationsData
+>(FORM_ID, new CommunicationsData());
+
+
+export const validateForm: ActionReducer<FormState<CommunicationsData>> = createFormStateReducerWithUpdate<CommunicationsData>(
+ updateGroup<CommunicationsData>(
+ {
+ communicationTypeId: validate(required),
+ }
+ )
+);
+
+
+export function reducer(
+ state: FormGroupState<CommunicationsData> = INITIAL_STATE,
+ action: Action
+): FormGroupState<CommunicationsData> {
+ if (!action || action.type === INIT) {
+ return INITIAL_STATE;
+ }
+
+ if (action.type === externalPersonActions.loadExternalPersonDetailCommunicationsDataDetailsSuccess.type) {
+ const externalPersonCommunicationsData: CommunicationsData = <CommunicationsData>action['payload'];
+ const setValueAction: SetValueAction<any> = new SetValueAction<any>(FORM_ID, externalPersonCommunicationsData);
+
+ return validateForm(state, setValueAction);
+ }
+
+ return validateForm(state, action);
+}
+export const getFormState = (state: FormGroupState<CommunicationsData>) => state;
+
diff --git a/src/app/shared/store/reducers/persons/external-person/communications-data.reducer.spec.ts b/src/app/shared/store/reducers/persons/external-person/communications-data.reducer.spec.ts
new file mode 100644
index 0000000..e2ec176
--- /dev/null
+++ b/src/app/shared/store/reducers/persons/external-person/communications-data.reducer.spec.ts
@@ -0,0 +1,80 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import {externalPersonCommunicationsDataReducer, INITIAL_STATE, getData, getLoading, getLoaded, getFailed, reducer} from '@shared/store/reducers/persons/external-person/communications-data.reducer';
+import * as addressActions from '@shared/store/actions/persons/external-person.action';
+import { CommunicationsData } from '@shared/models';
+
+describe('CommunicationsData reducer', () => {
+
+ it('should return the initial state', () => {
+ const action = { type: 'NOOP' } as any;
+ const result = reducer(undefined, action);
+
+ expect(result).toBe(INITIAL_STATE);
+ });
+
+ it('should trigger loading state', () => {
+ const action = addressActions.loadExternalPersonDetailCommunicationsData({payload: 'id'});
+ const result = externalPersonCommunicationsDataReducer(INITIAL_STATE, action);
+
+ expect(result).toEqual({
+ ...INITIAL_STATE,
+ loading: true,
+ });
+ });
+
+ it('should trigger loaded state', () => {
+ const addresses: addressActions.ILoadExternalPersonCommunicationsDataSuccess = {payload: [new CommunicationsData()]};
+ addresses.payload[0].communicationTypeId = 'testme';
+ const action = addressActions.loadExternalPersonDetailCommunicationsDataSuccess(addresses);
+ const result = externalPersonCommunicationsDataReducer(INITIAL_STATE, action);
+
+ expect(result.loaded).toBe(true);
+ });
+
+ it('should trigger failed state', () => {
+ const error: addressActions.ILoadExternalPersonCommunicationsDataFail = {payload: 'err_msg'};
+ const action = addressActions.loadExternalPersonDetailCommunicationsDataFail(error);
+ const result = externalPersonCommunicationsDataReducer(INITIAL_STATE, action);
+
+ expect(result).toEqual({
+ ...INITIAL_STATE,
+ failed: true,
+ });
+ });
+
+ it('getData return state.data', () => {
+ const state = { ...INITIAL_STATE };
+ const result = getData(state);
+ expect(result).toBe(state.data);
+ });
+
+ it('getLoading return state.loading', () => {
+ const state = { ...INITIAL_STATE };
+ const result = getLoading(state);
+ expect(result).toBe(state.loading);
+ });
+
+ it('getLoaded return state.loaded', () => {
+ const state = { ...INITIAL_STATE };
+ const result = getLoaded(state);
+ expect(result).toBe(state.loaded);
+ });
+
+ it('getFailed return state.failed', () => {
+ const state = { ...INITIAL_STATE };
+ const result = getFailed(state);
+ expect(result).toBe(state.failed);
+ });
+
+});
diff --git a/src/app/shared/store/reducers/contacts/contacts.reducer.ts b/src/app/shared/store/reducers/persons/external-person/communications-data.reducer.ts
similarity index 69%
copy from src/app/shared/store/reducers/contacts/contacts.reducer.ts
copy to src/app/shared/store/reducers/persons/external-person/communications-data.reducer.ts
index 8ddc539..575435e 100644
--- a/src/app/shared/store/reducers/contacts/contacts.reducer.ts
+++ b/src/app/shared/store/reducers/persons/external-person/communications-data.reducer.ts
@@ -10,15 +10,15 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as contactsActions from '@shared/store/actions/contacts.action';
-import { Contact } from '@shared/models';
+import * as externalPersonActions from '@shared/store/actions/persons/external-person.action';
import { createReducer, on } from '@ngrx/store';
+import { CommunicationsData } from '@shared/models';
export interface State {
loading: boolean;
loaded: boolean;
failed: boolean;
- data: Array<Contact>;
+ data: Array<CommunicationsData>;
}
export const INITIAL_STATE: State = {
@@ -27,9 +27,9 @@
failed: false,
data: []
};
-export const ContactsReducer = createReducer(
+export const externalPersonCommunicationsDataReducer = createReducer(
INITIAL_STATE,
- on(contactsActions.loadContacts, (state: any, action: any) => {
+ on(externalPersonActions.loadExternalPersonDetailCommunicationsData, (state: any, action: any) => {
return {
...state,
loading: true,
@@ -38,7 +38,7 @@
data: []
};
}),
- on(contactsActions.loadContactsSuccess, (state: any, action: any) => {
+ on(externalPersonActions.loadExternalPersonDetailCommunicationsDataSuccess, (state: any, action: any) => {
return {
...state,
loading: false,
@@ -47,7 +47,7 @@
data: action['payload']
};
}),
- on(contactsActions.loadContactsFail, (state: any, action: any) => {
+ on(externalPersonActions.loadExternalPersonDetailCommunicationsDataFail, (state: any, action: any) => {
return {
...state,
loaded: false,
@@ -58,11 +58,7 @@
})
);
export function reducer(state = INITIAL_STATE, action: any): State {
- if (!action) {
- return state;
- }
-
- return ContactsReducer(state, action);
+ return externalPersonCommunicationsDataReducer(state, action);
}
export const getData = (state: State) => state.data;
diff --git a/src/app/shared/store/reducers/persons/external-person/external-person-details-form.reducer.ts b/src/app/shared/store/reducers/persons/external-person/external-person-details-form.reducer.ts
index 380e000..445ac74 100644
--- a/src/app/shared/store/reducers/persons/external-person/external-person-details-form.reducer.ts
+++ b/src/app/shared/store/reducers/persons/external-person/external-person-details-form.reducer.ts
@@ -11,7 +11,7 @@
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
import { Action, ActionReducer, INIT } from '@ngrx/store';
-import * as externalPersonActions from '@app/shared/store/actions/persons/external-person.action';
+import * as externalPersonActions from '@shared/store/actions/persons/external-person.action';
import {
createFormGroupState,
createFormStateReducerWithUpdate,
@@ -26,16 +26,8 @@
export const FORM_ID = 'externalPersonDetailsForm';
-/**
- * The initial state of the details form.
- */
export const INITIAL_STATE: FormGroupState<ExternalPerson> = createFormGroupState<ExternalPerson>(FORM_ID, new ExternalPerson());
-/**
- * Validation function.
- *
- * @export
- */
export const validateForm: ActionReducer<FormState<ExternalPerson>> = createFormStateReducerWithUpdate<ExternalPerson>(
updateGroup<ExternalPerson>(
{
@@ -44,13 +36,6 @@
)
);
-/**
- * The reducer function.
- *
- * @export
- * @param {FormGroupState<ExternalPerson>} state FormGroupState object.
- * @param {Action} action Action being invoked on the FormState object.
- */
export function reducer(
state: FormGroupState<ExternalPerson> = INITIAL_STATE,
action: Action
diff --git a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts b/src/app/shared/store/reducers/persons/internal-person/addresses-details-form.reducer.spec.ts
similarity index 62%
copy from src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts
copy to src/app/shared/store/reducers/persons/internal-person/addresses-details-form.reducer.spec.ts
index e6cdffb..65e40db 100644
--- a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts
+++ b/src/app/shared/store/reducers/persons/internal-person/addresses-details-form.reducer.spec.ts
@@ -10,40 +10,32 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as fromReducer from '@shared/store/reducers/salutations/salutations-details-form.reducer';
-import { Salutation } from '@shared/models';
+import * as fromReducer from '@shared/store/reducers/persons/internal-person/addresses-details-form.reducer';
+import { Address } from '@shared/models';
import { Action } from '@ngrx/store';
import { FormGroupState } from 'ngrx-forms';
-
-describe('Salutation Detail Form reducer', () => {
+describe('Internal Person Addresses Form reducer', () => {
const { INITIAL_STATE } = fromReducer;
it('should return the default state when no state is given', () => {
const action: Action = { type: 'testAction' };
- const state: FormGroupState<Salutation> = fromReducer.reducer(undefined, action);
+ const state: FormGroupState<Address> = fromReducer.reducer(undefined, action);
expect(state).toBe(INITIAL_STATE);
});
it('should return the initial state when action is not found', () => {
const action: Action = { type: 'testAction' };
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
+ const state: FormGroupState<Address> = fromReducer.reducer(INITIAL_STATE, action);
expect(state).toBe(INITIAL_STATE);
});
it('should return the initial state when no action set', () => {
const action: Action = null;
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
+ const state: FormGroupState<Address> = fromReducer.reducer(INITIAL_STATE, action);
expect(state).toBe(INITIAL_STATE);
});
-
- it('should return state via getFormState', () => {
- const action: Action = null;
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
- expect(fromReducer.getFormState(state)).toBe(state);
- });
-
});
diff --git a/src/app/shared/store/reducers/persons/internal-person/addresses-details-form.reducer.ts b/src/app/shared/store/reducers/persons/internal-person/addresses-details-form.reducer.ts
new file mode 100644
index 0000000..03d7851
--- /dev/null
+++ b/src/app/shared/store/reducers/persons/internal-person/addresses-details-form.reducer.ts
@@ -0,0 +1,61 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { Action, ActionReducer, INIT } from '@ngrx/store';
+import * as internalPersonActions from '@shared/store/actions/persons/internal-person.action';
+import {
+ createFormGroupState,
+ createFormStateReducerWithUpdate,
+ updateGroup,
+ FormGroupState,
+ FormState,
+ SetValueAction,
+ validate,
+} from 'ngrx-forms';
+import { Address } from '@app/shared/models/address/address.model';
+import { required } from 'ngrx-forms/validation';
+
+export const FORM_ID = 'internalPersonAddressDetailForm';
+
+export const INITIAL_STATE: FormGroupState<Address> = createFormGroupState<
+Address
+>(FORM_ID, new Address());
+
+
+export const validateForm: ActionReducer<FormState<Address>> = createFormStateReducerWithUpdate<Address>(
+ updateGroup<Address>(
+ {
+ addressTypeId: validate(required),
+ }
+ )
+);
+
+
+export function reducer(
+ state: FormGroupState<Address> = INITIAL_STATE,
+ action: Action
+): FormGroupState<Address> {
+ if (!action || action.type === INIT) {
+ return INITIAL_STATE;
+ }
+
+ if (action.type === internalPersonActions.loadInternalPersonDetailAddressDetailsSuccess.type) {
+ const internalPersonAddress: Address = <Address>action['payload'];
+ const setValueAction: SetValueAction<any> = new SetValueAction<any>(FORM_ID, internalPersonAddress);
+
+ return validateForm(state, setValueAction);
+ }
+
+ return validateForm(state, action);
+}
+export const getFormState = (state: FormGroupState<Address>) => state;
+
diff --git a/src/app/shared/store/reducers/persons/internal-person/addresses.reducer.spec.ts b/src/app/shared/store/reducers/persons/internal-person/addresses.reducer.spec.ts
new file mode 100644
index 0000000..767e0ff
--- /dev/null
+++ b/src/app/shared/store/reducers/persons/internal-person/addresses.reducer.spec.ts
@@ -0,0 +1,80 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import {internalPersonAddressesReducer, INITIAL_STATE, getData, getLoading, getLoaded, getFailed, reducer} from '@shared/store/reducers/persons/internal-person/addresses.reducer';
+import * as addressActions from '@shared/store/actions/persons/internal-person.action';
+import { Address } from '@shared/models';
+
+describe('InternalPersonAddress reducer', () => {
+
+ it('should return the initial state', () => {
+ const action = { type: 'NOOP' } as any;
+ const result = reducer(undefined, action);
+
+ expect(result).toBe(INITIAL_STATE);
+ });
+
+ it('should trigger loading state', () => {
+ const action = addressActions.loadInternalPersonDetailAddresses({payload: 'id'});
+ const result = internalPersonAddressesReducer(INITIAL_STATE, action);
+
+ expect(result).toEqual({
+ ...INITIAL_STATE,
+ loading: true,
+ });
+ });
+
+ it('should trigger loaded state', () => {
+ const addresses: addressActions.ILoadInternalPersonAddressesSuccess = {payload: [new Address()]};
+ addresses.payload[0].addressTypeId = 'testme';
+ const action = addressActions.loadInternalPersonDetailAddressesSuccess(addresses);
+ const result = internalPersonAddressesReducer(INITIAL_STATE, action);
+
+ expect(result.loaded).toBe(true);
+ });
+
+ it('should trigger failed state', () => {
+ const error: addressActions.ILoadInternalPersonAddressesFail = {payload: 'err_msg'};
+ const action = addressActions.loadInternalPersonDetailAddressesFail(error);
+ const result = internalPersonAddressesReducer(INITIAL_STATE, action);
+
+ expect(result).toEqual({
+ ...INITIAL_STATE,
+ failed: true,
+ });
+ });
+
+ it('getData return state.data', () => {
+ const state = { ...INITIAL_STATE };
+ const result = getData(state);
+ expect(result).toBe(state.data);
+ });
+
+ it('getLoading return state.loading', () => {
+ const state = { ...INITIAL_STATE };
+ const result = getLoading(state);
+ expect(result).toBe(state.loading);
+ });
+
+ it('getLoaded return state.loaded', () => {
+ const state = { ...INITIAL_STATE };
+ const result = getLoaded(state);
+ expect(result).toBe(state.loaded);
+ });
+
+ it('getFailed return state.failed', () => {
+ const state = { ...INITIAL_STATE };
+ const result = getFailed(state);
+ expect(result).toBe(state.failed);
+ });
+
+});
diff --git a/src/app/shared/store/reducers/contacts/contacts.reducer.ts b/src/app/shared/store/reducers/persons/internal-person/addresses.reducer.ts
similarity index 71%
copy from src/app/shared/store/reducers/contacts/contacts.reducer.ts
copy to src/app/shared/store/reducers/persons/internal-person/addresses.reducer.ts
index 8ddc539..f11352b 100644
--- a/src/app/shared/store/reducers/contacts/contacts.reducer.ts
+++ b/src/app/shared/store/reducers/persons/internal-person/addresses.reducer.ts
@@ -10,15 +10,15 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as contactsActions from '@shared/store/actions/contacts.action';
-import { Contact } from '@shared/models';
+import { Address } from '@app/shared/models/address/address.model';
+import * as internalPersonActions from '@shared/store/actions/persons/internal-person.action';
import { createReducer, on } from '@ngrx/store';
export interface State {
loading: boolean;
loaded: boolean;
failed: boolean;
- data: Array<Contact>;
+ data: Array<Address>;
}
export const INITIAL_STATE: State = {
@@ -27,9 +27,9 @@
failed: false,
data: []
};
-export const ContactsReducer = createReducer(
+export const internalPersonAddressesReducer = createReducer(
INITIAL_STATE,
- on(contactsActions.loadContacts, (state: any, action: any) => {
+ on(internalPersonActions.loadInternalPersonDetailAddresses, (state: any, action: any) => {
return {
...state,
loading: true,
@@ -38,7 +38,7 @@
data: []
};
}),
- on(contactsActions.loadContactsSuccess, (state: any, action: any) => {
+ on(internalPersonActions.loadInternalPersonDetailAddressesSuccess, (state: any, action: any) => {
return {
...state,
loading: false,
@@ -47,7 +47,7 @@
data: action['payload']
};
}),
- on(contactsActions.loadContactsFail, (state: any, action: any) => {
+ on(internalPersonActions.loadInternalPersonDetailAddressesFail, (state: any, action: any) => {
return {
...state,
loaded: false,
@@ -58,11 +58,7 @@
})
);
export function reducer(state = INITIAL_STATE, action: any): State {
- if (!action) {
- return state;
- }
-
- return ContactsReducer(state, action);
+ return internalPersonAddressesReducer(state, action);
}
export const getData = (state: State) => state.data;
diff --git a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts b/src/app/shared/store/reducers/persons/internal-person/communications-data-details-form.reducer.spec.ts
similarity index 62%
copy from src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts
copy to src/app/shared/store/reducers/persons/internal-person/communications-data-details-form.reducer.spec.ts
index e6cdffb..88e02fa 100644
--- a/src/app/shared/store/reducers/salutations/salutations-details-form.reducer.spec.ts
+++ b/src/app/shared/store/reducers/persons/internal-person/communications-data-details-form.reducer.spec.ts
@@ -10,40 +10,32 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as fromReducer from '@shared/store/reducers/salutations/salutations-details-form.reducer';
-import { Salutation } from '@shared/models';
+import * as fromReducer from '@shared/store/reducers/persons/internal-person/communications-data-details-form.reducer';
+import { CommunicationsData } from '@shared/models';
import { Action } from '@ngrx/store';
import { FormGroupState } from 'ngrx-forms';
-
-describe('Salutation Detail Form reducer', () => {
+describe('Internal Person CommunicationsData Form reducer', () => {
const { INITIAL_STATE } = fromReducer;
it('should return the default state when no state is given', () => {
const action: Action = { type: 'testAction' };
- const state: FormGroupState<Salutation> = fromReducer.reducer(undefined, action);
+ const state: FormGroupState<CommunicationsData> = fromReducer.reducer(undefined, action);
expect(state).toBe(INITIAL_STATE);
});
it('should return the initial state when action is not found', () => {
const action: Action = { type: 'testAction' };
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
+ const state: FormGroupState<CommunicationsData> = fromReducer.reducer(INITIAL_STATE, action);
expect(state).toBe(INITIAL_STATE);
});
it('should return the initial state when no action set', () => {
const action: Action = null;
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
+ const state: FormGroupState<CommunicationsData> = fromReducer.reducer(INITIAL_STATE, action);
expect(state).toBe(INITIAL_STATE);
});
-
- it('should return state via getFormState', () => {
- const action: Action = null;
- const state: FormGroupState<Salutation> = fromReducer.reducer(INITIAL_STATE, action);
- expect(fromReducer.getFormState(state)).toBe(state);
- });
-
});
diff --git a/src/app/shared/store/reducers/persons/internal-person/communications-data-details-form.reducer.ts b/src/app/shared/store/reducers/persons/internal-person/communications-data-details-form.reducer.ts
new file mode 100644
index 0000000..28c2e90
--- /dev/null
+++ b/src/app/shared/store/reducers/persons/internal-person/communications-data-details-form.reducer.ts
@@ -0,0 +1,61 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { Action, ActionReducer, INIT } from '@ngrx/store';
+import * as internalPersonActions from '@shared/store/actions/persons/internal-person.action';
+import {
+ createFormGroupState,
+ createFormStateReducerWithUpdate,
+ updateGroup,
+ FormGroupState,
+ FormState,
+ SetValueAction,
+ validate,
+} from 'ngrx-forms';
+import { CommunicationsData } from '@shared/models';
+import { required } from 'ngrx-forms/validation';
+
+export const FORM_ID = 'internalPersonCommunicationsDataDetailForm';
+
+export const INITIAL_STATE: FormGroupState<CommunicationsData> = createFormGroupState<
+CommunicationsData
+>(FORM_ID, new CommunicationsData());
+
+
+export const validateForm: ActionReducer<FormState<CommunicationsData>> = createFormStateReducerWithUpdate<CommunicationsData>(
+ updateGroup<CommunicationsData>(
+ {
+ communicationTypeId: validate(required),
+ }
+ )
+);
+
+
+export function reducer(
+ state: FormGroupState<CommunicationsData> = INITIAL_STATE,
+ action: Action
+): FormGroupState<CommunicationsData> {
+ if (!action || action.type === INIT) {
+ return INITIAL_STATE;
+ }
+
+ if (action.type === internalPersonActions.loadInternalPersonDetailCommunicationsDataDetailsSuccess.type) {
+ const internalPersonCommunicationsData: CommunicationsData = <CommunicationsData>action['payload'];
+ const setValueAction: SetValueAction<any> = new SetValueAction<any>(FORM_ID, internalPersonCommunicationsData);
+
+ return validateForm(state, setValueAction);
+ }
+
+ return validateForm(state, action);
+}
+export const getFormState = (state: FormGroupState<CommunicationsData>) => state;
+
diff --git a/src/app/shared/store/reducers/persons/internal-person/communications-data.reducer.spec.ts b/src/app/shared/store/reducers/persons/internal-person/communications-data.reducer.spec.ts
new file mode 100644
index 0000000..9f72d7c
--- /dev/null
+++ b/src/app/shared/store/reducers/persons/internal-person/communications-data.reducer.spec.ts
@@ -0,0 +1,80 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import {internalPersonCommunicationsDataReducer, INITIAL_STATE, getData, getLoading, getLoaded, getFailed, reducer} from '@shared/store/reducers/persons/internal-person/communications-data.reducer';
+import * as addressActions from '@shared/store/actions/persons/internal-person.action';
+import { CommunicationsData } from '@shared/models';
+
+describe('InternalPersonCommunicationsData reducer', () => {
+
+ it('should return the initial state', () => {
+ const action = { type: 'NOOP' } as any;
+ const result = reducer(undefined, action);
+
+ expect(result).toBe(INITIAL_STATE);
+ });
+
+ it('should trigger loading state', () => {
+ const action = addressActions.loadInternalPersonDetailCommunicationsData({payload: 'id'});
+ const result = internalPersonCommunicationsDataReducer(INITIAL_STATE, action);
+
+ expect(result).toEqual({
+ ...INITIAL_STATE,
+ loading: true,
+ });
+ });
+
+ it('should trigger loaded state', () => {
+ const addresses: addressActions.ILoadInternalPersonCommunicationsDataSuccess = {payload: [new CommunicationsData()]};
+ addresses.payload[0].communicationTypeId = 'testme';
+ const action = addressActions.loadInternalPersonDetailCommunicationsDataSuccess(addresses);
+ const result = internalPersonCommunicationsDataReducer(INITIAL_STATE, action);
+
+ expect(result.loaded).toBe(true);
+ });
+
+ it('should trigger failed state', () => {
+ const error: addressActions.ILoadInternalPersonCommunicationsDataFail = {payload: 'err_msg'};
+ const action = addressActions.loadInternalPersonDetailCommunicationsDataFail(error);
+ const result = internalPersonCommunicationsDataReducer(INITIAL_STATE, action);
+
+ expect(result).toEqual({
+ ...INITIAL_STATE,
+ failed: true,
+ });
+ });
+
+ it('getData return state.data', () => {
+ const state = { ...INITIAL_STATE };
+ const result = getData(state);
+ expect(result).toBe(state.data);
+ });
+
+ it('getLoading return state.loading', () => {
+ const state = { ...INITIAL_STATE };
+ const result = getLoading(state);
+ expect(result).toBe(state.loading);
+ });
+
+ it('getLoaded return state.loaded', () => {
+ const state = { ...INITIAL_STATE };
+ const result = getLoaded(state);
+ expect(result).toBe(state.loaded);
+ });
+
+ it('getFailed return state.failed', () => {
+ const state = { ...INITIAL_STATE };
+ const result = getFailed(state);
+ expect(result).toBe(state.failed);
+ });
+
+});
diff --git a/src/app/shared/store/reducers/contacts/contacts.reducer.ts b/src/app/shared/store/reducers/persons/internal-person/communications-data.reducer.ts
similarity index 69%
copy from src/app/shared/store/reducers/contacts/contacts.reducer.ts
copy to src/app/shared/store/reducers/persons/internal-person/communications-data.reducer.ts
index 8ddc539..dc6e572 100644
--- a/src/app/shared/store/reducers/contacts/contacts.reducer.ts
+++ b/src/app/shared/store/reducers/persons/internal-person/communications-data.reducer.ts
@@ -10,15 +10,15 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import * as contactsActions from '@shared/store/actions/contacts.action';
-import { Contact } from '@shared/models';
+import * as internalPersonActions from '@shared/store/actions/persons/internal-person.action';
import { createReducer, on } from '@ngrx/store';
+import { CommunicationsData } from '@shared/models';
export interface State {
loading: boolean;
loaded: boolean;
failed: boolean;
- data: Array<Contact>;
+ data: Array<CommunicationsData>;
}
export const INITIAL_STATE: State = {
@@ -27,9 +27,9 @@
failed: false,
data: []
};
-export const ContactsReducer = createReducer(
+export const internalPersonCommunicationsDataReducer = createReducer(
INITIAL_STATE,
- on(contactsActions.loadContacts, (state: any, action: any) => {
+ on(internalPersonActions.loadInternalPersonDetailCommunicationsData, (state: any, action: any) => {
return {
...state,
loading: true,
@@ -38,7 +38,7 @@
data: []
};
}),
- on(contactsActions.loadContactsSuccess, (state: any, action: any) => {
+ on(internalPersonActions.loadInternalPersonDetailCommunicationsDataSuccess, (state: any, action: any) => {
return {
...state,
loading: false,
@@ -47,7 +47,7 @@
data: action['payload']
};
}),
- on(contactsActions.loadContactsFail, (state: any, action: any) => {
+ on(internalPersonActions.loadInternalPersonDetailCommunicationsDataFail, (state: any, action: any) => {
return {
...state,
loaded: false,
@@ -58,11 +58,7 @@
})
);
export function reducer(state = INITIAL_STATE, action: any): State {
- if (!action) {
- return state;
- }
-
- return ContactsReducer(state, action);
+ return internalPersonCommunicationsDataReducer(state, action);
}
export const getData = (state: State) => state.data;
diff --git a/src/app/shared/store/reducers/persons/internal-person/internal-person-details-form.reducer.ts b/src/app/shared/store/reducers/persons/internal-person/internal-person-details-form.reducer.ts
index c1e0961..e780548 100644
--- a/src/app/shared/store/reducers/persons/internal-person/internal-person-details-form.reducer.ts
+++ b/src/app/shared/store/reducers/persons/internal-person/internal-person-details-form.reducer.ts
@@ -11,7 +11,7 @@
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
import { Action, ActionReducer, INIT } from '@ngrx/store';
-import * as internalPersonActions from '@app/shared/store/actions/persons/internal-person.action';
+import * as internalPersonActions from '@shared/store/actions/persons/internal-person.action';
import {
createFormGroupState,
createFormStateReducerWithUpdate,
@@ -26,16 +26,8 @@
export const FORM_ID = 'internalPersonDetailsForm';
-/**
- * The initial state of the details form.
- */
export const INITIAL_STATE: FormGroupState<InternalPerson> = createFormGroupState<InternalPerson>(FORM_ID, new InternalPerson());
-/**
- * Validation function.
- *
- * @export
- */
export const validateForm: ActionReducer<FormState<InternalPerson>> = createFormStateReducerWithUpdate<InternalPerson>(
updateGroup<InternalPerson>(
{
@@ -44,13 +36,6 @@
)
);
-/**
- * The reducer function.
- *
- * @export
- * @param {FormGroupState<InternalPerson>} state FormGroupState object.
- * @param {Action} action Action being invoked on the FormState object.
- */
export function reducer(
state: FormGroupState<InternalPerson> = INITIAL_STATE,
action: Action
diff --git a/src/app/shared/utility/utility.service.spec.ts b/src/app/shared/utility/utility.service.spec.ts
new file mode 100644
index 0000000..71846f4
--- /dev/null
+++ b/src/app/shared/utility/utility.service.spec.ts
@@ -0,0 +1,96 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { UtilService } from '@shared/utility';
+
+describe('UtilService', () => {
+ let component: UtilService;
+ let translateService: any;
+ let notificationService: any;
+ let configService: any;
+
+ beforeEach(async(() => {
+ translateService = {
+ instant() {},
+ } as any;
+
+ notificationService = {
+ info: () => ({}),
+ error: () => ({}),
+ success: () => ({}),
+ alert: () => ({}),
+ } as any;
+
+ configService = {
+ get: () => ({options: null}),
+ } as any;
+ }));
+
+ beforeEach(() => {
+ component = new UtilService(translateService, notificationService, configService);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should show info notifications after call displayNotification', () => {
+ const messageTranslationCode = 'hello';
+ const type = 'info';
+ const titleTranslationCode = 'title';
+ const spyTranslation = spyOn(translateService, 'instant');
+
+ component.displayNotification(messageTranslationCode, type, titleTranslationCode);
+ expect(spyTranslation).toHaveBeenCalledWith(messageTranslationCode);
+ });
+
+ it('should show error notifications after call displayNotification', () => {
+ const messageTranslationCode = 'hello';
+ const type = 'error';
+ const titleTranslationCode = 'title';
+ const spyTranslation = spyOn(translateService, 'instant');
+
+ component.displayNotification(messageTranslationCode, type, titleTranslationCode);
+ expect(spyTranslation).toHaveBeenCalledWith(messageTranslationCode);
+ });
+
+ it('should show success notifications after call displayNotification', () => {
+ const messageTranslationCode = 'hello';
+ const type = 'success';
+ const titleTranslationCode = 'title';
+ const spyTranslation = spyOn(translateService, 'instant');
+
+ component.displayNotification(messageTranslationCode, type, titleTranslationCode);
+ expect(spyTranslation).toHaveBeenCalledWith(messageTranslationCode);
+ });
+
+ it('should show alert notifications after call displayNotification', () => {
+ const messageTranslationCode = 'hello';
+ const type = 'alert';
+ const titleTranslationCode = 'title';
+ const spyTranslation = spyOn(translateService, 'instant');
+
+ component.displayNotification(messageTranslationCode, type, titleTranslationCode);
+ expect(spyTranslation).toHaveBeenCalledWith(messageTranslationCode);
+ });
+
+ it('should show notifications after call displayNotification without titleTranslationCode', () => {
+ const messageTranslationCode = 'hello';
+ const type = 'alert';
+ const titleTranslationCode = null;
+ const spyTranslation = spyOn(translateService, 'instant');
+
+ component.displayNotification(messageTranslationCode, type, titleTranslationCode);
+ expect(spyTranslation).toHaveBeenCalledWith(messageTranslationCode);
+ });
+});
diff --git a/src/app/shared/utility/utilityHelpers.spec.ts b/src/app/shared/utility/utilityHelpers.spec.ts
new file mode 100644
index 0000000..67437ed
--- /dev/null
+++ b/src/app/shared/utility/utilityHelpers.spec.ts
@@ -0,0 +1,15 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+
+describe('utilityHelpers', () => {
+});
diff --git a/src/app/shared/utility/utilityHelpers.ts b/src/app/shared/utility/utilityHelpers.ts
index a874dd6..a57e83f 100644
--- a/src/app/shared/utility/utilityHelpers.ts
+++ b/src/app/shared/utility/utilityHelpers.ts
@@ -10,122 +10,6 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
-import { Observable } from 'rxjs/Rx';
-import { Store } from '@ngrx/store';
-import { State } from '../store';
-
-let typeCache: { [label: string]: boolean } = {};
-
-type Predicate = (oldValues: Array<any>, newValues: Array<any>) => boolean;
-
-/**
- * This function coerces a string into a string literal type.
- * Using tagged union types in TypeScript 2.0, this enables
- * powerful typechecking of our reducers.
- *
- * Since every action label passes through this function it
- * is a good place to ensure all of our action labels are unique.
- *
- * @param label
- */
-export function type<T>(label: T | ''): T {
- if (typeCache[<string>label]) {
- throw new Error(`Action type "${label}" is not unqiue"`);
- }
-
- typeCache[<string>label] = true;
-
- return <T>label;
-}
-
-/**
- * Runs through every condition, compares new and old values and returns true/false depends on condition state.
- * This is used to distinct if two observable values have changed.
- *
- * @param oldValues
- * @param newValues
- * @param conditions
- */
-export function distinctChanges(
- oldValues: Array<any>,
- newValues: Array<any>,
- conditions: Predicate[]
-): boolean {
- if (conditions.every(cond => cond(oldValues, newValues))) {
- return false;
- }
- return true;
-}
-
-/**
- * Returns true if the given value is type of Object
- *
- * @param val
- */
-export function isObject(val: any) {
- if (val === null) {
- return false;
- }
-
- return typeof val === 'function' || typeof val === 'object';
-}
-
-/**
- * Capitalizes the first character in given string
- *
- * @param s
- */
-export function capitalize(s: string) {
- if (!s || typeof s !== 'string') {
- return s;
- }
- return s && s[0].toUpperCase() + s.slice(1);
-}
-
-/**
- * Uncapitalizes the first character in given string
- *
- * @param s
- */
-export function uncapitalize(s: string) {
- if (!s || typeof s !== 'string') {
- return s;
- }
- return s && s[0].toLowerCase() + s.slice(1);
-}
-
-/**
- * Flattens multi dimensional object into one level deep
- *
- * @param obj
- * @param preservePath
- */
-export function flattenObject(ob: any, preservePath: boolean = false): any {
- let toReturn = {};
-
- for (let prop in ob) {
- if (!ob.hasOwnProperty(prop)) {
- continue;
- }
-
- if (typeof ob[prop] === 'object') {
- const flatObject = flattenObject(ob[prop], preservePath);
- for (let flatProp in flatObject) {
- if (!flatObject.hasOwnProperty(flatProp)) {
- continue;
- }
-
- const path = preservePath ? prop + '.' + flatProp : flatProp;
-
- toReturn[path] = flatObject[flatProp];
- }
- } else {
- toReturn[prop] = ob[prop];
- }
- }
-
- return toReturn;
-}
/**
* Returns formated date based on given culture
diff --git a/src/app/shared/utility/validation.service.spec.ts b/src/app/shared/utility/validation.service.spec.ts
new file mode 100644
index 0000000..965edcb
--- /dev/null
+++ b/src/app/shared/utility/validation.service.spec.ts
@@ -0,0 +1,61 @@
+ /********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import { async } from '@angular/core/testing';
+import { ValidationService } from '@shared/utility';
+
+describe('ValidationService', () => {
+ let component: ValidationService;
+
+ beforeEach(async(() => {
+ }));
+
+ beforeEach(() => {
+ component = new ValidationService();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should return null if the mail is valid', () => {
+ let formControl: any;
+ formControl = {value: 'test@test.de'};
+
+ const retsult = component.validateEmail(formControl);
+ expect(retsult).toBe(null);
+ });
+
+ it('should return error message if the mail is not valid', () => {
+ let formControl: any;
+ formControl = {value: 'test&test.de'};
+
+ const retsult = component.validateEmail(formControl);
+ expect(retsult).not.toBe(null);
+ });
+
+ it('should return null if the value is numeric', () => {
+ let formControl: any;
+ formControl = {value: 222};
+
+ const retsult = component.numericRequired(formControl);
+ expect(retsult).toBe(null);
+ });
+
+ it('should return error message if the value is not numeric', () => {
+ let formControl: any;
+ formControl = {value: 'test'};
+
+ const retsult = component.numericRequired(formControl);
+ expect(retsult).not.toBe(null);
+ });
+});
diff --git a/src/styles.scss b/src/styles.scss
index f6e483a..2dbdaf8 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -10,7 +10,7 @@
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
- /* ****************************************
+/* ****************************************
* Imports
* ****************************************/
@import '~ag-grid-community/dist/styles/ag-grid.css';
@@ -1371,7 +1371,7 @@
display: block;
width: 100%;
padding: 6px 12px;
- font-size: 14px;
+ font-size: 13px;
line-height: 1.25;
color: #495057;
background-color: #fff;
@@ -1401,7 +1401,7 @@
opacity: 1;
}
select.form-control:not([size]):not([multiple]) {
- height: calc(2.25rem + 2px);
+ height: calc(2.25rem - 4px);
}
select.form-control:focus::-ms-value {
color: #495057;
@@ -1479,7 +1479,7 @@
.input-group-lg > select.form-control:not([size]):not([multiple]),
.input-group-lg > select.input-group-addon:not([size]):not([multiple]),
.input-group-lg > .input-group-btn > select.btn:not([size]):not([multiple]) {
- height: calc(2.3125rem + 2px);
+ height: calc(2.3125rem + -2px);
}
.form-group {
margin-bottom: 1rem;
@@ -4151,185 +4151,6 @@
background-color: #000;
border-radius: 0.25rem;
}
-.popover {
- position: absolute;
- top: 0;
- left: 0;
- z-index: 1060;
- display: block;
- max-width: 276px;
- padding: 1px;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
- font-style: normal;
- font-weight: normal;
- line-height: 1.5;
- text-align: left;
- text-align: start;
- text-decoration: none;
- text-shadow: none;
- text-transform: none;
- letter-spacing: normal;
- word-break: normal;
- word-spacing: normal;
- white-space: normal;
- line-break: auto;
- font-size: 0.875rem;
- word-wrap: break-word;
- background-color: #fff;
- background-clip: padding-box;
- border: 1px solid rgba(0, 0, 0, 0.2);
- border-radius: 0.3rem;
-}
-.popover .arrow {
- position: absolute;
- display: block;
- width: 10px;
- height: 5px;
-}
-.popover .arrow::before,
-.popover .arrow::after {
- position: absolute;
- display: block;
- border-color: transparent;
- border-style: solid;
-}
-.popover .arrow::before {
- content: '';
- border-width: 11px;
-}
-.popover .arrow::after {
- content: '';
- border-width: 11px;
-}
-.popover.bs-popover-top,
-.popover.bs-popover-auto[x-placement^='top'] {
- margin-bottom: 10px;
-}
-.popover.bs-popover-top .arrow,
-.popover.bs-popover-auto[x-placement^='top'] .arrow {
- bottom: 0;
-}
-.popover.bs-popover-top .arrow::before,
-.popover.bs-popover-auto[x-placement^='top'] .arrow::before,
-.popover.bs-popover-top .arrow::after,
-.popover.bs-popover-auto[x-placement^='top'] .arrow::after {
- border-bottom-width: 0;
-}
-.popover.bs-popover-top .arrow::before,
-.popover.bs-popover-auto[x-placement^='top'] .arrow::before {
- bottom: -11px;
- margin-left: -6px;
- border-top-color: rgba(0, 0, 0, 0.25);
-}
-.popover.bs-popover-top .arrow::after,
-.popover.bs-popover-auto[x-placement^='top'] .arrow::after {
- bottom: -10px;
- margin-left: -6px;
- border-top-color: #fff;
-}
-.popover.bs-popover-right,
-.popover.bs-popover-auto[x-placement^='right'] {
- margin-left: 10px;
-}
-.popover.bs-popover-right .arrow,
-.popover.bs-popover-auto[x-placement^='right'] .arrow {
- left: 0;
-}
-.popover.bs-popover-right .arrow::before,
-.popover.bs-popover-auto[x-placement^='right'] .arrow::before,
-.popover.bs-popover-right .arrow::after,
-.popover.bs-popover-auto[x-placement^='right'] .arrow::after {
- margin-top: -8px;
- border-left-width: 0;
-}
-.popover.bs-popover-right .arrow::before,
-.popover.bs-popover-auto[x-placement^='right'] .arrow::before {
- left: -11px;
- border-right-color: rgba(0, 0, 0, 0.25);
-}
-.popover.bs-popover-right .arrow::after,
-.popover.bs-popover-auto[x-placement^='right'] .arrow::after {
- left: -10px;
- border-right-color: #fff;
-}
-.popover.bs-popover-bottom,
-.popover.bs-popover-auto[x-placement^='bottom'] {
- margin-top: 10px;
-}
-.popover.bs-popover-bottom .arrow,
-.popover.bs-popover-auto[x-placement^='bottom'] .arrow {
- top: 0;
-}
-.popover.bs-popover-bottom .arrow::before,
-.popover.bs-popover-auto[x-placement^='bottom'] .arrow::before,
-.popover.bs-popover-bottom .arrow::after,
-.popover.bs-popover-auto[x-placement^='bottom'] .arrow::after {
- margin-left: -7px;
- border-top-width: 0;
-}
-.popover.bs-popover-bottom .arrow::before,
-.popover.bs-popover-auto[x-placement^='bottom'] .arrow::before {
- top: -11px;
- border-bottom-color: rgba(0, 0, 0, 0.25);
-}
-.popover.bs-popover-bottom .arrow::after,
-.popover.bs-popover-auto[x-placement^='bottom'] .arrow::after {
- top: -10px;
- border-bottom-color: #fff;
-}
-.popover.bs-popover-bottom .popover-header::before,
-.popover.bs-popover-auto[x-placement^='bottom'] .popover-header::before {
- position: absolute;
- top: 0;
- left: 50%;
- display: block;
- width: 20px;
- margin-left: -10px;
- content: '';
- border-bottom: 1px solid #f7f7f7;
-}
-.popover.bs-popover-left,
-.popover.bs-popover-auto[x-placement^='left'] {
- margin-right: 10px;
-}
-.popover.bs-popover-left .arrow,
-.popover.bs-popover-auto[x-placement^='left'] .arrow {
- right: 0;
-}
-.popover.bs-popover-left .arrow::before,
-.popover.bs-popover-auto[x-placement^='left'] .arrow::before,
-.popover.bs-popover-left .arrow::after,
-.popover.bs-popover-auto[x-placement^='left'] .arrow::after {
- margin-top: -8px;
- border-right-width: 0;
-}
-.popover.bs-popover-left .arrow::before,
-.popover.bs-popover-auto[x-placement^='left'] .arrow::before {
- right: -11px;
- border-left-color: rgba(0, 0, 0, 0.25);
-}
-.popover.bs-popover-left .arrow::after,
-.popover.bs-popover-auto[x-placement^='left'] .arrow::after {
- right: -10px;
- border-left-color: #fff;
-}
-.popover-header {
- padding: 8px 14px;
- margin-bottom: 0;
- font-size: 1rem;
- color: inherit;
- background-color: #f7f7f7;
- border-bottom: 1px solid #ebebeb;
- border-top-left-radius: calc(0.3rem - 1px);
- border-top-right-radius: calc(0.3rem - 1px);
-}
-.popover-header:empty {
- display: none;
-}
-.popover-body {
- padding: 9px 14px;
- color: #212529;
-}
.carousel {
position: relative;
}
@@ -7207,17 +7028,17 @@
.ngrx-forms-valid[required],
.ngrx-forms-valid.required {
- border-left: 5px solid #42A948;
- /* green */
+ border-left: 5px solid #42a948;
+ /* green */
}
.ngrx-forms-invalid:not(form) {
- border-left: 5px solid #a94442;
- /* red */
+ border-left: 5px solid #a94442;
+ /* red */
}
.error {
- border-left: 5px solid #a94442;
+ border-left: 5px solid #a94442;
}
// toaster error font color
diff --git a/sw-precache-config.js b/sw-precache-config.js
deleted file mode 100644
index f75034a..0000000
--- a/sw-precache-config.js
+++ /dev/null
@@ -1,31 +0,0 @@
- /********************************************************************************
- * Copyright (c) 2020 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- ********************************************************************************/
-module.exports = {
- navigateFallback: '/index.html',
- stripPrefix: './dist',
- root: './dist/',
- staticFileGlobs: [
- './dist/index.html',
- './dist/**.js',
- './dist/**.css',
- './dist/**.ttf',
- './dist/assets/images/*',
- './dist/config/*',
- './dist/i18n/en.json',
- './dist/i18n/de.json'
- ],
- runtimeCaching: [{
- urlPattern: '',
- handler: 'fastest'
- }]
-};
diff --git a/yarn.lock b/yarn.lock
index 9717340..c65c290 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8989,22 +8989,6 @@
dependencies:
has-flag "^3.0.0"
-sw-precache@^5.0.0:
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/sw-precache/-/sw-precache-5.2.1.tgz#06134f319eec68f3b9583ce9a7036b1c119f7179"
- integrity sha512-8FAy+BP/FXE+ILfiVTt+GQJ6UEf4CVHD9OfhzH0JX+3zoy2uFk7Vn9EfXASOtVmmIVbL3jE/W8Z66VgPSZcMhw==
- dependencies:
- dom-urls "^1.1.0"
- es6-promise "^4.0.5"
- glob "^7.1.1"
- lodash.defaults "^4.2.0"
- lodash.template "^4.4.0"
- meow "^3.7.0"
- mkdirp "^0.5.1"
- pretty-bytes "^4.0.2"
- sw-toolbox "^3.4.0"
- update-notifier "^2.3.0"
-
sw-toolbox@^3.4.0, sw-toolbox@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/sw-toolbox/-/sw-toolbox-3.6.0.tgz#26df1d1c70348658e4dea2884319149b7b3183b5"