diff --git a/.appbuilder-state.json b/.appbuilder-state.json new file mode 100644 index 0000000..65f15a3 --- /dev/null +++ b/.appbuilder-state.json @@ -0,0 +1 @@ +{"applicationId":"fztemmkj4pbw","applicationName":"CRM App","platform":"WebComponents"} \ No newline at end of file diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..59d9a3a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..15936f0 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,23 @@ +{ + "root": true, + "env": { + "browser": true, + "es2021": true, + "jasmine": true + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 12, + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint" + ], + "rules": { + "@typescript-eslint/no-inferrable-types": "off" + } +} diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml new file mode 100644 index 0000000..1c7359d --- /dev/null +++ b/.github/workflows/node.js.yml @@ -0,0 +1,33 @@ +# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: Node.js CI + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [14.x, 16.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + # cache: 'npm' # enable after committing lock file from first install + - run: npm i # replace with 'npm ci' after committing lock file from first install +# - run: npm run lint + - run: npm run build + - run: npm run test + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1a876d8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/dist +/test + +# dependencies +/node_modules + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# misc +/coverage diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1c498fb --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Romeo Rosete + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..75c878b --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# CRM App + +This project was generated with [App Builder Code Gen](https://www.infragistics.com/products/appbuilder). + +## Development server + +Run `npm start` to build the application, start a web server and open the application in the default browser. The application will open in `http://localhost:8000/` by default. + +## Build + +Run `npm run build` to build the application into an output directory. + +## Running unit tests + +Run `npm test` to execute the unit tests via [Web Test Runner](https://modern-web.dev/docs/test-runner/overview). Runs all `.test.ts` files under `./src` folder. + +## Running code style checks + +Run `npm run lint` to execute the code styling rules for the project. + +## Licensing + +See the [License FAQ and Installation documentation](https://www.infragistics.com/products/ignite-ui-web-components/web-components/components/general-licensing) for information on how to upgrade to the full licensed package, if the project is using a Trial version of Ignite UI for Web Components, and how to setup your environment and CI to use our licensed npm feed. + +Alternatively run `npm run infragistics-login` for a guided login to our licensed feed. + +## Additional resources + +- [Ignite UI for Web Components](https://www.infragistics.com/products/ignite-ui-web-components) - to learn more about the product or to dive into component specifics and showcases. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..034e848 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,21 @@ +# Security Policy + +## Supported Versions + +Use this section to tell people about which versions of your project are +currently being supported with security updates. + +| Version | Supported | +| ------- | ------------------ | +| 5.1.x | :white_check_mark: | +| 5.0.x | :x: | +| 4.0.x | :white_check_mark: | +| < 4.0 | :x: | + +## Reporting a Vulnerability + +Use this section to tell people how to report a vulnerability. + +Tell them where to go, how often they can expect to get an update on a +reported vulnerability, what to expect if the vulnerability is accepted or +declined, etc. diff --git a/ig-theme.css b/ig-theme.css new file mode 100644 index 0000000..35fa88f --- /dev/null +++ b/ig-theme.css @@ -0,0 +1,273 @@ +:root { + --ig-font-family: "Lato"; + --ig-primary-h: 209deg; + --ig-primary-s: 71%; + --ig-primary-l: 36%; + --ig-secondary-h: 209deg; + --ig-secondary-s: 70%; + --ig-secondary-l: 57%; + --ig-error-h: 347deg; + --ig-error-s: 51%; + --ig-error-l: 46%; + --ig-success-h: 98deg; + --ig-success-s: 50%; + --ig-success-l: 32%; + --ig-warn-h: 22deg; + --ig-warn-s: 81%; + --ig-warn-l: 52%; + --ig-info-h: 285deg; + --ig-info-s: 34%; + --ig-info-l: 33%; + --ig-primary-300-contrast: white; + --ig-primary-400-contrast: white; + --ig-primary-500-contrast: white; + --ig-primary-600-contrast: white; + --ig-primary-700-contrast: white; + --ig-primary-A200-contrast: white; + --ig-primary-A400-contrast: white; + --ig-secondary-600-contrast: black; + --ig-secondary-700-contrast: black; + --ig-secondary-A400-contrast: black; + --ig-error-400-contrast: white; + --ig-error-500-contrast: white; + --ig-error-600-contrast: white; + --ig-error-A200-contrast: white; + --ig-error-A400-contrast: white; + --ig-success-400-contrast: white; + --ig-success-500-contrast: white; + --ig-success-600-contrast: white; + --ig-success-700-contrast: white; + --ig-success-800-contrast: white; + --ig-success-A400-contrast: white; + --ig-warn-800-contrast: white; + --ig-warn-900-contrast: white; + --ig-warn-A700-contrast: white; + --ig-info-200-contrast: white; + --ig-info-300-contrast: white; + --ig-info-400-contrast: white; + --ig-info-500-contrast: white; + --ig-info-A100-contrast: white; + --ig-info-A200-contrast: white; +} + +/* Charts */ +:root { + --charts-default-series: #9de772, #8b5bb1, #6db1ff, #9af2e4, #ee5879, #735656, #f7d262, #a8a8b7, #e051a9, #f8a15f; +} +igc-category-chart { + --brushes: var(--charts-default-series); + --outlines: var(--charts-default-series); + --marker-brushes: var(--charts-default-series); + --marker-outlines: var(--charts-default-series); + --negative-brushes: #ee5879; + --negative-outlines: #ee5879; + --title-text-color: hsla(var(--ig-gray-900)); + --subtitle-text-color: hsla(var(--ig-gray-700)); + --x-axis-label-text-color: hsla(var(--ig-gray-700)); + --x-axis-title-text-color: hsla(var(--ig-gray-900)); + --x-axis-stroke: hsla(var(--ig-gray-500)); + --x-axis-tick-stroke: hsla(var(--ig-gray-500)); + --y-axis-label-text-color: hsla(var(--ig-gray-700)); + --y-axis-title-text-color: hsla(var(--ig-gray-900)); + --y-axis-major-stroke: hsla(var(--ig-gray-300)); + --y-axis-tick-stroke: hsla(var(--ig-gray-500)); + --x-axis-label-text-style: normal 400 var(--ig-body-2-font-size) var(--ig-font-family); + --y-axis-label-text-style: normal 400 var(--ig-body-2-font-size) var(--ig-font-family); + --x-axis-title-text-style: normal 400 var(--ig-body-2-font-size) var(--ig-font-family); + --y-axis-title-text-style: normal 400 var(--ig-body-2-font-size) var(--ig-font-family); + --title-text-style: normal var(--ig-h6-font-weight) var(--ig-h6-font-size) var(--ig-font-family); + --subtitle-text-style: var(--ig-subtitle-1-font-weight) var(--ig-subtitle-1-font-size) var(--ig-font-family); +} +igc-pie-chart { + --brushes: var(--charts-default-series); + --outlines: var(--charts-default-series); + --label-extent: 30; + --label-outer-color: hsla(var(--ig-gray-700)); + --text-style: normal 400 var(--ig-body-2-font-size) var(--ig-font-family); +} + +/* Typography */ +h1 { + font-family: var(--ig-h1-font-family); + font-weight: var(--ig-h1-font-weight); + font-size: var(--ig-h1-font-size); + font-style: var(--ig-h1-font-style); + letter-spacing: var(--ig-h1-letter-spacing); + text-transform: var(--ig-h1-text-transform); + line-height: var(--ig-h1-line-height); + margin: 0; +} + +h2 { + font-family: var(--ig-h2-font-family); + font-weight: var(--ig-h2-font-weight); + font-size: var(--ig-h2-font-size); + font-style: var(--ig-h2-font-style); + letter-spacing: var(--ig-h2-letter-spacing); + text-transform: var(--ig-h2-text-transform); + line-height: var(--ig-h2-line-height); + margin: 0; +} + +h3 { + font-family: var(--ig-h3-font-family); + font-weight: var(--ig-h3-font-weight); + font-size: var(--ig-h3-font-size); + font-style: var(--ig-h3-font-style); + letter-spacing: var(--ig-h3-letter-spacing); + text-transform: var(--ig-h3-text-transform); + line-height: var(--ig-h3-line-height); + margin: 0; +} + +h4 { + font-family: var(--ig-h4-font-family); + font-weight: var(--ig-h4-font-weight); + font-size: var(--ig-h4-font-size); + font-style: var(--ig-h4-font-style); + letter-spacing: var(--ig-h4-letter-spacing); + text-transform: var(--ig-h4-text-transform); + line-height: var(--ig-h4-line-height); + margin: 0; +} + +h5 { + font-family: var(--ig-h5-font-family); + font-weight: var(--ig-h5-font-weight); + font-size: var(--ig-h5-font-size); + font-style: var(--ig-h5-font-style); + letter-spacing: var(--ig-h5-letter-spacing); + text-transform: var(--ig-h5-text-transform); + line-height: var(--ig-h5-line-height); + margin: 0; +} + +h6 { + font-family: var(--ig-h6-font-family); + font-weight: var(--ig-h6-font-weight); + font-size: var(--ig-h6-font-size); + font-style: var(--ig-h6-font-style); + letter-spacing: var(--ig-h6-letter-spacing); + text-transform: var(--ig-h6-text-transform); + line-height: var(--ig-h6-line-height); + margin: 0; +} + +p { + margin: 0; +} + +img, video { + height: auto; + max-width: 100%; +} + +.image_1 { + max-width: 100%; +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +.h6, +igc-card-header h1[slot='title'], +igc-card-header h2[slot='title'], +igc-card-header h3[slot='title'], +igc-card-header h4[slot='title'], +igc-card-header h5[slot='title'] { + font-family: var(--ig-h6-font-family); + font-weight: var(--ig-h6-font-weight); + font-size: var(--ig-h6-font-size); + font-style: var(--ig-h6-font-style); + letter-spacing: var(--ig-h6-letter-spacing); + text-transform: var(--ig-h6-text-transform); + line-height: var(--ig-h6-line-height); +} + +.typography__body-1 { + font-family: var(--ig-body-1-font-family); + font-weight: var(--ig-body-1-font-weight); + font-size: var(--ig-body-1-font-size); + font-style: var(--ig-body-1-font-style); + letter-spacing: var(--ig-body-1-letter-spacing); + text-transform: var(--ig-body-1-text-transform); + line-height: var(--ig-body-1-line-height); +} + +.typography__body-2 { + font-family: var(--ig-body-2-font-family); + font-weight: var(--ig-body-2-font-weight); + font-size: var(--ig-body-2-font-size); + font-style: var(--ig-body-2-font-style); + letter-spacing: var(--ig-body-2-letter-spacing); + text-transform: var(--ig-body-2-text-transform); + line-height: var(--ig-body-2-line-height); + margin: 0; +} + +.typography__subtitle-1 { + font-family: var(--ig-subtitle-1-font-family); + font-weight: var(--ig-subtitle-1-font-weight); + font-size: var(--ig-subtitle-1-font-size); + font-style: var(--ig-subtitle-1-font-style); + letter-spacing: var(--ig-subtitle-1-letter-spacing); + text-transform: var(--ig-subtitle-1-text-transform); + line-height: var(--ig-subtitle-1-line-height); +} + +.typography__subtitle-2, +igc-card-header h1[slot='subtitle'], +igc-card-header h2[slot='subtitle'], +igc-card-header h3[slot='subtitle'], +igc-card-header h4[slot='subtitle'], +igc-card-header h5[slot='subtitle'], +igc-card-header h6[slot='subtitle'] { + font-family: var(--ig-subtitle-2-font-family); + font-weight: var(--ig-subtitle-2-font-weight); + font-size: var(--ig-subtitle-2-font-size); + font-style: var(--ig-subtitle-2-font-style); + letter-spacing: var(--ig-subtitle-2-letter-spacing); + text-transform: var(--ig-subtitle-2-text-transform); + line-height: var(--ig-subtitle-2-line-height); + margin: 0; +} + +.typography__caption { + font-family: var(--ig-caption-font-family); + font-weight: var(--ig-caption-font-weight); + font-size: var(--ig-caption-font-size); + font-style: var(--ig-caption-font-style); + letter-spacing: var(--ig-caption-letter-spacing); + text-transform: var(--ig-caption-text-transform); + line-height: var(--ig-caption-line-height); +} + +.typography__overline { + font-family: var(--ig-overline-font-family); + font-weight: var(--ig-overline-font-weight); + font-size: var(--ig-overline-font-size); + font-style: var(--ig-overline-font-style); + letter-spacing: var(--ig-overline-letter-spacing); + text-transform: var(--ig-overline-text-transform); + line-height: var(--ig-overline-line-height); +} + + +/* align icons in their containers */ +.material-icons, .imx-icon { + vertical-align: middle; +} + +.ig-typography h1, +.ig-typography h2, +.ig-typography h3, +.ig-typography h4, +.ig-typography h5, +.ig-typography h6, +.ig-typography p, +.ig-typography__body-1 { + margin: 0 !important; +} diff --git a/ignite-ui-cli.json b/ignite-ui-cli.json new file mode 100644 index 0000000..caa0c4b --- /dev/null +++ b/ignite-ui-cli.json @@ -0,0 +1,16 @@ +{ + "version": "13.1.5", + "project": { + "defaultPort": 8000, + "framework": "webcomponents", + "projectTemplate": "base", + "projectType": "igc-ts", + "theme": "default", + "isBundle": false, + "components": [], + "sourceFiles": [], + "isShowcase": false, + "version": "" + }, + "build": {} +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..68b9a4d --- /dev/null +++ b/index.html @@ -0,0 +1,22 @@ + + + + + + + Ignite UI for Web Components + + + + + + + + + + + + + + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..1f0e58d --- /dev/null +++ b/package.json @@ -0,0 +1,59 @@ +{ + "name": "crmapp", + "version": "0.0.0", + "private": true, + "description": "WebComponents project for Ignite UI CLI", + "license": "MIT", + "author": "Infragistics", + "main": "dist/src/index.js", + "module": "dist/src/index.js", + "type": "module", + "exports": { + ".": "./dist/src/index.js", + "./crmapp.js": "./dist/src/crmapp.js" + }, + "scripts": { + "start": "tsc && concurrently -k -r \"tsc --watch\" \"wds\"", + "build": "rimraf dist && tsc && node --max-old-space-size=4096 node_modules/rollup/dist/bin/rollup -c rollup.config.mjs", + "start:build": "web-dev-server --root-dir dist --app-index index.html --open", + "lint": "eslint \"**/*.{js,ts}\" --ignore-path .gitignore", + "test": "tsc --project tsconfig.test.json && wtr" + }, + "dependencies": { + "@vaadin/router": "^1.7.4", + "igniteui-webcomponents": "~4.7.0", + "igniteui-webcomponents-charts": "~4.7.0", + "igniteui-webcomponents-core": "~4.7.0", + "igniteui-webcomponents-grids": "~4.7.0", + "igniteui-webcomponents-inputs": "~4.7.0", + "igniteui-webcomponents-layouts": "~4.7.0", + "lit": "^2.6.1", + "typescript": "^4.9.4" + }, + "devDependencies": { + "@babel/preset-env": "^7.20.2", + "@open-wc/building-rollup": "^2.2.1", + "@open-wc/testing": "^3.1.7", + "@rollup/plugin-babel": "^6.0.3", + "@rollup/plugin-node-resolve": "^15.0.1", + "@typescript-eslint/eslint-plugin": "^5.49.0", + "@typescript-eslint/parser": "^5.49.0", + "@web/dev-server": "^0.1.35", + "@web/rollup-plugin-html": "^1.11.0", + "@web/rollup-plugin-import-meta-assets": "^1.0.7", + "@web/test-runner": "^0.15.0", + "babel-plugin-template-html-minifier": "^4.1.0", + "concurrently": "^7.6.0", + "deepmerge": "^4.2.2", + "eslint": "^8.32.0", + "eslint-plugin-lit": "^1.8.2", + "igniteui-cli": "^11.0.2", + "rimraf": "^4.1.2", + "rollup": "^2.79.0", + "rollup-plugin-copy-assets": "^2.0.3", + "rollup-plugin-terser": "^7.0.2", + "rollup-plugin-workbox": "^6.2.0", + "source-map": "^0.7.4", + "tslib": "^2.4.1" + } +} diff --git a/rollup.config.mjs b/rollup.config.mjs new file mode 100644 index 0000000..47fb049 --- /dev/null +++ b/rollup.config.mjs @@ -0,0 +1,95 @@ +import babel from '@rollup/plugin-babel'; +import nodeResolve from '@rollup/plugin-node-resolve'; +import { rollupPluginHTML as html } from '@web/rollup-plugin-html'; +import { importMetaAssets } from '@web/rollup-plugin-import-meta-assets'; +import path from 'path'; +import copy from 'rollup-plugin-copy-assets'; +import { terser } from 'rollup-plugin-terser'; +import { generateSW } from 'rollup-plugin-workbox'; + +export default { + input: 'index.html', + output: { + entryFileNames: '[hash].js', + chunkFileNames: '[hash].js', + assetFileNames: '[hash][extname]', + format: 'es', + dir: 'dist', + }, + onwarn: function(warning) { + // Skip https://rollupjs.org/troubleshooting/#error-this-is-undefined + if ( warning.code === 'THIS_IS_UNDEFINED' ) { return; } + }, + preserveEntrySignatures: false, + + plugins: [ + copy({ + assets: [ + 'src/assets', + ], + }), + /** Enable using HTML as rollup entrypoint */ + html({ + minify: true, + injectServiceWorker: true, + serviceWorkerPath: 'dist/sw.js', + }), + /** Resolve bare module imports */ + nodeResolve(), + /** Minify JS */ + terser(), + /** Bundle assets references via import.meta.url */ + importMetaAssets(), + /** Compile JS to a lower language target */ + babel({ + compact: true, + babelHelpers: 'bundled', + presets: [ + [ + '@babel/preset-env', + { + targets: [ + 'last 3 Chrome major versions', + 'last 3 Firefox major versions', + 'last 3 Edge major versions', + 'last 3 Safari major versions', + ], + modules: false, + bugfixes: true, + }, + ], + ], + plugins: [ + [ + 'babel-plugin-template-html-minifier', + { + modules: { lit: ['html', { name: 'css', encapsulation: 'style' }] }, + failOnError: false, + strictCSS: true, + htmlMinifier: { + collapseWhitespace: true, + conservativeCollapse: true, + removeComments: true, + caseSensitive: true, + minifyCSS: true, + }, + }, + ], + ], + }), + /** Create and inject a service worker */ + generateSW({ + globIgnores: ['polyfills/*.js', 'nomodule-*.js'], + navigateFallback: '/index.html', + // where to output the generated sw + swDest: path.join('dist', 'sw.js'), + // directory to match patterns against to be precached + globDirectory: path.join('dist'), + // cache any html js and css by default + globPatterns: ['**/*.{html,js,css,webmanifest}'], + skipWaiting: true, + clientsClaim: true, + runtimeCaching: [{ urlPattern: 'polyfills/*.js', handler: 'CacheFirst' }], + }), + ], +}; diff --git a/src/app/account-sample/account-sample.test.ts b/src/app/account-sample/account-sample.test.ts new file mode 100644 index 0000000..7c3587b --- /dev/null +++ b/src/app/account-sample/account-sample.test.ts @@ -0,0 +1,9 @@ +import { expect } from '@open-wc/testing'; +import AccountSample from './account-sample.js'; + +describe('AccountSample', () => { + it(' is an instance of AccountSample', async () => { + const element = document.createElement('app-account-sample'); + expect(element).to.be.instanceOf(AccountSample); + }); +}); diff --git a/src/app/account-sample/account-sample.ts b/src/app/account-sample/account-sample.ts new file mode 100644 index 0000000..05ca50a --- /dev/null +++ b/src/app/account-sample/account-sample.ts @@ -0,0 +1,871 @@ +import { html, css, LitElement } from 'lit'; +import { customElement } from 'lit/decorators.js'; +import { defineComponents, IgcAccordionComponent, IgcAvatarComponent, IgcButtonComponent, IgcCheckboxComponent, IgcChipComponent, IgcExpansionPanelComponent, IgcIconComponent, IgcListComponent, IgcListItemComponent, IgcRippleComponent, IgcTabsComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcTabsComponent, IgcButtonComponent, IgcIconComponent, IgcRippleComponent, IgcAccordionComponent, IgcExpansionPanelComponent, IgcAvatarComponent, IgcCheckboxComponent, IgcListComponent, IgcListItemComponent, IgcChipComponent); + +@customElement('app-account-sample') +export default class AccountSample extends LitElement { + static styles = css` + :host { + height: 100%; + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + } + .column-layout { + display: flex; + flex-direction: column; + } + .group { + border-color: hsla(var(--ig-gray-200)); + border-width: 0px 0px 2px; + border-style: solid; + justify-content: flex-start; + align-items: stretch; + align-content: space-between; + position: relative; + padding: 20px; + min-width: 50px; + min-height: 50px; + } + .row-layout { + display: flex; + } + .account-header { + flex-wrap: wrap; + justify-content: space-between; + align-items: flex-start; + align-content: flex-start; + gap: 16px; + position: relative; + min-width: 50px; + } + .page-title { + justify-content: flex-start; + align-items: center; + align-content: flex-start; + gap: 16px; + position: relative; + min-width: 50px; + min-height: 50px; + } + .group_1 { + background-color: rgba(71, 124, 41, 0.2); + border-radius: 6px; + justify-content: center; + align-items: center; + align-content: flex-start; + position: relative; + width: 48px; + height: 48px; + min-width: 48px; + min-height: 48px; + max-width: 48px; + max-height: 48px; + } + .group_2 { + justify-content: center; + align-items: stretch; + align-content: flex-start; + position: relative; + min-width: 50px; + min-height: 50px; + } + .group_3 { + flex-wrap: wrap; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 24px; + position: relative; + min-width: 50px; + min-height: 50px; + } + .group_4 { + border-color: hsla(var(--ig-gray-200)); + border-width: 0px 1px 0px 0px; + border-style: solid; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + position: relative; + padding: 0 24px 0 0; + min-width: 50px; + min-height: 50px; + flex-grow: 1; + flex-shrink: 0; + } + .group_5 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + position: relative; + min-width: 50px; + } + .group_6 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + position: relative; + min-width: 50px; + min-height: 50px; + flex-grow: 1; + flex-shrink: 0; + } + .group_7 { + background-color: hsla(var(--ig-gray-100)); + flex-wrap: wrap; + justify-content: flex-start; + align-items: stretch; + align-content: stretch; + gap: 12px; + overflow: auto; + position: relative; + padding: 12px; + min-height: 50px; + flex-grow: 1; + flex-basis: 0; + } + .group_8 { + background-color: hsla(var(--ig-surface-500)); + border-color: hsla(var(--ig-gray-200)); + border-width: 1px; + border-style: solid; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 24px; + position: relative; + padding: 16px; + min-width: 576px; + flex-grow: 2; + flex-basis: 0; + } + .tabs { + min-width: 0; + min-height: 0; + flex-grow: 1; + flex-shrink: 0; + } + .buttons-1 { + flex-wrap: wrap; + justify-content: flex-start; + align-items: center; + align-content: flex-start; + gap: 16px; + position: relative; + min-width: 50px; + } + .accordion { + overflow-y: auto; + flex-shrink: 0; + } + .group_9 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 12px; + position: relative; + min-width: 50px; + min-height: 50px; + } + .group_10 { + justify-content: flex-start; + align-items: center; + align-content: flex-start; + gap: 8px; + position: relative; + min-width: 50px; + flex-shrink: 0; + } + .group_11 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 8px; + position: relative; + min-width: 50px; + min-height: 50px; + } + .group_12 { + justify-content: flex-start; + align-items: baseline; + align-content: flex-start; + gap: 16px; + position: relative; + min-width: 50px; + } + .group_13 { + justify-content: flex-start; + align-items: center; + align-content: flex-start; + gap: 16px; + position: relative; + min-width: 50px; + } + .demo-content { + border-color: hsla(var(--ig-secondary-200)); + border-width: 2px; + border-style: dashed; + flex-wrap: wrap; + justify-content: center; + align-items: center; + align-content: center; + gap: 32px; + padding: 48px; + min-height: 50px; + flex-grow: 1; + flex-basis: 0; + } + .demo-content-1 { + border-color: hsla(var(--ig-secondary-200)); + border-width: 2px; + border-style: dashed; + flex-wrap: wrap; + justify-content: center; + align-items: center; + align-content: center; + gap: 32px; + padding: 32px; + min-height: 50px; + flex-grow: 1; + flex-basis: 0; + } + .group_14 { + background-color: hsla(var(--ig-surface-500)); + border-color: hsla(var(--ig-gray-200)); + border-width: 1px; + border-style: solid; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 24px; + position: relative; + padding: 16px; + min-width: max-content; + flex-grow: 1; + flex-basis: 0; + } + .group_15 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 24px; + position: relative; + padding: 24px 0 0; + min-width: 50px; + min-height: 50px; + flex-shrink: 0; + } + .buttons { + flex-wrap: wrap; + justify-content: flex-start; + align-items: center; + align-content: flex-start; + gap: 16px; + position: relative; + } + .group_16 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 2px; + position: relative; + min-width: 50px; + min-height: 50px; + } + .group_17 { + flex-wrap: wrap; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 2px; + position: relative; + min-width: 50px; + flex-shrink: 0; + } + .group_18 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 2px; + position: relative; + min-width: 50px; + flex-shrink: 0; + } + .image { + object-fit: cover; + width: 20px; + height: 20px; + min-width: 20px; + min-height: 0; + max-width: 20px; + max-height: 20px; + flex-shrink: 0; + } + .content { + height: max-content; + min-width: min-content; + } + .text { + color: hsla(var(--ig-gray-700)); + height: max-content; + min-width: min-content; + } + .text_1 { + color: hsla(var(--ig-primary-500)); + height: max-content; + min-width: min-content; + } + .avatar::part(base) { + color: hsla(var(--ig-primary-500)); + background-color: rgba(27, 95, 158, 0.2); + } + .hyperlink { + color: hsla(var(--ig-primary-500)); + height: max-content; + min-width: min-content; + flex-shrink: 0; + } + .text_2 { + height: max-content; + min-width: 140px; + } + .hyperlink_1 { + color: hsla(var(--ig-info-500)); + height: max-content; + min-width: min-content; + } + .text_3 { + color: hsla(var(--ig-gray-600)); + height: max-content; + min-width: min-content; + } + .image_1 { + object-fit: cover; + min-width: 0; + min-height: 0; + max-width: 160px; + flex-shrink: 0; + } + .text_4 { + text-align: center; + color: hsla(var(--ig-gray-500)); + height: max-content; + min-width: min-content; + max-width: 320px; + } + .text_5 { + color: hsla(var(--ig-gray-800)); + height: max-content; + min-width: min-content; + } + .chip { + width: max-content; + height: max-content; + } + .avatar_1::part(base) { + background-color: rgba(71, 124, 41, 0.2); + } + .avatar_2::part(base) { + color: hsla(var(--ig-gray-500)); + } + .avatar_3::part(base) { + color: hsla(var(--ig-gray-500)); + } + .avatar_4::part(base) { + background-color: transparent; + } + .avatar_5::part(base) { + background-color: transparent; + } + .avatar_6::part(base) { + background-color: transparent; + } + .tab-item-content { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 24px; + padding: 24px 0 0; + height: 100%; + min-width: 100%; + min-height: 50px; + max-height: 100%; + } + .tab-item-content_1 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + padding: 24px 0 0; + height: 100%; + min-width: 100%; + min-height: 50px; + max-height: 100%; + } + .tab-item-content_2 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 24px; + height: 100%; + min-width: 100%; + min-height: 50px; + max-height: 100%; + } + .tab-item-content_3 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + overflow: auto; + padding: 24px 0 0; + height: 100%; + min-width: 100%; + min-height: 50px; + max-height: 100%; + } + .button { + height: max-content; + flex-shrink: 0; + } + .checkbox { + width: max-content; + height: max-content; + } + .button::part(base) { + color: hsla(var(--ig-primary-500)); + background-color: hsla(var(--ig-secondary-100)); + } + .list { + height: max-content; + } + `; + + render() { + return html` + + +
+ +
+
+
+ + +
+ + + person_add + + Contact + + + + + star_border + + New Opportunity + + + + + error_outline + + New Case + + + + + note_add + + Add note + + + + + file_copy + + Add files + + +
+ + +
+ +
+
+

+ Account Name: +

+

+ Thomas Hardy +

+
+
+

+ Title: +

+

+ Owner +

+
+
+

+ Direct: +

+ +
+
+
+ Related Contacts (1) +
+ +
+ +
+
+

+ Stage: +

+

+ Qualification +

+
+
+

+ Amount: +

+

+ Owner +

+
+
+

+ Close Date: +

+

+ 9/12/2022 +

+
+
+
+ Opportunities (1) +
+ + + + + + insert_drive_file + + + + + + + + insert_drive_file + + + + + + Contracts (2) + + +

+ No cases filed. +

+ Cases (0) +
+ +

+ No notes added. +

+ Notes (0) +
+ +

+ No files uploaded +

+ Files (0) +
+
+
+ + + info + + Related + + +
+ +

+ Remove the "demo-content" container, and add your own content. +

+
+
+ + + info + + Details + + +
+ +

+ Remove the "demo-content" container, and add your own content. +

+
+
+ + + info + + News + +
+
+
+ + +
+
+ + + calendar_today + + New Meeting + + + + + assignment + + New task + + + + + call + + Log a call + + +
+ + + + + +
+
+
+

+ Project Intro +

+
+
+

+ 11/1/2022 +

+

+ - +

+

+ 10am +

+
+ + Zoom Meeting + +
+
+
+ + +
+
+
+

+ Sync Meeting +

+
+
+

+ 11/7/2022 +

+

+ - +

+

+ 2pm +

+
+ + On Site Meeting + +
+
+
+ + +
+
+
+

+ Wrap Up Meeting +

+
+
+

+ 11/14/2022 +

+

+ - +

+

+ 4pm +

+
+ + Phone call + +
+
+
+
+ Upcoming Events (3) +
+ +

+ No tasks added. +

+ Tasks (0) +
+ +

+ No call logged. +

+ Call Logs (0) +
+
+
+
+ + + info + + Activity + + +
+ +

+ Remove the "demo-content" container, and add your own content. +

+
+
+ + + info + + Conversations + +
+
+
+ `; + } +} diff --git a/src/app/accounts/accounts.test.ts b/src/app/accounts/accounts.test.ts new file mode 100644 index 0000000..850d0ff --- /dev/null +++ b/src/app/accounts/accounts.test.ts @@ -0,0 +1,9 @@ +import { expect } from '@open-wc/testing'; +import Accounts from './accounts.js'; + +describe('Accounts', () => { + it(' is an instance of Accounts', async () => { + const element = document.createElement('app-accounts'); + expect(element).to.be.instanceOf(Accounts); + }); +}); diff --git a/src/app/accounts/accounts.ts b/src/app/accounts/accounts.ts new file mode 100644 index 0000000..dc1e555 --- /dev/null +++ b/src/app/accounts/accounts.ts @@ -0,0 +1,643 @@ +import { html, css, LitElement } from 'lit'; +import { customElement, state, query } from 'lit/decorators.js'; +import { Router } from '@vaadin/router'; +import { defineComponents, IgcButtonComponent, IgcDialogComponent, IgcDropdownComponent, IgcIconComponent, IgcInputComponent, IgcRippleComponent, IgcSelectComponent } from 'igniteui-webcomponents'; +import 'igniteui-webcomponents-grids/grids/combined.js'; +import { CustomersType } from '../models/northwind/customers-type'; +import { northwindService } from '../services/Northwind-service'; + +defineComponents(IgcButtonComponent, IgcIconComponent, IgcRippleComponent, IgcSelectComponent, IgcInputComponent, IgcDropdownComponent, IgcDialogComponent); + +@customElement('app-accounts') +export default class Accounts extends LitElement { + static styles = css` + :host { + height: 100%; + display: flex; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + } + .row-layout { + display: flex; + } + .group { + background-color: hsla(var(--ig-gray-100)); + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + overflow: auto; + position: relative; + padding: 12px; + min-width: 50px; + min-height: 50px; + flex-grow: 1; + flex-basis: 0; + } + .column-layout { + display: flex; + flex-direction: column; + } + .group_1 { + background-color: hsla(var(--ig-surface-500)); + border-color: hsla(var(--ig-gray-300)); + border-width: 1px; + border-style: solid; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 24px; + position: relative; + padding: 16px; + min-height: 50px; + flex-grow: 1; + flex-basis: 0; + } + .group_2 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 16px; + position: relative; + min-width: 50px; + min-height: 50px; + flex-shrink: 0; + } + .header { + flex-wrap: wrap; + justify-content: space-between; + align-items: center; + align-content: flex-start; + gap: 16px; + position: relative; + min-width: 50px; + } + .page-title { + justify-content: flex-start; + align-items: center; + align-content: flex-start; + gap: 12px; + position: relative; + min-width: 50px; + min-height: 50px; + } + .group_3 { + background-color: rgba(71, 124, 41, 0.2); + border-radius: 6px; + justify-content: center; + align-items: center; + align-content: flex-start; + position: relative; + width: 48px; + height: 48px; + min-width: 48px; + min-height: 48px; + max-width: 48px; + max-height: 48px; + } + .buttons { + flex-wrap: wrap; + justify-content: flex-start; + align-items: center; + align-content: flex-start; + gap: 16px; + position: relative; + min-width: 50px; + } + .filters-and-sorting { + flex-wrap: wrap; + justify-content: space-between; + align-items: flex-start; + align-content: flex-start; + gap: 24px; + position: relative; + min-width: 50px; + flex-shrink: 0; + } + .group_4 { + flex-wrap: wrap; + justify-content: flex-start; + align-items: center; + align-content: flex-start; + gap: 16px; + } + .group_5 { + justify-content: flex-start; + align-items: center; + align-content: flex-start; + position: relative; + min-width: 50px; + min-height: 50px; + flex-shrink: 0; + } + .group_6 { + flex-wrap: wrap; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 24px; + position: relative; + padding: 16px 0 0; + min-width: 50px; + min-height: 50px; + } + .group_7 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 40px; + overflow: auto; + position: relative; + min-width: 50px; + min-height: 50px; + max-height: 600px; + flex-shrink: 0; + } + .group_8 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + position: relative; + min-width: 50px; + min-height: 50px; + flex-shrink: 0; + } + .group_9 { + flex-wrap: wrap; + justify-content: flex-start; + align-items: flex-start; + align-content: flex-start; + gap: 40px; + position: relative; + min-width: 50px; + min-height: 50px; + } + .group_10 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 16px; + position: relative; + min-width: 280px; + min-height: 50px; + flex-grow: 1; + flex-basis: 0; + } + .group_11 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + position: relative; + margin: 0 0 5px; + min-width: 50px; + } + .group_12 { + flex-wrap: wrap; + justify-content: flex-start; + align-items: flex-start; + align-content: flex-start; + gap: 40px; + position: relative; + min-width: 50px; + min-height: 50px; + flex-shrink: 0; + } + .group_13 { + flex-wrap: wrap; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 16px; + position: relative; + min-width: 50px; + min-height: 50px; + } + .image { + object-fit: cover; + width: 20px; + height: 20px; + min-width: 20px; + min-height: 0; + max-width: 20px; + max-height: 20px; + flex-shrink: 0; + } + .h6 { + height: max-content; + min-width: min-content; + } + .icon { + --size: 24px; + font-size: 24px; + width: 24px; + height: 24px; + } + .h6_1 { + color: hsla(var(--ig-gray-900)); + height: max-content; + } + .text { + margin: 0 0 24px; + height: max-content; + } + .text_1 { + color: hsla(var(--ig-gray-500)); + height: max-content; + min-width: min-content; + } + .text_2 { + color: hsla(var(--ig-gray-700)); + height: max-content; + min-width: min-content; + } + .text_3 { + margin: 0 0 8px; + height: max-content; + } + .textarea { + height: max-content; + } + .button { + height: max-content; + flex-shrink: 0; + } + .select { + height: max-content; + min-width: min-content; + flex-shrink: 0; + } + .input { + height: max-content; + min-width: 120px; + flex-shrink: 0; + } + .dropdown { + min-width: min-content; + } + .user-input { + height: max-content; + } + .user-input_2 { + height: max-content; + flex-grow: 1; + flex-basis: 0; + } + .button_1 { + margin: 8px 16px 16px 0; + height: max-content; + } + .button_2::part(base) { + color: hsla(var(--ig-primary-500)); + background-color: hsla(var(--ig-secondary-100)); + } + .button_3::part(base) { + color: hsla(var(--ig-primary-500)); + background-color: hsla(var(--ig-secondary-100)); + } + .button_4::part(base) { + color: hsla(var(--ig-primary-500)); + background-color: hsla(var(--ig-secondary-100)); + } + .button_5::part(base) { + color: hsla(var(--ig-primary-500)); + } + .dropdown::part(base) { + height: max-content; + } + .button_1_1::part(base) { + color: hsla(var(--ig-surface-500)); + } + .grid { + min-height: 0; + flex-grow: 1; + flex-basis: 0; + } + `; + + constructor() { + super(); + this.northwindCustomers = northwindService.getData('CustomersType'); + } + + @state() + private value: string = '2'; + + @query('#button') + private button?: IgcButtonComponent; + + @query('#dropdown') + private dropdown?: IgcDropdownComponent; + + @state() + private northwindCustomers: CustomersType[] = []; + + @query('#new-account-dialog') + private newAccountDialog?: IgcDialogComponent; + + @state() + private value1: string = '1'; + + render() { + return html` + + + +
+
+
+
+
+
+ +
+
+ Accounts +
+
+
+ + + business + + New Account + + + + + search + + Discover companies + + + + + import_export + + Import + + +
+
+
+
+ + + My Accounts + + + All Accounts + + + + + + search + + + +
+
+ + Recently Updated + + keyboard_arrow_down + + + + + + Name + + + Recently Updated + + +
+
+
+ + + + + + + + + + + + +
+
+ +
+
+ New Account +
+
+
+

+ ACCOUNT INFORMATION +

+
+
+ + + + search + + + + + + -- None -- + + + Analyst + + + Competitor + + + Customer + + + Integrator + + + Investor + + + Partner + + + Press + + + Prospect + + + Reseller + + + Other + + + + Textarea not yet available in WebComponents +
+
+
+

+ Account Owner +

+

+ Andrea Silveira +

+
+ + + + search + + + + + + + -- None -- + + + Agriculture + + + Apparel + + + Banking + + + Biotechnology + + + Chemicals + + + Communications + + + Construction + + + + + Self Employed + + + 1-10 + + + 11-50 + + + 51-250 + + + +250 + + +
+
+
+
+
+

+ BILLING INFORMATION +

+ + + + search + + + + +
+ + +
+
+ + + + Country 1 + + + Country 1 + + + Country 1 + + + Country 1 + + + Country 1 + + +
+
+
+

+ SHIPPING INFORMATION +

+ + + + search + + + + +
+ + +
+
+ + + + Country 1 + + + Country 1 + + + Country 1 + + + Country 1 + + + Country 1 + + +
+
+
+
+
+
+ + Cancel + + + + Save + + +
+
+ `; + } +} diff --git a/src/app/app-routing.ts b/src/app/app-routing.ts new file mode 100644 index 0000000..f3fabe6 --- /dev/null +++ b/src/app/app-routing.ts @@ -0,0 +1,24 @@ +import { Route } from '@vaadin/router'; +import './not-found/not-found.js'; +import './home/home'; +import './accounts/accounts'; +import './account-sample/account-sample'; +import './contacts/contacts'; +import './contracts/contracts'; +import './reports/reports'; +import './calendar/calendar'; +import './tasks/tasks'; + +export const routes: Route[] = [ + { path: '', component: 'app-home', name: 'Home' }, + { path: 'home', component: 'app-home', name: 'Home' }, + { path: 'accounts', component: 'app-accounts', name: 'Accounts' }, + { path: 'account-sample', component: 'app-account-sample', name: 'Account Sample' }, + { path: 'contacts', component: 'app-contacts', name: 'Contacts' }, + { path: 'contracts', component: 'app-contracts', name: 'Contracts' }, + { path: 'reports', component: 'app-reports', name: 'Reports' }, + { path: 'calendar', component: 'app-calendar', name: 'Calendar' }, + { path: 'tasks', component: 'app-tasks', name: 'Tasks' }, + // The fallback route should always be after other alternatives. + { path: '(.*)', component: 'app-not-found' } +]; diff --git a/src/app/app.ts b/src/app/app.ts new file mode 100644 index 0000000..e9750b0 --- /dev/null +++ b/src/app/app.ts @@ -0,0 +1,204 @@ +import { html, css, LitElement } from 'lit'; +import { customElement, state, query } from 'lit/decorators.js'; +import { Router } from '@vaadin/router'; +import { routes } from './app-routing.js'; +import { defineComponents, IgcAvatarComponent, IgcIconButtonComponent, IgcIconComponent, IgcListComponent, IgcListItemComponent, IgcNavbarComponent, IgcNavDrawerComponent, IgcRippleComponent } from 'igniteui-webcomponents'; +import { Table1Type } from './models/crmapp-data/table1-type'; +import { cRMAppDataService } from './services/CRMAppData-service'; + +defineComponents(IgcIconComponent, IgcNavbarComponent, IgcIconButtonComponent, IgcRippleComponent, IgcNavDrawerComponent, IgcListComponent, IgcListItemComponent, IgcAvatarComponent); + +@customElement('app-root') +export default class App extends LitElement { + static styles = css` + :host { + height: 100%; + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + } + .row-layout { + display: flex; + } + .group { + background-color: hsla(var(--ig-gray-900)); + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + overflow: hidden; + position: relative; + min-height: 56px; + } + .group_1 { + justify-content: center; + align-items: center; + align-content: flex-start; + position: relative; + width: 56px; + height: 56px; + min-width: 50px; + min-height: 50px; + max-width: 56px; + max-height: 56px; + } + .group_2 { + justify-content: flex-start; + align-items: center; + align-content: flex-start; + gap: 1rem; + overflow: hidden; + } + .group_3 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + position: relative; + min-height: 50px; + flex-grow: 1; + } + .icon { + --size: 24px; + font-size: 24px; + width: 24px; + height: 24px; + color: hsla(var(--ig-surface-500)); + } + .image { + object-fit: none; + width: 413px; + height: 14px; + min-width: 413px; + min-height: 14px; + max-width: 413px; + max-height: 14px; + flex-shrink: 0; + } + .avatar::part(base) { + background-color: transparent; + } + .icon-button::part(base) { + color: hsla(var(--ig-surface-500)); + } + .navbar { + color: hsla(var(--ig-surface-500)); + background-color: hsla(var(--ig-primary-500)); + height: max-content; + min-width: min-content; + flex-grow: 1; + flex-basis: 0; + } + .nav-drawer { + min-width: min-content; + min-height: 0; + max-width: 200px; + flex-shrink: 0; + } + .view-container { + overflow: auto; + display: block; + position: relative; + flex-grow: 1; + } + .nav-drawer::part(main) { + width: 200px; + } + .list { + height: max-content; + } + `; + + constructor() { + super(); + cRMAppDataService.getTable1List().then((data) => { + this.cRMAppDataTable1 = data; + }, err => console.log(err)); + } + + @query('#nav-drawer') + private navDrawer?: IgcNavDrawerComponent; + + @state() + private cRMAppDataTable1: Table1Type[] = []; + + render() { + return html` + + +
+
+ + menu + +
+ +
+ +
+ + + search + + + + + + settings + + + + + + notifications_none + + + +
+
+
+ + + ${this.cRMAppDataTable1?.map((item) => html` + + +
Home
+
+ `)} + + +
Accounts
+
+ + +
Contacts
+
+ + +
Contracts
+
+ + +
Reports
+
+ + +
Calendar
+
+ + +
Tasks
+
+
+
+ +
+ `; + } + + firstUpdated() { + const outlet = this.shadowRoot?.querySelector('router-outlet'); + const router = new Router(outlet); + router.setRoutes(routes); + } +} diff --git a/src/app/calendar/calendar.test.ts b/src/app/calendar/calendar.test.ts new file mode 100644 index 0000000..6156e30 --- /dev/null +++ b/src/app/calendar/calendar.test.ts @@ -0,0 +1,9 @@ +import { expect } from '@open-wc/testing'; +import Calendar from './calendar.js'; + +describe('Calendar', () => { + it(' is an instance of Calendar', async () => { + const element = document.createElement('app-calendar'); + expect(element).to.be.instanceOf(Calendar); + }); +}); diff --git a/src/app/calendar/calendar.ts b/src/app/calendar/calendar.ts new file mode 100644 index 0000000..183adf3 --- /dev/null +++ b/src/app/calendar/calendar.ts @@ -0,0 +1,72 @@ +import { html, css, LitElement } from 'lit'; +import { customElement } from 'lit/decorators.js'; + +@customElement('app-calendar') +export default class Calendar extends LitElement { + static styles = css` + :host { + height: 100%; + display: flex; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + } + .column-layout { + display: flex; + flex-direction: column; + } + .demo-content { + background-color: transparent; + border-color: hsla(var(--ig-gray-400)); + border-width: 2px; + border-style: dashed; + justify-content: center; + align-items: center; + align-content: flex-start; + left: 50%; + transform: translate(-50%, -50%); + top: 50%; + position: absolute; + padding: 64px; + min-width: 50px; + min-height: 50px; + } + .image { + object-fit: cover; + margin: 0 0 24px; + min-width: 0; + min-height: 0; + max-width: 280px; + flex-shrink: 0; + } + .h5 { + color: hsla(var(--ig-secondary-800)); + margin: 0 0 16px; + height: max-content; + min-width: min-content; + } + .text { + text-align: center; + color: hsla(var(--ig-gray-700)); + margin: 0 0 24px; + height: max-content; + min-width: min-content; + max-width: 320px; + } + `; + + render() { + return html` + +
+ +
+ Start building! +
+

