mirror of
https://github.com/SuiteCRM/SuiteCRM-Core.git
synced 2025-08-29 01:10:42 +08:00
SuiteCRM 8 initial commit
This commit is contained in:
commit
c895877b7e
547 changed files with 40449 additions and 0 deletions
183
.github/CONTRIBUTING.md
vendored
Normal file
183
.github/CONTRIBUTING.md
vendored
Normal file
|
@ -0,0 +1,183 @@
|
|||
## How to contribute to SuiteCRM
|
||||
|
||||
|
||||
### **Code of Conduct**
|
||||
|
||||
This project and all community members are expected to uphold the [SuiteCRM Code of Conduct.](https://github.com/salesagility/SuiteCRM/blob/master/CODE_OF_CONDUCT.md)
|
||||
|
||||
#### **Bug Reporting**
|
||||
|
||||
* **Please do not open a GitHub issue if the bug is a security vulnerability**, and instead email us at security@suitecrm.com. This will be delivered to the product team who handle security issues. Please don't disclose security bugs publicly until they have been handled by the security team.
|
||||
|
||||
* Your email will be acknowledged within 24 hours during the business week (Mon - Fri), and you’ll receive a more detailed response to your email within 72 hours during the business week (Mon - Fri) indicating the next steps in handling your report.
|
||||
|
||||
* **Ensure the bug was not already reported** by searching on GitHub under [Issues.](https://github.com/salesagility/SuiteCRM/issues)
|
||||
|
||||
* If you're unable to find an open issue that relates to your problem, [open a new one.](https://github.com/salesagility/SuiteCRM/issues/new) Please be sure to follow the issue template as much as possible.
|
||||
|
||||
* **Ensure that the bug you are reporting is a core SuiteCRM issue** and not specific to your individual setup. For these types of issues please use the [Community Forum.](https://www.suitecrm.com/forum/suite-forum)
|
||||
|
||||
#### **Did you fix a bug?**
|
||||
|
||||
* To provide a code contribution for an issue you will need to set up your own fork of the SuiteCRM repository, make your code changes, commit the changes and make a Pull Request to the appropriate branch on the SuiteCM repository. See our [Quick Guide to Fork SuiteCRM.](https://suitecrm.com/wiki/index.php/Contributing_to_SuiteCRM#Quick_Guide_to_Fork_SuiteCRM) Once you have set up your forked repository you can begin making commits to the project.
|
||||
|
||||
* Determine which base branch your bug fix should use. If your bug is present in both hotfix and hotfix-7.10.x then you will need to make a seperate pull request for each branch.
|
||||
|
||||
* Separate each fix into a new branch in your repository and name it with the issue ID e.g. bugfix_3062 or issue-1234.
|
||||
|
||||
* When committing to your individual bugfix branch, please try and use the following as your commit message
|
||||
```Fixed #1234 - <the subject of the issue>```. E.g. ```Fixed #1436 - Reports with nested Parentheses are removing parameters```. By using this format we can easily include all bug fixes within major and minor release notes on our [Wiki](https://suitecrm.com/wiki/index.php/Main_Page).
|
||||
|
||||
* If you are new to Writing Commit Messages in git, follow the guide [here.](http://chris.beams.io/posts/git-commit/#seven-rules)
|
||||
|
||||
* After you have made your commits and pushed them up to your forked repository you then create a [Pull Request](https://help.github.com/articles/about-pull-requests/) to be reviewed and merged into the SuiteCRM repository. Make a new Pull Request for each issue you fix – do not combine multiple bugfixes into one Pull Request.
|
||||
Ensure that your Pull Request fork is salesagility/SuiteCRM, base branch is either hotfix or hotfix-7.8.x, the head fork is your repository, and the base branch is your unique bugfix branch e.g. bugfix_1234.
|
||||
We will automatically reject any Pull Requests made to the wrong branch!
|
||||
|
||||
* If you have not signed our CLA [Contributor License Agreement](https://www.clahub.com/agreements/salesagility/SuiteCRM) then your pull request will fail a check and we will be unable to merge it into the project. You will only be required to sign this once.
|
||||
|
||||
* When a new Pull Request is opened, Travis CI will test the merging of the origin and upstream branch and update the Pull Request. If this check fails you can review the test results and resolve accordingly. To test prior to making a Pull Request install PHPUnit via composer into your develop environment then cd into the tests directory and run: ```$ sh runtests.sh```
|
||||
|
||||
* Ensure that you follow the pull request [template](https://github.com/salesagility/SuiteCRM/blob/master/.github/PULL_REQUEST_TEMPLATE.md) as much as possible.
|
||||
|
||||
#### **Did you create a new feature or enhancement?**
|
||||
|
||||
* Changes that can be considered a new feature or enhancement should be made to the develop branch instead of the hotfix or hotfix-7.8.x. branch.
|
||||
|
||||
* To contribute a feature to SuiteCRM, similar to providing a Bug Fix, you must create a forked repository of SuiteCRM and set up your git and development environment.
|
||||
Once done, create a new branch from **hotfix-7.10.x** (Issues effecting 7.10 & 7.11) or **hotfix** (Issues effecting 7.11 only) and name it relevant to the feature's purpose e.g campaign-wizard-ui. Following our [Code Standards,](https://suitecrm.com/wiki/index.php/Coding_Standards) develop the new feature and ensure your forked repository is kept up to date with minor/major releases. See our [Quick Guide to Fork SuiteCRM](https://suitecrm.com/wiki/index.php/Contributing_to_SuiteCRM#Quick_Guide_to_Fork_SuiteCRM) to update your repository.
|
||||
Make sure your commit messages are relevant and descriptive. When ready to submit for review, make a Pull Request detailing your feature's functionality.
|
||||
Ensure that your Pull Requests base fork is **salesagility/SuiteCRM**, the base branch is **hotfix-7.10.x** (Issues effecting 7.10 & 7.11) or **hotfix** (Issues effecting 7.11 only), the head fork is your repository, and the base branch is your feature branch.
|
||||
Add any new PHPUnit tests to the new feature branch if required e.g new modules or classes.
|
||||
|
||||
### Issue and Pull Request Labels
|
||||
|
||||
* This section lists the labels we use to help us track and manage issues and pull requests across the SuiteCRM repositories.
|
||||
|
||||
* By using [GitHub search](https://help.github.com/articles/searching-issues/) you can use labels to help find issues and pull requests that you are interested in. If for example, you are interested in which PR's will be included in the next release of SuiteCRM, you can use the [open issues "Resolved: Next Release"](https://github.com/salesagility/SuiteCRM/issues?q=is%3Aopen+is%3Aissue+label%3A%22Resolved%3A+Next+Release%22) label.
|
||||
|
||||
* We encourage users whom feel an issue should be raised as a higher priority for a next release that they should make a comment to that affect. This also applies to incorrect labelling.
|
||||
|
||||
#### General Labels
|
||||
|
||||
| Label name | `salesagility/SuiteCRM` | Description |
|
||||
| --- | --- | --- |
|
||||
| `Bug` | [search][search-suitecrm-label-Bug] | Bugs within the core SuiteCRM codebase |
|
||||
| `Community Contribution` | [search][search-suitecrm-label-Community-Contribution] | These are contribution made by the community |
|
||||
| `Deprecated` | [search][search-suitecrm-label-Deprecated] | Issues & PRs related to an unsupported version of SuiteCRM |
|
||||
| `Enhancement` | [search][search-suitecrm-label-Enhancement] | Pull requests that provide more functionality. Associated Issues are called suggestions |
|
||||
| `Fix Proposed` | [search][search-suitecrm-label-Fix-Proposed] | A issue that has a PR related to it that provides a possible resolution |
|
||||
| `Good First Issue` | [search][search-suitecrm-label-Good-First-Issue] | A good issue for someone new to SuiteCRM or web development |
|
||||
| `Help Wanted` | [search][search-suitecrm-label-Help-Wanted] | Requesting help from the community to achieve a solution |
|
||||
| `High Priority` | [search][search-suitecrm-label-High-Priority] | Issues & PRs that are critical; broken core functionality; fatal errors; there are no workarounds |
|
||||
| `Medium Priority` | [search][search-suitecrm-label-Medium-Priority] | Issues & PRs that are important; broken functions; errors; there are workarounds |
|
||||
| `Low Priority` | [search][search-suitecrm-label-Low-Priority] | Issues & PRs that are minor; broken styling; warns; there are practical workarounds |
|
||||
| `Resolved: Next Release` | [search][search-suitecrm-label-Resolved-Next-Release] | Issues that have been resolved in a hotfix branch and scheduled to be in the next release |
|
||||
| `Suggestion` | [search][search-suitecrm-label-Suggestion] | Issue containing a suggestion of functionality, process or UI. Associated PRs are called enhancement |
|
||||
| `Question` | [search][search-suitecrm-label-Question] | This is a question raised about the functionality of SuiteCRM |
|
||||
|
||||
#### Description Labels
|
||||
|
||||
| Label name | `salesagility/SuiteCRM` | Description |
|
||||
| --- | --- | --- |
|
||||
| `API` | [search][search-suitecrm-label-API] | Issues & PRs related to all things regarding the API |
|
||||
| `Campaigns` | [search][search-suitecrm-label-Campaigns] | Issues & PRs related to all things regarding campaigns |
|
||||
| `Cases` | [search][search-suitecrm-label-Cases] | Issues & PRs related to all things regarding cases |
|
||||
| `Clean Up` | [search][search-suitecrm-label-Clean-Up] | Issues & PRs related to all things regarding to technical debt and log files |
|
||||
| `Databases` | [search][search-suitecrm-label-Databases] | Issues & PRs related to all things regarding databases |
|
||||
| `Dependencies` | [search][search-suitecrm-label-Dependencies] | Pull Requests that update a core dependency |
|
||||
| `Developer Tools` | [search][search-suitecrm-label-Developer-Tools] | Issues & PRs related to all things regarding development tools like Robo, Travis, etc |
|
||||
| `Discussion` | [search][search-suitecrm-label-Discussion] | Issues & PRs related to ongoing discussions |
|
||||
| `Elasticsearch` | [search][search-suitecrm-label-Elasticsearch] | Issues & PRs related to all things regarding Elasticsearch |
|
||||
| `Emails:Campaigns` | [search][search-suitecrm-label-Emails:Campaigns] | Issues & PRs related to email campaigns |
|
||||
| `Emails:Cases` | [search][search-suitecrm-label-Emails:Cases] | Issues & PRs related to email cases & AOP |
|
||||
| `Emails:Compose` | [search][search-suitecrm-label-Emails:Compose] | Issues & PRs related to email compose |
|
||||
| `Emails:Config` | [search][search-suitecrm-label-Emails:Config] | Issues & PRs related to email configuration |
|
||||
| `Emails:Templates` | [search][search-suitecrm-label-Emails:Templates] | Issues & PRs related to email templates |
|
||||
| `Emails` | [search][search-suitecrm-label-Emails] | Issues & PRs related to all things regarding emails & email module |
|
||||
| `Enviroment` | [search][search-suitecrm-label-Enviroment] | Issues & PRs related to the application environment |
|
||||
| `Installation` | [search][search-suitecrm-label-Installation] | Issues & PRs related to the installation of the application |
|
||||
| `Language` | [search][search-suitecrm-label-Language] | Issues & PRs that are confirmed as issues with language & translation within the core |
|
||||
| `Module` | [search][search-suitecrm-label-Module] | Issues & PRs related to modules that do not have specific label |
|
||||
| `Reports` | [search][search-suitecrm-label-Reports] | Issues & PRs related to all things regarding reports |
|
||||
| `Upgrading` | [search][search-suitecrm-label-Upgrading] | Issues & PRs related to all things regarding upgrading & UpgradeWizard |
|
||||
| `Workflow` | [search][search-suitecrm-label-Workflow] | Issues & PRs related to all things regarding workflow |
|
||||
| `Studio` | [search][search-suitecrm-label-Studio] | Issues & PRs related to all things regarding studio & module builder |
|
||||
| `Styling` | [search][search-suitecrm-label-Styling] | Issues & PRs related to all things regarding styling |
|
||||
|
||||
#### Status Labels
|
||||
|
||||
| Label name | `salesagility/SuiteCRM` | Description |
|
||||
| --- | --- | --- |
|
||||
| `Assessed` | [search][search-suitecrm-label-Assessed] | PRs that have been tested and confirmed to resolve an issue by a core team member |
|
||||
| `Community Assessed` | [search][search-suitecrm-label-Community-Assessed] | PRs that have been tested and confirmed to resolve an issue by at least 2 community members |
|
||||
| `In Review` | [search][search-suitecrm-label-In-Review] | Pull Requests that are activity being reviewed by the core team |
|
||||
| `Wrong Branch` | [search][search-suitecrm-label-Wrong-Branch] | Pull requests that point towards a restricted branch such as master |
|
||||
| `Needs Review` | [search][search-suitecrm-label-Needs-Review] | Needs the core team to code review |
|
||||
| `Needs Assessed` | [search][search-suitecrm-label-Needs-Assessed] | Needs the core team to assess |
|
||||
| `Invalid` | [search][search-suitecrm-label-Invalid] | Issues & PRs which are a duplicate of an existing issue/PR |
|
||||
| `Duplicate` | [search][search-suitecrm-label-Duplicate] | Issues & PRs which are a duplicate of an existing issue/PR |
|
||||
| `Requires Tests` | [search][search-suitecrm-label-Requires-Tests] | Suggestion to OP to provide automated testing (unit, or acceptance) |
|
||||
| `Requires Updates` | [search][search-suitecrm-label-Requires-Updates] | Issues & PRs which requires input or update from the author |
|
||||
| `Needs Documentation` | [search][search-suitecrm-label-Needs-Documentation] | Requires adding documentation |
|
||||
| `Needs Duplicated: Latest` | [search][search-suitecrm-label-Needs-Duplicated-Latest] | Pull Requests that require being duplicated to the "latest" branches i.e. Hotfix |
|
||||
| `Needs Duplicated: LTS` | [search][search-suitecrm-label-Needs-Duplicated-LTS] | Pull Requests that require being duplicated to the LTS branches i.e. hotfix-7.x.x |
|
||||
| `Work In Progress` | [search][search-suitecrm-label-Work-In-Progress] | Pull Requests that are not yet ready to be assessed |
|
||||
|
||||
[search-suitecrm-label-Bug]: https://github.com/salesagility/SuiteCRM/labels/Bug
|
||||
[search-suitecrm-label-Community-Contribution]: https://github.com/salesagility/SuiteCRM/labels/Community%20Contribution
|
||||
[search-suitecrm-label-Deprecated]: https://github.com/salesagility/SuiteCRM/labels/Deprecated
|
||||
[search-suitecrm-label-Enhancement]: https://github.com/salesagility/SuiteCRM/labels/Enhancement
|
||||
[search-suitecrm-label-Fix-Proposed]: https://github.com/salesagility/SuiteCRM/labels/Fix%20Proposed
|
||||
[search-suitecrm-label-Good-First-Issue]: https://github.com/salesagility/SuiteCRM/labels/Good%20First%20Issue
|
||||
[search-suitecrm-label-Help-Wanted]: https://github.com/salesagility/SuiteCRM/labels/Help%20Wanted
|
||||
[search-suitecrm-label-High-Priority]: https://github.com/salesagility/SuiteCRM/labels/High%20Priority
|
||||
[search-suitecrm-label-Medium-Priority]: https://github.com/salesagility/SuiteCRM/labels/Medium%20Priority
|
||||
[search-suitecrm-label-Low-Priority]: https://github.com/salesagility/SuiteCRM/labels/Low%20Priority
|
||||
[search-suitecrm-label-Resolved-Next-Release]: https://github.com/salesagility/SuiteCRM/labels/Resolved%3A%20Next%20Release
|
||||
[search-suitecrm-label-Suggestion]: https://github.com/salesagility/SuiteCRM/labels/Suggestion
|
||||
[search-suitecrm-label-Question]: https://github.com/salesagility/SuiteCRM/labels/Question
|
||||
|
||||
[search-suitecrm-label-API]: https://github.com/salesagility/SuiteCRM/labels/API
|
||||
[search-suitecrm-label-Campaigns]: https://github.com/salesagility/SuiteCRM/labels/Campaigns
|
||||
[search-suitecrm-label-Cases]: https://github.com/salesagility/SuiteCRM/labels/Cases
|
||||
[search-suitecrm-label-Clean-Up]: https://github.com/salesagility/SuiteCRM/labels/Clean%20Up
|
||||
[search-suitecrm-label-Databases]: https://github.com/salesagility/SuiteCRM/labels/Databases
|
||||
[search-suitecrm-label-Dependencies]: https://github.com/salesagility/SuiteCRM/labels/Dependencies
|
||||
[search-suitecrm-label-Developer-Tools]: https://github.com/salesagility/SuiteCRM/labels/Developer%20Tools
|
||||
[search-suitecrm-label-Discussion]: https://github.com/salesagility/SuiteCRM/labels/Discussion
|
||||
[search-suitecrm-label-Elasticsearch]: https://github.com/salesagility/SuiteCRM/labels/Elasticsearch
|
||||
[search-suitecrm-label-Emails:Campaigns]: https://github.com/salesagility/SuiteCRM/labels/Emails%3ACampaigns
|
||||
[search-suitecrm-label-Emails:Cases]: https://github.com/salesagility/SuiteCRM/labels/Emails%3ACases
|
||||
[search-suitecrm-label-Emails:Compose]: https://github.com/salesagility/SuiteCRM/labels/Emails%3ACompose
|
||||
[search-suitecrm-label-Emails:Config]: https://github.com/salesagility/SuiteCRM/labels/Emails%3AConfig
|
||||
[search-suitecrm-label-Emails:Templates]: https://github.com/salesagility/SuiteCRM/labels/Emails%3ATemplates
|
||||
[search-suitecrm-label-Emails]: https://github.com/salesagility/SuiteCRM/labels/Emails
|
||||
[search-suitecrm-label-Enviroment]: https://github.com/salesagility/SuiteCRM/labels/Environment
|
||||
[search-suitecrm-label-Installation]: https://github.com/salesagility/SuiteCRM/labels/Installation
|
||||
[search-suitecrm-label-Language]: https://github.com/salesagility/SuiteCRM/labels/Language
|
||||
[search-suitecrm-label-Module]: https://github.com/salesagility/SuiteCRM/labels/Module
|
||||
[search-suitecrm-label-Reports]: https://github.com/salesagility/SuiteCRM/labels/Reports
|
||||
[search-suitecrm-label-Studio]: https://github.com/salesagility/SuiteCRM/labels/Studio
|
||||
[search-suitecrm-label-Styling]: https://github.com/salesagility/SuiteCRM/labels/Styling
|
||||
[search-suitecrm-label-Upgrading]: https://github.com/salesagility/SuiteCRM/labels/Upgrading
|
||||
[search-suitecrm-label-Workflow]: https://github.com/salesagility/SuiteCRM/labels/Workflow
|
||||
|
||||
[search-suitecrm-label-Duplicate]: https://github.com/salesagility/SuiteCRM/labels/Duplicate
|
||||
[search-suitecrm-label-Assessed]: https://github.com/salesagility/SuiteCRM/labels/Assessed
|
||||
[search-suitecrm-label-Community-Assessed]: https://github.com/salesagility/SuiteCRM/labels/Community%20Assessed
|
||||
[search-suitecrm-label-In-Review]: https://github.com/salesagility/SuiteCRM/labels/In%20Review
|
||||
[search-suitecrm-label-Invalid]: https://github.com/salesagility/SuiteCRM/labels/Invalid
|
||||
[search-suitecrm-label-Needs-Assessed]: https://github.com/salesagility/SuiteCRM/labels/Needs%20Assessed
|
||||
[search-suitecrm-label-Needs-Documentation]: https://github.com/salesagility/SuiteCRM/labels/Needs%20Documentation
|
||||
[search-suitecrm-label-Needs-Duplicated-Latest]: https://github.com/salesagility/SuiteCRM/labels/Needs%20Duplicated%3A%20Latest
|
||||
[search-suitecrm-label-Needs-Duplicated-LTS]: https://github.com/salesagility/SuiteCRM/labels/Needs%20Duplicated%3A%20LTS
|
||||
[search-suitecrm-label-Needs-Review]: https://github.com/salesagility/SuiteCRM/labels/Needs%20Review
|
||||
[search-suitecrm-label-Requires-Tests]: https://github.com/salesagility/SuiteCRM/labels/Requires%20Tests
|
||||
[search-suitecrm-label-Requires-Updates]: https://github.com/salesagility/SuiteCRM/labels/Requires%20Updates
|
||||
[search-suitecrm-label-Work-In-Progress]: https://github.com/salesagility/SuiteCRM/labels/Work%20In%20Progress
|
||||
[search-suitecrm-label-Wrong-Branch]: https://github.com/salesagility/SuiteCRM/labels/Wrong%20Branch
|
||||
|
||||
Thanks!
|
||||
|
||||
SuiteCRM Team
|
12
.github/FUNDING.yml
vendored
Normal file
12
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: suitecrm
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
37
.github/ISSUE_TEMPLATE.md
vendored
Normal file
37
.github/ISSUE_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
<!--- Provide a general summary of the issue in the **Title** above -->
|
||||
<!--- Before you open an issue, please check if a similar issue already exists or has been closed before. --->
|
||||
<!--- If you have discovered a security risk please report it by emailing security@suitecrm.com. This will be delivered to the product team who handle security issues. Please don't disclose security bugs publicly until they have been handled by the security team. --->
|
||||
|
||||
#### Issue
|
||||
<!--- Provide a more detailed introduction to the issue itself, and why you consider it to be a bug -->
|
||||
<!--- Ensure that all code ``` is surrounded ``` by triple back quotes. This can also be done over multiple lines -->
|
||||
|
||||
#### Expected Behavior
|
||||
<!--- Tell us what should happen -->
|
||||
|
||||
#### Actual Behavior
|
||||
<!--- Tell us what happens instead -->
|
||||
<!--- Also please check relevant logs (suitecrm.log, php error.log etc.) -->
|
||||
|
||||
#### Possible Fix
|
||||
<!--- Not obligatory, but suggest a fix or reason for the bug -->
|
||||
|
||||
#### Steps to Reproduce
|
||||
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
|
||||
<!--- reproduce this bug include code to reproduce, if relevant -->
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
|
||||
#### Context
|
||||
<!--- How has this bug affected you? What were you trying to accomplish? -->
|
||||
<!--- If you feel this should be a low/medium/high priority then please state so -->
|
||||
|
||||
#### Your Environment
|
||||
<!--- Include as many relevant details about the environment you experienced the bug in -->
|
||||
* SuiteCRM Version used:
|
||||
* Browser name and version (e.g. Chrome Version 51.0.2704.63 (64-bit)):
|
||||
* Environment name and version (e.g. MySQL, PHP 7):
|
||||
* Operating System and version (e.g Ubuntu 16.04):
|
||||
|
30
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
30
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
<!--- Provide a general summary of your changes in the Title above -->
|
||||
|
||||
## Description
|
||||
<!--- Describe your changes in detail -->
|
||||
<!--- If fixing a bug, there should be an issue describing it with steps to reproduce -->
|
||||
<!--- Please link to the issue here unless your commit contains the issue number -->
|
||||
<!--- Ensure that all code ``` is surrounded ``` by triple back quotes. This can also be done over multiple lines -->
|
||||
|
||||
## Motivation and Context
|
||||
<!--- Why is this change required? What problem does it solve? -->
|
||||
|
||||
## How To Test This
|
||||
<!--- Please describe in detail how to test your changes. -->
|
||||
|
||||
## Types of changes
|
||||
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
|
||||
|
||||
### Final checklist
|
||||
<!--- Go over all the following points and check all the boxes that apply. --->
|
||||
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! --->
|
||||
- [ ] My code follows the code style of this project found [here](https://docs.suitecrm.com/community/contributing-code/coding-standards/).
|
||||
- [ ] My change requires a change to the documentation.
|
||||
- [ ] I have read the [**How to Contribute**](https://docs.suitecrm.com/community/contributing-code/) guidelines.
|
||||
|
||||
<!--- Your pull request will be tested via Travis CI to automatically indicate that your changes do not prevent compilation. --->
|
||||
|
||||
<!--- If it reports back that there are problems, you can log into the Travis system and check the log report for your pull request to see what the problem was. --->
|
21
.github/SECURITY.md
vendored
Normal file
21
.github/SECURITY.md
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
For a complete compatibility matrix, please see the documentation [here](https://docs.suitecrm.com/admin/compatibility-matrix/).
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 7.11.x | :heavy_check_mark: |
|
||||
| 7.10.x | :heavy_check_mark: |
|
||||
| ≤7.8.x | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
We take Security seriously here at SuiteCRM so if you have discovered a security risk report it by
|
||||
emailing [security@suitecrm.com](mailto:security@suitecrm.com). This will be delivered to the product team who handle security issues.
|
||||
Please don't disclose security bugs publicly until they have been handled by the security team.
|
||||
|
||||
Your email will be acknowledged within 24 hours during the business week (Mon - Fri), and you’ll receive a more
|
||||
detailed response to your email within 72 hours during the business week (Mon - Fri) indicating the next steps in
|
||||
handling your report.
|
94
.github/config.yml
vendored
Normal file
94
.github/config.yml
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
owner:
|
||||
- salesagility
|
||||
|
||||
repo:
|
||||
- SuiteCRM
|
||||
|
||||
members:
|
||||
- cameronblaikie
|
||||
- CamoMacdonald
|
||||
- code-ph0y
|
||||
- craigpanton
|
||||
- Dillon-Brown
|
||||
- e-reeley
|
||||
- g-fantini
|
||||
- gregsoper
|
||||
- gymad
|
||||
- jack7anderson7
|
||||
- JackBuchanan
|
||||
- Jason-Dang
|
||||
- JimMackin
|
||||
- johnM2401
|
||||
- Mac-Rae
|
||||
- mattlorimer
|
||||
- MikeyJC
|
||||
- murdal
|
||||
- PedroErnst
|
||||
- pgorod
|
||||
- samus-aran
|
||||
- SuiteBot
|
||||
- willrennie
|
||||
|
||||
eolBranches:
|
||||
- 7.9.x,
|
||||
- 7.8.x,
|
||||
- hotfix-7.8.x
|
||||
|
||||
invalidBranches:
|
||||
- master
|
||||
- 7.10.x
|
||||
|
||||
invalid: >
|
||||
Hello and thanks for the contribution! would you be able to rebase this pull request to the hotfix-7.10.x branch?
|
||||
we currently don't accept pull requests directly to this branch
|
||||
(See [SuiteDocs](https://docs.suitecrm.com/community/contributing-code/bugs) for more information).
|
||||
eol: >
|
||||
Hello and thanks for the contribution! unfortunately this branch is EOL
|
||||
(See our [blog post](https://suitecrm.com/7-8-x-end-of-life/) for more information).
|
||||
invalidIssueTemplate: >
|
||||
Hello and thanks for raising this issue! I notice you don't seem to be following the standard issue template. If this is a bug report, would you be able to go back and edit this issue while following the template and including exact replication steps?
|
||||
|
||||
|
||||
Thanks.
|
||||
sprintPlanning: >
|
||||
Hello Everyone! :wave:
|
||||
|
||||
|
||||
We are 1 week away from commencing our Sprint. So we would like to take this opportunity to ask for your nominated issues here in this thread so we can assess, refine and coordinate with ourselves (the Core Team) and the community contributors on the upcoming priorities.
|
||||
|
||||
|
||||
If you are new to this sprint planning then essentially we are asking you, as the users, to post your issues (by referencing the GitHub hash/ID) that you would like to see being tackled. We, the Core Team, will review and select the achievable ones within the sprint and allocate them among ourselves. The others we may label them as Help Wanted which would make them up for grabs by our community code contributors. This process will help encourage ownership of these bugs and their bug fixes. [Find out more of the sprint concept here](https://docs.suitecrm.com/community/nominating-issues-in-sprint-planning) :point_left:
|
||||
|
||||
|
||||
Sprints are every 2 weeks with the aim to deliver a release every 2 Sprints (monthly).
|
||||
|
||||
|
||||
Just to re-iterate from previous posts, that the core team do have other tasks that may not be identified in the above sprints and these are usually from our own internal backlog i.e. improving the release process, CI/CD tools, security patches etc so that accounts for some ‘slack’ visible in the public sprints.
|
||||
|
||||
|
||||
Look forward to your nominations! :writing_hand:
|
||||
sprintRetrospective: >
|
||||
Hello Everyone!
|
||||
|
||||
|
||||
Welcome to the sprint retrospective, lets break down the previous sprint.
|
||||
|
||||
|
||||
To Do | In Progress | In Review | Done
|
||||
|
||||
------------ | ------------- | ------------- | -------------
|
||||
|
||||
SPRINTMETRICS
|
||||
|
||||
|
||||
Again, to note, that we also tackle a lot of other issues that are high priorities, security patches and internal roadmap tasks
|
||||
|
||||
|
||||
List of the currently open "Help Wanted" issues:
|
||||
|
||||
HELPWANTED
|
||||
|
||||
|
||||
|
||||
Thanks everyone and comment below to start a discussion to improve the open sprint processes & gain feedback +1
|
||||
We are planning to open the next Sprint for nominations next week.
|
141
.gitignore
vendored
Normal file
141
.gitignore
vendored
Normal file
|
@ -0,0 +1,141 @@
|
|||
## SuiteCRM 8 ##
|
||||
|
||||
build/
|
||||
config/
|
||||
!config/.gitkeep
|
||||
cache/
|
||||
extentions/
|
||||
!extentions/.gitkeep
|
||||
logs/
|
||||
!logs/.gitkeep
|
||||
public/
|
||||
|
||||
# Theme
|
||||
.sass-cache
|
||||
*.css.map
|
||||
*.min.css
|
||||
|
||||
# Tests
|
||||
core/tests/coverage
|
||||
|
||||
# Composer
|
||||
vendor/
|
||||
composer.phar
|
||||
|
||||
|
||||
# Profiling files
|
||||
chrome-profiler-events.json
|
||||
speed-measure-plugin.json
|
||||
|
||||
# Compiled output
|
||||
dist
|
||||
tmp
|
||||
out-tsc
|
||||
|
||||
# Only exists if Bazel was run
|
||||
bazel-out
|
||||
|
||||
# e2e test files
|
||||
e2e/*.js
|
||||
e2e/*.map
|
||||
|
||||
## Generic ##
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
||||
# composer
|
||||
/vendor/*
|
||||
|
||||
#Ignore bower_components
|
||||
bower_components/
|
||||
node_modules/
|
||||
|
||||
# htacess
|
||||
/.htaccess
|
||||
|
||||
## IDE specific items
|
||||
# Eclipse
|
||||
*.pydevproject
|
||||
.project
|
||||
.buildpath
|
||||
.metadata
|
||||
bin/**
|
||||
tmp/**
|
||||
tmp/**/*
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.classpath
|
||||
.settings/
|
||||
.loadpath
|
||||
# Emacs
|
||||
*~
|
||||
\#*\#
|
||||
/.emacs.desktop
|
||||
/.emacs.desktop.lock
|
||||
.elc
|
||||
auto-save-list
|
||||
tramp
|
||||
# IntelliJ Idea
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
.phpstorm.meta.php
|
||||
.sass-cache/
|
||||
.php_cs.cache
|
||||
# NetBeans
|
||||
nbproject/
|
||||
#Visual Studio Code
|
||||
.vscode/
|
||||
# Vim
|
||||
.*.sw[a-z]
|
||||
*.un~
|
||||
*.sln
|
||||
*.suo
|
||||
*.phpproj
|
||||
Session.vim
|
||||
# Windows
|
||||
Thumbs.db
|
||||
Desktop.ini
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
.save
|
||||
#browserstack
|
||||
BrowserStackLocal
|
||||
browserstack.err
|
||||
|
||||
|
||||
# zips and executables
|
||||
*.7z
|
||||
*.dmg
|
||||
*.gz
|
||||
*.iso
|
||||
*.jar
|
||||
*.rar
|
||||
*.tar
|
||||
*.zip
|
||||
*.exe
|
||||
|
||||
# sql
|
||||
*.sql
|
||||
*.sql.gz
|
||||
*.sqlite
|
||||
|
||||
# Ignore testing environment
|
||||
build/tmp/
|
||||
|
||||
# Misc
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
.c9/
|
||||
*.launch
|
35
CODE_OF_CONDUCT.md
Normal file
35
CODE_OF_CONDUCT.md
Normal file
|
@ -0,0 +1,35 @@
|
|||
# Code of Conduct #
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
Examples of behaviour that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community in a professional manner
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behaviour by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
The SuiteCRM project maintainers are responsible for clarifying the standards of acceptable behaviour and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behaviour. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
|
||||
|
||||
The SuiteCRM project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviours that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, within project forums, posting via an official social media account, or acting as an appointed representative at an online or offline event.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behaviour may be reported by contacting the project team at [community@suitecrm.com][community_email]. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[community_email]: mailto:community@suitecrm.com
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
60
README.md
Executable file
60
README.md
Executable file
|
@ -0,0 +1,60 @@
|
|||
<a href="https://suitecrm.com">
|
||||
<img width="180px" height="41px" src="https://suitecrm.com/wp-content/uploads/2017/12/logo.png" align="right" />
|
||||
</a>
|
||||
|
||||
# SuiteCRM 8.0-alpha
|
||||
|
||||
[SuiteCRM](https://suitecrm.com) is the award-winning open-source, enterprise-ready Customer Relationship Management (CRM) software application.
|
||||
|
||||
Our vision is to be the most adopted open source enterprise CRM in the world, giving users full control of their data and freedom to own and customise their business solution.
|
||||
|
||||
Try out a free fully working [SuiteCRM demo available here](https://suitecrm.com/demo/)
|
||||
|
||||
|
||||
### License [](./LICENSE.txt)
|
||||
|
||||
SuiteCRM is published under the AGPLv3 license.
|
||||
|
||||
|
||||
## Quick Start Quide
|
||||
|
||||
### System Requirements
|
||||
|
||||
| Requirement | Version | | Database | Version |
|
||||
|---|---|---|---|---|
|
||||
| PHP | 7.2+ || MariaDB |10.2+ |
|
||||
| Angular | 7+ || MySQL | 5.6-5.7|
|
||||
| Node.js | 10 || SQL Server | 2012+ |
|
||||
| Apache | 2.4 |
|
||||
|
||||
### Installation
|
||||
|
||||
1. Run `composer install` in the root directory
|
||||
2. Run `composer install` in legacy directory
|
||||
3. Compile legacy theme
|
||||
3. Run legacy install process
|
||||
4. Create config.yml with config directory with the following strucure
|
||||
```
|
||||
server:
|
||||
environment: 'develop'
|
||||
storage:
|
||||
mysql:
|
||||
driver: 'pdo_mysql'
|
||||
host: '{db_host}'
|
||||
dbname: '{db_name}'
|
||||
user: '{db_user}'
|
||||
password: '{db_pass}'
|
||||
io: 'both'
|
||||
entity:
|
||||
namespaces:
|
||||
core/modules/Users/Config/orm: 'SuiteCRM\Core\Modules\Users\Entity'
|
||||
```
|
||||
5. Set permissions
|
||||
```
|
||||
chown -R {user ID}:{web user group} .
|
||||
find . -type d -exec chmod 0755 {} \;
|
||||
find . -type f -exec chmod 0644 {} \;
|
||||
chmod +x bin/cli
|
||||
```
|
||||
6. Run `bin/cli orm:schema-tool:update --force`
|
||||
7. Run `bin/cli app:rebuild`
|
52
composer.json
Executable file
52
composer.json
Executable file
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"name": "salesagility/suitecrm",
|
||||
"description": "SuiteCRM Application",
|
||||
"homepage": "https://suitecrm.com",
|
||||
"type": "project",
|
||||
"config": {
|
||||
"vendor-dir": "vendor",
|
||||
"platform": {
|
||||
"php": "7.2.0"
|
||||
},
|
||||
"optimize-autoloader": true,
|
||||
"sort-packages": true
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"bshaffer/oauth2-server-httpfoundation-bridge": "^1.4",
|
||||
"bshaffer/oauth2-server-php": "^1.11.1",
|
||||
"composer/installers": "~1.0",
|
||||
"doctrine/cache": "^1.8",
|
||||
"doctrine/dbal": "^2.9",
|
||||
"doctrine/orm": "2.6.*",
|
||||
"monolog/monolog": "^1.23",
|
||||
"symfony/config": "^4.2",
|
||||
"symfony/console": "^4.3",
|
||||
"symfony/http-foundation": "^4.2",
|
||||
"symfony/routing": "4.4.x-dev",
|
||||
"symfony/yaml": "^4.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"roave/security-advisories": "dev-master",
|
||||
"phpunit/phpunit": "^7.3",
|
||||
"phpmetrics/phpmetrics": "^2.4.1",
|
||||
"phploc/phploc": "^4.0.1",
|
||||
"doctrine/doctrine-fixtures-bundle": "~3.2",
|
||||
"dama/doctrine-test-bundle": "^5.0"
|
||||
},
|
||||
"license": "GPL-3.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "SalesAgility Ltd"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"SuiteCRM\\Core\\Base\\": "core/base/",
|
||||
"SuiteCRM\\Core\\Modules\\": "core/modules/",
|
||||
"SuiteCRM\\Core\\Legacy\\": "core/legacy/"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
5756
composer.lock
generated
Normal file
5756
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
0
config/.gitkeep
Normal file
0
config/.gitkeep
Normal file
13
core/app/engine/.editorconfig
Normal file
13
core/app/engine/.editorconfig
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Editor configuration, see http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
56
core/app/engine/.gitignore
vendored
Normal file
56
core/app/engine/.gitignore
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
# Only exists if Bazel was run
|
||||
/bazel-out
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# profiling files
|
||||
chrome-profiler-events.json
|
||||
speed-measure-plugin.json
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
|
||||
# IDE - VSCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
.history/*
|
||||
|
||||
# misc
|
||||
*.css.map
|
||||
.sass-cache
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
# e2e
|
||||
/e2e/*.js
|
||||
/e2e/*.map
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
src/app/app-files/*
|
||||
!src/app/app-files/.gitkeep
|
||||
src/app/config-local.ts
|
||||
/nbproject
|
108
core/app/engine/README.md
Normal file
108
core/app/engine/README.md
Normal file
|
@ -0,0 +1,108 @@
|
|||
# SuiteCRM
|
||||
|
||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.3.4.
|
||||
|
||||
## Development server
|
||||
|
||||
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Running end-to-end tests
|
||||
|
||||
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
||||
|
||||
# Creating in-build SVG files:
|
||||
|
||||
usage of svgbuild.js: `node svgbuild.js [folder-of-svg-files] [svg-icon-template-html]`
|
||||
|
||||
# Creating local config:
|
||||
|
||||
Set your local specific changes in `config-local.ts`.
|
||||
See more in `config-example.ts`.
|
||||
|
||||
(Note: You can make more environment specific configuration and set your config class in `config-class.ts`.)
|
||||
|
||||
example for `config-local.ts`:
|
||||
```
|
||||
import { ConfigExample } from './config-example';
|
||||
|
||||
export class ConfigLocal extends ConfigExample {
|
||||
|
||||
// add your local config overrides here..
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
// override the config variables separately:
|
||||
this.fakeApiUrls.fakeBaseUrl = 'http://localhost/scrm8/fakeapi.php?';
|
||||
}
|
||||
}
|
||||
```
|
||||
# Front End Testing
|
||||
|
||||
Front end tests are created to ensure the application runs as expected from start to finish for the end user
|
||||
|
||||
The Angular CLI downloads and install everything you need to test an Angular application with the Jasmine test framework
|
||||
|
||||
## Running Tests
|
||||
|
||||
The project you create with the CLI is immediately ready to test
|
||||
|
||||
Simply run the CLI command:
|
||||
|
||||
```ng test <project> [options]```
|
||||
OR
|
||||
```ng t <project> [options]```
|
||||
|
||||
For full testing options, see: https://angular.io/cli/test#options
|
||||
|
||||
### Karma configuration
|
||||
|
||||
Karma is the task runner for the tests written in Jasmine
|
||||
|
||||
There is a config created called karma.conf.js
|
||||
|
||||
The Angular CLI configuration of Karma uses the file “test.ts” as the entry point of the tests for the application
|
||||
|
||||
Within each component there is a test file where you add your unit test code
|
||||
|
||||
This will normally be automatically generated by the CLI as {component-name}.spec.ts as standard
|
||||
|
||||
Karma picks up files with extension '.spec.ts' as test files
|
||||
|
||||
## End-To-End Testing
|
||||
|
||||
In addition to running standard tests, you can run end to end tests within the Angular CLI using:
|
||||
|
||||
```ng e2e <project> [options]```
|
||||
OR
|
||||
```ng e <project> [options]```
|
||||
|
||||
For full testing options, see: https://angular.io/cli/e2e#options
|
||||
|
||||
The end-to-end tests build and serve your Angular app, then run end-to-end tests using Protractor
|
||||
|
||||
This allows you to run end-to-end testing from a user's perspective
|
||||
|
||||
The tests ensure the application runs as expected from start to finish
|
||||
|
||||
As the tests run, you will see the browser interaction just as you would see it from the user perspective
|
||||
|
||||
To run the tests, Protractor depends on two files
|
||||
|
||||
The spec files inside the e2e folder and the 'protractor.conf.json' file
|
138
core/app/engine/angular.json
Normal file
138
core/app/engine/angular.json
Normal file
|
@ -0,0 +1,138 @@
|
|||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"SuiteCRM": {
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"projectType": "application",
|
||||
"prefix": "scrm",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "src/tsconfig.app.json",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
],
|
||||
"scripts": [],
|
||||
"styles": [
|
||||
"node_modules/bootstrap-css-only/css/bootstrap.min.css",
|
||||
"src/assets/themes/suite8/css/style.min.css"
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"extractCss": true,
|
||||
"namedChunks": false,
|
||||
"aot": true,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "SuiteCRM:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "SuiteCRM:build:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"browserTarget": "SuiteCRM:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "src/tsconfig.spec.json",
|
||||
"karmaConfig": "src/karma.conf.js",
|
||||
"styles": [
|
||||
"node_modules/bootstrap-css-only/css/bootstrap.min.css",
|
||||
"themes/suite8/css/style.min.css"
|
||||
],
|
||||
"scripts": [],
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
]
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"src/tsconfig.app.json",
|
||||
"src/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"SuiteCRM-e2e": {
|
||||
"root": "e2e",
|
||||
"projectType": "application",
|
||||
"prefix": "",
|
||||
"architect": {
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"protractorConfig": "e2e/protractor.conf.js",
|
||||
"devServerTarget": "SuiteCRM:serve"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"devServerTarget": "SuiteCRM:serve:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": "e2e/tsconfig.e2e.json",
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "SuiteCRM",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"prefix": "app",
|
||||
"styleext": "css"
|
||||
},
|
||||
"@schematics/angular:directive": {
|
||||
"prefix": "app"
|
||||
}
|
||||
}
|
||||
}
|
14
core/app/engine/e2e/app.e2e-spec.ts
Normal file
14
core/app/engine/e2e/app.e2e-spec.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import {AppPage} from './app.po';
|
||||
|
||||
describe('dynamic-component-loader App', () => {
|
||||
let page: AppPage;
|
||||
|
||||
beforeEach(() => {
|
||||
page = new AppPage();
|
||||
});
|
||||
|
||||
it('should display welcome message', () => {
|
||||
page.navigateTo();
|
||||
expect(page.getParagraphText()).toEqual('Welcome to app!');
|
||||
});
|
||||
});
|
11
core/app/engine/e2e/app.po.ts
Normal file
11
core/app/engine/e2e/app.po.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import {browser, by, element} from 'protractor';
|
||||
|
||||
export class AppPage {
|
||||
navigateTo() {
|
||||
return browser.get('/');
|
||||
}
|
||||
|
||||
getParagraphText() {
|
||||
return element(by.css('app-root h1')).getText();
|
||||
}
|
||||
}
|
14
core/app/engine/e2e/tsconfig.e2e.json
Normal file
14
core/app/engine/e2e/tsconfig.e2e.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/e2e",
|
||||
"baseUrl": "./",
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"jasminewd2",
|
||||
"node"
|
||||
]
|
||||
}
|
||||
}
|
12059
core/app/engine/package-lock.json
generated
Normal file
12059
core/app/engine/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
62
core/app/engine/package.json
Normal file
62
core/app/engine/package.json
Normal file
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"name": "suitecrm",
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^7.2.2",
|
||||
"@angular/cdk": "^7.2.2",
|
||||
"@angular/common": "^7.2.2",
|
||||
"@angular/compiler": "^7.2.2",
|
||||
"@angular/core": "^7.2.2",
|
||||
"@angular/forms": "^7.2.2",
|
||||
"@angular/http": "^7.2.2",
|
||||
"@angular/material": "^7.2.2",
|
||||
"@angular/platform-browser": "^7.2.2",
|
||||
"@angular/platform-browser-dynamic": "^7.2.2",
|
||||
"@angular/router": "^7.2.2",
|
||||
"@ng-bootstrap/ng-bootstrap": "^4.2.2",
|
||||
"bootstrap-css-only": "^4.3.1",
|
||||
"@types/object-hash": "^1.3.0",
|
||||
"nyc": "~14.1.1",
|
||||
"chart.js": "^2.8.0",
|
||||
"chartjs-plugin-annotation": "^0.5.7",
|
||||
"core-js": "^3.4.5",
|
||||
"ng2-charts": "^2.2.3",
|
||||
"object-hash": "^1.3.1",
|
||||
"rxjs": "^6.3.3",
|
||||
"tslib": "^1.9.3",
|
||||
"zone.js": "~0.8.26",
|
||||
"ajv": "~6.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "0.12.4",
|
||||
"@angular/cli": "^7.2.2",
|
||||
"@angular/compiler-cli": "^7.2.2",
|
||||
"@angular/language-service": "^7.2.2",
|
||||
"@types/jasmine": "^3.3.7",
|
||||
"@types/jasminewd2": "^2.0.6",
|
||||
"@types/node": "^10.12.18",
|
||||
"codelyzer": "^4.5.0",
|
||||
"jasmine-core": "~3.3.0",
|
||||
"jasmine-spec-reporter": "^4.2.1",
|
||||
"karma": "^4.0.0",
|
||||
"karma-chrome-launcher": "^2.2.0",
|
||||
"karma-cli": "^2.0.0",
|
||||
"karma-coverage-istanbul-reporter": "^2.0.4",
|
||||
"karma-jasmine": "^2.0.1",
|
||||
"karma-jasmine-html-reporter": "^1.4.0",
|
||||
"prettier": "^1.16.1",
|
||||
"protractor": "^5.4.2",
|
||||
"ts-node": "^8.0.1",
|
||||
"tslint": "^5.12.1",
|
||||
"typescript": "~3.2.4"
|
||||
}
|
||||
}
|
72
core/app/engine/src/app/app-manager/app-manager.module.ts
Normal file
72
core/app/engine/src/app/app-manager/app-manager.module.ts
Normal file
|
@ -0,0 +1,72 @@
|
|||
import {
|
||||
ANALYZE_FOR_ENTRY_COMPONENTS,
|
||||
ModuleWithProviders,
|
||||
NgModule,
|
||||
NgModuleFactoryLoader,
|
||||
SystemJsNgModuleLoader,
|
||||
Type
|
||||
} from '@angular/core';
|
||||
|
||||
import {ROUTES} from '@angular/router';
|
||||
|
||||
import {AppManager} from './app-manager.service';
|
||||
|
||||
import {
|
||||
APP_COMPONENT,
|
||||
APP_MANIFESTS,
|
||||
APP_MODULE,
|
||||
AppManifest
|
||||
} from './app-manifest';
|
||||
|
||||
@NgModule()
|
||||
export class AppManagerModule {
|
||||
static forRoot(manifests: AppManifest[]): ModuleWithProviders {
|
||||
return {
|
||||
ngModule: AppManagerModule,
|
||||
providers: [
|
||||
AppManager,
|
||||
{provide: NgModuleFactoryLoader, useClass: SystemJsNgModuleLoader},
|
||||
// provider for Angular CLI to analyzes
|
||||
{provide: ROUTES, useValue: manifests, multi: true},
|
||||
// provider for AppManager to analyze
|
||||
{provide: APP_MANIFESTS, useValue: manifests}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
static forModule(manifest: AppManifest): ModuleWithProviders {
|
||||
return {
|
||||
ngModule: AppManagerModule,
|
||||
providers: [
|
||||
{
|
||||
provide: ANALYZE_FOR_ENTRY_COMPONENTS,
|
||||
useValue: manifest,
|
||||
multi: true
|
||||
},
|
||||
// provider for @angular/router to parse
|
||||
{provide: ROUTES, useValue: manifest, multi: true},
|
||||
// provider for AppManager to analyze
|
||||
{provide: APP_MODULE, useValue: manifest}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
static forChild(component: Type<any>): ModuleWithProviders {
|
||||
return {
|
||||
ngModule: AppManagerModule,
|
||||
providers: [
|
||||
{
|
||||
provide: ANALYZE_FOR_ENTRY_COMPONENTS,
|
||||
useValue: component,
|
||||
multi: true
|
||||
},
|
||||
// provider for @angular/router to parse
|
||||
{provide: ROUTES, useValue: [], multi: true},
|
||||
// provider for AppManager to analyze
|
||||
{provide: APP_COMPONENT, useValue: component}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export {AppManifest} from './app-manifest';
|
127
core/app/engine/src/app/app-manager/app-manager.service.ts
Normal file
127
core/app/engine/src/app/app-manager/app-manager.service.ts
Normal file
|
@ -0,0 +1,127 @@
|
|||
import {
|
||||
ComponentFactory,
|
||||
Inject,
|
||||
Injectable,
|
||||
Injector,
|
||||
NgModuleFactory,
|
||||
NgModuleFactoryLoader
|
||||
} from '@angular/core';
|
||||
|
||||
import {from, Observable, throwError} from 'rxjs';
|
||||
|
||||
import {
|
||||
AppManifest,
|
||||
APP_COMPONENT,
|
||||
APP_MANIFESTS,
|
||||
APP_MODULE
|
||||
} from './app-manifest';
|
||||
|
||||
@Injectable()
|
||||
export class AppManager {
|
||||
constructor(
|
||||
@Inject(APP_MANIFESTS)
|
||||
private manifests: AppManifest[],
|
||||
private loader: NgModuleFactoryLoader,
|
||||
private injector: Injector
|
||||
) {
|
||||
}
|
||||
|
||||
/** Retrieve a ComponentFactory, based on the specified componentId
|
||||
* (defined in the AppManifest array).
|
||||
*/
|
||||
getComponentFactory<T>(
|
||||
componentId: string,
|
||||
injector?: Injector
|
||||
): Observable<ComponentFactory<T>> {
|
||||
const manifest = this.manifests.find(m => m.componentId === componentId);
|
||||
if (!manifest) {
|
||||
return throwError(
|
||||
`AppManager: Unknown componentId "${componentId}"`
|
||||
);
|
||||
}
|
||||
|
||||
const path = manifest.loadChildren;
|
||||
|
||||
const p = this.load<T>(path, componentId, injector);
|
||||
return from(p);
|
||||
}
|
||||
|
||||
load<T>(
|
||||
path: string,
|
||||
componentId: string,
|
||||
injector?: Injector
|
||||
): Promise<ComponentFactory<T>> {
|
||||
return this.loader
|
||||
.load(path)
|
||||
.then(ngModuleFactory =>
|
||||
this.loadFactory<T>(ngModuleFactory, componentId, injector)
|
||||
);
|
||||
}
|
||||
|
||||
loadFactory<T>(
|
||||
ngModuleFactory: NgModuleFactory<any>,
|
||||
componentId: string,
|
||||
injector?: Injector
|
||||
): Promise<ComponentFactory<T>> {
|
||||
const moduleRef = ngModuleFactory.create(injector || this.injector);
|
||||
const appComponentType = moduleRef.injector.get(
|
||||
APP_COMPONENT,
|
||||
null
|
||||
);
|
||||
if (!appComponentType) {
|
||||
const AppModule: AppManifest = moduleRef.injector.get(
|
||||
APP_MODULE,
|
||||
null
|
||||
);
|
||||
|
||||
if (!AppModule) {
|
||||
throw new Error(
|
||||
'AppManager: App module for' +
|
||||
` componentId "${componentId}" does not contain` +
|
||||
' APP_COMPONENT or App_MODULE as a provider.'
|
||||
);
|
||||
}
|
||||
if (AppModule.componentId !== componentId) {
|
||||
throw new Error(
|
||||
'AppManager: App module for' +
|
||||
`${componentId} does not match manifest.`
|
||||
);
|
||||
}
|
||||
|
||||
const path = AppModule.loadChildren;
|
||||
|
||||
if (!path) {
|
||||
throw new Error(`${componentId} unknown!`);
|
||||
}
|
||||
|
||||
return this.load<T>(path, componentId, injector);
|
||||
}
|
||||
|
||||
return Promise.resolve(
|
||||
moduleRef.componentFactoryResolver.resolveComponentFactory<T>(
|
||||
appComponentType
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
loadAppComponent(outlet: any, componentId: string, data: any) {
|
||||
this.getComponentFactory<any>(componentId)
|
||||
.subscribe({
|
||||
next: componentFactory => {
|
||||
if (!outlet) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ref = outlet.createComponent(componentFactory);
|
||||
ref.changeDetectorRef.detectChanges();
|
||||
|
||||
const appComponent = ref.instance;
|
||||
|
||||
appComponent.data = data;
|
||||
},
|
||||
error: err => {
|
||||
console.warn(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
16
core/app/engine/src/app/app-manager/app-manifest.ts
Normal file
16
core/app/engine/src/app/app-manager/app-manifest.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import {InjectionToken} from '@angular/core';
|
||||
|
||||
export const APP_COMPONENT = new InjectionToken<any>('APP_COMPONENT');
|
||||
export const APP_MODULE = new InjectionToken<any>('APP_MODULE');
|
||||
export const APP_MANIFESTS = new InjectionToken<any>('APP_MANIFESTS');
|
||||
|
||||
export interface AppManifest {
|
||||
/** Unique identifier, used in the application to retrieve a ComponentFactory. */
|
||||
componentId: string;
|
||||
|
||||
/** Unique identifier, used internally by Angular. */
|
||||
path: string;
|
||||
|
||||
/** Path to component module. */
|
||||
loadChildren: string;
|
||||
}
|
46
core/app/engine/src/app/app-routing.module.ts
Normal file
46
core/app/engine/src/app/app-routing.module.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
import {NgModule} from '@angular/core';
|
||||
import {Routes, RouterModule} from '@angular/router';
|
||||
import {ClassicViewUiComponent} from './app-files/ui/components/classic-view/classic-view.component';
|
||||
|
||||
import {AuthGuard} from './app-files/ui/services/auth/auth-guard.service';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: 'Login',
|
||||
loadChildren: './app-files/ui/components/login/login.module#LoginUiModule'
|
||||
},
|
||||
{
|
||||
path: 'Logout',
|
||||
loadChildren: './app-files/ui/components/logout/logout.module#LogoutUiModule'
|
||||
},
|
||||
{
|
||||
path: 'Home',
|
||||
loadChildren: './app-files/ui/components/home/home.module#HomeUiModule',
|
||||
canActivate: [AuthGuard]
|
||||
},
|
||||
{
|
||||
path: ':module',
|
||||
component: ClassicViewUiComponent,
|
||||
canActivate: [AuthGuard]
|
||||
},
|
||||
{
|
||||
path: ':module/:action',
|
||||
component: ClassicViewUiComponent,
|
||||
canActivate: [AuthGuard]
|
||||
},
|
||||
{
|
||||
path: ':module/:action/:record',
|
||||
component: ClassicViewUiComponent,
|
||||
canActivate: [AuthGuard]
|
||||
},
|
||||
{path: '**', redirectTo: 'Login'},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes, {
|
||||
useHash: true
|
||||
})],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AppRoutingModule {
|
||||
}
|
5
core/app/engine/src/app/app.component.html
Normal file
5
core/app/engine/src/app/app.component.html
Normal file
|
@ -0,0 +1,5 @@
|
|||
<scrm-navbar-ui></scrm-navbar-ui>
|
||||
<scrm-message-ui></scrm-message-ui>
|
||||
<div #mainOutlet></div>
|
||||
<router-outlet></router-outlet>
|
||||
<scrm-footer-ui></scrm-footer-ui>
|
0
core/app/engine/src/app/app.component.scss
Normal file
0
core/app/engine/src/app/app.component.scss
Normal file
19
core/app/engine/src/app/app.component.spec.ts
Normal file
19
core/app/engine/src/app/app.component.spec.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
import {async, ComponentFixture, TestBed, inject} from '@angular/core/testing';
|
||||
import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {RouterTestingModule} from '@angular/router/testing';
|
||||
import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';
|
||||
|
||||
import {AppComponent} from './app.component';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
imports: [RouterTestingModule, HttpClientTestingModule, FormsModule],
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
}).compileComponents();
|
||||
}));
|
||||
});
|
17
core/app/engine/src/app/app.component.ts
Normal file
17
core/app/engine/src/app/app.component.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import {Component, ViewChild, ViewContainerRef, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html'
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
@ViewChild('mainOutlet', {read: ViewContainerRef})
|
||||
mainOutlet: ViewContainerRef | undefined;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
}
|
||||
}
|
38
core/app/engine/src/app/app.module.ts
Normal file
38
core/app/engine/src/app/app.module.ts
Normal file
|
@ -0,0 +1,38 @@
|
|||
import {NgModule, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {HttpClientModule} from '@angular/common/http';
|
||||
|
||||
import {AppRoutingModule} from './app-routing.module';
|
||||
import {AppComponent} from './app.component';
|
||||
|
||||
import {NavbarUiModule} from './app-files/ui/components/navbar/navbar.module';
|
||||
import {FooterUiModule} from './app-files/ui/components/footer/footer.module';
|
||||
import {ClassicViewUiModule} from './app-files/ui/components/classic-view/classic-view.module';
|
||||
import {MessageUiModule} from './app-files/ui/components/message/message.module';
|
||||
|
||||
import {
|
||||
AppManagerModule
|
||||
} from './app-manager/app-manager.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
HttpClientModule,
|
||||
AppManagerModule,
|
||||
AppRoutingModule,
|
||||
FooterUiModule,
|
||||
NavbarUiModule,
|
||||
MessageUiModule,
|
||||
ClassicViewUiModule
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
entryComponents: []
|
||||
})
|
||||
export class AppModule {
|
||||
constructor() {
|
||||
|
||||
}
|
||||
}
|
3
core/app/engine/src/environments/environment.prod.ts
Normal file
3
core/app/engine/src/environments/environment.prod.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export const environment = {
|
||||
production: true
|
||||
};
|
8
core/app/engine/src/environments/environment.ts
Normal file
8
core/app/engine/src/environments/environment.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
// The file contents for the current environment will overwrite these during build.
|
||||
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
|
||||
// `ng build --env=prod` then `environment.prod.ts` will be used instead.
|
||||
// The list of which env maps to which file can be found in `.angular-cli.json`.
|
||||
|
||||
export const environment = {
|
||||
production: false
|
||||
};
|
BIN
core/app/engine/src/favicon.ico
Normal file
BIN
core/app/engine/src/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
20
core/app/engine/src/index.html
Normal file
20
core/app/engine/src/index.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>SuiteCRM</title>
|
||||
<base href=""/>
|
||||
|
||||
<meta http-equiv="cache-control" content="no-cache, must-revalidate, post-check=0, pre-check=0">
|
||||
<meta http-equiv="expires" content="0">
|
||||
<meta http-equiv="pragma" content="no-cache">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1"/>
|
||||
|
||||
<link rel="icon" type="image/x-icon" href="public/assets/themes/suite8/images/favicon.ico"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
13
core/app/engine/src/main.ts
Normal file
13
core/app/engine/src/main.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import {enableProdMode} from '@angular/core';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
|
||||
import {AppModule} from './app/app.module';
|
||||
import {environment} from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
platformBrowserDynamic()
|
||||
.bootstrapModule(AppModule)
|
||||
.catch(err => console.log(err));
|
60
core/app/engine/src/polyfills.ts
Normal file
60
core/app/engine/src/polyfills.ts
Normal file
|
@ -0,0 +1,60 @@
|
|||
// tslint:disable
|
||||
/**
|
||||
* This file includes polyfills needed by Angular and is loaded before the app.
|
||||
* You can add your own extra polyfills to this file.
|
||||
*
|
||||
* This file is divided into 2 sections:
|
||||
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
|
||||
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
|
||||
* file.
|
||||
*
|
||||
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
|
||||
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
|
||||
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
|
||||
*
|
||||
* Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
|
||||
*/
|
||||
|
||||
/***************************************************************************************************
|
||||
* BROWSER POLYFILLS
|
||||
*/
|
||||
|
||||
/** IE9, IE10 and IE11 requires all of the following polyfills. **/
|
||||
// import 'core-js/es6/symbol';
|
||||
// import 'core-js/es6/object';
|
||||
// import 'core-js/es6/function';
|
||||
// import 'core-js/es6/parse-int';
|
||||
// import 'core-js/es6/parse-float';
|
||||
// import 'core-js/es6/number';
|
||||
// import 'core-js/es6/math';
|
||||
// import 'core-js/es6/string';
|
||||
// import 'core-js/es6/date';
|
||||
// import 'core-js/es6/array';
|
||||
// import 'core-js/es6/regexp';
|
||||
// import 'core-js/es6/map';
|
||||
// import 'core-js/es6/weak-map';
|
||||
// import 'core-js/es6/set';
|
||||
|
||||
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
|
||||
// import 'classlist.js'; // Run `npm install --save classlist.js`.
|
||||
|
||||
/** IE10 and IE11 requires the following for the Reflect API. */
|
||||
// import 'core-js/es6/reflect';
|
||||
|
||||
/** Evergreen browsers require these. **/
|
||||
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
|
||||
|
||||
/**
|
||||
* Required to support Web Animations `@angular/platform-browser/animations`.
|
||||
* Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
|
||||
**/
|
||||
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
||||
|
||||
/***************************************************************************************************
|
||||
* Zone JS is required by default for Angular itself.
|
||||
*/
|
||||
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
||||
|
||||
/***************************************************************************************************
|
||||
* APPLICATION IMPORTS
|
||||
*/
|
34
core/app/engine/src/test.ts
Normal file
34
core/app/engine/src/test.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
// tslint:disable
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js/dist/long-stack-trace-zone';
|
||||
import 'zone.js/dist/proxy.js';
|
||||
import 'zone.js/dist/sync-test';
|
||||
import 'zone.js/dist/jasmine-patch';
|
||||
import 'zone.js/dist/async-test';
|
||||
import 'zone.js/dist/fake-async-test';
|
||||
import {getTestBed} from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
|
||||
declare const __karma__: any;
|
||||
declare const require: any;
|
||||
|
||||
// Prevent Karma from running prematurely.
|
||||
__karma__.loaded = function () {
|
||||
};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting()
|
||||
);
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
// Finally, start Karma to run the tests.
|
||||
__karma__.start();
|
11
core/app/engine/src/tsconfig.app.json
Normal file
11
core/app/engine/src/tsconfig.app.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/app",
|
||||
"types": []
|
||||
},
|
||||
"exclude": [
|
||||
"test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
20
core/app/engine/src/tsconfig.spec.json
Normal file
20
core/app/engine/src/tsconfig.spec.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/spec",
|
||||
"baseUrl": "./",
|
||||
"target": "es5",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"test.ts",
|
||||
"polyfills.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
6
core/app/engine/src/typings.d.ts
vendored
Normal file
6
core/app/engine/src/typings.d.ts
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
/* SystemJS module definition */
|
||||
declare var module: NodeModule;
|
||||
|
||||
interface NodeModule {
|
||||
id: string;
|
||||
}
|
101
core/app/engine/svgbuild.js
Normal file
101
core/app/engine/svgbuild.js
Normal file
|
@ -0,0 +1,101 @@
|
|||
var fs = require('fs');
|
||||
|
||||
// TODO: oop refactoring: use classes
|
||||
function print(msg) {
|
||||
process.stdout.write(msg);
|
||||
}
|
||||
|
||||
function printbk(msg) {
|
||||
print(msg + '\r');
|
||||
}
|
||||
|
||||
|
||||
function println(msg) {
|
||||
print(msg + '\n');
|
||||
}
|
||||
|
||||
function clearln() {
|
||||
process.stdout.clearLine();
|
||||
}
|
||||
|
||||
function errorout(err) {
|
||||
console.error('ERROR: ', err);
|
||||
}
|
||||
|
||||
|
||||
String.prototype.replaceAll = function (search, replacement) {
|
||||
var target = this;
|
||||
return target.replace(new RegExp(search, 'g'), replacement);
|
||||
};
|
||||
|
||||
class Spinner {
|
||||
constructor() {
|
||||
this.chars = '|/-\\';
|
||||
this.pos = 0;
|
||||
}
|
||||
|
||||
next() {
|
||||
this.pos++;
|
||||
if (this.pos >= this.chars.length) {
|
||||
this.pos = 0;
|
||||
}
|
||||
return this.chars[this.pos];
|
||||
}
|
||||
}
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
// ---- starting point
|
||||
|
||||
async function doit() {
|
||||
|
||||
try {
|
||||
|
||||
var folder = process.argv[2];
|
||||
if (!folder) {
|
||||
throw Error('Folder parameter is not set!');
|
||||
}
|
||||
var template = process.argv[3];
|
||||
if (!template) {
|
||||
throw Error('Template file as a parameter is not set!');
|
||||
}
|
||||
|
||||
println('Processing svg files from folder `' + folder + '` into angular component template: ' + template + '\r\n');
|
||||
|
||||
if (fs.existsSync(template)) {
|
||||
println(template + ' file already exists, making a backup..');
|
||||
fs.copyFileSync(template, template + '.bak');
|
||||
fs.unlinkSync(template);
|
||||
}
|
||||
files = fs.readdirSync(folder);
|
||||
|
||||
spinner = new Spinner();
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
clearln();
|
||||
printbk('Processing files (' + (i + 1) + '/' + files.length + '): [' + spinner.next() + '] ' + files[i]);
|
||||
var cnt =
|
||||
'\n<ng-template [ngIf]="file==\'' + files[i] + '\'">\n' +
|
||||
(fs.readFileSync(folder + files[i], 'utf-8')
|
||||
.replace(/^\s*\<\?xml\s+(.*)\?\>/i, '')
|
||||
.replaceAll(/\s+id\s*\=\s*\"/i, ' class="')
|
||||
.replaceAll(/<style[\s+>](.|\n|\r)*<\/style>/i, '')
|
||||
.replaceAll(/<title[\s+>](.|\n|\r)*<\/title>/i, '')
|
||||
.replaceAll(/<desc[\s+>](.|\n|\r)*<\/desc>/i, '')
|
||||
) +
|
||||
'\n</ng-template>\n';
|
||||
fs.appendFileSync(template, cnt);
|
||||
// await sleep(100);
|
||||
}
|
||||
clearln();
|
||||
println('Template created.\nDone.\n');
|
||||
|
||||
} catch (err) {
|
||||
errorout(err);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
doit();
|
33
core/app/engine/tsconfig.json
Normal file
33
core/app/engine/tsconfig.json
Normal file
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"*": [
|
||||
"types/*"
|
||||
],
|
||||
"core-js/es7/reflect": [
|
||||
"node_modules/core-js/proposals/reflect-metadata"
|
||||
],
|
||||
"core-js/es6/*": [
|
||||
"node_modules/core-js/es"
|
||||
]
|
||||
},
|
||||
"baseUrl": "./",
|
||||
"outDir": "./dist/out-tsc",
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"importHelpers": true,
|
||||
"target": "es2015",
|
||||
"typeRoots": [
|
||||
"node_modules/@types"
|
||||
],
|
||||
"lib": [
|
||||
"es2018",
|
||||
"dom"
|
||||
]
|
||||
}
|
||||
}
|
75
core/app/engine/tslint.json
Normal file
75
core/app/engine/tslint.json
Normal file
|
@ -0,0 +1,75 @@
|
|||
{
|
||||
"extends": "tslint:recommended",
|
||||
"rulesDirectory": [
|
||||
"codelyzer"
|
||||
],
|
||||
"rules": {
|
||||
"array-type": false,
|
||||
"arrow-parens": false,
|
||||
"deprecation": {
|
||||
"severity": "warn"
|
||||
},
|
||||
"import-blacklist": [
|
||||
true,
|
||||
"rxjs/Rx"
|
||||
],
|
||||
"interface-name": false,
|
||||
"max-classes-per-file": false,
|
||||
"max-line-length": [
|
||||
true,
|
||||
140
|
||||
],
|
||||
"member-access": false,
|
||||
"member-ordering": [
|
||||
true,
|
||||
{
|
||||
"order": [
|
||||
"static-field",
|
||||
"instance-field",
|
||||
"static-method",
|
||||
"instance-method"
|
||||
]
|
||||
}
|
||||
],
|
||||
"no-consecutive-blank-lines": false,
|
||||
"no-console": [
|
||||
true,
|
||||
"debug",
|
||||
"info",
|
||||
"time",
|
||||
"timeEnd",
|
||||
"trace"
|
||||
],
|
||||
"no-empty": false,
|
||||
"no-inferrable-types": [
|
||||
true,
|
||||
"ignore-params"
|
||||
],
|
||||
"no-non-null-assertion": true,
|
||||
"no-redundant-jsdoc": true,
|
||||
"no-switch-case-fall-through": true,
|
||||
"no-use-before-declare": true,
|
||||
"no-var-requires": false,
|
||||
"object-literal-key-quotes": [
|
||||
true,
|
||||
"as-needed"
|
||||
],
|
||||
"object-literal-sort-keys": false,
|
||||
"ordered-imports": false,
|
||||
"quotemark": [
|
||||
true,
|
||||
"single"
|
||||
],
|
||||
"trailing-comma": false,
|
||||
"no-output-on-prefix": true,
|
||||
"use-input-property-decorator": true,
|
||||
"use-output-property-decorator": true,
|
||||
"use-host-property-decorator": true,
|
||||
"no-input-rename": true,
|
||||
"no-output-rename": true,
|
||||
"use-life-cycle-interface": true,
|
||||
"use-pipe-transform-interface": true,
|
||||
"component-class-suffix": true,
|
||||
"directive-class-suffix": true
|
||||
}
|
||||
}
|
3
core/app/fields/address/address.php
Normal file
3
core/app/fields/address/address.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
// stub for address
|
|
@ -0,0 +1 @@
|
|||
{{ data.fieldValue }}
|
|
@ -0,0 +1,25 @@
|
|||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {AddressListFieldsComponent} from './address.component';
|
||||
|
||||
describe('AddressListViewComponent', () => {
|
||||
let component: AddressListFieldsComponent;
|
||||
let fixture: ComponentFixture<AddressListFieldsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [AddressListFieldsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AddressListFieldsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
17
core/app/fields/address/templates/list/address.component.ts
Normal file
17
core/app/fields/address/templates/list/address.component.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-address-list',
|
||||
templateUrl: './address.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class AddressListFieldsComponent implements OnInit {
|
||||
data: any = [];
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
3
core/app/fields/assignedusername/assignedusername.php
Normal file
3
core/app/fields/assignedusername/assignedusername.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
// stub for assigned username
|
|
@ -0,0 +1 @@
|
|||
{{ data.fieldValue }}
|
|
@ -0,0 +1,25 @@
|
|||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {AssignedusernameListViewComponent} from './assignedusername.component';
|
||||
|
||||
describe('AssignedusernameListViewComponent', () => {
|
||||
let component: AssignedusernameListViewComponent;
|
||||
let fixture: ComponentFixture<AssignedusernameListViewComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [AssignedusernameListViewComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AssignedusernameListViewComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,17 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-assignedusername-list',
|
||||
templateUrl: './assignedusername.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class AssignedusernameListFieldsComponent implements OnInit {
|
||||
data: any = [];
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
3
core/app/fields/boolean/boolean.php
Normal file
3
core/app/fields/boolean/boolean.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
// stub for boolean
|
|
@ -0,0 +1 @@
|
|||
{{ data.fieldValue }}
|
|
@ -0,0 +1,25 @@
|
|||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {BooleanListFieldsComponent} from './boolean.component';
|
||||
|
||||
describe('BooleanListFieldsComponent', () => {
|
||||
let component: BooleanListFieldsComponent;
|
||||
let fixture: ComponentFixture<BooleanListFieldsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [BooleanListFieldsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(BooleanListFieldsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
18
core/app/fields/boolean/templates/list/boolean.component.ts
Normal file
18
core/app/fields/boolean/templates/list/boolean.component.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-boolean-list',
|
||||
templateUrl: './boolean.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class BooleanListFieldsComponent implements OnInit {
|
||||
|
||||
data: any = [];
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
<label>
|
||||
<input type="checkbox"/>
|
||||
</label>
|
|
@ -0,0 +1,25 @@
|
|||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {BooleanComponent} from './boolean.component';
|
||||
|
||||
describe('BooleanComponent', () => {
|
||||
let component: BooleanComponent;
|
||||
let fixture: ComponentFixture<BooleanComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [BooleanComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(BooleanComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,16 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-boolean-record',
|
||||
templateUrl: './boolean.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class BooleanRecordFieldsComponent implements OnInit {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
3
core/app/fields/button/button.php
Normal file
3
core/app/fields/button/button.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
// stub for button
|
|
@ -0,0 +1 @@
|
|||
{{ data.fieldValue }}
|
|
@ -0,0 +1,25 @@
|
|||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {ButtonListFieldsComponent} from './button.component';
|
||||
|
||||
describe('ButtonListFieldsComponent', () => {
|
||||
let component: ButtonListFieldsComponent;
|
||||
let fixture: ComponentFixture<ButtonListFieldsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ButtonListFieldsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ButtonListFieldsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
18
core/app/fields/button/templates/list/button.component.ts
Normal file
18
core/app/fields/button/templates/list/button.component.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-button-list',
|
||||
templateUrl: './button.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class ButtonListFieldsComponent implements OnInit {
|
||||
|
||||
data: any = [];
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
<button>{{ field.label }}</button>
|
|
@ -0,0 +1,21 @@
|
|||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {ButtonRecordFieldsComponent} from './button.component';
|
||||
|
||||
describe('ButtonRecordFieldsComponent', () => {
|
||||
let component: ButtonRecordFieldsComponent;
|
||||
let fixture: ComponentFixture<ButtonRecordFieldsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ButtonRecordFieldsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ButtonRecordFieldsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
});
|
16
core/app/fields/button/templates/record/button.component.ts
Normal file
16
core/app/fields/button/templates/record/button.component.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-button-list',
|
||||
templateUrl: './button.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class ButtonRecordFieldsComponent implements OnInit {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
3
core/app/fields/collection/collection.php
Normal file
3
core/app/fields/collection/collection.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
// stub for collection
|
|
@ -0,0 +1 @@
|
|||
{{ data.fieldValue }}
|
|
@ -0,0 +1,25 @@
|
|||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {CollectionListViewComponent} from './collection.component';
|
||||
|
||||
describe('CollectionListViewComponent', () => {
|
||||
let component: CollectionListViewComponent;
|
||||
let fixture: ComponentFixture<CollectionListViewComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [CollectionListViewComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CollectionListViewComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,17 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-collection-list',
|
||||
templateUrl: './collection.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class CollectionListFieldsComponent implements OnInit {
|
||||
data: any = [];
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
3
core/app/fields/cronschedule/cronschedule.php
Normal file
3
core/app/fields/cronschedule/cronschedule.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
// stub for cronschedule
|
|
@ -0,0 +1 @@
|
|||
{{ data.fieldValue }}
|
|
@ -0,0 +1,25 @@
|
|||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {CronscheduleListFieldsComponent} from './cronschedule.component';
|
||||
|
||||
describe('CronscheduleListFieldsComponent', () => {
|
||||
let component: CronscheduleListFieldsComponent;
|
||||
let fixture: ComponentFixture<CronscheduleListFieldsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [CronscheduleListFieldsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CronscheduleListFieldsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,17 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-cronschedule-list',
|
||||
templateUrl: './cronschedule.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class CronscheduleListFieldsComponent implements OnInit {
|
||||
data: any = [];
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
3
core/app/fields/currency/currency.php
Normal file
3
core/app/fields/currency/currency.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
// stub for currency
|
|
@ -0,0 +1 @@
|
|||
currency
|
|
@ -0,0 +1,25 @@
|
|||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {CurrencyListFieldsComponent} from './currency.component';
|
||||
|
||||
describe('CurrencyListFieldsComponent', () => {
|
||||
let component: CurrencyListFieldsComponent;
|
||||
let fixture: ComponentFixture<CurrencyListFieldsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [CurrencyListFieldsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CurrencyListFieldsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-currency-list',
|
||||
templateUrl: './currency.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class CurrencyListFieldsComponent implements OnInit {
|
||||
|
||||
data: any = [];
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
<label>
|
||||
<input type="text"/>
|
||||
</label>
|
|
@ -0,0 +1,25 @@
|
|||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {CurrencyRecordFieldsComponent} from './currency.component';
|
||||
|
||||
describe('CurrencyRecordFieldsComponent', () => {
|
||||
let component: CurrencyRecordFieldsComponent;
|
||||
let fixture: ComponentFixture<CurrencyRecordFieldsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [CurrencyRecordFieldsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CurrencyRecordFieldsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,16 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-currency-record',
|
||||
templateUrl: './currency.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class CurrencyRecordFieldsComponent implements OnInit {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
3
core/app/fields/date/date.php
Normal file
3
core/app/fields/date/date.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
// stub for date
|
1
core/app/fields/date/templates/list/date.component.html
Normal file
1
core/app/fields/date/templates/list/date.component.html
Normal file
|
@ -0,0 +1 @@
|
|||
{{ data.fieldValue }}
|
21
core/app/fields/date/templates/list/date.component.spec.ts
Normal file
21
core/app/fields/date/templates/list/date.component.spec.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {DateListFieldsComponent} from './date.component';
|
||||
|
||||
describe('DateListFieldsComponent', () => {
|
||||
let component: DateListFieldsComponent;
|
||||
let fixture: ComponentFixture<DateListFieldsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [DateListFieldsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DateListFieldsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
});
|
17
core/app/fields/date/templates/list/date.component.ts
Normal file
17
core/app/fields/date/templates/list/date.component.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-date-list',
|
||||
templateUrl: './date.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class DateListFieldsComponent implements OnInit {
|
||||
data: any = [];
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
3
core/app/fields/datetime/datetime.php
Normal file
3
core/app/fields/datetime/datetime.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
// stub for datetime
|
|
@ -0,0 +1 @@
|
|||
{{ data.fieldValue }}
|
|
@ -0,0 +1,25 @@
|
|||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {DatetimeListFieldsComponent} from './datetime.component';
|
||||
|
||||
describe('DatetimeListFieldsComponent', () => {
|
||||
let component: DatetimeListFieldsComponent;
|
||||
let fixture: ComponentFixture<DatetimeListFieldsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [DatetimeListFieldsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DatetimeListFieldsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,17 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-datetime-list',
|
||||
templateUrl: './datetime.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class DatetimeListFieldsComponent implements OnInit {
|
||||
data: any = {};
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
3
core/app/fields/datetimecombo/datetimecombo.php
Normal file
3
core/app/fields/datetimecombo/datetimecombo.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
// stub for datetimecombo
|
|
@ -0,0 +1 @@
|
|||
{{ data.fieldValue }}
|
|
@ -0,0 +1,25 @@
|
|||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {DatetimecomboListFieldsComponent} from './datetimecombo.component';
|
||||
|
||||
describe('DatetimecomboListFieldsComponent', () => {
|
||||
let component: DatetimecomboListFieldsComponent;
|
||||
let fixture: ComponentFixture<DatetimecomboListFieldsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [DatetimecomboListFieldsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DatetimecomboListFieldsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,17 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-datetimecombo-list',
|
||||
templateUrl: './datetimecombo.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class DatetimecomboListFieldsComponent implements OnInit {
|
||||
data: any = [];
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
3
core/app/fields/default/default.php
Normal file
3
core/app/fields/default/default.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
// stub for default
|
|
@ -0,0 +1 @@
|
|||
{{ data.fieldValue }}
|
|
@ -0,0 +1,25 @@
|
|||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {DefaultListFieldsComponent} from './default.component';
|
||||
|
||||
describe('DefaultListFieldsComponent', () => {
|
||||
let component: DefaultListFieldsComponent;
|
||||
let fixture: ComponentFixture<DefaultListFieldsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [DefaultListFieldsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DefaultListFieldsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
17
core/app/fields/default/templates/list/default.component.ts
Normal file
17
core/app/fields/default/templates/list/default.component.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-default-list',
|
||||
templateUrl: './default.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class DefaultListFieldsComponent implements OnInit {
|
||||
data: any = [];
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
3
core/app/fields/download/download.php
Normal file
3
core/app/fields/download/download.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
// stub for download
|
|
@ -0,0 +1 @@
|
|||
{{ data.fieldValue }}
|
|
@ -0,0 +1,25 @@
|
|||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {DownloadListFieldsComponent} from './download.component';
|
||||
|
||||
describe('DownloadListFieldsComponent', () => {
|
||||
let component: DownloadListFieldsComponent;
|
||||
let fixture: ComponentFixture<DownloadListFieldsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [DownloadListFieldsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DownloadListFieldsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,17 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-download-list',
|
||||
templateUrl: './download.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class DownloadListFieldsComponent implements OnInit {
|
||||
data: any = [];
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue