From 26fb79c39ded1c32fc73fc327a0eb296577cd669 Mon Sep 17 00:00:00 2001 From: Luke Stanley Date: Tue, 9 Jan 2024 16:44:57 +0000 Subject: [PATCH] Linting --- .eslintrc.json | 4 +- angular.json | 35 +- cypress/e2e/gosub.ts | 83 +- cypress/e2e/share.ts | 98 +- cypress/e2e/spec.ts | 167 +- cypress/fixtures/listWorkflowsFlow.json | 362 ++-- cypress/fixtures/workflow-cloud.json | 292 ++- src/app/_shared/base/base.component.ts | 33 +- .../_shared/services/validation.service.ts | 32 +- src/app/_shared/shared.module.ts | 87 +- src/app/_shared/ui-form/config.ts | 263 +-- .../ui-form/types/countries.component.ts | 559 +++--- .../ui-form/types/image-viewer.type.ts | 56 +- .../_shared/ui-form/types/money.component.ts | 39 +- src/app/_shared/ui-form/types/null.type.ts | 81 +- .../ui-form/types/percentage.component.ts | 32 +- .../ui-form/types/playlists.component.ts | 111 +- .../_shared/ui-form/types/textarea.type.ts | 102 +- .../_shared/ui-form/types/timepicker.type.ts | 45 +- .../ui-form/types/typeahead.component.ts | 83 +- .../ui-form/types/video-viewer.component.ts | 70 +- .../ui-form/types/video-viewer2.component.ts | 83 +- .../ui-form/types/video-viewerDM.component.ts | 94 +- .../ui-form/types/visibility.component.ts | 44 +- src/app/_shared/ui-form/ui-form.module.ts | 52 +- src/app/app-material/app-material.module.ts | 71 +- src/app/app.module.ts | 765 ++++---- src/app/auth/dirty.guard.ts | 17 +- .../button-block/button-block.component.ts | 38 +- .../dialog-block/dialog-block.component.ts | 47 +- .../http-block/http-block.component.spec.ts | 68 +- .../blocks/http-block/http-block.component.ts | 339 ++-- .../variable-set/variable-set.component.ts | 70 +- src/app/channels/channels.module.ts | 25 +- ...lock-comparison-builder-box.component.html | 237 ++- .../block-comparison-builder-box.component.ts | 151 +- .../blocks-editor/blocks-editor.component.ts | 58 +- src/app/components/layout/layout.component.ts | 98 +- ...r-blocks-config-select-dialog.component.ts | 53 +- .../adapter-query-select-dialog.component.ts | 48 +- .../add-block-dialog.component.ts | 26 +- .../add-new-node-dialog.component.ts | 25 +- .../api-data-select-dialog.component.ts | 33 +- .../blocks-dialog/blocks-dialog.component.ts | 23 +- .../confirm-delete-dialog.component.ts | 17 +- .../edit-clip-dialog.component.ts | 32 +- ...it-workflow-metadata-dialog.component.html | 46 +- ...edit-workflow-metadata-dialog.component.ts | 44 +- .../export-config-dialog.component.ts | 19 +- .../form-data-select-dialog.component.ts | 20 +- .../form-select-dialog.component.ts | 30 +- .../import-progress-dialog.component.ts | 53 +- .../load-workflow-dialog.component.ts | 22 +- .../paste-config-dialog.component.ts | 18 +- .../save-workflow-dialog.component.ts | 49 +- .../show-share-link-dialog.component.ts | 24 +- .../swagger-form-select-dialog.component.ts | 75 +- .../test-import-dialog.component.ts | 53 +- .../audio-input-control.component.ts | 92 +- .../formly-workflow-field.component.ts | 39 +- .../blocks-builder-page.component.ts | 51 +- .../bloomen-test-page.component.ts | 122 +- .../docs-list-page.component.ts | 39 +- .../form-builder-page.component.html | 114 +- .../form-builder-page.component.ts | 182 +- .../kql-builder/kql-builder.component.html | 42 +- .../kql-builder/kql-builder.component.ts | 164 +- .../query-builder-page.component.html | 72 +- .../query-builder-page.component.ts | 218 ++- .../settings-page/settings-page.component.ts | 44 +- .../test-api-page/test-api-page.component.ts | 87 +- .../upload-page/upload-page.component.ts | 1716 +++++++++-------- .../services/adapter-form-select.service.ts | 41 +- src/app/services/adapter-install.service.ts | 239 ++- src/app/services/form-data.service.ts | 76 +- .../services/global-error-handler.service.ts | 23 +- .../services/share-link-generator.service.ts | 44 +- src/app/services/workflow.service.ts | 291 ++- src/styles.scss | 59 +- 79 files changed, 4998 insertions(+), 4358 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 57660e0e0..6be522b7b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -9,8 +9,6 @@ "ecmaVersion": "latest", "sourceType": "module" }, - "plugins": [ - "@typescript-eslint" - ], + "plugins": ["@typescript-eslint"], "rules": {} } diff --git a/angular.json b/angular.json index aefe73e51..4645b8270 100644 --- a/angular.json +++ b/angular.json @@ -15,14 +15,12 @@ "@schematics/angular:application": { "strict": true } - }, + }, "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", "options": { - "allowedCommonJsDependencies": [ - "lodash" - ], + "allowedCommonJsDependencies": ["lodash"], "outputPath": "dist", "index": "src/index.html", "main": "src/main.ts", @@ -36,7 +34,11 @@ "src/mstile-150x150.png", "src/assets", "src/manifest.json", - { "glob": "**/*", "input": "node_modules/monaco-editor", "output": "/assets/monaco/" } + { + "glob": "**/*", + "input": "node_modules/monaco-editor", + "output": "/assets/monaco/" + } ], "styles": [ "node_modules/@fortawesome/fontawesome-free/css/all.css", @@ -160,15 +162,9 @@ "polyfills": "src/polyfills.ts", "tsConfig": "src/tsconfig.spec.json", "karmaConfig": "src/karma.conf.js", - "styles": [ - "src/styles.scss" - ], + "styles": ["src/styles.scss"], "scripts": [], - "assets": [ - "src/favicon.ico", - "src/assets", - "src/manifest.json" - ] + "assets": ["src/favicon.ico", "src/assets", "src/manifest.json"] } }, "cypress-run": { @@ -176,8 +172,7 @@ "options": { "devServerTarget": "kendraio-app:serve" }, - "configurations": { - } + "configurations": {} }, "cypress-open": { "builder": "@cypress/schematic:cypress", @@ -193,8 +188,7 @@ "watch": true, "headless": false }, - "configurations": { - } + "configurations": {} } } }, @@ -218,12 +212,9 @@ } } } - }, "cli": { "analytics": false, - "schematicCollections": [ - "@ngrx/schematics" - ] + "schematicCollections": ["@ngrx/schematics"] } -} \ No newline at end of file +} diff --git a/cypress/e2e/gosub.ts b/cypress/e2e/gosub.ts index ad305ff1c..edeab647a 100644 --- a/cypress/e2e/gosub.ts +++ b/cypress/e2e/gosub.ts @@ -1,46 +1,47 @@ -import { loadFlowCode } from '../support/helper'; +import { loadFlowCode } from "../support/helper"; // tslint:disable: quotemark -describe('Subroutine workflow block', () => { +describe("Subroutine workflow block", () => { + it("should display dropdown options from the workflow cloud", () => { + cy.intercept("GET", "https://app.kendra.io/api", { + fixture: "flowList.json", + }).as("flowList.json"); - it('should display dropdown options from the workflow cloud', () => { - cy.intercept('GET', 'https://app.kendra.io/api', { - fixture: 'flowList.json' - } - ).as('flowList.json'); - - // Prevent external network request for adapter config - cy.intercept('GET', 'https://kendraio.github.io/kendraio-adapter/config.json', { - fixture: 'adapterConfig.json' - } - ).as('adapterConfig.json'); - - // Prevent external network requests for fonts with empty CSS rule - cy.intercept('https://fonts.googleapis.com/**', "*{ }"); - loadFlowCode([ - { - "type": "gosub", - "adapterName": "someAdapterA", - "workflowId": "madeUpFlowIDA" - } - ]); - cy.get('mat-toolbar > button mat-icon').contains('settings').click({force: true}); - cy.get("#mat-expansion-panel-header-0").click(); - // cy.pause(); - cy.get("#mat-input-0") - .clear() - .type("s") - .type("o") - .get("mat-option", { timeout: 1000 }) - .contains("someAdapterB"); - cy.get("#mat-input-0") - .clear() - .type("someAdapterB") - .get("#mat-input-1") - .clear() - .get("mat-option", { timeout: 1000 }) - .contains("madeUpFlowIDB"); - }); + // Prevent external network request for adapter config + cy.intercept( + "GET", + "https://kendraio.github.io/kendraio-adapter/config.json", + { + fixture: "adapterConfig.json", + }, + ).as("adapterConfig.json"); + // Prevent external network requests for fonts with empty CSS rule + cy.intercept("https://fonts.googleapis.com/**", "*{ }"); + loadFlowCode([ + { + type: "gosub", + adapterName: "someAdapterA", + workflowId: "madeUpFlowIDA", + }, + ]); + cy.get("mat-toolbar > button mat-icon") + .contains("settings") + .click({ force: true }); + cy.get("#mat-expansion-panel-header-0").click(); + // cy.pause(); + cy.get("#mat-input-0") + .clear() + .type("s") + .type("o") + .get("mat-option", { timeout: 1000 }) + .contains("someAdapterB"); + cy.get("#mat-input-0") + .clear() + .type("someAdapterB") + .get("#mat-input-1") + .clear() + .get("mat-option", { timeout: 1000 }) + .contains("madeUpFlowIDB"); + }); }); - diff --git a/cypress/e2e/share.ts b/cypress/e2e/share.ts index 865c7c169..895a89ab8 100644 --- a/cypress/e2e/share.ts +++ b/cypress/e2e/share.ts @@ -1,47 +1,51 @@ - -describe('Share functionality', () => { - - beforeEach(() => { - // Prevent external network request for adapter config - cy.intercept('GET', 'https://kendraio.github.io/kendraio-adapter/config.json', { - fixture: 'adapterConfig.json' - } - ).as('adapterConfig.json'); - - // Prevent external network requests for Workflow cloud - cy.intercept('GET', 'https://app.kendra.io/api/workflowCloud/listWorkflows', { - fixture: 'workflow-cloud.json' - } - ).as('workflow-cloud.json'); - - - // Prevent external network requests for fonts with empty CSS rule - cy.intercept('https://fonts.googleapis.com/**', "*{ }"); - - }); - - it('should assert a shared database loads as expected using given URL', () => { - const databaseUrl = "/workflow-builder?metadata=NobwRArhCWAmYC4wGZkEMAsAOWBTADALT4BsAjLoRgKwCcAZobbWbYblgEwDGJyJnarGTwANGDSw0ABwAuuAE4A5NAFtciMAGduAC1yq0WsOJ37DK9ZukLo6gPqroAO2hb5C4+Kmy0icM5qGkgASm660GAAvuIANmgARrixmmFaEdGi4FBwmhj41NT0+ADsyIQlFGzYZGSEWCU87PjIZdTc+LQkuLQmElJyipbB2noGRn1m48PWtg5Oru6KXmA+fggBQZoAQgD2tsYxYPFJKUh7B5nZMPBIlZwJ1D3cVCW4JVS0aNT1WBgkxGQtGQ+FwsBKGH+Yn6Mg8MyQU0MK0RaHhYBsdlwjhcbg8KzW-jAgSsSAAMtAAF6ZY6JZKaclUmLXXJId5oTi1ESEJLvKj4WCwJiFH5oLokDD0LDIehkBJ+cSSWFDLYIsZIyZq1Eq0bmCbeNC+Qk5W5gNkcshcnkffICoWFQiikjiyXS2Xy9EKXbSRSyaC4YwIUBgADWuAAnppiRpxL7ZLERjMY2HvZoACq4AAesmiAF1xFHZpjsYs8X08DpbHJoLtnJoAAoAWQABLFcX0TnSkAWjh2zh6iwtcctc0A"; - const flowUrl = "/workflow-builder?data=NobwRALgngDgpmAXGA5gewM4FcBGYA0YAhgCZEwRwBOAckQLYLIYDGAFnPURgWAO5oqAawBmAGzR8AkiSRhWHLj0I4JLIQGE09RgDsIcgDJpSAAgWduYAL75w0eHICWupwdv3YTSJxhiilLyU9H4B3gA8bABMAHwAIgFEONxwpixo nD6GOEA9NExNnaQXnJcMDAuKLzllbrVyGQQRMAA-FhYTiQAvN0ABnAA7ERRAIyjAMwkALQ4cEPTACwADCQzAJwArNvTROsAbPuLIgAcEyKjyX0AuqYAPqbAy9e8qmjqWjpZBsgAYk5iShUczsSymCBoUxYKhiUwwIhUBhFTyOZDpTIADwg0wwRAAbghCOjKFiANJwKByCxcV5qTTaPQ-eT41JoaHmeAsJwiJwsEGKIjIkqosCMDC4lCEyBuMTeQxODAQUxuTgYUwiKjafmWRCmEAgNIZEkQAB01KIJt0DFS1msQoc3hIeEIaHgiIgTgycklBkIpHIQLojCpoKUvHNAHE4BAgXJiXAsWbQxarcGVHTPoyjCYSKYmkR1Zr6NqaR5hd5alUauQ6g0wPngNcTYwqJKABQAAXwetM-jmYl1Ps73YAJCb44nzSa 3AxABKaxz2nvelffRyKNKiAcUwAHWlEFl 9M9tKjTgOCw1Rd8F0SFGhAwbEkCWaSAgVCwcEfz74WkxPwiEQYgYN 8i-gAys0gSIEBIFwGWDrelQXS8CgKEkAA8hQnq6DwiDgPCKAuAEuHvp YFESRHoZAACkQkoQU4ABeTArLYYDpGIWD0LocRwCI GgGAHCkNQQZykks68Dys6yMgM5iEKokkOJ1pyNh1CkRkyicbOYgAEpZKpVDUHIAjCOIkhGboJlmUS k2XZVD0Yi9D4eAbzqEJKLeEQLA0XhrxYDGOlIMJilyAAoiQbjLt54W XI-hYLo7C8P6FBmcwya6RZogSNI8lgHAsUQFIwS8BOPzgOaMhxkaCamgAjl VBQK5DAYEmAr1YQqGNIkJodKhtrXIQWRJLK8kfl 1jXPNtrFCpanBsgUhxDJThyXII2yPN6Yrpm3xyKeIr YFumXqFQWIBFUlKcgACCaymBVnBVWgEhUHIqlAVggLxUIPnlslRCpelfpkFlP05QKeWCAVkj1cgpVuO99CfQBSC1cmKOcY1iatdQHUIl1PWWH1YADWAe1tkuY0TVaqileRc3FJFyDyoqpjAbC5pXXSINIQp4NpWwGXQ7GcOWAjlmFfjYgKu440lcz01swhqteauWbIGd3joNgzrEFLq3eE4ISCLGhD5VZRVyCIaBoDbYA68d65-M7QK7ne81AA"; - - cy.visit(databaseUrl) - .contains("Flow"); - cy.on('window:confirm', () => true); - - cy.wait(3000); - - cy.visit(flowUrl) - .contains('Boris'); - cy.contains('Liz'); - cy.contains('Rishi'); - - // Now we press the share button, and select share database: - cy.get('mat-icon').contains("settings").click({force: true}); - cy.get('mat-icon').contains("share").click({force: true}); - cy.get('button:contains("Share database")').click({force: true}); - - // assert shareValue is in the databaseUrl - cy.get('app-show-share-link-dialog textarea').should('contain', databaseUrl); - }); - -}); \ No newline at end of file +describe("Share functionality", () => { + beforeEach(() => { + // Prevent external network request for adapter config + cy.intercept( + "GET", + "https://kendraio.github.io/kendraio-adapter/config.json", + { + fixture: "adapterConfig.json", + }, + ).as("adapterConfig.json"); + + // Prevent external network requests for Workflow cloud + cy.intercept( + "GET", + "https://app.kendra.io/api/workflowCloud/listWorkflows", + { + fixture: "workflow-cloud.json", + }, + ).as("workflow-cloud.json"); + + // Prevent external network requests for fonts with empty CSS rule + cy.intercept("https://fonts.googleapis.com/**", "*{ }"); + }); + + it("should assert a shared database loads as expected using given URL", () => { + const databaseUrl = + "/workflow-builder?metadata=NobwRArhCWAmYC4wGZkEMAsAOWBTADALT4BsAjLoRgKwCcAZobbWbYblgEwDGJyJnarGTwANGDSw0ABwAuuAE4A5NAFtciMAGduAC1yq0WsOJ37DK9ZukLo6gPqroAO2hb5C4+Kmy0icM5qGkgASm660GAAvuIANmgARrixmmFaEdGi4FBwmhj41NT0+ADsyIQlFGzYZGSEWCU87PjIZdTc+LQkuLQmElJyipbB2noGRn1m48PWtg5Oru6KXmA+fggBQZoAQgD2tsYxYPFJKUh7B5nZMPBIlZwJ1D3cVCW4JVS0aNT1WBgkxGQtGQ+FwsBKGH+Yn6Mg8MyQU0MK0RaHhYBsdlwjhcbg8KzW-jAgSsSAAMtAAF6ZY6JZKaclUmLXXJId5oTi1ESEJLvKj4WCwJiFH5oLokDD0LDIehkBJ+cSSWFDLYIsZIyZq1Eq0bmCbeNC+Qk5W5gNkcshcnkffICoWFQiikjiyXS2Xy9EKXbSRSyaC4YwIUBgADWuAAnppiRpxL7ZLERjMY2HvZoACq4AAesmiAF1xFHZpjsYs8X08DpbHJoLtnJoAAoAWQABLFcX0TnSkAWjh2zh6iwtcctc0A"; + const flowUrl = + "/workflow-builder?data=NobwRALgngDgpmAXGA5gewM4FcBGYA0YAhgCZEwRwBOAckQLYLIYDGAFnPURgWAO5oqAawBmAGzR8AkiSRhWHLj0I4JLIQGE09RgDsIcgDJpSAAgWduYAL75w0eHICWupwdv3YTSJxhiilLyU9H4B3gA8bABMAHwAIgFEONxwpixo nD6GOEA9NExNnaQXnJcMDAuKLzllbrVyGQQRMAA-FhYTiQAvN0ABnAA7ERRAIyjAMwkALQ4cEPTACwADCQzAJwArNvTROsAbPuLIgAcEyKjyX0AuqYAPqbAy9e8qmjqWjpZBsgAYk5iShUczsSymCBoUxYKhiUwwIhUBhFTyOZDpTIADwg0wwRAAbghCOjKFiANJwKByCxcV5qTTaPQ-eT41JoaHmeAsJwiJwsEGKIjIkqosCMDC4lCEyBuMTeQxODAQUxuTgYUwiKjafmWRCmEAgNIZEkQAB01KIJt0DFS1msQoc3hIeEIaHgiIgTgycklBkIpHIQLojCpoKUvHNAHE4BAgXJiXAsWbQxarcGVHTPoyjCYSKYmkR1Zr6NqaR5hd5alUauQ6g0wPngNcTYwqJKABQAAXwetM-jmYl1Ps73YAJCb44nzSa 3AxABKaxz2nvelffRyKNKiAcUwAHWlEFl 9M9tKjTgOCw1Rd8F0SFGhAwbEkCWaSAgVCwcEfz74WkxPwiEQYgYN 8i-gAys0gSIEBIFwGWDrelQXS8CgKEkAA8hQnq6DwiDgPCKAuAEuHvp YFESRHoZAACkQkoQU4ABeTArLYYDpGIWD0LocRwCI GgGAHCkNQQZykks68Dys6yMgM5iEKokkOJ1pyNh1CkRkyicbOYgAEpZKpVDUHIAjCOIkhGboJlmUS k2XZVD0Yi9D4eAbzqEJKLeEQLA0XhrxYDGOlIMJilyAAoiQbjLt54W XI-hYLo7C8P6FBmcwya6RZogSNI8lgHAsUQFIwS8BOPzgOaMhxkaCamgAjl VBQK5DAYEmAr1YQqGNIkJodKhtrXIQWRJLK8kfl 1jXPNtrFCpanBsgUhxDJThyXII2yPN6Yrpm3xyKeIr YFumXqFQWIBFUlKcgACCaymBVnBVWgEhUHIqlAVggLxUIPnlslRCpelfpkFlP05QKeWCAVkj1cgpVuO99CfQBSC1cmKOcY1iatdQHUIl1PWWH1YADWAe1tkuY0TVaqileRc3FJFyDyoqpjAbC5pXXSINIQp4NpWwGXQ7GcOWAjlmFfjYgKu440lcz01swhqteauWbIGd3joNgzrEFLq3eE4ISCLGhD5VZRVyCIaBoDbYA68d65-M7QK7ne81AA"; + + cy.visit(databaseUrl).contains("Flow"); + cy.on("window:confirm", () => true); + + cy.wait(3000); + + cy.visit(flowUrl).contains("Boris"); + cy.contains("Liz"); + cy.contains("Rishi"); + + // Now we press the share button, and select share database: + cy.get("mat-icon").contains("settings").click({ force: true }); + cy.get("mat-icon").contains("share").click({ force: true }); + cy.get('button:contains("Share database")').click({ force: true }); + + // assert shareValue is in the databaseUrl + cy.get("app-show-share-link-dialog textarea").should( + "contain", + databaseUrl, + ); + }); +}); diff --git a/cypress/e2e/spec.ts b/cypress/e2e/spec.ts index 21e15ca78..d4499040f 100644 --- a/cypress/e2e/spec.ts +++ b/cypress/e2e/spec.ts @@ -1,117 +1,123 @@ -import { loadFlowCode } from '../support/helper'; +import { loadFlowCode } from "../support/helper"; // tslint:disable: quotemark - -describe('workspace-project App', () => { - +describe("workspace-project App", () => { beforeEach(() => { // Prevent external network request for adapter config - cy.intercept('GET', 'https://kendraio.github.io/kendraio-adapter/config.json', { - fixture: 'adapterConfig.json' - } - ).as('adapterConfig.json'); - - // Prevent external network requests for Workflow cloud - cy.intercept('GET', 'https://app.kendra.io/api/workflowCloud/listWorkflows', { - fixture: 'workflow-cloud.json' - } - ).as('workflow-cloud.json'); + cy.intercept( + "GET", + "https://kendraio.github.io/kendraio-adapter/config.json", + { + fixture: "adapterConfig.json", + }, + ).as("adapterConfig.json"); + // Prevent external network requests for Workflow cloud + cy.intercept( + "GET", + "https://app.kendra.io/api/workflowCloud/listWorkflows", + { + fixture: "workflow-cloud.json", + }, + ).as("workflow-cloud.json"); // Prevent external network requests for fonts with empty CSS rule - cy.intercept('https://fonts.googleapis.com/**', "*{ }").as('emptyFonts'); - + cy.intercept("https://fonts.googleapis.com/**", "*{ }").as("emptyFonts"); }); - - it('should assert the mapping block produces the expected UUID string output', () => { - + it("should assert the mapping block produces the expected UUID string output", () => { loadFlowCode([ { - "type": "mapping", - "mapping": "uuid('test')" + type: "mapping", + mapping: "uuid('test')", }, { - "type": "debug", - "open": 1, - "showContext": false - } + type: "debug", + open: 1, + showContext: false, + }, ]); - cy.contains( - '3ab8d0cd-7b76-5741-8bc9-5725650dc435' - ); - + cy.contains("3ab8d0cd-7b76-5741-8bc9-5725650dc435"); }); - - it('should make new workflow with mapping block', () => { - cy.visit('/workflow-builder'); - cy.contains('menu'); - cy.get('app-root mat-toolbar').contains('menu').click(); - cy.contains('Flow Builder').click(); - cy.contains('settings'); - cy.get('mat-toolbar > button mat-icon').contains('settings').click({force: true}); - cy.get('app-workflow-sidenav').contains('delete_forever').click().get('app-workflow-sidenav').contains('Mapping').should('not.exist'); - cy.get('app-workflow-sidenav').contains('Add Task').click({force: true}); - cy.contains('Select Task'); - cy.get('mat-dialog-container').contains('Mapping').click(); - cy.get('button').contains('Add Task').click({force: true}); - cy.get('button').contains('Mapping'); + it("should make new workflow with mapping block", () => { + cy.visit("/workflow-builder"); + cy.contains("menu"); + cy.get("app-root mat-toolbar").contains("menu").click(); + cy.contains("Flow Builder").click(); + cy.contains("settings"); + cy.get("mat-toolbar > button mat-icon") + .contains("settings") + .click({ force: true }); + cy.get("app-workflow-sidenav") + .contains("delete_forever") + .click() + .get("app-workflow-sidenav") + .contains("Mapping") + .should("not.exist"); + cy.get("app-workflow-sidenav").contains("Add Task").click({ force: true }); + cy.contains("Select Task"); + cy.get("mat-dialog-container").contains("Mapping").click(); + cy.get("button").contains("Add Task").click({ force: true }); + cy.get("button").contains("Mapping"); }); - - it('should display a custom title and additional form elements for the mapping editor block', () => { + it("should display a custom title and additional form elements for the mapping editor block", () => { loadFlowCode([ { - "type": "mapping", - "mapping": "`true`", - "blockComment": "testingComment", - } + type: "mapping", + mapping: "`true`", + blockComment: "testingComment", + }, ]); - cy.get('mat-toolbar > button > mat-icon').contains('settings').click({force: true}); - cy.get('app-workflow-sidenav').contains('testingComment').should('exist'); - cy.get('app-workflow-sidenav').contains('testingComment').click(); + cy.get("mat-toolbar > button > mat-icon") + .contains("settings") + .click({ force: true }); + cy.get("app-workflow-sidenav").contains("testingComment").should("exist"); + cy.get("app-workflow-sidenav").contains("testingComment").click(); // cy.get('app-workflow-sidenav').contains('Block Comment'); // FIXME: regression - MatFormField placeholder text is not visible }); - - it('should display the comment for a generic editor block', () => { + it("should display the comment for a generic editor block", () => { loadFlowCode([ { - "type": "template", - "blockComment": "testingComment first line\nComment line2", - } + type: "template", + blockComment: "testingComment first line\nComment line2", + }, ]); - cy.get('mat-toolbar > button mat-icon').contains('settings').click({force: true}); - cy.get('app-workflow-sidenav').contains('testingComment').should('exist'); - cy.get('app-workflow-sidenav').contains('line2').should('not.exist'); - cy.get('app-workflow-sidenav').contains('testingComment').click(); + cy.get("mat-toolbar > button mat-icon") + .contains("settings") + .click({ force: true }); + cy.get("app-workflow-sidenav").contains("testingComment").should("exist"); + cy.get("app-workflow-sidenav").contains("line2").should("not.exist"); + cy.get("app-workflow-sidenav").contains("testingComment").click(); }); - - - it('should display welcome message', () => { - cy.intercept('https://app.kendra.io/api/core/dashboard', { fixture: 'dashboardHomeFlow.json' }); - cy.visit('/'); - cy.contains('Kendraio App is an open source dashboard'); + it("should display welcome message", () => { + cy.intercept("https://app.kendra.io/api/core/dashboard", { + fixture: "dashboardHomeFlow.json", + }); + cy.visit("/"); + cy.contains("Kendraio App is an open source dashboard"); }); + it("should display saved workflows", () => { + cy.intercept( + "GET", + "https://app.kendra.io/api/workflowCloud/listWorkflows", + { + fixture: "listWorkflowsFlow.json", + }, + ).as("listWorkflowsFlow.json"); - it('should display saved workflows', () => { - - cy.intercept('GET', 'https://app.kendra.io/api/workflowCloud/listWorkflows', { - fixture: 'listWorkflowsFlow.json' - }).as('listWorkflowsFlow.json'); - - cy.intercept('GET', 'https://app.kendra.io/api', { - fixture: 'flowList.json' - } - ).as('flowList.json'); + cy.intercept("GET", "https://app.kendra.io/api", { + fixture: "flowList.json", + }).as("flowList.json"); - cy.visit('/workflowCloud/listWorkflows'); - cy.contains('Submit').click(); - cy.contains('Made up flow A'); + cy.visit("/workflowCloud/listWorkflows"); + cy.contains("Submit").click(); + cy.contains("Made up flow A"); }); /* @@ -164,5 +170,4 @@ describe('workspace-project App', () => { }); }) */ - }); diff --git a/cypress/fixtures/listWorkflowsFlow.json b/cypress/fixtures/listWorkflowsFlow.json index c32ab1770..5a7ed0b35 100644 --- a/cypress/fixtures/listWorkflowsFlow.json +++ b/cypress/fixtures/listWorkflowsFlow.json @@ -1,195 +1,193 @@ { - "blocks": [ - { - "type": "init", - "blockComment": "Mocked" - }, - { - "type": "variable-get", - "name": "filterTag" - }, - { - "type": "mapping", - "mapping": "(type(data)=='string' && data!='--none--') && data" - }, - { - "type": "template", - "template": "{{#if data}}Filtering by tag: {{data}}{{/if}}" - }, - { - "type": "context-save", - "contextKey": "filterTag" - }, - { - "type": "mapping", - "mapping": "{ \"term\":\" \", \"displayHidden\":false}" - }, - { - "type": "form", - "hasSubmit": true, - "emitOnInit": true, - "jsonSchema": { - "type": "object", - "properties": { - "term": { - "type": "string", - "title": "Search term", - "default": "" - }, - "displayHidden": { - "type": "boolean", - "title": "Show hidden", - "default": false - } - } - }, - "uiSchema": {} - }, - { - "type": "context-save", - "contextKey": "search" - }, - { - "type": "http", - "method": "get", - "endpoint": "https://app.kendra.io/api" - }, - { - "type": "mapping", - "mapping": "context.search.term!=null && data[?contains(toLower(title), toLower(trim($.context.search.term))) || contains(toLower(adapterName), toLower(trim($.context.search.term)))] || data" - }, - { - "type": "mapping", - "mapping": "data[?$.context.search.displayHidden || !(tags[?@ == 'hidden'])]" - }, - { - "type": "mapping", - "mapping": "context.filterTag && data[?(tags[?@ == $.context.filterTag])] || data" - }, - { - "type": "grid", - "passThrough": true, - "gridOptions": { - "pagination": true, - "paginationPageSize": 15, - "defaultColDef": { - "sortable": true, - "resizable": true - } - }, - "columnDefs": [ - { - "headerName": "Title", - "field": "title", - "width": 300, - "filter": true - }, - { - "headerName": "Operations", - "cellRenderer": "workflowRenderer", - "cellRendererParams": { - "blocks": [ - { - "type": "actions", - "buttons": [ - { - "label": "Launch", - "blocks": [ - { - "type": "launch", - "valueGetters": { - "adapter": "data.adapterName", - "workflowId": "data.id" - } - } - ] - } - ] - } - ] - } - }, - { - "headerName": "Workflow ID", - "field": "id" - }, - { - "headerName": "Adapter", - "field": "adapterName", - "filter": true - }, - { - "headerName": "Modified", - "field": "modified", - "sort": "desc", - "valueFormatter": "formatDate(value, 'ff')" - }, - { - "headerName": "tags", - "field": "tags" - } + "blocks": [ + { + "type": "init", + "blockComment": "Mocked" + }, + { + "type": "variable-get", + "name": "filterTag" + }, + { + "type": "mapping", + "mapping": "(type(data)=='string' && data!='--none--') && data" + }, + { + "type": "template", + "template": "{{#if data}}Filtering by tag: {{data}}{{/if}}" + }, + { + "type": "context-save", + "contextKey": "filterTag" + }, + { + "type": "mapping", + "mapping": "{ \"term\":\" \", \"displayHidden\":false}" + }, + { + "type": "form", + "hasSubmit": true, + "emitOnInit": true, + "jsonSchema": { + "type": "object", + "properties": { + "term": { + "type": "string", + "title": "Search term", + "default": "" + }, + "displayHidden": { + "type": "boolean", + "title": "Show hidden", + "default": false + } + } + }, + "uiSchema": {} + }, + { + "type": "context-save", + "contextKey": "search" + }, + { + "type": "http", + "method": "get", + "endpoint": "https://app.kendra.io/api" + }, + { + "type": "mapping", + "mapping": "context.search.term!=null && data[?contains(toLower(title), toLower(trim($.context.search.term))) || contains(toLower(adapterName), toLower(trim($.context.search.term)))] || data" + }, + { + "type": "mapping", + "mapping": "data[?$.context.search.displayHidden || !(tags[?@ == 'hidden'])]" + }, + { + "type": "mapping", + "mapping": "context.filterTag && data[?(tags[?@ == $.context.filterTag])] || data" + }, + { + "type": "grid", + "passThrough": true, + "gridOptions": { + "pagination": true, + "paginationPageSize": 15, + "defaultColDef": { + "sortable": true, + "resizable": true + } + }, + "columnDefs": [ + { + "headerName": "Title", + "field": "title", + "width": 300, + "filter": true + }, + { + "headerName": "Operations", + "cellRenderer": "workflowRenderer", + "cellRendererParams": { + "blocks": [ + { + "type": "actions", + "buttons": [ + { + "label": "Launch", + "blocks": [ + { + "type": "launch", + "valueGetters": { + "adapter": "data.adapterName", + "workflowId": "data.id" + } + } + ] + } + ] + } ] + } }, { - "type": "mapping", - "mapping": "data && uniq(data[*].tags[])" + "headerName": "Workflow ID", + "field": "id" }, { - "type": "mapping", - "mapping": "[data,['--none--']][]" + "headerName": "Adapter", + "field": "adapterName", + "filter": true }, { - "type": "mapping", - "mapping": "data && { form: set(`{\r\n \"type\": \"form\",\r\n \"jsonSchema\": {\r\n \"type\": \"object\",\r\n \"properties\": {\r\n \"tag\": {\r\n \"title\": \"Tag\",\r\n \"description\": \"Select a tag to filter by\",\r\n \"type\": \"string\",\r\n \"enum\": [\"1\"] \r\n }\r\n }\r\n },\r\n \"uiSchema\": { \r\n }\r\n}`, 'jsonSchema.properties.tag.enum', data) }" + "headerName": "Modified", + "field": "modified", + "sort": "desc", + "valueFormatter": "formatDate(value, 'ff')" }, { + "headerName": "tags", + "field": "tags" + } + ] + }, + { + "type": "mapping", + "mapping": "data && uniq(data[*].tags[])" + }, + { + "type": "mapping", + "mapping": "[data,['--none--']][]" + }, + { + "type": "mapping", + "mapping": "data && { form: set(`{\r\n \"type\": \"form\",\r\n \"jsonSchema\": {\r\n \"type\": \"object\",\r\n \"properties\": {\r\n \"tag\": {\r\n \"title\": \"Tag\",\r\n \"description\": \"Select a tag to filter by\",\r\n \"type\": \"string\",\r\n \"enum\": [\"1\"] \r\n }\r\n }\r\n },\r\n \"uiSchema\": { \r\n }\r\n}`, 'jsonSchema.properties.tag.enum', data) }" + }, + { + "type": "mapping", + "mapping": "context.filterTag!='--none--' && merge(data,{tag:$.context.filterTag}) || data" + }, + { + "type": "form", + "hasSubmit": false, + "label": "Filter", + "emitOnInit": false, + "schemaGetter": { + "blocks": [ + { "type": "mapping", - "mapping": "context.filterTag!='--none--' && merge(data,{tag:$.context.filterTag}) || data" - }, - { - "type": "form", - "hasSubmit": false, - "label": "Filter", - "emitOnInit": false, - "schemaGetter": { - "blocks": [ - { - "type": "mapping", - "mapping": "data.form" - } - ] + "mapping": "data.form" + } + ] + } + }, + { + "type": "actions", + "buttons": [ + { + "label": "Filter", + "color": "default", + "blocks": [ + { + "type": "variable-set", + "name": "filterTag", + "notify": false, + "valueGetter": "data.tag" + }, + { + "type": "dispatch", + "action": "refreshWorkflow" } - }, - { - "type": "actions", - "buttons": [ - { - "label": "Filter", - "color": "default", - "blocks": [ - { - "type": "variable-set", - "name": "filterTag", - "notify": false, - "valueGetter": "data.tag" - }, - { - "type": "dispatch", - "action": "refreshWorkflow" - } - ] - } - ] + ] } - ], - "id": "listWorkflows", - "workflowId": "listWorkflows", - "adapterName": "workflowCloud", - "created": "2021-11-19T16:58:04.556Z", - "tags": [ - "start" - ], - "updated": "2021-11-19T16:58:04.555Z", - "modified": "2021-11-19T16:58:04.555Z", - "title": "List Workflows" -} \ No newline at end of file + ] + } + ], + "id": "listWorkflows", + "workflowId": "listWorkflows", + "adapterName": "workflowCloud", + "created": "2021-11-19T16:58:04.556Z", + "tags": ["start"], + "updated": "2021-11-19T16:58:04.555Z", + "modified": "2021-11-19T16:58:04.555Z", + "title": "List Workflows" +} diff --git a/cypress/fixtures/workflow-cloud.json b/cypress/fixtures/workflow-cloud.json index 6d8118cc4..16f9635d3 100644 --- a/cypress/fixtures/workflow-cloud.json +++ b/cypress/fixtures/workflow-cloud.json @@ -1,158 +1,156 @@ { - "blocks": [ - { - "type": "init", - "blockComment": "Mocked" - }, - { - "type": "variable-get", - "name": "filterTag" - }, - { - "type": "mapping", - "mapping": "(type(data)=='string' && data!='--none--') && data" - }, - { - "type": "template", - "template": "{{#if data}}Filtering by tag: {{data}}{{/if}}" - }, - { - "type": "context-save", - "contextKey": "filterTag" + "blocks": [ + { + "type": "init", + "blockComment": "Mocked" + }, + { + "type": "variable-get", + "name": "filterTag" + }, + { + "type": "mapping", + "mapping": "(type(data)=='string' && data!='--none--') && data" + }, + { + "type": "template", + "template": "{{#if data}}Filtering by tag: {{data}}{{/if}}" + }, + { + "type": "context-save", + "contextKey": "filterTag" + }, + { + "type": "mapping", + "mapping": "{ \"term\":\" \", \"displayHidden\":false}" + }, + { + "type": "form", + "hasSubmit": false, + "emitOnInit": true, + "jsonSchema": { + "type": "object", + "properties": { + "term": { + "type": "string", + "title": "Search term", + "default": "" + }, + "displayHidden": { + "type": "boolean", + "title": "Show hidden", + "default": false + } + } + }, + "uiSchema": {} + }, + { + "type": "context-save", + "contextKey": "search" + }, + { + "type": "http", + "method": "get", + "endpoint": "https://app.kendra.io/api" + }, + { + "type": "mapping", + "mapping": "context.search.term!=null && data[?contains(toLower(title), toLower(trim($.context.search.term))) || contains(toLower(adapterName), toLower(trim($.context.search.term)))] || data" + }, + { + "type": "mapping", + "mapping": "data[?$.context.search.displayHidden || !(tags[?@ == 'hidden'])]" + }, + { + "type": "mapping", + "mapping": "context.filterTag && data[?(tags[?@ == $.context.filterTag])] || data" + }, + { + "type": "grid", + "passThrough": true, + "gridOptions": { + "pagination": true, + "paginationPageSize": 15, + "defaultColDef": { + "sortable": true, + "resizable": true + } + }, + "columnDefs": [ + { + "headerName": "Title", + "field": "title", + "width": 300, + "filter": true }, { - "type": "mapping", - "mapping": "{ \"term\":\" \", \"displayHidden\":false}" - }, - { - "type": "form", - "hasSubmit": false, - "emitOnInit": true, - "jsonSchema": { - "type": "object", - "properties": { - "term": { - "type": "string", - "title": "Search term", - "default": "" - }, - "displayHidden": { - "type": "boolean", - "title": "Show hidden", - "default": false - } - } - }, - "uiSchema": {} - }, - { - "type": "context-save", - "contextKey": "search" - }, - { - "type": "http", - "method": "get", - "endpoint": "https://app.kendra.io/api" - }, - { - "type": "mapping", - "mapping": "context.search.term!=null && data[?contains(toLower(title), toLower(trim($.context.search.term))) || contains(toLower(adapterName), toLower(trim($.context.search.term)))] || data" - }, - { - "type": "mapping", - "mapping": "data[?$.context.search.displayHidden || !(tags[?@ == 'hidden'])]" - }, - { - "type": "mapping", - "mapping": "context.filterTag && data[?(tags[?@ == $.context.filterTag])] || data" + "headerName": "Operations", + "cellRenderer": "workflowRenderer", + "cellRendererParams": { + "blocks": [ + { + "type": "actions", + "buttons": [ + { + "label": "Launch", + "blocks": [ + { + "type": "launch", + "valueGetters": { + "adapter": "data.adapterName", + "workflowId": "data.id" + } + } + ], + "enabled": true + } + ] + } + ] + } }, { - "type": "grid", - "passThrough": true, - "gridOptions": { - "pagination": true, - "paginationPageSize": 15, - "defaultColDef": { - "sortable": true, - "resizable": true - } - }, - "columnDefs": [ - { - "headerName": "Title", - "field": "title", - "width": 300, - "filter": true - }, - { - "headerName": "Operations", - "cellRenderer": "workflowRenderer", - "cellRendererParams": { - "blocks": [ - { - "type": "actions", - "buttons": [ - { - "label": "Launch", - "blocks": [ - { - "type": "launch", - "valueGetters": { - "adapter": "data.adapterName", - "workflowId": "data.id" - } - } - ], - "enabled": true - } - ] - } - ] - } - }, - { - "headerName": "Workflow ID", - "field": "id" - }, - { - "headerName": "Adapter", - "field": "adapterName", - "filter": true - }, - { - "headerName": "Modified", - "field": "modified", - "sort": "desc", - "valueFormatter": "formatDate(value, 'ff')" - }, - { - "headerName": "tags", - "field": "tags" - } - ] + "headerName": "Workflow ID", + "field": "id" }, { - "type": "mapping", - "mapping": "data && uniq(data[*].tags[])" + "headerName": "Adapter", + "field": "adapterName", + "filter": true }, { - "type": "mapping", - "mapping": "[data,['--none--']][]" + "headerName": "Modified", + "field": "modified", + "sort": "desc", + "valueFormatter": "formatDate(value, 'ff')" }, { - "type": "mapping", - "mapping": "data && { form: set(`{\r\n \"type\": \"form\",\r\n \"jsonSchema\": {\r\n \"type\": \"object\",\r\n \"properties\": {\r\n \"tag\": {\r\n \"title\": \"🏷️ Tag\",\r\n \"description\": \"Select a tag to filter by\",\r\n \"type\": \"string\",\r\n \"enum\": [\"1\"] \r\n }\r\n }\r\n },\r\n \"uiSchema\": { \r\n }\r\n}`, 'jsonSchema.properties.tag.enum', data) }", - "blockComment": "" - } - ], - "id": "listWorkflows", - "workflowId": "listWorkflows", - "adapterName": "workflowCloud", - "created": "2022-03-01T11:37:56.041Z", - "tags": [ - "start" - ], - "updated": "2022-03-01T11:37:55.957Z", - "modified": "2022-03-01T11:37:55.957Z", - "title": "List Workflows" -} \ No newline at end of file + "headerName": "tags", + "field": "tags" + } + ] + }, + { + "type": "mapping", + "mapping": "data && uniq(data[*].tags[])" + }, + { + "type": "mapping", + "mapping": "[data,['--none--']][]" + }, + { + "type": "mapping", + "mapping": "data && { form: set(`{\r\n \"type\": \"form\",\r\n \"jsonSchema\": {\r\n \"type\": \"object\",\r\n \"properties\": {\r\n \"tag\": {\r\n \"title\": \"🏷️ Tag\",\r\n \"description\": \"Select a tag to filter by\",\r\n \"type\": \"string\",\r\n \"enum\": [\"1\"] \r\n }\r\n }\r\n },\r\n \"uiSchema\": { \r\n }\r\n}`, 'jsonSchema.properties.tag.enum', data) }", + "blockComment": "" + } + ], + "id": "listWorkflows", + "workflowId": "listWorkflows", + "adapterName": "workflowCloud", + "created": "2022-03-01T11:37:56.041Z", + "tags": ["start"], + "updated": "2022-03-01T11:37:55.957Z", + "modified": "2022-03-01T11:37:55.957Z", + "title": "List Workflows" +} diff --git a/src/app/_shared/base/base.component.ts b/src/app/_shared/base/base.component.ts index 63a1e0668..151d4f9e7 100644 --- a/src/app/_shared/base/base.component.ts +++ b/src/app/_shared/base/base.component.ts @@ -1,14 +1,14 @@ -import {Injectable} from '@angular/core'; -import {RouteData} from 'src/app/_models/classes/common'; -import {ActivatedRoute, Router} from '@angular/router'; -import {PageTitleService} from 'src/app/services/page-title.service'; -import {MatDialog} from '@angular/material/dialog'; - -import {TestDataService} from 'src/app/services/test-data.service'; -import {GridOptions} from 'ag-grid-community'; -import {HelpTextService} from '../services/help-text.service'; -import {AppConfigService} from '../services/config.service'; -import {TranslateService} from '@ngx-translate/core'; +import { Injectable } from "@angular/core"; +import { RouteData } from "src/app/_models/classes/common"; +import { ActivatedRoute, Router } from "@angular/router"; +import { PageTitleService } from "src/app/services/page-title.service"; +import { MatDialog } from "@angular/material/dialog"; + +import { TestDataService } from "src/app/services/test-data.service"; +import { GridOptions } from "ag-grid-community"; +import { HelpTextService } from "../services/help-text.service"; +import { AppConfigService } from "../services/config.service"; +import { TranslateService } from "@ngx-translate/core"; @Injectable() export abstract class BaseComponent { @@ -24,7 +24,7 @@ export abstract class BaseComponent { protected readonly testData: TestDataService, protected help: HelpTextService, protected config: AppConfigService, - protected translate: TranslateService + protected translate: TranslateService, ) { // this.router.events.pipe( // filter(event => event instanceof NavigationEnd), @@ -33,22 +33,15 @@ export abstract class BaseComponent { // ); this.routeData = this.route.snapshot.data; this.pageTitle.setTitle(this.routeData.pageTitle[this.config.locale]); - // this.pageHelp = this.help.getHelpTextForSection('assets'); - - - - + // this.pageHelp = this.help.getHelpTextForSection('assets'); } getHelpText(page: string, itemRef: string) { - // this.pageHelp = this.help.getHelpTextForSection(this.routeData.breadcrumb) || []; - // if (this.pageHelp.length) { // const v = this.pageHelp[0].items.filter(f => f.ref === itemRef)[0].text; // console.log(v); // return v; // } } - } diff --git a/src/app/_shared/services/validation.service.ts b/src/app/_shared/services/validation.service.ts index 81f3778b9..3c14c94d7 100644 --- a/src/app/_shared/services/validation.service.ts +++ b/src/app/_shared/services/validation.service.ts @@ -1,22 +1,20 @@ - -import {throwError as observableThrowError, Observable } from 'rxjs'; -import { Injectable } from '@angular/core'; +import { throwError as observableThrowError, Observable } from "rxjs"; +import { Injectable } from "@angular/core"; // import { Http, Response, Headers, RequestOptions } from '@angular/http'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient } from "@angular/common/http"; @Injectable() export class ValidationService { - - static getValidatorErrorMessage(validatorName: string, validatorValue?: any) { const config = { - 'required': 'Required field', + required: "Required field", // 'invalidEmailAddress': 'Invalid email address', - 'invalidPassword': 'Invalid password. Password must be at least 6 characters long, and contain a number.', - 'minLength': `Min. length ${validatorValue.requiredLength}`, - 'badword' : 'Ilegal word', - 'invalid' : 'Ilegal word', - 'pattern' : 'Invalid entry' + invalidPassword: + "Invalid password. Password must be at least 6 characters long, and contain a number.", + minLength: `Min. length ${validatorValue.requiredLength}`, + badword: "Ilegal word", + invalid: "Ilegal word", + pattern: "Invalid entry", }; return config[validatorName]; @@ -27,12 +25,11 @@ export class ValidationService { if (control.value.match(/^(?=.*[0-9])[a-zA-Z0-9!@#$%^&*]{6,100}$/)) { return null; } else { - return { 'invalidPassword': true }; + return { invalidPassword: true }; } } - - constructor(private http: HttpClient) { } + constructor(private http: HttpClient) {} // checkForDupEmail(email: string): Observable { @@ -44,15 +41,10 @@ export class ValidationService { // return body || ''; // } - // private handleError(error: Response): Observable { // // in a real world app, we may send the server to some remote logging infrastructure // // instead of just logging it to the console // console.error(error); // return observableThrowError(error.json().error || 'Server error'); // } - - - - } diff --git a/src/app/_shared/shared.module.ts b/src/app/_shared/shared.module.ts index ee8243b69..ffe67798d 100644 --- a/src/app/_shared/shared.module.ts +++ b/src/app/_shared/shared.module.ts @@ -1,28 +1,38 @@ -import { NgModule } from '@angular/core'; -import { CommonModule, LowerCasePipe, DatePipe } from '@angular/common'; -import { HttpClientModule } from '@angular/common/http'; -import { FormsModule, ReactiveFormsModule, NG_VALIDATORS } from '@angular/forms'; -import { RouterModule } from '@angular/router'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatCardModule } from '@angular/material/card'; -import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; -import { MatTreeModule } from '@angular/material/tree'; +import { NgModule } from "@angular/core"; +import { CommonModule, LowerCasePipe, DatePipe } from "@angular/common"; +import { HttpClientModule } from "@angular/common/http"; +import { + FormsModule, + ReactiveFormsModule, + NG_VALIDATORS, +} from "@angular/forms"; +import { RouterModule } from "@angular/router"; +import { MatButtonToggleModule } from "@angular/material/button-toggle"; +import { MatCardModule } from "@angular/material/card"; +import { MatIconModule } from "@angular/material/icon"; +import { MatInputModule } from "@angular/material/input"; +import { MatTreeModule } from "@angular/material/tree"; -import * as matComponents from '../_shared/components'; -import { FlexModule, FlexLayoutModule } from '@angular/flex-layout'; -import { BreadcrumbComponent } from './components/breadcrumb/breadcrumb.component'; -import { HelpTextService } from './services/help-text.service'; -import { HelpTextBtnDirective } from './directives/help-text-btn.directive'; -import { TranslateModule } from '@ngx-translate/core'; -import { PasswordStrength2, matchPasswords } from './directives/passwordValidation'; -import { PasswordInputComponent } from './form-controls/password-input/password-input.component'; -import { FormlyModule } from '@ngx-formly/core'; -import { UiFormModule } from './ui-form/ui-form.module'; +import * as matComponents from "../_shared/components"; +import { FlexModule, FlexLayoutModule } from "@angular/flex-layout"; +import { BreadcrumbComponent } from "./components/breadcrumb/breadcrumb.component"; +import { HelpTextService } from "./services/help-text.service"; +import { HelpTextBtnDirective } from "./directives/help-text-btn.directive"; +import { TranslateModule } from "@ngx-translate/core"; +import { + PasswordStrength2, + matchPasswords, +} from "./directives/passwordValidation"; +import { PasswordInputComponent } from "./form-controls/password-input/password-input.component"; +import { FormlyModule } from "@ngx-formly/core"; +import { UiFormModule } from "./ui-form/ui-form.module"; -import { NgSelectModule } from '@ng-select/ng-select'; +import { NgSelectModule } from "@ng-select/ng-select"; -export function minlengthValidationMessage(err: any, field: { templateOptions: { minLength: any; }; }) { +export function minlengthValidationMessage( + err: any, + field: { templateOptions: { minLength: any } }, +) { return `what the.. ${field.templateOptions.minLength} characters`; } @@ -36,12 +46,15 @@ export function minlengthValidationMessage(err: any, field: { templateOptions: { MatButtonToggleModule, MatIconModule, MatTreeModule, - FlexModule, FlexLayoutModule, + FlexModule, + FlexLayoutModule, FormsModule, ReactiveFormsModule, UiFormModule, NgSelectModule, - FormlyModule.forChild(), MatCardModule, MatInputModule + FormlyModule.forChild(), + MatCardModule, + MatInputModule, ], declarations: [ matComponents.MatInputComponent, @@ -51,24 +64,24 @@ export function minlengthValidationMessage(err: any, field: { templateOptions: { PasswordInputComponent, ], exports: [ - FormsModule, - ReactiveFormsModule, - FlexModule, - FlexLayoutModule, - BreadcrumbComponent, + FormsModule, + ReactiveFormsModule, + FlexModule, + FlexLayoutModule, + BreadcrumbComponent, - MatTreeModule, - HelpTextBtnDirective, - UiFormModule, - NgSelectModule, -TranslateModule + MatTreeModule, + HelpTextBtnDirective, + UiFormModule, + NgSelectModule, + TranslateModule, ], providers: [ DatePipe, LowerCasePipe, HelpTextService, - {provide: NG_VALIDATORS , useValue: PasswordStrength2, multi: true}, - {provide: NG_VALIDATORS , useValue: matchPasswords, multi: true}, - ] + { provide: NG_VALIDATORS, useValue: PasswordStrength2, multi: true }, + { provide: NG_VALIDATORS, useValue: matchPasswords, multi: true }, + ], }) export class SharedModule {} diff --git a/src/app/_shared/ui-form/config.ts b/src/app/_shared/ui-form/config.ts index 85846bd31..b66c6758b 100644 --- a/src/app/_shared/ui-form/config.ts +++ b/src/app/_shared/ui-form/config.ts @@ -7,116 +7,128 @@ import { passwordMatchValidationMessage, maximumNumValidationMessage, PasswordStrengthValidationMessage, - patternMatchMessage -} from './helpers/validations-messages'; + patternMatchMessage, +} from "./helpers/validations-messages"; -import { maximumNumValidation, passwordMatchValidation, PasswordStrengthValidation } from './helpers/validators'; +import { + maximumNumValidation, + passwordMatchValidation, + PasswordStrengthValidation, +} from "./helpers/validators"; import { PanelWrapperComponent, - CheckBoxWrapperComponent + CheckBoxWrapperComponent, // AnimationWrapperComponent, ErrorWrapperComponent -} from './wrappers'; +} from "./wrappers"; // import { RepeatSectionComponent } from './types/repeat-section.component'; // import { FormlyFieldInputMoney } from './types/money.component'; -import { KendraFieldInputPercentage } from './types/percentage.component'; -import { ConfigOption, FormlyFieldConfig } from '@ngx-formly/core'; +import { KendraFieldInputPercentage } from "./types/percentage.component"; +import { ConfigOption, FormlyFieldConfig } from "@ngx-formly/core"; -import * as types from './types'; -import {FormlyImageInputComponent} from '../../form-controls/formly-image-input/formly-image-input.component'; -import {FormlyAudioInputComponent} from '../../form-controls/formly-audio-input/formly-audio-input.component'; -import {FormlyRemoteImageInputComponent} from '../../form-controls/formly-remote-image-input/formly-remote-image-input.component'; -import {FormlyBlocksInputComponent} from '../../form-controls/formly-blocks-input/formly-blocks-input.component'; -import {FormlyWorkflowFieldComponent} from '../../form-controls/formly-workflow-field/formly-workflow-field.component'; -import {FormlyCardListComponent} from '../../form-controls/formly-card-list/formly-card-list.component'; -import {FormlyTableWidgetComponent} from '../../form-controls/formly-table-widget/formly-table-widget.component'; -import {FormlyFieldFileComponent} from './types/file-type.component'; -import {FormlyFileInputComponent} from '../../form-controls/formly-file-input/formly-file-input.component'; -import {FormlyPaginatedWidgetComponent} from '../../form-controls/formly-paginated-widget/formly-paginated-widget.component'; -import {ReadonlyInputComponent} from '../../form-controls/readonly-input/readonly-input.component'; +import * as types from "./types"; +import { FormlyImageInputComponent } from "../../form-controls/formly-image-input/formly-image-input.component"; +import { FormlyAudioInputComponent } from "../../form-controls/formly-audio-input/formly-audio-input.component"; +import { FormlyRemoteImageInputComponent } from "../../form-controls/formly-remote-image-input/formly-remote-image-input.component"; +import { FormlyBlocksInputComponent } from "../../form-controls/formly-blocks-input/formly-blocks-input.component"; +import { FormlyWorkflowFieldComponent } from "../../form-controls/formly-workflow-field/formly-workflow-field.component"; +import { FormlyCardListComponent } from "../../form-controls/formly-card-list/formly-card-list.component"; +import { FormlyTableWidgetComponent } from "../../form-controls/formly-table-widget/formly-table-widget.component"; +import { FormlyFieldFileComponent } from "./types/file-type.component"; +import { FormlyFileInputComponent } from "../../form-controls/formly-file-input/formly-file-input.component"; +import { FormlyPaginatedWidgetComponent } from "../../form-controls/formly-paginated-widget/formly-paginated-widget.component"; +import { ReadonlyInputComponent } from "../../form-controls/readonly-input/readonly-input.component"; export const config: ConfigOption = { validationMessages: [ - { name: 'required', message: requiredValidationMessage}, - { name: 'pattern', message: patternMatchMessage }, - { name: 'minLength', message: minlengthValidationMessage }, - { name: 'maxLength', message: maxlengthValidationMessage }, - { name: 'min', message: minValidationMessage }, - { name: 'max', message: maxValidationMessage }, - { name: 'passwordMatchValidation', message: passwordMatchValidationMessage }, - { name: 'maximumNumValidation', message: maximumNumValidationMessage }, - { name: 'PasswordStrengthValidation', message: PasswordStrengthValidationMessage } + { name: "required", message: requiredValidationMessage }, + { name: "pattern", message: patternMatchMessage }, + { name: "minLength", message: minlengthValidationMessage }, + { name: "maxLength", message: maxlengthValidationMessage }, + { name: "min", message: minValidationMessage }, + { name: "max", message: maxValidationMessage }, + { + name: "passwordMatchValidation", + message: passwordMatchValidationMessage, + }, + { name: "maximumNumValidation", message: maximumNumValidationMessage }, + { + name: "PasswordStrengthValidation", + message: PasswordStrengthValidationMessage, + }, ], wrappers: [ - { name: 'panel', component: PanelWrapperComponent }, - { name: 'checkbox', component: CheckBoxWrapperComponent }, + { name: "panel", component: PanelWrapperComponent }, + { name: "checkbox", component: CheckBoxWrapperComponent }, // { name: 'error-on-top', component: ErrorWrapperComponent }, // { name: 'slideInOut', component: AnimationWrapperComponent } ], types: [ // { name: 'repeat', component: RepeatSectionComponent }, - { name: 'array', component: types.ArrayTypeComponent }, - { name: 'videoviewer', component: types.FormlyFieldVideoViewer }, - { name: 'videoviewer2', component: types.FormlyFieldVideoViewer2 }, + { name: "array", component: types.ArrayTypeComponent }, + { name: "videoviewer", component: types.FormlyFieldVideoViewer }, + { name: "videoviewer2", component: types.FormlyFieldVideoViewer2 }, // TODO: there should only be one vid viewer that accoms all players - { name: 'videoviewerDM', component: types.FormlyFieldVideoViewerDM }, // TODO: temp player refactor and delete ...see above - { name: 'thumbnailviewer', component: types.ThumbnailViewerComponent }, - { name: 'visibility', component: types.FieldInputVisibilityComponent }, - { name: 'playlist', component: types.FieldInputPlaylistComponent }, - { name: 'tags', component: types.SelectTagsComponent }, - { name: 'countries', component: types.FieldCountriesComponent }, - { name: 'image', component: FormlyImageInputComponent }, - { name: 'audio', component: FormlyAudioInputComponent }, - { name: 'remote-image', component: FormlyRemoteImageInputComponent }, - { name: 'blocks', component: FormlyBlocksInputComponent }, - { name: 'workflow', component: FormlyWorkflowFieldComponent }, - { name: 'cards', component: FormlyCardListComponent }, - { name: 'table', component: FormlyTableWidgetComponent }, - { name: 'paginated', component: FormlyPaginatedWidgetComponent }, + { name: "videoviewerDM", component: types.FormlyFieldVideoViewerDM }, // TODO: temp player refactor and delete ...see above + { name: "thumbnailviewer", component: types.ThumbnailViewerComponent }, + { name: "visibility", component: types.FieldInputVisibilityComponent }, + { name: "playlist", component: types.FieldInputPlaylistComponent }, + { name: "tags", component: types.SelectTagsComponent }, + { name: "countries", component: types.FieldCountriesComponent }, + { name: "image", component: FormlyImageInputComponent }, + { name: "audio", component: FormlyAudioInputComponent }, + { name: "remote-image", component: FormlyRemoteImageInputComponent }, + { name: "blocks", component: FormlyBlocksInputComponent }, + { name: "workflow", component: FormlyWorkflowFieldComponent }, + { name: "cards", component: FormlyCardListComponent }, + { name: "table", component: FormlyTableWidgetComponent }, + { name: "paginated", component: FormlyPaginatedWidgetComponent }, { - name: 'money', component: types.FormlyFieldInputMoney, + name: "money", + component: types.FormlyFieldInputMoney, defaultOptions: { expressionProperties: {}, defaultValue: 5903, templateOptions: { - placeholder: 'hello', + placeholder: "hello", disabled: false, }, }, }, { - name: 'percentage', component: KendraFieldInputPercentage, + name: "percentage", + component: KendraFieldInputPercentage, defaultOptions: { expressionProperties: {}, defaultValue: 0, templateOptions: { - placeholder: 'hello', + placeholder: "hello", disabled: false, }, }, }, - { name: 'typeahead', component: types.KendraFieldTypeahead }, + { name: "typeahead", component: types.KendraFieldTypeahead }, { - name: 'number', - extends: 'input', + name: "number", + extends: "input", defaultOptions: { templateOptions: { - type: 'number', + type: "number", }, }, }, { - name: 'date', - extends: 'input', + name: "date", + extends: "input", defaultOptions: { templateOptions: { - type: 'date', + type: "date", }, }, }, { - name: 'integer', - extends: 'input', + name: "integer", + extends: "input", // defaultOptions: { // templateOptions: { // type: 'email', @@ -124,11 +136,11 @@ export const config: ConfigOption = { // }, }, { - name: 'k-password', + name: "k-password", component: types.FieldInputPasswordComponent, defaultOptions: { templateOptions: { - type: 'password', + type: "password", }, validators: { // validation: ['PasswordStrengthValidation'], @@ -136,11 +148,11 @@ export const config: ConfigOption = { }, }, { - name: 'kendraio-password', + name: "kendraio-password", component: types.FieldInputPasswordComponent, defaultOptions: { templateOptions: { - type: 'password', + type: "password", }, validators: { // validation: ['PasswordStrengthValidation'], @@ -148,114 +160,115 @@ export const config: ConfigOption = { }, }, { - name: 'password', - extends: 'input', + name: "password", + extends: "input", defaultOptions: { templateOptions: { - type: 'password', - }, - validators: { + type: "password", }, + validators: {}, }, }, { - name: 'readonly', + name: "readonly", // extends: 'input', // defaultOptions: { // templateOptions: { // disabled: true, // }, // }, - component: ReadonlyInputComponent + component: ReadonlyInputComponent, }, { - name: 'hidden', - component: types.FieldHiddenComponent + name: "hidden", + component: types.FieldHiddenComponent, }, { - name: 'kendraio-hidden', - component: types.FieldHiddenComponent + name: "kendraio-hidden", + component: types.FieldHiddenComponent, }, - { name: 'string', extends: 'input' }, + { name: "string", extends: "input" }, // { name: 'object', extends: 'formly-group' }, - { name: 'object', component: types.ObjectTypeComponent }, - { name: 'multischema', component: types.MultiSchemaTypeComponent }, - { name: 'formgroup', component: types.FormGroupTypeComponent }, + { name: "object", component: types.ObjectTypeComponent }, + { name: "multischema", component: types.MultiSchemaTypeComponent }, + { name: "formgroup", component: types.FormGroupTypeComponent }, - { name: 'boolean', extends: 'checkbox', - defaultOptions: { - wrappers: ['checkbox'] - } - }, + { + name: "boolean", + extends: "checkbox", + defaultOptions: { + wrappers: ["checkbox"], + }, + }, // { name: 'array', component: ArrayTypeComponent }, - { name: 'enum', extends: 'select' }, - { name: 'textarea', component: types.TextareaComponent}, - { name: 'kendraio-textarea', component: types.TextareaComponent}, - { name: 'k-image', component: types.ImageViewerComponent}, - { name: 'kendraio-image', component: types.ImageViewerComponent}, - { name: 'null', component: types.NullTypeComponent}, + { name: "enum", extends: "select" }, + { name: "textarea", component: types.TextareaComponent }, + { name: "kendraio-textarea", component: types.TextareaComponent }, + { name: "k-image", component: types.ImageViewerComponent }, + { name: "kendraio-image", component: types.ImageViewerComponent }, + { name: "null", component: types.NullTypeComponent }, { - name: 'multiselect', component: types.KendraFieldSelect, + name: "multiselect", + component: types.KendraFieldSelect, defaultOptions: { templateOptions: { multiple: true, - placeholder: 'Select Option', - options: [ ] - } - } - + placeholder: "Select Option", + options: [], + }, + }, }, { - name: 'k-select', component: types.KendraFieldSelect, + name: "k-select", + component: types.KendraFieldSelect, defaultOptions: { - wrappers: ['panel'], + wrappers: ["panel"], templateOptions: { multiple: false, - placeholder: 'Select Option', - options: [] - } - } - + placeholder: "Select Option", + options: [], + }, + }, }, { - name: 'kendraio-select', component: types.KendraFieldSelect, + name: "kendraio-select", + component: types.KendraFieldSelect, defaultOptions: { - wrappers: ['panel'], + wrappers: ["panel"], templateOptions: { multiple: false, - placeholder: 'Select Option', - options: [] - } - } - + placeholder: "Select Option", + options: [], + }, + }, }, { - name: 'k-timepicker', component: types.TimePickerComponent + name: "k-timepicker", + component: types.TimePickerComponent, }, { - name: 'kendraio-timepicker', component: types.TimePickerComponent + name: "kendraio-timepicker", + component: types.TimePickerComponent, }, { - name: 'timepicker', component: types.TimePickerComponent + name: "timepicker", + component: types.TimePickerComponent, }, { - name: 'file', - component: FormlyFileInputComponent + name: "file", + component: FormlyFileInputComponent, // component: FormlyFieldFileComponent, // wrappers: ['form-field'] }, ], validators: [ - { name: 'maximumNumValidation', validation: maximumNumValidation }, - { name: 'passwordMatchValidation', validation: passwordMatchValidation }, - { name: 'PasswordStrengthValidation', validation: PasswordStrengthValidation } - ] + { name: "maximumNumValidation", validation: maximumNumValidation }, + { name: "passwordMatchValidation", validation: passwordMatchValidation }, + { + name: "PasswordStrengthValidation", + validation: PasswordStrengthValidation, + }, + ], }; - - - - - - diff --git a/src/app/_shared/ui-form/types/countries.component.ts b/src/app/_shared/ui-form/types/countries.component.ts index c51f8c15f..05498e23a 100644 --- a/src/app/_shared/ui-form/types/countries.component.ts +++ b/src/app/_shared/ui-form/types/countries.component.ts @@ -1,248 +1,311 @@ -import { Component, EventEmitter, OnDestroy, OnInit } from '@angular/core'; -import { FieldType } from '@ngx-formly/material'; -import { Subject, Observable, of, concat } from 'rxjs'; -import { takeUntil, startWith, filter, debounceTime, distinctUntilChanged, switchMap, concatAll, tap } from 'rxjs/operators'; -import { FormlyFieldConfig } from '@ngx-formly/core'; +import { Component, EventEmitter, OnDestroy, OnInit } from "@angular/core"; +import { FieldType } from "@ngx-formly/material"; +import { Subject, Observable, of, concat } from "rxjs"; +import { + takeUntil, + startWith, + filter, + debounceTime, + distinctUntilChanged, + switchMap, + concatAll, + tap, +} from "rxjs/operators"; +import { FormlyFieldConfig } from "@ngx-formly/core"; // import { of as observableOf } from 'rxjs/observable/of'; - - @Component({ - selector: 'formly-field-typeahead', - template: ` - - - - - {{item.name}} ({{item.alpha3}}) - - - - `, - styleUrls: ['./typeahead.component.scss'], - }) - export class FieldCountriesComponent extends FieldType implements OnDestroy, OnInit { -countries = [{'id': 4, 'name': 'Afghanistan', 'alpha2': 'af', 'alpha3': 'afg'}, -{'id': 8, 'name': 'Albania', 'alpha2': 'al', 'alpha3': 'alb'}, -{'id': 12, 'name': 'Algeria', 'alpha2': 'dz', 'alpha3': 'dza'}, -{'id': 20, 'name': 'Andorra', 'alpha2': 'ad', 'alpha3': 'and'}, -{'id': 24, 'name': 'Angola', 'alpha2': 'ao', 'alpha3': 'ago'}, -{'id': 28, 'name': 'Antigua and Barbuda', 'alpha2': 'ag', 'alpha3': 'atg'}, -{'id': 32, 'name': 'Argentina', 'alpha2': 'ar', 'alpha3': 'arg'}, -{'id': 51, 'name': 'Armenia', 'alpha2': 'am', 'alpha3': 'arm'}, -{'id': 36, 'name': 'Australia', 'alpha2': 'au', 'alpha3': 'aus'}, -{'id': 40, 'name': 'Austria', 'alpha2': 'at', 'alpha3': 'aut'}, -{'id': 31, 'name': 'Azerbaijan', 'alpha2': 'az', 'alpha3': 'aze'}, -{'id': 44, 'name': 'Bahamas', 'alpha2': 'bs', 'alpha3': 'bhs'}, -{'id': 48, 'name': 'Bahrain', 'alpha2': 'bh', 'alpha3': 'bhr'}, -{'id': 50, 'name': 'Bangladesh', 'alpha2': 'bd', 'alpha3': 'bgd'}, -{'id': 52, 'name': 'Barbados', 'alpha2': 'bb', 'alpha3': 'brb'}, -{'id': 112, 'name': 'Belarus', 'alpha2': 'by', 'alpha3': 'blr'}, -{'id': 56, 'name': 'Belgium', 'alpha2': 'be', 'alpha3': 'bel'}, -{'id': 84, 'name': 'Belize', 'alpha2': 'bz', 'alpha3': 'blz'}, -{'id': 204, 'name': 'Benin', 'alpha2': 'bj', 'alpha3': 'ben'}, -{'id': 64, 'name': 'Bhutan', 'alpha2': 'bt', 'alpha3': 'btn'}, -{'id': 68, 'name': 'Bolivia (Plurinational State of)', 'alpha2': 'bo', 'alpha3': 'bol'}, -{'id': 70, 'name': 'Bosnia and Herzegovina', 'alpha2': 'ba', 'alpha3': 'bih'}, -{'id': 72, 'name': 'Botswana', 'alpha2': 'bw', 'alpha3': 'bwa'}, -{'id': 76, 'name': 'Brazil', 'alpha2': 'br', 'alpha3': 'bra'}, -{'id': 96, 'name': 'Brunei Darussalam', 'alpha2': 'bn', 'alpha3': 'brn'}, -{'id': 100, 'name': 'Bulgaria', 'alpha2': 'bg', 'alpha3': 'bgr'}, -{'id': 854, 'name': 'Burkina Faso', 'alpha2': 'bf', 'alpha3': 'bfa'}, -{'id': 108, 'name': 'Burundi', 'alpha2': 'bi', 'alpha3': 'bdi'}, -{'id': 132, 'name': 'Cabo Verde', 'alpha2': 'cv', 'alpha3': 'cpv'}, -{'id': 116, 'name': 'Cambodia', 'alpha2': 'kh', 'alpha3': 'khm'}, -{'id': 120, 'name': 'Cameroon', 'alpha2': 'cm', 'alpha3': 'cmr'}, -{'id': 124, 'name': 'Canada', 'alpha2': 'ca', 'alpha3': 'can'}, -{'id': 140, 'name': 'Central African Republic', 'alpha2': 'cf', 'alpha3': 'caf'}, -{'id': 148, 'name': 'Chad', 'alpha2': 'td', 'alpha3': 'tcd'}, -{'id': 152, 'name': 'Chile', 'alpha2': 'cl', 'alpha3': 'chl'}, -{'id': 156, 'name': 'China', 'alpha2': 'cn', 'alpha3': 'chn'}, -{'id': 170, 'name': 'Colombia', 'alpha2': 'co', 'alpha3': 'col'}, -{'id': 174, 'name': 'Comoros', 'alpha2': 'km', 'alpha3': 'com'}, -{'id': 178, 'name': 'Congo', 'alpha2': 'cg', 'alpha3': 'cog'}, -{'id': 180, 'name': 'Congo, Democratic Republic of the', 'alpha2': 'cd', 'alpha3': 'cod'}, -{'id': 188, 'name': 'Costa Rica', 'alpha2': 'cr', 'alpha3': 'cri'}, -{'id': 384, 'name': 'Côte d\'Ivoire', 'alpha2': 'ci', 'alpha3': 'civ'}, -{'id': 191, 'name': 'Croatia', 'alpha2': 'hr', 'alpha3': 'hrv'}, -{'id': 192, 'name': 'Cuba', 'alpha2': 'cu', 'alpha3': 'cub'}, -{'id': 196, 'name': 'Cyprus', 'alpha2': 'cy', 'alpha3': 'cyp'}, -{'id': 203, 'name': 'Czechia', 'alpha2': 'cz', 'alpha3': 'cze'}, -{'id': 208, 'name': 'Denmark', 'alpha2': 'dk', 'alpha3': 'dnk'}, -{'id': 262, 'name': 'Djibouti', 'alpha2': 'dj', 'alpha3': 'dji'}, -{'id': 212, 'name': 'Dominica', 'alpha2': 'dm', 'alpha3': 'dma'}, -{'id': 214, 'name': 'Dominican Republic', 'alpha2': 'do', 'alpha3': 'dom'}, -{'id': 218, 'name': 'Ecuador', 'alpha2': 'ec', 'alpha3': 'ecu'}, -{'id': 818, 'name': 'Egypt', 'alpha2': 'eg', 'alpha3': 'egy'}, -{'id': 222, 'name': 'El Salvador', 'alpha2': 'sv', 'alpha3': 'slv'}, -{'id': 226, 'name': 'Equatorial Guinea', 'alpha2': 'gq', 'alpha3': 'gnq'}, -{'id': 232, 'name': 'Eritrea', 'alpha2': 'er', 'alpha3': 'eri'}, -{'id': 233, 'name': 'Estonia', 'alpha2': 'ee', 'alpha3': 'est'}, -{'id': 748, 'name': 'Eswatini', 'alpha2': 'sz', 'alpha3': 'swz'}, -{'id': 231, 'name': 'Ethiopia', 'alpha2': 'et', 'alpha3': 'eth'}, -{'id': 242, 'name': 'Fiji', 'alpha2': 'fj', 'alpha3': 'fji'}, -{'id': 246, 'name': 'Finland', 'alpha2': 'fi', 'alpha3': 'fin'}, -{'id': 250, 'name': 'France', 'alpha2': 'fr', 'alpha3': 'fra'}, -{'id': 266, 'name': 'Gabon', 'alpha2': 'ga', 'alpha3': 'gab'}, -{'id': 270, 'name': 'Gambia', 'alpha2': 'gm', 'alpha3': 'gmb'}, -{'id': 268, 'name': 'Georgia', 'alpha2': 'ge', 'alpha3': 'geo'}, -{'id': 276, 'name': 'Germany', 'alpha2': 'de', 'alpha3': 'deu'}, -{'id': 288, 'name': 'Ghana', 'alpha2': 'gh', 'alpha3': 'gha'}, -{'id': 300, 'name': 'Greece', 'alpha2': 'gr', 'alpha3': 'grc'}, -{'id': 308, 'name': 'Grenada', 'alpha2': 'gd', 'alpha3': 'grd'}, -{'id': 320, 'name': 'Guatemala', 'alpha2': 'gt', 'alpha3': 'gtm'}, -{'id': 324, 'name': 'Guinea', 'alpha2': 'gn', 'alpha3': 'gin'}, -{'id': 624, 'name': 'Guinea-Bissau', 'alpha2': 'gw', 'alpha3': 'gnb'}, -{'id': 328, 'name': 'Guyana', 'alpha2': 'gy', 'alpha3': 'guy'}, -{'id': 332, 'name': 'Haiti', 'alpha2': 'ht', 'alpha3': 'hti'}, -{'id': 340, 'name': 'Honduras', 'alpha2': 'hn', 'alpha3': 'hnd'}, -{'id': 348, 'name': 'Hungary', 'alpha2': 'hu', 'alpha3': 'hun'}, -{'id': 352, 'name': 'Iceland', 'alpha2': 'is', 'alpha3': 'isl'}, -{'id': 356, 'name': 'India', 'alpha2': 'in', 'alpha3': 'ind'}, -{'id': 360, 'name': 'Indonesia', 'alpha2': 'id', 'alpha3': 'idn'}, -{'id': 364, 'name': 'Iran (Islamic Republic of)', 'alpha2': 'ir', 'alpha3': 'irn'}, -{'id': 368, 'name': 'Iraq', 'alpha2': 'iq', 'alpha3': 'irq'}, -{'id': 372, 'name': 'Ireland', 'alpha2': 'ie', 'alpha3': 'irl'}, -{'id': 376, 'name': 'Israel', 'alpha2': 'il', 'alpha3': 'isr'}, -{'id': 380, 'name': 'Italy', 'alpha2': 'it', 'alpha3': 'ita'}, -{'id': 388, 'name': 'Jamaica', 'alpha2': 'jm', 'alpha3': 'jam'}, -{'id': 392, 'name': 'Japan', 'alpha2': 'jp', 'alpha3': 'jpn'}, -{'id': 400, 'name': 'Jordan', 'alpha2': 'jo', 'alpha3': 'jor'}, -{'id': 398, 'name': 'Kazakhstan', 'alpha2': 'kz', 'alpha3': 'kaz'}, -{'id': 404, 'name': 'Kenya', 'alpha2': 'ke', 'alpha3': 'ken'}, -{'id': 296, 'name': 'Kiribati', 'alpha2': 'ki', 'alpha3': 'kir'}, -{'id': 408, 'name': 'Korea (Democratic People\'s Republic of)', 'alpha2': 'kp', 'alpha3': 'prk'}, -{'id': 410, 'name': 'Korea, Republic of', 'alpha2': 'kr', 'alpha3': 'kor'}, -{'id': 414, 'name': 'Kuwait', 'alpha2': 'kw', 'alpha3': 'kwt'}, -{'id': 417, 'name': 'Kyrgyzstan', 'alpha2': 'kg', 'alpha3': 'kgz'}, -{'id': 418, 'name': 'Lao People\'s Democratic Republic', 'alpha2': 'la', 'alpha3': 'lao'}, -{'id': 428, 'name': 'Latvia', 'alpha2': 'lv', 'alpha3': 'lva'}, -{'id': 422, 'name': 'Lebanon', 'alpha2': 'lb', 'alpha3': 'lbn'}, -{'id': 426, 'name': 'Lesotho', 'alpha2': 'ls', 'alpha3': 'lso'}, -{'id': 430, 'name': 'Liberia', 'alpha2': 'lr', 'alpha3': 'lbr'}, -{'id': 434, 'name': 'Libya', 'alpha2': 'ly', 'alpha3': 'lby'}, -{'id': 438, 'name': 'Liechtenstein', 'alpha2': 'li', 'alpha3': 'lie'}, -{'id': 440, 'name': 'Lithuania', 'alpha2': 'lt', 'alpha3': 'ltu'}, -{'id': 442, 'name': 'Luxembourg', 'alpha2': 'lu', 'alpha3': 'lux'}, -{'id': 450, 'name': 'Madagascar', 'alpha2': 'mg', 'alpha3': 'mdg'}, -{'id': 454, 'name': 'Malawi', 'alpha2': 'mw', 'alpha3': 'mwi'}, -{'id': 458, 'name': 'Malaysia', 'alpha2': 'my', 'alpha3': 'mys'}, -{'id': 462, 'name': 'Maldives', 'alpha2': 'mv', 'alpha3': 'mdv'}, -{'id': 466, 'name': 'Mali', 'alpha2': 'ml', 'alpha3': 'mli'}, -{'id': 470, 'name': 'Malta', 'alpha2': 'mt', 'alpha3': 'mlt'}, -{'id': 584, 'name': 'Marshall Islands', 'alpha2': 'mh', 'alpha3': 'mhl'}, -{'id': 478, 'name': 'Mauritania', 'alpha2': 'mr', 'alpha3': 'mrt'}, -{'id': 480, 'name': 'Mauritius', 'alpha2': 'mu', 'alpha3': 'mus'}, -{'id': 484, 'name': 'Mexico', 'alpha2': 'mx', 'alpha3': 'mex'}, -{'id': 583, 'name': 'Micronesia (Federated States of)', 'alpha2': 'fm', 'alpha3': 'fsm'}, -{'id': 498, 'name': 'Moldova, Republic of', 'alpha2': 'md', 'alpha3': 'mda'}, -{'id': 492, 'name': 'Monaco', 'alpha2': 'mc', 'alpha3': 'mco'}, -{'id': 496, 'name': 'Mongolia', 'alpha2': 'mn', 'alpha3': 'mng'}, -{'id': 499, 'name': 'Montenegro', 'alpha2': 'me', 'alpha3': 'mne'}, -{'id': 504, 'name': 'Morocco', 'alpha2': 'ma', 'alpha3': 'mar'}, -{'id': 508, 'name': 'Mozambique', 'alpha2': 'mz', 'alpha3': 'moz'}, -{'id': 104, 'name': 'Myanmar', 'alpha2': 'mm', 'alpha3': 'mmr'}, -{'id': 516, 'name': 'Namibia', 'alpha2': 'na', 'alpha3': 'nam'}, -{'id': 520, 'name': 'Nauru', 'alpha2': 'nr', 'alpha3': 'nru'}, -{'id': 524, 'name': 'Nepal', 'alpha2': 'np', 'alpha3': 'npl'}, -{'id': 528, 'name': 'Netherlands', 'alpha2': 'nl', 'alpha3': 'nld'}, -{'id': 554, 'name': 'New Zealand', 'alpha2': 'nz', 'alpha3': 'nzl'}, -{'id': 558, 'name': 'Nicaragua', 'alpha2': 'ni', 'alpha3': 'nic'}, -{'id': 562, 'name': 'Niger', 'alpha2': 'ne', 'alpha3': 'ner'}, -{'id': 566, 'name': 'Nigeria', 'alpha2': 'ng', 'alpha3': 'nga'}, -{'id': 807, 'name': 'North Macedonia', 'alpha2': 'mk', 'alpha3': 'mkd'}, -{'id': 578, 'name': 'Norway', 'alpha2': 'no', 'alpha3': 'nor'}, -{'id': 512, 'name': 'Oman', 'alpha2': 'om', 'alpha3': 'omn'}, -{'id': 586, 'name': 'Pakistan', 'alpha2': 'pk', 'alpha3': 'pak'}, -{'id': 585, 'name': 'Palau', 'alpha2': 'pw', 'alpha3': 'plw'}, -{'id': 591, 'name': 'Panama', 'alpha2': 'pa', 'alpha3': 'pan'}, -{'id': 598, 'name': 'Papua New Guinea', 'alpha2': 'pg', 'alpha3': 'png'}, -{'id': 600, 'name': 'Paraguay', 'alpha2': 'py', 'alpha3': 'pry'}, -{'id': 604, 'name': 'Peru', 'alpha2': 'pe', 'alpha3': 'per'}, -{'id': 608, 'name': 'Philippines', 'alpha2': 'ph', 'alpha3': 'phl'}, -{'id': 616, 'name': 'Poland', 'alpha2': 'pl', 'alpha3': 'pol'}, -{'id': 620, 'name': 'Portugal', 'alpha2': 'pt', 'alpha3': 'prt'}, -{'id': 634, 'name': 'Qatar', 'alpha2': 'qa', 'alpha3': 'qat'}, -{'id': 642, 'name': 'Romania', 'alpha2': 'ro', 'alpha3': 'rou'}, -{'id': 643, 'name': 'Russian Federation', 'alpha2': 'ru', 'alpha3': 'rus'}, -{'id': 646, 'name': 'Rwanda', 'alpha2': 'rw', 'alpha3': 'rwa'}, -{'id': 659, 'name': 'Saint Kitts and Nevis', 'alpha2': 'kn', 'alpha3': 'kna'}, -{'id': 662, 'name': 'Saint Lucia', 'alpha2': 'lc', 'alpha3': 'lca'}, -{'id': 670, 'name': 'Saint Vincent and the Grenadines', 'alpha2': 'vc', 'alpha3': 'vct'}, -{'id': 882, 'name': 'Samoa', 'alpha2': 'ws', 'alpha3': 'wsm'}, -{'id': 674, 'name': 'San Marino', 'alpha2': 'sm', 'alpha3': 'smr'}, -{'id': 678, 'name': 'Sao Tome and Principe', 'alpha2': 'st', 'alpha3': 'stp'}, -{'id': 682, 'name': 'Saudi Arabia', 'alpha2': 'sa', 'alpha3': 'sau'}, -{'id': 686, 'name': 'Senegal', 'alpha2': 'sn', 'alpha3': 'sen'}, -{'id': 688, 'name': 'Serbia', 'alpha2': 'rs', 'alpha3': 'srb'}, -{'id': 690, 'name': 'Seychelles', 'alpha2': 'sc', 'alpha3': 'syc'}, -{'id': 694, 'name': 'Sierra Leone', 'alpha2': 'sl', 'alpha3': 'sle'}, -{'id': 702, 'name': 'Singapore', 'alpha2': 'sg', 'alpha3': 'sgp'}, -{'id': 703, 'name': 'Slovakia', 'alpha2': 'sk', 'alpha3': 'svk'}, -{'id': 705, 'name': 'Slovenia', 'alpha2': 'si', 'alpha3': 'svn'}, -{'id': 90, 'name': 'Solomon Islands', 'alpha2': 'sb', 'alpha3': 'slb'}, -{'id': 706, 'name': 'Somalia', 'alpha2': 'so', 'alpha3': 'som'}, -{'id': 710, 'name': 'South Africa', 'alpha2': 'za', 'alpha3': 'zaf'}, -{'id': 728, 'name': 'South Sudan', 'alpha2': 'ss', 'alpha3': 'ssd'}, -{'id': 724, 'name': 'Spain', 'alpha2': 'es', 'alpha3': 'esp'}, -{'id': 144, 'name': 'Sri Lanka', 'alpha2': 'lk', 'alpha3': 'lka'}, -{'id': 729, 'name': 'Sudan', 'alpha2': 'sd', 'alpha3': 'sdn'}, -{'id': 740, 'name': 'Suriname', 'alpha2': 'sr', 'alpha3': 'sur'}, -{'id': 752, 'name': 'Sweden', 'alpha2': 'se', 'alpha3': 'swe'}, -{'id': 756, 'name': 'Switzerland', 'alpha2': 'ch', 'alpha3': 'che'}, -{'id': 760, 'name': 'Syrian Arab Republic', 'alpha2': 'sy', 'alpha3': 'syr'}, -{'id': 762, 'name': 'Tajikistan', 'alpha2': 'tj', 'alpha3': 'tjk'}, -{'id': 834, 'name': 'Tanzania, United Republic of', 'alpha2': 'tz', 'alpha3': 'tza'}, -{'id': 764, 'name': 'Thailand', 'alpha2': 'th', 'alpha3': 'tha'}, -{'id': 626, 'name': 'Timor-Leste', 'alpha2': 'tl', 'alpha3': 'tls'}, -{'id': 768, 'name': 'Togo', 'alpha2': 'tg', 'alpha3': 'tgo'}, -{'id': 776, 'name': 'Tonga', 'alpha2': 'to', 'alpha3': 'ton'}, -{'id': 780, 'name': 'Trinidad and Tobago', 'alpha2': 'tt', 'alpha3': 'tto'}, -{'id': 788, 'name': 'Tunisia', 'alpha2': 'tn', 'alpha3': 'tun'}, -{'id': 792, 'name': 'Turkey', 'alpha2': 'tr', 'alpha3': 'tur'}, -{'id': 795, 'name': 'Turkmenistan', 'alpha2': 'tm', 'alpha3': 'tkm'}, -{'id': 798, 'name': 'Tuvalu', 'alpha2': 'tv', 'alpha3': 'tuv'}, -{'id': 800, 'name': 'Uganda', 'alpha2': 'ug', 'alpha3': 'uga'}, -{'id': 804, 'name': 'Ukraine', 'alpha2': 'ua', 'alpha3': 'ukr'}, -{'id': 784, 'name': 'United Arab Emirates', 'alpha2': 'ae', 'alpha3': 'are'}, -{'id': 826, 'name': 'United Kingdom of Great Britain and Northern Ireland', 'alpha2': 'gb', 'alpha3': 'gbr'}, -{'id': 840, 'name': 'United States of America', 'alpha2': 'us', 'alpha3': 'usa'}, -{'id': 858, 'name': 'Uruguay', 'alpha2': 'uy', 'alpha3': 'ury'}, -{'id': 860, 'name': 'Uzbekistan', 'alpha2': 'uz', 'alpha3': 'uzb'}, -{'id': 548, 'name': 'Vanuatu', 'alpha2': 'vu', 'alpha3': 'vut'}, -{'id': 862, 'name': 'Venezuela (Bolivarian Republic of)', 'alpha2': 've', 'alpha3': 'ven'}, -{'id': 704, 'name': 'Viet Nam', 'alpha2': 'vn', 'alpha3': 'vnm'}, -{'id': 887, 'name': 'Yemen', 'alpha2': 'ye', 'alpha3': 'yem'}, -{'id': 894, 'name': 'Zambia', 'alpha2': 'zm', 'alpha3': 'zmb'}, -{'id': 716, 'name': 'Zimbabwe', 'alpha2': 'zw', 'alpha3': 'zwe'} -]; -countriesLoading = false; -selectedCountry: string; -onDestroy$ = new Subject(); -search$ = new EventEmitter(); -countries$: Observable; -// field: FormlyFieldConfig = -// { -// templateOptions: { -// placeholder: 'Search for a state:', -// search$: (term) => { -// if ((!term || term === '')) { -// return of(this.countries); -// } - -// return of(this.countries.filter(name => name.name.toLowerCase().indexOf(term.toLowerCase()) > -1).slice(0, 10)); -// }, -// } -// }; + selector: "formly-field-typeahead", + template: ` + + + + {{ item.name }} ({{ item.alpha3 }}) + + + `, + styleUrls: ["./typeahead.component.scss"], +}) +export class FieldCountriesComponent + extends FieldType + implements OnDestroy, OnInit +{ + countries = [ + { id: 4, name: "Afghanistan", alpha2: "af", alpha3: "afg" }, + { id: 8, name: "Albania", alpha2: "al", alpha3: "alb" }, + { id: 12, name: "Algeria", alpha2: "dz", alpha3: "dza" }, + { id: 20, name: "Andorra", alpha2: "ad", alpha3: "and" }, + { id: 24, name: "Angola", alpha2: "ao", alpha3: "ago" }, + { id: 28, name: "Antigua and Barbuda", alpha2: "ag", alpha3: "atg" }, + { id: 32, name: "Argentina", alpha2: "ar", alpha3: "arg" }, + { id: 51, name: "Armenia", alpha2: "am", alpha3: "arm" }, + { id: 36, name: "Australia", alpha2: "au", alpha3: "aus" }, + { id: 40, name: "Austria", alpha2: "at", alpha3: "aut" }, + { id: 31, name: "Azerbaijan", alpha2: "az", alpha3: "aze" }, + { id: 44, name: "Bahamas", alpha2: "bs", alpha3: "bhs" }, + { id: 48, name: "Bahrain", alpha2: "bh", alpha3: "bhr" }, + { id: 50, name: "Bangladesh", alpha2: "bd", alpha3: "bgd" }, + { id: 52, name: "Barbados", alpha2: "bb", alpha3: "brb" }, + { id: 112, name: "Belarus", alpha2: "by", alpha3: "blr" }, + { id: 56, name: "Belgium", alpha2: "be", alpha3: "bel" }, + { id: 84, name: "Belize", alpha2: "bz", alpha3: "blz" }, + { id: 204, name: "Benin", alpha2: "bj", alpha3: "ben" }, + { id: 64, name: "Bhutan", alpha2: "bt", alpha3: "btn" }, + { + id: 68, + name: "Bolivia (Plurinational State of)", + alpha2: "bo", + alpha3: "bol", + }, + { id: 70, name: "Bosnia and Herzegovina", alpha2: "ba", alpha3: "bih" }, + { id: 72, name: "Botswana", alpha2: "bw", alpha3: "bwa" }, + { id: 76, name: "Brazil", alpha2: "br", alpha3: "bra" }, + { id: 96, name: "Brunei Darussalam", alpha2: "bn", alpha3: "brn" }, + { id: 100, name: "Bulgaria", alpha2: "bg", alpha3: "bgr" }, + { id: 854, name: "Burkina Faso", alpha2: "bf", alpha3: "bfa" }, + { id: 108, name: "Burundi", alpha2: "bi", alpha3: "bdi" }, + { id: 132, name: "Cabo Verde", alpha2: "cv", alpha3: "cpv" }, + { id: 116, name: "Cambodia", alpha2: "kh", alpha3: "khm" }, + { id: 120, name: "Cameroon", alpha2: "cm", alpha3: "cmr" }, + { id: 124, name: "Canada", alpha2: "ca", alpha3: "can" }, + { id: 140, name: "Central African Republic", alpha2: "cf", alpha3: "caf" }, + { id: 148, name: "Chad", alpha2: "td", alpha3: "tcd" }, + { id: 152, name: "Chile", alpha2: "cl", alpha3: "chl" }, + { id: 156, name: "China", alpha2: "cn", alpha3: "chn" }, + { id: 170, name: "Colombia", alpha2: "co", alpha3: "col" }, + { id: 174, name: "Comoros", alpha2: "km", alpha3: "com" }, + { id: 178, name: "Congo", alpha2: "cg", alpha3: "cog" }, + { + id: 180, + name: "Congo, Democratic Republic of the", + alpha2: "cd", + alpha3: "cod", + }, + { id: 188, name: "Costa Rica", alpha2: "cr", alpha3: "cri" }, + { id: 384, name: "Côte d'Ivoire", alpha2: "ci", alpha3: "civ" }, + { id: 191, name: "Croatia", alpha2: "hr", alpha3: "hrv" }, + { id: 192, name: "Cuba", alpha2: "cu", alpha3: "cub" }, + { id: 196, name: "Cyprus", alpha2: "cy", alpha3: "cyp" }, + { id: 203, name: "Czechia", alpha2: "cz", alpha3: "cze" }, + { id: 208, name: "Denmark", alpha2: "dk", alpha3: "dnk" }, + { id: 262, name: "Djibouti", alpha2: "dj", alpha3: "dji" }, + { id: 212, name: "Dominica", alpha2: "dm", alpha3: "dma" }, + { id: 214, name: "Dominican Republic", alpha2: "do", alpha3: "dom" }, + { id: 218, name: "Ecuador", alpha2: "ec", alpha3: "ecu" }, + { id: 818, name: "Egypt", alpha2: "eg", alpha3: "egy" }, + { id: 222, name: "El Salvador", alpha2: "sv", alpha3: "slv" }, + { id: 226, name: "Equatorial Guinea", alpha2: "gq", alpha3: "gnq" }, + { id: 232, name: "Eritrea", alpha2: "er", alpha3: "eri" }, + { id: 233, name: "Estonia", alpha2: "ee", alpha3: "est" }, + { id: 748, name: "Eswatini", alpha2: "sz", alpha3: "swz" }, + { id: 231, name: "Ethiopia", alpha2: "et", alpha3: "eth" }, + { id: 242, name: "Fiji", alpha2: "fj", alpha3: "fji" }, + { id: 246, name: "Finland", alpha2: "fi", alpha3: "fin" }, + { id: 250, name: "France", alpha2: "fr", alpha3: "fra" }, + { id: 266, name: "Gabon", alpha2: "ga", alpha3: "gab" }, + { id: 270, name: "Gambia", alpha2: "gm", alpha3: "gmb" }, + { id: 268, name: "Georgia", alpha2: "ge", alpha3: "geo" }, + { id: 276, name: "Germany", alpha2: "de", alpha3: "deu" }, + { id: 288, name: "Ghana", alpha2: "gh", alpha3: "gha" }, + { id: 300, name: "Greece", alpha2: "gr", alpha3: "grc" }, + { id: 308, name: "Grenada", alpha2: "gd", alpha3: "grd" }, + { id: 320, name: "Guatemala", alpha2: "gt", alpha3: "gtm" }, + { id: 324, name: "Guinea", alpha2: "gn", alpha3: "gin" }, + { id: 624, name: "Guinea-Bissau", alpha2: "gw", alpha3: "gnb" }, + { id: 328, name: "Guyana", alpha2: "gy", alpha3: "guy" }, + { id: 332, name: "Haiti", alpha2: "ht", alpha3: "hti" }, + { id: 340, name: "Honduras", alpha2: "hn", alpha3: "hnd" }, + { id: 348, name: "Hungary", alpha2: "hu", alpha3: "hun" }, + { id: 352, name: "Iceland", alpha2: "is", alpha3: "isl" }, + { id: 356, name: "India", alpha2: "in", alpha3: "ind" }, + { id: 360, name: "Indonesia", alpha2: "id", alpha3: "idn" }, + { + id: 364, + name: "Iran (Islamic Republic of)", + alpha2: "ir", + alpha3: "irn", + }, + { id: 368, name: "Iraq", alpha2: "iq", alpha3: "irq" }, + { id: 372, name: "Ireland", alpha2: "ie", alpha3: "irl" }, + { id: 376, name: "Israel", alpha2: "il", alpha3: "isr" }, + { id: 380, name: "Italy", alpha2: "it", alpha3: "ita" }, + { id: 388, name: "Jamaica", alpha2: "jm", alpha3: "jam" }, + { id: 392, name: "Japan", alpha2: "jp", alpha3: "jpn" }, + { id: 400, name: "Jordan", alpha2: "jo", alpha3: "jor" }, + { id: 398, name: "Kazakhstan", alpha2: "kz", alpha3: "kaz" }, + { id: 404, name: "Kenya", alpha2: "ke", alpha3: "ken" }, + { id: 296, name: "Kiribati", alpha2: "ki", alpha3: "kir" }, + { + id: 408, + name: "Korea (Democratic People's Republic of)", + alpha2: "kp", + alpha3: "prk", + }, + { id: 410, name: "Korea, Republic of", alpha2: "kr", alpha3: "kor" }, + { id: 414, name: "Kuwait", alpha2: "kw", alpha3: "kwt" }, + { id: 417, name: "Kyrgyzstan", alpha2: "kg", alpha3: "kgz" }, + { + id: 418, + name: "Lao People's Democratic Republic", + alpha2: "la", + alpha3: "lao", + }, + { id: 428, name: "Latvia", alpha2: "lv", alpha3: "lva" }, + { id: 422, name: "Lebanon", alpha2: "lb", alpha3: "lbn" }, + { id: 426, name: "Lesotho", alpha2: "ls", alpha3: "lso" }, + { id: 430, name: "Liberia", alpha2: "lr", alpha3: "lbr" }, + { id: 434, name: "Libya", alpha2: "ly", alpha3: "lby" }, + { id: 438, name: "Liechtenstein", alpha2: "li", alpha3: "lie" }, + { id: 440, name: "Lithuania", alpha2: "lt", alpha3: "ltu" }, + { id: 442, name: "Luxembourg", alpha2: "lu", alpha3: "lux" }, + { id: 450, name: "Madagascar", alpha2: "mg", alpha3: "mdg" }, + { id: 454, name: "Malawi", alpha2: "mw", alpha3: "mwi" }, + { id: 458, name: "Malaysia", alpha2: "my", alpha3: "mys" }, + { id: 462, name: "Maldives", alpha2: "mv", alpha3: "mdv" }, + { id: 466, name: "Mali", alpha2: "ml", alpha3: "mli" }, + { id: 470, name: "Malta", alpha2: "mt", alpha3: "mlt" }, + { id: 584, name: "Marshall Islands", alpha2: "mh", alpha3: "mhl" }, + { id: 478, name: "Mauritania", alpha2: "mr", alpha3: "mrt" }, + { id: 480, name: "Mauritius", alpha2: "mu", alpha3: "mus" }, + { id: 484, name: "Mexico", alpha2: "mx", alpha3: "mex" }, + { + id: 583, + name: "Micronesia (Federated States of)", + alpha2: "fm", + alpha3: "fsm", + }, + { id: 498, name: "Moldova, Republic of", alpha2: "md", alpha3: "mda" }, + { id: 492, name: "Monaco", alpha2: "mc", alpha3: "mco" }, + { id: 496, name: "Mongolia", alpha2: "mn", alpha3: "mng" }, + { id: 499, name: "Montenegro", alpha2: "me", alpha3: "mne" }, + { id: 504, name: "Morocco", alpha2: "ma", alpha3: "mar" }, + { id: 508, name: "Mozambique", alpha2: "mz", alpha3: "moz" }, + { id: 104, name: "Myanmar", alpha2: "mm", alpha3: "mmr" }, + { id: 516, name: "Namibia", alpha2: "na", alpha3: "nam" }, + { id: 520, name: "Nauru", alpha2: "nr", alpha3: "nru" }, + { id: 524, name: "Nepal", alpha2: "np", alpha3: "npl" }, + { id: 528, name: "Netherlands", alpha2: "nl", alpha3: "nld" }, + { id: 554, name: "New Zealand", alpha2: "nz", alpha3: "nzl" }, + { id: 558, name: "Nicaragua", alpha2: "ni", alpha3: "nic" }, + { id: 562, name: "Niger", alpha2: "ne", alpha3: "ner" }, + { id: 566, name: "Nigeria", alpha2: "ng", alpha3: "nga" }, + { id: 807, name: "North Macedonia", alpha2: "mk", alpha3: "mkd" }, + { id: 578, name: "Norway", alpha2: "no", alpha3: "nor" }, + { id: 512, name: "Oman", alpha2: "om", alpha3: "omn" }, + { id: 586, name: "Pakistan", alpha2: "pk", alpha3: "pak" }, + { id: 585, name: "Palau", alpha2: "pw", alpha3: "plw" }, + { id: 591, name: "Panama", alpha2: "pa", alpha3: "pan" }, + { id: 598, name: "Papua New Guinea", alpha2: "pg", alpha3: "png" }, + { id: 600, name: "Paraguay", alpha2: "py", alpha3: "pry" }, + { id: 604, name: "Peru", alpha2: "pe", alpha3: "per" }, + { id: 608, name: "Philippines", alpha2: "ph", alpha3: "phl" }, + { id: 616, name: "Poland", alpha2: "pl", alpha3: "pol" }, + { id: 620, name: "Portugal", alpha2: "pt", alpha3: "prt" }, + { id: 634, name: "Qatar", alpha2: "qa", alpha3: "qat" }, + { id: 642, name: "Romania", alpha2: "ro", alpha3: "rou" }, + { id: 643, name: "Russian Federation", alpha2: "ru", alpha3: "rus" }, + { id: 646, name: "Rwanda", alpha2: "rw", alpha3: "rwa" }, + { id: 659, name: "Saint Kitts and Nevis", alpha2: "kn", alpha3: "kna" }, + { id: 662, name: "Saint Lucia", alpha2: "lc", alpha3: "lca" }, + { + id: 670, + name: "Saint Vincent and the Grenadines", + alpha2: "vc", + alpha3: "vct", + }, + { id: 882, name: "Samoa", alpha2: "ws", alpha3: "wsm" }, + { id: 674, name: "San Marino", alpha2: "sm", alpha3: "smr" }, + { id: 678, name: "Sao Tome and Principe", alpha2: "st", alpha3: "stp" }, + { id: 682, name: "Saudi Arabia", alpha2: "sa", alpha3: "sau" }, + { id: 686, name: "Senegal", alpha2: "sn", alpha3: "sen" }, + { id: 688, name: "Serbia", alpha2: "rs", alpha3: "srb" }, + { id: 690, name: "Seychelles", alpha2: "sc", alpha3: "syc" }, + { id: 694, name: "Sierra Leone", alpha2: "sl", alpha3: "sle" }, + { id: 702, name: "Singapore", alpha2: "sg", alpha3: "sgp" }, + { id: 703, name: "Slovakia", alpha2: "sk", alpha3: "svk" }, + { id: 705, name: "Slovenia", alpha2: "si", alpha3: "svn" }, + { id: 90, name: "Solomon Islands", alpha2: "sb", alpha3: "slb" }, + { id: 706, name: "Somalia", alpha2: "so", alpha3: "som" }, + { id: 710, name: "South Africa", alpha2: "za", alpha3: "zaf" }, + { id: 728, name: "South Sudan", alpha2: "ss", alpha3: "ssd" }, + { id: 724, name: "Spain", alpha2: "es", alpha3: "esp" }, + { id: 144, name: "Sri Lanka", alpha2: "lk", alpha3: "lka" }, + { id: 729, name: "Sudan", alpha2: "sd", alpha3: "sdn" }, + { id: 740, name: "Suriname", alpha2: "sr", alpha3: "sur" }, + { id: 752, name: "Sweden", alpha2: "se", alpha3: "swe" }, + { id: 756, name: "Switzerland", alpha2: "ch", alpha3: "che" }, + { id: 760, name: "Syrian Arab Republic", alpha2: "sy", alpha3: "syr" }, + { id: 762, name: "Tajikistan", alpha2: "tj", alpha3: "tjk" }, + { + id: 834, + name: "Tanzania, United Republic of", + alpha2: "tz", + alpha3: "tza", + }, + { id: 764, name: "Thailand", alpha2: "th", alpha3: "tha" }, + { id: 626, name: "Timor-Leste", alpha2: "tl", alpha3: "tls" }, + { id: 768, name: "Togo", alpha2: "tg", alpha3: "tgo" }, + { id: 776, name: "Tonga", alpha2: "to", alpha3: "ton" }, + { id: 780, name: "Trinidad and Tobago", alpha2: "tt", alpha3: "tto" }, + { id: 788, name: "Tunisia", alpha2: "tn", alpha3: "tun" }, + { id: 792, name: "Turkey", alpha2: "tr", alpha3: "tur" }, + { id: 795, name: "Turkmenistan", alpha2: "tm", alpha3: "tkm" }, + { id: 798, name: "Tuvalu", alpha2: "tv", alpha3: "tuv" }, + { id: 800, name: "Uganda", alpha2: "ug", alpha3: "uga" }, + { id: 804, name: "Ukraine", alpha2: "ua", alpha3: "ukr" }, + { id: 784, name: "United Arab Emirates", alpha2: "ae", alpha3: "are" }, + { + id: 826, + name: "United Kingdom of Great Britain and Northern Ireland", + alpha2: "gb", + alpha3: "gbr", + }, + { id: 840, name: "United States of America", alpha2: "us", alpha3: "usa" }, + { id: 858, name: "Uruguay", alpha2: "uy", alpha3: "ury" }, + { id: 860, name: "Uzbekistan", alpha2: "uz", alpha3: "uzb" }, + { id: 548, name: "Vanuatu", alpha2: "vu", alpha3: "vut" }, + { + id: 862, + name: "Venezuela (Bolivarian Republic of)", + alpha2: "ve", + alpha3: "ven", + }, + { id: 704, name: "Viet Nam", alpha2: "vn", alpha3: "vnm" }, + { id: 887, name: "Yemen", alpha2: "ye", alpha3: "yem" }, + { id: 894, name: "Zambia", alpha2: "zm", alpha3: "zmb" }, + { id: 716, name: "Zimbabwe", alpha2: "zw", alpha3: "zwe" }, + ]; + countriesLoading = false; + selectedCountry: string; + onDestroy$ = new Subject(); + search$ = new EventEmitter(); + countries$: Observable; + // field: FormlyFieldConfig = + // { + // templateOptions: { + // placeholder: 'Search for a state:', + // search$: (term) => { + // if ((!term || term === '')) { + // return of(this.countries); + // } + // return of(this.countries.filter(name => name.name.toLowerCase().indexOf(term.toLowerCase()) > -1).slice(0, 10)); + // }, + // } + // }; - ngOnInit() { + ngOnInit() { // this.countries$ = concat( // of([]), // this.search$.pipe( @@ -255,16 +318,14 @@ countries$: Observable; // switchMap(this.to.search$), // ) // ); - - // this.countries$.subscribe(); - } + } - onChange($event) { - this.formControl.patchValue($event); - } + onChange($event) { + this.formControl.patchValue($event); + } - ngOnDestroy() { - this.onDestroy$.complete(); - } + ngOnDestroy() { + this.onDestroy$.complete(); } +} diff --git a/src/app/_shared/ui-form/types/image-viewer.type.ts b/src/app/_shared/ui-form/types/image-viewer.type.ts index f5918c682..0c064df5e 100644 --- a/src/app/_shared/ui-form/types/image-viewer.type.ts +++ b/src/app/_shared/ui-form/types/image-viewer.type.ts @@ -1,45 +1,35 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { FieldType } from '@ngx-formly/core'; - +import { Component, Input, OnInit } from "@angular/core"; +import { FieldType } from "@ngx-formly/core"; @Component({ - selector: 'app-thumbnail-viewer', + selector: "app-thumbnail-viewer", template: ` - - - - {{to.label}} - - - -
- - - -
- -
-
- - `, + + + {{ to.label }} + + +
+ +
+
+
+ `, }) - export class ImageViewerComponent extends FieldType implements OnInit { - @Input() - private _formControl: any; - public get formControl() { - return this._formControl; - } - public set formControl(value) { - this._formControl = value; - } + @Input() + private _formControl: any; + public get formControl() { + return this._formControl; + } + public set formControl(value) { + this._formControl = value; + } imgId: any; imgUrl: any; - imgProps: {}; + imgProps: {}; ngOnInit() { this.imgUrl = this.formControl.value; } - - } diff --git a/src/app/_shared/ui-form/types/money.component.ts b/src/app/_shared/ui-form/types/money.component.ts index 83a0dafa4..ce18f68f4 100644 --- a/src/app/_shared/ui-form/types/money.component.ts +++ b/src/app/_shared/ui-form/types/money.component.ts @@ -1,30 +1,29 @@ -import {Component} from '@angular/core'; -import {FieldType} from '@ngx-formly/core'; -import createNumberMask from 'text-mask-addons/dist/createNumberMask'; +import { Component } from "@angular/core"; +import { FieldType } from "@ngx-formly/core"; +import createNumberMask from "text-mask-addons/dist/createNumberMask"; @Component({ - selector: 'formly-field-input-money', + selector: "formly-field-input-money", template: ` + + {{ to.label }} + + {{ to.errMessage }} - - {{ to.label }} - - {{to.errMessage}} - - - - - - `, + + + `, }) // tslint:disable-next-line: component-class-suffix export class FormlyFieldInputMoney extends FieldType { public numberMask = createNumberMask({ - prefix: '£ ', - allowDecimal: true + prefix: "£ ", + allowDecimal: true, }); } - diff --git a/src/app/_shared/ui-form/types/null.type.ts b/src/app/_shared/ui-form/types/null.type.ts index 26b3caa0b..e8de039d4 100644 --- a/src/app/_shared/ui-form/types/null.type.ts +++ b/src/app/_shared/ui-form/types/null.type.ts @@ -1,48 +1,51 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { FieldType } from '@ngx-formly/core'; -import { indexOf } from 'lodash-es'; +import { Component, Input, OnInit } from "@angular/core"; +import { FieldType } from "@ngx-formly/core"; +import { indexOf } from "lodash-es"; @Component({ - selector: 'app-null-type', - template: ` -
- - - - - {{cleanUrl(text)}} - -

{{ to.description }}

+ selector: "app-null-type", + template: ` +
+ + + + + {{ cleanUrl(text) }} + +

+ {{ to.description }} +

`, }) export class NullTypeComponent extends FieldType implements OnInit { - @Input() - private _formControl: any; - public get formControl() { - return this._formControl; + @Input() + private _formControl: any; + public get formControl() { + return this._formControl; + } + public set formControl(value) { + this._formControl = value; + } + imgId: any; + text: any; + imgProps: {}; + text2: string; + isUrl: boolean; + + ngOnInit() { + this.text = this.formControl.value; + if (this.formControl.value) { + this.isUrl = this.formControl.value.toString().indexOf("http") > -1; } - public set formControl(value) { - this._formControl = value; - } - imgId: any; - text: any; - imgProps: {}; - text2: string; - isUrl: boolean; - - ngOnInit() { - this.text = this.formControl.value; - if (this.formControl.value) { - this.isUrl = this.formControl.value.toString().indexOf('http') > -1; - } - this.text2 = this.to.description; - - - } - cleanUrl(urlStr: string) { - return urlStr.split('/')[2]; - } + this.text2 = this.to.description; + } + cleanUrl(urlStr: string) { + return urlStr.split("/")[2]; + } } - diff --git a/src/app/_shared/ui-form/types/percentage.component.ts b/src/app/_shared/ui-form/types/percentage.component.ts index f90f32aa2..4baf13e4b 100644 --- a/src/app/_shared/ui-form/types/percentage.component.ts +++ b/src/app/_shared/ui-form/types/percentage.component.ts @@ -1,16 +1,22 @@ -import { Component } from '@angular/core'; -import { FieldType } from '@ngx-formly/core'; +import { Component } from "@angular/core"; +import { FieldType } from "@ngx-formly/core"; @Component({ - selector: 'formly-field-input-percentage', + selector: "formly-field-input-percentage", template: ` - - {{ to.label }} - - - {{ to.description }} - - ` + + {{ to.label }} + + + {{ to.description }} + + `, }) export class KendraFieldInputPercentage extends FieldType { public limitToHundred(rawValue) { @@ -18,10 +24,10 @@ export class KendraFieldInputPercentage extends FieldType { if (value < 100) { if (value < 10) { - return [/\d/, ' %']; - } else return [/\d/, /\d/, ' %']; + return [/\d/, " %"]; + } else return [/\d/, /\d/, " %"]; } else { - return ['100 %']; + return ["100 %"]; } } } diff --git a/src/app/_shared/ui-form/types/playlists.component.ts b/src/app/_shared/ui-form/types/playlists.component.ts index ca4658ebe..f43b282cc 100644 --- a/src/app/_shared/ui-form/types/playlists.component.ts +++ b/src/app/_shared/ui-form/types/playlists.component.ts @@ -1,20 +1,19 @@ -import { Component, OnInit, Input } from '@angular/core'; -import { FieldType } from '@ngx-formly/core'; -import { MatRadioChange } from '@angular/material/radio'; -import { UntypedFormGroup, UntypedFormBuilder } from '@angular/forms'; -import { Observable, Subscription } from 'rxjs'; -import { Animations } from '../../animations'; -import { UserProfile } from '../../services/google/user-profile.service'; -import { YoutubeDataService } from 'src/app/services/youtube-data.service'; +import { Component, OnInit, Input } from "@angular/core"; +import { FieldType } from "@ngx-formly/core"; +import { MatRadioChange } from "@angular/material/radio"; +import { UntypedFormGroup, UntypedFormBuilder } from "@angular/forms"; +import { Observable, Subscription } from "rxjs"; +import { Animations } from "../../animations"; +import { UserProfile } from "../../services/google/user-profile.service"; +import { YoutubeDataService } from "src/app/services/youtube-data.service"; @Component({ - selector: 'app-field-input-visibility', - templateUrl: 'playlists.component.html', - animations: [Animations.kendraAnimations] + selector: "app-field-input-visibility", + templateUrl: "playlists.component.html", + animations: [Animations.kendraAnimations], }) // tslint:disable-next-line: component-class-suffiximplements OnInit export class FieldInputPlaylistComponent extends FieldType implements OnInit { - // @Input() // formControl; @@ -23,17 +22,13 @@ export class FieldInputPlaylistComponent extends FieldType implements OnInit { @Input() context = {}; @Input() videoId = {}; - showNewPlaylist = false; + showNewPlaylist = false; mySelectedPlaylists = []; -Playlists: any = []; - + Playlists: any = []; videoPlaylist: { id: string; - }[] = [ - { 'id': '1' }, - { 'id': '3' } - ]; + }[] = [{ id: "1" }, { id: "3" }]; val: string; showSchedulue: boolean; @@ -47,32 +42,24 @@ Playlists: any = []; constructor( private fb: UntypedFormBuilder, - private userProfile: UserProfile, - private yt: YoutubeDataService - ) { + private userProfile: UserProfile, + private yt: YoutubeDataService, + ) { super(); - - } ngOnInit(): void { - - - - - -this.yt.getMyPlaylists().subscribe((response: any) => { -this.Playlists = response.items; -}); - + this.yt.getMyPlaylists().subscribe((response: any) => { + this.Playlists = response.items; + }); this.newPlaylistForm = this.fb.group({ - visibility: '', - playlistTitle: '' + visibility: "", + playlistTitle: "", }); this.myform = this.fb.group({ - myPlaylistCtrl: '' + myPlaylistCtrl: "", }); this.updateList(); @@ -97,31 +84,23 @@ this.Playlists = response.items; // console.log(value); // }); - } - -addVideoToPlayList (playlistId, videoId) { - this.yt.addVideoToPlaylist(playlistId, videoId).subscribe(()=> { - - }) -} - - + addVideoToPlayList(playlistId, videoId) { + this.yt.addVideoToPlaylist(playlistId, videoId).subscribe(() => {}); + } private updateList() { -// this.mySelectedPlaylists = this.myPlaylists -// .filter(option => { -// return this.videoPlaylist.find(select => { -// return option.id === select.id; -// }); -// }); -// setTimeout(() => { -// this.myform.get('myPlaylistCtrl').setValue(this.mySelectedPlaylists); - -// this.formControl.setValue(this.myform.value); - -// }, 500); + // this.mySelectedPlaylists = this.myPlaylists + // .filter(option => { + // return this.videoPlaylist.find(select => { + // return option.id === select.id; + // }); + // }); + // setTimeout(() => { + // this.myform.get('myPlaylistCtrl').setValue(this.mySelectedPlaylists); + // this.formControl.setValue(this.myform.value); + // }, 500); } // get myPlaylistCtrl() { @@ -129,32 +108,28 @@ addVideoToPlayList (playlistId, videoId) { // } get visibility() { - return this.newPlaylistForm.get('visibility').value; + return this.newPlaylistForm.get("visibility").value; } get playlistTitle() { - return this.newPlaylistForm.get('playlistTitle').value; + return this.newPlaylistForm.get("playlistTitle").value; } onListControlChanged(listId, event) { // this.selectedOptionsx = list.options.map(item => item.value); - this.formControl.patchValue(this.videoPlaylist); + this.formControl.patchValue(this.videoPlaylist); // this.formControl.setValue('this.videoPlaylist'); - // console.log(this.formControl); + // console.log(this.formControl); // console.log(this.videoPlaylist); - console.log(this.myform.value); - // this.addVideoToPlayList(listId, this.formControl.value) // TODO uncomment when ready + console.log(this.myform.value); + // this.addVideoToPlayList(listId, this.formControl.value) // TODO uncomment when ready } createPlayList(event) { const newId = Date.now().toString(); // this.myPlaylists.unshift({ 'id': newId, 'name': this.playlistTitle, 'visibility': this.visibility }); - this.videoPlaylist.unshift({ 'id': newId }); + this.videoPlaylist.unshift({ id: newId }); this.formControl.patchValue(this.videoPlaylist); this.updateList(); - - } - } - diff --git a/src/app/_shared/ui-form/types/textarea.type.ts b/src/app/_shared/ui-form/types/textarea.type.ts index d9050febf..f14336003 100644 --- a/src/app/_shared/ui-form/types/textarea.type.ts +++ b/src/app/_shared/ui-form/types/textarea.type.ts @@ -1,12 +1,12 @@ -import { Component, ViewChild } from '@angular/core'; -import { FieldType } from '@ngx-formly/material'; -import { ErrorStateMatcher } from '@angular/material/core'; -import { MatInput } from '@angular/material/input'; +import { Component, ViewChild } from "@angular/core"; +import { FieldType } from "@ngx-formly/material"; +import { ErrorStateMatcher } from "@angular/material/core"; +import { MatInput } from "@angular/material/input"; /** Error when invalid control is dirty, touched, or submitted. * this is an attempt to allow custom error msgs * -*/ + */ // export class errorStateMatcher implements ErrorStateMatcher { // do not remove maybe use later! // isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean { // const isSubmitted = form && form.submitted; @@ -16,58 +16,66 @@ import { MatInput } from '@angular/material/input'; @Component({ template: ` - - - - - - - {{description}} - - - - - - - {{formControl?.value?.length}}/{{maxLength}} - + + + + + {{ formControl?.value?.length }}/{{ maxLength }} + - ` + `, }) - export class TextareaComponent extends FieldType { -// defaultOptions = { -// hideExpression: () => true, -// // defaultValue: {}, -// // validators: { -// // validation: ['PasswordStrengthValidation'], -// // }, -// }; + // defaultOptions = { + // hideExpression: () => true, + // // defaultValue: {}, + // // validators: { + // // validation: ['PasswordStrengthValidation'], + // // }, + // }; -// @ViewChild(MatInput) formFieldControl: MatInput; - get autosize(): boolean { return this.to.autosize || false; } - get cols(): number { return this.to.cols || 50; } - get rows(): number { return this.to.rows || 8; } - get maxLength(): number { return this.to.maxLength || 15000; } + // @ViewChild(MatInput) formFieldControl: MatInput; + get autosize(): boolean { + return this.to.autosize || false; + } + get cols(): number { + return this.to.cols || 50; + } + get rows(): number { + return this.to.rows || 8; + } + get maxLength(): number { + return this.to.maxLength || 15000; + } // In the absense of a placeholder, may use JSON schema label (title key), see below: - get placeholderOrLabel(): string {return this.to.placeholder || this.to.label; } - get description(): string {return this.to.description; } - get test(): string {return this.formControl.getError('maxLength'); } - + get placeholderOrLabel(): string { + return this.to.placeholder || this.to.label; + } + get description(): string { + return this.to.description; + } + get test(): string { + return this.formControl.getError("maxLength"); + } } // Form blocks have may labels may be defined like this: @@ -90,4 +98,4 @@ export class TextareaComponent extends FieldType { "ui:rows": 10 } } -}` +}`; diff --git a/src/app/_shared/ui-form/types/timepicker.type.ts b/src/app/_shared/ui-form/types/timepicker.type.ts index 480f46882..a6fe19071 100644 --- a/src/app/_shared/ui-form/types/timepicker.type.ts +++ b/src/app/_shared/ui-form/types/timepicker.type.ts @@ -1,26 +1,31 @@ -import { Component, ViewChild } from '@angular/core'; -import { FieldType } from '@ngx-formly/material'; -import { ErrorStateMatcher } from '@angular/material/core'; -import { MatInput } from '@angular/material/input'; - - +import { Component, ViewChild } from "@angular/core"; +import { FieldType } from "@ngx-formly/material"; +import { ErrorStateMatcher } from "@angular/material/core"; +import { MatInput } from "@angular/material/input"; @Component({ template: ` -
- - {{ to.label }}

-
- -
- -
- - ` +
+ {{ to.label }}

+
+ +
+
+ `, }) - export class TimePickerComponent extends FieldType { - get format(): string { return this.to.timeFormat || 12; } - get controlOnly(): number { return this.to.hideClock || false; } - get defaultTime(): string { return this.to.defaultTime || '7:13'; } + get format(): string { + return this.to.timeFormat || 12; + } + get controlOnly(): number { + return this.to.hideClock || false; + } + get defaultTime(): string { + return this.to.defaultTime || "7:13"; + } } diff --git a/src/app/_shared/ui-form/types/typeahead.component.ts b/src/app/_shared/ui-form/types/typeahead.component.ts index 38fbfaf37..77033dc41 100644 --- a/src/app/_shared/ui-form/types/typeahead.component.ts +++ b/src/app/_shared/ui-form/types/typeahead.component.ts @@ -1,41 +1,67 @@ -import { Component, EventEmitter, OnDestroy, OnInit, Input } from '@angular/core'; -import { FieldType } from '@ngx-formly/material'; -import { Subject } from 'rxjs'; -import { takeUntil, startWith, filter, debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators'; - +import { + Component, + EventEmitter, + OnDestroy, + OnInit, + Input, +} from "@angular/core"; +import { FieldType } from "@ngx-formly/material"; +import { Subject } from "rxjs"; +import { + takeUntil, + startWith, + filter, + debounceTime, + distinctUntilChanged, + switchMap, +} from "rxjs/operators"; @Component({ - selector: 'kendra-field-typeahead', + selector: "kendra-field-typeahead", template: ` - - - - - - {{item.name}} ({{item.alpha2}}) - - - `, - styleUrls: ['./typeahead.component.scss'], + + + + {{ item.name }} ({{ item.alpha2 }}) + + + `, + styleUrls: ["./typeahead.component.scss"], }) -export class KendraFieldTypeahead extends FieldType implements OnDestroy, OnInit { - get isMultiSelect(): boolean { return this.to.isMultiSelect || false; } - get labelProp(): string { return this.to.labelProp || 'name'; } - get valueProp(): string { return this.to.valueProp || 'id'; } - get groupProp(): string { return this.to.groupProp || 'group'; } +export class KendraFieldTypeahead + extends FieldType + implements OnDestroy, OnInit +{ + get isMultiSelect(): boolean { + return this.to.isMultiSelect || false; + } + get labelProp(): string { + return this.to.labelProp || "name"; + } + get valueProp(): string { + return this.to.valueProp || "id"; + } + get groupProp(): string { + return this.to.groupProp || "group"; + } @Input() data: []; - onDestroy$ = new Subject(); search$ = new EventEmitter(); options$; - selectedCity: string; + selectedCity: string; ngOnInit() { // this.options$ = this.search$.pipe( @@ -46,7 +72,6 @@ export class KendraFieldTypeahead extends FieldType implements OnDestroy, O // distinctUntilChanged(), // switchMap(this.to.search$), // ); - // this.options$.subscribe(); } diff --git a/src/app/_shared/ui-form/types/video-viewer.component.ts b/src/app/_shared/ui-form/types/video-viewer.component.ts index 1c5ab61d8..f05d3be7c 100644 --- a/src/app/_shared/ui-form/types/video-viewer.component.ts +++ b/src/app/_shared/ui-form/types/video-viewer.component.ts @@ -1,50 +1,56 @@ -import { Component, Input } from '@angular/core'; -import { FieldType } from '@ngx-formly/core'; -import { DomSanitizer, SafeResourceUrl, SafeUrl } from '@angular/platform-browser'; - +import { Component, Input } from "@angular/core"; +import { FieldType } from "@ngx-formly/core"; +import { + DomSanitizer, + SafeResourceUrl, + SafeUrl, +} from "@angular/platform-browser"; @Component({ - selector: 'formly-field-video-viewer', + selector: "formly-field-video-viewer", template: ` + + + {{ to.label }} + + +
- - - {{to.label}} - - -
- -Video URL
-https://youtu.be/{{videoId}}

- - -
-

- - `, + Video URL
+ https://youtu.be/{{ videoId }}

+

+ `, }) - export class FormlyFieldVideoViewer extends FieldType { @Input() private _formControl: any; public get formControl() { - return this._formControl; - } - public set formControl(value) { - this._formControl = value; - } + return this._formControl; + } + public set formControl(value) { + this._formControl = value; + } videoId: any; videoUrl: any; - constructor( - private sanitizer: DomSanitizer - ) { + constructor(private sanitizer: DomSanitizer) { super(); } ngOnInit() { this.videoId = this.formControl.value; - this.videoUrl = this.sanitizer.bypassSecurityTrustResourceUrl('https://www.youtube.com/embed/' + this.formControl.value); + this.videoUrl = this.sanitizer.bypassSecurityTrustResourceUrl( + "https://www.youtube.com/embed/" + this.formControl.value, + ); } // innerHTML: string = "" @@ -56,8 +62,4 @@ export class FormlyFieldVideoViewer extends FieldType { // this.dangerousVideoUrl = 'https://www.youtube.com/embed/' + id; // videoUrl = this.sanitizer.bypassSecurityTrustResourceUrl('https://www.youtube.com/embed/YA9N4nsAxZo'); // } - - } - - diff --git a/src/app/_shared/ui-form/types/video-viewer2.component.ts b/src/app/_shared/ui-form/types/video-viewer2.component.ts index 8fe0c36c3..68802f3cd 100644 --- a/src/app/_shared/ui-form/types/video-viewer2.component.ts +++ b/src/app/_shared/ui-form/types/video-viewer2.component.ts @@ -1,58 +1,59 @@ -import { Component, Input } from '@angular/core'; -import { FieldType } from '@ngx-formly/core'; -import { DomSanitizer, SafeResourceUrl, SafeUrl } from '@angular/platform-browser'; - +import { Component, Input } from "@angular/core"; +import { FieldType } from "@ngx-formly/core"; +import { + DomSanitizer, + SafeResourceUrl, + SafeUrl, +} from "@angular/platform-browser"; @Component({ - selector: 'formly-field-video-viewer2', + selector: "formly-field-video-viewer2", template: ` - - - - {{to.label}} - - - - - - -{{formControl.value}} - - - -
- - `, + + + {{ to.label }} + + + + + {{ formControl.value }} +
+ `, }) - export class FormlyFieldVideoViewer2 extends FieldType { @Input() private _formControl: any; public get formControl() { - return this._formControl; - } - public set formControl(value) { - this._formControl = value; - } + return this._formControl; + } + public set formControl(value) { + this._formControl = value; + } videoId: any; videoUrl: any; - constructor( - private sanitizer: DomSanitizer - ) { + constructor(private sanitizer: DomSanitizer) { super(); } ngOnInit() { this.videoId = this.formControl.value; - this.videoUrl = this.sanitizer.bypassSecurityTrustResourceUrl('https://player.vimeo.com/video/' - + this.formControl.value + '?badge=0&autopause=0&player_id=0&app_id=16166'); + this.videoUrl = this.sanitizer.bypassSecurityTrustResourceUrl( + "https://player.vimeo.com/video/" + + this.formControl.value + + "?badge=0&autopause=0&player_id=0&app_id=16166", + ); } // innerHTML: string = "" @@ -64,8 +65,4 @@ export class FormlyFieldVideoViewer2 extends FieldType { // this.dangerousVideoUrl = 'https://www.youtube.com/embed/' + id; // videoUrl = this.sanitizer.bypassSecurityTrustResourceUrl('https://www.youtube.com/embed/YA9N4nsAxZo'); // } - - } - - diff --git a/src/app/_shared/ui-form/types/video-viewerDM.component.ts b/src/app/_shared/ui-form/types/video-viewerDM.component.ts index 5088bed45..6faca05e8 100644 --- a/src/app/_shared/ui-form/types/video-viewerDM.component.ts +++ b/src/app/_shared/ui-form/types/video-viewerDM.component.ts @@ -1,50 +1,49 @@ -import { Component, Input } from '@angular/core'; -import { FieldType } from '@ngx-formly/core'; -import { DomSanitizer, SafeResourceUrl, SafeUrl } from '@angular/platform-browser'; - +import { Component, Input } from "@angular/core"; +import { FieldType } from "@ngx-formly/core"; +import { + DomSanitizer, + SafeResourceUrl, + SafeUrl, +} from "@angular/platform-browser"; @Component({ - selector: 'formly-field-video-viewer2', + selector: "formly-field-video-viewer2", template: ` - - - - {{to.label}} ({{to.uiSchema.adapter}} Video Player) - - - - - - - - - -
- - `, + + + {{ to.label }} ({{ to.uiSchema.adapter }} Video Player) + + + +
+ `, }) - export class FormlyFieldVideoViewerDM extends FieldType { @Input() private _formControl: any; public get formControl() { - return this._formControl; - } - public set formControl(value) { - this._formControl = value; - } + return this._formControl; + } + public set formControl(value) { + this._formControl = value; + } videoId: any; videoUrl: any; - constructor( - private sanitizer: DomSanitizer - ) { + constructor(private sanitizer: DomSanitizer) { super(); } @@ -52,25 +51,20 @@ export class FormlyFieldVideoViewerDM extends FieldType { this.videoId = this.formControl.value; switch (this.to.uiSchema.adapter) { - case 'dailymotion': - this.videoUrl = this.sanitizer.bypassSecurityTrustResourceUrl('//www.dailymotion.com/embed/video/' - + this.formControl.value + '?'); + case "dailymotion": + this.videoUrl = this.sanitizer.bypassSecurityTrustResourceUrl( + "//www.dailymotion.com/embed/video/" + this.formControl.value + "?", + ); break; default: - this.videoUrl = this.sanitizer.bypassSecurityTrustResourceUrl('https://player.vimeo.com/video/' - + this.formControl.value + '?badge=0&autopause=0&player_id=0&app_id=16166'); + this.videoUrl = this.sanitizer.bypassSecurityTrustResourceUrl( + "https://player.vimeo.com/video/" + + this.formControl.value + + "?badge=0&autopause=0&player_id=0&app_id=16166", + ); break; } - - - } - - - - } - - diff --git a/src/app/_shared/ui-form/types/visibility.component.ts b/src/app/_shared/ui-form/types/visibility.component.ts index 5f5aad81e..cc752bb19 100644 --- a/src/app/_shared/ui-form/types/visibility.component.ts +++ b/src/app/_shared/ui-form/types/visibility.component.ts @@ -1,19 +1,17 @@ -import { Component, OnInit } from '@angular/core'; -import { FieldType } from '@ngx-formly/core'; -import { MatRadioChange } from '@angular/material/radio'; -import { UntypedFormGroup, UntypedFormBuilder } from '@angular/forms'; -import { Observable, Subscription } from 'rxjs'; -import { Animations } from '../../animations'; - - +import { Component, OnInit } from "@angular/core"; +import { FieldType } from "@ngx-formly/core"; +import { MatRadioChange } from "@angular/material/radio"; +import { UntypedFormGroup, UntypedFormBuilder } from "@angular/forms"; +import { Observable, Subscription } from "rxjs"; +import { Animations } from "../../animations"; @Component({ - selector: 'app-field-input-visibility', - templateUrl: 'visibility.component.html', - animations: [Animations.kendraAnimations] + selector: "app-field-input-visibility", + templateUrl: "visibility.component.html", + animations: [Animations.kendraAnimations], }) // tslint:disable-next-line: component-class-suffiximplements OnInit -export class FieldInputVisibilityComponent extends FieldType implements OnInit { +export class FieldInputVisibilityComponent extends FieldType implements OnInit { val: string; showSchedulue: boolean; visabilityForm = new UntypedFormGroup({}); @@ -26,32 +24,28 @@ export class FieldInputVisibilityComponent extends FieldType implements OnInit ngOnInit(): void { this.visabilityForm = this.fb.group({ - date: '', - time: '', - privacyStatus: this.formControl.value + date: "", + time: "", + privacyStatus: this.formControl.value, }); - this.valueChanges$ = this.visabilityForm.valueChanges; + this.valueChanges$ = this.visabilityForm.valueChanges; - this.subscription = this.valueChanges$ - .pipe().subscribe(res => { - // this.formControl.patchValue(this.visabilityForm.value); - }); + this.subscription = this.valueChanges$.pipe().subscribe((res) => { + // this.formControl.patchValue(this.visabilityForm.value); + }); } get date() { - return this.visabilityForm.get('date').value; + return this.visabilityForm.get("date").value; } get time() { - return this.visabilityForm.get('time').value; + return this.visabilityForm.get("time").value; } - radioChange(event: MatRadioChange) { this.val = event.value; this.formControl.patchValue(this.val); } - } - diff --git a/src/app/_shared/ui-form/ui-form.module.ts b/src/app/_shared/ui-form/ui-form.module.ts index 90abb2692..07cc98a5d 100644 --- a/src/app/_shared/ui-form/ui-form.module.ts +++ b/src/app/_shared/ui-form/ui-form.module.ts @@ -1,30 +1,34 @@ -import {NgModule} from '@angular/core'; -import {CommonModule} from '@angular/common'; -import {FormsModule, ReactiveFormsModule} from '@angular/forms'; +import { NgModule } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -import {CheckBoxWrapperComponent, PanelWrapperComponent,} from './wrappers'; +import { CheckBoxWrapperComponent, PanelWrapperComponent } from "./wrappers"; -import * as types from './types/'; +import * as types from "./types/"; -import {ErrorStateMatcher, MatNativeDateModule, ShowOnDirtyErrorStateMatcher} from '@angular/material/core'; -import {NgSelectModule} from '@ng-select/ng-select'; -import {FormlyMatDatepickerModule} from '@ngx-formly/material/datepicker'; +import { + ErrorStateMatcher, + MatNativeDateModule, + ShowOnDirtyErrorStateMatcher, +} from "@angular/material/core"; +import { NgSelectModule } from "@ng-select/ng-select"; +import { FormlyMatDatepickerModule } from "@ngx-formly/material/datepicker"; -import {MatButtonToggleModule} from '@angular/material/button-toggle'; -import {MatIconModule} from '@angular/material/icon'; -import {FormlyMaterialModule} from '@ngx-formly/material'; -import {NgxMaterialTimepickerModule} from 'ngx-material-timepicker'; -import {FlexLayoutModule} from '@angular/flex-layout'; -import {FormlyFieldFileComponent} from './types/file-type.component'; -import {FormlyModule} from '@ngx-formly/core'; -import {MatCardModule} from '@angular/material/card'; -import {MatInputModule} from '@angular/material/input'; -import {MaskitoModule} from '@maskito/angular'; -import {MatRadioModule} from '@angular/material/radio'; +import { MatButtonToggleModule } from "@angular/material/button-toggle"; +import { MatIconModule } from "@angular/material/icon"; +import { FormlyMaterialModule } from "@ngx-formly/material"; +import { NgxMaterialTimepickerModule } from "ngx-material-timepicker"; +import { FlexLayoutModule } from "@angular/flex-layout"; +import { FormlyFieldFileComponent } from "./types/file-type.component"; +import { FormlyModule } from "@ngx-formly/core"; +import { MatCardModule } from "@angular/material/card"; +import { MatInputModule } from "@angular/material/input"; +import { MaskitoModule } from "@maskito/angular"; +import { MatRadioModule } from "@angular/material/radio"; @NgModule({ providers: [ - {provide: ErrorStateMatcher, useClass: ShowOnDirtyErrorStateMatcher} + { provide: ErrorStateMatcher, useClass: ShowOnDirtyErrorStateMatcher }, ], imports: [ CommonModule, @@ -41,7 +45,7 @@ import {MatRadioModule} from '@angular/material/radio'; MatCardModule, MatInputModule, MaskitoModule, - MatRadioModule + MatRadioModule, ], exports: [ FormsModule, @@ -51,7 +55,7 @@ import {MatRadioModule} from '@angular/material/radio'; NgSelectModule, MatNativeDateModule, FormlyMatDatepickerModule, - NgxMaterialTimepickerModule + NgxMaterialTimepickerModule, ], declarations: [ PanelWrapperComponent, @@ -78,7 +82,7 @@ import {MatRadioModule} from '@angular/material/radio'; types.ImageViewerComponent, types.NullTypeComponent, FormlyFieldFileComponent, - types.MultiSchemaTypeComponent - ] + types.MultiSchemaTypeComponent, + ], }) export class UiFormModule {} diff --git a/src/app/app-material/app-material.module.ts b/src/app/app-material/app-material.module.ts index 8844e6bcb..28edd342d 100644 --- a/src/app/app-material/app-material.module.ts +++ b/src/app/app-material/app-material.module.ts @@ -1,33 +1,33 @@ -import {NgModule} from '@angular/core'; -import {CommonModule} from '@angular/common'; -import {MatBadgeModule} from '@angular/material/badge'; -import {MatButtonModule} from '@angular/material/button'; -import {MatCardModule} from '@angular/material/card'; -import {MatCheckboxModule} from '@angular/material/checkbox'; -import {MatChipsModule} from '@angular/material/chips'; -import {MatDatepickerModule} from '@angular/material/datepicker'; -import {MatDialogModule} from '@angular/material/dialog'; -import {MatExpansionModule} from '@angular/material/expansion'; -import {MatFormFieldModule} from '@angular/material/form-field'; -import {MatGridListModule} from '@angular/material/grid-list'; -import {MatIconModule} from '@angular/material/icon'; -import {MatInputModule} from '@angular/material/input'; -import {MatListModule} from '@angular/material/list'; -import {MatMenuModule} from '@angular/material/menu'; -import {MatProgressBarModule} from '@angular/material/progress-bar'; -import {MatProgressSpinnerModule} from '@angular/material/progress-spinner'; -import {MatSelectModule} from '@angular/material/select'; -import {MatSidenavModule} from '@angular/material/sidenav'; -import {MatSlideToggleModule} from '@angular/material/slide-toggle'; -import {MatSnackBarModule} from '@angular/material/snack-bar'; -import {MatStepperModule} from '@angular/material/stepper'; -import {MatTableModule} from '@angular/material/table'; -import {MatToolbarModule} from '@angular/material/toolbar'; -import {MatTreeModule} from '@angular/material/tree'; -import {ScrollingModule} from '@angular/cdk/scrolling'; -import {MatTooltipModule} from '@angular/material/tooltip'; -import {MatTabsModule} from '@angular/material/tabs'; -import {MatRadioModule} from '@angular/material/radio'; +import { NgModule } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { MatBadgeModule } from "@angular/material/badge"; +import { MatButtonModule } from "@angular/material/button"; +import { MatCardModule } from "@angular/material/card"; +import { MatCheckboxModule } from "@angular/material/checkbox"; +import { MatChipsModule } from "@angular/material/chips"; +import { MatDatepickerModule } from "@angular/material/datepicker"; +import { MatDialogModule } from "@angular/material/dialog"; +import { MatExpansionModule } from "@angular/material/expansion"; +import { MatFormFieldModule } from "@angular/material/form-field"; +import { MatGridListModule } from "@angular/material/grid-list"; +import { MatIconModule } from "@angular/material/icon"; +import { MatInputModule } from "@angular/material/input"; +import { MatListModule } from "@angular/material/list"; +import { MatMenuModule } from "@angular/material/menu"; +import { MatProgressBarModule } from "@angular/material/progress-bar"; +import { MatProgressSpinnerModule } from "@angular/material/progress-spinner"; +import { MatSelectModule } from "@angular/material/select"; +import { MatSidenavModule } from "@angular/material/sidenav"; +import { MatSlideToggleModule } from "@angular/material/slide-toggle"; +import { MatSnackBarModule } from "@angular/material/snack-bar"; +import { MatStepperModule } from "@angular/material/stepper"; +import { MatTableModule } from "@angular/material/table"; +import { MatToolbarModule } from "@angular/material/toolbar"; +import { MatTreeModule } from "@angular/material/tree"; +import { ScrollingModule } from "@angular/cdk/scrolling"; +import { MatTooltipModule } from "@angular/material/tooltip"; +import { MatTabsModule } from "@angular/material/tabs"; +import { MatRadioModule } from "@angular/material/radio"; const MATERIAL = [ MatButtonModule, @@ -57,15 +57,12 @@ const MATERIAL = [ MatBadgeModule, MatTooltipModule, MatTabsModule, - MatRadioModule + MatRadioModule, ]; @NgModule({ declarations: [], - imports: [ - CommonModule, - ...MATERIAL - ], - exports: [ ...MATERIAL ] + imports: [CommonModule, ...MATERIAL], + exports: [...MATERIAL], }) -export class AppMaterialModule { } +export class AppMaterialModule {} diff --git a/src/app/app.module.ts b/src/app/app.module.ts index cb53172f3..626e222a4 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,190 +1,195 @@ -import {BrowserModule} from '@angular/platform-browser'; -import {APP_INITIALIZER, ErrorHandler, NgModule} from '@angular/core'; -import { MonacoEditorModule, NgxMonacoEditorConfig } from 'ngx-monaco-editor-v2'; -import {AppRoutingModule} from './app-routing.module'; -import {AppComponent} from './app.component'; -import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; -import {ServiceWorkerModule} from '@angular/service-worker'; -import {environment} from '@env/environment'; -import {LayoutComponent} from './components/layout/layout.component'; -import {FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {UploadPageComponent} from './pages/upload-page/upload-page.component'; -import {AdaptersPageComponent} from './pages/adapters-page/adapters-page.component'; -import {SettingsPageComponent} from './pages/settings-page/settings-page.component'; -import {UserPageComponent} from './pages/user-page/user-page.component'; -import {ConfirmAppResetDialogComponent} from './dialogs/confirm-app-reset-dialog/confirm-app-reset-dialog.component'; -import {HttpClientModule, HttpClient, HTTP_INTERCEPTORS} from '@angular/common/http'; -import {ObjectKeysPipe} from './pipes/object-keys.pipe'; -import {ImportProgressDialogComponent} from './dialogs/import-progress-dialog/import-progress-dialog.component'; -import {AddNewNodeDialogComponent} from './dialogs/add-new-node-dialog/add-new-node-dialog.component'; -import {ConfirmDeleteDialogComponent} from './dialogs/confirm-delete-dialog/confirm-delete-dialog.component'; -import {ReplaceImageUrlDialogComponent} from './dialogs/replace-image-url-dialog/replace-image-url-dialog.component'; -import {AuthCallbackComponent} from './pages/auth-callback/auth-callback.component'; -import {WaveformComponent} from './components/waveform/waveform.component'; -import {DocsListPageComponent} from './pages/docs-list-page/docs-list-page.component'; -import {AddDocDialogComponent} from './dialogs/add-doc-dialog/add-doc-dialog.component'; -import {ImageInputControlComponent} from './form-controls/image-input-control/image-input-control.component'; -import {TextInputFormControlComponent} from './form-controls/text-input-form-control/text-input-form-control.component'; -import {AppMaterialModule} from './app-material/app-material.module'; -import {NgxTaggerModule} from './ngx-tagger/ngx-tagger.module'; -import {SchemaRepositoryService} from './services/schema-repository.service'; -import {DocumentRepositoryService} from './services/document-repository.service'; -import {DropboxPageComponent} from './pages/dropbox-page/dropbox-page.component'; -import {LegacyDataFormControlComponent} from './form-controls/legacy-data-form-control/legacy-data-form-control.component'; -import {AudioInputControlComponent} from './form-controls/audio-input-control/audio-input-control.component'; -import {TrackClipDirective} from './directives/track-clip.directive'; -import {EditClipDialogComponent} from './dialogs/edit-clip-dialog/edit-clip-dialog.component'; -import {DoughnutChartDirective} from './directives/doughnut-chart.directive'; -import {TestApiPageComponent} from './pages/test-api-page/test-api-page.component'; -import {TestImportDialogComponent} from './dialogs/test-import-dialog/test-import-dialog.component'; +import { BrowserModule } from "@angular/platform-browser"; +import { APP_INITIALIZER, ErrorHandler, NgModule } from "@angular/core"; +import { + MonacoEditorModule, + NgxMonacoEditorConfig, +} from "ngx-monaco-editor-v2"; +import { AppRoutingModule } from "./app-routing.module"; +import { AppComponent } from "./app.component"; +import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; +import { ServiceWorkerModule } from "@angular/service-worker"; +import { environment } from "@env/environment"; +import { LayoutComponent } from "./components/layout/layout.component"; +import { FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { UploadPageComponent } from "./pages/upload-page/upload-page.component"; +import { AdaptersPageComponent } from "./pages/adapters-page/adapters-page.component"; +import { SettingsPageComponent } from "./pages/settings-page/settings-page.component"; +import { UserPageComponent } from "./pages/user-page/user-page.component"; +import { ConfirmAppResetDialogComponent } from "./dialogs/confirm-app-reset-dialog/confirm-app-reset-dialog.component"; +import { + HttpClientModule, + HttpClient, + HTTP_INTERCEPTORS, +} from "@angular/common/http"; +import { ObjectKeysPipe } from "./pipes/object-keys.pipe"; +import { ImportProgressDialogComponent } from "./dialogs/import-progress-dialog/import-progress-dialog.component"; +import { AddNewNodeDialogComponent } from "./dialogs/add-new-node-dialog/add-new-node-dialog.component"; +import { ConfirmDeleteDialogComponent } from "./dialogs/confirm-delete-dialog/confirm-delete-dialog.component"; +import { ReplaceImageUrlDialogComponent } from "./dialogs/replace-image-url-dialog/replace-image-url-dialog.component"; +import { AuthCallbackComponent } from "./pages/auth-callback/auth-callback.component"; +import { WaveformComponent } from "./components/waveform/waveform.component"; +import { DocsListPageComponent } from "./pages/docs-list-page/docs-list-page.component"; +import { AddDocDialogComponent } from "./dialogs/add-doc-dialog/add-doc-dialog.component"; +import { ImageInputControlComponent } from "./form-controls/image-input-control/image-input-control.component"; +import { TextInputFormControlComponent } from "./form-controls/text-input-form-control/text-input-form-control.component"; +import { AppMaterialModule } from "./app-material/app-material.module"; +import { NgxTaggerModule } from "./ngx-tagger/ngx-tagger.module"; +import { SchemaRepositoryService } from "./services/schema-repository.service"; +import { DocumentRepositoryService } from "./services/document-repository.service"; +import { DropboxPageComponent } from "./pages/dropbox-page/dropbox-page.component"; +import { LegacyDataFormControlComponent } from "./form-controls/legacy-data-form-control/legacy-data-form-control.component"; +import { AudioInputControlComponent } from "./form-controls/audio-input-control/audio-input-control.component"; +import { TrackClipDirective } from "./directives/track-clip.directive"; +import { EditClipDialogComponent } from "./dialogs/edit-clip-dialog/edit-clip-dialog.component"; +import { DoughnutChartDirective } from "./directives/doughnut-chart.directive"; +import { TestApiPageComponent } from "./pages/test-api-page/test-api-page.component"; +import { TestImportDialogComponent } from "./dialogs/test-import-dialog/test-import-dialog.component"; -import {ReferenceInputControlComponent} from './form-controls/reference-input-control/reference-input-control.component'; +import { ReferenceInputControlComponent } from "./form-controls/reference-input-control/reference-input-control.component"; -import {BloomenTestPageComponent} from './pages/bloomen-test-page/bloomen-test-page.component'; -import {RemoteImageControlComponent} from './form-controls/remote-image-control/remote-image-control.component'; -import {MenuItemComponent} from './_shared/components/menu/menu-item.component'; -import {Menu2ItemComponent} from './_shared/components/menu/menu-2-item.component'; -import {MessagesModule} from './messages/messages.module'; -import {AppSettingsService} from './services/app-settings.service'; -import {DebugOnlyDirective} from './directives/debug-only.directive'; +import { BloomenTestPageComponent } from "./pages/bloomen-test-page/bloomen-test-page.component"; +import { RemoteImageControlComponent } from "./form-controls/remote-image-control/remote-image-control.component"; +import { MenuItemComponent } from "./_shared/components/menu/menu-item.component"; +import { Menu2ItemComponent } from "./_shared/components/menu/menu-2-item.component"; +import { MessagesModule } from "./messages/messages.module"; +import { AppSettingsService } from "./services/app-settings.service"; +import { DebugOnlyDirective } from "./directives/debug-only.directive"; -import {YoutubePageComponent} from './pages/youtube-page/youtube-page.component'; -import {TranslateModule, TranslateLoader} from '@ngx-translate/core'; -import {TranslateHttpLoader} from '@ngx-translate/http-loader'; -import {YoutubeUploadComponent} from './components/youtube-upload/youtube-upload.component'; -import {BloomenSearchPageComponent} from './pages/bloomen-search-page/bloomen-search-page.component'; -import {HttpErrorInterceptor} from './_shared/404.interceptor'; -import {UserIpnFormComponent} from './forms/user-ipn-form/user-ipn-form.component'; -import {GenericFormComponent} from './forms/generic-form/generic-form.component'; -import {FormTestPageComponent} from './pages/form-test-page/form-test-page.component'; -import {OrderKeysPipe} from './pipes/order-keys.pipe'; -import {ShowShareLinkDialogComponent} from './dialogs/show-share-link-dialog/show-share-link-dialog.component'; -import {FormlyImageInputComponent} from './form-controls/formly-image-input/formly-image-input.component'; -import {FormlyAudioInputComponent} from './form-controls/formly-audio-input/formly-audio-input.component'; -import {FormBuilderPageComponent} from './pages/form-builder-page/form-builder-page.component'; -import {FormSelectDialogComponent} from './dialogs/form-select-dialog/form-select-dialog.component'; -import {FormDataSelectDialogComponent} from './dialogs/form-data-select-dialog/form-data-select-dialog.component'; -import {FormlyRemoteImageInputComponent} from './form-controls/formly-remote-image-input/formly-remote-image-input.component'; -import {SwaggerFormSelectDialogComponent} from './dialogs/swagger-form-select-dialog/swagger-form-select-dialog.component'; -import {ApiDataSelectDialogComponent} from './dialogs/api-data-select-dialog/api-data-select-dialog.component'; -import {QueryBuilderPageComponent} from './pages/query-builder-page/query-builder-page.component'; -import {AgGridModule} from 'ag-grid-angular'; -import {AdapterQuerySelectDialogComponent} from './dialogs/adapter-query-select-dialog/adapter-query-select-dialog.component'; -import {DataChartOutputComponent} from './components/data-chart-output/data-chart-output.component'; -import {TeostoUserFormComponent} from './forms/teosto-user-form/teosto-user-form.component'; -import {BlocksBuilderPageComponent} from './pages/blocks-builder-page/blocks-builder-page.component'; -import {FormBlockComponent} from './blocks/form-block/form-block.component'; -import {DebugBlockComponent} from './blocks/debug-block/debug-block.component'; -import {QueryBlockComponent} from './blocks/query-block/query-block.component'; -import {MappingBlockComponent} from './blocks/mapping-block/mapping-block.component'; -import {GridBlockComponent} from './blocks/grid-block/grid-block.component'; -import {DragDropModule} from '@angular/cdk/drag-drop'; -import {EditorLayoutComponent} from './components/editor-layout/editor-layout.component'; -import {BlockBuilderBoxComponent} from './components/block-builder-box/block-builder-box.component'; -import {HttpBlockComponent} from './blocks/http-block/http-block.component'; -import { - AdapterBlocksConfigSelectDialogComponent -} from './dialogs/adapter-blocks-config-select-dialog/adapter-blocks-config-select-dialog.component'; -import {ExportConfigDialogComponent} from './dialogs/export-config-dialog/export-config-dialog.component'; -import {ChartBlockComponent} from './blocks/chart-block/chart-block.component'; -import {InitBlockComponent} from './blocks/init-block/init-block.component'; -import {MessageBlockComponent} from './blocks/message-block/message-block.component'; -import {TemplateBlockComponent} from './blocks/template-block/template-block.component'; -import {ButtonBlockComponent} from './blocks/button-block/button-block.component'; -import {BlocksDialogComponent} from './dialogs/blocks-dialog/blocks-dialog.component'; -import {PasteConfigDialogComponent} from './dialogs/paste-config-dialog/paste-config-dialog.component'; -import {BlocksWorkflowComponent} from './components/blocks-workflow/blocks-workflow.component'; -import {FormlyBlocksInputComponent} from './form-controls/formly-blocks-input/formly-blocks-input.component'; -import {BlocksInputControlComponent} from './form-controls/blocks-input-control/blocks-input-control.component'; -import {DialogBlockComponent} from './blocks/dialog-block/dialog-block.component'; -import {ActionsBlockComponent} from './blocks/actions-block/actions-block.component'; -import {NotFoundComponent} from './components/not-found/not-found.component'; -import {SwitchBlockComponent} from './blocks/switch-block/switch-block.component'; -import {BatchBlockComponent} from './blocks/batch-block/batch-block.component'; -import {VariableGetComponent} from './blocks/variable-get/variable-get.component'; -import {VariableSetComponent} from './blocks/variable-set/variable-set.component'; -import {EventDispatchBlockComponent} from './blocks/event-dispatch-block/event-dispatch-block.component'; -import {MultiBlockComponent} from './blocks/multi-block/multi-block.component'; -import {AddBlockDialogComponent} from './dialogs/add-block-dialog/add-block-dialog.component'; -import {KendraioIconComponent} from './components/kendraio-icon/kendraio-icon.component'; -import {BlocksEditorComponent} from './components/blocks-editor/blocks-editor.component'; -import {BlockEditorMappingComponent} from './components/block-editor-mapping/block-editor-mapping.component'; -import {FormlyWorkflowFieldComponent} from './form-controls/formly-workflow-field/formly-workflow-field.component'; -import {FormlyCardListComponent} from './form-controls/formly-card-list/formly-card-list.component'; -import {CsvImportBlockComponent} from './blocks/csv-import-block/csv-import-block.component'; -import {WorkflowCellRendererComponent} from './components/workflow-cell-renderer/workflow-cell-renderer.component'; -import {CsvExportBlockComponent} from './blocks/csv-export-block/csv-export-block.component'; -import {CardBlockComponent} from './blocks/card-block/card-block.component'; -import {FakerBlockComponent} from './blocks/faker-block/faker-block.component'; -import {WorkflowSidenavComponent} from './components/workflow-sidenav/workflow-sidenav.component'; -import {LoadWorkflowDialogComponent} from './dialogs/load-workflow-dialog/load-workflow-dialog.component'; -import {SaveWorkflowDialogComponent} from './dialogs/save-workflow-dialog/save-workflow-dialog.component'; -import {EditWorkflowMetadataDialogComponent} from './dialogs/edit-workflow-metadata-dialog/edit-workflow-metadata-dialog.component'; -import {DataImportBlockComponent} from './blocks/data-import-block/data-import-block.component'; -import {DataExportBlockComponent} from './blocks/data-export-block/data-export-block.component'; -import {BaseBlockComponent} from './blocks/base-block/base-block.component'; -import {FileInputBlockComponent} from './blocks/file-input-block/file-input-block.component'; -import {ParseDataBlockComponent} from './blocks/parse-data-block/parse-data-block.component'; -import {FileExportBlockComponent} from './blocks/file-export-block/file-export-block.component'; -import {SerializeDataBlockComponent} from './blocks/serialize-data-block/serialize-data-block.component'; -import {LaunchBlockComponent} from './blocks/launch-block/launch-block.component'; -import {DbBlockComponent} from './blocks/db-block/db-block.component'; -import {ReferenceBlockComponent} from './blocks/reference-block/reference-block.component'; -import {GlobalErrorHandlerService} from './services/global-error-handler.service'; -import {FormlyTableWidgetComponent} from './form-controls/formly-table-widget/formly-table-widget.component'; -import {FormlyFormDialogComponent} from './dialogs/formly-form-dialog/formly-form-dialog.component'; -import {MappingPipe} from './pipes/mapping.pipe'; -import {ContextBlockComponent} from './blocks/context-block/context-block.component'; -import {Auth0ProfileDataBlockComponent} from './blocks/auth0-profile-data-block/auth0-profile-data-block.component'; -import {AdapterListBlockComponent} from './blocks/adapter-list-block/adapter-list-block.component'; -import {AdapterInfoBlockComponent} from './blocks/adapter-info-block/adapter-info-block.component'; -import {MainMenuComponent} from './components/main-menu/main-menu.component'; -import {FileValueAccessor} from './_shared/ui-form/types/file-type-value-accessor'; -import {FormlyFileInputComponent} from './form-controls/formly-file-input/formly-file-input.component'; -import {ReadFileBlockComponent} from './blocks/read-file-block/read-file-block.component'; -import {ImageBlockComponent} from './blocks/image-block/image-block.component'; -import {ContextSaveBlockComponent} from './blocks/context-save-block/context-save-block.component'; -import {VimeoBlockComponent} from './blocks/vimeo-block/vimeo-block.component'; -import {VideoUploadBlockComponent} from './blocks/video-upload-block/video-upload-block.component'; -import {JsonViewPageComponent} from './pages/json-view-page/json-view-page.component'; -import {GosubBlockComponent} from './blocks/gosub-block/gosub-block.component'; -import {GsheetBlockComponent} from './blocks/gsheet-block/gsheet-block.component'; -import {MapBlockComponent} from './blocks/map-block/map-block.component'; -import {LeafletModule} from '@asymmetrik/ngx-leaflet'; -import {LeafletMarkerClusterModule} from '@asymmetrik/ngx-leaflet-markercluster'; -import {DashboardPageComponent} from './pages/dashboard-page/dashboard-page.component'; -import {config} from './_shared/ui-form/config'; -import {FormlyMaterialModule} from '@ngx-formly/material'; -import { GraphqlBlockComponent } from './blocks/graphql-block/graphql-block.component'; -import { ValidatorBlockComponent } from './blocks/validator-block/validator-block.component'; -import { ConnectComponent } from './pages/connect/connect.component'; -import { LoadAuthBlockComponent } from './blocks/load-auth-block/load-auth-block.component'; -import { ConnectionStatusRendererComponent } from './components/connection-status-renderer/connection-status-renderer.component'; -import { KqlBuilderComponent } from './pages/kql-builder/kql-builder.component'; -import { BlockGraphqlBuilderBoxComponent } from './components/block-graphql-builder-box/block-graphql-builder-box.component'; -import { XlsxTemplateBlockComponent } from './blocks/xlsx-template-block/xlsx-template-block.component'; -import { BlockMappingBuilderBoxComponent } from './components/block-mapping-builder-box/block-mapping-builder-box.component'; -import { ValidateBlockComponent } from './blocks/validate-block/validate-block.component'; -import { BookmarkButtonComponent } from './components/bookmark-button/bookmark-button.component'; -import { AudioPlayerBlockComponent } from './blocks/audio-player-block/audio-player-block.component'; -import { PlayerBlockComponent } from './blocks/player-block/player-block.component'; -import { BlockMultiBuilderBoxComponent } from './components/block-multi-builder-box/block-multi-builder-box.component'; -import { DurationPipe } from './pipes/duration.pipe'; -import { WebMoneyComponent } from './blocks/web-money/web-money.component'; -import { WalletComponent } from './blocks/wallet/wallet.component'; +import { YoutubePageComponent } from "./pages/youtube-page/youtube-page.component"; +import { TranslateModule, TranslateLoader } from "@ngx-translate/core"; +import { TranslateHttpLoader } from "@ngx-translate/http-loader"; +import { YoutubeUploadComponent } from "./components/youtube-upload/youtube-upload.component"; +import { BloomenSearchPageComponent } from "./pages/bloomen-search-page/bloomen-search-page.component"; +import { HttpErrorInterceptor } from "./_shared/404.interceptor"; +import { UserIpnFormComponent } from "./forms/user-ipn-form/user-ipn-form.component"; +import { GenericFormComponent } from "./forms/generic-form/generic-form.component"; +import { FormTestPageComponent } from "./pages/form-test-page/form-test-page.component"; +import { OrderKeysPipe } from "./pipes/order-keys.pipe"; +import { ShowShareLinkDialogComponent } from "./dialogs/show-share-link-dialog/show-share-link-dialog.component"; +import { FormlyImageInputComponent } from "./form-controls/formly-image-input/formly-image-input.component"; +import { FormlyAudioInputComponent } from "./form-controls/formly-audio-input/formly-audio-input.component"; +import { FormBuilderPageComponent } from "./pages/form-builder-page/form-builder-page.component"; +import { FormSelectDialogComponent } from "./dialogs/form-select-dialog/form-select-dialog.component"; +import { FormDataSelectDialogComponent } from "./dialogs/form-data-select-dialog/form-data-select-dialog.component"; +import { FormlyRemoteImageInputComponent } from "./form-controls/formly-remote-image-input/formly-remote-image-input.component"; +import { SwaggerFormSelectDialogComponent } from "./dialogs/swagger-form-select-dialog/swagger-form-select-dialog.component"; +import { ApiDataSelectDialogComponent } from "./dialogs/api-data-select-dialog/api-data-select-dialog.component"; +import { QueryBuilderPageComponent } from "./pages/query-builder-page/query-builder-page.component"; +import { AgGridModule } from "ag-grid-angular"; +import { AdapterQuerySelectDialogComponent } from "./dialogs/adapter-query-select-dialog/adapter-query-select-dialog.component"; +import { DataChartOutputComponent } from "./components/data-chart-output/data-chart-output.component"; +import { TeostoUserFormComponent } from "./forms/teosto-user-form/teosto-user-form.component"; +import { BlocksBuilderPageComponent } from "./pages/blocks-builder-page/blocks-builder-page.component"; +import { FormBlockComponent } from "./blocks/form-block/form-block.component"; +import { DebugBlockComponent } from "./blocks/debug-block/debug-block.component"; +import { QueryBlockComponent } from "./blocks/query-block/query-block.component"; +import { MappingBlockComponent } from "./blocks/mapping-block/mapping-block.component"; +import { GridBlockComponent } from "./blocks/grid-block/grid-block.component"; +import { DragDropModule } from "@angular/cdk/drag-drop"; +import { EditorLayoutComponent } from "./components/editor-layout/editor-layout.component"; +import { BlockBuilderBoxComponent } from "./components/block-builder-box/block-builder-box.component"; +import { HttpBlockComponent } from "./blocks/http-block/http-block.component"; +import { AdapterBlocksConfigSelectDialogComponent } from "./dialogs/adapter-blocks-config-select-dialog/adapter-blocks-config-select-dialog.component"; +import { ExportConfigDialogComponent } from "./dialogs/export-config-dialog/export-config-dialog.component"; +import { ChartBlockComponent } from "./blocks/chart-block/chart-block.component"; +import { InitBlockComponent } from "./blocks/init-block/init-block.component"; +import { MessageBlockComponent } from "./blocks/message-block/message-block.component"; +import { TemplateBlockComponent } from "./blocks/template-block/template-block.component"; +import { ButtonBlockComponent } from "./blocks/button-block/button-block.component"; +import { BlocksDialogComponent } from "./dialogs/blocks-dialog/blocks-dialog.component"; +import { PasteConfigDialogComponent } from "./dialogs/paste-config-dialog/paste-config-dialog.component"; +import { BlocksWorkflowComponent } from "./components/blocks-workflow/blocks-workflow.component"; +import { FormlyBlocksInputComponent } from "./form-controls/formly-blocks-input/formly-blocks-input.component"; +import { BlocksInputControlComponent } from "./form-controls/blocks-input-control/blocks-input-control.component"; +import { DialogBlockComponent } from "./blocks/dialog-block/dialog-block.component"; +import { ActionsBlockComponent } from "./blocks/actions-block/actions-block.component"; +import { NotFoundComponent } from "./components/not-found/not-found.component"; +import { SwitchBlockComponent } from "./blocks/switch-block/switch-block.component"; +import { BatchBlockComponent } from "./blocks/batch-block/batch-block.component"; +import { VariableGetComponent } from "./blocks/variable-get/variable-get.component"; +import { VariableSetComponent } from "./blocks/variable-set/variable-set.component"; +import { EventDispatchBlockComponent } from "./blocks/event-dispatch-block/event-dispatch-block.component"; +import { MultiBlockComponent } from "./blocks/multi-block/multi-block.component"; +import { AddBlockDialogComponent } from "./dialogs/add-block-dialog/add-block-dialog.component"; +import { KendraioIconComponent } from "./components/kendraio-icon/kendraio-icon.component"; +import { BlocksEditorComponent } from "./components/blocks-editor/blocks-editor.component"; +import { BlockEditorMappingComponent } from "./components/block-editor-mapping/block-editor-mapping.component"; +import { FormlyWorkflowFieldComponent } from "./form-controls/formly-workflow-field/formly-workflow-field.component"; +import { FormlyCardListComponent } from "./form-controls/formly-card-list/formly-card-list.component"; +import { CsvImportBlockComponent } from "./blocks/csv-import-block/csv-import-block.component"; +import { WorkflowCellRendererComponent } from "./components/workflow-cell-renderer/workflow-cell-renderer.component"; +import { CsvExportBlockComponent } from "./blocks/csv-export-block/csv-export-block.component"; +import { CardBlockComponent } from "./blocks/card-block/card-block.component"; +import { FakerBlockComponent } from "./blocks/faker-block/faker-block.component"; +import { WorkflowSidenavComponent } from "./components/workflow-sidenav/workflow-sidenav.component"; +import { LoadWorkflowDialogComponent } from "./dialogs/load-workflow-dialog/load-workflow-dialog.component"; +import { SaveWorkflowDialogComponent } from "./dialogs/save-workflow-dialog/save-workflow-dialog.component"; +import { EditWorkflowMetadataDialogComponent } from "./dialogs/edit-workflow-metadata-dialog/edit-workflow-metadata-dialog.component"; +import { DataImportBlockComponent } from "./blocks/data-import-block/data-import-block.component"; +import { DataExportBlockComponent } from "./blocks/data-export-block/data-export-block.component"; +import { BaseBlockComponent } from "./blocks/base-block/base-block.component"; +import { FileInputBlockComponent } from "./blocks/file-input-block/file-input-block.component"; +import { ParseDataBlockComponent } from "./blocks/parse-data-block/parse-data-block.component"; +import { FileExportBlockComponent } from "./blocks/file-export-block/file-export-block.component"; +import { SerializeDataBlockComponent } from "./blocks/serialize-data-block/serialize-data-block.component"; +import { LaunchBlockComponent } from "./blocks/launch-block/launch-block.component"; +import { DbBlockComponent } from "./blocks/db-block/db-block.component"; +import { ReferenceBlockComponent } from "./blocks/reference-block/reference-block.component"; +import { GlobalErrorHandlerService } from "./services/global-error-handler.service"; +import { FormlyTableWidgetComponent } from "./form-controls/formly-table-widget/formly-table-widget.component"; +import { FormlyFormDialogComponent } from "./dialogs/formly-form-dialog/formly-form-dialog.component"; +import { MappingPipe } from "./pipes/mapping.pipe"; +import { ContextBlockComponent } from "./blocks/context-block/context-block.component"; +import { Auth0ProfileDataBlockComponent } from "./blocks/auth0-profile-data-block/auth0-profile-data-block.component"; +import { AdapterListBlockComponent } from "./blocks/adapter-list-block/adapter-list-block.component"; +import { AdapterInfoBlockComponent } from "./blocks/adapter-info-block/adapter-info-block.component"; +import { MainMenuComponent } from "./components/main-menu/main-menu.component"; +import { FileValueAccessor } from "./_shared/ui-form/types/file-type-value-accessor"; +import { FormlyFileInputComponent } from "./form-controls/formly-file-input/formly-file-input.component"; +import { ReadFileBlockComponent } from "./blocks/read-file-block/read-file-block.component"; +import { ImageBlockComponent } from "./blocks/image-block/image-block.component"; +import { ContextSaveBlockComponent } from "./blocks/context-save-block/context-save-block.component"; +import { VimeoBlockComponent } from "./blocks/vimeo-block/vimeo-block.component"; +import { VideoUploadBlockComponent } from "./blocks/video-upload-block/video-upload-block.component"; +import { JsonViewPageComponent } from "./pages/json-view-page/json-view-page.component"; +import { GosubBlockComponent } from "./blocks/gosub-block/gosub-block.component"; +import { GsheetBlockComponent } from "./blocks/gsheet-block/gsheet-block.component"; +import { MapBlockComponent } from "./blocks/map-block/map-block.component"; +import { LeafletModule } from "@asymmetrik/ngx-leaflet"; +import { LeafletMarkerClusterModule } from "@asymmetrik/ngx-leaflet-markercluster"; +import { DashboardPageComponent } from "./pages/dashboard-page/dashboard-page.component"; +import { config } from "./_shared/ui-form/config"; +import { FormlyMaterialModule } from "@ngx-formly/material"; +import { GraphqlBlockComponent } from "./blocks/graphql-block/graphql-block.component"; +import { ValidatorBlockComponent } from "./blocks/validator-block/validator-block.component"; +import { ConnectComponent } from "./pages/connect/connect.component"; +import { LoadAuthBlockComponent } from "./blocks/load-auth-block/load-auth-block.component"; +import { ConnectionStatusRendererComponent } from "./components/connection-status-renderer/connection-status-renderer.component"; +import { KqlBuilderComponent } from "./pages/kql-builder/kql-builder.component"; +import { BlockGraphqlBuilderBoxComponent } from "./components/block-graphql-builder-box/block-graphql-builder-box.component"; +import { XlsxTemplateBlockComponent } from "./blocks/xlsx-template-block/xlsx-template-block.component"; +import { BlockMappingBuilderBoxComponent } from "./components/block-mapping-builder-box/block-mapping-builder-box.component"; +import { ValidateBlockComponent } from "./blocks/validate-block/validate-block.component"; +import { BookmarkButtonComponent } from "./components/bookmark-button/bookmark-button.component"; +import { AudioPlayerBlockComponent } from "./blocks/audio-player-block/audio-player-block.component"; +import { PlayerBlockComponent } from "./blocks/player-block/player-block.component"; +import { BlockMultiBuilderBoxComponent } from "./components/block-multi-builder-box/block-multi-builder-box.component"; +import { DurationPipe } from "./pipes/duration.pipe"; +import { WebMoneyComponent } from "./blocks/web-money/web-money.component"; +import { WalletComponent } from "./blocks/wallet/wallet.component"; -import { FormlyPaginatedWidgetComponent } from './form-controls/formly-paginated-widget/formly-paginated-widget.component'; -import { LoadSchemaBlockComponent } from './blocks/load-schema-block/load-schema-block.component'; -import { AppLayoutBlockComponent } from './blocks/app-layout-block/app-layout-block.component'; -import { ReadonlyInputComponent } from './form-controls/readonly-input/readonly-input.component'; -import { RenameFieldsBlockComponent } from './blocks/rename-fields-block/rename-fields-block.component'; -import { BlockGosubBuilderBoxComponent } from './components/block-gosub-builder-box/block-gosub-builder-box.component'; -import { MermaidBlockComponent } from './blocks/mermaid-block/mermaid-block.component'; -import { ComparisonComponent } from './blocks/comparison/comparison.component'; -import { BlockComparisonBuilderBoxComponent } from './components/block-comparison-builder-box/block-comparison-builder-box.component'; -import {FormlyModule} from '@ngx-formly/core'; -import {MatAutocompleteModule} from '@angular/material/autocomplete'; -import {MatChipsModule} from '@angular/material/chips'; +import { FormlyPaginatedWidgetComponent } from "./form-controls/formly-paginated-widget/formly-paginated-widget.component"; +import { LoadSchemaBlockComponent } from "./blocks/load-schema-block/load-schema-block.component"; +import { AppLayoutBlockComponent } from "./blocks/app-layout-block/app-layout-block.component"; +import { ReadonlyInputComponent } from "./form-controls/readonly-input/readonly-input.component"; +import { RenameFieldsBlockComponent } from "./blocks/rename-fields-block/rename-fields-block.component"; +import { BlockGosubBuilderBoxComponent } from "./components/block-gosub-builder-box/block-gosub-builder-box.component"; +import { MermaidBlockComponent } from "./blocks/mermaid-block/mermaid-block.component"; +import { ComparisonComponent } from "./blocks/comparison/comparison.component"; +import { BlockComparisonBuilderBoxComponent } from "./components/block-comparison-builder-box/block-comparison-builder-box.component"; +import { FormlyModule } from "@ngx-formly/core"; +import { MatAutocompleteModule } from "@angular/material/autocomplete"; +import { MatChipsModule } from "@angular/material/chips"; // AoT requires an exported function for factories export function HttpLoaderFactory(http: HttpClient) { @@ -192,180 +197,182 @@ export function HttpLoaderFactory(http: HttpClient) { } const monacoConfig: NgxMonacoEditorConfig = { - baseUrl: 'assets', + baseUrl: "assets", requireConfig: { preferScriptTags: true }, - monacoRequire: (window as any).monacoRequire + monacoRequire: (window as any).monacoRequire, }; @NgModule({ - declarations: [ - AppComponent, - LayoutComponent, - DocsListPageComponent, - AddDocDialogComponent, - ImageInputControlComponent, - TextInputFormControlComponent, - DashboardPageComponent, - UploadPageComponent, - AdaptersPageComponent, - SettingsPageComponent, - UserPageComponent, - ConfirmAppResetDialogComponent, - ObjectKeysPipe, - ImportProgressDialogComponent, - AddNewNodeDialogComponent, - ConfirmDeleteDialogComponent, - ReplaceImageUrlDialogComponent, - AuthCallbackComponent, - WaveformComponent, - DropboxPageComponent, - LegacyDataFormControlComponent, - AudioInputControlComponent, - TrackClipDirective, - EditClipDialogComponent, - DoughnutChartDirective, - TestApiPageComponent, - TestImportDialogComponent, - BloomenTestPageComponent, - RemoteImageControlComponent, - ReferenceInputControlComponent, - MainMenuComponent, - MenuItemComponent, - Menu2ItemComponent, - DebugOnlyDirective, - YoutubePageComponent, - YoutubeUploadComponent, - BloomenSearchPageComponent, - UserIpnFormComponent, - GenericFormComponent, - FormTestPageComponent, - OrderKeysPipe, - ShowShareLinkDialogComponent, - FormlyImageInputComponent, - FormlyAudioInputComponent, - FormBuilderPageComponent, - FormSelectDialogComponent, - FormDataSelectDialogComponent, - FormlyRemoteImageInputComponent, - SwaggerFormSelectDialogComponent, - ApiDataSelectDialogComponent, - QueryBuilderPageComponent, - AdapterQuerySelectDialogComponent, - DataChartOutputComponent, - TeostoUserFormComponent, - BlocksBuilderPageComponent, - FormBlockComponent, - DebugBlockComponent, - QueryBlockComponent, - MappingBlockComponent, - GridBlockComponent, - EditorLayoutComponent, - BlockBuilderBoxComponent, - HttpBlockComponent, - AdapterBlocksConfigSelectDialogComponent, - ExportConfigDialogComponent, - ChartBlockComponent, - InitBlockComponent, - MessageBlockComponent, - TemplateBlockComponent, - ButtonBlockComponent, - BlocksDialogComponent, - PasteConfigDialogComponent, - BlocksWorkflowComponent, - FormlyBlocksInputComponent, - BlocksInputControlComponent, - DialogBlockComponent, - ActionsBlockComponent, - NotFoundComponent, - SwitchBlockComponent, - BatchBlockComponent, - VariableGetComponent, - VariableSetComponent, - EventDispatchBlockComponent, - MultiBlockComponent, - AddBlockDialogComponent, - KendraioIconComponent, - BlocksEditorComponent, - BlockEditorMappingComponent, - FormlyWorkflowFieldComponent, - FormlyCardListComponent, - CsvImportBlockComponent, - WorkflowCellRendererComponent, - CsvExportBlockComponent, - CardBlockComponent, - ImageBlockComponent, - FakerBlockComponent, - WorkflowSidenavComponent, - LoadWorkflowDialogComponent, - SaveWorkflowDialogComponent, - EditWorkflowMetadataDialogComponent, - DataImportBlockComponent, - DataExportBlockComponent, - BaseBlockComponent, - FileInputBlockComponent, - ParseDataBlockComponent, - FileExportBlockComponent, - SerializeDataBlockComponent, - LaunchBlockComponent, - DbBlockComponent, - ReferenceBlockComponent, - FormlyTableWidgetComponent, - FormlyFormDialogComponent, - MappingPipe, - ContextBlockComponent, - Auth0ProfileDataBlockComponent, - AdapterListBlockComponent, - AdapterInfoBlockComponent, - FileValueAccessor, - FormlyFileInputComponent, - ReadFileBlockComponent, - ContextSaveBlockComponent, - VimeoBlockComponent, - VideoUploadBlockComponent, - JsonViewPageComponent, - GosubBlockComponent, - GsheetBlockComponent, - MapBlockComponent, - GraphqlBlockComponent, - ValidatorBlockComponent, - ConnectComponent, - LoadAuthBlockComponent, - ConnectionStatusRendererComponent, - KqlBuilderComponent, - BlockGraphqlBuilderBoxComponent, - XlsxTemplateBlockComponent, - BlockMappingBuilderBoxComponent, - ValidateBlockComponent, - BookmarkButtonComponent, - AudioPlayerBlockComponent, - PlayerBlockComponent, - BlockMultiBuilderBoxComponent, - DurationPipe, - WebMoneyComponent, - WalletComponent, - FormlyPaginatedWidgetComponent, - LoadSchemaBlockComponent, - AppLayoutBlockComponent, - ReadonlyInputComponent, - RenameFieldsBlockComponent, - BlockGosubBuilderBoxComponent, - MermaidBlockComponent, - ComparisonComponent, - BlockComparisonBuilderBoxComponent, - ], + declarations: [ + AppComponent, + LayoutComponent, + DocsListPageComponent, + AddDocDialogComponent, + ImageInputControlComponent, + TextInputFormControlComponent, + DashboardPageComponent, + UploadPageComponent, + AdaptersPageComponent, + SettingsPageComponent, + UserPageComponent, + ConfirmAppResetDialogComponent, + ObjectKeysPipe, + ImportProgressDialogComponent, + AddNewNodeDialogComponent, + ConfirmDeleteDialogComponent, + ReplaceImageUrlDialogComponent, + AuthCallbackComponent, + WaveformComponent, + DropboxPageComponent, + LegacyDataFormControlComponent, + AudioInputControlComponent, + TrackClipDirective, + EditClipDialogComponent, + DoughnutChartDirective, + TestApiPageComponent, + TestImportDialogComponent, + BloomenTestPageComponent, + RemoteImageControlComponent, + ReferenceInputControlComponent, + MainMenuComponent, + MenuItemComponent, + Menu2ItemComponent, + DebugOnlyDirective, + YoutubePageComponent, + YoutubeUploadComponent, + BloomenSearchPageComponent, + UserIpnFormComponent, + GenericFormComponent, + FormTestPageComponent, + OrderKeysPipe, + ShowShareLinkDialogComponent, + FormlyImageInputComponent, + FormlyAudioInputComponent, + FormBuilderPageComponent, + FormSelectDialogComponent, + FormDataSelectDialogComponent, + FormlyRemoteImageInputComponent, + SwaggerFormSelectDialogComponent, + ApiDataSelectDialogComponent, + QueryBuilderPageComponent, + AdapterQuerySelectDialogComponent, + DataChartOutputComponent, + TeostoUserFormComponent, + BlocksBuilderPageComponent, + FormBlockComponent, + DebugBlockComponent, + QueryBlockComponent, + MappingBlockComponent, + GridBlockComponent, + EditorLayoutComponent, + BlockBuilderBoxComponent, + HttpBlockComponent, + AdapterBlocksConfigSelectDialogComponent, + ExportConfigDialogComponent, + ChartBlockComponent, + InitBlockComponent, + MessageBlockComponent, + TemplateBlockComponent, + ButtonBlockComponent, + BlocksDialogComponent, + PasteConfigDialogComponent, + BlocksWorkflowComponent, + FormlyBlocksInputComponent, + BlocksInputControlComponent, + DialogBlockComponent, + ActionsBlockComponent, + NotFoundComponent, + SwitchBlockComponent, + BatchBlockComponent, + VariableGetComponent, + VariableSetComponent, + EventDispatchBlockComponent, + MultiBlockComponent, + AddBlockDialogComponent, + KendraioIconComponent, + BlocksEditorComponent, + BlockEditorMappingComponent, + FormlyWorkflowFieldComponent, + FormlyCardListComponent, + CsvImportBlockComponent, + WorkflowCellRendererComponent, + CsvExportBlockComponent, + CardBlockComponent, + ImageBlockComponent, + FakerBlockComponent, + WorkflowSidenavComponent, + LoadWorkflowDialogComponent, + SaveWorkflowDialogComponent, + EditWorkflowMetadataDialogComponent, + DataImportBlockComponent, + DataExportBlockComponent, + BaseBlockComponent, + FileInputBlockComponent, + ParseDataBlockComponent, + FileExportBlockComponent, + SerializeDataBlockComponent, + LaunchBlockComponent, + DbBlockComponent, + ReferenceBlockComponent, + FormlyTableWidgetComponent, + FormlyFormDialogComponent, + MappingPipe, + ContextBlockComponent, + Auth0ProfileDataBlockComponent, + AdapterListBlockComponent, + AdapterInfoBlockComponent, + FileValueAccessor, + FormlyFileInputComponent, + ReadFileBlockComponent, + ContextSaveBlockComponent, + VimeoBlockComponent, + VideoUploadBlockComponent, + JsonViewPageComponent, + GosubBlockComponent, + GsheetBlockComponent, + MapBlockComponent, + GraphqlBlockComponent, + ValidatorBlockComponent, + ConnectComponent, + LoadAuthBlockComponent, + ConnectionStatusRendererComponent, + KqlBuilderComponent, + BlockGraphqlBuilderBoxComponent, + XlsxTemplateBlockComponent, + BlockMappingBuilderBoxComponent, + ValidateBlockComponent, + BookmarkButtonComponent, + AudioPlayerBlockComponent, + PlayerBlockComponent, + BlockMultiBuilderBoxComponent, + DurationPipe, + WebMoneyComponent, + WalletComponent, + FormlyPaginatedWidgetComponent, + LoadSchemaBlockComponent, + AppLayoutBlockComponent, + ReadonlyInputComponent, + RenameFieldsBlockComponent, + BlockGosubBuilderBoxComponent, + MermaidBlockComponent, + ComparisonComponent, + BlockComparisonBuilderBoxComponent, + ], imports: [ FormlyModule.forRoot({}), BrowserModule, AppRoutingModule, BrowserAnimationsModule, AppMaterialModule, - ServiceWorkerModule.register('ngsw-worker.js', {enabled: environment.production}), + ServiceWorkerModule.register("ngsw-worker.js", { + enabled: environment.production, + }), TranslateModule.forRoot({ loader: { provide: TranslateLoader, useFactory: HttpLoaderFactory, - deps: [HttpClient] - } + deps: [HttpClient], + }, }), HttpClientModule, ReactiveFormsModule, @@ -380,41 +387,41 @@ const monacoConfig: NgxMonacoEditorConfig = { MonacoEditorModule.forRoot(monacoConfig), MatAutocompleteModule, AgGridModule, - MatChipsModule + MatChipsModule, + ], + providers: [ + // This service is from old legacy code and no longer used, + // so I'm commenting out the init() function and the whole thing + // can be removed once confirmed nothing is still using it. + // { + // provide: APP_INITIALIZER, + // multi: true, + // useFactory: (schemaRepo: SchemaRepositoryService) => () => schemaRepo.init(), + // deps: [SchemaRepositoryService] + // }, + { + provide: APP_INITIALIZER, + multi: true, + useFactory: (docsRepo: DocumentRepositoryService) => () => + docsRepo.init(), + deps: [DocumentRepositoryService], + }, + { + provide: APP_INITIALIZER, + multi: true, + useFactory: (settings: AppSettingsService) => () => settings.init(), + deps: [AppSettingsService], + }, + { + provide: HTTP_INTERCEPTORS, + useClass: HttpErrorInterceptor, + multi: true, + }, + { + provide: ErrorHandler, + useClass: GlobalErrorHandlerService, + }, ], - providers: [ - // This service is from old legacy code and no longer used, - // so I'm commenting out the init() function and the whole thing - // can be removed once confirmed nothing is still using it. - // { - // provide: APP_INITIALIZER, - // multi: true, - // useFactory: (schemaRepo: SchemaRepositoryService) => () => schemaRepo.init(), - // deps: [SchemaRepositoryService] - // }, - { - provide: APP_INITIALIZER, - multi: true, - useFactory: (docsRepo: DocumentRepositoryService) => () => docsRepo.init(), - deps: [DocumentRepositoryService] - }, - { - provide: APP_INITIALIZER, - multi: true, - useFactory: (settings: AppSettingsService) => () => settings.init(), - deps: [AppSettingsService] - }, - { - provide: HTTP_INTERCEPTORS, - useClass: HttpErrorInterceptor, - multi: true - }, - { - provide: ErrorHandler, - useClass: GlobalErrorHandlerService - } - ], - bootstrap: [AppComponent] + bootstrap: [AppComponent], }) -export class AppModule { -} +export class AppModule {} diff --git a/src/app/auth/dirty.guard.ts b/src/app/auth/dirty.guard.ts index 333347ffe..26da9cfb0 100644 --- a/src/app/auth/dirty.guard.ts +++ b/src/app/auth/dirty.guard.ts @@ -1,28 +1,27 @@ -import { Injectable } from '@angular/core'; +import { Injectable } from "@angular/core"; -import { Observable } from 'rxjs'; +import { Observable } from "rxjs"; /** @fileoverview - * When a kendra flow has been changed, we want to warn the user that they may lose their changes if they + * When a kendra flow has been changed, we want to warn the user that they may lose their changes if they * navigate away from the page. - * + * * A CanDeactivate guard is assigned in the app-workflow to run on navigation. * To implement the guard on a component, implement the CanDeactivate interface. */ - /** * Implement this interface in a component if you want to ask for confirmation before navigating away */ export interface CanComponentDeactivate { - canDeactivate: () => Observable | Promise | boolean; + canDeactivate: () => Observable | Promise | boolean; } @Injectable({ - providedIn: 'root', + providedIn: "root", }) -export class CanDeactivateGuard { +export class CanDeactivateGuard { canDeactivate(component: CanComponentDeactivate) { return component.canDeactivate ? component.canDeactivate() : true; } -} \ No newline at end of file +} diff --git a/src/app/blocks/button-block/button-block.component.ts b/src/app/blocks/button-block/button-block.component.ts index dd77ccce0..20d2b969f 100644 --- a/src/app/blocks/button-block/button-block.component.ts +++ b/src/app/blocks/button-block/button-block.component.ts @@ -1,15 +1,21 @@ -import {Component, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core'; -import {clone, get, isArray, isObject} from 'lodash-es'; -import {MatDialog } from '@angular/material/dialog'; -import {BlocksDialogComponent} from '../../dialogs/blocks-dialog/blocks-dialog.component'; +import { + Component, + EventEmitter, + Input, + OnChanges, + OnInit, + Output, +} from "@angular/core"; +import { clone, get, isArray, isObject } from "lodash-es"; +import { MatDialog } from "@angular/material/dialog"; +import { BlocksDialogComponent } from "../../dialogs/blocks-dialog/blocks-dialog.component"; @Component({ - selector: 'app-button-block', - templateUrl: './button-block.component.html', - styleUrls: ['./button-block.component.scss'] + selector: "app-button-block", + templateUrl: "./button-block.component.html", + styleUrls: ["./button-block.component.scss"], }) export class ButtonBlockComponent implements OnInit, OnChanges { - // TODO: deprecate in favour of actions block @Input() config; @@ -18,29 +24,27 @@ export class ButtonBlockComponent implements OnInit, OnChanges { @Output() output = new EventEmitter(); - label = ''; + label = ""; - constructor( - private readonly dialog: MatDialog - ) { } + constructor(private readonly dialog: MatDialog) {} ngOnInit() { // this.updateOutputDisplay(); } ngOnChanges(changes) { - this.label = get(this.config, 'label', 'Submit'); + this.label = get(this.config, "label", "Submit"); } onSubmit() { const dialogRef = this.dialog.open(BlocksDialogComponent, { // TODO: Add other dialog options to config data: { - blocks: get(this.config, 'blocks', []), - model: this.model - } + blocks: get(this.config, "blocks", []), + model: this.model, + }, }); - dialogRef.afterClosed().subscribe(value => { + dialogRef.afterClosed().subscribe((value) => { this.output.emit(clone(value)); }); } diff --git a/src/app/blocks/dialog-block/dialog-block.component.ts b/src/app/blocks/dialog-block/dialog-block.component.ts index b810353dd..0a87735e4 100644 --- a/src/app/blocks/dialog-block/dialog-block.component.ts +++ b/src/app/blocks/dialog-block/dialog-block.component.ts @@ -1,45 +1,50 @@ -import {Component, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core'; -import {get, isArray, isObject} from 'lodash-es'; -import { MatDialog } from '@angular/material/dialog'; -import {BlocksDialogComponent} from '../../dialogs/blocks-dialog/blocks-dialog.component'; -import { RepositionScrollStrategy } from '@angular/cdk/overlay'; +import { + Component, + EventEmitter, + Input, + OnChanges, + OnInit, + Output, +} from "@angular/core"; +import { get, isArray, isObject } from "lodash-es"; +import { MatDialog } from "@angular/material/dialog"; +import { BlocksDialogComponent } from "../../dialogs/blocks-dialog/blocks-dialog.component"; +import { RepositionScrollStrategy } from "@angular/cdk/overlay"; @Component({ - selector: 'app-dialog-block', - templateUrl: './dialog-block.component.html', - styleUrls: ['./dialog-block.component.scss'] + selector: "app-dialog-block", + templateUrl: "./dialog-block.component.html", + styleUrls: ["./dialog-block.component.scss"], }) export class DialogBlockComponent implements OnInit, OnChanges { - @Input() config; @Input() context; @Input() model: any = {}; @Output() output = new EventEmitter(); - constructor( - private readonly dialog: MatDialog - ) { } + constructor(private readonly dialog: MatDialog) {} - ngOnInit() { - } + ngOnInit() {} ngOnChanges(changes) { - if (get(changes, 'model.firstChange', false)) { + if (get(changes, "model.firstChange", false)) { return; } const dialogRef = this.dialog.open(BlocksDialogComponent, { - maxHeight: '90vh', + maxHeight: "90vh", // TODO: Add other dialog options to config data: { - blocks: get(this.config, 'blocks', []), + blocks: get(this.config, "blocks", []), model: this.model, - context: this.context - } + context: this.context, + }, }); - dialogRef.afterClosed().subscribe(value => { + dialogRef.afterClosed().subscribe((value) => { // TODO: replace this shallow copy code with _.clone() or similar - this.output.emit(isArray(value) ? [ ...value ] : isObject(value) ? { ...value } : value); + this.output.emit( + isArray(value) ? [...value] : isObject(value) ? { ...value } : value, + ); }); } } diff --git a/src/app/blocks/http-block/http-block.component.spec.ts b/src/app/blocks/http-block/http-block.component.spec.ts index 49e85d68b..201a9f69e 100644 --- a/src/app/blocks/http-block/http-block.component.spec.ts +++ b/src/app/blocks/http-block/http-block.component.spec.ts @@ -1,37 +1,45 @@ -import { HttpBlockComponent } from './http-block.component'; -import { ContextDataService } from '../../services/context-data.service'; -import { MatSnackBar } from '@angular/material/snack-bar'; -import { HttpClient } from '@angular/common/http'; +import { HttpBlockComponent } from "./http-block.component"; +import { ContextDataService } from "../../services/context-data.service"; +import { MatSnackBar } from "@angular/material/snack-bar"; +import { HttpClient } from "@angular/common/http"; -describe('extractNextPageUrl', () => { - let component: HttpBlockComponent; - let contextDataServiceMock: ContextDataService; - let httpClientMock: HttpClient; - let matSnackBarMock: MatSnackBar; +describe("extractNextPageUrl", () => { + let component: HttpBlockComponent; + let contextDataServiceMock: ContextDataService; + let httpClientMock: HttpClient; + let matSnackBarMock: MatSnackBar; - beforeEach(() => { - contextDataServiceMock = jasmine.createSpyObj('ContextDataService', ['getGlobalContext']); - httpClientMock = jasmine.createSpyObj('HttpClient', ['get']); - matSnackBarMock = jasmine.createSpyObj('MatSnackBar', ['open']); - component = new HttpBlockComponent(contextDataServiceMock, matSnackBarMock, httpClientMock); - }); + beforeEach(() => { + contextDataServiceMock = jasmine.createSpyObj("ContextDataService", [ + "getGlobalContext", + ]); + httpClientMock = jasmine.createSpyObj("HttpClient", ["get"]); + matSnackBarMock = jasmine.createSpyObj("MatSnackBar", ["open"]); + component = new HttpBlockComponent( + contextDataServiceMock, + matSnackBarMock, + httpClientMock, + ); + }); - it('should extract the next page URL from a link header', () => { - const linkHeader = '; rel="next"'; - expect(component.extractNextPageUrl(linkHeader)).toEqual('https://example.com/page2'); - }); + it("should extract the next page URL from a link header", () => { + const linkHeader = '; rel="next"'; + expect(component.extractNextPageUrl(linkHeader)).toEqual( + "https://example.com/page2", + ); + }); - it('should return null if no next link is present', () => { - const linkHeader = '; rel="last"'; - expect(component.extractNextPageUrl(linkHeader)).toBeNull(); - }); + it("should return null if no next link is present", () => { + const linkHeader = '; rel="last"'; + expect(component.extractNextPageUrl(linkHeader)).toBeNull(); + }); - it('should return null for an invalid link header', () => { - const linkHeader = 'invalid link header'; - expect(component.extractNextPageUrl(linkHeader)).toBeNull(); - }); + it("should return null for an invalid link header", () => { + const linkHeader = "invalid link header"; + expect(component.extractNextPageUrl(linkHeader)).toBeNull(); + }); - it('should return null for an empty string', () => { - expect(component.extractNextPageUrl('')).toBeNull(); - }); + it("should return null for an empty string", () => { + expect(component.extractNextPageUrl("")).toBeNull(); + }); }); diff --git a/src/app/blocks/http-block/http-block.component.ts b/src/app/blocks/http-block/http-block.component.ts index ec7eb5313..b484cd331 100644 --- a/src/app/blocks/http-block/http-block.component.ts +++ b/src/app/blocks/http-block/http-block.component.ts @@ -1,27 +1,38 @@ -import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core'; -import { get, has, includes, isString, toUpper } from 'lodash-es'; -import { ContextDataService } from '../../services/context-data.service'; -import { HttpClient, HttpHeaders, HttpParams, HttpResponse } from '@angular/common/http'; -import { MatSnackBar } from '@angular/material/snack-bar'; -import { catchError, expand, reduce, takeWhile } from 'rxjs/operators'; -import { of, EMPTY } from 'rxjs'; -import { mappingUtility } from '../mapping-block/mapping-util'; +import { + Component, + EventEmitter, + Input, + OnChanges, + OnInit, + Output, +} from "@angular/core"; +import { get, has, includes, isString, toUpper } from "lodash-es"; +import { ContextDataService } from "../../services/context-data.service"; +import { + HttpClient, + HttpHeaders, + HttpParams, + HttpResponse, +} from "@angular/common/http"; +import { MatSnackBar } from "@angular/material/snack-bar"; +import { catchError, expand, reduce, takeWhile } from "rxjs/operators"; +import { of, EMPTY } from "rxjs"; +import { mappingUtility } from "../mapping-block/mapping-util"; @Component({ - selector: 'app-http-block', - templateUrl: './http-block.component.html', - styleUrls: ['./http-block.component.scss'] + selector: "app-http-block", + templateUrl: "./http-block.component.html", + styleUrls: ["./http-block.component.scss"], }) export class HttpBlockComponent implements OnInit, OnChanges { - @Input() config; @Input() context; @Input() model: any = {}; @Output() output = new EventEmitter(); - responseType: 'json' = 'json'; + responseType: "json" = "json"; hasError = false; - errorMessage = ''; + errorMessage = ""; errorData = {}; errorBlocks = []; @@ -29,39 +40,41 @@ export class HttpBlockComponent implements OnInit, OnChanges { isLoading = false; contextErrorKey = null; - contextErrors = ''; - prevContextKey = ''; + contextErrors = ""; + prevContextKey = ""; constructor( private readonly contextData: ContextDataService, private readonly notify: MatSnackBar, - private readonly http: HttpClient - ) { - } + private readonly http: HttpClient, + ) {} - ngOnInit() { - } + ngOnInit() {} ngOnChanges(changes) { const keyChanges = Object.keys(changes); - this.contextErrorKey = get(this.config, 'contextErrorKey', null); + this.contextErrorKey = get(this.config, "contextErrorKey", null); if (this.context.__key !== this.prevContextKey) { // context has changed this.prevContextKey = this.context.__key; // update errors from context if used if (this.contextErrorKey) { - this.contextErrors = mappingUtility(this.context, this.contextErrorKey) || ''; + this.contextErrors = + mappingUtility(this.context, this.contextErrorKey) || ""; } - if (keyChanges.length === 1 && keyChanges.includes('context')) { + if (keyChanges.length === 1 && keyChanges.includes("context")) { // exit if only the context was changed return; } } - if (get(this.config, 'skipInit', true) && get(changes, 'model.firstChange', false)) { + if ( + get(this.config, "skipInit", true) && + get(changes, "model.firstChange", false) + ) { return; } - this.responseType = get(this.config, 'responseType', 'json'); - this.errorBlocks = get(this.config, 'onError.blocks', []); + this.responseType = get(this.config, "responseType", "json"); + this.errorBlocks = get(this.config, "onError.blocks", []); this.makeRequest(); } @@ -73,17 +86,22 @@ export class HttpBlockComponent implements OnInit, OnChanges { makeRequest() { this.hasError = false; this.isLoading = true; - const method = get(this.config, 'method'); + const method = get(this.config, "method"); if (!method) { - this.errorMessage = 'No HTTP method provided'; + this.errorMessage = "No HTTP method provided"; this.errorData = {}; this.errorBlocks = []; this.hasError = true; this.isLoading = false; return; } - if (!includes(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'BPUT'], toUpper(method))) { - this.errorMessage = 'HTTP method not supported'; + if ( + !includes( + ["GET", "POST", "PUT", "DELETE", "PATCH", "BPUT"], + toUpper(method), + ) + ) { + this.errorMessage = "HTTP method not supported"; this.errorData = {}; this.errorBlocks = []; this.hasError = true; @@ -93,171 +111,228 @@ export class HttpBlockComponent implements OnInit, OnChanges { let url = this.constructEndpointUrl(this.config); let headers = new HttpHeaders(this.getPayloadHeaders()); - const useProxy = get(this.config, 'useProxy', false); + const useProxy = get(this.config, "useProxy", false); if (useProxy) { - headers = headers.append('Target-URL', url); - const appSettings = JSON.parse(localStorage.getItem('core.variables.settings') || '{}'); - const defaultProxy = get(appSettings, 'defaultCorsProxy', 'https://proxy.kendra.io/'); - url = get(this.config, 'proxyUrl', defaultProxy); + headers = headers.append("Target-URL", url); + const appSettings = JSON.parse( + localStorage.getItem("core.variables.settings") || "{}", + ); + const defaultProxy = get( + appSettings, + "defaultCorsProxy", + "https://proxy.kendra.io/", + ); + url = get(this.config, "proxyUrl", defaultProxy); if (!url) { this.hasError = true; - this.errorMessage = 'Invalid proxy URL'; + this.errorMessage = "Invalid proxy URL"; return; } } - if (has(this.config, 'authentication.type')) { - const valueGetters = get(this.config, 'authentication.valueGetters', {}); - const context = { ...this.config.authentication, ...this.contextData.getGlobalContext(valueGetters, this.context, this.model) }; - switch (get(this.config, 'authentication.type')) { - case 'basic-auth': - if (has(context, 'username') && has(context, 'password')) { + if (has(this.config, "authentication.type")) { + const valueGetters = get(this.config, "authentication.valueGetters", {}); + const context = { + ...this.config.authentication, + ...this.contextData.getGlobalContext( + valueGetters, + this.context, + this.model, + ), + }; + switch (get(this.config, "authentication.type")) { + case "basic-auth": + if (has(context, "username") && has(context, "password")) { const { username, password } = context; - headers = headers.append('Authorization', 'Basic ' + btoa(`${username}:${password}`)); + headers = headers.append( + "Authorization", + "Basic " + btoa(`${username}:${password}`), + ); } break; - case 'bearer': - if (has(context, 'jwt')) { + case "bearer": + if (has(context, "jwt")) { const { jwt } = context; - headers = headers.append('Authorization', `Bearer ${jwt}`); + headers = headers.append("Authorization", `Bearer ${jwt}`); } break; default: - console.log('Unknown authentication type'); + console.log("Unknown authentication type"); } } // TODO: decide what to do with response when error condition switch (toUpper(method)) { - case 'GET': + case "GET": // force the service worker bypass. // When calls are passed to the service worker, they can be invisibly cached // by forcing a bypass, we have more control to force a call to take place - headers = headers.append('ngsw-bypass', 'true'); - if (get(this.config, 'followPaginationLinksMerged', false)) { + headers = headers.append("ngsw-bypass", "true"); + if (get(this.config, "followPaginationLinksMerged", false)) { this.getAllPages(url, headers, this.responseType); } else { - this.http.get(url, { headers, responseType: this.responseType }) + this.http + .get(url, { headers, responseType: this.responseType }) .pipe( - catchError(error => { + catchError((error) => { this.hasError = true; this.errorMessage = error.message; this.errorData = error; // TODO: need to prevent errors for triggering subsequent blocks - return of({error, hasError: this.hasError, errorMessage: this.errorMessage}); - }) + return of({ + error, + hasError: this.hasError, + errorMessage: this.errorMessage, + }); + }), ) .subscribe((response: Record) => { this.isLoading = false; this.hasError = false; - if(!response.hasError) this.errorBlocks = []; + if (!response.hasError) this.errorBlocks = []; this.outputResult(response); }); } break; - case 'DELETE': - this.http.delete(url, { headers, responseType: this.responseType }) + case "DELETE": + this.http + .delete(url, { headers, responseType: this.responseType }) .pipe( - catchError(error => { + catchError((error) => { this.hasError = true; this.errorMessage = error.message; this.errorData = error; // TODO: need to prevent errors for triggering subsequent blocks - return of({error, hasError: this.hasError, errorMessage: this.errorMessage}); - }) + return of({ + error, + hasError: this.hasError, + errorMessage: this.errorMessage, + }); + }), ) .subscribe((response: Record) => { this.isLoading = false; this.hasError = false; - if(!response.hasError) this.errorBlocks = []; - + if (!response.hasError) this.errorBlocks = []; + this.outputResult(response); }); break; - case 'BPUT': // binary PUT - const isArrayBufferWithContent = obj => (obj instanceof ArrayBuffer) && obj.byteLength > 0; - const payloadB = get(this.model, 'content'); + case "BPUT": // binary PUT + const isArrayBufferWithContent = (obj) => + obj instanceof ArrayBuffer && obj.byteLength > 0; + const payloadB = get(this.model, "content"); if (!isArrayBufferWithContent(payloadB)) { this.isLoading = false; this.hasError = true; - this.errorMessage = `${toUpper(method)} of empty payload prevented in http block`; + this.errorMessage = `${toUpper( + method, + )} of empty payload prevented in http block`; this.errorData = {}; this.errorBlocks = []; return; } - this.http.put(url, payloadB, { headers, responseType: this.responseType }) + this.http + .put(url, payloadB, { headers, responseType: this.responseType }) .pipe( - catchError(error => { + catchError((error) => { this.hasError = true; this.errorMessage = error.message; this.errorData = error; // TODO: need to prevent errors for triggering subsequent blocks - return of({error, hasError: this.hasError, errorMessage: this.errorMessage}); - }) + return of({ + error, + hasError: this.hasError, + errorMessage: this.errorMessage, + }); + }), ) .subscribe((response: Record) => { this.isLoading = false; this.hasError = false; - if(!response.hasError) this.errorBlocks = []; + if (!response.hasError) this.errorBlocks = []; this.outputResult(response); - const notify = get(this.config, 'notify', true); + const notify = get(this.config, "notify", true); if (notify) { - const message = 'API update successful'; - this.notify.open(message, 'OK', { + const message = "API update successful"; + this.notify.open(message, "OK", { duration: 2000, - verticalPosition: 'top' + verticalPosition: "top", }); } }); break; - case 'PUT': - case 'POST': - case 'PATCH': - const isEmptyObject = obj => (obj instanceof Object && Object.keys(obj).length === 0); + case "PUT": + case "POST": + case "PATCH": + const isEmptyObject = (obj) => + obj instanceof Object && Object.keys(obj).length === 0; let payload = this.getPayload(); - if ('application/x-www-form-urlencoded' === get(this.config, 'requestType', 'application/json')) { - payload = (new HttpParams({ fromObject: payload })).toString(); - headers = headers.set('Content-Type', 'application/x-www-form-urlencoded'); + if ( + "application/x-www-form-urlencoded" === + get(this.config, "requestType", "application/json") + ) { + payload = new HttpParams({ fromObject: payload }).toString(); + headers = headers.set( + "Content-Type", + "application/x-www-form-urlencoded", + ); } if (isEmptyObject(payload)) { this.isLoading = false; this.hasError = true; - this.errorMessage = `${toUpper(method)} of empty payload prevented in http block`; + this.errorMessage = `${toUpper( + method, + )} of empty payload prevented in http block`; this.errorData = {}; this.errorBlocks = []; return; } - const sub = (toUpper(method) === 'PUT') - ? this.http.put(url, payload, { headers, responseType: this.responseType }) - : (toUpper(method) === 'PATCH') ? - this.http.patch(url, payload, { headers, responseType: this.responseType }) - : this.http.post(url, payload, { headers, responseType: this.responseType }); + const sub = + toUpper(method) === "PUT" + ? this.http.put(url, payload, { + headers, + responseType: this.responseType, + }) + : toUpper(method) === "PATCH" + ? this.http.patch(url, payload, { + headers, + responseType: this.responseType, + }) + : this.http.post(url, payload, { + headers, + responseType: this.responseType, + }); sub .pipe( - catchError(error => { + catchError((error) => { this.hasError = true; this.errorMessage = error.message; this.errorData = error; // TODO: need to prevent errors for triggering subsequent blocks - return of({error, hasError: this.hasError, errorMessage: this.errorMessage}); - }) + return of({ + error, + hasError: this.hasError, + errorMessage: this.errorMessage, + }); + }), ) .subscribe((response: Record) => { this.isLoading = false; this.hasError = false; - if(!response.hasError) this.errorBlocks = []; + if (!response.hasError) this.errorBlocks = []; this.outputResult(response); - const notify = get(this.config, 'notify', true); + const notify = get(this.config, "notify", true); if (notify) { - const message = 'API update successful'; - this.notify.open(message, 'OK', { + const message = "API update successful"; + this.notify.open(message, "OK", { duration: 2000, - verticalPosition: 'top' + verticalPosition: "top", }); } }); @@ -265,7 +340,6 @@ export class HttpBlockComponent implements OnInit, OnChanges { } } - /** * Fetches paginated API results by recursively getting each page and merging the results. * @param {string} url - The endpoint URL. @@ -274,34 +348,43 @@ export class HttpBlockComponent implements OnInit, OnChanges { */ getAllPages(url, headers, responseType) { // Expands through pages recursively based on nextPageUrl - this.http.get(url, { headers, responseType, observe: 'response' }) + this.http + .get(url, { headers, responseType, observe: "response" }) .pipe( expand((response: HttpResponse) => { - const linkHeader = response.headers.get('link'); + const linkHeader = response.headers.get("link"); const nextPageUrl = this.extractNextPageUrl(linkHeader); if (nextPageUrl) { - if (get(this.config, 'useProxy', false)) { - headers = headers.delete('Target-URL'); - headers = headers.append('Target-URL', nextPageUrl); + if (get(this.config, "useProxy", false)) { + headers = headers.delete("Target-URL"); + headers = headers.append("Target-URL", nextPageUrl); } else { url = nextPageUrl; } - return this.http.get(url, { headers, responseType, observe: 'response' }); + return this.http.get(url, { + headers, + responseType, + observe: "response", + }); } else { return EMPTY; } }), - takeWhile(response => response.status === 200), // Stop when there's an error or nextPageUrl is null - catchError(error => { + takeWhile((response) => response.status === 200), // Stop when there's an error or nextPageUrl is null + catchError((error) => { this.hasError = true; this.errorMessage = error.message; this.errorData = error; return of([]); }), - reduce((accumlated_results: any[], response: HttpResponse) => accumlated_results.concat(response.body || []), []) + reduce( + (accumlated_results: any[], response: HttpResponse) => + accumlated_results.concat(response.body || []), + [], + ), ) - .subscribe(results => { + .subscribe((results) => { this.isLoading = false; this.hasError = false; this.outputResult(results); @@ -335,10 +418,9 @@ export class HttpBlockComponent implements OnInit, OnChanges { return null; } - // We use a regex to extract the URL and relation type from each link, // and return an object with the URL and relation type. - const links = linkHeader.split(',').map(link => { + const links = linkHeader.split(",").map((link) => { // The regex will match the first pair of angle brackets enclosing the URL, // and the first pair of double quotes enclosing the relation type. // Example: `; rel="next"` @@ -352,7 +434,7 @@ export class HttpBlockComponent implements OnInit, OnChanges { }); // Get the first link that matches the condition: - const nextPageLink = links.find(link => link?.rel === 'next'); + const nextPageLink = links.find((link) => link?.rel === "next"); // We return the URL of the next page if it exists, or null otherwise. return nextPageLink?.url || null; } @@ -362,34 +444,47 @@ export class HttpBlockComponent implements OnInit, OnChanges { } getPayloadHeaders() { - const headers = get(this.config, 'headers', {}); + const headers = get(this.config, "headers", {}); return Object.keys(headers).reduce((a, key) => { - a[key] = mappingUtility({ data: this.model, context: this.context }, headers[key]); + a[key] = mappingUtility( + { data: this.model, context: this.context }, + headers[key], + ); return a; }, {}); } getPayload() { - const payloadMapping = get(this.config, 'payload'); + const payloadMapping = get(this.config, "payload"); if (payloadMapping) { - return mappingUtility({ data: this.model, context: this.context }, payloadMapping); + return mappingUtility( + { data: this.model, context: this.context }, + payloadMapping, + ); } return this.model; } constructEndpointUrl(config) { - if (isString(get(config, 'endpoint', ''))) { + if (isString(get(config, "endpoint", ""))) { return config.endpoint; } - const endpoint = this.contextData.getFromContextWithModel(config.endpoint, this.model, this.context); + const endpoint = this.contextData.getFromContextWithModel( + config.endpoint, + this.model, + this.context, + ); if (isString(endpoint)) { return endpoint; } - const protocol = get(endpoint, 'protocol', 'https:'); - const host = get(endpoint, 'host', ''); - const pathname = get(endpoint, 'pathname', '/'); - const query = get(endpoint, 'query', []); - const reduceQuery = _q => Object.keys(_q).map(key => `${key}=${_q[key]}`, []).join('&'); + const protocol = get(endpoint, "protocol", "https:"); + const host = get(endpoint, "host", ""); + const pathname = get(endpoint, "pathname", "/"); + const query = get(endpoint, "query", []); + const reduceQuery = (_q) => + Object.keys(_q) + .map((key) => `${key}=${_q[key]}`, []) + .join("&"); return `${protocol}//${host}${pathname}?${reduceQuery(query)}`; } diff --git a/src/app/blocks/variable-set/variable-set.component.ts b/src/app/blocks/variable-set/variable-set.component.ts index 6fd07b951..fc3bf8f6d 100644 --- a/src/app/blocks/variable-set/variable-set.component.ts +++ b/src/app/blocks/variable-set/variable-set.component.ts @@ -1,17 +1,25 @@ -import {Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, ViewChild} from '@angular/core'; -import {clone, get, isArray, isObject} from 'lodash-es'; -import * as stringify from 'json-stringify-safe'; -import { MatSnackBar } from '@angular/material/snack-bar'; -import {AppSettingsService} from '../../services/app-settings.service'; -import {mappingUtility} from '../mapping-block/mapping-util'; +import { + Component, + ElementRef, + EventEmitter, + Input, + OnChanges, + OnInit, + Output, + ViewChild, +} from "@angular/core"; +import { clone, get, isArray, isObject } from "lodash-es"; +import * as stringify from "json-stringify-safe"; +import { MatSnackBar } from "@angular/material/snack-bar"; +import { AppSettingsService } from "../../services/app-settings.service"; +import { mappingUtility } from "../mapping-block/mapping-util"; @Component({ - selector: 'app-variable-set', - templateUrl: './variable-set.component.html', - styleUrls: ['./variable-set.component.scss'] + selector: "app-variable-set", + templateUrl: "./variable-set.component.html", + styleUrls: ["./variable-set.component.scss"], }) export class VariableSetComponent implements OnInit, OnChanges { - @Input() config; @Input() context; @Input() model: any = {}; @@ -22,46 +30,52 @@ export class VariableSetComponent implements OnInit, OnChanges { constructor( private readonly notify: MatSnackBar, - private readonly settings: AppSettingsService - ) { - } + private readonly settings: AppSettingsService, + ) {} - ngOnInit() { - } + ngOnInit() {} ngOnChanges(changes) { - this.showNotify = get(this.config, 'notify', true); - this.nameGetter = get(this.config, 'nameGetter'); - this.valueGetter = get(this.config, 'valueGetter'); - if (get(changes, 'model.firstChange', false)) { + this.showNotify = get(this.config, "notify", true); + this.nameGetter = get(this.config, "nameGetter"); + this.valueGetter = get(this.config, "valueGetter"); + if (get(changes, "model.firstChange", false)) { return; } - if (!this.model || (isObject(this.model) && Object.keys(this.model).length === 0)) { + if ( + !this.model || + (isObject(this.model) && Object.keys(this.model).length === 0) + ) { return; } - const adapterName = get(this.context, 'app.adapterName', 'UNKNOWN'); - const variableName = get(this.config, 'name', 'UNKNOWN'); + const adapterName = get(this.context, "app.adapterName", "UNKNOWN"); + const variableName = get(this.config, "name", "UNKNOWN"); let savedVariableName = `${adapterName}.variables.${variableName}`; if (this.nameGetter) { // console.log(this.nameGetter, this.model, this.context); - savedVariableName = mappingUtility({ data: this.model, context: this.context }, this.nameGetter); + savedVariableName = mappingUtility( + { data: this.model, context: this.context }, + this.nameGetter, + ); } const data = this.valueGetter - ? mappingUtility({ data: this.model, context: this.context }, this.valueGetter) + ? mappingUtility( + { data: this.model, context: this.context }, + this.valueGetter, + ) : stringify(this.model); localStorage.setItem(savedVariableName, data); if (this.showNotify) { const message = `${variableName} update successful`; - this.notify.open(message, 'OK', { + this.notify.open(message, "OK", { duration: 4000, - verticalPosition: 'top' + verticalPosition: "top", }); } this.output.emit(clone(this.model)); - if (get(this.context, 'app.adapterName') === 'core') { + if (get(this.context, "app.adapterName") === "core") { this.settings.settingsUpdated$.next(); } } - } diff --git a/src/app/channels/channels.module.ts b/src/app/channels/channels.module.ts index e2faff8fd..e8b824507 100644 --- a/src/app/channels/channels.module.ts +++ b/src/app/channels/channels.module.ts @@ -1,21 +1,14 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; +import { NgModule } from "@angular/core"; +import { CommonModule } from "@angular/common"; -import { ChannelsRoutingModule } from './channels-routing.module'; -import { ChannelsComponent } from './channels.component'; -import { SharedModule } from '../_shared/shared.module'; -import { ChannelComponent } from './channel/channel.component'; +import { ChannelsRoutingModule } from "./channels-routing.module"; +import { ChannelsComponent } from "./channels.component"; +import { SharedModule } from "../_shared/shared.module"; +import { ChannelComponent } from "./channel/channel.component"; @NgModule({ declarations: [ChannelsComponent, ChannelComponent], - imports: [ - CommonModule, - SharedModule, - ChannelsRoutingModule - - ], - exports: [ - - ] + imports: [CommonModule, SharedModule, ChannelsRoutingModule], + exports: [], }) -export class ChannelsModule { } +export class ChannelsModule {} diff --git a/src/app/components/block-comparison-builder-box/block-comparison-builder-box.component.html b/src/app/components/block-comparison-builder-box/block-comparison-builder-box.component.html index 7132dabf3..cfdea2a32 100644 --- a/src/app/components/block-comparison-builder-box/block-comparison-builder-box.component.html +++ b/src/app/components/block-comparison-builder-box/block-comparison-builder-box.component.html @@ -1,100 +1,143 @@
- - Value source (jmespath) - - - - - - - - - reorder -
- - - If [  {{ comparison.get('operator').value }} ] : - [ {{ comparison.get('target').value | slice:0:12 - }}  ] then - [ {{ comparison.get('output').value | - slice:0:12}} ] - - - - - If [  {{ comparison.get('operator').value }} ] then - [ {{ comparison.get('output').value | slice:0:30 - }} ] - - - -
- -
- -
- - Operator - - {{op}} - - - - Target - - - Target type - - value - jmespath - - - - Output - - - - Output type - - value - jmespath - - -
- -
-
-
-
-

- -
- -
- - - Default - - - - Default type - - value - jmespath - - - - - - - + + Value source (jmespath) + + + + + + + + + reorder +
+ + + If [  + {{ comparison.get("operator").value }} ] : [ {{ + comparison.get("target").value | slice: 0 : 12 + }}  ] then [ {{ + comparison.get("output").value | slice: 0 : 12 + }} ] + + + + + If [  + {{ comparison.get("operator").value }} ] then [ {{ + comparison.get("output").value | slice: 0 : 30 + }} ] + + +
+
+
+ + Operator + + {{ + op + }} + + + + Target + + + Target type + + value + jmespath + + + + Output + + + + Output type + + value + jmespath + + +
+ +
+
+
+
+
+
+ +
+
+ + + Default + + + + Default type + + value + jmespath + + + +
diff --git a/src/app/components/block-comparison-builder-box/block-comparison-builder-box.component.ts b/src/app/components/block-comparison-builder-box/block-comparison-builder-box.component.ts index 939c0a5f0..68dc08538 100644 --- a/src/app/components/block-comparison-builder-box/block-comparison-builder-box.component.ts +++ b/src/app/components/block-comparison-builder-box/block-comparison-builder-box.component.ts @@ -1,26 +1,27 @@ -import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; -import {get} from 'lodash-es'; -import {comparisonDefinition, comparisonOperators, comparisonTypes} from 'src/app/blocks/comparison/comparison.component'; -import {FormArray, FormControl, FormGroup } from '@angular/forms'; - +import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core"; +import { get } from "lodash-es"; +import { + comparisonDefinition, + comparisonOperators, + comparisonTypes, +} from "src/app/blocks/comparison/comparison.component"; +import { FormArray, FormControl, FormGroup } from "@angular/forms"; @Component({ - selector: 'app-block-comparison-builder-box', - templateUrl: './block-comparison-builder-box.component.html', - styleUrls: ['./block-comparison-builder-box.component.scss'] + selector: "app-block-comparison-builder-box", + templateUrl: "./block-comparison-builder-box.component.html", + styleUrls: ["./block-comparison-builder-box.component.scss"], }) /** * Defines an editor form for the comparison block type */ - export class BlockComparisonBuilderBoxComponent implements OnInit { - @Input() block; @Output() blockUpdated = new EventEmitter(); - valueGetter: string = 'data'; - default: string = 'OK'; + valueGetter: string = "data"; + default: string = "OK"; defaultType: string = comparisonTypes[0]; comparisons: comparisonDefinition[]; operators: string[]; @@ -29,52 +30,59 @@ export class BlockComparisonBuilderBoxComponent implements OnInit { valueGetter: new FormControl(this.valueGetter), default: new FormControl(this.default), defaultType: new FormControl(this.defaultType), - comparisons: new FormArray([]) - }) + comparisons: new FormArray([]), + }); ngOnInit() { - this.form.controls['valueGetter'].setValue(get(this.block, 'valueGetter', this.valueGetter)); - this.form.controls['default'].setValue(get(this.block, 'default', this.default)); - this.form.controls['defaultType'].setValue(get(this.block, 'defaultType', this.defaultType)); + this.form.controls["valueGetter"].setValue( + get(this.block, "valueGetter", this.valueGetter), + ); + this.form.controls["default"].setValue( + get(this.block, "default", this.default), + ); + this.form.controls["defaultType"].setValue( + get(this.block, "defaultType", this.defaultType), + ); this.operators = Object.keys(comparisonOperators); this.targetTypes = comparisonTypes; - this.comparisons = get(this.block,'comparisons',[]); + this.comparisons = get(this.block, "comparisons", []); this.comparisons.forEach((comparison) => { - this.form.controls['comparisons'].push(new FormGroup({ - operator: new FormControl(comparison.operator), - target: new FormControl(comparison.target), - targetType: new FormControl(comparison.targetType || 'value'), - output: new FormControl(comparison.output), - outputType: new FormControl(comparison.outputType || 'value') - })) - }) + this.form.controls["comparisons"].push( + new FormGroup({ + operator: new FormControl(comparison.operator), + target: new FormControl(comparison.target), + targetType: new FormControl(comparison.targetType || "value"), + output: new FormControl(comparison.output), + outputType: new FormControl(comparison.outputType || "value"), + }), + ); + }); } /** * Converts the form into a block config object * @returns the new data model */ - getUpdatedModel():any { - let comparisons:comparisonDefinition[] = []; + getUpdatedModel(): any { + let comparisons: comparisonDefinition[] = []; for (let comparisonGroup of this.form.controls.comparisons.controls) { - let comparison = { - operator: comparisonGroup.get('operator').value, - target: comparisonGroup.get('target').value, - targetType: comparisonGroup.get('targetType').value, - output: comparisonGroup.get('output').value, - outputType: comparisonGroup.get('outputType').value - } - comparisons.push(comparison); + let comparison = { + operator: comparisonGroup.get("operator").value, + target: comparisonGroup.get("target").value, + targetType: comparisonGroup.get("targetType").value, + output: comparisonGroup.get("output").value, + outputType: comparisonGroup.get("outputType").value, + }; + comparisons.push(comparison); } - return { ...this.block, - valueGetter: this.form.controls['valueGetter'].value, - default: this.form.controls['default'].value, - defaultType: this.form.controls['defaultType'].value, - comparisons:comparisons + valueGetter: this.form.controls["valueGetter"].value, + default: this.form.controls["default"].value, + defaultType: this.form.controls["defaultType"].value, + comparisons: comparisons, }; } @@ -83,23 +91,24 @@ export class BlockComparisonBuilderBoxComponent implements OnInit { * @param op The selected operation * @returns Returns true if the provided operator requires multiple parameters */ - opMultiParam(op:string):boolean { + opMultiParam(op: string): boolean { //console.log("o"+op) return comparisonOperators[op].paramcount == 2; } - /** * Insert a new comparison object into the form */ - insertComparison():void { - this.form.controls['comparisons'].push(new FormGroup({ - operator: new FormControl('=='), - target: new FormControl(''), - targetType: new FormControl('value'), - output: new FormControl(''), - outputType: new FormControl('value') - })) + insertComparison(): void { + this.form.controls["comparisons"].push( + new FormGroup({ + operator: new FormControl("=="), + target: new FormControl(""), + targetType: new FormControl("value"), + output: new FormControl(""), + outputType: new FormControl("value"), + }), + ); } /** @@ -107,7 +116,7 @@ export class BlockComparisonBuilderBoxComponent implements OnInit { * @param index */ removeComparison(index) { - let formArray = this.form.get('comparisons') as FormArray; + let formArray = this.form.get("comparisons") as FormArray; formArray.removeAt(index); } @@ -115,31 +124,25 @@ export class BlockComparisonBuilderBoxComponent implements OnInit { * Handle the drag drop * @param event */ - drop(event):void { - this.moveComparison(event.previousIndex,event.currentIndex); + drop(event): void { + this.moveComparison(event.previousIndex, event.currentIndex); } -/** - * Moves an item in a FormArray to another position. - * @param fromIndex Starting index of the item. - * @param toIndex Index to which he item should be moved. - */ + /** + * Moves an item in a FormArray to another position. + * @param fromIndex Starting index of the item. + * @param toIndex Index to which he item should be moved. + */ - moveComparison(fromIndex: number, toIndex: number): void { - const dir = toIndex > fromIndex ? 1 : -1; - let formArray = this.form.get('comparisons') as FormArray; + moveComparison(fromIndex: number, toIndex: number): void { + const dir = toIndex > fromIndex ? 1 : -1; + let formArray = this.form.get("comparisons") as FormArray; - const item = formArray.at(fromIndex); - for (let i = fromIndex; i * dir < toIndex * dir; i = i + dir) { - const current = formArray.at(i + dir); - formArray.setControl(i, current); + const item = formArray.at(fromIndex); + for (let i = fromIndex; i * dir < toIndex * dir; i = i + dir) { + const current = formArray.at(i + dir); + formArray.setControl(i, current); + } + formArray.setControl(toIndex, item); } - formArray.setControl(toIndex, item); -} - - } - - - - diff --git a/src/app/components/blocks-editor/blocks-editor.component.ts b/src/app/components/blocks-editor/blocks-editor.component.ts index 9951c6dbc..17aa29416 100644 --- a/src/app/components/blocks-editor/blocks-editor.component.ts +++ b/src/app/components/blocks-editor/blocks-editor.component.ts @@ -1,23 +1,30 @@ -import {Component, EventEmitter, Input, OnInit, OnChanges, Output} from '@angular/core'; -import {AddBlockDialogComponent} from '../../dialogs/add-block-dialog/add-block-dialog.component'; -import {BLOCK_TYPES} from '../../dialogs/add-block-dialog/block-types'; -import { MatDialog } from '@angular/material/dialog'; -import {moveItemInArray} from '@angular/cdk/drag-drop'; -import {clone} from 'lodash-es'; - +import { + Component, + EventEmitter, + Input, + OnInit, + OnChanges, + Output, +} from "@angular/core"; +import { AddBlockDialogComponent } from "../../dialogs/add-block-dialog/add-block-dialog.component"; +import { BLOCK_TYPES } from "../../dialogs/add-block-dialog/block-types"; +import { MatDialog } from "@angular/material/dialog"; +import { moveItemInArray } from "@angular/cdk/drag-drop"; +import { clone } from "lodash-es"; const _blockIcons = {}; const _blockTypes = {}; -BLOCK_TYPES.forEach(element => _blockIcons[element.type]=element.icon||'?'); +BLOCK_TYPES.forEach( + (element) => (_blockIcons[element.type] = element.icon || "?"), +); -BLOCK_TYPES.forEach(element => _blockTypes[element.type]=element); +BLOCK_TYPES.forEach((element) => (_blockTypes[element.type] = element)); @Component({ - selector: 'app-blocks-editor', - templateUrl: './blocks-editor.component.html', - styleUrls: ['./blocks-editor.component.scss'] + selector: "app-blocks-editor", + templateUrl: "./blocks-editor.component.html", + styleUrls: ["./blocks-editor.component.scss"], }) export class BlocksEditorComponent implements OnInit, OnChanges { - @Input() blocks = []; @Input() blockIcons = _blockIcons; @Input() blockTypes = _blockTypes; @@ -25,20 +32,19 @@ export class BlocksEditorComponent implements OnInit, OnChanges { blockTitles = []; - constructor( - private readonly dialog: MatDialog - ) { } + constructor(private readonly dialog: MatDialog) {} - ngOnInit() { - } + ngOnInit() {} - ngOnChanges(){ + ngOnChanges() { this.generateTitles(); } - generateTitles(){ + generateTitles() { this.blocks.forEach((block, i) => { - this.blockTitles[i] = block.blockComment ? block.blockComment.split("\n")[0]: ''; + this.blockTitles[i] = block.blockComment + ? block.blockComment.split("\n")[0] + : ""; }); } @@ -58,15 +64,19 @@ export class BlocksEditorComponent implements OnInit, OnChanges { } onUpdateBlock(i, c) { - this.blocks = [...this.blocks.slice(0, i), c.getUpdatedModel(), ...this.blocks.slice(i + 1)]; + this.blocks = [ + ...this.blocks.slice(0, i), + c.getUpdatedModel(), + ...this.blocks.slice(i + 1), + ]; this.blocksChanged(); } addBlock() { const dialogRef = this.dialog.open(AddBlockDialogComponent, { - width: '65vw' + width: "65vw", }); - dialogRef.afterClosed().subscribe(newBlock => { + dialogRef.afterClosed().subscribe((newBlock) => { if (!!newBlock) { // TODO: use immutable data for efficiency/structural sharing this.blocks = [...this.blocks, newBlock]; diff --git a/src/app/components/layout/layout.component.ts b/src/app/components/layout/layout.component.ts index f586a0d75..8f8a78e3f 100644 --- a/src/app/components/layout/layout.component.ts +++ b/src/app/components/layout/layout.component.ts @@ -1,53 +1,52 @@ -import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; -import { MatMenu } from '@angular/material/menu'; -import { MatSidenav } from '@angular/material/sidenav'; -import { Observable } from 'rxjs'; -import {SharedModule} from '../../_shared/shared.module'; -import { PageTitleService } from '../../services/page-title.service'; +import { Component, OnInit } from "@angular/core"; +import { Router } from "@angular/router"; +import { MatMenu } from "@angular/material/menu"; +import { MatSidenav } from "@angular/material/sidenav"; +import { Observable } from "rxjs"; +import { SharedModule } from "../../_shared/shared.module"; +import { PageTitleService } from "../../services/page-title.service"; @Component({ - selector: 'app-layout', - templateUrl: './layout.component.html', - styleUrls: ['./layout.component.scss'] + selector: "app-layout", + templateUrl: "./layout.component.html", + styleUrls: ["./layout.component.scss"], }) export class LayoutComponent implements OnInit { - links = [ { - href: '/', - title: 'Dashboard', - icon: 'dashboard' + href: "/", + title: "Dashboard", + icon: "dashboard", }, { - href: '/claims', - title: 'Claims', - icon: 'attach_money' + href: "/claims", + title: "Claims", + icon: "attach_money", }, { - href: '/tasks', - title: 'Tasks', - icon: 'alarm_on' + href: "/tasks", + title: "Tasks", + icon: "alarm_on", }, { - href: '/reports', - title: 'Reports', - icon: 'assignment' + href: "/reports", + title: "Reports", + icon: "assignment", }, { - href: '/contacts', - title: 'Contacts', - icon: 'contacts' + href: "/contacts", + title: "Contacts", + icon: "contacts", }, { - href: '/import', - title: 'Import', - icon: 'import_export' + href: "/import", + title: "Import", + icon: "import_export", }, { - href: '/upload', - title: 'Upload', - icon: 'cloud_upload' + href: "/upload", + title: "Upload", + icon: "cloud_upload", }, // { // href: '/diagram', @@ -55,39 +54,38 @@ export class LayoutComponent implements OnInit { // icon: 'bubble_chart' // }, { - href: '/adapters', - title: 'Adapters', - icon: 'extension' + href: "/adapters", + title: "Adapters", + icon: "extension", }, { - href: '/settings', - title: 'settings', - icon: 'settings' + href: "/settings", + title: "settings", + icon: "settings", }, { - href: '/docs', - title: 'database', - icon: 'storage' + href: "/docs", + title: "database", + icon: "storage", }, { - href: '/user', - title: 'Identities', - icon: 'person' - } + href: "/user", + title: "Identities", + icon: "person", + }, ]; - pageTitle$: Observable<{ title: string, isWorkflow: boolean}>; + pageTitle$: Observable<{ title: string; isWorkflow: boolean }>; sidenav: MatSidenav; constructor( private readonly router: Router, private readonly title: PageTitleService, - - ) { } + ) {} ngOnInit() { this.pageTitle$ = this.title.pageTitle$; - // this.sidenav.open(); + // this.sidenav.open(); } onRefresh() { @@ -96,6 +94,6 @@ export class LayoutComponent implements OnInit { gotoPage(href: string, sidenav: MatSidenav) { this.router.navigate([href]); - // sidenav.open(); + // sidenav.open(); } } diff --git a/src/app/dialogs/adapter-blocks-config-select-dialog/adapter-blocks-config-select-dialog.component.ts b/src/app/dialogs/adapter-blocks-config-select-dialog/adapter-blocks-config-select-dialog.component.ts index 79f9d3e09..707c83070 100644 --- a/src/app/dialogs/adapter-blocks-config-select-dialog/adapter-blocks-config-select-dialog.component.ts +++ b/src/app/dialogs/adapter-blocks-config-select-dialog/adapter-blocks-config-select-dialog.component.ts @@ -1,19 +1,18 @@ -import { Component, OnInit } from '@angular/core'; -import {AdaptersService} from '../../services/adapters.service'; -import {HttpClient} from '@angular/common/http'; -import {MatDialogRef } from '@angular/material/dialog'; -import {map, tap} from 'rxjs/operators'; -import {get, has, pickBy} from 'lodash-es'; -import {forkJoin} from 'rxjs'; -import {environment} from '../../../environments/environment'; +import { Component, OnInit } from "@angular/core"; +import { AdaptersService } from "../../services/adapters.service"; +import { HttpClient } from "@angular/common/http"; +import { MatDialogRef } from "@angular/material/dialog"; +import { map, tap } from "rxjs/operators"; +import { get, has, pickBy } from "lodash-es"; +import { forkJoin } from "rxjs"; +import { environment } from "../../../environments/environment"; @Component({ - selector: 'app-adapter-blocks-config-select-dialog', - templateUrl: './adapter-blocks-config-select-dialog.component.html', - styleUrls: ['./adapter-blocks-config-select-dialog.component.scss'] + selector: "app-adapter-blocks-config-select-dialog", + templateUrl: "./adapter-blocks-config-select-dialog.component.html", + styleUrls: ["./adapter-blocks-config-select-dialog.component.scss"], }) export class AdapterBlocksConfigSelectDialogComponent implements OnInit { - adapters$; selectedAdapter; selectedConfig; @@ -24,27 +23,31 @@ export class AdapterBlocksConfigSelectDialogComponent implements OnInit { constructor( private readonly adapters: AdaptersService, private readonly http: HttpClient, - public dialogRef: MatDialogRef - ) { } + public dialogRef: MatDialogRef, + ) {} ngOnInit() { - this.adapters$ = this.adapters.adapters$ - .pipe( - map((adapters) => { - return pickBy(adapters, config => has(config, 'adapter.configs')); - }), - tap(value => this.adapterCache = value) - ); + this.adapters$ = this.adapters.adapters$.pipe( + map((adapters) => { + return pickBy(adapters, (config) => has(config, "adapter.configs")); + }), + tap((value) => (this.adapterCache = value)), + ); } adapterChange() { - forkJoin(get(this.adapterCache, `${this.selectedAdapter}.adapter.configs`, []) - .map(path => this.http.get(`${environment.adapterBaseUrl}${path}`))) - .subscribe(results => this.configs = results); + forkJoin( + get(this.adapterCache, `${this.selectedAdapter}.adapter.configs`, []).map( + (path) => this.http.get(`${environment.adapterBaseUrl}${path}`), + ), + ).subscribe((results) => (this.configs = results)); } loadConfig() { - this.dialogRef.close({ adapterName: this.selectedAdapter, ...this.configs[this.selectedConfig] }); + this.dialogRef.close({ + adapterName: this.selectedAdapter, + ...this.configs[this.selectedConfig], + }); } cancel() { diff --git a/src/app/dialogs/adapter-query-select-dialog/adapter-query-select-dialog.component.ts b/src/app/dialogs/adapter-query-select-dialog/adapter-query-select-dialog.component.ts index 615cc2831..f4727f95c 100644 --- a/src/app/dialogs/adapter-query-select-dialog/adapter-query-select-dialog.component.ts +++ b/src/app/dialogs/adapter-query-select-dialog/adapter-query-select-dialog.component.ts @@ -1,19 +1,18 @@ -import { Component, OnInit } from '@angular/core'; -import { MatDialogRef } from '@angular/material/dialog'; -import {HttpClient} from '@angular/common/http'; -import {AdaptersService} from '../../services/adapters.service'; -import {map, tap} from 'rxjs/operators'; -import {get, has, pickBy} from 'lodash-es'; -import {forkJoin} from 'rxjs'; -import {environment} from '../../../environments/environment'; +import { Component, OnInit } from "@angular/core"; +import { MatDialogRef } from "@angular/material/dialog"; +import { HttpClient } from "@angular/common/http"; +import { AdaptersService } from "../../services/adapters.service"; +import { map, tap } from "rxjs/operators"; +import { get, has, pickBy } from "lodash-es"; +import { forkJoin } from "rxjs"; +import { environment } from "../../../environments/environment"; @Component({ - selector: 'app-adapter-query-select-dialog', - templateUrl: './adapter-query-select-dialog.component.html', - styleUrls: ['./adapter-query-select-dialog.component.scss'] + selector: "app-adapter-query-select-dialog", + templateUrl: "./adapter-query-select-dialog.component.html", + styleUrls: ["./adapter-query-select-dialog.component.scss"], }) export class AdapterQuerySelectDialogComponent implements OnInit { - adapters$; selectedAdapter; selectedQuery; @@ -24,23 +23,24 @@ export class AdapterQuerySelectDialogComponent implements OnInit { constructor( private readonly adapters: AdaptersService, private readonly http: HttpClient, - public dialogRef: MatDialogRef - ) { } + public dialogRef: MatDialogRef, + ) {} ngOnInit() { - this.adapters$ = this.adapters.adapters$ - .pipe( - map((adapters) => { - return pickBy(adapters, config => has(config, 'adapter.queries')); - }), - tap(value => this.adapterCache = value) - ); + this.adapters$ = this.adapters.adapters$.pipe( + map((adapters) => { + return pickBy(adapters, (config) => has(config, "adapter.queries")); + }), + tap((value) => (this.adapterCache = value)), + ); } adapterChange() { - forkJoin(get(this.adapterCache, `${this.selectedAdapter}.adapter.queries`, []) - .map(path => this.http.get(`${environment.adapterBaseUrl}${path}`))) - .subscribe(results => this.queries = results); + forkJoin( + get(this.adapterCache, `${this.selectedAdapter}.adapter.queries`, []).map( + (path) => this.http.get(`${environment.adapterBaseUrl}${path}`), + ), + ).subscribe((results) => (this.queries = results)); } loadForm() { diff --git a/src/app/dialogs/add-block-dialog/add-block-dialog.component.ts b/src/app/dialogs/add-block-dialog/add-block-dialog.component.ts index 289cd81eb..686bce987 100644 --- a/src/app/dialogs/add-block-dialog/add-block-dialog.component.ts +++ b/src/app/dialogs/add-block-dialog/add-block-dialog.component.ts @@ -1,32 +1,28 @@ -import { Component, OnInit } from '@angular/core'; -import {MatDialogRef } from '@angular/material/dialog'; -import {BLOCK_TYPES} from './block-types'; -import {get} from 'lodash-es'; +import { Component, OnInit } from "@angular/core"; +import { MatDialogRef } from "@angular/material/dialog"; +import { BLOCK_TYPES } from "./block-types"; +import { get } from "lodash-es"; @Component({ - selector: 'app-add-block-dialog', - templateUrl: './add-block-dialog.component.html', - styleUrls: ['./add-block-dialog.component.scss'] + selector: "app-add-block-dialog", + templateUrl: "./add-block-dialog.component.html", + styleUrls: ["./add-block-dialog.component.scss"], }) export class AddBlockDialogComponent implements OnInit { - - blockTypes = BLOCK_TYPES.filter(def => !(def.deprecated)); + blockTypes = BLOCK_TYPES.filter((def) => !def.deprecated); selectedBlockType; - constructor( - public dialogRef: MatDialogRef - ) { } + constructor(public dialogRef: MatDialogRef) {} - ngOnInit() { - } + ngOnInit() {} setBlockType(b) { this.selectedBlockType = b; } addBlock() { - this.dialogRef.close(get(this.selectedBlockType, 'defaultConfig')); + this.dialogRef.close(get(this.selectedBlockType, "defaultConfig")); } cancel() { diff --git a/src/app/dialogs/add-new-node-dialog/add-new-node-dialog.component.ts b/src/app/dialogs/add-new-node-dialog/add-new-node-dialog.component.ts index e89da9f59..b80b45e46 100644 --- a/src/app/dialogs/add-new-node-dialog/add-new-node-dialog.component.ts +++ b/src/app/dialogs/add-new-node-dialog/add-new-node-dialog.component.ts @@ -1,29 +1,28 @@ -import { Component, Inject, OnInit } from '@angular/core'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { SchemaRepositoryService } from '../../services/schema-repository.service'; +import { Component, Inject, OnInit } from "@angular/core"; +import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; +import { SchemaRepositoryService } from "../../services/schema-repository.service"; @Component({ - selector: 'app-add-new-node-dialog', - templateUrl: './add-new-node-dialog.component.html', - styleUrls: ['./add-new-node-dialog.component.scss'] + selector: "app-add-new-node-dialog", + templateUrl: "./add-new-node-dialog.component.html", + styleUrls: ["./add-new-node-dialog.component.scss"], }) export class AddNewNodeDialogComponent implements OnInit { - labelField; constructor( public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data, - private readonly schemaService: SchemaRepositoryService - ) { - - } + private readonly schemaService: SchemaRepositoryService, + ) {} ngOnInit() { - this.labelField = this.schemaService.getLabelFieldForSchema(this.data['type']); + this.labelField = this.schemaService.getLabelFieldForSchema( + this.data["type"], + ); } closeDialog(labelValue) { - this.dialogRef.close({ [this.labelField['id']]: labelValue }); + this.dialogRef.close({ [this.labelField["id"]]: labelValue }); } } diff --git a/src/app/dialogs/api-data-select-dialog/api-data-select-dialog.component.ts b/src/app/dialogs/api-data-select-dialog/api-data-select-dialog.component.ts index b0064e236..221bddc4a 100644 --- a/src/app/dialogs/api-data-select-dialog/api-data-select-dialog.component.ts +++ b/src/app/dialogs/api-data-select-dialog/api-data-select-dialog.component.ts @@ -1,19 +1,18 @@ -import { Component, OnInit } from '@angular/core'; -import {HttpClient} from '@angular/common/http'; -import { MatDialogRef } from '@angular/material/dialog'; +import { Component, OnInit } from "@angular/core"; +import { HttpClient } from "@angular/common/http"; +import { MatDialogRef } from "@angular/material/dialog"; @Component({ - selector: 'app-api-data-select-dialog', - templateUrl: './api-data-select-dialog.component.html', - styleUrls: ['./api-data-select-dialog.component.scss'] + selector: "app-api-data-select-dialog", + templateUrl: "./api-data-select-dialog.component.html", + styleUrls: ["./api-data-select-dialog.component.scss"], }) export class ApiDataSelectDialogComponent implements OnInit { - APIs = [ - 'https://fake-api.now32.now.sh/soundRecording', - 'https://fake-api.now32.now.sh/musicalWork', - 'https://bloomen.herokuapp.com/sound/music', - 'https://bloomen.herokuapp.com/sound/recordings' + "https://fake-api.now32.now.sh/soundRecording", + "https://fake-api.now32.now.sh/musicalWork", + "https://bloomen.herokuapp.com/sound/music", + "https://bloomen.herokuapp.com/sound/recordings", ]; dataList = []; @@ -23,14 +22,13 @@ export class ApiDataSelectDialogComponent implements OnInit { constructor( private readonly http: HttpClient, - public dialogRef: MatDialogRef - ) { } + public dialogRef: MatDialogRef, + ) {} - ngOnInit() { - } + ngOnInit() {} getList() { - this.http.get>(this.selectedApi).subscribe(value => { + this.http.get>(this.selectedApi).subscribe((value) => { this.dataList = value; }); } @@ -38,12 +36,11 @@ export class ApiDataSelectDialogComponent implements OnInit { loadData() { this.dialogRef.close({ endpoint: this.selectedApi, - values: this.dataList[this.selectedData] + values: this.dataList[this.selectedData], }); } cancel() { this.dialogRef.close(false); } - } diff --git a/src/app/dialogs/blocks-dialog/blocks-dialog.component.ts b/src/app/dialogs/blocks-dialog/blocks-dialog.component.ts index 58b04a199..af3222275 100644 --- a/src/app/dialogs/blocks-dialog/blocks-dialog.component.ts +++ b/src/app/dialogs/blocks-dialog/blocks-dialog.component.ts @@ -1,14 +1,13 @@ -import {Component, Inject, NgZone, OnInit} from '@angular/core'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import {get} from 'lodash-es'; +import { Component, Inject, NgZone, OnInit } from "@angular/core"; +import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; +import { get } from "lodash-es"; @Component({ - selector: 'app-blocks-dialog', - templateUrl: './blocks-dialog.component.html', - styleUrls: ['./blocks-dialog.component.scss'] + selector: "app-blocks-dialog", + templateUrl: "./blocks-dialog.component.html", + styleUrls: ["./blocks-dialog.component.scss"], }) export class BlocksDialogComponent implements OnInit { - blocks = []; models = []; context = {}; @@ -16,13 +15,13 @@ export class BlocksDialogComponent implements OnInit { constructor( public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data, - private readonly zone: NgZone - ) { } + private readonly zone: NgZone, + ) {} ngOnInit() { - this.blocks = get(this.data, 'blocks', []); - this.models = [get(this.data, 'model', {})]; - this.context = get(this.data, 'context', {}); + this.blocks = get(this.data, "blocks", []); + this.models = [get(this.data, "model", {})]; + this.context = get(this.data, "context", {}); } onWorkflowComplete(value) { diff --git a/src/app/dialogs/confirm-delete-dialog/confirm-delete-dialog.component.ts b/src/app/dialogs/confirm-delete-dialog/confirm-delete-dialog.component.ts index 6bb7a432a..2adf93975 100644 --- a/src/app/dialogs/confirm-delete-dialog/confirm-delete-dialog.component.ts +++ b/src/app/dialogs/confirm-delete-dialog/confirm-delete-dialog.component.ts @@ -1,23 +1,20 @@ -import { Component, Inject, OnInit } from '@angular/core'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, Inject, OnInit } from "@angular/core"; +import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; @Component({ - selector: 'app-confirm-delete-dialog', - templateUrl: './confirm-delete-dialog.component.html', - styleUrls: ['./confirm-delete-dialog.component.scss'] + selector: "app-confirm-delete-dialog", + templateUrl: "./confirm-delete-dialog.component.html", + styleUrls: ["./confirm-delete-dialog.component.scss"], }) export class ConfirmDeleteDialogComponent implements OnInit { - item; constructor( public dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public data + @Inject(MAT_DIALOG_DATA) public data, ) { this.item = data.item; } - ngOnInit() { - } - + ngOnInit() {} } diff --git a/src/app/dialogs/edit-clip-dialog/edit-clip-dialog.component.ts b/src/app/dialogs/edit-clip-dialog/edit-clip-dialog.component.ts index 9bee3804c..1f359a4bc 100644 --- a/src/app/dialogs/edit-clip-dialog/edit-clip-dialog.component.ts +++ b/src/app/dialogs/edit-clip-dialog/edit-clip-dialog.component.ts @@ -1,37 +1,31 @@ -import { Component, Inject, OnInit } from '@angular/core'; -import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, Inject, OnInit } from "@angular/core"; +import { UntypedFormBuilder, UntypedFormGroup } from "@angular/forms"; +import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; @Component({ - selector: 'app-edit-clip-dialog', - templateUrl: './edit-clip-dialog.component.html', - styleUrls: ['./edit-clip-dialog.component.scss'] + selector: "app-edit-clip-dialog", + templateUrl: "./edit-clip-dialog.component.html", + styleUrls: ["./edit-clip-dialog.component.scss"], }) export class EditClipDialogComponent implements OnInit { - form: UntypedFormGroup; - rightsGroups = [ - 'Composition', - 'Recording', - 'Performance', - 'Design' - ]; + rightsGroups = ["Composition", "Recording", "Performance", "Design"]; constructor( private readonly fb: UntypedFormBuilder, public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data, - ) { } + ) {} ngOnInit() { this.form = this.fb.group({ - name: [''], - right: [''], - role: [''], - contributor: [''], + name: [""], + right: [""], + role: [""], + contributor: [""], start: [0], - end: [100] + end: [100], }); this.form.patchValue(this.data.clip); } diff --git a/src/app/dialogs/edit-workflow-metadata-dialog/edit-workflow-metadata-dialog.component.html b/src/app/dialogs/edit-workflow-metadata-dialog/edit-workflow-metadata-dialog.component.html index 5949f61f4..4cd03186a 100644 --- a/src/app/dialogs/edit-workflow-metadata-dialog/edit-workflow-metadata-dialog.component.html +++ b/src/app/dialogs/edit-workflow-metadata-dialog/edit-workflow-metadata-dialog.component.html @@ -1,30 +1,48 @@
- + - + - + - - {{tag}} + + {{ tag }} cancel - +
-
- +
+ -
+
diff --git a/src/app/dialogs/edit-workflow-metadata-dialog/edit-workflow-metadata-dialog.component.ts b/src/app/dialogs/edit-workflow-metadata-dialog/edit-workflow-metadata-dialog.component.ts index 6dd3ad1d2..dd99322c1 100644 --- a/src/app/dialogs/edit-workflow-metadata-dialog/edit-workflow-metadata-dialog.component.ts +++ b/src/app/dialogs/edit-workflow-metadata-dialog/edit-workflow-metadata-dialog.component.ts @@ -1,17 +1,21 @@ -import {Component, Inject, OnInit} from '@angular/core'; -import { MatChipInputEvent } from '@angular/material/chips'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import {clone} from 'lodash-es'; -import {UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators} from '@angular/forms'; -import {COMMA, ENTER} from '@angular/cdk/keycodes'; +import { Component, Inject, OnInit } from "@angular/core"; +import { MatChipInputEvent } from "@angular/material/chips"; +import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; +import { clone } from "lodash-es"; +import { + UntypedFormArray, + UntypedFormBuilder, + UntypedFormGroup, + Validators, +} from "@angular/forms"; +import { COMMA, ENTER } from "@angular/cdk/keycodes"; @Component({ - selector: 'app-edit-workflow-metadata-dialog', - templateUrl: './edit-workflow-metadata-dialog.component.html', - styleUrls: ['./edit-workflow-metadata-dialog.component.scss'] + selector: "app-edit-workflow-metadata-dialog", + templateUrl: "./edit-workflow-metadata-dialog.component.html", + styleUrls: ["./edit-workflow-metadata-dialog.component.scss"], }) export class EditWorkflowMetadataDialogComponent implements OnInit { - form: UntypedFormGroup; visible = true; selectable = true; @@ -20,24 +24,26 @@ export class EditWorkflowMetadataDialogComponent implements OnInit { readonly separatorKeysCodes: number[] = [ENTER, COMMA]; get tags() { - return (this.form.get('tags') as UntypedFormArray); + return this.form.get("tags") as UntypedFormArray; } constructor( public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data, - private readonly fb: UntypedFormBuilder - ) { } + private readonly fb: UntypedFormBuilder, + ) {} ngOnInit() { this.form = this.fb.group({ - title: ['', [Validators.required]], - id: [''], - adapterName: [''], + title: ["", [Validators.required]], + id: [""], + adapterName: [""], tags: this.fb.array([]), }); this.form.patchValue(this.data); - (this.data.tags).forEach(tag => this.tags.push(this.fb.control(tag))); + (this.data.tags).forEach((tag) => + this.tags.push(this.fb.control(tag)), + ); } addTag(event: MatChipInputEvent): void { @@ -45,13 +51,13 @@ export class EditWorkflowMetadataDialogComponent implements OnInit { const value = event.value; // Add our tag - if ((value || '').trim()) { + if ((value || "").trim()) { this.tags.push(this.fb.control(value)); } // Reset the input value if (input) { - input.value = ''; + input.value = ""; } } diff --git a/src/app/dialogs/export-config-dialog/export-config-dialog.component.ts b/src/app/dialogs/export-config-dialog/export-config-dialog.component.ts index 41def643e..c02344bab 100644 --- a/src/app/dialogs/export-config-dialog/export-config-dialog.component.ts +++ b/src/app/dialogs/export-config-dialog/export-config-dialog.component.ts @@ -1,21 +1,20 @@ -import {Component, Inject, OnInit, ViewChild} from '@angular/core'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, Inject, OnInit, ViewChild } from "@angular/core"; +import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; @Component({ - selector: 'app-export-config-dialog', - templateUrl: './export-config-dialog.component.html', - styleUrls: ['./export-config-dialog.component.scss'] + selector: "app-export-config-dialog", + templateUrl: "./export-config-dialog.component.html", + styleUrls: ["./export-config-dialog.component.scss"], }) export class ExportConfigDialogComponent implements OnInit { + configText = ""; - configText = ''; - - @ViewChild('textBox') textBox; + @ViewChild("textBox") textBox; constructor( public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data, - ) { } + ) {} ngOnInit() { this.configText = this.data.configText; @@ -24,6 +23,6 @@ export class ExportConfigDialogComponent implements OnInit { copyText() { this.textBox.nativeElement.focus(); this.textBox.nativeElement.select(); - window.document.execCommand('copy'); + window.document.execCommand("copy"); } } diff --git a/src/app/dialogs/form-data-select-dialog/form-data-select-dialog.component.ts b/src/app/dialogs/form-data-select-dialog/form-data-select-dialog.component.ts index 8a0413144..66b48ddab 100644 --- a/src/app/dialogs/form-data-select-dialog/form-data-select-dialog.component.ts +++ b/src/app/dialogs/form-data-select-dialog/form-data-select-dialog.component.ts @@ -1,26 +1,24 @@ -import {Component, Inject, OnInit} from '@angular/core'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, Inject, OnInit } from "@angular/core"; +import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; @Component({ - selector: 'app-form-data-select-dialog', - templateUrl: './form-data-select-dialog.component.html', - styleUrls: ['./form-data-select-dialog.component.scss'] + selector: "app-form-data-select-dialog", + templateUrl: "./form-data-select-dialog.component.html", + styleUrls: ["./form-data-select-dialog.component.scss"], }) export class FormDataSelectDialogComponent implements OnInit { - selectedID; constructor( public dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public data - ) { } + @Inject(MAT_DIALOG_DATA) public data, + ) {} - ngOnInit() { - } + ngOnInit() {} loadData() { this.dialogRef.close({ - id: this.selectedID + id: this.selectedID, }); } diff --git a/src/app/dialogs/form-select-dialog/form-select-dialog.component.ts b/src/app/dialogs/form-select-dialog/form-select-dialog.component.ts index b3f18b7f8..76af04a26 100644 --- a/src/app/dialogs/form-select-dialog/form-select-dialog.component.ts +++ b/src/app/dialogs/form-select-dialog/form-select-dialog.component.ts @@ -1,16 +1,15 @@ -import {Component, Inject, OnInit} from '@angular/core'; -import {AdaptersService} from '../../services/adapters.service'; -import { MatDialogRef } from '@angular/material/dialog'; -import {has, omitBy, pickBy} from 'lodash-es'; -import {map} from 'rxjs/operators'; +import { Component, Inject, OnInit } from "@angular/core"; +import { AdaptersService } from "../../services/adapters.service"; +import { MatDialogRef } from "@angular/material/dialog"; +import { has, omitBy, pickBy } from "lodash-es"; +import { map } from "rxjs/operators"; @Component({ - selector: 'app-form-select-dialog', - templateUrl: './form-select-dialog.component.html', - styleUrls: ['./form-select-dialog.component.scss'] + selector: "app-form-select-dialog", + templateUrl: "./form-select-dialog.component.html", + styleUrls: ["./form-select-dialog.component.scss"], }) export class FormSelectDialogComponent implements OnInit { - adapters$; selectedAdapter; selectedForm; @@ -18,19 +17,20 @@ export class FormSelectDialogComponent implements OnInit { constructor( private readonly adapters: AdaptersService, public dialogRef: MatDialogRef, - ) { } + ) {} ngOnInit() { - this.adapters$ = this.adapters.adapters$ - .pipe(map((adapters) => { - return pickBy(adapters, config => has(config, 'adapter.forms')); - })); + this.adapters$ = this.adapters.adapters$.pipe( + map((adapters) => { + return pickBy(adapters, (config) => has(config, "adapter.forms")); + }), + ); } loadForm() { this.dialogRef.close({ adapterId: this.selectedAdapter, - formId: this.selectedForm + formId: this.selectedForm, }); } diff --git a/src/app/dialogs/import-progress-dialog/import-progress-dialog.component.ts b/src/app/dialogs/import-progress-dialog/import-progress-dialog.component.ts index 2ae08271a..41c956f9c 100644 --- a/src/app/dialogs/import-progress-dialog/import-progress-dialog.component.ts +++ b/src/app/dialogs/import-progress-dialog/import-progress-dialog.component.ts @@ -1,30 +1,29 @@ -import { Component, Inject, OnInit } from '@angular/core'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { interval } from 'rxjs'; -import { startWith, take } from 'rxjs/operators'; -import * as X2JS from 'x2js'; -import { DocumentRepositoryService } from '../../services/document-repository.service'; +import { Component, Inject, OnInit } from "@angular/core"; +import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; +import { interval } from "rxjs"; +import { startWith, take } from "rxjs/operators"; +import * as X2JS from "x2js"; +import { DocumentRepositoryService } from "../../services/document-repository.service"; @Component({ - selector: 'app-import-progress-dialog', - templateUrl: './import-progress-dialog.component.html', - styleUrls: ['./import-progress-dialog.component.scss'] + selector: "app-import-progress-dialog", + templateUrl: "./import-progress-dialog.component.html", + styleUrls: ["./import-progress-dialog.component.scss"], }) export class ImportProgressDialogComponent implements OnInit { - progress = 0; constructor( public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data, - private readonly docsRepo: DocumentRepositoryService - ) { } + private readonly docsRepo: DocumentRepositoryService, + ) {} ngOnInit() { const { content } = this.data; const defaultConfig = { - enableToStringFunc: false + enableToStringFunc: false, }; const config = {}; const x2js = new X2JS({ ...defaultConfig, ...config }); @@ -32,25 +31,25 @@ export class ImportProgressDialogComponent implements OnInit { const _r = x2js.xml2js(content); console.log(_r); - if (_r['RecordingInformationNotification'].ProjectList.Project.ProjectName) { + if ( + _r["RecordingInformationNotification"].ProjectList.Project.ProjectName + ) { const data = { - name: _r['RecordingInformationNotification'].ProjectList.Project.ProjectName, - json_data: _r + name: _r["RecordingInformationNotification"].ProjectList.Project + .ProjectName, + json_data: _r, }; - this.docsRepo.addNew('mrin_Project', data).subscribe(() => { - interval(10).pipe( - startWith(0), - take(100), - ).subscribe( - () => this.progress += 1, - err => console.log(err), - () => this.dialogRef.close() - ); + this.docsRepo.addNew("mrin_Project", data).subscribe(() => { + interval(10) + .pipe(startWith(0), take(100)) + .subscribe( + () => (this.progress += 1), + (err) => console.log(err), + () => this.dialogRef.close(), + ); }); } else { this.dialogRef.close(); } - } - } diff --git a/src/app/dialogs/load-workflow-dialog/load-workflow-dialog.component.ts b/src/app/dialogs/load-workflow-dialog/load-workflow-dialog.component.ts index d05cbcd48..d6eb877aa 100644 --- a/src/app/dialogs/load-workflow-dialog/load-workflow-dialog.component.ts +++ b/src/app/dialogs/load-workflow-dialog/load-workflow-dialog.component.ts @@ -1,33 +1,31 @@ -import { Component, OnInit } from '@angular/core'; -import { MatDialogRef } from '@angular/material/dialog'; -import {HttpClient} from '@angular/common/http'; -import {environment} from '../../../environments/environment'; +import { Component, OnInit } from "@angular/core"; +import { MatDialogRef } from "@angular/material/dialog"; +import { HttpClient } from "@angular/common/http"; +import { environment } from "../../../environments/environment"; @Component({ - selector: 'app-load-workflow-dialog', - templateUrl: './load-workflow-dialog.component.html', - styleUrls: ['./load-workflow-dialog.component.scss'] + selector: "app-load-workflow-dialog", + templateUrl: "./load-workflow-dialog.component.html", + styleUrls: ["./load-workflow-dialog.component.scss"], }) export class LoadWorkflowDialogComponent implements OnInit { - configs$; isLoading = false; constructor( public dialogRef: MatDialogRef, - private readonly http: HttpClient - ) { } + private readonly http: HttpClient, + ) {} ngOnInit() { const URL = `${environment.workflowStoreUrl}`; this.configs$ = this.http.get(URL); } - onLoad(id) { this.isLoading = true; const URL = `${environment.workflowStoreUrl}/${id}`; - this.http.get(URL).subscribe(response => { + this.http.get(URL).subscribe((response) => { this.isLoading = false; this.dialogRef.close(response); }); diff --git a/src/app/dialogs/paste-config-dialog/paste-config-dialog.component.ts b/src/app/dialogs/paste-config-dialog/paste-config-dialog.component.ts index 683b315fe..693db585a 100644 --- a/src/app/dialogs/paste-config-dialog/paste-config-dialog.component.ts +++ b/src/app/dialogs/paste-config-dialog/paste-config-dialog.component.ts @@ -1,17 +1,13 @@ -import { Component, OnInit } from '@angular/core'; -import { MatDialogRef } from '@angular/material/dialog'; +import { Component, OnInit } from "@angular/core"; +import { MatDialogRef } from "@angular/material/dialog"; @Component({ - selector: 'app-paste-config-dialog', - templateUrl: './paste-config-dialog.component.html', - styleUrls: ['./paste-config-dialog.component.scss'] + selector: "app-paste-config-dialog", + templateUrl: "./paste-config-dialog.component.html", + styleUrls: ["./paste-config-dialog.component.scss"], }) export class PasteConfigDialogComponent implements OnInit { + constructor(public dialogRef: MatDialogRef) {} - constructor( - public dialogRef: MatDialogRef - ) { } - - ngOnInit() { - } + ngOnInit() {} } diff --git a/src/app/dialogs/save-workflow-dialog/save-workflow-dialog.component.ts b/src/app/dialogs/save-workflow-dialog/save-workflow-dialog.component.ts index 348178dec..bd4ce3811 100644 --- a/src/app/dialogs/save-workflow-dialog/save-workflow-dialog.component.ts +++ b/src/app/dialogs/save-workflow-dialog/save-workflow-dialog.component.ts @@ -1,44 +1,43 @@ -import {Component, Inject, OnInit} from '@angular/core'; -import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; -import {HttpClient, HttpHeaders} from '@angular/common/http'; -import {has, get} from 'lodash-es'; -import {environment} from '../../../environments/environment'; +import { Component, Inject, OnInit } from "@angular/core"; +import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; +import { HttpClient, HttpHeaders } from "@angular/common/http"; +import { has, get } from "lodash-es"; +import { environment } from "../../../environments/environment"; @Component({ - selector: 'app-save-workflow-dialog', - templateUrl: './save-workflow-dialog.component.html', - styleUrls: ['./save-workflow-dialog.component.scss'] + selector: "app-save-workflow-dialog", + templateUrl: "./save-workflow-dialog.component.html", + styleUrls: ["./save-workflow-dialog.component.scss"], }) export class SaveWorkflowDialogComponent implements OnInit { - isLoading = false; isLoggedIn = false; - idToken = ''; + idToken = ""; get hasId() { - return !!get(this.data, 'id', false); + return !!get(this.data, "id", false); } constructor( public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data, - private readonly http: HttpClient - ) { } + private readonly http: HttpClient, + ) {} ngOnInit() { // TODO: The adapterName is not always updated, so for now check both possibilities - const idToken = localStorage.getItem('kendraio.variables.idToken'); + const idToken = localStorage.getItem("kendraio.variables.idToken"); if (idToken) { this.isLoggedIn = true; this.idToken = JSON.parse(idToken); return; } - const idToken2 = localStorage.getItem('UNKNOWN.variables.idToken'); + const idToken2 = localStorage.getItem("UNKNOWN.variables.idToken"); if (idToken2) { this.isLoggedIn = true; this.idToken = JSON.parse(idToken2); } - const idToken3 = localStorage.getItem('workflowCloud.variables.idToken'); + const idToken3 = localStorage.getItem("workflowCloud.variables.idToken"); if (idToken3) { this.isLoggedIn = true; this.idToken = JSON.parse(idToken3); @@ -48,10 +47,13 @@ export class SaveWorkflowDialogComponent implements OnInit { onSave() { this.isLoading = true; const URL = `${environment.workflowStoreUrl}`; - const headers = new HttpHeaders().append('authorization', `Bearer ${this.idToken}`); - this.http.put(URL, this.data, { headers }).subscribe(response => { + const headers = new HttpHeaders().append( + "authorization", + `Bearer ${this.idToken}`, + ); + this.http.put(URL, this.data, { headers }).subscribe((response) => { this.isLoading = false; - if (has(response, 'id')) { + if (has(response, "id")) { this.dialogRef.close(response); } else { this.dialogRef.close(); @@ -64,10 +66,13 @@ export class SaveWorkflowDialogComponent implements OnInit { this.isLoading = true; const { id, adapterName } = this.data; const URL = `${environment.workflowStoreUrl}/${adapterName}/${id}`; - const headers = new HttpHeaders().append('authorization', `Bearer ${this.idToken}`); - this.http.post(URL, this.data, { headers }).subscribe(response => { + const headers = new HttpHeaders().append( + "authorization", + `Bearer ${this.idToken}`, + ); + this.http.post(URL, this.data, { headers }).subscribe((response) => { this.isLoading = false; - if (get(response, 'status') === 'ok') { + if (get(response, "status") === "ok") { this.dialogRef.close(response); } else { this.dialogRef.close(); diff --git a/src/app/dialogs/show-share-link-dialog/show-share-link-dialog.component.ts b/src/app/dialogs/show-share-link-dialog/show-share-link-dialog.component.ts index 82546a7af..c3d163ac7 100644 --- a/src/app/dialogs/show-share-link-dialog/show-share-link-dialog.component.ts +++ b/src/app/dialogs/show-share-link-dialog/show-share-link-dialog.component.ts @@ -1,23 +1,22 @@ -import { Component, Inject, OnInit, ViewChild } from '@angular/core'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, Inject, OnInit, ViewChild } from "@angular/core"; +import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; @Component({ - selector: 'app-show-share-link-dialog', - templateUrl: './show-share-link-dialog.component.html', - styleUrls: ['./show-share-link-dialog.component.scss'] + selector: "app-show-share-link-dialog", + templateUrl: "./show-share-link-dialog.component.html", + styleUrls: ["./show-share-link-dialog.component.scss"], }) export class ShowShareLinkDialogComponent implements OnInit { + flowShareLink = ""; + dbShareLink = ""; + shareMode = ""; - flowShareLink = ''; - dbShareLink = ''; - shareMode = ''; - - @ViewChild('textBox') textBox; + @ViewChild("textBox") textBox; constructor( public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data, - ) { } + ) {} ngOnInit() { this.flowShareLink = this.data.flowShareLink; @@ -27,9 +26,8 @@ export class ShowShareLinkDialogComponent implements OnInit { copyText() { this.textBox.nativeElement.focus(); this.textBox.nativeElement.select(); - window.document.execCommand('copy'); + window.document.execCommand("copy"); // TODO: consider the more new API: // navigator.clipboard.writeText(this.shareLink); } - } diff --git a/src/app/dialogs/swagger-form-select-dialog/swagger-form-select-dialog.component.ts b/src/app/dialogs/swagger-form-select-dialog/swagger-form-select-dialog.component.ts index 057b7f705..62e59dfeb 100644 --- a/src/app/dialogs/swagger-form-select-dialog/swagger-form-select-dialog.component.ts +++ b/src/app/dialogs/swagger-form-select-dialog/swagger-form-select-dialog.component.ts @@ -1,19 +1,18 @@ -import { Component, OnInit } from '@angular/core'; -import {AdaptersService} from '../../services/adapters.service'; -import { MatDialogRef } from '@angular/material/dialog'; -import {map, switchMap, tap} from 'rxjs/operators'; -import {has, pickBy} from 'lodash-es'; -import {forkJoin} from 'rxjs'; -import {HttpClient} from '@angular/common/http'; -import {environment} from '../../../environments/environment'; +import { Component, OnInit } from "@angular/core"; +import { AdaptersService } from "../../services/adapters.service"; +import { MatDialogRef } from "@angular/material/dialog"; +import { map, switchMap, tap } from "rxjs/operators"; +import { has, pickBy } from "lodash-es"; +import { forkJoin } from "rxjs"; +import { HttpClient } from "@angular/common/http"; +import { environment } from "../../../environments/environment"; @Component({ - selector: 'app-swagger-form-select-dialog', - templateUrl: './swagger-form-select-dialog.component.html', - styleUrls: ['./swagger-form-select-dialog.component.scss'] + selector: "app-swagger-form-select-dialog", + templateUrl: "./swagger-form-select-dialog.component.html", + styleUrls: ["./swagger-form-select-dialog.component.scss"], }) export class SwaggerFormSelectDialogComponent implements OnInit { - adapters$; selectedAdapter; selectedForm; @@ -23,35 +22,43 @@ export class SwaggerFormSelectDialogComponent implements OnInit { constructor( private readonly http: HttpClient, private readonly adapters: AdaptersService, - public dialogRef: MatDialogRef - ) { } + public dialogRef: MatDialogRef, + ) {} ngOnInit() { - this.adapters$ = this.adapters.adapters$ - .pipe( - // tap(console.log), - map((adapters) => { - return pickBy(adapters, config => has(config, 'adapter.swagger')); - }), - map((adapters) => { - return Object.keys(adapters) - .map(adapterName => ({ adapterName, swagger: adapters[adapterName]['adapter'].swagger })); - }), - switchMap(adapters => { - return forkJoin(adapters.map(({ adapterName, swagger }) => - this.http.get(`${environment.adapterBaseUrl}${swagger}`).pipe(map(result => ({ adapterName, result }))))); - }), - map(adapters => adapters.reduce((a, { adapterName, result }) => { + this.adapters$ = this.adapters.adapters$.pipe( + // tap(console.log), + map((adapters) => { + return pickBy(adapters, (config) => has(config, "adapter.swagger")); + }), + map((adapters) => { + return Object.keys(adapters).map((adapterName) => ({ + adapterName, + swagger: adapters[adapterName]["adapter"].swagger, + })); + }), + switchMap((adapters) => { + return forkJoin( + adapters.map(({ adapterName, swagger }) => + this.http + .get(`${environment.adapterBaseUrl}${swagger}`) + .pipe(map((result) => ({ adapterName, result }))), + ), + ); + }), + map((adapters) => + adapters.reduce((a, { adapterName, result }) => { a[adapterName] = result; return a; - }, {})), - // tap(console.log), - tap(s => this._swaggers = s) - ); + }, {}), + ), + // tap(console.log), + tap((s) => (this._swaggers = s)), + ); } loadForm() { - const definitions = this._swaggers[this.selectedAdapter]['definitions']; + const definitions = this._swaggers[this.selectedAdapter]["definitions"]; this.dialogRef.close({ ...definitions[this.selectedForm], definitions }); } diff --git a/src/app/dialogs/test-import-dialog/test-import-dialog.component.ts b/src/app/dialogs/test-import-dialog/test-import-dialog.component.ts index 37efbd5b2..8420c82b7 100644 --- a/src/app/dialogs/test-import-dialog/test-import-dialog.component.ts +++ b/src/app/dialogs/test-import-dialog/test-import-dialog.component.ts @@ -1,41 +1,42 @@ -import {Component, Inject, OnInit} from '@angular/core'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import {forkJoin, interval} from 'rxjs'; -import {startWith, take} from 'rxjs/operators'; -import {DocumentRepositoryService} from '../../services/document-repository.service'; +import { Component, Inject, OnInit } from "@angular/core"; +import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; +import { forkJoin, interval } from "rxjs"; +import { startWith, take } from "rxjs/operators"; +import { DocumentRepositoryService } from "../../services/document-repository.service"; @Component({ - selector: 'app-test-import-dialog', - templateUrl: './test-import-dialog.component.html', - styleUrls: ['./test-import-dialog.component.scss'] + selector: "app-test-import-dialog", + templateUrl: "./test-import-dialog.component.html", + styleUrls: ["./test-import-dialog.component.scss"], }) export class TestImportDialogComponent implements OnInit { - progress = 0; - importType = ''; + importType = ""; constructor( public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data, - private readonly docsRepo: DocumentRepositoryService - ) { - } + private readonly docsRepo: DocumentRepositoryService, + ) {} ngOnInit() { - const { content: { type, records } } = this.data; + const { + content: { type, records }, + } = this.data; this.importType = type; - const schemaType = type.startsWith('bloomen_') ? type : `kendraio_${type}`; - forkJoin(records.map(item => this.docsRepo.addNew(schemaType, { type, ...item }))) - .subscribe(() => { - interval(10).pipe( - startWith(0), - take(100), - ).subscribe( - () => this.progress += 1, - err => console.log(err), - () => this.dialogRef.close() + const schemaType = type.startsWith("bloomen_") ? type : `kendraio_${type}`; + forkJoin( + records.map((item) => + this.docsRepo.addNew(schemaType, { type, ...item }), + ), + ).subscribe(() => { + interval(10) + .pipe(startWith(0), take(100)) + .subscribe( + () => (this.progress += 1), + (err) => console.log(err), + () => this.dialogRef.close(), ); - }); + }); } - } diff --git a/src/app/form-controls/audio-input-control/audio-input-control.component.ts b/src/app/form-controls/audio-input-control/audio-input-control.component.ts index e84e8b971..6f0666c7a 100644 --- a/src/app/form-controls/audio-input-control/audio-input-control.component.ts +++ b/src/app/form-controls/audio-input-control/audio-input-control.component.ts @@ -1,61 +1,65 @@ -import { Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; -import { ControlValueAccessor, UntypedFormControl, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { Subject } from 'rxjs'; -import { blobToDataURL } from 'blob-util'; -import { MatDialog } from '@angular/material/dialog'; -import { EditClipDialogComponent } from '../../dialogs/edit-clip-dialog/edit-clip-dialog.component'; -import { ConfirmDeleteDialogComponent } from '../../dialogs/confirm-delete-dialog/confirm-delete-dialog.component'; -import { WaveformComponent } from '../../components/waveform/waveform.component'; -import {map, startWith} from 'rxjs/operators'; +import { Component, Input, OnDestroy, OnInit, ViewChild } from "@angular/core"; +import { + ControlValueAccessor, + UntypedFormControl, + NG_VALUE_ACCESSOR, +} from "@angular/forms"; +import { Subject } from "rxjs"; +import { blobToDataURL } from "blob-util"; +import { MatDialog } from "@angular/material/dialog"; +import { EditClipDialogComponent } from "../../dialogs/edit-clip-dialog/edit-clip-dialog.component"; +import { ConfirmDeleteDialogComponent } from "../../dialogs/confirm-delete-dialog/confirm-delete-dialog.component"; +import { WaveformComponent } from "../../components/waveform/waveform.component"; +import { map, startWith } from "rxjs/operators"; @Component({ - selector: 'app-audio-input-control', - templateUrl: './audio-input-control.component.html', - styleUrls: ['./audio-input-control.component.scss'], + selector: "app-audio-input-control", + templateUrl: "./audio-input-control.component.html", + styleUrls: ["./audio-input-control.component.scss"], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: AudioInputControlComponent, - multi: true - } - ] + multi: true, + }, + ], }) -export class AudioInputControlComponent implements OnInit, OnDestroy, ControlValueAccessor { - +export class AudioInputControlComponent + implements OnInit, OnDestroy, ControlValueAccessor +{ @Input() placeholder: string; destroy$ = new Subject(); - data = [ - ]; + data = []; src; file: Blob; @Input() clipControl: UntypedFormControl; - @ViewChild('player') player: WaveformComponent; + @ViewChild("player") player: WaveformComponent; isPlaying = false; clipValues; - constructor( - private readonly dialog: MatDialog - ) { } + constructor(private readonly dialog: MatDialog) {} ngOnInit() { this.clipValues = this.clipControl.valueChanges.pipe( startWith(this.clipControl.value), - map(this.chartData) + map(this.chartData), ); } chartData(clips) { return { - datasets: [{ - data: clips.map(({ start, end }) => end - start), - backgroundColor: ['red', 'yellow', 'pink', 'blue', 'green', 'purple'] - }], - labels: clips.map(({ name }) => name) + datasets: [ + { + data: clips.map(({ start, end }) => end - start), + backgroundColor: ["red", "yellow", "pink", "blue", "green", "purple"], + }, + ], + labels: clips.map(({ name }) => name), }; } @@ -66,11 +70,11 @@ export class AudioInputControlComponent implements OnInit, OnDestroy, ControlVal } } - _onValueChanged = v => {}; + _onValueChanged = (v) => {}; valueChanged(file) { this.file = file; - blobToDataURL(file).then(dataUrl => this.src = dataUrl); + blobToDataURL(file).then((dataUrl) => (this.src = dataUrl)); this._onValueChanged(file); } @@ -89,21 +93,19 @@ export class AudioInputControlComponent implements OnInit, OnDestroy, ControlVal this._onValueChanged = fn; } - registerOnTouched(fn: any): void { - } + registerOnTouched(fn: any): void {} - setDisabledState(isDisabled: boolean): void { - } + setDisabledState(isDisabled: boolean): void {} writeValue(file: any): void { this.file = file; if (file) { - blobToDataURL(file).then(dataUrl => this.src = dataUrl); + blobToDataURL(file).then((dataUrl) => (this.src = dataUrl)); } } add(name) { - if (name.trim() !== '') { + if (name.trim() !== "") { this.data.push({ name, start: 0, end: 100 }); const clips = this.clipControl.value as Array; clips.push({ name, start: 0, end: 100 }); @@ -121,12 +123,12 @@ export class AudioInputControlComponent implements OnInit, OnDestroy, ControlVal const dialogRef = this.dialog.open(ConfirmDeleteDialogComponent, { data: { item: { - type: 'Clip', - name: (this.clipControl.value as Array)[i].name - } - } + type: "Clip", + name: (this.clipControl.value as Array)[i].name, + }, + }, }); - dialogRef.afterClosed().subscribe(result => { + dialogRef.afterClosed().subscribe((result) => { if (result) { const clips = this.clipControl.value as Array; clips.splice(i, 1); @@ -139,10 +141,10 @@ export class AudioInputControlComponent implements OnInit, OnDestroy, ControlVal const clip = (this.clipControl.value as Array)[i]; const dialogRef = this.dialog.open(EditClipDialogComponent, { data: { - clip - } + clip, + }, }); - dialogRef.afterClosed().subscribe(result => { + dialogRef.afterClosed().subscribe((result) => { if (result) { const clips = this.clipControl.value as Array; clips[i] = result; diff --git a/src/app/form-controls/formly-workflow-field/formly-workflow-field.component.ts b/src/app/form-controls/formly-workflow-field/formly-workflow-field.component.ts index 53ce56819..c3abf8e70 100644 --- a/src/app/form-controls/formly-workflow-field/formly-workflow-field.component.ts +++ b/src/app/form-controls/formly-workflow-field/formly-workflow-field.component.ts @@ -1,9 +1,13 @@ -import { Component, OnInit } from '@angular/core'; -import {FieldArrayType, FormlyFieldConfig, FormlyFormBuilder} from '@ngx-formly/core'; -import {AddBlockDialogComponent} from '../../dialogs/add-block-dialog/add-block-dialog.component'; -import { MatDialog } from '@angular/material/dialog'; -import {UntypedFormArray} from '@angular/forms'; -import {EDITOR_OPTIONS} from '../../components/block-builder-box/editor-options'; +import { Component, OnInit } from "@angular/core"; +import { + FieldArrayType, + FormlyFieldConfig, + FormlyFormBuilder, +} from "@ngx-formly/core"; +import { AddBlockDialogComponent } from "../../dialogs/add-block-dialog/add-block-dialog.component"; +import { MatDialog } from "@angular/material/dialog"; +import { UntypedFormArray } from "@angular/forms"; +import { EDITOR_OPTIONS } from "../../components/block-builder-box/editor-options"; export class WorkflowType { name: string; @@ -17,28 +21,27 @@ export interface WorkflowFieldConfig extends FormlyFieldConfig { } @Component({ - selector: 'app-formly-workflow-field', - templateUrl: './formly-workflow-field.component.html', - styleUrls: ['./formly-workflow-field.component.scss'] + selector: "app-formly-workflow-field", + templateUrl: "./formly-workflow-field.component.html", + styleUrls: ["./formly-workflow-field.component.scss"], }) -export class FormlyWorkflowFieldComponent extends FieldArrayType implements OnInit { - +export class FormlyWorkflowFieldComponent + extends FieldArrayType + implements OnInit +{ editorOptions = EDITOR_OPTIONS; - constructor( - private readonly dialog: MatDialog - ) { + constructor(private readonly dialog: MatDialog) { super(); } - ngOnInit() { - } + ngOnInit() {} addTask() { const dialogRef = this.dialog.open(AddBlockDialogComponent, { - width: '460px' + width: "460px", }); - dialogRef.afterClosed().subscribe(newTask => { + dialogRef.afterClosed().subscribe((newTask) => { if (!!newTask) { this.add(null, newTask); } diff --git a/src/app/pages/blocks-builder-page/blocks-builder-page.component.ts b/src/app/pages/blocks-builder-page/blocks-builder-page.component.ts index 1e7cf1e30..8a3f24b73 100644 --- a/src/app/pages/blocks-builder-page/blocks-builder-page.component.ts +++ b/src/app/pages/blocks-builder-page/blocks-builder-page.component.ts @@ -1,41 +1,36 @@ -import {Component, OnInit} from '@angular/core'; -import {clone, get, has, isArray} from 'lodash-es'; -import {moveItemInArray} from '@angular/cdk/drag-drop'; -import {ShareLinkGeneratorService} from '../../services/share-link-generator.service'; -import {AdaptersService} from '../../services/adapters.service'; -import {filter, take} from 'rxjs/operators'; -import { MatDialog } from '@angular/material/dialog'; -import {AdapterBlocksConfigSelectDialogComponent} from - '../../dialogs/adapter-blocks-config-select-dialog/adapter-blocks-config-select-dialog.component'; -import {ExportConfigDialogComponent} from '../../dialogs/export-config-dialog/export-config-dialog.component'; -import {PasteConfigDialogComponent} from '../../dialogs/paste-config-dialog/paste-config-dialog.component'; -import * as stringify from 'json-stringify-safe'; -import {PageTitleService} from '../../services/page-title.service'; -import {AddBlockDialogComponent} from '../../dialogs/add-block-dialog/add-block-dialog.component'; -import {WorkflowService} from '../../services/workflow.service'; +import { Component, OnInit } from "@angular/core"; +import { clone, get, has, isArray } from "lodash-es"; +import { moveItemInArray } from "@angular/cdk/drag-drop"; +import { ShareLinkGeneratorService } from "../../services/share-link-generator.service"; +import { AdaptersService } from "../../services/adapters.service"; +import { filter, take } from "rxjs/operators"; +import { MatDialog } from "@angular/material/dialog"; +import { AdapterBlocksConfigSelectDialogComponent } from "../../dialogs/adapter-blocks-config-select-dialog/adapter-blocks-config-select-dialog.component"; +import { ExportConfigDialogComponent } from "../../dialogs/export-config-dialog/export-config-dialog.component"; +import { PasteConfigDialogComponent } from "../../dialogs/paste-config-dialog/paste-config-dialog.component"; +import * as stringify from "json-stringify-safe"; +import { PageTitleService } from "../../services/page-title.service"; +import { AddBlockDialogComponent } from "../../dialogs/add-block-dialog/add-block-dialog.component"; +import { WorkflowService } from "../../services/workflow.service"; @Component({ - selector: 'app-blocks-builder-page', - templateUrl: './blocks-builder-page.component.html', - styleUrls: ['./blocks-builder-page.component.scss'] + selector: "app-blocks-builder-page", + templateUrl: "./blocks-builder-page.component.html", + styleUrls: ["./blocks-builder-page.component.scss"], }) export class BlocksBuilderPageComponent implements OnInit { - constructor( public readonly workflow: WorkflowService, private readonly shareLinks: ShareLinkGeneratorService, private readonly adapters: AdaptersService, private readonly dialog: MatDialog, - private readonly pageTitle: PageTitleService - ) { } + private readonly pageTitle: PageTitleService, + ) {} ngOnInit() { - this.pageTitle.setTitle('Flow', true); - this.adapters.adaptersReady$.pipe( - filter(Boolean), - take(1) - ).subscribe(() => this.workflow.initBlocks({ isBuilder: true })); + this.pageTitle.setTitle("Flow", true); + this.adapters.adaptersReady$ + .pipe(filter(Boolean), take(1)) + .subscribe(() => this.workflow.initBlocks({ isBuilder: true })); } - - } diff --git a/src/app/pages/bloomen-test-page/bloomen-test-page.component.ts b/src/app/pages/bloomen-test-page/bloomen-test-page.component.ts index ce2e2e9a0..dbeb61b66 100644 --- a/src/app/pages/bloomen-test-page/bloomen-test-page.component.ts +++ b/src/app/pages/bloomen-test-page/bloomen-test-page.component.ts @@ -1,45 +1,46 @@ -import { Component, OnInit } from '@angular/core'; -import {HttpClient} from '@angular/common/http'; -import {tap} from 'rxjs/operators'; -import {TestImportDialogComponent} from '../../dialogs/test-import-dialog/test-import-dialog.component'; -import {PageTitleService} from '../../services/page-title.service'; -import { MatDialog } from '@angular/material/dialog'; -import {Router} from '@angular/router'; -import {omit} from 'lodash-es'; +import { Component, OnInit } from "@angular/core"; +import { HttpClient } from "@angular/common/http"; +import { tap } from "rxjs/operators"; +import { TestImportDialogComponent } from "../../dialogs/test-import-dialog/test-import-dialog.component"; +import { PageTitleService } from "../../services/page-title.service"; +import { MatDialog } from "@angular/material/dialog"; +import { Router } from "@angular/router"; +import { omit } from "lodash-es"; -const BLOOMEN_URL = 'https://bloomen.herokuapp.com'; // no trailing slash +const BLOOMEN_URL = "https://bloomen.herokuapp.com"; // no trailing slash @Component({ - selector: 'app-bloomen-test-page', - templateUrl: './bloomen-test-page.component.html', - styleUrls: ['./bloomen-test-page.component.scss'] + selector: "app-bloomen-test-page", + templateUrl: "./bloomen-test-page.component.html", + styleUrls: ["./bloomen-test-page.component.scss"], }) export class BloomenTestPageComponent implements OnInit { - keys = { - Publisher: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.' + - 'eyJ1c2VyIjp7InJvbGUiOiJwdWJsaXNoZXIiLCJyZXB1dGF0aW9uIjp7InBvc2l0aXZlI' + - 'jowLCJuZWdhdGl2ZSI6MH0sInNldHRpbmdzIjp7ImF0dHJpYnV0aW9uIjp0cnVlfSwia3l' + - 'jIjp7ImFkZHJlc3MiOiIiLCJwaG9uZSI6IiIsImZpcnN0bmFtZSI6IiIsImxhc3RuYW1lIj' + - 'oiIiwiaWQxIjoiIiwiaWQyIjoiIiwic3RhdHVzIjowLCJyZXZpZXdlZEJ5IjoiIn0sIl9pZC' + - 'I6IjViYjQ5MDI5NGRkN2ExMmNhYzQxYTU3NSIsInVzZXJuYW1lIjoicHVibGlzaGVyIiwiaGF' + - 'zaCI6IjUyYWRlZDE2NTM2MDM1MmEwZjU4NTc1NzFkOTZkNjhmIiwiZW1haWwiOiJwdWJsaXNoZ' + - 'XJAYXRjLmdyIiwib3JnYW5pc2F0aW9uIjoiQVRDIiwiY3JlYXRlZEF0VVRDIjoiMjAxOC0xMC0w' + - 'M1QwOTo0NzoyMS4zMDlaIiwiX192IjowLCJvcmciOm51bGwsImlkIjoiNWJiNDkwMjk0ZGQ3YTEy' + - 'Y2FjNDFhNTc1In0sImlhdCI6MTU1MDU4MTk0Nn0.jxCWK2avRtvmuh0rdeg8z0iu1sG4JaBfkI_gZDNx1Co', - Photographer: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.' + - 'eyJ1c2VyIjp7InJvbGUiOiJwaG90b2dyYXBoZXIiLCJyZXB1dGF0aW9uIjp7InBvc2l0aX' + - 'ZlIjo3LCJuZWdhdGl2ZSI6MH0sInNldHRpbmdzIjp7ImF0dHJpYnV0aW9uIjp0cnVlfSwia' + - '3ljIjp7ImFkZHJlc3MiOiIiLCJwaG9uZSI6IiIsImZpcnN0bmFtZSI6IiIsImxhc3RuYW1lI' + - 'joiIiwiaWQxIjoiIiwiaWQyIjoiIiwic3RhdHVzIjowLCJyZXZpZXdlZEJ5IjoiIn0sIl9pZC' + - 'I6IjViYjM1ZmE2ZWIwNDMxMWE1YzYwNjA0MCIsInVzZXJuYW1lIjoicGhvdG9ncmFwaGVyIiwi' + - 'aGFzaCI6ImFiNWIwMzgxN2NhYTAxYzRhMmEwZWFkY2ZlNjQ4NjljIiwiZW1haWwiOiJwaG90b2d' + - 'yYXBoZXJAdGVzdC5jb20iLCJvcmdhbmlzYXRpb24iOiJwaG90b2dyYXBoZXIiLCJjcmVhdGVkQXR' + - 'VVEMiOiIyMDE4LTEwLTAyVDEyOjA4OjA2LjEyMloiLCJfX3YiOjB9LCJpYXQiOjE1NTA1MDM2NTR9' + - '.LThaEsPkrDkvlvKMw276PHlEsl430yNDAPATFi9sNw8' + Publisher: + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9." + + "eyJ1c2VyIjp7InJvbGUiOiJwdWJsaXNoZXIiLCJyZXB1dGF0aW9uIjp7InBvc2l0aXZlI" + + "jowLCJuZWdhdGl2ZSI6MH0sInNldHRpbmdzIjp7ImF0dHJpYnV0aW9uIjp0cnVlfSwia3l" + + "jIjp7ImFkZHJlc3MiOiIiLCJwaG9uZSI6IiIsImZpcnN0bmFtZSI6IiIsImxhc3RuYW1lIj" + + "oiIiwiaWQxIjoiIiwiaWQyIjoiIiwic3RhdHVzIjowLCJyZXZpZXdlZEJ5IjoiIn0sIl9pZC" + + "I6IjViYjQ5MDI5NGRkN2ExMmNhYzQxYTU3NSIsInVzZXJuYW1lIjoicHVibGlzaGVyIiwiaGF" + + "zaCI6IjUyYWRlZDE2NTM2MDM1MmEwZjU4NTc1NzFkOTZkNjhmIiwiZW1haWwiOiJwdWJsaXNoZ" + + "XJAYXRjLmdyIiwib3JnYW5pc2F0aW9uIjoiQVRDIiwiY3JlYXRlZEF0VVRDIjoiMjAxOC0xMC0w" + + "M1QwOTo0NzoyMS4zMDlaIiwiX192IjowLCJvcmciOm51bGwsImlkIjoiNWJiNDkwMjk0ZGQ3YTEy" + + "Y2FjNDFhNTc1In0sImlhdCI6MTU1MDU4MTk0Nn0.jxCWK2avRtvmuh0rdeg8z0iu1sG4JaBfkI_gZDNx1Co", + Photographer: + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9." + + "eyJ1c2VyIjp7InJvbGUiOiJwaG90b2dyYXBoZXIiLCJyZXB1dGF0aW9uIjp7InBvc2l0aX" + + "ZlIjo3LCJuZWdhdGl2ZSI6MH0sInNldHRpbmdzIjp7ImF0dHJpYnV0aW9uIjp0cnVlfSwia" + + "3ljIjp7ImFkZHJlc3MiOiIiLCJwaG9uZSI6IiIsImZpcnN0bmFtZSI6IiIsImxhc3RuYW1lI" + + "joiIiwiaWQxIjoiIiwiaWQyIjoiIiwic3RhdHVzIjowLCJyZXZpZXdlZEJ5IjoiIn0sIl9pZC" + + "I6IjViYjM1ZmE2ZWIwNDMxMWE1YzYwNjA0MCIsInVzZXJuYW1lIjoicGhvdG9ncmFwaGVyIiwi" + + "aGFzaCI6ImFiNWIwMzgxN2NhYTAxYzRhMmEwZWFkY2ZlNjQ4NjljIiwiZW1haWwiOiJwaG90b2d" + + "yYXBoZXJAdGVzdC5jb20iLCJvcmdhbmlzYXRpb24iOiJwaG90b2dyYXBoZXIiLCJjcmVhdGVkQXR" + + "VVEMiOiIyMDE4LTEwLTAyVDEyOjA4OjA2LjEyMloiLCJfX3YiOjB9LCJpYXQiOjE1NTA1MDM2NTR9" + + ".LThaEsPkrDkvlvKMw276PHlEsl430yNDAPATFi9sNw8", }; - activeUser = 'Publisher'; + activeUser = "Publisher"; userInfo$; @@ -47,31 +48,34 @@ export class BloomenTestPageComponent implements OnInit { private readonly http: HttpClient, private readonly router: Router, private readonly pageTitle: PageTitleService, - private readonly dialog: MatDialog + private readonly dialog: MatDialog, ) { - this.pageTitle.setTitle('Bloomen API'); + this.pageTitle.setTitle("Bloomen API"); } - ngOnInit() { - } + ngOnInit() {} login() { console.log(`Login as ${this.activeUser}`); - this.userInfo$ = this.http.get(`${BLOOMEN_URL}/me`, { - headers: { Authorization: `Bearer ${this.keys[this.activeUser]}` } - }).pipe(tap(console.log)); + this.userInfo$ = this.http + .get(`${BLOOMEN_URL}/me`, { + headers: { Authorization: `Bearer ${this.keys[this.activeUser]}` }, + }) + .pipe(tap(console.log)); } importUsers() { - this.http.get(`${BLOOMEN_URL}/users/kyc`, { - headers: { Authorization: `Bearer ${this.keys[this.activeUser]}` } - }).pipe(tap(console.log)) - .subscribe(users => { + this.http + .get(`${BLOOMEN_URL}/users/kyc`, { + headers: { Authorization: `Bearer ${this.keys[this.activeUser]}` }, + }) + .pipe(tap(console.log)) + .subscribe((users) => { if (users) { - const type = 'bloomen_User'; - const records = users.map(user => { + const type = "bloomen_User"; + const records = users.map((user) => { return { - ...omit(user, ['__v', '_id']), + ...omit(user, ["__v", "_id"]), }; }); this.doImport({ type, records }); @@ -80,16 +84,18 @@ export class BloomenTestPageComponent implements OnInit { } importPhotos() { - this.http.get(`${BLOOMEN_URL}/photos`, { - headers: { Authorization: `Bearer ${this.keys[this.activeUser]}` } - }).pipe(tap(console.log)) - .subscribe(photos => { + this.http + .get(`${BLOOMEN_URL}/photos`, { + headers: { Authorization: `Bearer ${this.keys[this.activeUser]}` }, + }) + .pipe(tap(console.log)) + .subscribe((photos) => { if (photos) { - const type = 'bloomen_Photo'; - const records = photos.map(photo => { + const type = "bloomen_Photo"; + const records = photos.map((photo) => { return { - ...omit(photo, ['__v', '_id']), - url: photo['url'] ? photo.url.replace('http://', 'https://') : '' + ...omit(photo, ["__v", "_id"]), + url: photo["url"] ? photo.url.replace("http://", "https://") : "", }; }); this.doImport({ type, records }); @@ -100,10 +106,10 @@ export class BloomenTestPageComponent implements OnInit { doImport(content) { const dialogRef = this.dialog.open(TestImportDialogComponent, { disableClose: true, - data: {content} + data: { content }, }); dialogRef.afterClosed().subscribe(() => { - this.router.navigate(['/docs']); + this.router.navigate(["/docs"]); }); } } diff --git a/src/app/pages/docs-list-page/docs-list-page.component.ts b/src/app/pages/docs-list-page/docs-list-page.component.ts index 9bae2d8bf..7ba965248 100644 --- a/src/app/pages/docs-list-page/docs-list-page.component.ts +++ b/src/app/pages/docs-list-page/docs-list-page.component.ts @@ -1,28 +1,27 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit } from "@angular/core"; import { DocumentRepositoryService } from "../../services/document-repository.service"; -import { PageTitleService } from '../../services/page-title.service'; -import { Router } from '@angular/router'; -import { MatDialog } from '@angular/material/dialog'; -import { ConfirmDeleteDialogComponent } from '../../dialogs/confirm-delete-dialog/confirm-delete-dialog.component'; +import { PageTitleService } from "../../services/page-title.service"; +import { Router } from "@angular/router"; +import { MatDialog } from "@angular/material/dialog"; +import { ConfirmDeleteDialogComponent } from "../../dialogs/confirm-delete-dialog/confirm-delete-dialog.component"; @Component({ - selector: 'app-docs-list-page', - templateUrl: './docs-list-page.component.html', - styleUrls: ['./docs-list-page.component.scss'] + selector: "app-docs-list-page", + templateUrl: "./docs-list-page.component.html", + styleUrls: ["./docs-list-page.component.scss"], }) export class DocsListPageComponent implements OnInit { - docs$; constructor( private readonly pageTitle: PageTitleService, private readonly router: Router, private readonly docsRepo: DocumentRepositoryService, - private readonly dialog: MatDialog - ) { } + private readonly dialog: MatDialog, + ) {} ngOnInit() { - this.pageTitle.setTitle('Dashboard'); + this.pageTitle.setTitle("Dashboard"); this.docs$ = this.docsRepo.listAll(); } @@ -30,15 +29,15 @@ export class DocsListPageComponent implements OnInit { const dialogRef = this.dialog.open(ConfirmDeleteDialogComponent, { data: { item: { - type: doc.id.split(':')[0], - name: doc.key - } - } + type: doc.id.split(":")[0], + name: doc.key, + }, + }, }); - dialogRef.afterClosed().subscribe(result => { + dialogRef.afterClosed().subscribe((result) => { if (result) { - this.docsRepo.deleteDoc(doc.id).subscribe(({ok}) => { - console.log(`Deleted: ${ ok }`); + this.docsRepo.deleteDoc(doc.id).subscribe(({ ok }) => { + console.log(`Deleted: ${ok}`); this.docs$ = this.docsRepo.listAll(); }); } @@ -46,6 +45,6 @@ export class DocsListPageComponent implements OnInit { } addContent() { - this.router.navigate(['/import']); + this.router.navigate(["/import"]); } } diff --git a/src/app/pages/form-builder-page/form-builder-page.component.html b/src/app/pages/form-builder-page/form-builder-page.component.html index f306033ed..38523067c 100644 --- a/src/app/pages/form-builder-page/form-builder-page.component.html +++ b/src/app/pages/form-builder-page/form-builder-page.component.html @@ -1,40 +1,79 @@
- - - - - - -
-
JSON Schema - + UI Schema - +
Model Output
@@ -44,18 +83,45 @@ {{ errorMessage }} - +
- - - - + + + +
-
+    
 
 
-
-
diff --git a/src/app/pages/form-builder-page/form-builder-page.component.ts b/src/app/pages/form-builder-page/form-builder-page.component.ts index 9b3e19474..86fb7a41e 100644 --- a/src/app/pages/form-builder-page/form-builder-page.component.ts +++ b/src/app/pages/form-builder-page/form-builder-page.component.ts @@ -1,34 +1,39 @@ -import {Component, ElementRef, OnDestroy, OnInit, ViewChild} from '@angular/core'; -import {UntypedFormGroup} from '@angular/forms'; -import {FormlyFieldConfig, FormlyFormOptions} from '@ngx-formly/core'; -import {KendraioFormService} from '../../_shared/ui-form/services/kendraio.form.service'; -import {FormSubmitHandlerService} from '../../services/form-submit-handler.service'; -import {ShareLinkGeneratorService} from '../../services/share-link-generator.service'; -import {Subject} from 'rxjs'; -import {debounceTime, takeUntil} from 'rxjs/operators'; -import JSONFormatter from 'json-formatter-js'; -import {JSON_SCHEMA} from './jsonschema'; -import { MonacoEditorModule } from 'ngx-monaco-editor-v2'; -import {UI_SCHEMA} from './uischema'; -import {EDITOR_OPTIONS} from './editor-options'; -import {AdapterFormSelectService} from '../../services/adapter-form-select.service'; -import {FormDataService} from '../../services/form-data.service'; -import {clone, get, has} from 'lodash-es'; -import {PageTitleService} from '../../services/page-title.service'; +import { + Component, + ElementRef, + OnDestroy, + OnInit, + ViewChild, +} from "@angular/core"; +import { UntypedFormGroup } from "@angular/forms"; +import { FormlyFieldConfig, FormlyFormOptions } from "@ngx-formly/core"; +import { KendraioFormService } from "../../_shared/ui-form/services/kendraio.form.service"; +import { FormSubmitHandlerService } from "../../services/form-submit-handler.service"; +import { ShareLinkGeneratorService } from "../../services/share-link-generator.service"; +import { Subject } from "rxjs"; +import { debounceTime, takeUntil } from "rxjs/operators"; +import JSONFormatter from "json-formatter-js"; +import { JSON_SCHEMA } from "./jsonschema"; +import { MonacoEditorModule } from "ngx-monaco-editor-v2"; +import { UI_SCHEMA } from "./uischema"; +import { EDITOR_OPTIONS } from "./editor-options"; +import { AdapterFormSelectService } from "../../services/adapter-form-select.service"; +import { FormDataService } from "../../services/form-data.service"; +import { clone, get, has } from "lodash-es"; +import { PageTitleService } from "../../services/page-title.service"; @Component({ - selector: 'app-form-builder-page', - templateUrl: './form-builder-page.component.html', - styleUrls: ['./form-builder-page.component.scss'] + selector: "app-form-builder-page", + templateUrl: "./form-builder-page.component.html", + styleUrls: ["./form-builder-page.component.scss"], }) export class FormBuilderPageComponent implements OnInit, OnDestroy { - editorOptions = EDITOR_OPTIONS; - JSONSchema = '{}'; + JSONSchema = "{}"; jsonModel: MonacoEditorModule; - UISchema = '{}'; + UISchema = "{}"; uiModel: MonacoEditorModule; form = new UntypedFormGroup({}); @@ -45,12 +50,12 @@ export class FormBuilderPageComponent implements OnInit, OnDestroy { showFormConfig = false; hasError = false; - errorMessage = ''; + errorMessage = ""; isAPIData = false; - endpoint = ''; + endpoint = ""; - @ViewChild('modelOutput') modelOutput: ElementRef; + @ViewChild("modelOutput") modelOutput: ElementRef; constructor( private formService: KendraioFormService, @@ -58,27 +63,28 @@ export class FormBuilderPageComponent implements OnInit, OnDestroy { private shareLinks: ShareLinkGeneratorService, private formSelect: AdapterFormSelectService, private formData: FormDataService, - private readonly pageTitle: PageTitleService - ) { - } + private readonly pageTitle: PageTitleService, + ) {} ngOnInit() { - this.pageTitle.setTitle('formBuilder.pageTitle'); - this._schemaChange$.pipe( - takeUntil(this._destroy$), - debounceTime(500) - ).subscribe(() => { - try { - this.hasError = false; - const JSONSchema = JSON.parse(this.JSONSchema); - this.isDbForm = has(JSONSchema, 'name'); - this.fields = this.formService.schemasToFieldConfig(JSONSchema, JSON.parse(this.UISchema)); - } catch ({message}) { - this.hasError = true; - this.errorMessage = message; - this.fields = []; - } - }); + this.pageTitle.setTitle("formBuilder.pageTitle"); + this._schemaChange$ + .pipe(takeUntil(this._destroy$), debounceTime(500)) + .subscribe(() => { + try { + this.hasError = false; + const JSONSchema = JSON.parse(this.JSONSchema); + this.isDbForm = has(JSONSchema, "name"); + this.fields = this.formService.schemasToFieldConfig( + JSONSchema, + JSON.parse(this.UISchema), + ); + } catch ({ message }) { + this.hasError = true; + this.errorMessage = message; + this.fields = []; + } + }); const urlData = this.shareLinks.getData(); if (urlData) { @@ -88,7 +94,7 @@ export class FormBuilderPageComponent implements OnInit, OnDestroy { this.jsonSchemaChange(); } - setSchemaValues({JSONSchema, UISchema}) { + setSchemaValues({ JSONSchema, UISchema }) { this.JSONSchema = JSON.stringify(JSONSchema, null, 4); this.UISchema = JSON.stringify(UISchema, null, 4); } @@ -101,13 +107,13 @@ export class FormBuilderPageComponent implements OnInit, OnDestroy { updateEditorModels() { this.jsonModel = { value: this.JSONSchema, - language: 'json', - uri: 'a:jsonModel.json' + language: "json", + uri: "a:jsonModel.json", }; this.uiModel = { value: this.UISchema, - language: 'json', - uri: 'a:uiModel.json' + language: "json", + uri: "a:uiModel.json", }; } @@ -115,15 +121,18 @@ export class FormBuilderPageComponent implements OnInit, OnDestroy { const monaco = (window as any).monaco; monaco.languages.json.jsonDefaults.setDiagnosticsOptions({ validate: true, - schemas: [{ - fileMatch: ['a:jsonModel.json'], - uri: 'https://json-schema.org/draft-07/schema', - schema: JSON_SCHEMA - }, { - fileMatch: ['a:uiModel.json'], - uri: 'https://app.kendra.io/v0/ui-schema', - schema: UI_SCHEMA - }] + schemas: [ + { + fileMatch: ["a:jsonModel.json"], + uri: "https://json-schema.org/draft-07/schema", + schema: JSON_SCHEMA, + }, + { + fileMatch: ["a:uiModel.json"], + uri: "https://app.kendra.io/v0/ui-schema", + schema: UI_SCHEMA, + }, + ], }); } @@ -134,14 +143,16 @@ export class FormBuilderPageComponent implements OnInit, OnDestroy { shareForm() { const JSONSchema = JSON.parse(this.JSONSchema); const UISchema = JSON.parse(this.UISchema); - this.shareLinks.shareFlowLink('form-builder', {JSONSchema, UISchema}); + this.shareLinks.shareFlowLink("form-builder", { JSONSchema, UISchema }); } onChange() { // Replace #modelOutput DIV contents with formatted JSON const formatter = new JSONFormatter(this.model, Infinity); while (this.modelOutput.nativeElement.firstChild) { - this.modelOutput.nativeElement.removeChild(this.modelOutput.nativeElement.firstChild); + this.modelOutput.nativeElement.removeChild( + this.modelOutput.nativeElement.firstChild, + ); } this.modelOutput.nativeElement.append(formatter.render()); } @@ -150,8 +161,8 @@ export class FormBuilderPageComponent implements OnInit, OnDestroy { // Send form submit event to the form handler service this.formSubmitHandler.handle({ form: `formBuilderForm`, - action: 'submit', - payload: this.form.getRawValue() + action: "submit", + payload: this.form.getRawValue(), }); } @@ -160,12 +171,13 @@ export class FormBuilderPageComponent implements OnInit, OnDestroy { if (this.isDbForm) { const JSONSchema = JSON.parse(this.JSONSchema); this.saveOriginalDbValues(this.model); - this.formData.saveData(get(JSONSchema, 'name'), this.model) - .subscribe(({ok, id, rev}) => { + this.formData + .saveData(get(JSONSchema, "name"), this.model) + .subscribe(({ ok, id, rev }) => { // TODO: This logic is specific to DB and should not be here if (ok) { - this.model['_rev'] = rev; - this.model['_id'] = id; + this.model["_rev"] = rev; + this.model["_id"] = id; this.onChange(); } }); @@ -173,7 +185,7 @@ export class FormBuilderPageComponent implements OnInit, OnDestroy { } loadFromAdapter() { - this.formSelect.selectForm().subscribe(values => { + this.formSelect.selectForm().subscribe((values) => { if (!!values) { this.setSchemaValues(values); this.updateEditorModels(); @@ -183,7 +195,7 @@ export class FormBuilderPageComponent implements OnInit, OnDestroy { } loadFromSwagger() { - this.formSelect.selectSwagger().subscribe(values => { + this.formSelect.selectSwagger().subscribe((values) => { if (!!values) { this.setSchemaValues(values); this.updateEditorModels(); @@ -194,13 +206,13 @@ export class FormBuilderPageComponent implements OnInit, OnDestroy { saveOriginalDbValues(values) { // TODO: Deep copy to save original values? - this.originalDbValues = {...values}; + this.originalDbValues = { ...values }; } loadFromDatabase() { const data = JSON.parse(this.JSONSchema); - if (data && has(data, 'name')) { - this.formData.loadData(get(data, 'name')).subscribe(values => { + if (data && has(data, "name")) { + this.formData.loadData(get(data, "name")).subscribe((values) => { if (!!values) { this.isAPIData = false; this.saveOriginalDbValues(values); @@ -227,21 +239,24 @@ export class FormBuilderPageComponent implements OnInit, OnDestroy { } loadDataFromAPI() { - this.formData.loadDataFromAPI().subscribe(({ status, endpoint, values}) => { - if (!!status) { - // console.log({ values }); - this.saveOriginalDbValues(values); - this.model = values; - this.onChange(); - this.isAPIData = true; - this.endpoint = endpoint; - } - }); + this.formData + .loadDataFromAPI() + .subscribe(({ status, endpoint, values }) => { + if (!!status) { + // console.log({ values }); + this.saveOriginalDbValues(values); + this.model = values; + this.onChange(); + this.isAPIData = true; + this.endpoint = endpoint; + } + }); } onSaveAPI() { if (this.isAPIData) { - this.formData.saveAPIData(this.endpoint, this.model) + this.formData + .saveAPIData(this.endpoint, this.model) .subscribe((result) => { // TODO: Data update success // console.log({ result }); @@ -249,4 +264,3 @@ export class FormBuilderPageComponent implements OnInit, OnDestroy { } } } - diff --git a/src/app/pages/kql-builder/kql-builder.component.html b/src/app/pages/kql-builder/kql-builder.component.html index d0c6eccd3..3fec0b17f 100644 --- a/src/app/pages/kql-builder/kql-builder.component.html +++ b/src/app/pages/kql-builder/kql-builder.component.html @@ -1,15 +1,21 @@ -
+
-
- {{errorMessage}} +
+ {{ errorMessage }}
- +
- +
@@ -19,7 +25,9 @@
- +
- +
diff --git a/src/app/pages/kql-builder/kql-builder.component.ts b/src/app/pages/kql-builder/kql-builder.component.ts index 72a7450ff..50eab860a 100644 --- a/src/app/pages/kql-builder/kql-builder.component.ts +++ b/src/app/pages/kql-builder/kql-builder.component.ts @@ -1,81 +1,83 @@ -import {Component, NgZone, OnInit} from '@angular/core'; -import {JSON_EDITOR_OPTIONS} from './json-editor-options'; -import {KQL_EDITOR_OPTIONS} from './kql-editor-options'; -import { MonacoEditorModule } from 'ngx-monaco-editor-v2'; -import {mappingUtility} from '../../blocks/mapping-block/mapping-util'; -import {HttpClient} from '@angular/common/http'; -import {map, take} from 'rxjs/operators'; -import {camelCase, get, sortBy, set} from 'lodash-es'; -import {WorkflowService} from '../../services/workflow.service'; -import {SaveWorkflowDialogComponent} from '../../dialogs/save-workflow-dialog/save-workflow-dialog.component'; -import {MatDialog} from '@angular/material/dialog'; -import {ActivatedRoute, Router} from '@angular/router'; +import { Component, NgZone, OnInit } from "@angular/core"; +import { JSON_EDITOR_OPTIONS } from "./json-editor-options"; +import { KQL_EDITOR_OPTIONS } from "./kql-editor-options"; +import { MonacoEditorModule } from "ngx-monaco-editor-v2"; +import { mappingUtility } from "../../blocks/mapping-block/mapping-util"; +import { HttpClient } from "@angular/common/http"; +import { map, take } from "rxjs/operators"; +import { camelCase, get, sortBy, set } from "lodash-es"; +import { WorkflowService } from "../../services/workflow.service"; +import { SaveWorkflowDialogComponent } from "../../dialogs/save-workflow-dialog/save-workflow-dialog.component"; +import { MatDialog } from "@angular/material/dialog"; +import { ActivatedRoute, Router } from "@angular/router"; @Component({ - selector: 'app-kql-builder', - templateUrl: './kql-builder.component.html', - styleUrls: ['./kql-builder.component.scss'] + selector: "app-kql-builder", + templateUrl: "./kql-builder.component.html", + styleUrls: ["./kql-builder.component.scss"], }) export class KqlBuilderComponent implements OnInit { - jsonEditorOptions = JSON_EDITOR_OPTIONS; kqlEditorOptions = KQL_EDITOR_OPTIONS; - dataInTxt = JSON.stringify({ - 'employees': { - 'jd101': { - 'firstname': 'Jane', - 'surname': 'Doe', - 'department': 'IT', - 'manager': 'kp102' - }, - 'kp102': { - 'firstname': 'Kitty', - 'surname': 'Pride', - 'department': 'IT', - 'manager': 'jh104' + dataInTxt = JSON.stringify( + { + employees: { + jd101: { + firstname: "Jane", + surname: "Doe", + department: "IT", + manager: "kp102", + }, + kp102: { + firstname: "Kitty", + surname: "Pride", + department: "IT", + manager: "jh104", + }, + cx103: { + firstname: "Charles", + surname: "Xavier", + department: "Management", + }, + jh104: { + firstname: "James", + surname: "Howlett", + department: "Security", + manager: "cx103", + }, }, - 'cx103': { - 'firstname': 'Charles', - 'surname': 'Xavier', - 'department': 'Management' - }, - 'jh104': { - 'firstname': 'James', - 'surname': 'Howlett', - 'department': 'Security', - 'manager': 'cx103' - } - } - }, null, 2); + }, + null, + 2, + ); dataInModel: MonacoEditorModule; dataOut = {}; - queryTxt = 'data'; + queryTxt = "data"; queryModel: MonacoEditorModule; - errorMessage = ''; + errorMessage = ""; flows = []; selectedFlow; blockOptions = []; - blockLimit = '0'; + blockLimit = "0"; blockExec = []; startModels; context = {}; flowConfig = {}; selectedBlock = {}; - selectedBlockType = ''; + selectedBlockType = ""; constructor( private readonly http: HttpClient, private readonly zone: NgZone, private readonly dialog: MatDialog, - private readonly route: ActivatedRoute - ) { - } + private readonly route: ActivatedRoute, + ) {} ngOnInit() { this.getFlows(); @@ -84,27 +86,27 @@ export class KqlBuilderComponent implements OnInit { } async createDummyContext() { - this.route.queryParams.pipe( - take(1) - ).subscribe(queryParams => { - this.context = {...this.context, queryParams}; + this.route.queryParams.pipe(take(1)).subscribe((queryParams) => { + this.context = { ...this.context, queryParams }; }); } async getFlows() { - const url = 'https://app.kendra.io/api'; - this.flows = await this.http.get(url) - .pipe( - map(x => sortBy(x, 'title')) - ) + const url = "https://app.kendra.io/api"; + this.flows = await this.http + .get(url) + .pipe(map((x) => sortBy(x, "title"))) .toPromise(); } runMapping() { - this.errorMessage = ''; + this.errorMessage = ""; try { const data = JSON.parse(this.dataInTxt); - this.dataOut = mappingUtility({data, context: this.context }, this.queryTxt); + this.dataOut = mappingUtility( + { data, context: this.context }, + this.queryTxt, + ); } catch (e) { this.errorMessage = e.message; } @@ -112,14 +114,15 @@ export class KqlBuilderComponent implements OnInit { async updateBlockOptions(v) { this.blockOptions = []; - this.blockLimit = '0'; - const {adapterName, workflowId} = this.flows[+v]; - const {blocks, ...flowConfig} = await this.http.get(`https://app.kendra.io/api/${adapterName}/${workflowId}`) + this.blockLimit = "0"; + const { adapterName, workflowId } = this.flows[+v]; + const { blocks, ...flowConfig } = await this.http + .get(`https://app.kendra.io/api/${adapterName}/${workflowId}`) .toPromise(); this.blockOptions = blocks; this.flowConfig = flowConfig; this.context = { - app: {adapterName, workflowId} + app: { adapterName, workflowId }, }; await this.createDummyContext(); } @@ -128,13 +131,19 @@ export class KqlBuilderComponent implements OnInit { setTimeout(() => { this.zone.run(() => { this.selectedBlock = this.blockOptions[parseInt(this.blockLimit, 10)]; - this.selectedBlockType = get(this.selectedBlock, 'type', ''); - if (this.selectedBlockType === 'mapping') { - this.queryTxt = get(this.selectedBlock, 'mapping', 'data'); - this.blockExec = this.blockOptions.slice(0, parseInt(this.blockLimit, 10)); + this.selectedBlockType = get(this.selectedBlock, "type", ""); + if (this.selectedBlockType === "mapping") { + this.queryTxt = get(this.selectedBlock, "mapping", "data"); + this.blockExec = this.blockOptions.slice( + 0, + parseInt(this.blockLimit, 10), + ); this.startModels = this.blockExec.map(() => ({})); } else { - this.blockExec = this.blockOptions.slice(0, 1 + parseInt(this.blockLimit, 10)); + this.blockExec = this.blockOptions.slice( + 0, + 1 + parseInt(this.blockLimit, 10), + ); this.startModels = this.blockExec.map(() => ({})); } }); @@ -144,17 +153,20 @@ export class KqlBuilderComponent implements OnInit { saveBlocks() { // console.log(this.blockOptions); // const prevMapping = get(this.selectedBlock, 'mapping', 'data'); - set(this.blockOptions[parseInt(this.blockLimit, 10)], 'mapping', this.queryTxt); + set( + this.blockOptions[parseInt(this.blockLimit, 10)], + "mapping", + this.queryTxt, + ); const dialogRef = this.dialog.open(SaveWorkflowDialogComponent, { disableClose: true, - data: {...this.flowConfig, blocks: this.blockOptions} + data: { ...this.flowConfig, blocks: this.blockOptions }, }); - dialogRef.afterClosed().subscribe(values => { + dialogRef.afterClosed().subscribe((values) => { if (!!values) { - console.log('workflow saved', {values}); + console.log("workflow saved", { values }); } }); - } loadNewData(v) { @@ -179,8 +191,8 @@ export class KqlBuilderComponent implements OnInit { updateDataInModel() { this.dataInModel = { value: this.dataInTxt, - language: 'json', - uri: 'a:dataModel.json' + language: "json", + uri: "a:dataModel.json", }; } } diff --git a/src/app/pages/query-builder-page/query-builder-page.component.html b/src/app/pages/query-builder-page/query-builder-page.component.html index 315dbf900..816fcabd8 100644 --- a/src/app/pages/query-builder-page/query-builder-page.component.html +++ b/src/app/pages/query-builder-page/query-builder-page.component.html @@ -1,41 +1,60 @@ -/** -* DEPRECATED -* All functionality has been moved to the blocks builder -*/ +/** * DEPRECATED * All functionality has been moved to the blocks builder */
- - - -
-
Query Schema - + -
+
{{ errorMessage }}
-
+
Result output
-
+
Mapping output
@@ -46,14 +65,21 @@

{{ title }}

{{ description }}

- - + +
-
diff --git a/src/app/pages/query-builder-page/query-builder-page.component.ts b/src/app/pages/query-builder-page/query-builder-page.component.ts index ef91549ff..692ac198e 100644 --- a/src/app/pages/query-builder-page/query-builder-page.component.ts +++ b/src/app/pages/query-builder-page/query-builder-page.component.ts @@ -2,32 +2,37 @@ * DEPRECATED * All functionality has been moved to the blocks builder */ -import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core'; -import { EDITOR_OPTIONS } from './editor-options'; -import JSONFormatter from 'json-formatter-js'; -import {get, has, isString} from 'lodash-es'; -import {BehaviorSubject} from 'rxjs'; -import '@angular/material/tooltip'; -import { HttpClient, HttpHeaders } from '@angular/common/http'; -import {AdapterQuerySelectDialogComponent} from '../../dialogs/adapter-query-select-dialog/adapter-query-select-dialog.component'; -import {ShareLinkGeneratorService} from '../../services/share-link-generator.service'; -import { search } from 'jmespath'; -import {DocumentRepositoryService} from '../../services/document-repository.service'; -import {QUERY_SCHEMA} from './query.schema'; -import {map, tap} from 'rxjs/operators'; -import {ContextDataService} from '../../services/context-data.service'; -import {MatDialog} from '@angular/material/dialog'; +import { + AfterViewInit, + Component, + ElementRef, + OnInit, + ViewChild, +} from "@angular/core"; +import { EDITOR_OPTIONS } from "./editor-options"; +import JSONFormatter from "json-formatter-js"; +import { get, has, isString } from "lodash-es"; +import { BehaviorSubject } from "rxjs"; +import "@angular/material/tooltip"; +import { HttpClient, HttpHeaders } from "@angular/common/http"; +import { AdapterQuerySelectDialogComponent } from "../../dialogs/adapter-query-select-dialog/adapter-query-select-dialog.component"; +import { ShareLinkGeneratorService } from "../../services/share-link-generator.service"; +import { search } from "jmespath"; +import { DocumentRepositoryService } from "../../services/document-repository.service"; +import { QUERY_SCHEMA } from "./query.schema"; +import { map, tap } from "rxjs/operators"; +import { ContextDataService } from "../../services/context-data.service"; +import { MatDialog } from "@angular/material/dialog"; @Component({ - selector: 'app-query-builder-page', - templateUrl: './query-builder-page.component.html', - styleUrls: ['./query-builder-page.component.scss'] + selector: "app-query-builder-page", + templateUrl: "./query-builder-page.component.html", + styleUrls: ["./query-builder-page.component.scss"], }) export class QueryBuilderPageComponent implements OnInit, AfterViewInit { - showFormConfig = false; - title = ''; - description = ''; + title = ""; + description = ""; editorOptions = EDITOR_OPTIONS; @@ -35,54 +40,54 @@ export class QueryBuilderPageComponent implements OnInit, AfterViewInit { queryModel; output; - @ViewChild('modelOutput') modelOutput: ElementRef; + @ViewChild("modelOutput") modelOutput: ElementRef; showMappingResult = false; - @ViewChild('mappingOutput') mappingOutput: ElementRef; + @ViewChild("mappingOutput") mappingOutput: ElementRef; - @ViewChild('gridAngular') gridAngular; + @ViewChild("gridAngular") gridAngular; defaultColDef = { - resizable: true + resizable: true, }; columnDefs = []; - outputMapping = ''; + outputMapping = ""; - outputType = 'grid'; + outputType = "grid"; outputConfig; _rowData = new BehaviorSubject>([]); rowData = this._rowData.pipe( - map(values => { + map((values) => { if (!!this.outputMapping && this.outputMapping.length > 0) { try { const mappingResult = search(values, this.outputMapping); this.updateMappingResult(mappingResult); - setTimeout(() => this.showMappingResult = true, 0); + setTimeout(() => (this.showMappingResult = true), 0); return mappingResult; } catch (e) { - console.log('JMESPath Error', e.message); + console.log("JMESPath Error", e.message); } } - setTimeout(() => this.showMappingResult = false, 0); + setTimeout(() => (this.showMappingResult = false), 0); return values; }), tap(() => { if (!!this.gridAngular) { this.gridAngular.api.sizeColumnsToFit(); } - }) + }), ); hasError = false; - errorMessage = ''; + errorMessage = ""; constructor( private readonly http: HttpClient, private shareLinks: ShareLinkGeneratorService, private readonly dialog: MatDialog, private readonly docRepo: DocumentRepositoryService, - private readonly contextData: ContextDataService - ) { } + private readonly contextData: ContextDataService, + ) {} ngOnInit() { const urlData = this.shareLinks.getData(); @@ -91,8 +96,8 @@ export class QueryBuilderPageComponent implements OnInit, AfterViewInit { this.queryModelText = JSON.stringify(Q, null, 4); this.queryModel = { value: this.queryModelText, - language: 'json', - uri: 'a:queryModel.json' + language: "json", + uri: "a:queryModel.json", }; } this.runQuery(); @@ -106,26 +111,34 @@ export class QueryBuilderPageComponent implements OnInit, AfterViewInit { const monaco = (window as any).monaco; monaco.languages.json.jsonDefaults.setDiagnosticsOptions({ validate: true, - schemas: [{ - fileMatch: ['a:queryModel.json'], - uri: 'https://app.kendra.io/v0/query-schema', - schema: QUERY_SCHEMA - }] + schemas: [ + { + fileMatch: ["a:queryModel.json"], + uri: "https://app.kendra.io/v0/query-schema", + schema: QUERY_SCHEMA, + }, + ], }); } constructEndpointUrl(dataSource) { - if (isString(get(dataSource, 'endpoint', ''))) { + if (isString(get(dataSource, "endpoint", ""))) { return dataSource.endpoint; } const demoModel = {}; - const endpoint = this.contextData.getFromContextWithModel(dataSource.endpoint, demoModel); + const endpoint = this.contextData.getFromContextWithModel( + dataSource.endpoint, + demoModel, + ); // console.log({ endpoint }); - const protocol = get(endpoint, 'protocol', 'https:'); - const host = get(endpoint, 'host', ''); - const pathname = get(endpoint, 'pathname', '/'); - const query = get(endpoint, 'query', []); - const reduceQuery = _q => Object.keys(_q).map(key => `${key}=${_q[key]}`, []).join('&'); + const protocol = get(endpoint, "protocol", "https:"); + const host = get(endpoint, "host", ""); + const pathname = get(endpoint, "pathname", "/"); + const query = get(endpoint, "query", []); + const reduceQuery = (_q) => + Object.keys(_q) + .map((key) => `${key}=${_q[key]}`, []) + .join("&"); return `${protocol}//${host}${pathname}?${reduceQuery(query)}`; } @@ -134,58 +147,71 @@ export class QueryBuilderPageComponent implements OnInit, AfterViewInit { try { // Parse and validate model const query = JSON.parse(this.queryModelText); - this.outputConfig = get(query, 'output'); - this.outputType = get(query, 'output.type', 'grid'); - this.columnDefs = this.preprocessColumnDefinition(get(query, 'output.columnDefs', [])); - this.outputMapping = get(query, 'mapping', ''); - const { type, ...dataSource } = get(query, 'dataSource', { type: false }); - this.title = get(query, 'title', ''); - this.description = get(query, 'description', ''); + this.outputConfig = get(query, "output"); + this.outputType = get(query, "output.type", "grid"); + this.columnDefs = this.preprocessColumnDefinition( + get(query, "output.columnDefs", []), + ); + this.outputMapping = get(query, "mapping", ""); + const { type, ...dataSource } = get(query, "dataSource", { type: false }); + this.title = get(query, "title", ""); + this.description = get(query, "description", ""); // Run query switch (type) { - case 'local': + case "local": const { schema } = dataSource; - this.docRepo.listAllOfType(schema).subscribe(values => { + this.docRepo.listAllOfType(schema).subscribe((values) => { // console.log({ values }); this.output = values; this.updateOutputDisplay(); this._rowData.next(values || []); }); break; - case 'remote': + case "remote": const endpoint = this.constructEndpointUrl(dataSource); // console.log({ endpoint }); let headers = new HttpHeaders(); - if (has(dataSource, 'authentication.type')) { - switch (get(dataSource, 'authentication.type')) { - case 'basic-auth': - const valueGetters = get(dataSource, 'authentication.valueGetters', {}); - const context = { ...dataSource.authentication, ...this.contextData.getGlobalContext(valueGetters, {}) }; - if (has(context, 'username') && has(context, 'password')) { + if (has(dataSource, "authentication.type")) { + switch (get(dataSource, "authentication.type")) { + case "basic-auth": + const valueGetters = get( + dataSource, + "authentication.valueGetters", + {}, + ); + const context = { + ...dataSource.authentication, + ...this.contextData.getGlobalContext(valueGetters, {}), + }; + if (has(context, "username") && has(context, "password")) { const { username, password } = context; - headers = headers.append('Authorization', 'Basic ' + btoa(`${username}:${password}`)); + headers = headers.append( + "Authorization", + "Basic " + btoa(`${username}:${password}`), + ); } break; - case 'bearer': + case "bearer": break; default: - console.log('Unknown authentication type'); + console.log("Unknown authentication type"); } } - this.http.get>(endpoint, { headers }).subscribe(values => { - this.output = values; - this.updateOutputDisplay(); - this._rowData.next(values); - }); + this.http + .get>(endpoint, { headers }) + .subscribe((values) => { + this.output = values; + this.updateOutputDisplay(); + this._rowData.next(values); + }); break; default: this.hasError = true; - this.errorMessage = 'Unknown data source type'; + this.errorMessage = "Unknown data source type"; this._rowData.next([]); } // Update display - } catch ({ message }) { this.hasError = true; this.errorMessage = message; @@ -193,25 +219,31 @@ export class QueryBuilderPageComponent implements OnInit, AfterViewInit { } preprocessColumnDefinition(def: Array) { - return def.map(item => ({ + return def.map((item) => ({ ...item, - ...has(item, 'valueGetter') ? { valueGetter: ({ data }) => { - // console.log({ data, item }); - try { - return search(data, item['valueGetter']); - } catch (e) { - return e.message; - } - }} : {} + ...(has(item, "valueGetter") + ? { + valueGetter: ({ data }) => { + // console.log({ data, item }); + try { + return search(data, item["valueGetter"]); + } catch (e) { + return e.message; + } + }, + } + : {}), })); } updateOutputDisplay() { if (!!this.modelOutput) { // Replace #modelOutput DIV contents with formatted JSON - const formatter = new JSONFormatter(this.output, 0, {theme: 'dark'}); + const formatter = new JSONFormatter(this.output, 0, { theme: "dark" }); while (this.modelOutput.nativeElement.firstChild) { - this.modelOutput.nativeElement.removeChild(this.modelOutput.nativeElement.firstChild); + this.modelOutput.nativeElement.removeChild( + this.modelOutput.nativeElement.firstChild, + ); } this.modelOutput.nativeElement.append(formatter.render()); } @@ -219,9 +251,11 @@ export class QueryBuilderPageComponent implements OnInit, AfterViewInit { updateMappingResult(mappingResult) { if (!!this.mappingOutput && this.showMappingResult) { - const formatter = new JSONFormatter(mappingResult, 0, {theme: 'dark'}); + const formatter = new JSONFormatter(mappingResult, 0, { theme: "dark" }); while (this.mappingOutput.nativeElement.firstChild) { - this.mappingOutput.nativeElement.removeChild(this.mappingOutput.nativeElement.firstChild); + this.mappingOutput.nativeElement.removeChild( + this.mappingOutput.nativeElement.firstChild, + ); } this.mappingOutput.nativeElement.append(formatter.render()); } @@ -233,13 +267,13 @@ export class QueryBuilderPageComponent implements OnInit, AfterViewInit { loadQueryFromAdapter() { const dialogRef = this.dialog.open(AdapterQuerySelectDialogComponent, {}); - dialogRef.afterClosed().subscribe(data => { + dialogRef.afterClosed().subscribe((data) => { if (!!data) { this.queryModelText = JSON.stringify(data, null, 4); this.queryModel = { value: this.queryModelText, - language: 'json', - uri: 'a:queryModel.json' + language: "json", + uri: "a:queryModel.json", }; this.runQuery(); } @@ -248,6 +282,6 @@ export class QueryBuilderPageComponent implements OnInit, AfterViewInit { shareQuery() { const Q = JSON.parse(this.queryModelText); - this.shareLinks.shareFlowLink('query-builder', {Q}); + this.shareLinks.shareFlowLink("query-builder", { Q }); } } diff --git a/src/app/pages/settings-page/settings-page.component.ts b/src/app/pages/settings-page/settings-page.component.ts index 51ac421f8..0f6c64d29 100644 --- a/src/app/pages/settings-page/settings-page.component.ts +++ b/src/app/pages/settings-page/settings-page.component.ts @@ -1,19 +1,18 @@ -import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; -import { MatDialog } from '@angular/material/dialog'; -import { ConfirmAppResetDialogComponent } from '../../dialogs/confirm-app-reset-dialog/confirm-app-reset-dialog.component'; -import { PageTitleService } from '../../services/page-title.service'; -import { AdaptersService } from '../../services/adapters.service'; -import { DocumentRepositoryService } from '../../services/document-repository.service'; -import {AppSettingsService} from '../../services/app-settings.service'; +import { Component, OnInit } from "@angular/core"; +import { Router } from "@angular/router"; +import { MatDialog } from "@angular/material/dialog"; +import { ConfirmAppResetDialogComponent } from "../../dialogs/confirm-app-reset-dialog/confirm-app-reset-dialog.component"; +import { PageTitleService } from "../../services/page-title.service"; +import { AdaptersService } from "../../services/adapters.service"; +import { DocumentRepositoryService } from "../../services/document-repository.service"; +import { AppSettingsService } from "../../services/app-settings.service"; @Component({ - selector: 'app-settings-page', - templateUrl: './settings-page.component.html', - styleUrls: ['./settings-page.component.scss'] + selector: "app-settings-page", + templateUrl: "./settings-page.component.html", + styleUrls: ["./settings-page.component.scss"], }) export class SettingsPageComponent implements OnInit { - isDebug = false; showHelp = true; @@ -23,37 +22,36 @@ export class SettingsPageComponent implements OnInit { private readonly pageTitle: PageTitleService, private readonly adapters: AdaptersService, private readonly database: DocumentRepositoryService, - private readonly settings: AppSettingsService - ) { } + private readonly settings: AppSettingsService, + ) {} ngOnInit() { - this.pageTitle.setTitle('App settings'); - this.isDebug = this.settings.get('debugMode', false); - this.showHelp = this.settings.getTmp('showHelp', true); + this.pageTitle.setTitle("App settings"); + this.isDebug = this.settings.get("debugMode", false); + this.showHelp = this.settings.getTmp("showHelp", true); } // TODO: Remove any other data added to localStorage resetApp() { const dialogRef = this.dialog.open(ConfirmAppResetDialogComponent, { - width: '300px' + width: "300px", }); - dialogRef.afterClosed().subscribe(result => { + dialogRef.afterClosed().subscribe((result) => { if (result) { this.adapters.resetApp(); this.database.resetApp(); - this.router.navigate(['/']); + this.router.navigate(["/"]); } }); } toggleDebugMode() { this.isDebug = !this.isDebug; - this.settings.set('debugMode', this.isDebug); + this.settings.set("debugMode", this.isDebug); } toggleShowHelp() { this.showHelp = !this.showHelp; - this.settings.set('showHelp', this.showHelp); + this.settings.set("showHelp", this.showHelp); } - } diff --git a/src/app/pages/test-api-page/test-api-page.component.ts b/src/app/pages/test-api-page/test-api-page.component.ts index d360c16c3..c9a43ff06 100644 --- a/src/app/pages/test-api-page/test-api-page.component.ts +++ b/src/app/pages/test-api-page/test-api-page.component.ts @@ -1,20 +1,27 @@ -import {Component, OnInit} from '@angular/core'; -import {TestDataService} from '../../services/test-data.service'; -import {forkJoin, Observable, of, Subject} from 'rxjs'; -import {catchError, map, mergeMap, switchMap, take, tap, withLatestFrom} from 'rxjs/operators'; -import {ImportProgressDialogComponent} from '../../dialogs/import-progress-dialog/import-progress-dialog.component'; -import {Router} from '@angular/router'; -import {PageTitleService} from '../../services/page-title.service'; -import { MatDialog } from '@angular/material/dialog'; -import {TestImportDialogComponent} from '../../dialogs/test-import-dialog/test-import-dialog.component'; +import { Component, OnInit } from "@angular/core"; +import { TestDataService } from "../../services/test-data.service"; +import { forkJoin, Observable, of, Subject } from "rxjs"; +import { + catchError, + map, + mergeMap, + switchMap, + take, + tap, + withLatestFrom, +} from "rxjs/operators"; +import { ImportProgressDialogComponent } from "../../dialogs/import-progress-dialog/import-progress-dialog.component"; +import { Router } from "@angular/router"; +import { PageTitleService } from "../../services/page-title.service"; +import { MatDialog } from "@angular/material/dialog"; +import { TestImportDialogComponent } from "../../dialogs/test-import-dialog/test-import-dialog.component"; @Component({ - selector: 'app-test-api-page', - templateUrl: './test-api-page.component.html', - styleUrls: ['./test-api-page.component.scss'] + selector: "app-test-api-page", + templateUrl: "./test-api-page.component.html", + styleUrls: ["./test-api-page.component.scss"], }) export class TestApiPageComponent implements OnInit { - entityTypes$; selectedType; @@ -31,19 +38,20 @@ export class TestApiPageComponent implements OnInit { private readonly router: Router, private readonly pageTitle: PageTitleService, private readonly dialog: MatDialog, - ) { - } + ) {} ngOnInit() { this.entityTypes$ = this.testData.listEntityTypes({ live: true }); this.entityList$ = new Subject().pipe( - switchMap(type => this.testData.listEntities(type, { live: true })) + switchMap((type) => this.testData.listEntities(type, { live: true })), ); this.selectedEntity$ = new Subject().pipe( - switchMap(id => this.testData.getEntity(this.selectedType, id, { live: true })) + switchMap((id) => + this.testData.getEntity(this.selectedType, id, { live: true }), + ), ); this.listAll$ = new Subject().pipe( - switchMap(type => this.testData.listAll(type, { live: true })) + switchMap((type) => this.testData.listAll(type, { live: true })), ); } @@ -65,18 +73,24 @@ export class TestApiPageComponent implements OnInit { (this.testData.listEntityTypes({ live: true }) as Observable) .pipe( take(1), - map(types => types.filter(type => type !== 'video' && type !== 'photo')), - mergeMap(types => forkJoin(types.map(type => { - return this.testData.listAll(type, { live: true }).pipe( - take(1), - catchError(err => of([])), - map(records => ({ type, records })) - ); - }))) + map((types) => + types.filter((type) => type !== "video" && type !== "photo"), + ), + mergeMap((types) => + forkJoin( + types.map((type) => { + return this.testData.listAll(type, { live: true }).pipe( + take(1), + catchError((err) => of([])), + map((records) => ({ type, records })), + ); + }), + ), + ), ) - .subscribe(allItems => { + .subscribe((allItems) => { this.isLoadingAll = false; - allItems.map(content => { + allItems.map((content) => { this.doImport(content); }); }); @@ -84,20 +98,23 @@ export class TestApiPageComponent implements OnInit { importAll() { const type = this.selectedType; - this.testData.listAll(type, { live: true }).pipe(take(1)).subscribe(records => { - if (records) { - this.doImport({ type, records }); - } - }); + this.testData + .listAll(type, { live: true }) + .pipe(take(1)) + .subscribe((records) => { + if (records) { + this.doImport({ type, records }); + } + }); } doImport(content) { const dialogRef = this.dialog.open(TestImportDialogComponent, { disableClose: true, - data: {content} + data: { content }, }); dialogRef.afterClosed().subscribe(() => { - this.router.navigate(['/docs']); + this.router.navigate(["/docs"]); }); } } diff --git a/src/app/pages/upload-page/upload-page.component.ts b/src/app/pages/upload-page/upload-page.component.ts index 356fff0cf..e41d00586 100644 --- a/src/app/pages/upload-page/upload-page.component.ts +++ b/src/app/pages/upload-page/upload-page.component.ts @@ -1,17 +1,16 @@ -import { Component, OnInit } from '@angular/core'; -import { PageTitleService } from '../../services/page-title.service'; -import {from, interval} from 'rxjs'; -import { take, tap } from 'rxjs/operators'; -import { forkJoin } from 'rxjs'; -import { MatSnackBar } from '@angular/material/snack-bar'; +import { Component, OnInit } from "@angular/core"; +import { PageTitleService } from "../../services/page-title.service"; +import { from, interval } from "rxjs"; +import { take, tap } from "rxjs/operators"; +import { forkJoin } from "rxjs"; +import { MatSnackBar } from "@angular/material/snack-bar"; @Component({ - selector: 'app-upload-page', - templateUrl: './upload-page.component.html', - styleUrls: ['./upload-page.component.scss'] + selector: "app-upload-page", + templateUrl: "./upload-page.component.html", + styleUrls: ["./upload-page.component.scss"], }) export class UploadPageComponent implements OnInit { - adapters$; uploadStatus = {}; uploadEnabled = {}; @@ -21,962 +20,989 @@ export class UploadPageComponent implements OnInit { bloomen: true, mixcloud: true, ddex: true, - 'copyright-hub': true, + "copyright-hub": true, unsplash: true, dotbc: true, chant: true, - 'apple-music': true, + "apple-music": true, youtube: true, teosto: true, spotify: true, schema: true, - 'ppl-ipn': true, + "ppl-ipn": true, bandcamp: true, - 'm-rin': true, + "m-rin": true, example: true, resonate: true, tidal: true, omi: true, kendraio: true, - soundcloud: true + soundcloud: true, }; constructor( private readonly pageTitle: PageTitleService, - private readonly snackBar: MatSnackBar - ) { } + private readonly snackBar: MatSnackBar, + ) {} ngOnInit() { - this.pageTitle.setTitle('Upload'); + this.pageTitle.setTitle("Upload"); this.adapters$ = from([ { - 'bloomen': { - 'adapter': { - 'name': 'bloomen', - 'title': 'Bloomen', - 'description': 'Integration with the Bloomen project', - 'infoUrl': 'http://bloomen.io/', - 'maintainer': 'Kendraio', - 'supportUrl': 'http://kendra.io', - 'uploads': true, - 'swagger': 'extra/bloomen/api-docs.json', - 'database': [ - 'extra/bloomen/schemas/user.schema.json', - 'extra/bloomen/schemas/photo.schema.json' + bloomen: { + adapter: { + name: "bloomen", + title: "Bloomen", + description: "Integration with the Bloomen project", + infoUrl: "http://bloomen.io/", + maintainer: "Kendraio", + supportUrl: "http://kendra.io", + uploads: true, + swagger: "extra/bloomen/api-docs.json", + database: [ + "extra/bloomen/schemas/user.schema.json", + "extra/bloomen/schemas/photo.schema.json", ], - 'forms': { - 'musicalWork': { - 'jsonSchema': 'extra/bloomen/schemas/musicalWork.schema.json', - 'uiSchema': 'extra/bloomen/schemas/musicalWork.ui.json' - }, - 'soundRecording': { - 'jsonSchema': 'extra/bloomen/schemas/soundRecording.schema.json', - 'uiSchema': 'extra/bloomen/schemas/soundRecording.ui.json' - }, - 'user': { - 'jsonSchema': 'extra/bloomen/schemas/user.schema.json', - 'uiSchema': 'extra/bloomen/schemas/user.ui.json' - }, - 'photo': { - 'jsonSchema': 'extra/bloomen/schemas/photo.schema.json', - 'uiSchema': 'extra/bloomen/schemas/photo.ui.json' - } + forms: { + musicalWork: { + jsonSchema: "extra/bloomen/schemas/musicalWork.schema.json", + uiSchema: "extra/bloomen/schemas/musicalWork.ui.json", + }, + soundRecording: { + jsonSchema: "extra/bloomen/schemas/soundRecording.schema.json", + uiSchema: "extra/bloomen/schemas/soundRecording.ui.json", + }, + user: { + jsonSchema: "extra/bloomen/schemas/user.schema.json", + uiSchema: "extra/bloomen/schemas/user.ui.json", + }, + photo: { + jsonSchema: "extra/bloomen/schemas/photo.schema.json", + uiSchema: "extra/bloomen/schemas/photo.ui.json", + }, }, - 'queries': [ - 'extra/bloomen/queries/listSoundRecordings.json', - 'extra/bloomen/queries/listMusicalWorks.json', - 'extra/bloomen/queries/chartReleases.json' + queries: [ + "extra/bloomen/queries/listSoundRecordings.json", + "extra/bloomen/queries/listMusicalWorks.json", + "extra/bloomen/queries/chartReleases.json", + ], + configs: [ + "extra/bloomen/configs/listSoundRecordings.json", + "extra/bloomen/configs/listMusicalWorks.json", + "extra/bloomen/configs/chartReleases.json", + "extra/bloomen/configs/editSoundRecording.json", + "extra/bloomen/configs/messageExample.json", + "extra/bloomen/configs/templateExample.json", + "extra/bloomen/configs/dialogExample.json", + "extra/bloomen/configs/bloomenApiJwt-musicalWorks.json", + "extra/bloomen/configs/bloomenApiJwt-soundRecordings.json", + "extra/bloomen/configs/bloomenApiJwt-exportMusicalWorks.json", + "extra/bloomen/configs/photo-search-example.json", + "extra/bloomen/configs/importMusicalWorks.json", + "extra/bloomen/configs/listSoundRecordings-view-edit.json", ], - 'configs': [ - 'extra/bloomen/configs/listSoundRecordings.json', - 'extra/bloomen/configs/listMusicalWorks.json', - 'extra/bloomen/configs/chartReleases.json', - 'extra/bloomen/configs/editSoundRecording.json', - 'extra/bloomen/configs/messageExample.json', - 'extra/bloomen/configs/templateExample.json', - 'extra/bloomen/configs/dialogExample.json', - 'extra/bloomen/configs/bloomenApiJwt-musicalWorks.json', - 'extra/bloomen/configs/bloomenApiJwt-soundRecordings.json', - 'extra/bloomen/configs/bloomenApiJwt-exportMusicalWorks.json', - 'extra/bloomen/configs/photo-search-example.json', - 'extra/bloomen/configs/importMusicalWorks.json', - 'extra/bloomen/configs/listSoundRecordings-view-edit.json' - ] - } + }, }, - 'mixcloud': { - 'adapter': { - 'name': 'mixcloud', - 'title': 'MixCloud', - 'description': 'Upload your mix, radio show or Podcast to Mixcloud for free', - 'infoUrl': 'https://www.mixcloud.com/', - 'maintainer': 'Kendraio', - 'supportUrl': 'http://kendra.io', - 'uploads': true - } + mixcloud: { + adapter: { + name: "mixcloud", + title: "MixCloud", + description: + "Upload your mix, radio show or Podcast to Mixcloud for free", + infoUrl: "https://www.mixcloud.com/", + maintainer: "Kendraio", + supportUrl: "http://kendra.io", + uploads: true, + }, }, - 'ddex': { - 'adapter': { - 'name': 'ddex', - 'title': 'DDEX', - 'description': 'Implementation of schemas for DDEX messages', - 'infoUrl': 'https://ddex.net/', - 'maintainer': 'Kendraio', - 'supportUrl': 'https://kendra.io', - 'uploads': false, - 'configs': [ - 'extra/ddex/ern4-import.json' - ] - } + ddex: { + adapter: { + name: "ddex", + title: "DDEX", + description: "Implementation of schemas for DDEX messages", + infoUrl: "https://ddex.net/", + maintainer: "Kendraio", + supportUrl: "https://kendra.io", + uploads: false, + configs: ["extra/ddex/ern4-import.json"], + }, }, - 'copyright-hub': { - 'adapter': { - 'name': 'copyright-hub', - 'title': 'Copyright Hub', + "copyright-hub": { + adapter: { + name: "copyright-hub", + title: "Copyright Hub", // tslint:disable-next-line:max-line-length - 'description': 'The Copyright Hub aims to help copyright work the way the internet works by making the process of giving and getting permission – the basic building block of the copyright process – fit for purpose in the age of the Internet.', - 'infoUrl': 'http://www.copyrighthub.org', - 'maintainer': 'Kendraio', - 'supportUrl': 'http://kendra.io', - 'uploads': true - } + description: + "The Copyright Hub aims to help copyright work the way the internet works by making the process of giving and getting permission – the basic building block of the copyright process – fit for purpose in the age of the Internet.", + infoUrl: "http://www.copyrighthub.org", + maintainer: "Kendraio", + supportUrl: "http://kendra.io", + uploads: true, + }, }, - 'unsplash': { - 'adapter': { - 'name': 'unsplash', - 'title': 'Unsplash', + unsplash: { + adapter: { + name: "unsplash", + title: "Unsplash", // tslint:disable-next-line:max-line-length - 'description': 'Beautiful high quality free images and photos you can download and use for any project. No attribution required.', - 'infoUrl': 'https://unsplash.com/', - 'maintainer': 'Kendraio', - 'supportUrl': 'http://kendra.io', - 'uploads': true, - 'swagger': 'extra/unsplash/swagger.json' - } + description: + "Beautiful high quality free images and photos you can download and use for any project. No attribution required.", + infoUrl: "https://unsplash.com/", + maintainer: "Kendraio", + supportUrl: "http://kendra.io", + uploads: true, + swagger: "extra/unsplash/swagger.json", + }, }, - 'dotbc': { - 'adapter': { - 'name': 'dotbc', - 'title': 'dotBC', - 'description': 'dotBC is a new dynamic file format and supporting technology architecture, ' + - 'designed to modernize rights management of media files globally for all participants', - 'infoUrl': 'https://dotblockchainmusic.com/', - 'maintainer': 'Kendraio', - 'supportUrl': 'http://kendra.io', - 'uploads': true - } + dotbc: { + adapter: { + name: "dotbc", + title: "dotBC", + description: + "dotBC is a new dynamic file format and supporting technology architecture, " + + "designed to modernize rights management of media files globally for all participants", + infoUrl: "https://dotblockchainmusic.com/", + maintainer: "Kendraio", + supportUrl: "http://kendra.io", + uploads: true, + }, }, - 'chant': { - 'adapter': { - 'name': 'chant', - 'title': 'Chant', - 'description': 'An adapter for Chant specific features', - 'infoUrl': 'https://chant.world/', - 'maintainer': 'Kendraio', - 'supportUrl': 'https://www.kendra.io', - 'uploads': true, - 'forms': { - 'gig': { - 'jsonSchema': 'extra/chant/schemas/gig.json', - 'uiSchema': 'extra/chant/schemas/gig-ui.json' - }, - 'chant': { - 'jsonSchema': 'extra/chant/schemas/chant.json', - 'uiSchema': 'extra/chant/schemas/chant-ui.json' - } + chant: { + adapter: { + name: "chant", + title: "Chant", + description: "An adapter for Chant specific features", + infoUrl: "https://chant.world/", + maintainer: "Kendraio", + supportUrl: "https://www.kendra.io", + uploads: true, + forms: { + gig: { + jsonSchema: "extra/chant/schemas/gig.json", + uiSchema: "extra/chant/schemas/gig-ui.json", + }, + chant: { + jsonSchema: "extra/chant/schemas/chant.json", + uiSchema: "extra/chant/schemas/chant-ui.json", + }, }, - 'actions': [ + actions: [ { - 'title': 'Add/Edit Gig', - 'path': 'extra/chant/workflow/edit-gig.txt' + title: "Add/Edit Gig", + path: "extra/chant/workflow/edit-gig.txt", }, { - 'title': 'Upload Chant', - 'path': 'extra/chant/workflow/upload-chant.txt' - } - ] - } + title: "Upload Chant", + path: "extra/chant/workflow/upload-chant.txt", + }, + ], + }, }, - 'apple-music': { - 'adapter': { - 'name': 'apple-music', - 'title': 'Apple Music', - 'description': 'Stream 45 million songs, ad-free on Apple Music. Shop HomePod, ' + - 'AirPods and headphones. And build your entertainment collection with iPod and iTunes.', - 'infoUrl': 'https://www.apple.com/uk/music/', - 'maintainer': 'Kendraio', - 'supportUrl': 'http://kendra.io', - 'uploads': true - } + "apple-music": { + adapter: { + name: "apple-music", + title: "Apple Music", + description: + "Stream 45 million songs, ad-free on Apple Music. Shop HomePod, " + + "AirPods and headphones. And build your entertainment collection with iPod and iTunes.", + infoUrl: "https://www.apple.com/uk/music/", + maintainer: "Kendraio", + supportUrl: "http://kendra.io", + uploads: true, + }, }, - 'youtube': { - 'adapter': { - 'name': 'youtube', - 'title': 'YouTube', - 'description': 'Enjoy the videos and music you love, upload original content,' + - ' and share it all with friends, family, and the world on YouTube.', - 'infoUrl': 'https://www.youtube.com/', - 'maintainer': 'Kendraio', - 'supportUrl': 'http://kendra.io', - 'uploads': true, - 'forms': { - 'basic': { - 'jsonSchema': 'extra/youtube/schemas/youtube-edit-video-basic.json', - 'uiSchema': 'extra/youtube/schemas/youtube-edit-video-basic-ui.json' - }, - 'advanced': { - 'jsonSchema': 'extra/youtube/schemas/youtube-edit-video-advanced.schema.json', - 'uiSchema': 'extra/youtube/schemas/youtube-edit-video-advanced.ui.json' - } - } - } + youtube: { + adapter: { + name: "youtube", + title: "YouTube", + description: + "Enjoy the videos and music you love, upload original content," + + " and share it all with friends, family, and the world on YouTube.", + infoUrl: "https://www.youtube.com/", + maintainer: "Kendraio", + supportUrl: "http://kendra.io", + uploads: true, + forms: { + basic: { + jsonSchema: + "extra/youtube/schemas/youtube-edit-video-basic.json", + uiSchema: + "extra/youtube/schemas/youtube-edit-video-basic-ui.json", + }, + advanced: { + jsonSchema: + "extra/youtube/schemas/youtube-edit-video-advanced.schema.json", + uiSchema: + "extra/youtube/schemas/youtube-edit-video-advanced.ui.json", + }, + }, + }, }, - 'teosto': { - 'adapter': { - 'name': 'teosto', - 'title': 'Teosto', - 'description': 'Teosto is a non-profit performance rights organization that collects' + - ' royalties on behalf of songwriters and composers in Finland.', - 'infoUrl': 'https://www.teosto.fi/', - 'maintainer': 'Kendraio', - 'supportUrl': 'http://kendra.io', - 'uploads': false, - 'configs': [ - 'extra/teosto/configs/listWorks.json', - 'extra/teosto/configs/authorsWorksByName.json', - 'extra/teosto/configs/authorsWorksFromIPI.json', - 'extra/teosto/configs/getRightsHolderForISWC.json', - 'extra/teosto/configs/listPublishersWorks.json', - 'extra/teosto/configs/listWorksSelectionExample.json' - ] - } + teosto: { + adapter: { + name: "teosto", + title: "Teosto", + description: + "Teosto is a non-profit performance rights organization that collects" + + " royalties on behalf of songwriters and composers in Finland.", + infoUrl: "https://www.teosto.fi/", + maintainer: "Kendraio", + supportUrl: "http://kendra.io", + uploads: false, + configs: [ + "extra/teosto/configs/listWorks.json", + "extra/teosto/configs/authorsWorksByName.json", + "extra/teosto/configs/authorsWorksFromIPI.json", + "extra/teosto/configs/getRightsHolderForISWC.json", + "extra/teosto/configs/listPublishersWorks.json", + "extra/teosto/configs/listWorksSelectionExample.json", + ], + }, }, - 'spotify': { - 'adapter': { - 'name': 'spotify', - 'title': 'Spotify', - 'description': 'Spotify is a digital music service that gives you access to millions of songs.', - 'infoUrl': 'https://www.spotify.com/uk/', - 'maintainer': 'Kendraio', - 'supportUrl': 'http://kendra.io', - 'uploads': true - } + spotify: { + adapter: { + name: "spotify", + title: "Spotify", + description: + "Spotify is a digital music service that gives you access to millions of songs.", + infoUrl: "https://www.spotify.com/uk/", + maintainer: "Kendraio", + supportUrl: "http://kendra.io", + uploads: true, + }, }, - 'schema': { - 'adapter': { - 'name': 'schema', - 'title': 'schema.org', - 'description': 'Schema.org is a collaborative, community activity with a mission to create, ' + - 'maintain, and promote schemas for structured data on the Internet, on web pages, in email messages, and beyond.', - 'infoUrl': 'https://schema.org/', - 'maintainer': 'Kendraio', - 'supportUrl': 'https://www.kendra.io', - 'uploads': false, - 'forms': { - 'addImage': { - 'jsonSchema': 'extra/schema.org/schemas/imageObject.json', - 'uiSchema': 'extra/schema.org/schemas/addImage-ui.json' - }, - 'editImage': { - 'jsonSchema': 'extra/schema.org/schemas/imageObject.json', - 'uiSchema': 'extra/schema.org/schemas/editImage-ui.json' - } + schema: { + adapter: { + name: "schema", + title: "schema.org", + description: + "Schema.org is a collaborative, community activity with a mission to create, " + + "maintain, and promote schemas for structured data on the Internet, on web pages, in email messages, and beyond.", + infoUrl: "https://schema.org/", + maintainer: "Kendraio", + supportUrl: "https://www.kendra.io", + uploads: false, + forms: { + addImage: { + jsonSchema: "extra/schema.org/schemas/imageObject.json", + uiSchema: "extra/schema.org/schemas/addImage-ui.json", + }, + editImage: { + jsonSchema: "extra/schema.org/schemas/imageObject.json", + uiSchema: "extra/schema.org/schemas/editImage-ui.json", + }, }, - 'rootNodeTypes': [], - 'nodeTypes': [ - 'Person', - 'ImageObject' - ], - 'linkTypes': [] + rootNodeTypes: [], + nodeTypes: ["Person", "ImageObject"], + linkTypes: [], }, - 'schemas': { - 'Person': { - 'context': 'http://schema.org', - 'type': 'Person', - 'label': 'Person', - 'icon': 'person', - 'fields': [ + schemas: { + Person: { + context: "http://schema.org", + type: "Person", + label: "Person", + icon: "person", + fields: [ { - 'name': 'name', - 'label': 'Name', - 'type': 'string', - 'widget': 'textfield' - } - ] + name: "name", + label: "Name", + type: "string", + widget: "textfield", + }, + ], }, - 'ImageObject': { - 'context': 'http://schema.org', - 'type': 'ImageObject', - 'label': 'Image', - 'icon': 'photo_camera', - 'labelField': 'contentUrl', - 'fields': [ + ImageObject: { + context: "http://schema.org", + type: "ImageObject", + label: "Image", + icon: "photo_camera", + labelField: "contentUrl", + fields: [ { - 'name': 'contentUrl', - 'label': 'Image URL', - 'type': 'string', - 'widget': 'imageTagger', - 'required': true, - 'widthField': 'width', - 'heightField': 'height' + name: "contentUrl", + label: "Image URL", + type: "string", + widget: "imageTagger", + required: true, + widthField: "width", + heightField: "height", }, { - 'name': 'name', - 'label': 'Filename', - 'type': 'string', - 'widget': 'textfield' + name: "name", + label: "Filename", + type: "string", + widget: "textfield", }, { - 'name': 'description', - 'label': 'Description', - 'widget': 'textarea' + name: "description", + label: "Description", + widget: "textarea", }, { - 'name': 'url', - 'label': 'Source URL', - 'type': 'string', - 'widget': 'textfield', - 'required': true + name: "url", + label: "Source URL", + type: "string", + widget: "textfield", + required: true, }, { - 'name': 'width', - 'label': 'Width', - 'type': 'integer', - 'widget': 'hidden' + name: "width", + label: "Width", + type: "integer", + widget: "hidden", }, { - 'name': 'height', - 'label': 'Height', - 'type': 'integer', - 'widget': 'hidden' - } - ] - } - } + name: "height", + label: "Height", + type: "integer", + widget: "hidden", + }, + ], + }, + }, }, - 'ppl-ipn': { - 'adapter': { - 'name': 'ppl-ipn', - 'title': 'PPL IPN', - 'description': 'Verification of International Performer Number (IPN) for PPL members', - 'infoUrl': 'https://www.ppluk.com/membership/more-information/ipn/', - 'maintainer': 'Kendraio', - 'supportUrl': 'https://www.kendra.io', - 'uploads': false, - 'actions': [ + "ppl-ipn": { + adapter: { + name: "ppl-ipn", + title: "PPL IPN", + description: + "Verification of International Performer Number (IPN) for PPL members", + infoUrl: "https://www.ppluk.com/membership/more-information/ipn/", + maintainer: "Kendraio", + supportUrl: "https://www.kendra.io", + uploads: false, + actions: [ { - 'title': 'PPL IPN Process', - 'path': 'extra/ppl-ipn/ipn.txt' - } + title: "PPL IPN Process", + path: "extra/ppl-ipn/ipn.txt", + }, ], - 'forms': { - 'ipn': { - 'jsonSchema': 'extra/ppl-ipn/schemas/ipn-jsonSchema.json', - 'uiSchema': 'extra/ppl-ipn/schemas/ipn-uiSchema.json' - } - } - } + forms: { + ipn: { + jsonSchema: "extra/ppl-ipn/schemas/ipn-jsonSchema.json", + uiSchema: "extra/ppl-ipn/schemas/ipn-uiSchema.json", + }, + }, + }, }, - 'bandcamp': { - 'adapter': { - 'name': 'bandcamp', - 'title': 'Bandcamp', - 'description': 'Discover amazing music and directly support the artists who make it.', - 'infoUrl': 'https://bandcamp.com/', - 'maintainer': 'Kendraio', - 'supportUrl': 'http://kendra.io', - 'uploads': true - } + bandcamp: { + adapter: { + name: "bandcamp", + title: "Bandcamp", + description: + "Discover amazing music and directly support the artists who make it.", + infoUrl: "https://bandcamp.com/", + maintainer: "Kendraio", + supportUrl: "http://kendra.io", + uploads: true, + }, }, - 'm-rin': { - 'adapter': { - 'name': 'm-rin', - 'title': 'Recording Information Notification (RIN)', - 'description': 'This adapter defines the schema and parser for the DDEX M-RIN (Minimum) ' + - 'Recording Information Notification standard.\nThis adapter enables support for import ' + - 'and export of M-RIN data, as well as the core entities for storage of projects, people,' + - ' recordings, and works.\n', - 'infoUrl': 'http://www.ddex.net/recording-information-notification-rin', - 'maintainer': 'Kendraio', - 'supportUrl': 'http://kendra.io', - 'source': { - 'parser': 'xml', - 'parserConfig': { - 'arrayAccessFormPaths': [ - '.\\.Party$', - '.\\.PostalAddress$', - '.\\.PhoneNumber$', - '.\\.EmailAddress$', - '.\\.MusicalWork$', - '.\\.SoundRecording$', - '.\\.Project$', - '.\\.Session$', - '.\\.SoundRecordingSessionReference$', - '.\\.ContributorReference$', - '.\\.SessionSoundRecordingReference$' - ] - }, - 'extractor': 'extractor.jmespath' + "m-rin": { + adapter: { + name: "m-rin", + title: "Recording Information Notification (RIN)", + description: + "This adapter defines the schema and parser for the DDEX M-RIN (Minimum) " + + "Recording Information Notification standard.\nThis adapter enables support for import " + + "and export of M-RIN data, as well as the core entities for storage of projects, people," + + " recordings, and works.\n", + infoUrl: + "http://www.ddex.net/recording-information-notification-rin", + maintainer: "Kendraio", + supportUrl: "http://kendra.io", + source: { + parser: "xml", + parserConfig: { + arrayAccessFormPaths: [ + ".\\.Party$", + ".\\.PostalAddress$", + ".\\.PhoneNumber$", + ".\\.EmailAddress$", + ".\\.MusicalWork$", + ".\\.SoundRecording$", + ".\\.Project$", + ".\\.Session$", + ".\\.SoundRecordingSessionReference$", + ".\\.ContributorReference$", + ".\\.SessionSoundRecordingReference$", + ], + }, + extractor: "extractor.jmespath", }, - 'rootNodeType': 'Project', - 'nodeTypes': [ - 'Project', - 'Party', - 'MusicalWork', - 'Session', - 'Resource' + rootNodeType: "Project", + nodeTypes: [ + "Project", + "Party", + "MusicalWork", + "Session", + "Resource", ], - 'linkTypes': [ - 'ContributorReference', - 'MainArtist', - 'Label' - ], - 'schemas': { - 'Project': { - 'options': { - 'labelField': 'name' - }, - 'properties': { - 'name': { - 'type': 'string', - 'options': { - 'label': 'Name' - } + linkTypes: ["ContributorReference", "MainArtist", "Label"], + schemas: { + Project: { + options: { + labelField: "name", + }, + properties: { + name: { + type: "string", + options: { + label: "Name", + }, + }, + artist: { + type: "string", + options: { + label: "Artist Name", + }, + }, + comment: { + type: "string", + options: { + fieldType: "TEXTAREA", + label: "Comment", + }, }, - 'artist': { - 'type': 'string', - 'options': { - 'label': 'Artist Name' - } + }, + links: ["MainArtist", "Label", "ContributorReference"], + }, + Party: { + options: { + labelField: "FullName", + }, + properties: { + FullName: { + type: "string", + }, + FullNameIndexed: { + type: "string", }, - 'comment': { - 'type': 'string', - 'options': { - 'fieldType': 'TEXTAREA', - 'label': 'Comment' - } - } - }, - 'links': [ - 'MainArtist', - 'Label', - 'ContributorReference' - ] - }, - 'Party': { - 'options': { - 'labelField': 'FullName' - }, - 'properties': { - 'FullName': { - 'type': 'string' + ISNI: { + type: "string", }, - 'FullNameIndexed': { - 'type': 'string' + IsOrganization: { + type: "boolean", + options: { + fieldType: "SWITCH", + }, + }, + }, + }, + MusicalWork: { + options: { + labelField: "name", + }, + properties: { + name: { + type: "string", }, - 'ISNI': { - 'type': 'string' + Comment: { + type: "string", + options: { + fieldType: "TEXTAREA", + }, }, - 'IsOrganization': { - 'type': 'boolean', - 'options': { - 'fieldType': 'SWITCH' - } - } - } - }, - 'MusicalWork': { - 'options': { - 'labelField': 'name' - }, - 'properties': { - 'name': { - 'type': 'string' + }, + }, + ContributorReference: { + properties: { + role: { + type: "string", }, - 'Comment': { - 'type': 'string', - 'options': { - 'fieldType': 'TEXTAREA' - } - } - } - }, - 'ContributorReference': { - 'properties': { - 'role': { - 'type': 'string' - } - } - } - } + }, + }, + }, }, - 'schemas': { - 'Party': { - 'name': 'Party', - 'description': 'A Composite containing details of a Party.', - 'id': 'm-rin:Party', - 'type': 'object', - 'required': [ - 'PartyId', - 'PartyReference', - 'IsOrganization' - ], - 'properties': { - 'PartyId': { - 'description': 'A Composite containing details of the PartyId for the Party. ' + - 'If no Namespace is given, the Identifier is a DdexPartyId (DPID). ' + - 'Note that DPIDs are not normally used to identify Artists, producers or other Creators.\n', - 'type': 'array', - 'minItems': 1, - 'items': { - '$ref': 'm-rin:DetailedPartyId' - } - }, - 'PartyReference': { - 'description': 'The Identifier (specific to the Message) of the Party. This is' + - ' a LocalPartyAnchor starting with the letter P.\n', - 'type': 'string', - 'pattern': '^P[\\d\\-_a-zA-Z]+$' - }, - 'PartyName': { - 'description': 'A Composite containing details of the PartyName(s).', - 'type': 'array', - 'items': { - '$ref': 'm-rin:PartyName' - } - }, - 'Publisher': { - 'type': 'array', - 'description': 'A Composite containing details of the MusicPublisher the Party is signed to.', - 'items': { - '$ref': 'm-rin:Affiliation' - } - }, - 'AuthorsSociety': { - 'type': 'array', - 'description': 'A Composite containing details of the AuthorsSociety the Party is a member of.', - 'items': { - '$ref': 'm-rin:Affiliation' - } - }, - 'Label': { - 'description': 'A Composite containing details of the Label the Party is signed to.', - 'type': 'array', - 'items': { - '$ref': 'm-rin:Affiliation' - } - }, - 'MusicLicensingCompany': { - 'description': 'A Composite containing details of the MusicLicensingCompany the Party is a member of.', - 'type': 'array', - 'items': { - '$ref': 'm-rin:Affiliation' - } - }, - 'Sex': { - '$ref': 'avs:Sex', - 'description': 'The sex of the Party.' - }, - 'TerritoryOfResidency': { - '$ref': 'm-rin:AllTerritoryCode', - 'description': 'The country of main residency of the Party.' - }, - 'GoverningAgreementType': { - '$ref': 'm-rin:GoverningAgreementType', - 'description': 'A Composite containing details of a Type of an agreement that ' + - 'covers the Party\'s participation in making a SoundRecording.' - }, - 'ArtistDelegatedUsageRights': { - '$ref': 'm-rin:ArtistDelegatedUsageRights', - 'description': 'A Composite containing details of the kinds of usage for which' + - ' rights have been delegated by the Party.' - }, - 'IsOrganization': { - 'description': 'A Flag indicating whether the Party is an Organization (=true) or a Person (=false).', - 'type': 'boolean' - }, - 'PostalAddress': { - 'description': 'A Composite containing details of a PostalAddress of the Party.', - 'type': 'array', - 'items': { - '$ref': 'm-rin:PostalAddress' - } - }, - 'PhoneNumber': { - 'description': 'A Composite containing details of a PhoneNumber of the Party.', - 'type': 'array', - 'items': { - '$ref': 'm-rin:PhoneNumber' - } - }, - 'EmailAddress': { - 'description': 'A Composite containing details of an EmailAddress of the Party.', - 'type': 'array', - 'items': { - '$ref': 'm-rin:EmailAddress' - } - }, - 'Nationality': { - '$ref': 'm-rin:CurrentTerritoryCode', - 'description': 'The nationality of the Party.' - }, - 'DateAndPlaceOfBirth': { - '$ref': 'm-rin:EventDate', - 'description': 'A Composite containing details of the Date and Place of birth. ' + - 'This is a string with the syntax YYYY[-MM[-DD]].' - }, - 'DateAndPlaceOfDeath': { - '$ref': 'm-rin:EventDate', - 'description': 'A Composite containing details of the Date and Place of death. This ' + - 'is a string with the syntax YYYY[-MM[-DD]].' - } - } + schemas: { + Party: { + name: "Party", + description: "A Composite containing details of a Party.", + id: "m-rin:Party", + type: "object", + required: ["PartyId", "PartyReference", "IsOrganization"], + properties: { + PartyId: { + description: + "A Composite containing details of the PartyId for the Party. " + + "If no Namespace is given, the Identifier is a DdexPartyId (DPID). " + + "Note that DPIDs are not normally used to identify Artists, producers or other Creators.\n", + type: "array", + minItems: 1, + items: { + $ref: "m-rin:DetailedPartyId", + }, + }, + PartyReference: { + description: + "The Identifier (specific to the Message) of the Party. This is" + + " a LocalPartyAnchor starting with the letter P.\n", + type: "string", + pattern: "^P[\\d\\-_a-zA-Z]+$", + }, + PartyName: { + description: + "A Composite containing details of the PartyName(s).", + type: "array", + items: { + $ref: "m-rin:PartyName", + }, + }, + Publisher: { + type: "array", + description: + "A Composite containing details of the MusicPublisher the Party is signed to.", + items: { + $ref: "m-rin:Affiliation", + }, + }, + AuthorsSociety: { + type: "array", + description: + "A Composite containing details of the AuthorsSociety the Party is a member of.", + items: { + $ref: "m-rin:Affiliation", + }, + }, + Label: { + description: + "A Composite containing details of the Label the Party is signed to.", + type: "array", + items: { + $ref: "m-rin:Affiliation", + }, + }, + MusicLicensingCompany: { + description: + "A Composite containing details of the MusicLicensingCompany the Party is a member of.", + type: "array", + items: { + $ref: "m-rin:Affiliation", + }, + }, + Sex: { + $ref: "avs:Sex", + description: "The sex of the Party.", + }, + TerritoryOfResidency: { + $ref: "m-rin:AllTerritoryCode", + description: "The country of main residency of the Party.", + }, + GoverningAgreementType: { + $ref: "m-rin:GoverningAgreementType", + description: + "A Composite containing details of a Type of an agreement that " + + "covers the Party's participation in making a SoundRecording.", + }, + ArtistDelegatedUsageRights: { + $ref: "m-rin:ArtistDelegatedUsageRights", + description: + "A Composite containing details of the kinds of usage for which" + + " rights have been delegated by the Party.", + }, + IsOrganization: { + description: + "A Flag indicating whether the Party is an Organization (=true) or a Person (=false).", + type: "boolean", + }, + PostalAddress: { + description: + "A Composite containing details of a PostalAddress of the Party.", + type: "array", + items: { + $ref: "m-rin:PostalAddress", + }, + }, + PhoneNumber: { + description: + "A Composite containing details of a PhoneNumber of the Party.", + type: "array", + items: { + $ref: "m-rin:PhoneNumber", + }, + }, + EmailAddress: { + description: + "A Composite containing details of an EmailAddress of the Party.", + type: "array", + items: { + $ref: "m-rin:EmailAddress", + }, + }, + Nationality: { + $ref: "m-rin:CurrentTerritoryCode", + description: "The nationality of the Party.", + }, + DateAndPlaceOfBirth: { + $ref: "m-rin:EventDate", + description: + "A Composite containing details of the Date and Place of birth. " + + "This is a string with the syntax YYYY[-MM[-DD]].", + }, + DateAndPlaceOfDeath: { + $ref: "m-rin:EventDate", + description: + "A Composite containing details of the Date and Place of death. This " + + "is a string with the syntax YYYY[-MM[-DD]].", + }, + }, }, - 'ProprietaryId': { - 'name': 'ProprietaryId', - 'description': 'A Composite containing details of a ProprietaryIdentifier.', - 'id': 'm-rin:ProprietaryId', - 'type': 'object', - 'required': [ - 'ProprietaryId', - 'Namespace' - ], - 'properties': { - 'ProprietaryId': { - 'type': 'string' - }, - 'Namespace': { - 'description': 'The Namespace of the ProprietaryIdentifier. This is represented in an' + - ' XML schema as an XML Attribute.', - 'type': 'string' - } - } + ProprietaryId: { + name: "ProprietaryId", + description: + "A Composite containing details of a ProprietaryIdentifier.", + id: "m-rin:ProprietaryId", + type: "object", + required: ["ProprietaryId", "Namespace"], + properties: { + ProprietaryId: { + type: "string", + }, + Namespace: { + description: + "The Namespace of the ProprietaryIdentifier. This is represented in an" + + " XML schema as an XML Attribute.", + type: "string", + }, + }, }, - 'PartyName': { - 'name': 'PartyName', - 'description': 'A Composite containing details of a PartyName. Name details for a Party ' + - 'typically either contain a FullName or a KeyName.\n', - 'id': 'm-rin:PartyName', - 'type': 'object', - 'required': [ - 'FullName' - ], - 'properties': { - 'FullName': { - '$ref': 'm-rin:Name', - 'description': 'A Composite containing the complete Name of the Party, in its normal ' + - 'form of presentation (e.g. John H. Smith, Acme Music Inc, the Beatles).' - }, - 'FullNameAsciiTranscribed': { - 'type': 'string', - 'description': 'The FullName transcribed using 7-bit ASCII code.' - }, - 'FullNameIndexed': { - '$ref': 'm-rin:Name', - 'description': 'A Composite containing the complete Name of the Party in the form in ' + - 'which it normally appears in an alphabetic index, with the KeyName first (e.g. Smith,' + - ' John H.; Beatles, The).' - }, - 'NamesBeforeKeyName': { - '$ref': 'm-rin:Name', - 'description': 'A Composite containing the Name(s) preceding the KeyName in the ' + - 'FullName (and that is placed after it in a FullNameIndexed). Examples: \'George\' ' + - 'in \'George Michael\'; \'John Fitzgerald\' in \'John Fitzgerald Kennedy\'. ' + - 'Not all PartyNames have a NamesBeforeKeyName (e.g. Madonna, EMI Music Inc).' - }, - 'KeyName': { - '$ref': 'm-rin:Name', - 'description': 'A Composite containing the Part of a Name of the Party normally used to' + - ' index an entry in an alphabetical list, such as \'Smith\' (in John Smith) or' + - ' \'Garcia Marquez\' or \'Madonna\' or \'Francis de Sales\' (in Saint Francis de Sales). ' + - 'For persons, this normally corresponds to the \'family name\' or names, which in ' + - 'Western name forms usually comes as a surname at the end of a FullName, and in Asian ' + - 'name forms often at the beginning of a FullName.' - }, - 'NamesAfterKeyName': { - '$ref': 'm-rin:Name', - 'description': 'A Composite containing the Name(s) following the KeyName.' + - ' Example:\'Ibrahim\' (in Anwar Ibrahim). This is common, e.g., in many Asian ' + - 'personal name forms where a FullName begins with the KeyName, which is followed ' + - 'by other names.' - }, - 'AbbreviatedName': { - '$ref': 'm-rin:Name', - 'description': 'A Composite containing a short version of the PartyName (e.g. for use' + - ' on devices with a small display).' - }, - 'LanguageAndScriptCode': { - 'type': 'string', - 'description': 'The Language and script for the Elements of the PartyName as ' + - 'defined in IETF RfC 5646. The default is the same as indicated for the containing ' + - 'composite. Language and Script are provided as lang[-scipt][-region][-variant]. ' + - 'This is represented in an XML schema as an XML Attribute.' - } - } + PartyName: { + name: "PartyName", + description: + "A Composite containing details of a PartyName. Name details for a Party " + + "typically either contain a FullName or a KeyName.\n", + id: "m-rin:PartyName", + type: "object", + required: ["FullName"], + properties: { + FullName: { + $ref: "m-rin:Name", + description: + "A Composite containing the complete Name of the Party, in its normal " + + "form of presentation (e.g. John H. Smith, Acme Music Inc, the Beatles).", + }, + FullNameAsciiTranscribed: { + type: "string", + description: + "The FullName transcribed using 7-bit ASCII code.", + }, + FullNameIndexed: { + $ref: "m-rin:Name", + description: + "A Composite containing the complete Name of the Party in the form in " + + "which it normally appears in an alphabetic index, with the KeyName first (e.g. Smith," + + " John H.; Beatles, The).", + }, + NamesBeforeKeyName: { + $ref: "m-rin:Name", + description: + "A Composite containing the Name(s) preceding the KeyName in the " + + "FullName (and that is placed after it in a FullNameIndexed). Examples: 'George' " + + "in 'George Michael'; 'John Fitzgerald' in 'John Fitzgerald Kennedy'. " + + "Not all PartyNames have a NamesBeforeKeyName (e.g. Madonna, EMI Music Inc).", + }, + KeyName: { + $ref: "m-rin:Name", + description: + "A Composite containing the Part of a Name of the Party normally used to" + + " index an entry in an alphabetical list, such as 'Smith' (in John Smith) or" + + " 'Garcia Marquez' or 'Madonna' or 'Francis de Sales' (in Saint Francis de Sales). " + + "For persons, this normally corresponds to the 'family name' or names, which in " + + "Western name forms usually comes as a surname at the end of a FullName, and in Asian " + + "name forms often at the beginning of a FullName.", + }, + NamesAfterKeyName: { + $ref: "m-rin:Name", + description: + "A Composite containing the Name(s) following the KeyName." + + " Example:'Ibrahim' (in Anwar Ibrahim). This is common, e.g., in many Asian " + + "personal name forms where a FullName begins with the KeyName, which is followed " + + "by other names.", + }, + AbbreviatedName: { + $ref: "m-rin:Name", + description: + "A Composite containing a short version of the PartyName (e.g. for use" + + " on devices with a small display).", + }, + LanguageAndScriptCode: { + type: "string", + description: + "The Language and script for the Elements of the PartyName as " + + "defined in IETF RfC 5646. The default is the same as indicated for the containing " + + "composite. Language and Script are provided as lang[-scipt][-region][-variant]. " + + "This is represented in an XML schema as an XML Attribute.", + }, + }, }, - 'DetailedPartyId': { - 'name': 'DetailedPartyId', - 'description': 'A Composite containing details of a PartyId.', - 'id': 'm-rin:DetailedPartyId', - 'type': 'object', - 'properties': { - 'ISNI': { - 'description': 'An International Standard Name Identifier, the ISO 27729 Standard ' + - 'Identifier for names. DDEX will enforce the syntax [0-9]{15}[X0-9] using XML ' + - 'Schema in the future.\n', - 'type': 'string' - }, - 'DPID': { - 'description': 'An Identifier of a Party according to the DdexPartyId standard DDEX-DPID.', - 'type': 'string', - 'pattern': 'PADPIDA[a-zA-Z0-9]+' - }, - 'IpiNameNumber': { - 'description': 'An Interested Party Identifier, a CISAC standard Identifier.', - 'type': 'string' - }, - 'IPN': { - 'description': 'An International Performer Number, an IPDA Identifier (http://www2.ipddb.org/content/ipd-project).\n', - 'type': 'string' - }, - 'CisacSocietyId': { - 'description': 'A CISAC Society Identifier, a CISAC standard Identifier for music rights societies.', - 'type': 'string' - }, - 'ProprietaryId': { - 'description': 'A Composite containing details of a ProprietaryIdentifier of the Party.', - 'type': 'array', - 'items': { - '$ref': 'm-rin:ProprietaryId' - } - } - } + DetailedPartyId: { + name: "DetailedPartyId", + description: "A Composite containing details of a PartyId.", + id: "m-rin:DetailedPartyId", + type: "object", + properties: { + ISNI: { + description: + "An International Standard Name Identifier, the ISO 27729 Standard " + + "Identifier for names. DDEX will enforce the syntax [0-9]{15}[X0-9] using XML " + + "Schema in the future.\n", + type: "string", + }, + DPID: { + description: + "An Identifier of a Party according to the DdexPartyId standard DDEX-DPID.", + type: "string", + pattern: "PADPIDA[a-zA-Z0-9]+", + }, + IpiNameNumber: { + description: + "An Interested Party Identifier, a CISAC standard Identifier.", + type: "string", + }, + IPN: { + description: + "An International Performer Number, an IPDA Identifier (http://www2.ipddb.org/content/ipd-project).\n", + type: "string", + }, + CisacSocietyId: { + description: + "A CISAC Society Identifier, a CISAC standard Identifier for music rights societies.", + type: "string", + }, + ProprietaryId: { + description: + "A Composite containing details of a ProprietaryIdentifier of the Party.", + type: "array", + items: { + $ref: "m-rin:ProprietaryId", + }, + }, + }, }, - 'Name': { - 'name': 'Name', - 'description': 'A Composite containing details of a Name.', - 'id': 'm-rin:Name', - 'type': 'object', - 'required': [ - 'Name' - ], - 'properties': { - 'Name': { - 'type': 'string' - }, - 'LanguageAndScriptCode': { - 'type': 'string', - 'description': 'The Language and script of the Name as defined in IETF RfC 5646. ' + - 'The default is the same as indicated for the containing composite. Language and ' + - 'Script are provided as lang[-scipt][-region][-variant]. This is represented in ' + - 'an XML schema as an XML Attribute.' - } - } - } - } + Name: { + name: "Name", + description: "A Composite containing details of a Name.", + id: "m-rin:Name", + type: "object", + required: ["Name"], + properties: { + Name: { + type: "string", + }, + LanguageAndScriptCode: { + type: "string", + description: + "The Language and script of the Name as defined in IETF RfC 5646. " + + "The default is the same as indicated for the containing composite. Language and " + + "Script are provided as lang[-scipt][-region][-variant]. This is represented in " + + "an XML schema as an XML Attribute.", + }, + }, + }, + }, }, - 'example': { - 'adapter': { - 'name': 'example', - 'title': 'Example', - 'description': 'An adapter for examples and demonstrations.', - 'infoUrl': 'https://www.example.com/', - 'maintainer': 'Kendraio', - 'supportUrl': 'https://www.kendra.io', - 'uploads': false, - 'configs': [ - 'extra/example/configs/productChart.json', - 'extra/example/configs/customFormElements.json' + example: { + adapter: { + name: "example", + title: "Example", + description: "An adapter for examples and demonstrations.", + infoUrl: "https://www.example.com/", + maintainer: "Kendraio", + supportUrl: "https://www.kendra.io", + uploads: false, + configs: [ + "extra/example/configs/productChart.json", + "extra/example/configs/customFormElements.json", ], - 'forms': { - 'customElements': { - 'jsonSchema': 'extra/example/schemas/customElements.schema.json', - 'uiSchema': 'extra/example/schemas/customElements.ui.json' - } - } - } + forms: { + customElements: { + jsonSchema: "extra/example/schemas/customElements.schema.json", + uiSchema: "extra/example/schemas/customElements.ui.json", + }, + }, + }, }, - 'resonate': { - 'adapter': { - 'name': 'resonate', - 'title': 'Resonate', - 'description': 'Resonate Co-operative is a community owned music streaming platform', - 'infoUrl': 'https://resonate.is/', - 'maintainer': 'Resonate', - 'supportUrl': 'https://kendra.io/' - } + resonate: { + adapter: { + name: "resonate", + title: "Resonate", + description: + "Resonate Co-operative is a community owned music streaming platform", + infoUrl: "https://resonate.is/", + maintainer: "Resonate", + supportUrl: "https://kendra.io/", + }, }, - 'tidal': { - 'adapter': { - 'name': 'tidal', - 'title': 'TIDAL', - 'description': 'TIDAL is the first music service with High Fidelity sound quality, ' + - 'High Definition music videos and Curated Editorial, expertly crafted by music journalists.', - 'infoUrl': 'http://tidal.com/gb', - 'maintainer': 'Kendraio', - 'supportUrl': 'http://kendra.io', - 'uploads': true - } + tidal: { + adapter: { + name: "tidal", + title: "TIDAL", + description: + "TIDAL is the first music service with High Fidelity sound quality, " + + "High Definition music videos and Curated Editorial, expertly crafted by music journalists.", + infoUrl: "http://tidal.com/gb", + maintainer: "Kendraio", + supportUrl: "http://kendra.io", + uploads: true, + }, }, - 'omi': { - 'adapter': { - 'name': 'omi', - 'title': 'OMI', - 'description': 'We are a non-profit initiative creating an open-source protocol for ' + - 'the uniform identification of music rights holders and creators.', - 'infoUrl': 'http://open-music.org/', - 'maintainer': 'Kendraio', - 'supportUrl': 'http://kendra.io', - 'uploads': true - } + omi: { + adapter: { + name: "omi", + title: "OMI", + description: + "We are a non-profit initiative creating an open-source protocol for " + + "the uniform identification of music rights holders and creators.", + infoUrl: "http://open-music.org/", + maintainer: "Kendraio", + supportUrl: "http://kendra.io", + uploads: true, + }, }, - 'kendraio': { - 'adapter': { - 'name': 'kendraio', - 'title': 'Kendraio', - 'description': 'An adapter for Kendraio specific features', - 'infoUrl': 'https://www.kendra.io/', - 'maintainer': 'Kendraio', - 'supportUrl': 'https://www.kendra.io', - 'uploads': false, - 'database': [ - 'extra/kendraio/schemas/music_recording.schema.json', - 'extra/kendraio/schemas/music_work.schema.json', - 'extra/kendraio/schemas/file.schema.json' + kendraio: { + adapter: { + name: "kendraio", + title: "Kendraio", + description: "An adapter for Kendraio specific features", + infoUrl: "https://www.kendra.io/", + maintainer: "Kendraio", + supportUrl: "https://www.kendra.io", + uploads: false, + database: [ + "extra/kendraio/schemas/music_recording.schema.json", + "extra/kendraio/schemas/music_work.schema.json", + "extra/kendraio/schemas/file.schema.json", ], - 'forms': { - 'edit_music_recording': { - 'jsonSchema': 'extra/kendraio/schemas/music_recording.schema.json', - 'uiSchema': 'extra/kendraio/schemas/music_recording.ui.json' - }, - 'edit_music_work': { - 'jsonSchema': 'extra/kendraio/schemas/music_work.schema.json', - 'uiSchema': 'extra/kendraio/schemas/music_work.ui.json' - }, - 'edit_file': { - 'jsonSchema': 'extra/kendraio/schemas/file.schema.json', - 'uiSchema': 'extra/kendraio/schemas/file.ui.json' - } + forms: { + edit_music_recording: { + jsonSchema: + "extra/kendraio/schemas/music_recording.schema.json", + uiSchema: "extra/kendraio/schemas/music_recording.ui.json", + }, + edit_music_work: { + jsonSchema: "extra/kendraio/schemas/music_work.schema.json", + uiSchema: "extra/kendraio/schemas/music_work.ui.json", + }, + edit_file: { + jsonSchema: "extra/kendraio/schemas/file.schema.json", + uiSchema: "extra/kendraio/schemas/file.ui.json", + }, }, - 'queries': [ - 'extra/kendraio/queries/listRecordings.json' - ], - 'actions': [ + queries: ["extra/kendraio/queries/listRecordings.json"], + actions: [ { - 'title': 'Claim Workflow States', - 'path': 'extra/kendraio/flow-chart.txt' + title: "Claim Workflow States", + path: "extra/kendraio/flow-chart.txt", }, { - 'title': 'Rights Claim', - 'path': 'extra/kendraio/sequence.txt' + title: "Rights Claim", + path: "extra/kendraio/sequence.txt", }, { - 'title': 'Claim object states', - 'path': 'extra/kendraio/claim-process-states.txt' + title: "Claim object states", + path: "extra/kendraio/claim-process-states.txt", }, { - 'title': 'Adapter API example', - 'path': 'extra/kendraio/adapter-api-form-example.txt' - } + title: "Adapter API example", + path: "extra/kendraio/adapter-api-form-example.txt", + }, + ], + configs: [ + "extra/kendraio/configs/listRecordings.json", + "extra/kendraio/configs/bulkOperationsExample.json", + "extra/kendraio/configs/fakerTest.json", ], - 'configs': [ - 'extra/kendraio/configs/listRecordings.json', - 'extra/kendraio/configs/bulkOperationsExample.json', - 'extra/kendraio/configs/fakerTest.json' - ] }, - 'schemas': { - 'InclusionRelationship': { - 'context': 'https://kendra.io/schema-v1', - 'type': 'InclusionRelationship', - 'label': 'Tag', - 'icon': 'label', - 'sourceNodeTypes': [ - 'ImageObject' - ], - 'targetNodeTypes': [ - 'Person' - ], - 'fields': [ + schemas: { + InclusionRelationship: { + context: "https://kendra.io/schema-v1", + type: "InclusionRelationship", + label: "Tag", + icon: "label", + sourceNodeTypes: ["ImageObject"], + targetNodeTypes: ["Person"], + fields: [ { - 'name': 'visibility', - 'label': 'Visibility', - 'type': 'string', - 'widget': 'select', - 'options': [ - 'Public', - 'Private', - 'Custom' - ] + name: "visibility", + label: "Visibility", + type: "string", + widget: "select", + options: ["Public", "Private", "Custom"], }, { - 'name': 'boundingBox', - 'label': 'Region', - 'type': 'region', - 'widget': 'none' - } - ] - } - } + name: "boundingBox", + label: "Region", + type: "region", + widget: "none", + }, + ], + }, + }, + }, + soundcloud: { + adapter: { + name: "soundcloud", + title: "SoundCloud", + description: "Testing additional adapter", + infoUrl: "http://soundcloud.com", + maintainer: "Kendraio", + supportUrl: "http://kendra.io", + uploads: true, + }, }, - 'soundcloud': { - 'adapter': { - 'name': 'soundcloud', - 'title': 'SoundCloud', - 'description': 'Testing additional adapter', - 'infoUrl': 'http://soundcloud.com', - 'maintainer': 'Kendraio', - 'supportUrl': 'http://kendra.io', - 'uploads': true - } - } - } + }, ]); this.uploadEnabled = { bloomen: true, mixcloud: true, ddex: true, - 'copyright-hub': true, + "copyright-hub": true, unsplash: true, dotbc: true, chant: true, - 'apple-music': true, + "apple-music": true, youtube: true, teosto: true, spotify: true, schema: true, - 'ppl-ipn': true, + "ppl-ipn": true, bandcamp: true, - 'm-rin': true, + "m-rin": true, example: true, resonate: true, tidal: true, omi: true, kendraio: true, - soundcloud: true + soundcloud: true, }; } doUpload() { - if (Object.keys(this.uploadEnabled).filter(key => this.uploadEnabled[key]).length === 0) { + if ( + Object.keys(this.uploadEnabled).filter((key) => this.uploadEnabled[key]) + .length === 0 + ) { return; } - Object.keys(this.uploadEnabled).forEach(key => { + Object.keys(this.uploadEnabled).forEach((key) => { this.uploadStatus[key] = 0; }); - forkJoin(Object.keys(this.uploadEnabled) - .filter(key => this.uploadEnabled[key]) - .map(key => interval(Math.random() * 30).pipe( - tap(() => this.uploadStatus[key] += 1), - take(100) - ))).subscribe(() => { - const message = 'Upload complete'; - this.snackBar.open(message, 'OK', { - duration: 5000, - horizontalPosition: 'center', - verticalPosition: 'top' - }); - this.isUploading = false; + forkJoin( + Object.keys(this.uploadEnabled) + .filter((key) => this.uploadEnabled[key]) + .map((key) => + interval(Math.random() * 30).pipe( + tap(() => (this.uploadStatus[key] += 1)), + take(100), + ), + ), + ).subscribe(() => { + const message = "Upload complete"; + this.snackBar.open(message, "OK", { + duration: 5000, + horizontalPosition: "center", + verticalPosition: "top", + }); + this.isUploading = false; }); this.isUploading = true; } diff --git a/src/app/services/adapter-form-select.service.ts b/src/app/services/adapter-form-select.service.ts index 8fc323795..10c4b902f 100644 --- a/src/app/services/adapter-form-select.service.ts +++ b/src/app/services/adapter-form-select.service.ts @@ -1,48 +1,49 @@ -import { Injectable } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; -import {FormSelectDialogComponent} from '../dialogs/form-select-dialog/form-select-dialog.component'; -import {map, switchMap} from 'rxjs/operators'; -import {has} from 'lodash-es'; -import {Observable, of} from 'rxjs'; -import {KendraioFormService} from '../_shared/ui-form/services/kendraio.form.service'; -import {SwaggerFormSelectDialogComponent} from '../dialogs/swagger-form-select-dialog/swagger-form-select-dialog.component'; +import { Injectable } from "@angular/core"; +import { MatDialog } from "@angular/material/dialog"; +import { FormSelectDialogComponent } from "../dialogs/form-select-dialog/form-select-dialog.component"; +import { map, switchMap } from "rxjs/operators"; +import { has } from "lodash-es"; +import { Observable, of } from "rxjs"; +import { KendraioFormService } from "../_shared/ui-form/services/kendraio.form.service"; +import { SwaggerFormSelectDialogComponent } from "../dialogs/swagger-form-select-dialog/swagger-form-select-dialog.component"; @Injectable({ - providedIn: 'root' + providedIn: "root", }) export class AdapterFormSelectService { - constructor( private readonly dialog: MatDialog, - private readonly formService: KendraioFormService - ) { } + private readonly formService: KendraioFormService, + ) {} selectForm(): Observable { const dialogRef = this.dialog.open(FormSelectDialogComponent); return dialogRef.afterClosed().pipe( - switchMap(data => { - if (!!data && has(data, 'adapterId') && has(data, 'formId')) { + switchMap((data) => { + if (!!data && has(data, "adapterId") && has(data, "formId")) { const { adapterId, formId } = data; if (adapterId.length > 0 && formId.length > 0) { - return this.formService.getFormData(adapterId, formId).pipe( - map(([ UISchema, JSONSchema ]) => ({ UISchema, JSONSchema })) - ); + return this.formService + .getFormData(adapterId, formId) + .pipe( + map(([UISchema, JSONSchema]) => ({ UISchema, JSONSchema })), + ); } } return of(false); - }) + }), ); } selectSwagger(): Observable { const dialogRef = this.dialog.open(SwaggerFormSelectDialogComponent); return dialogRef.afterClosed().pipe( - switchMap(data => { + switchMap((data) => { if (!!data) { return of({ UISchema: {}, JSONSchema: data }); } return of(false); - }) + }), ); } } diff --git a/src/app/services/adapter-install.service.ts b/src/app/services/adapter-install.service.ts index 8a3176365..42717c3ba 100644 --- a/src/app/services/adapter-install.service.ts +++ b/src/app/services/adapter-install.service.ts @@ -1,187 +1,257 @@ -import { Injectable } from '@angular/core'; -import {HttpClient} from '@angular/common/http'; -import {LocalDatabaseService} from './local-database.service'; -import {findIndex, get, has} from 'lodash-es'; -import {AppSettingsService} from './app-settings.service'; -import { MatSnackBar } from '@angular/material/snack-bar'; -import * as LZS from 'lz-string'; +import { Injectable } from "@angular/core"; +import { HttpClient } from "@angular/common/http"; +import { LocalDatabaseService } from "./local-database.service"; +import { findIndex, get, has } from "lodash-es"; +import { AppSettingsService } from "./app-settings.service"; +import { MatSnackBar } from "@angular/material/snack-bar"; +import * as LZS from "lz-string"; @Injectable({ - providedIn: 'root' + providedIn: "root", }) export class AdapterInstallService { - constructor( private readonly http: HttpClient, private readonly localData: LocalDatabaseService, private readonly settings: AppSettingsService, - private readonly notify: MatSnackBar - ) { } + private readonly notify: MatSnackBar, + ) {} addNewAdapter(adapter) { - const errorReporter = params => err => console.error('db error', err.message, params); + const errorReporter = (params) => (err) => + console.error("db error", err.message, params); // console.log({ adapter }); - this.localData['adapters'] - .add({ ...adapter, name: get(adapter, 'adapterName'), modified: false }) + this.localData["adapters"] + .add({ ...adapter, name: get(adapter, "adapterName"), modified: false }) .then(() => { - this.notify.open('Saved adapter', 'OK', { verticalPosition: 'top', horizontalPosition: 'center', duration: 2000 }); + this.notify.open("Saved adapter", "OK", { + verticalPosition: "top", + horizontalPosition: "center", + duration: 2000, + }); }) .catch(errorReporter(adapter)); } addNewWorkflow(workflow) { const { adapterName, workflowId, title } = workflow; - const errorReporter = params => err => console.error('db error', err.message, params); + const errorReporter = (params) => (err) => + console.error("db error", err.message, params); // console.log({ workflow }); - this.localData['workflows'] + this.localData["workflows"] .add({ ...workflow, adapterName, workflowId, title, blocks: [] }) .catch(errorReporter(workflow)) .then(() => { - this.localData['adapters'].get(adapterName).then(adapter => { - const workflowMeta = get(adapter, 'workflow', []); + this.localData["adapters"].get(adapterName).then((adapter) => { + const workflowMeta = get(adapter, "workflow", []); workflowMeta.push({ ...workflow, modified: false }); - this.localData['adapters'].update(adapterName, { ...adapter, workflow: workflowMeta, modified: true }).then(() => { - this.notify.open('Saved workflow', 'OK', { verticalPosition: 'top', horizontalPosition: 'center', duration: 2000 }); - }); + this.localData["adapters"] + .update(adapterName, { + ...adapter, + workflow: workflowMeta, + modified: true, + }) + .then(() => { + this.notify.open("Saved workflow", "OK", { + verticalPosition: "top", + horizontalPosition: "center", + duration: 2000, + }); + }); }); }); } async cloneAdapter(payload) { const { sourceAdapter, sourceId, targetAdapter, targetId } = payload; - const workflow = get(await this.localData['workflows'].where({adapterName: sourceAdapter, workflowId: sourceId}).toArray(), '[0]', {}); + const workflow = get( + await this.localData["workflows"] + .where({ adapterName: sourceAdapter, workflowId: sourceId }) + .toArray(), + "[0]", + {}, + ); - const errorReporter = params => err => console.error('db error', err.message, params); - this.localData['workflows'] + const errorReporter = (params) => (err) => + console.error("db error", err.message, params); + this.localData["workflows"] .add({ ...workflow, adapterName: targetAdapter, workflowId: targetId }) .catch(errorReporter(workflow)) .then(() => { - this.localData['adapters'].get(targetAdapter).then(adapter => { - const workflowMeta = get(adapter, 'workflow', []); - workflowMeta.push({ adapterName: targetAdapter, workflowId: targetId, title: workflow.title, modified: false }); - this.localData['adapters'].update(targetAdapter, { ...adapter, workflow: workflowMeta, modified: true }).then(() => { - this.notify.open('Saved workflow', 'OK', { verticalPosition: 'top', horizontalPosition: 'center', duration: 2000 }); + this.localData["adapters"].get(targetAdapter).then((adapter) => { + const workflowMeta = get(adapter, "workflow", []); + workflowMeta.push({ + adapterName: targetAdapter, + workflowId: targetId, + title: workflow.title, + modified: false, }); + this.localData["adapters"] + .update(targetAdapter, { + ...adapter, + workflow: workflowMeta, + modified: true, + }) + .then(() => { + this.notify.open("Saved workflow", "OK", { + verticalPosition: "top", + horizontalPosition: "center", + duration: 2000, + }); + }); }); }); } async packageAdapter(adapterConfig) { // console.log({adapterConfig}); - const {adapterName} = adapterConfig; + const { adapterName } = adapterConfig; // const compressed = LZS.compressToEncodedURIComponent(JSON.stringify(adapterConfig)); - const database = get(adapterConfig, 'database', []) - .map(item => ({ ...item, schema: `schemas/${item.schemaName}.json`})); - const workflow = get(adapterConfig, 'workflow', []) - .map(item => ({ ...item, config: `configs/${item.workflowId}.json`})); - const forms = get(adapterConfig, 'forms', []) - .map(item => ({ ...item, jsonSchema: `jsonSchema/${item.formId}.json`, uiSchema: `uiSchema/${item.formId}.json`})); + const database = get(adapterConfig, "database", []).map((item) => ({ + ...item, + schema: `schemas/${item.schemaName}.json`, + })); + const workflow = get(adapterConfig, "workflow", []).map((item) => ({ + ...item, + config: `configs/${item.workflowId}.json`, + })); + const forms = get(adapterConfig, "forms", []).map((item) => ({ + ...item, + jsonSchema: `jsonSchema/${item.formId}.json`, + uiSchema: `uiSchema/${item.formId}.json`, + })); const attachments = {}; - const databaseConfigs = await this.localData['schemas'].where({adapterName}).toArray(); - databaseConfigs.forEach(item => { + const databaseConfigs = await this.localData["schemas"] + .where({ adapterName }) + .toArray(); + databaseConfigs.forEach((item) => { attachments[`schemas/${item.schemaName}.json`] = item; }); - const workflowConfigs = await this.localData['workflows'].where({adapterName}).toArray(); - workflowConfigs.forEach(item => { + const workflowConfigs = await this.localData["workflows"] + .where({ adapterName }) + .toArray(); + workflowConfigs.forEach((item) => { attachments[`configs/${item.workflowId}.json`] = item; }); - const formConfigs = await this.localData['forms'].where({adapterName}).toArray(); - formConfigs.forEach(item => { + const formConfigs = await this.localData["forms"] + .where({ adapterName }) + .toArray(); + formConfigs.forEach((item) => { attachments[`jsonSchema/${item.formId}.json`] = item.jsonSchema; attachments[`uiSchema/${item.formId}.json`] = item.uiSchema; }); - const exportData = {...adapterConfig, workflow, database, forms, attachments}; + const exportData = { + ...adapterConfig, + workflow, + database, + forms, + attachments, + }; return exportData; } async exportAdapter(adapterConfig) { - const {adapterName} = adapterConfig; - this.packageAdapter(adapterConfig).then(exportData => { + const { adapterName } = adapterConfig; + this.packageAdapter(adapterConfig).then((exportData) => { this.downloadData(exportData, adapterName); }); } downloadData(outputData, fileName) { - const blob = new Blob([JSON.stringify(outputData, null, 2)], { type: `application/json;charset=utf-8;` }); - const link = document.createElement('a'); - if (link.download !== undefined) { // feature detection + const blob = new Blob([JSON.stringify(outputData, null, 2)], { + type: `application/json;charset=utf-8;`, + }); + const link = document.createElement("a"); + if (link.download !== undefined) { + // feature detection // Browsers that support HTML5 download attribute const url = URL.createObjectURL(blob); - link.setAttribute('href', url); - link.setAttribute('download', `${fileName}.json`); - link.style.visibility = 'hidden'; + link.setAttribute("href", url); + link.setAttribute("download", `${fileName}.json`); + link.style.visibility = "hidden"; document.body.appendChild(link); link.click(); document.body.removeChild(link); } } - - importAdapter({ attachments, ...adapterConfig }) { // const decompressed = LZS.decompressFromEncodedURIComponent(data); // return JSON.parse(decompressed); - const adapterName = get(adapterConfig, 'name'); + const adapterName = get(adapterConfig, "name"); if (!adapterName) { - throw new Error('Adapter config does not have a name property'); + throw new Error("Adapter config does not have a name property"); } - const errorReporter = params => err => console.error('db error', err.message, params); + const errorReporter = (params) => (err) => + console.error("db error", err.message, params); // Load in main adapter metadata - this.localData['adapters'] + this.localData["adapters"] .add({ ...adapterConfig, adapterName, modified: false }) .catch(errorReporter({ adapterName })); // Load in adapter dashboard route location - if (has(adapterConfig, 'dashboard')) { - this.localData['dashboards'] - .add({ ...get(adapterConfig, 'dashboard'), adapterName }) - .catch(errorReporter({ type: 'dashboard', adapterName })); + if (has(adapterConfig, "dashboard")) { + this.localData["dashboards"] + .add({ ...get(adapterConfig, "dashboard"), adapterName }) + .catch(errorReporter({ type: "dashboard", adapterName })); } // Load services menu items - const services = get(adapterConfig, 'services', []); - this.localData['services'] + const services = get(adapterConfig, "services", []); + this.localData["services"] .add({ services, adapterName }) - .catch(errorReporter({ type: 'services', adapterName })); + .catch(errorReporter({ type: "services", adapterName })); // Load in database schemas - const schemas = get(adapterConfig, 'database', []); + const schemas = get(adapterConfig, "database", []); schemas.forEach(({ name: schemaName, schema }) => { const schemaConfig = get(attachments, schema, {}); - this.localData['schemas'] + this.localData["schemas"] .add({ ...schemaConfig, schemaName, adapterName }) .catch(errorReporter({ schema })); }); // Load in workflow configs - const workflows = get(adapterConfig, 'workflow', []); + const workflows = get(adapterConfig, "workflow", []); workflows.forEach(({ title, workflowId, config }) => { const workflowConfig = get(attachments, config, {}); - this.localData['workflows'] - .add({ ...workflowConfig, title, workflowId, adapterName, modified: false }) + this.localData["workflows"] + .add({ + ...workflowConfig, + title, + workflowId, + adapterName, + modified: false, + }) .catch(errorReporter({ workflowId })); }); // Load in form configs - const forms = get(adapterConfig, 'forms', []); + const forms = get(adapterConfig, "forms", []); forms.forEach(({ formId, title, jsonSchema, uiSchema }) => { - const jsonSchemaConfig = get(attachments, jsonSchema, {}); + const jsonSchemaConfig = get(attachments, jsonSchema, {}); const uiSchemaConfig = get(attachments, uiSchema, {}); - this.localData['forms'] - .add({ formId, title, jsonSchema: jsonSchemaConfig, uiSchema: uiSchemaConfig, adapterName }) + this.localData["forms"] + .add({ + formId, + title, + jsonSchema: jsonSchemaConfig, + uiSchema: uiSchemaConfig, + adapterName, + }) .catch(errorReporter({ formId })); }); // Load in API configs - const apis = get(adapterConfig, 'apis', []); + const apis = get(adapterConfig, "apis", []); apis.forEach((apiPath) => { const apiConfig = get(attachments, apiPath, {}); - this.localData['apis'] + this.localData["apis"] .add({ adapterName, apiPath, apiConfig }) .catch(errorReporter({ apiPath })); }); @@ -189,7 +259,8 @@ export class AdapterInstallService { install({ repoUrl, name }) { // console.log(`Installing ${name} from ${repoUrl}`); - this.http.get(`${repoUrl}${name}.json`, { responseType: 'json' }) + this.http + .get(`${repoUrl}${name}.json`, { responseType: "json" }) .subscribe(({ attachments, ...adapterConfig }) => { this.importAdapter({ attachments, ...adapterConfig }); setTimeout(() => this.settings.settingsUpdated$.next(), 400); @@ -197,12 +268,12 @@ export class AdapterInstallService { } uninstall({ name: adapterName }) { - this.localData['adapters'].where({ adapterName }).delete(); - this.localData['dashboards'].where({ adapterName }).delete(); - this.localData['services'].where({ adapterName }).delete(); - this.localData['schemas'].where({ adapterName }).delete(); - this.localData['forms'].where({ adapterName }).delete(); - this.localData['workflows'].where({ adapterName }).delete(); - this.localData['apis'].where({ adapterName }).delete(); + this.localData["adapters"].where({ adapterName }).delete(); + this.localData["dashboards"].where({ adapterName }).delete(); + this.localData["services"].where({ adapterName }).delete(); + this.localData["schemas"].where({ adapterName }).delete(); + this.localData["forms"].where({ adapterName }).delete(); + this.localData["workflows"].where({ adapterName }).delete(); + this.localData["apis"].where({ adapterName }).delete(); } } diff --git a/src/app/services/form-data.service.ts b/src/app/services/form-data.service.ts index 9dda4c329..e96c912e1 100644 --- a/src/app/services/form-data.service.ts +++ b/src/app/services/form-data.service.ts @@ -1,92 +1,92 @@ -import { Injectable } from '@angular/core'; -import {of} from 'rxjs'; -import { MatDialog } from '@angular/material/dialog'; -import { MatSnackBar } from '@angular/material/snack-bar'; -import {FormDataSelectDialogComponent} from '../dialogs/form-data-select-dialog/form-data-select-dialog.component'; -import {DocumentRepositoryService} from './document-repository.service'; -import {map, switchMap, tap} from 'rxjs/operators'; -import {get, has} from 'lodash-es'; -import {ApiDataSelectDialogComponent} from '../dialogs/api-data-select-dialog/api-data-select-dialog.component'; -import {HttpClient} from '@angular/common/http'; +import { Injectable } from "@angular/core"; +import { of } from "rxjs"; +import { MatDialog } from "@angular/material/dialog"; +import { MatSnackBar } from "@angular/material/snack-bar"; +import { FormDataSelectDialogComponent } from "../dialogs/form-data-select-dialog/form-data-select-dialog.component"; +import { DocumentRepositoryService } from "./document-repository.service"; +import { map, switchMap, tap } from "rxjs/operators"; +import { get, has } from "lodash-es"; +import { ApiDataSelectDialogComponent } from "../dialogs/api-data-select-dialog/api-data-select-dialog.component"; +import { HttpClient } from "@angular/common/http"; @Injectable({ - providedIn: 'root' + providedIn: "root", }) export class FormDataService { - constructor( private readonly dialog: MatDialog, private readonly notify: MatSnackBar, private readonly database: DocumentRepositoryService, - private readonly http: HttpClient - ) { } + private readonly http: HttpClient, + ) {} loadDataFromAPI() { const dialogRef = this.dialog.open(ApiDataSelectDialogComponent); return dialogRef.afterClosed().pipe( - map(data => { + map((data) => { if (!!data) { const { endpoint, values } = data; return { status: true, endpoint, values }; } - return { status: false, endpoint: '', values: {}}; - }) + return { status: false, endpoint: "", values: {} }; + }), ); } loadData(schemaName) { return this.database.listAllOfType(schemaName).pipe( - switchMap(docs => { + switchMap((docs) => { const dialogRef = this.dialog.open(FormDataSelectDialogComponent, { data: { schemaName, - docs + docs, }, }); return dialogRef.afterClosed().pipe( - switchMap(values => { - if (!!values && has(values, 'id')) { - return this.database.getDoc(get(values, 'id')); + switchMap((values) => { + if (!!values && has(values, "id")) { + return this.database.getDoc(get(values, "id")); } return of(false); - }) + }), ); - }) + }), ); } saveData(schemaName, values) { - return this.database.putDoc({ '@schema': schemaName, ... values}) - .pipe(tap(({ ok }) => { + return this.database.putDoc({ "@schema": schemaName, ...values }).pipe( + tap(({ ok }) => { if (ok) { - const message = 'Database update successful'; - this.notify.open(message, 'OK', { + const message = "Database update successful"; + this.notify.open(message, "OK", { duration: 4000, - verticalPosition: 'top' + verticalPosition: "top", }); } - })); + }), + ); } saveAPIData(endpoint, data) { - return this.http.put(`${endpoint}/${data['id']}`, data).pipe( + return this.http.put(`${endpoint}/${data["id"]}`, data).pipe( tap((ok) => { if (ok) { - const message = 'API update successful'; - this.notify.open(message, 'OK', { + const message = "API update successful"; + this.notify.open(message, "OK", { duration: 4000, - verticalPosition: 'top' + verticalPosition: "top", }); } - }) + }), ); } noSchemaName() { - const message = 'No schema name provided'; - this.notify.open(message, 'OK', { + const message = "No schema name provided"; + this.notify.open(message, "OK", { duration: 4000, - verticalPosition: 'top' + verticalPosition: "top", }); } } diff --git a/src/app/services/global-error-handler.service.ts b/src/app/services/global-error-handler.service.ts index 966a397b8..1fda5ad9a 100644 --- a/src/app/services/global-error-handler.service.ts +++ b/src/app/services/global-error-handler.service.ts @@ -1,22 +1,21 @@ -import { Injectable, ErrorHandler } from '@angular/core'; -import { MatSnackBar } from '@angular/material/snack-bar'; -import {Subject} from 'rxjs'; -import {debounceTime, throttleTime} from 'rxjs/operators'; +import { Injectable, ErrorHandler } from "@angular/core"; +import { MatSnackBar } from "@angular/material/snack-bar"; +import { Subject } from "rxjs"; +import { debounceTime, throttleTime } from "rxjs/operators"; @Injectable() export class GlobalErrorHandlerService implements ErrorHandler { - error$ = new Subject(); - constructor( - private readonly notify: MatSnackBar - ) { - this.error$.pipe( - throttleTime(4000) - ).subscribe((error: any) => { + constructor(private readonly notify: MatSnackBar) { + this.error$.pipe(throttleTime(4000)).subscribe((error: any) => { this.notify.dismiss(); if (error.message && error.message.length > 0) { - this.notify.open(error.message, 'Dismiss', { horizontalPosition: 'center', verticalPosition: 'top', duration: 4000 }); + this.notify.open(error.message, "Dismiss", { + horizontalPosition: "center", + verticalPosition: "top", + duration: 4000, + }); } }); } diff --git a/src/app/services/share-link-generator.service.ts b/src/app/services/share-link-generator.service.ts index c1f9a6df0..7b33b8fb5 100644 --- a/src/app/services/share-link-generator.service.ts +++ b/src/app/services/share-link-generator.service.ts @@ -1,63 +1,65 @@ -import { Injectable } from '@angular/core'; -import { environment } from '../../environments/environment'; -import * as LZS from 'lz-string'; -import { MatDialog } from '@angular/material/dialog'; -import { ShowShareLinkDialogComponent } from '../dialogs/show-share-link-dialog/show-share-link-dialog.component'; -import { LocalDatabaseService } from '../services/local-database.service'; +import { Injectable } from "@angular/core"; +import { environment } from "../../environments/environment"; +import * as LZS from "lz-string"; +import { MatDialog } from "@angular/material/dialog"; +import { ShowShareLinkDialogComponent } from "../dialogs/show-share-link-dialog/show-share-link-dialog.component"; +import { LocalDatabaseService } from "../services/local-database.service"; @Injectable({ - providedIn: 'root' + providedIn: "root", }) export class ShareLinkGeneratorService { - constructor( private readonly dialog: MatDialog, - private readonly localDatabase: LocalDatabaseService - ) { } + private readonly localDatabase: LocalDatabaseService, + ) {} async shareFlowLink(path, flowData) { //environment.urlPrefix = 'http://127.0.0.1:4200/'; - const compressed_flow = LZS.compressToEncodedURIComponent(JSON.stringify(flowData)); + const compressed_flow = LZS.compressToEncodedURIComponent( + JSON.stringify(flowData), + ); const flowShareLink = `${environment.urlPrefix}${path}?data=${compressed_flow}`; const json_metadata_string = await this.localDatabase.exportMetadataTable(); - const compressed_database = LZS.compressToEncodedURIComponent(json_metadata_string); + const compressed_database = + LZS.compressToEncodedURIComponent(json_metadata_string); const dbShareLink = `${environment.urlPrefix}${path}?metadata=${compressed_database}`; this.dialog.open(ShowShareLinkDialogComponent, { data: { flowShareLink: flowShareLink, - dbShareLink: dbShareLink - } + dbShareLink: dbShareLink, + }, }); } getData() { const url = new URL(window.location.href); - const data = url.searchParams.get('data'); + const data = url.searchParams.get("data"); if (!!data) { const decompressed = LZS.decompressFromEncodedURIComponent(data); return JSON.parse(decompressed); } - const metadata = url.searchParams.get('metadata'); + const metadata = url.searchParams.get("metadata"); if (!!metadata) { const decompressed = LZS.decompressFromEncodedURIComponent(metadata); const parsed = JSON.parse(decompressed); if (parsed.length === 0) { - throw new Error('The metadata table is empty.'); + throw new Error("The metadata table is empty."); } console.dir(parsed); - const response = confirm("Do you want to replace your metadata table with the one from the share link? WARNING: You may lose data."); + const response = confirm( + "Do you want to replace your metadata table with the one from the share link? WARNING: You may lose data.", + ); if (response == true) { this.localDatabase.importMetadataTable(parsed); return true; - } - else { + } else { return false; } } return false; } - } diff --git a/src/app/services/workflow.service.ts b/src/app/services/workflow.service.ts index 741ee4316..585d22965 100644 --- a/src/app/services/workflow.service.ts +++ b/src/app/services/workflow.service.ts @@ -1,41 +1,39 @@ -import { Injectable } from '@angular/core'; -import {NavigationEnd, Router} from '@angular/router'; -import {filter, take, tap, withLatestFrom} from 'rxjs/operators'; -import {ExportConfigDialogComponent} from '../dialogs/export-config-dialog/export-config-dialog.component'; -import * as stringify from 'json-stringify-safe'; -import {PasteConfigDialogComponent} from '../dialogs/paste-config-dialog/paste-config-dialog.component'; -import {clone, findIndex, get, has, isArray, pick, set} from 'lodash-es'; -import { MatDialog } from '@angular/material/dialog'; -import { MatSnackBar } from '@angular/material/snack-bar'; -import {PageTitleService} from './page-title.service'; -import {AdaptersService} from './adapters.service'; +import { Injectable } from "@angular/core"; +import { NavigationEnd, Router } from "@angular/router"; +import { filter, take, tap, withLatestFrom } from "rxjs/operators"; +import { ExportConfigDialogComponent } from "../dialogs/export-config-dialog/export-config-dialog.component"; +import * as stringify from "json-stringify-safe"; +import { PasteConfigDialogComponent } from "../dialogs/paste-config-dialog/paste-config-dialog.component"; +import { clone, findIndex, get, has, isArray, pick, set } from "lodash-es"; +import { MatDialog } from "@angular/material/dialog"; +import { MatSnackBar } from "@angular/material/snack-bar"; +import { PageTitleService } from "./page-title.service"; +import { AdaptersService } from "./adapters.service"; // tslint:disable-next-line:import-spacing -import {AdapterBlocksConfigSelectDialogComponent} from - '../dialogs/adapter-blocks-config-select-dialog/adapter-blocks-config-select-dialog.component'; -import {ShareLinkGeneratorService} from './share-link-generator.service'; -import {LoadWorkflowDialogComponent} from '../dialogs/load-workflow-dialog/load-workflow-dialog.component'; -import {SaveWorkflowDialogComponent} from '../dialogs/save-workflow-dialog/save-workflow-dialog.component'; -import {EditWorkflowMetadataDialogComponent} from '../dialogs/edit-workflow-metadata-dialog/edit-workflow-metadata-dialog.component'; -import {LocalDatabaseService} from './local-database.service'; -import { camelCase } from 'lodash-es'; -import {ConnectionManagerService} from './connection-manager.service'; -import {WorkflowRepoService} from './workflow-repo.service'; +import { AdapterBlocksConfigSelectDialogComponent } from "../dialogs/adapter-blocks-config-select-dialog/adapter-blocks-config-select-dialog.component"; +import { ShareLinkGeneratorService } from "./share-link-generator.service"; +import { LoadWorkflowDialogComponent } from "../dialogs/load-workflow-dialog/load-workflow-dialog.component"; +import { SaveWorkflowDialogComponent } from "../dialogs/save-workflow-dialog/save-workflow-dialog.component"; +import { EditWorkflowMetadataDialogComponent } from "../dialogs/edit-workflow-metadata-dialog/edit-workflow-metadata-dialog.component"; +import { LocalDatabaseService } from "./local-database.service"; +import { camelCase } from "lodash-es"; +import { ConnectionManagerService } from "./connection-manager.service"; +import { WorkflowRepoService } from "./workflow-repo.service"; -const DEFAULT_ADAPTER_NAME = 'Adapter name'; +const DEFAULT_ADAPTER_NAME = "Adapter name"; @Injectable({ - providedIn: 'root' + providedIn: "root", }) export class WorkflowService { - - title = ''; + title = ""; id; blocks = []; models = []; context = {}; tags = []; - dirty:boolean = false; // has this workflow been modified since last load/save? + dirty: boolean = false; // has this workflow been modified since last load/save? constructor( private readonly router: Router, @@ -51,42 +49,54 @@ export class WorkflowService { this.router.events .pipe( filter((e): e is NavigationEnd => e instanceof NavigationEnd), - filter(({ url }) => url === '/workflow-builder') + filter(({ url }) => url === "/workflow-builder"), ) - .subscribe(_ => this.loadState()); + .subscribe((_) => this.loadState()); } initBlocks({ isBuilder }) { const urlData = this.shareLinks.getData(); if (urlData && isArray(urlData)) { this.blocks = urlData; - this.initWorkflow({ title: 'Flow name', blocks: urlData, context: {}, tags: [] }, true); + this.initWorkflow( + { title: "Flow name", blocks: urlData, context: {}, tags: [] }, + true, + ); } } loadState() { - const state = JSON.parse(localStorage.getItem('kendraio-workflow-state')); - const title = get(state, 'title', 'Flow name'); - const blocks = get(state, 'blocks', []); - const context = get(state, 'context', {}); - const tags = get(state, 'tags', []); + const state = JSON.parse(localStorage.getItem("kendraio-workflow-state")); + const title = get(state, "title", "Flow name"); + const blocks = get(state, "blocks", []); + const context = get(state, "context", {}); + const tags = get(state, "tags", []); this.initWorkflow({ title, blocks, context, tags }); - this.id = get(state, 'id', false); - set(this.context, 'app.adapterName', get(state, 'adapterName', this.getAdapterName())); + this.id = get(state, "id", false); + set( + this.context, + "app.adapterName", + get(state, "adapterName", this.getAdapterName()), + ); } saveState() { const { title, blocks, context, id } = this; const adapterName = this.getAdapterName(); this.workflowRepo.clearCacheFor(adapterName, id); - localStorage.setItem('kendraio-workflow-state', JSON.stringify({ title, blocks, context, id, adapterName })); + localStorage.setItem( + "kendraio-workflow-state", + JSON.stringify({ title, blocks, context, id, adapterName }), + ); } refresh() { // TODO: disabled this as was triggering a full workflow re-load // this.pageTitle.onRefresh(); // ... when this refresh call should just re-init the running workflow - this.models = this.blocks.map(blockDef => get(blockDef, 'defaultValue', {})); + this.models = this.blocks.map((blockDef) => + get(blockDef, "defaultValue", {}), + ); this.models.push({}); // TODO: this is a partial refresh of context data, but needs refactoring // set(this.context, 'adapters', this.adapters.getAdaptersInfo()); @@ -101,51 +111,68 @@ export class WorkflowService { clearBlocks() { this.blocks = []; - this.id = ''; - this.title = 'Flow'; - set(this.context, 'app.adapterName', undefined); + this.id = ""; + this.title = "Flow"; + set(this.context, "app.adapterName", undefined); this.saveState(); - this.router.navigate(['/workflow-builder']); + this.router.navigate(["/workflow-builder"]); } clearWorkflowData() { - this.models = this.blocks.map(blockDef => get(blockDef, 'defaultValue', {})); + this.models = this.blocks.map((blockDef) => + get(blockDef, "defaultValue", {}), + ); this.models.push({}); } copyConfig() { const dialogRef = this.dialog.open(ExportConfigDialogComponent, { data: { - configText: stringify({ title: this.title, blocks: this.blocks, id: this.id, adapterName: this.getAdapterName() }, null, 2) - } + configText: stringify( + { + title: this.title, + blocks: this.blocks, + id: this.id, + adapterName: this.getAdapterName(), + }, + null, + 2, + ), + }, }); } pasteConfig() { const dialogRef = this.dialog.open(PasteConfigDialogComponent, {}); - dialogRef.afterClosed().subscribe(value => { + dialogRef.afterClosed().subscribe((value) => { if (!!value) { - this.router.navigate(['/workflow-builder']).then(() => { + this.router.navigate(["/workflow-builder"]).then(() => { try { const config = JSON.parse(value); - if (has(config, 'blocks')) { - this.router.routerState.root.queryParams.pipe( - take(1), - withLatestFrom(this.router.routerState.root.fragment) - ).subscribe(([queryParams, fragment]) => { - this.initWorkflow({ - title: get(config, 'title', 'Imported config'), - blocks: get(config, 'blocks', []), - context: {queryParams, fragment}, - tags: get(config, 'tags', []) + if (has(config, "blocks")) { + this.router.routerState.root.queryParams + .pipe( + take(1), + withLatestFrom(this.router.routerState.root.fragment), + ) + .subscribe(([queryParams, fragment]) => { + this.initWorkflow({ + title: get(config, "title", "Imported config"), + blocks: get(config, "blocks", []), + context: { queryParams, fragment }, + tags: get(config, "tags", []), + }); + this.id = get(config, "id"); + set( + this.context, + "app.adapterName", + get(config, "adapterName", DEFAULT_ADAPTER_NAME), + ); + this.saveState(); }); - this.id = get(config, 'id'); - set(this.context, 'app.adapterName', get(config, 'adapterName', DEFAULT_ADAPTER_NAME)); - this.saveState(); - }); } } catch (e) { - console.log('Error importing config', e); + console.log("Error importing config", e); } }); } @@ -159,15 +186,30 @@ export class WorkflowService { this.blocks = blocks; this.tags = tags || []; this.context = clone(context); - set(this.context, 'app.location', pick(location, ['origin', 'protocol', 'host', 'port', 'pathname', 'search', 'hash', 'href'])); + set( + this.context, + "app.location", + pick(location, [ + "origin", + "protocol", + "host", + "port", + "pathname", + "search", + "hash", + "href", + ]), + ); this.connectionManager.addToContext(this.context); this.id = this.getWorkflowId(); - this.models = this.blocks.map(blockDef => get(blockDef, 'defaultValue', {})); + this.models = this.blocks.map((blockDef) => + get(blockDef, "defaultValue", {}), + ); this.models.push({}); if (isBuilder) { this.saveState(); } - if (this.tags.includes('app')) { + if (this.tags.includes("app")) { this.pageTitle.enableAppLayout(); } else { this.pageTitle.disableAppLayout(); @@ -175,51 +217,88 @@ export class WorkflowService { } shareConfig() { - this.shareLinks.shareFlowLink('workflow-builder', this.blocks); + this.shareLinks.shareFlowLink("workflow-builder", this.blocks); } loadFromAdapter() { - const dialogRef = this.dialog.open(AdapterBlocksConfigSelectDialogComponent, { - data: {} - }); - dialogRef.afterClosed().subscribe(values => { + const dialogRef = this.dialog.open( + AdapterBlocksConfigSelectDialogComponent, + { + data: {}, + }, + ); + dialogRef.afterClosed().subscribe((values) => { if (!!values) { this.initWorkflow({ ...values, context: {} }); - set(this.context, 'app.adapterName', get(values, 'adapterName', this.getAdapterName())); + set( + this.context, + "app.adapterName", + get(values, "adapterName", this.getAdapterName()), + ); } }); } saveToAdapter() { - this.localData['workflows'] - .where('[adapterName+workflowId]') + this.localData["workflows"] + .where("[adapterName+workflowId]") .equals([this.getAdapterName() || DEFAULT_ADAPTER_NAME, this.id]) - .modify({ blocks: this.blocks, title: this.title, workflowId: this.id, modified: true }) + .modify({ + blocks: this.blocks, + title: this.title, + workflowId: this.id, + modified: true, + }) .then(() => { - this.localData['adapters'].get(this.getAdapterName()).then(adapter => { - const workflow = get(adapter, 'workflow', []); - const workflowIndex = findIndex(workflow, ({ workflowId }) => workflowId === this.id); - if (workflowIndex !== -1) { - workflow[workflowIndex] = { ...workflow[workflowIndex], title: this.title, modified: true }; - } - this.localData['adapters'].update(this.getAdapterName(), { ...adapter, workflow, modified: true }).then(() => { - this.notify.open('Saved workflow', 'OK', { verticalPosition: 'top', horizontalPosition: 'center', duration: 2000 }); + this.localData["adapters"] + .get(this.getAdapterName()) + .then((adapter) => { + const workflow = get(adapter, "workflow", []); + const workflowIndex = findIndex( + workflow, + ({ workflowId }) => workflowId === this.id, + ); + if (workflowIndex !== -1) { + workflow[workflowIndex] = { + ...workflow[workflowIndex], + title: this.title, + modified: true, + }; + } + this.localData["adapters"] + .update(this.getAdapterName(), { + ...adapter, + workflow, + modified: true, + }) + .then(() => { + this.notify.open("Saved workflow", "OK", { + verticalPosition: "top", + horizontalPosition: "center", + duration: 2000, + }); + }); }); - }); }) - .catch(error => console.log({ error })); + .catch((error) => console.log({ error })); } upload() { const { title, blocks, id, tags } = this; const dialogRef = this.dialog.open(SaveWorkflowDialogComponent, { disableClose: true, - data: { title, blocks, id: camelCase(id), adapterName: this.getAdapterName(), tags } + data: { + title, + blocks, + id: camelCase(id), + adapterName: this.getAdapterName(), + tags, + }, }); - dialogRef.afterClosed().subscribe(values => { + dialogRef.afterClosed().subscribe((values) => { if (!!values) { // console.log(values); - this.id = get(values, 'id', this.id); + this.id = get(values, "id", this.id); this.saveState(); this.dirty = false; } @@ -228,16 +307,20 @@ export class WorkflowService { download() { const dialogRef = this.dialog.open(LoadWorkflowDialogComponent); - dialogRef.afterClosed().subscribe(values => { + dialogRef.afterClosed().subscribe((values) => { if (!!values) { // console.log(values); - const blocks = get(values, 'blocks', []); - const tags = get(values, 'tags', []); - const title = get(values, 'title', 'Flow'); + const blocks = get(values, "blocks", []); + const tags = get(values, "tags", []); + const title = get(values, "title", "Flow"); this.initWorkflow({ title, blocks, context: {}, tags }); - this.id = get(values, 'id'); - this.tags = get(values, 'tags', []); - set(this.context, 'app.adapterName', get(values, 'adapterName', this.getAdapterName())); + this.id = get(values, "id"); + this.tags = get(values, "tags", []); + set( + this.context, + "app.adapterName", + get(values, "adapterName", this.getAdapterName()), + ); this.saveState(); } }); @@ -247,14 +330,18 @@ export class WorkflowService { const { title, id, tags } = this; const dialogRef = this.dialog.open(EditWorkflowMetadataDialogComponent, { disableClose: true, - data: { title, id, adapterName: this.getAdapterName(), tags } + data: { title, id, adapterName: this.getAdapterName(), tags }, }); - dialogRef.afterClosed().subscribe(values => { + dialogRef.afterClosed().subscribe((values) => { if (!!values) { - this.title = get(values, 'title', 'Flow'); - this.id = get(values, 'id'); - this.tags = get(values, 'tags'); - set(this.context, 'app.adapterName', get(values, 'adapterName', this.getAdapterName())); + this.title = get(values, "title", "Flow"); + this.id = get(values, "id"); + this.tags = get(values, "tags"); + set( + this.context, + "app.adapterName", + get(values, "adapterName", this.getAdapterName()), + ); this.saveState(); this.dirty = true; } @@ -262,10 +349,10 @@ export class WorkflowService { } getAdapterName() { - return get(this.context, 'app.adapterName', 'Adapter name'); + return get(this.context, "app.adapterName", "Adapter name"); } getWorkflowId() { - return get(this.context, 'app.workflowId'); + return get(this.context, "app.workflowId"); } } diff --git a/src/styles.scss b/src/styles.scss index d0ed04415..864e14e28 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -1,6 +1,6 @@ -@use '@angular/material' as mat; -@import '../node_modules/ag-grid-community/styles/ag-theme-alpine.css'; -@import '../node_modules/ag-grid-community/styles/ag-grid.css'; +@use "@angular/material" as mat; +@import "../node_modules/ag-grid-community/styles/ag-theme-alpine.css"; +@import "../node_modules/ag-grid-community/styles/ag-grid.css"; @import "@fortawesome/fontawesome-free/css/all.css"; // Custom Theming for Angular Material @@ -21,7 +21,7 @@ @include mat.all-legacy-component-typographies(); @include mat.legacy-core(); -@import '@angular/material/theming'; +@import "@angular/material/theming"; @include mat-core(); // Define the palettes for your theme using the Material Design palettes available in palette.scss @@ -34,16 +34,17 @@ $kendraio-app-accent: mat.define-palette(mat.$orange-palette, A200, A100, A400); $kendraio-app-warn: mat.define-palette(mat.$red-palette); // Create the theme object (a Sass map containing all of the palettes). -$kendraio-app-theme: mat.define-light-theme(( - color: ( - primary: $kendraio-app-primary, - accent: $kendraio-app-accent, - warn: $kendraio-app-warn - ), - typography: mat.define-typography-config(), - density: 0, -)); - +$kendraio-app-theme: mat.define-light-theme( + ( + color: ( + primary: $kendraio-app-primary, + accent: $kendraio-app-accent, + warn: $kendraio-app-warn, + ), + typography: mat.define-typography-config(), + density: 0, + ) +); // Include theme styles for core and each component used in your app. // Alternatively, you can import and @include the theme mixins for each component @@ -51,9 +52,15 @@ $kendraio-app-theme: mat.define-light-theme(( @include mat.all-legacy-component-themes($kendraio-app-theme); @include angular-material-theme($kendraio-app-theme); - -html, body { height: 100%; overflow: hidden; } -body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } +html, +body { + height: 100%; + overflow: hidden; +} +body { + margin: 0; + font-family: Roboto, "Helvetica Neue", sans-serif; +} .mb-1 { margin-bottom: 1em; @@ -76,19 +83,19 @@ dynamic-material-form-control .mat-form-field { display: none; } -.schedule-popup{ +.schedule-popup { // display:none; position: absolute; - box-shadow: 3px 3px 3px rgba(55,3, 3, .5); + box-shadow: 3px 3px 3px rgba(55, 3, 3, 0.5); padding: 16px; background-color: silver; -transform: translatey(-80px); -transition: all 2s ease; -z-index: 9; -&.in{ - display: block; -// transform: translate(80px,-80px); -} + transform: translatey(-80px); + transition: all 2s ease; + z-index: 9; + &.in { + display: block; + // transform: translate(80px,-80px); + } } .editor-config-column .mat-expansion-panel-body {