+ Remove the "demo-content" container, and add your own content. +

+
+ `; + } +} diff --git a/src/app/contacts/contacts.test.ts b/src/app/contacts/contacts.test.ts new file mode 100644 index 0000000..c69aff8 --- /dev/null +++ b/src/app/contacts/contacts.test.ts @@ -0,0 +1,9 @@ +import { expect } from '@open-wc/testing'; +import Contacts from './contacts.js'; + +describe('Contacts', () => { + it(' is an instance of Contacts', async () => { + const element = document.createElement('app-contacts'); + expect(element).to.be.instanceOf(Contacts); + }); +}); diff --git a/src/app/contacts/contacts.ts b/src/app/contacts/contacts.ts new file mode 100644 index 0000000..ee005f8 --- /dev/null +++ b/src/app/contacts/contacts.ts @@ -0,0 +1,72 @@ +import { html, css, LitElement } from 'lit'; +import { customElement } from 'lit/decorators.js'; + +@customElement('app-contacts') +export default class Contacts extends LitElement { + static styles = css` + :host { + height: 100%; + display: flex; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + } + .column-layout { + display: flex; + flex-direction: column; + } + .demo-content { + background-color: transparent; + border-color: hsla(var(--ig-gray-400)); + border-width: 2px; + border-style: dashed; + justify-content: center; + align-items: center; + align-content: flex-start; + left: 50%; + transform: translate(-50%, -50%); + top: 50%; + position: absolute; + padding: 64px; + min-width: 50px; + min-height: 50px; + } + .image { + object-fit: cover; + margin: 0 0 24px; + min-width: 0; + min-height: 0; + max-width: 280px; + flex-shrink: 0; + } + .h5 { + color: hsla(var(--ig-secondary-800)); + margin: 0 0 16px; + height: max-content; + min-width: min-content; + } + .text { + text-align: center; + color: hsla(var(--ig-gray-700)); + margin: 0 0 24px; + height: max-content; + min-width: min-content; + max-width: 320px; + } + `; + + render() { + return html` + +
+ +
+ Start building! +
+

