{"version":3,"sources":["webpack:///./src/pages/dashboard-program-edit/routes/webhook-detail.ts","webpack:///./src/pages/dashboard-program-edit/routes/webhook-detail.html","webpack:///./src/pages/dashboard-program-edit/routes/webhook-edit.ts","webpack:///./src/pages/dashboard-program-edit/routes/webhook-edit.html","webpack:///./src/pages/dashboard-program-edit/routes/webhook-list.ts","webpack:///./src/pages/dashboard-program-edit/routes/webhook-list.html","webpack:///./src/pages/dashboard-shareable/dashboard-shareable.ts","webpack:///./src/pages/dashboard-shareable/dashboard-shareable.html","webpack:///./src/pages/dfp-form.ts","webpack:///./src/pages/dfp-form.html","webpack:///./src/pages/home.ts","webpack:///./src/pages/home.html","webpack:///./src/pages/login.ts","webpack:///./src/pages/login.html"],"names":["WebhookDetail","api","router","this","auth","me","params","config","webhookId","programId","settings","updateJobs","loading","jobs","find","query","$limit","$sort","id","webhook_id","program_id","then","result","data","finally","job","j","jobWithData","get","$select","create","retryId","retryAt","Date","toISOString","retryNote","remove","module","exports","log","getLogger","WebhookEdit","_validation","alerts","super","dirtyProps","active","triggerOptions","value","label","initWebhook","validation","createForCurrentScope","defaults","headers","triggers","enabled","programWebhooks","webhook","updateClones","push","service","methods","index","splice","navigateToRoute","validate","valid","Error","patch","level","dismissable","Object","assign","catch","e","error","message","WebhookList","dialogService","updateWebhooks","webhooks","map","item","filteredJobs","filter","__completed","status","length","__progress","__failed","__delayed","open","viewModel","model","whenClosed","wasCancelled","DashboardShareable","element","stores","configId","programConfigs","activate","Element","DFPForm","programSurvey","programSurveys","surveyId","err","actions","action","survey","metadataObj","metadata","metadataKeyValues","URLSearchParams","entries","pair","keys","forEach","field","formSubmission","form","context","__expanded","survey_id","instance_id","attachments","isValid","constraintErrors","join","info","output","PageHome","program","ea","db","tourDriver","$skip","pageNumber","filesTotal","perPage","numAccess","version","dashboardList","hasOrgPermission","updatePrograms","setTour","programs","p","destroy","perpage","newValue","oldValue","isLoading","getPrograms","load","searchParams","programSearch","$or","title","$ilike","description","orgId","managementOrganizationId","matchingOrg","organizationId","isAdmin","type","$eager","files","getThumbnail","total","events","event","eventEmitter","fn","Login","controllerFactory","environment","flags","url","window","location","origin","authentication","loginComplete","credentials","strategy","credentialsChanged","startUnleash","creds","controller","pending","login","setTourHistory"],"mappings":"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","file":"app~88f8c17e.645488c27f3565953270.chunk.js","sourcesContent":["import { Paginated } from '@feathersjs/feathers';\nimport { Job } from '@wsb_dev/datafi-shared/lib/types';\nimport { autoinject } from 'aurelia-dependency-injection';\nimport { Router, Redirect } from 'aurelia-router';\nimport { DatafiProAPI } from '../../../services/api/DatafiProAPI';\nimport { userHasPermission } from '@wsb_dev/datafi-shared/lib/util/users/userHasPermission';\n\n@autoinject\nexport class WebhookDetail {\n    webhookId: number;\n    programId: number;\n    jobs: Job<any>[];\n    loading: boolean;\n\n    constructor(private api: DatafiProAPI, private router: Router) { }\n\n    canActivate() {\n        if (userHasPermission(this.api.auth.me, '*', '*')) {\n            return true;\n        }\n        return new Redirect('/');\n    }\n\n    activate(params, config) {\n        this.webhookId = params.webhookId;\n        this.programId = config.settings.programId;\n    }\n\n    attached() {\n        this.updateJobs();\n    }\n\n    updateJobs() {\n        this.loading = true;\n        this.api.jobs\n            .find({\n                query: {\n                    $limit: 100,\n                    $sort: { id: -1 },\n                    webhook_id: this.webhookId,\n                    program_id: this.programId,\n                },\n            })\n            .then((result: Paginated<Job<any>>) => {\n                this.jobs = result.data;\n            }).finally(() => {\n                this.loading = false;\n            });\n    }\n\n    async retryJob(job: Job) {\n        const data = this.jobs.find((j) => j.id === job.id);\n        const jobWithData = await this.api.jobs.get(data.id, { query: { $select: ['data'] } });\n\n        return this.api.jobs\n            .create({\n                ...data,\n                data: {\n                    ...jobWithData.data,\n                    retryId: job.id,\n                    retryAt: new Date().toISOString(),\n                    retryNote: `Retry of job ${job.id} from webhook ${this.webhookId} on program ${this.programId}.`,\n                },\n            })\n            .then(() => this.updateJobs());\n    }\n\n    removeJob(job: Job) {\n        // not implemented on backend\n        return this.api.jobs.remove(job.id, {})\n            .finally(() => this.updateJobs());\n    }\n}\n","// Module\nvar code = \"<template> <require from=\\\"components/admin/admin-table\\\"></require> <mdc-data-table busy.bind=\\\"loading\\\" class=\\\"w-100\\\"> <table> <thead> <th>Job</th> <th>Status</th> <th>Date</th> <th>Actions</th> </thead> <tbody> <tr mdc-data-table-row repeat.for=\\\"job of jobs\\\"> <td>${job.id}</td> <td class=\\\"${job.status === 'completed' ? 'text-success' : ''} ${job.status === 'active' ? 'text-info' : ''} ${job.status === 'failed' ? 'text-error' : ''}\\\">${job.status}</td> <td>${job.createdAt | date:'MM/DD/YYYY HH:mm A'}</td> <td> <a route-href=\\\"route: webhook-job-detail; params.bind: {webhookId: webhookId, jobId: job.id}\\\" mdc-button> <mdc-icon>info</mdc-icon>Info </a> <button click.delegate=\\\"retryJob(job)\\\" mdc-button> <mdc-icon>replay</mdc-icon>Retry </button> <button click.delegate=\\\"removeJob(job)\\\" class=\\\"button--color--danger\\\" mdc-button> <mdc-icon>delete</mdc-icon>Delete </button> </td> </tr> </tbody> </table> <mdc-linear-progress if.bind=\\\"loading\\\" open.bind=\\\"true\\\"></mdc-linear-progress> </mdc-data-table> <div class=\\\"divider\\\"></div> <mdc-button click.delegate=\\\"updateJobs()\\\" mdc-icon=\\\"refresh\\\">Refresh</mdc-button> </template>\";\n// Exports\nmodule.exports = code;","import { Option } from '@wsb_dev/datafi-shared/lib/types';\nimport { autoinject } from 'aurelia-dependency-injection';\nimport { LogManager } from 'aurelia-framework';\nimport { Router, Redirect } from 'aurelia-router';\nimport { ValidationController, ValidationControllerFactory } from 'aurelia-validation';\nimport { DatafiProAPI } from '../../../services/api/DatafiProAPI';\nimport { AlertService } from '../../../services/util/Alert';\nimport { DirtyChecker } from '../../../types/DirtyChecker';\nimport { ValidatedWebhook } from '../../../types/Webhooks';\nimport { ensureNumber } from '../../../util/numbers/ensureNumber';\nimport { userHasPermission } from '@wsb_dev/datafi-shared/lib/util/users/userHasPermission';\n\nconst log = LogManager.getLogger('dfp:admin');\n\n@autoinject\nexport class WebhookEdit extends DirtyChecker {\n    public dirtyProps: string[] = ['webhook'];\n    webhook: ValidatedWebhook;\n    programId: number;\n    webhookId: number;\n    validation: ValidationController;\n    active = 'headers';\n    triggerOptions: Option[] = [\n        { value: 'create', label: 'Item Created' },\n        // {value: 'patch', label: 'Item Updated'}, //This function may be added later, but does not work as of now.\n    ]\n\n    constructor(\n        private api: DatafiProAPI,\n        private _validation: ValidationControllerFactory,\n        private alerts: AlertService,\n        private router: Router,\n    ) { super(); }\n\n    canActivate() {\n        if (userHasPermission(this.api.auth.me, '*', '*')) {\n            return true;\n        }\n        return new Redirect('/');\n    }\n\n    activate(params, config): void {\n        this.programId = ensureNumber(config.settings.programId);\n        this.webhookId = ensureNumber(params.webhookId);\n        this.initWebhook();\n        this.validation = this._validation.createForCurrentScope();\n    }\n\n    async initWebhook() {\n        const defaults = {\n            program_id: this.programId,\n            headers: {},\n            data: {},\n            triggers: [],\n            enabled: true,\n        };\n        if (this.webhookId) {\n            await this.api.programWebhooks.get(this.webhookId)\n                .then((result) => {\n                    this.webhook = new ValidatedWebhook({\n                        ...defaults,\n                        ...result,\n                    });\n                });\n        } else {\n            this.webhook = new ValidatedWebhook(defaults);\n        }\n\n        this.updateClones();\n    }\n\n    createTrigger() {\n        if (!this.webhook.triggers) {\n            this.webhook.triggers = [];\n        }\n        this.webhook.triggers.push({\n            label: '',\n            service: 'api/v1/form-submissions',\n            methods: [],\n        });\n    }\n\n    removeTrigger(index: number) {\n        this.webhook.triggers.splice(index, 1);\n    }\n\n    cancel() {\n        this.router.navigateToRoute('webhook-list');\n    }\n\n    submit(webhook: ValidatedWebhook) {\n        this.validation.validate()\n            .then((result) => {\n                if (!result.valid) {\n                    throw new Error('Form is not valid');\n                }\n\n                return webhook.id ?\n                    this.api.programWebhooks.patch(webhook.id, webhook) :\n                    this.api.programWebhooks.create(webhook);\n            })\n            .then((result) => {\n                this.alerts.create({\n                    level: 'success',\n                    label: webhook.id ? 'Webhook updated' : 'Webhook created',\n                    dismissable: true,\n                });\n\n                Object.assign(this.webhook, result);\n                this.updateClones();\n\n                this.router.navigateToRoute('webhook-list');\n            })\n            .catch((e) => {\n                log.error(e);\n                this.alerts.create({\n                    level: 'error',\n                    label: e.message,\n                    dismissable: true,\n                });\n            });\n    }\n}\n","// Module\nvar code = \"<template> <require from=\\\"../../../components/mdc-json-field/mdc-json-field\\\"></require> <require from=\\\"../../../components/mdc-simple-accordion/mdc-simple-accordion\\\"></require> <div class=\\\"flex-grow-1 d-flex flex-column w-100 p-2\\\"> <h3>${webhook.id ? 'Edit' : 'New'} Webhook</h3> <p class=\\\"text-italic\\\" if.bind=\\\"webhook.id\\\">Created: ${webhook.createdAt | date} (${webhook.createdBy}); Modified: ${webhook.updatedAt | date} (${webhook.updatedBy})</p> <mdc-text-field class=\\\"mt-2\\\" value.bind=\\\"webhook.label & validate\\\" label=\\\"Name\\\"> </mdc-text-field> <mdc-text-field-helper-line> <mdc-text-field-helper-text validation>Required</mdc-text-field-helper-text> </mdc-text-field-helper-line> <mdc-text-field class=\\\"mt-2\\\" value.bind=\\\"webhook.url & validate\\\" label=\\\"Endpoint URL\\\"> </mdc-text-field> <mdc-text-field-helper-line> <mdc-text-field-helper-text validation></mdc-text-field-helper-text> </mdc-text-field-helper-line> <mdc-select class=\\\"mt-2\\\" label=\\\"HTTP Method\\\" value.bind=\\\"webhook.method\\\"> <mdc-list> <mdc-list-item value=\\\"get\\\">GET</mdc-list-item> <mdc-list-item value=\\\"post\\\">POST</mdc-list-item> </mdc-list> </mdc-select> <mdc-select-helper-text if.bind=\\\"standardSelect.valid\\\">Helper text</mdc-select-helper-text> <mdc-select-helper-text validation>Field is required</mdc-select-helper-text> <mdc-form-field class=\\\"my-4\\\"> <mdc-checkbox checked.bind=\\\"webhook.enabled\\\"></mdc-checkbox> <label>Enabled</label> </mdc-form-field> <mdc-tab-bar class=\\\"p-4\\\"> <mdc-tab label=\\\"Headers\\\" click.delegate=\\\"active = 'headers'\\\" icon=\\\"data_object\\\"> </mdc-tab> <mdc-tab label=\\\"Data\\\" click.delegate=\\\"active = 'data'\\\" icon=\\\"data_object\\\"> </mdc-tab> <mdc-tab label=\\\"Triggers\\\" click.delegate=\\\"active = 'triggers'\\\" icon=\\\"bolt\\\"> </mdc-tab> </mdc-tab-bar> <div if.bind=\\\"active === 'headers'\\\"> <h3 slot=\\\"caption\\\">Headers:</h3> <mdc-json-field value.two-way=\\\"webhook.headers\\\"></mdc-json-field> </div> <div if.bind=\\\"active === 'data'\\\"> <h3 slot=\\\"caption\\\">Data:</h3> <mdc-json-field value.two-way=\\\"webhook.data\\\"></mdc-json-field> </div> <div if.bind=\\\"active === 'triggers'\\\"> <h3 slot=\\\"caption\\\">Trigger Management</h3> <button mdc-button raised click.delegate=\\\"createTrigger()\\\"> <mdc-icon>add</mdc-icon>Create Trigger </button> <div class=\\\"divider\\\"></div> <mdc-simple-accordion repeat.for=\\\"trigger of webhook.triggers\\\" accordion=\\\"triggers\\\"> <template replace-part=\\\"heading\\\"> <mdc-icon class=\\\"icon-danger float-right mr-3\\\" click.delegate=\\\"removeTrigger($index)\\\">delete</mdc-icon> ${trigger.label} </template> <template replace-part=\\\"content\\\"> <mdc-text-field value.bind=\\\"trigger.label & validate\\\" label=\\\"Label\\\"> </mdc-text-field> <mdc-text-field-helper-line> <mdc-text-field-helper-text validation></mdc-text-field-helper-text> </mdc-text-field-helper-line> <mdc-select label=\\\"Service\\\" value.bind=\\\"trigger.service\\\"> <mdc-list> <mdc-list-item value=\\\"api/v1/form-submissions\\\">Form Submissions</mdc-list-item> </mdc-list> </mdc-select> <mdc-select-helper-text if.bind=\\\"standardSelect.valid\\\">Helper text</mdc-select-helper-text> <mdc-select-helper-text validation>Field is required</mdc-select-helper-text> <mdc-form-field class=\\\"pr-4\\\" repeat.for=\\\"option of triggerOptions\\\"> <mdc-checkbox model.bind=\\\"option.value\\\" checked.bind=\\\"trigger.methods\\\"></mdc-checkbox> <label model.bind=\\\"option.value\\\">${option.label}</label> </mdc-form-field> <h3>Filters:</h3> <mdc-json-field value.two-way=\\\"trigger.filters\\\"></mdc-json-field> </template> </mdc-simple-accordion> </div> <div class=\\\"divider\\\"></div> <div class=\\\"p-centered mt-3\\\"> <button class=\\\"button--color--secondary\\\" mdc-button click.trigger=\\\"cancel()\\\">Cancel</button> <mdc-button raised click.delegate=\\\"submit(webhook)\\\">Save</mdc-button> </div> </div> </template> \";\n// Exports\nmodule.exports = code;","import { ProgramWebhook } from '@wsb_dev/datafi-shared/lib/types/ProgramWebhook';\nimport { Job } from '@wsb_dev/datafi-shared/lib/types';\nimport { LogManager, autoinject } from 'aurelia-framework';\nimport { DatafiProAPI } from '../../../services/api/DatafiProAPI';\nimport { Paginated } from '@feathersjs/feathers';\nimport { AlertService } from '../../../services/util/Alert';\nimport { DialogService } from 'aurelia-dialog';\nimport { MDCDelete } from '../../../components/mdc-delete-dialog/mdc-delete-dialog';\nimport { userHasPermission } from '@wsb_dev/datafi-shared/lib/util/users/userHasPermission';\nimport { Redirect } from 'aurelia-router';\n\nconst log = LogManager.getLogger('dfp:admin');\n\nexport interface IProgramWebhookExtended extends ProgramWebhook {\n    __completed: number;\n    __progress: number;\n    __failed: number;\n    __delayed: number;\n}\n\n@autoinject\nexport class WebhookList {\n    programId: number;\n    webhooks: IProgramWebhookExtended[];\n    loading: boolean;\n\n    constructor(\n        private api: DatafiProAPI,\n        private alerts: AlertService,\n        private dialogService: DialogService,\n    ) { }\n\n    canActivate() {\n        if (userHasPermission(this.api.auth.me, '*', '*')) {\n            return true;\n        }\n        return new Redirect('/');\n    }\n\n    activate(params) {\n        this.programId = params.id;\n    }\n\n    attached() {\n        this.updateWebhooks();\n    }\n\n    async updateWebhooks() {\n        this.loading = true;\n        const jobs = await this.api.jobs.find({ query: { program_id: this.programId, $limit: 100, $select: ['status', 'webhook_id'] } }) as Paginated<Job<any>>;\n        const webhooks = await this.api.programWebhooks.find({\n            query: { program_id: this.programId, $sort: { label: 1 }, $limit: 100 },\n        }) as Paginated<ProgramWebhook>;\n        this.webhooks = webhooks.data.map((item) => {\n            const filteredJobs = jobs.data.filter((job) => job.webhook_id === item.id);\n            return {\n                ...item,\n                __completed: filteredJobs.filter((job) => job.status === 'completed').length || 0,\n                __progress: filteredJobs.filter((job) => job.status === 'active').length || 0,\n                __failed: filteredJobs.filter((job) => job.status === 'failed').length || 0,\n                __delayed: filteredJobs.filter((job) => job.status === 'delayed').length || 0,\n            };\n        });\n        this.loading = false;\n    }\n\n    deleteWebhook(webhook: ProgramWebhook): Promise<void> {\n\n        return this.dialogService.open({\n            viewModel: MDCDelete,\n            model: webhook.id,\n        }).whenClosed((result) => {\n            if (result.wasCancelled) {\n                return;\n            }\n            this.api.programWebhooks.remove(webhook.id)\n                .then(() => {\n                    this.alerts.create({\n                        level: 'success',\n                        label: 'Webhook Deleted',\n                        dismissable: true,\n                    });\n                    this.updateWebhooks();\n                })\n                .catch((e) => {\n                    log.error(e);\n                    this.alerts.create({\n                        level: 'error',\n                        label: e.message,\n                        dismissable: true,\n                    });\n                });\n        });\n    }\n}\n","// Module\nvar code = \"<template> <h1 class=\\\"text-center\\\">Webhooks</h1> <mdc-data-table class=\\\"w-100\\\" busy.bind=\\\"loading\\\"> <table> <thead> <th>Name</th> <th>Failed</th> <th>Delayed</th> <th>Pending</th> <th>Success</th> <th></th> </thead> <tbody> <tr mdc-data-table-row repeat.for=\\\"webhook of webhooks\\\" class=\\\"${webhook.enabled ? '' : 'opacity-50'}\\\"> <td>${webhook.label}</td> <td class=\\\"text-error\\\">${webhook.__failed}</td> <td>${webhook.__delayed}</td> <td>${webhook.__progress}</td> <td class=\\\"text-success\\\">${webhook.__completed}</td> <td> <a route-href=\\\"route: webhook-detail; params.bind: {webhookId: webhook.id}\\\" mdc-button> <mdc-icon>info</mdc-icon>Info </a> <a route-href=\\\"route: webhook-edit; params.bind: {webhookId: webhook.id}\\\" mdc-button> <mdc-icon>edit</mdc-icon>Edit </a> <button class=\\\"button--color--danger\\\" mdc-button click.delegate=\\\"deleteWebhook(webhook)\\\"> <mdc-icon>delete</mdc-icon>Delete </button> </td> </tr> </tbody> </table> <mdc-linear-progress if.bind=\\\"loading\\\" open.bind=\\\"true\\\"></mdc-linear-progress> </mdc-data-table> <br/> <br/> <div class=\\\"w-100 flex-1 justify-center py-4\\\"> <a route-href=\\\"route: webhook-create;\\\" raised mdc-button> <mdc-icon>add</mdc-icon>Create New </a> <button mdc-button click.delegate=\\\"updateWebhooks()\\\"><mdc-icon>refresh</mdc-icon>Refresh</button> </div> </template>\";\n// Exports\nmodule.exports = code;","/* eslint-disable @typescript-eslint/no-empty-function */\nimport { autoinject, observable } from 'aurelia-framework';\nimport { DatafiProAPI } from '../../services/api/DatafiProAPI';\nimport { ValidatedProgramConfig } from '../../types/ProgramConfig';\nimport { ProgramConfig } from '@wsb_dev/datafi-shared/lib/types';\nimport { IDashboardConfig, IDashboardItem } from '../../types/Dashboards';\nimport { StoreManager } from '../../services/util/StoreManager';\n\n@autoinject\nexport class DashboardShareable {\n\n    config: ProgramConfig<IDashboardConfig>;\n\n    constructor(\n        private element: Element,\n        private api: DatafiProAPI,\n        private stores: StoreManager,\n    ) { }\n\n    async activate(params) {\n        if (params.configId){\n\n            this.config = await(\n                this.api.programConfigs.get(params.configId)\n                    .then((config) => new ValidatedProgramConfig(config)));\n\n            await this.stores.activate(params.programId);\n\n        }\n    }\n\n}\n","// Module\nvar code = \"<template> <require from=\\\"../../components/dashboard-grid/dashboard-grid\\\"></require> <div class=\\\"dashboard-shareable\\\"> <div class=\\\"ds-container\\\"> <dashboard-grid class=\\\"dashboard-content w-100\\\" config.two-way=\\\"config\\\" if.bind=\\\"config\\\"> </dashboard-grid> </div> </div> </template>\";\n// Exports\nmodule.exports = code;","import { autoinject, LogManager } from 'aurelia-framework';\nimport { FormSubmission } from '@wsb_dev/datafi-shared/lib/types/FormSubmission';\nimport { ProgramSurvey } from '@wsb_dev/datafi-shared/lib/types';\nimport { userHasPermission } from '@wsb_dev/datafi-shared/lib/util/users/userHasPermission';\nimport { ValidatedFormSubmission } from '../types/FormSubmission';\nimport { FormEventData } from '../components/mdc-dynamic-form/mdc-dynamic-form';\nimport { FormSubmissionDialog } from '../components/form-submission-dialog/form-submission-dialog';\nimport { DatafiProAPI } from '../services/api/DatafiProAPI';\nimport { AuthenticationService } from '../services/api/authentication';\nimport { AlertService } from '../services/util/Alert';\nimport set from 'lodash.set';\nimport { v4 as uuidv4 } from 'uuid';\nimport { ensureNumber } from '../util/numbers/ensureNumber';\nimport { Redirect, Router } from 'aurelia-router';\nimport { DialogService } from 'aurelia-dialog';\n\nconst log = LogManager.getLogger('dfp:actions');\n\n@autoinject\nexport class DFPForm {\n    formSubmission: FormSubmission;\n    survey: ProgramSurvey;\n\n    constructor(\n        private api: DatafiProAPI,\n        private alerts: AlertService,\n        private auth: AuthenticationService,\n        private dialogService: DialogService,\n        private router: Router,\n    ) { }\n\n    async canActivate(params) {\n        const hasPermission = userHasPermission(this.api.auth.me, 'api/v1/form-submissions', 'create', ensureNumber(params.programId));\n        if (hasPermission) {\n            const programSurvey = await this.api.programSurveys.get(params.surveyId).catch((err) => {\n                log.error(`[dfp-form]: could not load survey: ${err}`);\n                this.alerts.create({\n                    label: 'Could not load survey',\n                    level: 'warning',\n                    dismissable: true,\n                });\n            }) as ProgramSurvey;\n\n            const canAddDFPform = programSurvey.actions.find((action) => action.id === 'EditDFPForm');\n            if (canAddDFPform) {\n                programSurvey ? this.survey = programSurvey : {};\n                return true;\n            } else {\n                return new Redirect('/');\n            }\n        } else {\n            return new Redirect('/');\n        }\n\n    }\n\n    async activate(params) {\n        //parse params.metadata into a workable object\n        const metadataObj: Record<string, unknown> = {};\n        if (params.metadata) {\n            const metadataKeyValues = new URLSearchParams(params.metadata).entries();\n            for (const pair of metadataKeyValues) {\n                metadataObj[pair[0]] = pair[1];\n            }\n        }\n\n        if (metadataObj) {\n            const defaults = {};\n            Object.keys(metadataObj).forEach((field) => {\n                if (metadataObj[field]) {\n                    set(defaults, field, metadataObj[field]);\n                }\n            });\n            this.formSubmission  = new ValidatedFormSubmission(defaults);\n        }\n    }\n\n    onSubmit(form: FormEventData): Promise<void> {\n        delete form.context.metadata?.__expanded;\n        const query = {\n            survey_id: this.survey.id,\n            instance_id: uuidv4(),\n            program_id: this.survey.program_id,\n            metadata: form.context.metadata,\n            attachments: form.context.attachments,\n        };\n\n        if (!form.isValid) {\n            return this.alerts.create({\n                level: 'error',\n                label: `Form is invalid: ${form.constraintErrors.map((e) => {\n                    return `${e.field}: ${e.message}`;\n                }).join('; ')}`,\n                dismissable: true,\n            });\n        }\n\n        this.dialogService.open({\n            viewModel: FormSubmissionDialog,\n            model: { id: this.formSubmission.id, query: query },\n        }).whenClosed((result) => {\n            // repopulate form logic\n            log.info(`[dfp-form]: form-submission status: ${result.output}`);\n            if (result.output === 'success') {\n                this.router.navigateToRoute('projects', { programId: this.survey.program_id });\n            }\n        });\n    }\n}\n","// Module\nvar code = \"<template> <require from=\\\"../components/mdc-dynamic-form/mdc-dynamic-form\\\"></require> <div class=\\\"dfp-form\\\"> <div class=\\\"paper\\\"> <h1 class=\\\"text-wsb-tangerine\\\">${survey.title}</h1> <mdc-dynamic-form object.bind=\\\"formSubmission\\\" schema.bind=\\\"survey.surveySchema\\\" submit.trigger=\\\"onSubmit($event.detail)\\\"> <template replace-part=\\\"actions\\\"> <button mdc-button click.delegate=\\\"dispatch('submit')\\\">Submit</button> </template> </mdc-dynamic-form> </div> </div> </template>\";\n// Exports\nmodule.exports = code;","import { ActiveProgram } from '../services/util/ActiveProgram';\nimport { AlertService } from '../services/util/Alert';\nimport { Router, Redirect } from 'aurelia-router';\nimport { autoinject, bindable } from 'aurelia-framework';\nimport { Program } from '../types/Program';\nimport { version } from '../../package.json';\nimport { debounced } from '../util/decorators/debounced';\nimport { subscribe } from '../util/decorators/subscribe';\nimport { EventAggregatorWrapper } from '../util/events/eventAggregatorWrapper';\nimport { AuthCreated } from '@wsb_dev/datafi-shared/lib/types/Events';\nimport { DatafiProAPI } from '../services/api/DatafiProAPI';\nimport { DB } from '../services/util/DB';\nimport { userHasPermission } from '@wsb_dev/datafi-shared/lib/util/users/userHasPermission';\nimport { hasOrgPermission } from '../util/orgs/hasOrgPermission';\nimport { TourService } from '../services/tour/TourService';\n\nconst params = {\n    $limit: 100,\n};\n\nexport interface IDashboardSelect {\n    id: number,\n    label: string\n}\n\n@subscribe({\n    events: [\n        { event: AuthCreated, eventEmitter: 'ea', fn: 'handleAuthCreated' },\n    ],\n})\n@autoinject\nexport class PageHome {\n    message = 'Welcome To Datafi!';\n    @bindable programs: Program[];\n    @bindable params = {\n        $limit: 20,\n        $skip: 0,\n    };\n    @bindable pageNumber = 1;\n    @bindable filesTotal = 0;\n    @bindable perPage = 20;\n    programSearch: string;\n    isLoading: boolean;\n    numAccess = 0;\n    version = version;\n    dashboardList: IDashboardSelect[] = [];\n    hasOrgPermission = hasOrgPermission\n\n    constructor(\n        private router: Router,\n        private alerts: AlertService,\n        private program: ActiveProgram,\n        private ea: EventAggregatorWrapper,\n        private api: DatafiProAPI,\n        private db: DB,\n        private tourDriver: TourService,\n    ) {}\n\n    canActivate() {\n        if (!this.api.auth.me) return new Redirect('/login');\n    }\n\n    attached() {\n        this.updatePrograms();\n        this.tourDriver.setTour('homeTour');\n    }\n\n    detached() {\n        this.programs?.forEach((p) => p.destroy());\n        this.tourDriver.setTour();\n    }\n\n    pageNumberChanged() {\n        this.params = {\n            ...this.params,\n            $skip: (this.pageNumber - 1) * this.perPage,\n        };\n\n        this.updatePrograms();\n    }\n    perPageChanged(perpage: number): void {\n        this.params = {\n            ...this.params,\n            $limit: perpage,\n            $skip: (this.pageNumber - 1) * this.perPage,\n        };\n        this.updatePrograms();\n    }\n\n    programsChanged(newValue, oldValue){\n        oldValue?.forEach((p) => p.destroy());\n    }\n\n    handleAuthCreated(){\n        if(!this.programs && !this.isLoading){\n            this.updatePrograms();\n        }\n    }\n\n    @debounced(200)\n    updatePrograms() {\n        this.isLoading = true;\n        if (!this.api.auth.me) {\n            return;\n        }\n        this.getPrograms();\n    }\n\n    selectProgram(id: number) {\n        if (id) {\n            this.alerts.create({\n                label: 'Loading program...',\n                dismissable: true,\n            });\n            this.program.load(id)\n                .then(() => this.router.navigateToRoute('projects', { programId: id }));\n        }\n    }\n\n    editProgram(program?: Program) {\n        return this.router.navigateToRoute('program/settings', { id: program?.id || 0 });\n    }\n\n    @debounced(200)\n    searchPrograms() {\n        this.isLoading = true;\n\n        let searchParams = null;\n\n        if (this.programSearch.length > 1) {\n            searchParams = {\n                $or: [\n                    { title: { $ilike: '%' + this.programSearch + '%' } },\n                    { description: { $ilike: '%' + this.programSearch + '%' } },\n                ],\n            };\n        }\n        this.getPrograms(searchParams);\n\n    }\n\n    getDashboards(id: number) {\n        this.dashboardList = [];\n        const orgId = this.programs.find((p) => p.id === id)?.managementOrganizationId;\n        const matchingOrg = this.api.auth.me.organizationId === orgId;\n        const isAdmin = userHasPermission(this.api.auth.me, '*', '*');\n\n        if (orgId) {\n            if (!matchingOrg && !isAdmin) {\n                return;\n            }\n        }\n\n        this.api.programConfigs.find({\n            query: {\n                program_id: id,\n                type: 'dashboard',\n                $select: ['id', 'label'],\n            },\n        }).then((result: any) => {\n            this.dashboardList = result.data as IDashboardSelect[];\n        });\n    }\n\n    getPrograms(searchParams = null) {\n        this.api.programs.find({\n            query: {\n                ...params,\n                ...this.params,\n                $eager: 'roles.role',\n                $sort: {title: 1},\n                ...searchParams,\n            },\n        }).then((result: any) => {\n            this.programs = result.data.map((p) => {\n                p = new Program(p, this.api.files);\n                p.getThumbnail();\n                return p;\n            });\n\n            this.filesTotal = result.total;\n            if (this.numAccess < 1) {\n                this.numAccess = this.programs.length;\n            }\n            this.isLoading = false;\n        });\n    }\n}\n","// Module\nvar code = \"<template> <require from=\\\"../components/mdc-pagination/mdc-pagination\\\"></require> <div class=\\\"home\\\"> <div class=\\\"container\\\"> <div class=\\\"columns\\\"> <div class=\\\"column\\\"> <div class=\\\"m-4 p-6 boxes\\\"> <div class=\\\"d-flex justify-between\\\"> <h2 class=\\\"mr-3\\\">Programs</h2> <mdc-text-field outlined class=\\\"mb-2 mx-5 w-50\\\" value.bind=\\\"programSearch\\\" type=\\\"text\\\" label=\\\"Search\\\" input.delegate=\\\"searchPrograms()\\\" if.bind=\\\"numAccess > 2\\\"> </mdc-text-field> <button mdc-button raised class=\\\"button--color--primary mt-2\\\" if.bind=\\\"api.auth.me | hasPermission:'api/v1/programs':'create'\\\" click.delegate=\\\"editProgram()\\\" data-tour-id=\\\"new-program-button\\\"> <mdc-icon>add</mdc-icon> New</button> </div> <mdc-linear-progress if.bind=\\\"isLoading\\\" open.bind=\\\"true\\\"> </mdc-linear-progress> <div class=\\\"empty\\\" if.bind=\\\"!programs.length && !isLoading\\\"> <mdc-icon>help</mdc-icon> <p>No programs were found. Start by creating a new program or contacting your administrator</p> </div> <div class=\\\"columns\\\" if.bind=\\\"programs.length\\\" data-tour-id=\\\"home-programs-grid\\\"> <div repeat.for=\\\"item of programs\\\" class=\\\"column p-3 col-3 col-xl-6 col-lg-6 col-md-6 col-sm-12 col-xs-12\\\"> <mdc-card class=\\\"card h-100\\\" data-tour-id=\\\"home-program-card\\\"> <mdc-card-primary-action click.delegate=\\\"selectProgram(item.id)\\\"> <div class=\\\"card__container\\\"> <div class=\\\"mdc-card__media ml-3\\\" if.bind=\\\"item._blobs.thumbnail.url\\\"> <div class=\\\"card__image bg-image\\\" css=\\\"background-image:url(${item._blobs.thumbnail.url});\\\"></div> </div> <div class=\\\"mdc-card__media ml-3\\\" else> <mdc-icon class=\\\"card__image icon-xxlg mt-4 mr-2\\\">image</mdc-icon> </div> <div class=\\\"card__info\\\"> <div class=\\\"card__primary\\\"> <h2 class=\\\"card__title m-0\\\" mdc-headline6>${item.title}</h2>  </div> <div class=\\\"card__secondary\\\" mdc-body2> ${item.description} </div> </div> </div> </mdc-card-primary-action> <mdc-list-divider></mdc-list-divider> <mdc-card-actions> <mdc-card-action-buttons> <a class=\\\"button--raised-secondary\\\" href=\\\"#\\\" mdc-button click.delegate=\\\"selectProgram(item.id)\\\">Launch</a> </mdc-card-action-buttons> <mdc-card-action-icons> <a if.bind=\\\"hasOrgPermission(api.auth.me, item)\\\" mdc-icon-button icon=\\\"dashboard\\\" route-href=\\\"route: program/dashboard-manager; params.bind: { id: item.id }\\\" data-tour-id=\\\"program-dashboard-button\\\"></a> <a if.bind=\\\"api.auth.me | hasPermission:item:'api/v1/programs':'patch'\\\" mdc-icon-button icon=\\\"settings\\\" route-href=\\\"route: program/settings; params.bind: { id: item.id }\\\" data-tour-id=\\\"program-settings-button\\\"> </a> <div mdc-menu-surface-anchor ref=\\\"hierarchicalAnchor\\\"> <button mdc-icon-button on.bind=\\\"on\\\" mdc-tooltip=\\\"Open Sharable Dashboard\\\" click.delegate=\\\"getDashboards(item.id)\\\" click.trigger=\\\"(hierarchical.open = !hierarchical.open)\\\"> <mdc-icon-button-icon icon=\\\"expand_more\\\"></mdc-icon-button-icon> <mdc-icon-button-icon on icon=\\\"expand_less\\\"></mdc-icon-button-icon> </button> <mdc-menu anchor-corner=\\\"BOTTOM_LEFT\\\" view-model.ref=\\\"hierarchical\\\" anchor.bind=\\\"hierarchicalAnchor\\\" hoistToBody> <mdc-list> <mdc-list-item if.bind=\\\"!dashboardList.length\\\">No Dashboards found</mdc-list-item> <a mdc-list-item repeat.for=\\\"d of dashboardList\\\" target=\\\"_blank\\\" route-href=\\\"route: dashboard-share; params.bind: {configId: d.id, programId: item.id}\\\">${d.label} </a> </mdc-list>  </mdc-menu> </div> </mdc-card-action-icons> </mdc-card-actions> </mdc-card> </div> </div> <mdc-pagination if.bind=\\\"filesTotal > 20\\\" per-page-options.bind=\\\"[20,40,60]\\\" per-page.two-way=\\\"perPage\\\" page.two-way=\\\"pageNumber\\\" total.bind=\\\"filesTotal\\\"> </mdc-pagination> </div> </div> </div> <p class=\\\"float-right text-small\\\">Version: ${version}</p> </div> </div> </template> \";\n// Exports\nmodule.exports = code;","import { Router } from 'aurelia-router';\nimport { LogManager, autoinject, bindable } from 'aurelia-framework';\nimport { ValidationController, ValidationControllerFactory } from 'aurelia-validation';\n\nimport { ValidatedCredentials } from '../types/Credentials';\n\nimport { AlertService } from '../services/util/Alert';\nimport { DatafiProAPI } from '../services/api/DatafiProAPI';\nimport { AppConfig } from '../services/util/AppConfig';\nimport { FeatureFlagsService } from 'services/util/FeatureFlags';\nimport { TourService } from 'services/tour/TourService';\n\nconst log = LogManager.getLogger('dfp:login');\n\n@autoinject\nexport class Login {\n    pending: boolean;\n    controller: ValidationController;\n    @bindable credentials: ValidatedCredentials;\n    url = window.location.origin;\n\n    constructor(\n        private controllerFactory: ValidationControllerFactory,\n        private router: Router,\n        private alerts: AlertService,\n        private api: DatafiProAPI,\n        private environment: AppConfig,\n        private flags: FeatureFlagsService,\n        private tourDriver: TourService,\n    ) { }\n\n    async activate() {\n        if (this.api.auth.authentication) {\n            return this.loginComplete();\n        }\n        this.credentials = new ValidatedCredentials({strategy: 'local'});\n        this.credentialsChanged(this.credentials);\n        await this.flags.startUnleash();\n    }\n\n    credentialsChanged(creds) {\n        this.controller = this.controllerFactory.createForCurrentScope();\n    }\n\n    async login() {\n        return this.controller.validate().then((result) => {\n            if (!result.valid) {\n                throw new Error('Form is not valid');\n            }\n            this.pending = true;\n            return this.api.auth.login(this.credentials).then(() => this.loginComplete());\n        }).catch((e) => {\n            log.error(e);\n            this.alerts.create({\n                label: e.message,\n                level: 'error',\n                dismissable: true,\n            });\n        }).finally(() => this.pending = false);\n    }\n\n    async loginComplete() {\n        this.credentials = new ValidatedCredentials({});\n        this.router.navigateToRoute('home');\n        this.tourDriver.setTourHistory();\n    }\n}\n","// Module\nvar code = \"<template> <div class=\\\"login-styles flex-1 justify-center align-center\\\"> <div class=\\\"login-container text-center px-4\\\"> <p if.bind=\\\"api.auth.authentication\\\">You are logged in as: ${api.auth.authentication.user.username}</p> <form else class=\\\"d-inline-block text-left m-4 page--login--form\\\" submit.trigger=\\\"login()\\\"> <h2 class=\\\"text-center\\\">Login</h2> <div class=\\\"mb-3\\\"> <mdc-text-field outlined value.bind=\\\"credentials.username & validate\\\" type=\\\"text\\\" label=\\\"Username\\\" label=\\\"Type 'error'\\\"> </mdc-text-field> <mdc-text-field-helper-line> <mdc-text-field-helper-text validation>Required</mdc-text-field-helper-text> </mdc-text-field-helper-line> </div> <div class=\\\"password-wrapper mb-3\\\"> <mdc-text-field outlined value.bind=\\\"credentials.password & validate\\\" type.bind=\\\"passwordVisible ? 'text' : 'password'\\\" label=\\\"Password\\\"> </mdc-text-field> <mdc-text-field-helper-line> <mdc-text-field-helper-text validation>Required</mdc-text-field-helper-text> </mdc-text-field-helper-line> <span class=\\\"toggle-password\\\" click.delegate=\\\"passwordVisible = !passwordVisible\\\"> <mdc-icon if.bind=\\\"passwordVisible\\\">visibility</mdc-icon> <mdc-icon if.bind=\\\"!passwordVisible\\\">visibility_off</mdc-icon> </span> </div> <mdc-linear-progress open.bind=\\\"true\\\" if.bind=\\\"pending\\\"></mdc-linear-progress> <button else click.delegate=\\\"login(username, password)\\\" type=\\\"submit\\\" class=\\\"w-100 mx-auto\\\" mdc-button raised> <mdc-icon>login</mdc-icon> Log In </button> <div class=\\\"divider\\\" data-content=\\\"Or continue with your organization\\\"></div> <a mdc-button outlined class=\\\"w-100\\\" href=\\\"${ environment.API_HOST }/oauth/microsoft?redirect=${url}\\\" data-router-ignore=\\\"true\\\"> <mdc-icon>groups</mdc-icon>Single Sign On </a> <a class=\\\"divider-style-text mt-7 mb-5\\\" route-href=\\\"password-reset\\\">Forgot password?</a> </form> </div> </div> </template> \";\n// Exports\nmodule.exports = code;"],"sourceRoot":""}