+ Remove the "demo-content" container, and add your own content. +

+
+ `; + } +} diff --git a/src/app/contracts/contracts.test.ts b/src/app/contracts/contracts.test.ts new file mode 100644 index 0000000..dbd596f --- /dev/null +++ b/src/app/contracts/contracts.test.ts @@ -0,0 +1,9 @@ +import { expect } from '@open-wc/testing'; +import Contracts from './contracts.js'; + +describe('Contracts', () => { + it(' is an instance of Contracts', async () => { + const element = document.createElement('app-contracts'); + expect(element).to.be.instanceOf(Contracts); + }); +}); diff --git a/src/app/contracts/contracts.ts b/src/app/contracts/contracts.ts new file mode 100644 index 0000000..345489b --- /dev/null +++ b/src/app/contracts/contracts.ts @@ -0,0 +1,72 @@ +import { html, css, LitElement } from 'lit'; +import { customElement } from 'lit/decorators.js'; + +@customElement('app-contracts') +export default class Contracts extends LitElement { + static styles = css` + :host { + height: 100%; + display: flex; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + } + .column-layout { + display: flex; + flex-direction: column; + } + .demo-content { + background-color: transparent; + border-color: hsla(var(--ig-gray-400)); + border-width: 2px; + border-style: dashed; + justify-content: center; + align-items: center; + align-content: flex-start; + left: 50%; + transform: translate(-50%, -50%); + top: 50%; + position: absolute; + padding: 64px; + min-width: 50px; + min-height: 50px; + } + .image { + object-fit: cover; + margin: 0 0 24px; + min-width: 0; + min-height: 0; + max-width: 280px; + flex-shrink: 0; + } + .h5 { + color: hsla(var(--ig-secondary-800)); + margin: 0 0 16px; + height: max-content; + min-width: min-content; + } + .text { + text-align: center; + color: hsla(var(--ig-gray-700)); + margin: 0 0 24px; + height: max-content; + min-width: min-content; + max-width: 320px; + } + `; + + render() { + return html` + +
+ +
+ Start building! +
+

+ Remove the "demo-content" container, and add your own content. +

+
+ `; + } +} diff --git a/src/app/home/home.test.ts b/src/app/home/home.test.ts new file mode 100644 index 0000000..abc508b --- /dev/null +++ b/src/app/home/home.test.ts @@ -0,0 +1,9 @@ +import { expect } from '@open-wc/testing'; +import Home from './home.js'; + +describe('Home', () => { + it(' is an instance of Home', async () => { + const element = document.createElement('app-home'); + expect(element).to.be.instanceOf(Home); + }); +}); diff --git a/src/app/home/home.ts b/src/app/home/home.ts new file mode 100644 index 0000000..d2c9246 --- /dev/null +++ b/src/app/home/home.ts @@ -0,0 +1,498 @@ +import { html, css, LitElement } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { Router } from '@vaadin/router'; +import { defineComponents, IgcAvatarComponent, IgcChipComponent, IgcListComponent, IgcListItemComponent } from 'igniteui-webcomponents'; +import { IgcCategoryChartModule } from 'igniteui-webcomponents-charts'; +import { ModuleManager } from 'igniteui-webcomponents-core'; +import 'igniteui-webcomponents-grids/grids/combined.js'; +import { CustomersType } from '../models/northwind/customers-type'; +import { MeetingsTasksType } from '../models/crmapp-data/meetings-tasks-type'; +import { RevenueType } from '../models/e-commerce/revenue-type'; +import { eCommerceService } from '../services/ECommerce-service'; +import { cRMAppDataService } from '../services/CRMAppData-service'; +import { northwindService } from '../services/Northwind-service'; + +ModuleManager.register(IgcCategoryChartModule); + +defineComponents(IgcListComponent, IgcListItemComponent, IgcAvatarComponent, IgcChipComponent); + +@customElement('app-home') +export default class Home extends LitElement { + static styles = css` + :host { + height: 100%; + display: flex; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + } + .row-layout { + display: flex; + } + .group { + background-color: hsla(var(--ig-gray-100)); + flex-wrap: wrap; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 12px; + overflow: auto; + position: relative; + padding: 12px; + min-height: 50px; + flex-grow: 1; + flex-basis: 0; + } + .column-layout { + display: flex; + flex-direction: column; + } + .group_1 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 12px; + position: relative; + min-width: 280px; + min-height: 50px; + flex-grow: 2; + flex-basis: 0; + } + .group_2 { + background-color: hsla(var(--ig-surface-500)); + border-color: hsla(var(--ig-gray-200)); + border-width: 1px; + border-style: solid; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 16px; + position: relative; + padding: 16px 16px 24px; + min-width: 50px; + min-height: 50px; + flex-shrink: 0; + } + .group_3 { + background-color: hsla(var(--ig-surface-500)); + border-color: hsla(var(--ig-gray-300)); + border-width: 1px; + border-style: solid; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 16px; + position: relative; + padding: 16px 16px 24px; + min-width: 50px; + min-height: 50px; + flex-shrink: 0; + } + .group_4 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 12px; + position: relative; + min-width: 280px; + min-height: 50px; + flex-grow: 1; + flex-basis: 0; + } + .group_5 { + background-color: hsla(var(--ig-surface-500)); + border-color: hsla(var(--ig-gray-300)); + border-width: 1px; + border-style: solid; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 16px; + overflow: auto; + position: relative; + padding: 16px 16px 24px; + min-width: 50px; + max-height: 428px; + flex-shrink: 0; + } + .group_6 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + overflow: auto; + position: relative; + min-width: 50px; + min-height: 50px; + } + .group_7 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 2px; + position: relative; + min-width: 50px; + min-height: 50px; + } + .group_8 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + position: relative; + min-width: 50px; + flex-shrink: 0; + } + .group_9 { + flex-wrap: wrap; + justify-content: flex-start; + align-items: center; + align-content: flex-start; + gap: 4px; + position: relative; + flex-shrink: 0; + } + .group_10 { + flex-wrap: wrap; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 2px; + position: relative; + min-width: 50px; + flex-shrink: 0; + } + .group_11 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 2px; + position: relative; + min-width: 50px; + flex-shrink: 0; + } + .group_12 { + flex-wrap: wrap; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: -2px; + position: relative; + min-width: 50px; + flex-shrink: 0; + } + .group_13 { + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + gap: 2px; + position: relative; + min-width: 50px; + } + .text { + height: max-content; + min-width: min-content; + } + .hyperlink { + text-align: right; + color: hsla(var(--ig-primary-500)); + cursor: pointer; + height: max-content; + min-width: min-content; + } + .avatar::part(base) { + background-color: rgba(71, 124, 41, 0.2); + } + .hyperlink_1 { + color: hsla(var(--ig-primary-500)); + cursor: pointer; + height: max-content; + min-width: min-content; + } + .text_1 { + color: hsla(var(--ig-gray-800)); + height: max-content; + min-width: min-content; + } + .text_2 { + color: hsla(var(--ig-gray-600)); + height: max-content; + min-width: min-content; + } + .text_3 { + color: hsla(var(--ig-gray-600)); + margin: 0 4px 0 0; + height: max-content; + min-width: min-content; + } + .hyperlink_2 { + color: hsla(var(--ig-primary-500)); + height: max-content; + min-width: min-content; + } + .hyperlink_3 { + color: hsla(var(--ig-gray-600)); + height: max-content; + min-width: min-content; + flex-shrink: 0; + } + .chip { + margin: 4px 0 0; + width: max-content; + height: max-content; + } + .avatar_1::part(base) { + background-color: rgba(27, 95, 158, 0.2); + } + .avatar_2::part(base) { + background-color: transparent; + } + .avatar_3::part(base) { + background-color: transparent; + } + .category-chart { + --brushes: #72B24D #9362A3 #F06583 #FCB13F #407DB7; + --outlines: #72B24D #9362A3 #F06583 #FCB13F #407DB7; + --marker-brushes: #72B24D #9362A3 #F06583 #FCB13F #407DB7; + --marker-outlines: #72B24D #9362A3 #F06583 #FCB13F #407DB7; + min-height: 300px; + flex-grow: 1; + flex-basis: 0; + } + .grid { + min-width: 248px; + min-height: 300px; + flex-grow: 1; + flex-basis: 0; + } + .list { + height: max-content; + } + `; + + constructor() { + super(); + eCommerceService.getRevenueList().then((data) => { + this.eCommerceRevenue = data; + }, err => console.log(err)); + this.northwindCustomers = northwindService.getData('CustomersType'); + cRMAppDataService.getMeetingsTasksList().then((data) => { + this.cRMAppDataMeetingsTasks = data; + }, err => console.log(err)); + } + + @state() + private eCommerceRevenue: RevenueType[] = []; + + @state() + private northwindCustomers: CustomersType[] = []; + + @state() + private cRMAppDataMeetingsTasks: MeetingsTasksType[] = []; + + render() { + return html` + + +
+
+
+

+ Quarterly Performance +

+ + + View All Reports + +
+
+

+ New Contracts +

+ + + + + + + + + + + + + + View All Contracts + +
+
+
+
+

+ New Accounts +

+
+ + ${this.northwindCustomers?.map((item) => html` + + +
+
+ + ${item.companyName} + +

+ ${item.contactName} +

+
+

+ ${item.address?.street} +

+

+ , +

+

+ ${item.address?.city} +

+

+ , +

+

+ ${item.address?.country} +

+
+

+ ${item.address?.phone} +

+
+
+
+ `)} +
+
+ + View All Accounts + +
+
+

+ Recent Contacts +

+
+ + ${this.northwindCustomers?.map((item) => html` + + +
+
+ + ${item.contactName} + +
+

+ ${item.contactTitle} +

+

+ @ +

+ + ${item.companyName} + +
+
+
+
+ `)} +
+
+ + View All Contacts + +
+
+
+
+

+ My Meetings +

+ + ${this.cRMAppDataMeetingsTasks?.map((item) => html` + + +
+
+
+

+ Meeting with +

+

+ ${item.Contact} +

+
+
+

+ ${item.MeetingDate} +

+

+ - +

+

+ ${item.MeetingTime} +

+
+ + ${item.MeetingType} + +
+
+
+ `)} +
+ + View Calendar + +
+
+

+ Today’s Tasks +

+ + ${this.cRMAppDataMeetingsTasks?.map((item) => html` + + +
+
+
+

+ ${item.Task} +

+

+ - +

+

+ ${item.Company} +

+
+
+

+ Due by +

+

+ ${item.DueDate} +

+
+ + ${item.TaskStatus} + +
+
+
+ `)} +
+ + View Tasks + +
+
+
+ `; + } +} diff --git a/src/app/models/crmapp-data/meetings-tasks-type.ts b/src/app/models/crmapp-data/meetings-tasks-type.ts new file mode 100644 index 0000000..32cbcaa --- /dev/null +++ b/src/app/models/crmapp-data/meetings-tasks-type.ts @@ -0,0 +1,10 @@ +export interface MeetingsTasksType { + MeetingDate: string; + MeetingTime: string; + Contact: string; + Company: string; + MeetingType: string; + Task: string; + TaskStatus: string; + DueDate: string; +} diff --git a/src/app/models/crmapp-data/table1-type.ts b/src/app/models/crmapp-data/table1-type.ts new file mode 100644 index 0000000..657baff --- /dev/null +++ b/src/app/models/crmapp-data/table1-type.ts @@ -0,0 +1,6 @@ +export interface Table1Type { + Client: string; + Contact: string; + Address: string; + Phone: string; +} diff --git a/src/app/models/e-commerce/revenue-type.ts b/src/app/models/e-commerce/revenue-type.ts new file mode 100644 index 0000000..eb05b36 --- /dev/null +++ b/src/app/models/e-commerce/revenue-type.ts @@ -0,0 +1,4 @@ +export interface RevenueType { + Month: string; + Revenue: number; +} diff --git a/src/app/models/northwind/address-type.ts b/src/app/models/northwind/address-type.ts new file mode 100644 index 0000000..49db6cd --- /dev/null +++ b/src/app/models/northwind/address-type.ts @@ -0,0 +1,8 @@ +export interface AddressType { + street: string; + city: string; + region: string; + postalCode: string; + country: string; + phone: string; +} diff --git a/src/app/models/northwind/customers-type.ts b/src/app/models/northwind/customers-type.ts new file mode 100644 index 0000000..b59f0fe --- /dev/null +++ b/src/app/models/northwind/customers-type.ts @@ -0,0 +1,9 @@ +import { AddressType } from './address-type'; + +export interface CustomersType { + customerID: string; + companyName: string; + contactName: string; + contactTitle: string; + address: AddressType; +} diff --git a/src/app/not-found/not-found.ts b/src/app/not-found/not-found.ts new file mode 100644 index 0000000..f2d99f4 --- /dev/null +++ b/src/app/not-found/not-found.ts @@ -0,0 +1,11 @@ +import { html, LitElement } from 'lit'; +import { customElement } from 'lit/decorators.js'; + +@customElement('app-not-found') +export default class NotFound extends LitElement { + render() { + return html` +

Error 404: Page not found

+ `; + } +} diff --git a/src/app/reports/reports.test.ts b/src/app/reports/reports.test.ts new file mode 100644 index 0000000..cdca1da --- /dev/null +++ b/src/app/reports/reports.test.ts @@ -0,0 +1,9 @@ +import { expect } from '@open-wc/testing'; +import Reports from './reports.js'; + +describe('Reports', () => { + it(' is an instance of Reports', async () => { + const element = document.createElement('app-reports'); + expect(element).to.be.instanceOf(Reports); + }); +}); diff --git a/src/app/reports/reports.ts b/src/app/reports/reports.ts new file mode 100644 index 0000000..397efdc --- /dev/null +++ b/src/app/reports/reports.ts @@ -0,0 +1,72 @@ +import { html, css, LitElement } from 'lit'; +import { customElement } from 'lit/decorators.js'; + +@customElement('app-reports') +export default class Reports extends LitElement { + static styles = css` + :host { + height: 100%; + display: flex; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + } + .column-layout { + display: flex; + flex-direction: column; + } + .demo-content { + background-color: transparent; + border-color: hsla(var(--ig-gray-400)); + border-width: 2px; + border-style: dashed; + justify-content: center; + align-items: center; + align-content: flex-start; + left: 50%; + transform: translate(-50%, -50%); + top: 50%; + position: absolute; + padding: 64px; + min-width: 50px; + min-height: 50px; + } + .image { + object-fit: cover; + margin: 0 0 24px; + min-width: 0; + min-height: 0; + max-width: 280px; + flex-shrink: 0; + } + .h5 { + color: hsla(var(--ig-secondary-800)); + margin: 0 0 16px; + height: max-content; + min-width: min-content; + } + .text { + text-align: center; + color: hsla(var(--ig-gray-700)); + margin: 0 0 24px; + height: max-content; + min-width: min-content; + max-width: 320px; + } + `; + + render() { + return html` + +
+ +
+ Start building! +
+

+ Remove the "demo-content" container, and add your own content. +

+
+ `; + } +} diff --git a/src/app/services/CRMAppData-service.ts b/src/app/services/CRMAppData-service.ts new file mode 100644 index 0000000..3bc2ed8 --- /dev/null +++ b/src/app/services/CRMAppData-service.ts @@ -0,0 +1,21 @@ +import { Table1Type } from '../models/crmapp-data/table1-type'; +import { MeetingsTasksType } from '../models/crmapp-data/meetings-tasks-type'; + +class CRMAppDataService { + public getTable1List = async (): Promise => { + const response = await fetch('https://excel2json.io/api/share/7c450fc9-b631-4529-e668-08dab79fa5b4'); + if (!response.ok) { + return Promise.resolve([]); + } + return response.json(); + } + + public getMeetingsTasksList = async (): Promise => { + const response = await fetch('https://excel2json.io/api/share/2fd4ecd6-da6c-4e37-e666-08dab79fa5b4'); + if (!response.ok) { + return Promise.resolve([]); + } + return response.json(); + } +} +export const cRMAppDataService: CRMAppDataService = new CRMAppDataService(); diff --git a/src/app/services/ECommerce-service.ts b/src/app/services/ECommerce-service.ts new file mode 100644 index 0000000..eef552c --- /dev/null +++ b/src/app/services/ECommerce-service.ts @@ -0,0 +1,12 @@ +import { RevenueType } from '../models/e-commerce/revenue-type'; + +class ECommerceService { + public getRevenueList = async (): Promise => { + const response = await fetch('https://excel2json.io/api/share/03e74dde-d2e1-4fee-437d-08da496bf5f2'); + if (!response.ok) { + return Promise.resolve([]); + } + return response.json(); + } +} +export const eCommerceService: ECommerceService = new ECommerceService(); diff --git a/src/app/services/Northwind-service.ts b/src/app/services/Northwind-service.ts new file mode 100644 index 0000000..b96914b --- /dev/null +++ b/src/app/services/Northwind-service.ts @@ -0,0 +1,8 @@ +import { Northwind } from '../static-data/northwind'; + +class NorthwindService { + public getData(tableName: string): any[] { + return Northwind[tableName]; + } +} +export const northwindService: NorthwindService = new NorthwindService(); diff --git a/src/app/static-data/northwind.ts b/src/app/static-data/northwind.ts new file mode 100644 index 0000000..421f641 --- /dev/null +++ b/src/app/static-data/northwind.ts @@ -0,0 +1,4 @@ +/* eslint-disable */ +export const Northwind: { [key: string]: any } = { + 'CustomersType': [{"customerID":"AROUT","companyName":"Around the Horn","contactName":"Thomas Hardy","contactTitle":"Sales Representative","address":{"street":"120 Hanover Sq.","city":"London","region":null,"postalCode":"WA1 1DP","country":"UK","phone":"(171) 555-7788"}},{"customerID":"BERGS","companyName":"Berglunds snabbköp","contactName":"Christina Berglund","contactTitle":"Order Administrator","address":{"street":"Berguvsvägen 8","city":"Luleå","region":null,"postalCode":"S-958 22","country":"Sweden","phone":"0921-12 34 65"}},{"customerID":"BLAUS","companyName":"Blauer See Delikatessen","contactName":"Hanna Moos","contactTitle":"Sales Representative","address":{"street":"Forsterstr. 57","city":"Mannheim","region":null,"postalCode":"68306","country":"Germany","phone":"0621-08460"}},{"customerID":"BLONP","companyName":"Blondesddsl père et fils","contactName":"Frédérique Citeaux","contactTitle":"Marketing Manager","address":{"street":"24 place Kléber","city":"Strasbourg","region":null,"postalCode":"67000","country":"France","phone":"88.60.15.31"}},{"customerID":"BOLID","companyName":"Bólido Comidas preparadas","contactName":"Martín Sommer","contactTitle":"Owner","address":{"street":"67C Araquil","city":"Madrid","region":null,"postalCode":"28023","country":"Spain","phone":"(91) 555 22 82"}},{"customerID":"BONAP","companyName":"Bon app'","contactName":"Laurence Lebihan","contactTitle":"Owner","address":{"street":"12 rue des Bouchers","city":"Marseille","region":null,"postalCode":"13008","country":"France","phone":"91.24.45.40"}},{"customerID":"ANTON","companyName":"Antonio Moreno Taquería","contactName":"Antonio Moreno","contactTitle":"Owner","address":{"street":"Mataderos 2312","city":"México D.F.","region":null,"postalCode":"5023","country":"Mexico","phone":"(5) 555-3932"}},{"customerID":"ANATR","companyName":"Ana Trujillo Emparedados y helados","contactName":"Ana Trujillo","contactTitle":"Owner","address":{"street":"Avda. de la Constitución 2222","city":"México D.F.","region":null,"postalCode":"5021","country":"Mexico","phone":"(5) 555-4729"}},{"customerID":"CACTU","companyName":"Cactus Comidas para llevar","contactName":"Patricio Simpson","contactTitle":"Sales Agent","address":{"street":"Cerrito 333","city":"Buenos Aires","region":null,"postalCode":"1010","country":"Argentina","phone":"(1) 135-5555"}},{"customerID":"BSBEV","companyName":"B's Beverages","contactName":"Victoria Ashworth","contactTitle":"Sales Representative","address":{"street":"Fauntleroy Circus","city":"London","region":null,"postalCode":"EC2 5NT","country":"UK","phone":"(171) 555-1212"}},{"customerID":"CENTC","companyName":"Centro comercial Moctezuma","contactName":"Francisco Chang","contactTitle":"Marketing Manager","address":{"street":"Sierras de Granada 9993","city":"México D.F.","region":null,"postalCode":"5022","country":"Mexico","phone":"(5) 555-3392"}},{"customerID":"CHOPS","companyName":"Chop-suey Chinese","contactName":"Yang Wang","contactTitle":"Owner","address":{"street":"Hauptstr. 29","city":"Bern","region":null,"postalCode":"3012","country":"Switzerland","phone":"0452-076545"}},{"customerID":"COMMI","companyName":"Comércio Mineiro","contactName":"Pedro Afonso","contactTitle":"Sales Associate","address":{"street":"23 Av. dos Lusíadas","city":"Sao Paulo","region":"SP","postalCode":"05432-043","country":"Brazil","phone":"(11) 555-7647"}},{"customerID":"CONSH","companyName":"Consolidated Holdings","contactName":"Elizabeth Brown","contactTitle":"Sales Representative","address":{"street":"Berkeley Gardens 12 Brewery","city":"London","region":null,"postalCode":"WX1 6LT","country":"UK","phone":"(171) 555-2282"}},{"customerID":"ALFKI","companyName":"Alfreds Futterkiste","contactName":"Maria Anders","contactTitle":"Sales Representative","address":{"street":"Obere Str. 57","city":"Berlin","region":null,"postalCode":"12209","country":"Germany","phone":"030-0074321"}},{"customerID":"BOTTM","companyName":"Bottom-Dollar Markets","contactName":"Elizabeth Lincoln","contactTitle":"Accounting Manager","address":{"street":"23 Tsawassen Blvd.","city":"Tsawassen","region":"BC","postalCode":"T2F 8M4","country":"Canada","phone":"(604) 555-4729"}},{"customerID":"DRACD","companyName":"Drachenblut Delikatessen","contactName":"Sven Ottlieb","contactTitle":"Order Administrator","address":{"street":"Walserweg 21","city":"Aachen","region":null,"postalCode":"52066","country":"Germany","phone":"0241-039123"}},{"customerID":"DUMON","companyName":"Du monde entier","contactName":"Janine Labrune","contactTitle":"Owner","address":{"street":"67 rue des Cinquante Otages","city":"Nantes","region":null,"postalCode":"44000","country":"France","phone":"40.67.88.88"}},{"customerID":"FAMIA","companyName":"Familia Arquibaldo","contactName":"Aria Cruz","contactTitle":"Marketing Assistant","address":{"street":"Rua Orós 92","city":"Sao Paulo","region":"SP","postalCode":"05442-030","country":"Brazil","phone":"(11) 555-9857"}},{"customerID":"FISSA","companyName":"FISSA Fabrica Inter. Salchichas S.A.","contactName":"Diego Roel","contactTitle":"Accounting Manager","address":{"street":"C/ Moralzarzal 86","city":"Madrid","region":null,"postalCode":"28034","country":"Spain","phone":"(91) 555 94 44"}},{"customerID":"FOLIG","companyName":"Folies gourmandes","contactName":"Martine Rancé","contactTitle":"Assistant Sales Agent","address":{"street":"184 chaussée de Tournai","city":"Lille","region":null,"postalCode":"59000","country":"France","phone":"20.16.10.16"}},{"customerID":"FOLKO","companyName":"Folk och fä HB","contactName":"Maria Larsson","contactTitle":"Owner","address":{"street":"Åkergatan 24","city":"Bräcke","region":null,"postalCode":"S-844 67","country":"Sweden","phone":"0695-34 67 21"}},{"customerID":"FRANK","companyName":"Frankenversand","contactName":"Peter Franken","contactTitle":"Marketing Manager","address":{"street":"Berliner Platz 43","city":"München","region":null,"postalCode":"80805","country":"Germany","phone":"089-0877310"}},{"customerID":"FRANR","companyName":"France restauration","contactName":"Carine Schmitt","contactTitle":"Marketing Manager","address":{"street":"54 rue Royale","city":"Nantes","region":null,"postalCode":"44000","country":"France","phone":"40.32.21.21"}},{"customerID":"EASTC","companyName":"Eastern Connection","contactName":"Ann Devon","contactTitle":"Sales Agent","address":{"street":"35 King George","city":"London","region":null,"postalCode":"WX3 6FW","country":"UK","phone":"(171) 555-0297"}},{"customerID":"ERNSH","companyName":"Ernst Handel","contactName":"Roland Mendel","contactTitle":"Sales Manager","address":{"street":"Kirchgasse 6","city":"Graz","region":null,"postalCode":"8010","country":"Austria","phone":"7675-3425"}},{"customerID":"FRANS","companyName":"Franchi S.p.A.","contactName":"Paolo Accorti","contactTitle":"Sales Representative","address":{"street":"Via Monte Bianco 34","city":"Torino","region":null,"postalCode":"10100","country":"Italy","phone":"011-4988260"}},{"customerID":"FURIB","companyName":"Furia Bacalhau e Frutos do Mar","contactName":"Lino Rodriguez","contactTitle":"Sales Manager","address":{"street":"Jardim das rosas n. 32","city":"Lisboa","region":null,"postalCode":"1675","country":"Portugal","phone":"(1) 354-2534"}},{"customerID":"GALED","companyName":"Galería del gastrónomo","contactName":"Eduardo Saavedra","contactTitle":"Marketing Manager","address":{"street":"Rambla de Cataluña 23","city":"Barcelona","region":null,"postalCode":"8022","country":"Spain","phone":"(93) 203 4560"}},{"customerID":"GODOS","companyName":"Godos Cocina Típica","contactName":"José Pedro Freyre","contactTitle":"Sales Manager","address":{"street":"C/ Romero 33","city":"Sevilla","region":null,"postalCode":"41101","country":"Spain","phone":"(95) 555 82 82"}},{"customerID":"GOURL","companyName":"Gourmet Lanchonetes","contactName":"André Fonseca","contactTitle":"Sales Associate","address":{"street":"Av. Brasil 442","city":"Campinas","region":"SP","postalCode":"04876-786","country":"Brazil","phone":"(11) 555-9482"}},{"customerID":"HILAA","companyName":"HILARION-Abastos","contactName":"Carlos Hernández","contactTitle":"Sales Representative","address":{"street":"Carrera 22 con Ave. Carlos Soublette #8-35","city":"San Cristóbal","region":"Táchira","postalCode":"5022","country":"Venezuela","phone":"(5) 555-1340"}},{"customerID":"HUNGC","companyName":"Hungry Coyote Import Store","contactName":"Yoshi Latimer","contactTitle":"Sales Representative","address":{"street":"City Center Plaza 516 Main St.","city":"Elgin","region":"OR","postalCode":"97827","country":"USA","phone":"(503) 555-6874"}},{"customerID":"HUNGO","companyName":"Hungry Owl All-Night Grocers","contactName":"Patricia McKenna","contactTitle":"Sales Associate","address":{"street":"8 Johnstown Road","city":"Cork","region":"Co. Cork","postalCode":null,"country":"Ireland","phone":"2967 542"}},{"customerID":"ISLAT","companyName":"Island Trading","contactName":"Helen Bennett","contactTitle":"Marketing Manager","address":{"street":"Garden House Crowther Way","city":"Cowes","region":"Isle of Wight","postalCode":"PO31 7PJ","country":"UK","phone":"(198) 555-8888"}},{"customerID":"KOENE","companyName":"Königlich Essen","contactName":"Philip Cramer","contactTitle":"Sales Associate","address":{"street":"Maubelstr. 90","city":"Brandenburg","region":null,"postalCode":"14776","country":"Germany","phone":"0555-09876"}},{"customerID":"LACOR","companyName":"La corne d'abondance","contactName":"Daniel Tonini","contactTitle":"Sales Representative","address":{"street":"67 avenue de l'Europe","city":"Versailles","region":null,"postalCode":"78000","country":"France","phone":"30.59.84.10"}},{"customerID":"GROSR","companyName":"GROSELLA-Restaurante","contactName":"Manuel Pereira","contactTitle":"Owner","address":{"street":"5ª Ave. Los Palos Grandes","city":"Caracas","region":"DF","postalCode":"1081","country":"Venezuela","phone":"(2) 283-2951"}},{"customerID":"HANAR","companyName":"Hanari Carnes","contactName":"Mario Pontes","contactTitle":"Accounting Manager","address":{"street":"Rua do Paço 67","city":"Rio de Janeiro","region":"RJ","postalCode":"05454-876","country":"Brazil","phone":"(21) 555-0091"}},{"customerID":"LAUGB","companyName":"Laughing Bacchus Wine Cellars","contactName":"Yoshi Tannamuri","contactTitle":"Marketing Assistant","address":{"street":"1900 Oak St.","city":"Vancouver","region":"BC","postalCode":"V3F 2K1","country":"Canada","phone":"(604) 555-3392"}},{"customerID":"LAZYK","companyName":"Lazy K Kountry Store","contactName":"John Steel","contactTitle":"Marketing Manager","address":{"street":"12 Orchestra Terrace","city":"Walla Walla","region":"WA","postalCode":"99362","country":"USA","phone":"(509) 555-7969"}},{"customerID":"LEHMS","companyName":"Lehmanns Marktstand","contactName":"Renate Messner","contactTitle":"Sales Representative","address":{"street":"Magazinweg 7","city":"Frankfurt a.M.","region":null,"postalCode":"60528","country":"Germany","phone":"069-0245984"}},{"customerID":"GREAL","companyName":"Great Lakes Food Market","contactName":"Howard Snyder","contactTitle":"Marketing Manager","address":{"street":"2732 Baker Blvd.","city":"Eugene","region":"OR","postalCode":"97403","country":"USA","phone":"(503) 555-7555"}},{"customerID":"LAMAI","companyName":"La maison d'Asie","contactName":"Annette Roulet","contactTitle":"Sales Manager","address":{"street":"1 rue Alsace-Lorraine","city":"Toulouse","region":null,"postalCode":"31000","country":"France","phone":"61.77.61.10"}},{"customerID":"LETSS","companyName":"Let's Stop N Shop","contactName":"Jaime Yorres","contactTitle":"Owner","address":{"street":"87 Polk St. Suite 5","city":"San Francisco","region":"CA","postalCode":"94117","country":"USA","phone":"(415) 555-5938"}},{"customerID":"MAGAA","companyName":"Magazzini Alimentari Riuniti","contactName":"Giovanni Rovelli","contactTitle":"Marketing Manager","address":{"street":"Via Ludovico il Moro 22","city":"Bergamo","region":null,"postalCode":"24100","country":"Italy","phone":"035-640230"}},{"customerID":"MAISD","companyName":"Maison Dewey","contactName":"Catherine Dewey","contactTitle":"Sales Agent","address":{"street":"Rue Joseph-Bens 532","city":"Bruxelles","region":null,"postalCode":"B-1180","country":"Belgium","phone":"(02) 201 24 67"}},{"customerID":"MEREP","companyName":"Mère Paillarde","contactName":"Jean Fresnière","contactTitle":"Marketing Assistant","address":{"street":"43 rue St. Laurent","city":"Montréal","region":"Québec","postalCode":"H1J 1C3","country":"Canada","phone":"(514) 555-8054"}},{"customerID":"MORGK","companyName":"Morgenstern Gesundkost","contactName":"Alexander Feuer","contactTitle":"Marketing Assistant","address":{"street":"Heerstr. 22","city":"Leipzig","region":null,"postalCode":"4179","country":"Germany","phone":"0342-023176"}},{"customerID":"NORTS","companyName":"North/South","contactName":"Simon Crowther","contactTitle":"Sales Associate","address":{"street":"South House 300 Queensbridge","city":"London","region":null,"postalCode":"SW7 1RZ","country":"UK","phone":"(171) 555-7733"}},{"customerID":"OCEAN","companyName":"Océano Atlántico Ltda.","contactName":"Yvonne Moncada","contactTitle":"Sales Agent","address":{"street":"Ing. Gustavo Moncada 8585 Piso 20-A","city":"Buenos Aires","region":null,"postalCode":"1010","country":"Argentina","phone":"(1) 135-5333"}},{"customerID":"LINOD","companyName":"LINO-Delicateses","contactName":"Felipe Izquierdo","contactTitle":"Owner","address":{"street":"Ave. 5 de Mayo Porlamar","city":"I. de Margarita","region":"Nueva Esparta","postalCode":"4980","country":"Venezuela","phone":"(8) 34-56-12"}},{"customerID":"LILAS","companyName":"LILA-Supermercado","contactName":"Carlos González","contactTitle":"Accounting Manager","address":{"street":"Carrera 52 con Ave. Bolívar #65-98 Llano Largo","city":"Barquisimeto","region":"Lara","postalCode":"3508","country":"Venezuela","phone":"(9) 331-6954"}},{"customerID":"OLDWO","companyName":"Old World Delicatessen","contactName":"Rene Phillips","contactTitle":"Sales Representative","address":{"street":"2743 Bering St.","city":"Anchorage","region":"AK","postalCode":"99508","country":"USA","phone":"(907) 555-7584"}},{"customerID":"OTTIK","companyName":"Ottilies Käseladen","contactName":"Henriette Pfalzheim","contactTitle":"Owner","address":{"street":"Mehrheimerstr. 369","city":"Köln","region":null,"postalCode":"50739","country":"Germany","phone":"0221-0644327"}},{"customerID":"PICCO","companyName":"Piccolo und mehr","contactName":"Georg Pipps","contactTitle":"Sales Manager","address":{"street":"Geislweg 14","city":"Salzburg","region":null,"postalCode":"5020","country":"Austria","phone":"6562-9722"}},{"customerID":"PARIS","companyName":"Paris spécialités","contactName":"Marie Bertrand","contactTitle":"Owner","address":{"street":"265 boulevard Charonne","city":"Paris","region":null,"postalCode":"75012","country":"France","phone":"(1) 42.34.22.66"}},{"customerID":"PERIC","companyName":"Pericles Comidas clásicas","contactName":"Guillermo Fernández","contactTitle":"Sales Representative","address":{"street":"Calle Dr. Jorge Cash 321","city":"México D.F.","region":null,"postalCode":"5033","country":"Mexico","phone":"(5) 552-3745"}},{"customerID":"PRINI","companyName":"Princesa Isabel Vinhos","contactName":"Isabel de Castro","contactTitle":"Sales Representative","address":{"street":"Estrada da saúde n. 58","city":"Lisboa","region":null,"postalCode":"1756","country":"Portugal","phone":"(1) 356-5634"}},{"customerID":"LONEP","companyName":"Lonesome Pine Restaurant","contactName":"Fran Wilson","contactTitle":"Sales Manager","address":{"street":"89 Chiaroscuro Rd.","city":"Portland","region":"OR","postalCode":"97219","country":"USA","phone":"(503) 555-9573"}},{"customerID":"QUEEN","companyName":"Queen Cozinha","contactName":"Lúcia Carvalho","contactTitle":"Marketing Assistant","address":{"street":"Alameda dos Canàrios 891","city":"Sao Paulo","region":"SP","postalCode":"05487-020","country":"Brazil","phone":"(11) 555-1189"}},{"customerID":"RATTC","companyName":"Rattlesnake Canyon Grocery","contactName":"Paula Wilson","contactTitle":"Assistant Sales Representative","address":{"street":"2817 Milton Dr.","city":"Albuquerque","region":"NM","postalCode":"87110","country":"USA","phone":"(505) 555-5939"}},{"customerID":"REGGC","companyName":"Reggiani Caseifici","contactName":"Maurizio Moroni","contactTitle":"Sales Associate","address":{"street":"Strada Provinciale 124","city":"Reggio Emilia","region":null,"postalCode":"42100","country":"Italy","phone":"0522-556721"}},{"customerID":"QUEDE","companyName":"Que Delícia","contactName":"Bernardo Batista","contactTitle":"Accounting Manager","address":{"street":"Rua da Panificadora","city":"12Rio de Janeiro","region":"RJ","postalCode":"02389-673","country":"Brazil","phone":"(21) 555-4252"}},{"customerID":"RANCH","companyName":"Rancho grande","contactName":"Sergio Gutiérrez","contactTitle":"Sales Representative","address":{"street":"Av. del Libertador 900","city":"Buenos Aires","region":null,"postalCode":"1010","country":"Argentina","phone":"(1) 123-5555"}},{"customerID":"ROMEY","companyName":"Romero y tomillo","contactName":"Alejandra Camino","contactTitle":"Accounting Manager","address":{"street":"Gran Vía 1","city":"Madrid","region":null,"postalCode":"28001","country":"Spain","phone":"(91) 745 6200"}},{"customerID":"QUICK","companyName":"QUICK-Stop","contactName":"Horst Kloss","contactTitle":"Accounting Manager","address":{"street":"Taucherstraße 10","city":"Cunewalde","region":null,"postalCode":"1307","country":"Germany","phone":"0372-035188"}},{"customerID":"RICAR","companyName":"Ricardo Adocicados","contactName":"Janete Limeira","contactTitle":"Assistant Sales Agent","address":{"street":"Av. Copacabana 267","city":"Rio de Janeiro","region":"RJ","postalCode":"02389-890","country":"Brazil","phone":"(21) 555-3412"}},{"customerID":"RICSU","companyName":"Richter Supermarkt","contactName":"Michael Holz","contactTitle":"Sales Manager","address":{"street":"Grenzacherweg 237","city":"Genève","region":null,"postalCode":"1203","country":"Switzerland","phone":"0897-034214"}},{"customerID":"SANTG","companyName":"Santé Gourmet","contactName":"Jonas Bergulfsen","contactTitle":"Owner","address":{"street":"Erling Skakkes gate 78","city":"Stavern","region":null,"postalCode":"4110","country":"Norway","phone":"07-98 92 35"}},{"customerID":"SAVEA","companyName":"Save-a-lot Markets","contactName":"Jose Pavarotti","contactTitle":"Sales Representative","address":{"street":"187 Suffolk Ln.","city":"Boise","region":"ID","postalCode":"83720","country":"USA","phone":"(208) 555-8097"}},{"customerID":"SEVES","companyName":"Seven Seas Imports","contactName":"Hari Kumar","contactTitle":"Sales Manager","address":{"street":"90 Wadhurst Rd.","city":"London","region":null,"postalCode":"OX15 4NB","country":"UK","phone":"(171) 555-1717"}},{"customerID":"SIMOB","companyName":"Simons bistro","contactName":"Jytte Petersen","contactTitle":"Owner","address":{"street":"Vinbæltet 34","city":"Kobenhavn","region":null,"postalCode":"1734","country":"Denmark","phone":"31 12 34 56"}},{"customerID":"SPECD","companyName":"Spécialités du monde","contactName":"Dominique Perrier","contactTitle":"Marketing Manager","address":{"street":"25 rue Lauriston","city":"Paris","region":null,"postalCode":"75016","country":"France","phone":"(1) 47.55.60.10"}},{"customerID":"SPLIR","companyName":"Split Rail Beer & Ale","contactName":"Art Braunschweiger","contactTitle":"Sales Manager","address":{"street":"P.O. Box 555","city":"Lander","region":"WY","postalCode":"82520","country":"USA","phone":"(307) 555-4680"}},{"customerID":"SUPRD","companyName":"Suprêmes délices","contactName":"Pascale Cartrain","contactTitle":"Accounting Manager","address":{"street":"Boulevard Tirou 255","city":"Charleroi","region":null,"postalCode":"B-6000","country":"Belgium","phone":"(071) 23 67 22 20"}},{"customerID":"THEBI","companyName":"The Big Cheese","contactName":"Liz Nixon","contactTitle":"Marketing Manager","address":{"street":"89 Jefferson Way Suite 2","city":"Portland","region":"OR","postalCode":"97201","country":"USA","phone":"(503) 555-3612"}},{"customerID":"THECR","companyName":"The Cracker Box","contactName":"Liu Wong","contactTitle":"Marketing Assistant","address":{"street":"55 Grizzly Peak Rd.","city":"Butte","region":"MT","postalCode":"59801","country":"USA","phone":"(406) 555-5834"}},{"customerID":"TOMSP","companyName":"Toms Spezialitäten","contactName":"Karin Josephs","contactTitle":"Marketing Manager","address":{"street":"Luisenstr. 48","city":"Münster","region":null,"postalCode":"44087","country":"Germany","phone":"0251-031259"}},{"customerID":"TORTU","companyName":"Tortuga Restaurante","contactName":"Miguel Angel Paolino","contactTitle":"Owner","address":{"street":"Avda. Azteca 123","city":"México D.F.","region":null,"postalCode":"5033","country":"Mexico","phone":"(5) 555-2933"}},{"customerID":"TRADH","companyName":"Tradição Hipermercados","contactName":"Anabela Domingues","contactTitle":"Sales Representative","address":{"street":"Av. Inês de Castro 414","city":"Sao Paulo","region":"SP","postalCode":"05634-030","country":"Brazil","phone":"(11) 555-2167"}},{"customerID":"TRAIH","companyName":"Trail's Head Gourmet Provisioners","contactName":"Helvetius Nagy","contactTitle":"Sales Associate","address":{"street":"722 DaVinci Blvd.","city":"Kirkland","region":"WA","postalCode":"98034","country":"USA","phone":"(206) 555-8257"}},{"customerID":"VAFFE","companyName":"Vaffeljernet","contactName":"Palle Ibsen","contactTitle":"Sales Manager","address":{"street":"Smagsloget 45","city":"Århus","region":null,"postalCode":"8200","country":"Denmark","phone":"86 21 32 43"}},{"customerID":"VICTE","companyName":"Victuailles en stock","contactName":"Mary Saveley","contactTitle":"Sales Agent","address":{"street":"2 rue du Commerce","city":"Lyon","region":null,"postalCode":"69004","country":"France","phone":"78.32.54.86"}},{"customerID":"VINET","companyName":"Vins et alcools Chevalier","contactName":"Paul Henriot","contactTitle":"Accounting Manager","address":{"street":"59 rue de l'Abbaye","city":"Reims","region":null,"postalCode":"51100","country":"France","phone":"26.47.15.10"}},{"customerID":"WANDK","companyName":"Die Wandernde Kuh","contactName":"Rita Müller","contactTitle":"Sales Representative","address":{"street":"Adenauerallee 900","city":"Stuttgart","region":null,"postalCode":"70563","country":"Germany","phone":"0711-020361"}},{"customerID":"WARTH","companyName":"Wartian Herkku","contactName":"Pirkko Koskitalo","contactTitle":"Accounting Manager","address":{"street":"Torikatu 38","city":"Oulu","region":null,"postalCode":"90110","country":"Finland","phone":"981-443655"}},{"customerID":"WELLI","companyName":"Wellington Importadora","contactName":"Paula Parente","contactTitle":"Sales Manager","address":{"street":"Rua do Mercado 12","city":"Resende","region":"SP","postalCode":"08737-363","country":"Brazil","phone":"(14) 555-8122"}},{"customerID":"WHITC","companyName":"White Clover Markets","contactName":"Karl Jablonski","contactTitle":"Owner","address":{"street":"305 - 14th Ave. S. Suite 3B","city":"Seattle","region":"WA","postalCode":"98128","country":"USA","phone":"(206) 555-4112"}},{"customerID":"WILMK","companyName":"Wilman Kala","contactName":"Matti Karttunen","contactTitle":"Owner/Marketing Assistant","address":{"street":"Keskuskatu 45","city":"Helsinki","region":null,"postalCode":"21240","country":"Finland","phone":"90-224 8858"}},{"customerID":"WOLZA","companyName":"Wolski Zajazd","contactName":"Zbyszek Piestrzeniewicz","contactTitle":"Owner","address":{"street":"ul. Filtrowa 68","city":"Warszawa","region":null,"postalCode":"01-012","country":"Poland","phone":"(26) 642-7012"}}], +}; diff --git a/src/app/tasks/tasks.test.ts b/src/app/tasks/tasks.test.ts new file mode 100644 index 0000000..6c99590 --- /dev/null +++ b/src/app/tasks/tasks.test.ts @@ -0,0 +1,9 @@ +import { expect } from '@open-wc/testing'; +import Tasks from './tasks.js'; + +describe('Tasks', () => { + it(' is an instance of Tasks', async () => { + const element = document.createElement('app-tasks'); + expect(element).to.be.instanceOf(Tasks); + }); +}); diff --git a/src/app/tasks/tasks.ts b/src/app/tasks/tasks.ts new file mode 100644 index 0000000..8edce04 --- /dev/null +++ b/src/app/tasks/tasks.ts @@ -0,0 +1,72 @@ +import { html, css, LitElement } from 'lit'; +import { customElement } from 'lit/decorators.js'; + +@customElement('app-tasks') +export default class Tasks extends LitElement { + static styles = css` + :host { + height: 100%; + display: flex; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + } + .column-layout { + display: flex; + flex-direction: column; + } + .demo-content { + background-color: transparent; + border-color: hsla(var(--ig-gray-400)); + border-width: 2px; + border-style: dashed; + justify-content: center; + align-items: center; + align-content: flex-start; + left: 50%; + transform: translate(-50%, -50%); + top: 50%; + position: absolute; + padding: 64px; + min-width: 50px; + min-height: 50px; + } + .image { + object-fit: cover; + margin: 0 0 24px; + min-width: 0; + min-height: 0; + max-width: 280px; + flex-shrink: 0; + } + .h5 { + color: hsla(var(--ig-secondary-800)); + margin: 0 0 16px; + height: max-content; + min-width: min-content; + } + .text { + text-align: center; + color: hsla(var(--ig-gray-700)); + margin: 0 0 24px; + height: max-content; + min-width: min-content; + max-width: 320px; + } + `; + + render() { + return html` + +
+ +
+ Start building! +
+

+ Remove the "demo-content" container, and add your own content. +

+
+ `; + } +} diff --git a/src/assets/Account-List-Avatar-Icon.svg b/src/assets/Account-List-Avatar-Icon.svg new file mode 100644 index 0000000..ab11dcb --- /dev/null +++ b/src/assets/Account-List-Avatar-Icon.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/Accounts Icon - Green.svg b/src/assets/Accounts Icon - Green.svg new file mode 100644 index 0000000..f12085c --- /dev/null +++ b/src/assets/Accounts Icon - Green.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/Accounts-Avatar-Icon.svg b/src/assets/Accounts-Avatar-Icon.svg new file mode 100644 index 0000000..161d843 --- /dev/null +++ b/src/assets/Accounts-Avatar-Icon.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/CRM Logo.svg b/src/assets/CRM Logo.svg new file mode 100644 index 0000000..70af781 --- /dev/null +++ b/src/assets/CRM Logo.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/Calendar-Avatar-Icon.svg b/src/assets/Calendar-Avatar-Icon.svg new file mode 100644 index 0000000..6bd3acd --- /dev/null +++ b/src/assets/Calendar-Avatar-Icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/assets/Contacts-Avatar-Icon.svg b/src/assets/Contacts-Avatar-Icon.svg new file mode 100644 index 0000000..8169bc3 --- /dev/null +++ b/src/assets/Contacts-Avatar-Icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/Contacts-List-Avatar-Icon.svg b/src/assets/Contacts-List-Avatar-Icon.svg new file mode 100644 index 0000000..17238be --- /dev/null +++ b/src/assets/Contacts-List-Avatar-Icon.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/assets/Contracts-Avatar-Icon.svg b/src/assets/Contracts-Avatar-Icon.svg new file mode 100644 index 0000000..b325c5c --- /dev/null +++ b/src/assets/Contracts-Avatar-Icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/Home-Avatar-Icon.svg b/src/assets/Home-Avatar-Icon.svg new file mode 100644 index 0000000..f099155 --- /dev/null +++ b/src/assets/Home-Avatar-Icon.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/assets/Reports-Avatar-Icon.svg b/src/assets/Reports-Avatar-Icon.svg new file mode 100644 index 0000000..2d76e49 --- /dev/null +++ b/src/assets/Reports-Avatar-Icon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/assets/Tasks-Avatar-Icon.svg b/src/assets/Tasks-Avatar-Icon.svg new file mode 100644 index 0000000..669518d --- /dev/null +++ b/src/assets/Tasks-Avatar-Icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/start-building-dark.svg b/src/assets/start-building-dark.svg new file mode 100644 index 0000000..d560e70 --- /dev/null +++ b/src/assets/start-building-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/start-building.svg b/src/assets/start-building.svg new file mode 100644 index 0000000..c418b8d --- /dev/null +++ b/src/assets/start-building.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..1a6b6bc --- /dev/null +++ b/src/index.ts @@ -0,0 +1,2 @@ +import './app/app.js'; +import './app/app-routing.js'; diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..e06ecae --- /dev/null +++ b/styles.css @@ -0,0 +1,24 @@ +body { + background: hsla(var(--ig-surface-500, 0 0% 100%)); + color: var(--ig-surface-500-contrast, black); + font-family: var(--ig-font-family); +} + +html, +body { + height: 100%; +} + +/* minor CSS reset */ +body, h1, h2, h3, h4, h5, h6, p { + margin: 0; +} + +html { + box-sizing: border-box; +} + +img, video { + height: auto; + max-width: 100%; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..aef874d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "target": "es2018", + "module": "esnext", + "moduleResolution": "node", + "noEmitOnError": true, + "lib": [ + "es2017", + "dom", + "dom.iterable" + ], + "strict": true, + "skipLibCheck": true, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "experimentalDecorators": true, + "importHelpers": true, + "outDir": "dist", + "sourceMap": true, + "inlineSources": true, + "rootDir": "./", + "declaration": true, + "incremental": true + }, + "exclude": [ + "test" + ], + "files": [ + "src/index.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 0000000..473725e --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,13 @@ + +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "test" + }, + "exclude": [ + "dist" + ], + "include": [ + "**/*.ts" + ] +} diff --git a/web-dev-server.config.mjs b/web-dev-server.config.mjs new file mode 100644 index 0000000..0325792 --- /dev/null +++ b/web-dev-server.config.mjs @@ -0,0 +1,27 @@ +// import { hmrPlugin, presets } from '@open-wc/dev-server-hmr'; + +/** Use Hot Module replacement by adding --hmr to the start command */ +const hmr = process.argv.includes('--hmr'); + +export default /** @type {import('@web/dev-server').DevServerConfig} */ ({ + open: '/', + /** Use regular watch mode if HMR is not enabled. */ + watch: !hmr, + /** Resolve bare module imports */ + nodeResolve: { + exportConditions: ['browser', 'development'], + }, + + /** Compile JS for older browsers. Requires @web/dev-server-esbuild plugin */ + // esbuildTarget: 'auto' + + /** Set appIndex to enable SPA routing */ + appIndex: './index.html', + + plugins: [ + /** Use Hot Module Replacement by uncommenting. Requires @open-wc/dev-server-hmr plugin */ + // hmr && hmrPlugin({ exclude: ['**/*/node_modules/**/*'], presets: [presets.litElement] }), + ], + + // See documentation for all available options +}); diff --git a/web-test-runner.config.mjs b/web-test-runner.config.mjs new file mode 100644 index 0000000..20068e9 --- /dev/null +++ b/web-test-runner.config.mjs @@ -0,0 +1,41 @@ +// import { playwrightLauncher } from '@web/test-runner-playwright'; + +const filteredLogs = ['Running in dev mode', 'lit-html is in dev mode']; + +export default /** @type {import("@web/test-runner").TestRunnerConfig} */ ({ + /** Test files to run */ + files: 'test/src/app/**/*.test.js', + + /** Resolve bare module imports */ + nodeResolve: { + exportConditions: ['browser', 'development'], + }, + + /** Filter out lit dev mode logs */ + filterBrowserLogs(log) { + for (const arg of log.args) { + if (typeof arg === 'string' && filteredLogs.some(l => arg.includes(l))) { + return false; + } + } + return true; + }, + + /** Compile JS for older browsers. Requires @web/dev-server-esbuild plugin */ + // esbuildTarget: 'auto', + + /** Amount of browsers to run concurrently */ + // concurrentBrowsers: 2, + + /** Amount of test files per browser to test concurrently */ + // concurrency: 1, + + /** Browsers to run tests on */ + // browsers: [ + // playwrightLauncher({ product: 'chromium' }), + // playwrightLauncher({ product: 'firefox' }), + // playwrightLauncher({ product: 'webkit' }), + // ], + + // See documentation for all available options +});