├── .nvmrc
├── libs
├── plugin
│ ├── src
│ │ ├── index.ts
│ │ ├── generators
│ │ │ └── nx
│ │ │ │ ├── files
│ │ │ │ └── src
│ │ │ │ │ └── index.ts__template__
│ │ │ │ ├── schema.d.ts
│ │ │ │ ├── generator.spec.ts
│ │ │ │ └── schema.json
│ │ └── executors
│ │ │ ├── deploy-docker
│ │ │ ├── schema.d.ts
│ │ │ ├── executor.ts
│ │ │ ├── schema.json
│ │ │ └── executor.spec.ts
│ │ │ └── deploy-npm
│ │ │ ├── utils
│ │ │ ├── index.ts
│ │ │ ├── default-options.ts
│ │ │ └── package-json.ts
│ │ │ └── executor.ts
│ ├── .babelrc
│ ├── README.md
│ ├── tsconfig.json
│ ├── tsconfig.lib.json
│ ├── generators.json
│ ├── .eslintrc.json
│ ├── package.json
│ ├── tsconfig.spec.json
│ ├── jest.config.ts
│ └── executors.json
├── demos
│ ├── dyn-forms
│ │ ├── index.ts
│ │ ├── basic
│ │ │ └── intro
│ │ │ │ ├── app.component.scss
│ │ │ │ ├── index.ts
│ │ │ │ ├── ng-package.json
│ │ │ │ ├── app.component.html
│ │ │ │ ├── app.component.ts
│ │ │ │ ├── index.json
│ │ │ │ └── form.config.ts
│ │ ├── README.md
│ │ └── ng-package.json
│ ├── README.md
│ ├── index.ts
│ ├── ng-package.json
│ ├── tsconfig.lib.prod.json
│ ├── tsconfig.lib.json
│ ├── package.json
│ ├── tsconfig.json
│ ├── examples.json
│ ├── .eslintrc.json
│ └── project.json
├── forms
│ ├── ui-bootstrap
│ │ ├── src
│ │ │ ├── controls
│ │ │ │ ├── input
│ │ │ │ │ ├── input.component.scss
│ │ │ │ │ ├── input.component.params.ts
│ │ │ │ │ ├── input.component.html
│ │ │ │ │ └── input.component.ts
│ │ │ │ ├── radio
│ │ │ │ │ ├── radio.component.scss
│ │ │ │ │ ├── radio.component.params.ts
│ │ │ │ │ ├── radio.component.html
│ │ │ │ │ └── radio.component.ts
│ │ │ │ ├── select
│ │ │ │ │ ├── select.component.scss
│ │ │ │ │ ├── select.component.params.ts
│ │ │ │ │ ├── select.component.html
│ │ │ │ │ └── select.component.ts
│ │ │ │ ├── checkbox
│ │ │ │ │ ├── checkbox.component.scss
│ │ │ │ │ ├── checkbox.component.params.ts
│ │ │ │ │ ├── checkbox.component.html
│ │ │ │ │ └── checkbox.component.ts
│ │ │ │ └── index.ts
│ │ │ └── dyn-forms-bootstrap.module.ts
│ │ ├── index.ts
│ │ └── ng-package.json
│ ├── ui-material
│ │ ├── src
│ │ │ ├── controls
│ │ │ │ ├── container
│ │ │ │ │ ├── container.component.scss
│ │ │ │ │ ├── container.component.html
│ │ │ │ │ ├── container.component.params.ts
│ │ │ │ │ └── container.component.ts
│ │ │ │ ├── divider
│ │ │ │ │ ├── divider.component.html
│ │ │ │ │ ├── divider.component.scss
│ │ │ │ │ ├── divider.component.params.ts
│ │ │ │ │ └── divider.component.ts
│ │ │ │ ├── checkbox
│ │ │ │ │ ├── checkbox.component.scss
│ │ │ │ │ ├── checkbox.component.html
│ │ │ │ │ ├── checkbox.component.params.ts
│ │ │ │ │ ├── checkbox.component.ts
│ │ │ │ │ └── checkbox.component.spec.ts
│ │ │ │ ├── select
│ │ │ │ │ ├── select.component.scss
│ │ │ │ │ ├── select.component.html
│ │ │ │ │ ├── select.component.params.ts
│ │ │ │ │ └── select.component.spec.ts
│ │ │ │ ├── card
│ │ │ │ │ ├── card.component.scss
│ │ │ │ │ ├── card.component.params.ts
│ │ │ │ │ ├── card.component.html
│ │ │ │ │ ├── card.component.ts
│ │ │ │ │ └── card.component.spec.ts
│ │ │ │ ├── multicheckbox
│ │ │ │ │ ├── multicheckbox.component.params.ts
│ │ │ │ │ ├── multicheckbox.component.scss
│ │ │ │ │ └── multicheckbox.component.html
│ │ │ │ ├── radio
│ │ │ │ │ ├── radio.component.params.ts
│ │ │ │ │ ├── radio.component.html
│ │ │ │ │ ├── radio.component.scss
│ │ │ │ │ ├── radio.component.ts
│ │ │ │ │ └── radio.component.spec.ts
│ │ │ │ ├── input
│ │ │ │ │ ├── input.component.scss
│ │ │ │ │ ├── input.component.params.ts
│ │ │ │ │ ├── input.component.html
│ │ │ │ │ └── input.component.spec.ts
│ │ │ │ ├── datepicker
│ │ │ │ │ ├── datepicker.component.scss
│ │ │ │ │ ├── datepicker.component.params.ts
│ │ │ │ │ └── datepicker.component.html
│ │ │ │ ├── array
│ │ │ │ │ ├── array.component.params.ts
│ │ │ │ │ ├── array.component.scss
│ │ │ │ │ ├── array.component.html
│ │ │ │ │ └── array.component.spec.ts
│ │ │ │ ├── table
│ │ │ │ │ └── table.component.params.ts
│ │ │ │ ├── table-row
│ │ │ │ │ └── table-row.component.html
│ │ │ │ └── index.ts
│ │ │ └── wrappers
│ │ │ │ ├── index.ts
│ │ │ │ └── form-field
│ │ │ │ ├── form-field.component.params.ts
│ │ │ │ └── form-field.component.scss
│ │ ├── index.ts
│ │ └── ng-package.json
│ ├── index.ts
│ ├── ui-native
│ │ ├── src
│ │ │ ├── controls
│ │ │ │ ├── input
│ │ │ │ │ ├── input.component.scss
│ │ │ │ │ ├── input.component.html
│ │ │ │ │ ├── input.component.params.ts
│ │ │ │ │ ├── input.component.ts
│ │ │ │ │ └── input.component.spec.ts
│ │ │ │ └── index.ts
│ │ │ ├── dyn-forms-native.factory.ts
│ │ │ └── dyn-forms-native.module.ts
│ │ ├── index.ts
│ │ └── ng-package.json
│ ├── testing
│ │ ├── index.ts
│ │ ├── ng-package.json
│ │ ├── form
│ │ │ └── form-testing.component.ts
│ │ └── dyn-forms-testing.module.ts
│ ├── lib
│ │ ├── components
│ │ │ ├── form
│ │ │ │ ├── form.component.scss
│ │ │ │ ├── form.component.html
│ │ │ │ ├── form.config.ts
│ │ │ │ └── form.component.spec.ts
│ │ │ ├── index.ts
│ │ │ ├── group
│ │ │ │ ├── group.component.html
│ │ │ │ └── group.component.spec.ts
│ │ │ └── factory
│ │ │ │ └── factory.directive.spec.ts
│ │ ├── schematics
│ │ │ ├── control
│ │ │ │ └── files
│ │ │ │ │ └── __name@dasherize@if-flat__
│ │ │ │ │ ├── __name@dasherize__.__type@dasherize__.__style__.template
│ │ │ │ │ ├── __name@dasherize__.__type@dasherize__.params.ts.template
│ │ │ │ │ └── __name@dasherize__.__type@dasherize__.html.template
│ │ │ └── module
│ │ │ │ ├── schema.ts
│ │ │ │ └── files
│ │ │ │ └── __name@dasherize@if-flat__
│ │ │ │ └── __name@dasherize__.module.ts.template
│ │ └── migrations
│ │ │ └── 12_6_1
│ │ │ └── index.ts
│ ├── core
│ │ ├── ng-package.json
│ │ └── src
│ │ │ ├── types
│ │ │ ├── utils
│ │ │ │ ├── tree.types.ts
│ │ │ │ └── option.types.ts
│ │ │ ├── events.types.ts
│ │ │ ├── mode.types.ts
│ │ │ ├── wrapper.types.ts
│ │ │ ├── templates.types.ts
│ │ │ ├── params.types.ts
│ │ │ ├── forms.types.ts
│ │ │ ├── provider.types.ts
│ │ │ └── config.types.ts
│ │ │ ├── hidden
│ │ │ ├── control.component.ts
│ │ │ └── group.component.ts
│ │ │ ├── utils
│ │ │ ├── hidden.util.ts
│ │ │ ├── config.utils.ts
│ │ │ └── rxjs.utils.ts
│ │ │ ├── dyn-form-group.class.ts
│ │ │ └── dyn-form-container.class.ts
│ ├── logger
│ │ ├── README.md
│ │ ├── ng-package.json
│ │ ├── index.ts
│ │ └── src
│ │ │ ├── interfaces
│ │ │ └── node.interface.ts
│ │ │ ├── log-level.token.ts
│ │ │ ├── log.interface.ts
│ │ │ └── log-levels.constant.ts
│ ├── tsconfig.schematics.json
│ ├── tsconfig.spec.json
│ ├── tsconfig.lib.prod.json
│ ├── ng-package.json
│ ├── index.tests.ts
│ ├── migrations.json
│ ├── schematics.json
│ ├── tsconfig.lib.json
│ ├── tsconfig.json
│ ├── jest.config.ts
│ ├── package.json
│ └── .eslintrc.json
└── utils
│ ├── src
│ ├── index.ts
│ ├── rxjs-tree.ts
│ ├── rxjs-fs.ts
│ └── json.ts
│ ├── .babelrc
│ ├── README.md
│ ├── tsconfig.lib.json
│ ├── CHANGELOG.md
│ ├── .eslintrc.json
│ ├── tsconfig.json
│ ├── jest.config.ts
│ ├── tsconfig.spec.json
│ └── package.json
├── .eslintignore
├── apps
└── website
│ ├── src
│ ├── app
│ │ ├── docs
│ │ │ ├── components
│ │ │ │ ├── stackblitz
│ │ │ │ │ ├── stackblitz.component.scss
│ │ │ │ │ ├── stackblitz.component.html
│ │ │ │ │ └── stackblitz.component.ts
│ │ │ │ ├── viewer
│ │ │ │ │ ├── viewer.component.html
│ │ │ │ │ └── viewer.component.scss
│ │ │ │ ├── content
│ │ │ │ │ ├── content.component.scss
│ │ │ │ │ └── content.component.html
│ │ │ │ ├── layout
│ │ │ │ │ ├── layout.component.html
│ │ │ │ │ └── layout.component.scss
│ │ │ │ └── example
│ │ │ │ │ └── example.component.scss
│ │ │ ├── services
│ │ │ │ ├── index.ts
│ │ │ │ └── i18n.service.ts
│ │ │ └── interfaces
│ │ │ │ ├── index.ts
│ │ │ │ ├── nav.interfaces.ts
│ │ │ │ └── metadata.interfaces.ts
│ │ ├── demos
│ │ │ ├── submodules
│ │ │ │ └── dyn-forms
│ │ │ │ │ ├── components
│ │ │ │ │ ├── stepper
│ │ │ │ │ │ ├── step1
│ │ │ │ │ │ │ ├── step1.component.scss
│ │ │ │ │ │ │ ├── step1.component.html
│ │ │ │ │ │ │ ├── step1.component.ts
│ │ │ │ │ │ │ └── step1.component.spec.ts
│ │ │ │ │ │ ├── step2
│ │ │ │ │ │ │ ├── step2.component.scss
│ │ │ │ │ │ │ ├── step2.component.ts
│ │ │ │ │ │ │ ├── step2.component.html
│ │ │ │ │ │ │ └── step2.component.spec.ts
│ │ │ │ │ │ ├── summary
│ │ │ │ │ │ │ ├── summary.component.scss
│ │ │ │ │ │ │ ├── summary.component.ts
│ │ │ │ │ │ │ ├── summary.component.html
│ │ │ │ │ │ │ └── summary.component.spec.ts
│ │ │ │ │ │ ├── stepper.component.html
│ │ │ │ │ │ ├── stepper.component.scss
│ │ │ │ │ │ ├── stepper.component.spec.ts
│ │ │ │ │ │ └── stepper.component.ts
│ │ │ │ │ ├── combo
│ │ │ │ │ │ ├── combo.component.scss
│ │ │ │ │ │ ├── combo.component.spec.ts
│ │ │ │ │ │ ├── combo.component.html
│ │ │ │ │ │ └── combo.service.ts
│ │ │ │ │ ├── single
│ │ │ │ │ │ ├── single.component.scss
│ │ │ │ │ │ ├── success.control
│ │ │ │ │ │ │ ├── success.component.scss
│ │ │ │ │ │ │ ├── success.component.html
│ │ │ │ │ │ │ └── success.component.ts
│ │ │ │ │ │ ├── single.component.spec.ts
│ │ │ │ │ │ ├── single.component.html
│ │ │ │ │ │ └── single.form.ts
│ │ │ │ │ ├── simple
│ │ │ │ │ │ ├── simple.component.scss
│ │ │ │ │ │ ├── simple.component.spec.ts
│ │ │ │ │ │ └── simple.component.html
│ │ │ │ │ └── builder
│ │ │ │ │ │ ├── builder.component.scss
│ │ │ │ │ │ ├── builder.component.spec.ts
│ │ │ │ │ │ └── business.types.ts
│ │ │ │ │ └── constants
│ │ │ │ │ └── dyn-forms.links.ts
│ │ │ ├── components
│ │ │ │ └── index
│ │ │ │ │ ├── index.component.scss
│ │ │ │ │ ├── index.component.html
│ │ │ │ │ └── index.component.ts
│ │ │ └── demos.module.ts
│ │ ├── layout
│ │ │ ├── containers
│ │ │ │ ├── index.ts
│ │ │ │ └── wrapper
│ │ │ │ │ ├── wrapper.component.html
│ │ │ │ │ ├── wrapper.component.ts
│ │ │ │ │ └── wrapper.component.scss
│ │ │ ├── components
│ │ │ │ ├── section-badges
│ │ │ │ │ ├── section-badges.component.scss
│ │ │ │ │ ├── section-badge.interface.ts
│ │ │ │ │ ├── section-badges.component.html
│ │ │ │ │ └── section-badges.component.ts
│ │ │ │ ├── prompt
│ │ │ │ │ ├── prompt.dialog.scss
│ │ │ │ │ ├── prompt-data.interface.ts
│ │ │ │ │ ├── prompt.dialog.html
│ │ │ │ │ └── prompt.dialog.ts
│ │ │ │ ├── section-actions
│ │ │ │ │ ├── section-action.interface.ts
│ │ │ │ │ ├── section-actions.component.scss
│ │ │ │ │ ├── section-actions.component.html
│ │ │ │ │ └── section-actions.component.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── footer
│ │ │ │ │ ├── footer.component.ts
│ │ │ │ │ └── footer.component.scss
│ │ │ │ └── header
│ │ │ │ │ ├── header.component.ts
│ │ │ │ │ └── header.component.html
│ │ │ └── index.ts
│ │ ├── pages
│ │ │ ├── index.ts
│ │ │ └── components
│ │ │ │ ├── not-found
│ │ │ │ ├── not-found.component.html
│ │ │ │ ├── not-found.component.scss
│ │ │ │ └── not-found.component.ts
│ │ │ │ ├── homepage
│ │ │ │ ├── homepage.component.ts
│ │ │ │ ├── homepage.component.scss
│ │ │ │ └── homepage.component.html
│ │ │ │ └── docs
│ │ │ │ ├── docs.component.scss
│ │ │ │ ├── docs.component.html
│ │ │ │ └── docs.component.ts
│ │ ├── app.component.ts
│ │ ├── app.server.module.ts
│ │ └── app.module.ts
│ ├── environments
│ │ ├── environment.prod.ts
│ │ └── environment.ts
│ ├── favicon.jpg
│ ├── assets
│ │ ├── logo.png
│ │ └── logos
│ │ │ ├── fb.svg
│ │ │ ├── github.svg
│ │ │ ├── linkedin.svg
│ │ │ └── tw.svg
│ ├── main.server.ts
│ ├── test-setup.ts
│ ├── main.ts
│ └── index.html
│ ├── tsconfig.editor.json
│ ├── tsconfig.app.prod.json
│ ├── tsconfig.spec.json
│ ├── tsconfig.json
│ ├── tsconfig.server.json
│ ├── tsconfig.app.json
│ ├── .browserslistrc
│ ├── jest.config.ts
│ └── .eslintrc.json
├── .prettierrc
├── .commitlintrc.json
├── .vscode
├── settings.json
└── extensions.json
├── .husky
├── commit-msg
└── post-checkout
├── .prettierignore
├── jest.preset.js
├── jest.config.ts
├── netlify.toml
├── docs
└── dyn-forms
│ ├── examples
│ └── basic
│ │ ├── README.md
│ │ └── README.es.md
│ ├── ui
│ ├── packages
│ │ └── README.md
│ └── ui-material
│ │ └── README.md
│ └── intro
│ └── 9-schematics.md
├── .editorconfig
├── tools
└── tsconfig.tools.json
├── .github
├── ISSUE_TEMPLATE
│ ├── ui-package.md
│ ├── feature-request.md
│ └── bug-report.md
└── FUNDING.yml
├── DEVELOPMENT.md
├── .gitignore
├── tsconfig.schematics.json
├── .all-contributorsrc
├── CODE_OF_CONDUCT.md
├── LICENSE
├── tsconfig.base.json
└── .eslintrc.json
/.nvmrc:
--------------------------------------------------------------------------------
1 | 18
2 |
--------------------------------------------------------------------------------
/libs/plugin/src/index.ts:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/libs/demos/dyn-forms/index.ts:
--------------------------------------------------------------------------------
1 | export {};
2 |
--------------------------------------------------------------------------------
/libs/demos/dyn-forms/basic/intro/app.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/controls/input/input.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/controls/radio/radio.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/controls/select/select.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/website/src/app/docs/components/stackblitz/stackblitz.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/controls/checkbox/checkbox.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/container/container.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "trailingComma": "es5"
4 | }
5 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/stepper/step1/step1.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/stepper/step2/step2.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/website/src/app/docs/components/viewer/viewer.component.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.commitlintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["@commitlint/config-angular"],
3 | "rules": {}
4 | }
5 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "git.pullTags": false,
3 | "git.autoStash": true
4 | }
5 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/stepper/summary/summary.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/website/src/app/docs/components/stackblitz/stackblitz.component.html:
--------------------------------------------------------------------------------
1 | Stackblitz button
2 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/containers/index.ts:
--------------------------------------------------------------------------------
1 | export * from './wrapper/wrapper.component';
2 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/divider/divider.component.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/libs/plugin/src/generators/nx/files/src/index.ts__template__:
--------------------------------------------------------------------------------
1 | const variable = "<%= projectName %>";
--------------------------------------------------------------------------------
/.husky/commit-msg:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | yarn commitlint --edit $1
5 |
--------------------------------------------------------------------------------
/apps/website/src/app/pages/index.ts:
--------------------------------------------------------------------------------
1 | export * from './components/not-found/not-found.component';
2 |
--------------------------------------------------------------------------------
/libs/forms/index.ts:
--------------------------------------------------------------------------------
1 | export * from './lib/dyn-forms.module';
2 | export * from './lib/components';
3 |
--------------------------------------------------------------------------------
/libs/forms/ui-native/src/controls/input/input.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # Add files here to ignore them from prettier formatting
2 |
3 | /dist
4 | /coverage
5 |
--------------------------------------------------------------------------------
/libs/demos/README.md:
--------------------------------------------------------------------------------
1 | # @myndpm/demos
2 |
3 | Library with demo module NgFactory and Dynamic Components.
4 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/checkbox/checkbox.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
--------------------------------------------------------------------------------
/apps/website/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true,
3 | };
4 |
--------------------------------------------------------------------------------
/apps/website/src/favicon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/myndpm/open-source/HEAD/apps/website/src/favicon.jpg
--------------------------------------------------------------------------------
/libs/demos/dyn-forms/basic/intro/index.ts:
--------------------------------------------------------------------------------
1 | export * from './app.module';
2 | export * from './app.component';
3 |
--------------------------------------------------------------------------------
/apps/website/src/app/docs/services/index.ts:
--------------------------------------------------------------------------------
1 | export * from './content.service';
2 | export * from './i18n.service';
3 |
--------------------------------------------------------------------------------
/apps/website/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/myndpm/open-source/HEAD/apps/website/src/assets/logo.png
--------------------------------------------------------------------------------
/jest.preset.js:
--------------------------------------------------------------------------------
1 | const nxPreset = require('@nx/jest/preset').default;
2 |
3 | module.exports = { ...nxPreset };
4 |
--------------------------------------------------------------------------------
/apps/website/src/app/docs/interfaces/index.ts:
--------------------------------------------------------------------------------
1 | export * from './metadata.interfaces';
2 | export * from './nav.interfaces';
3 |
--------------------------------------------------------------------------------
/jest.config.ts:
--------------------------------------------------------------------------------
1 | const { getJestProjects } = require('@nx/jest');
2 |
3 | export default { projects: getJestProjects() };
4 |
--------------------------------------------------------------------------------
/libs/plugin/src/executors/deploy-docker/schema.d.ts:
--------------------------------------------------------------------------------
1 | export interface DeployDockerExecutorSchema {} // eslint-disable-line
2 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/components/section-badges/section-badges.component.scss:
--------------------------------------------------------------------------------
1 | .badges {
2 | margin-bottom: 16px;
3 | }
4 |
--------------------------------------------------------------------------------
/libs/forms/testing/index.ts:
--------------------------------------------------------------------------------
1 | export * from './dyn-forms-testing.module';
2 |
3 | export * from './form/form-testing.component';
4 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/index.ts:
--------------------------------------------------------------------------------
1 | export * from './layout.module';
2 | export * from './containers';
3 | export * from './components';
4 |
--------------------------------------------------------------------------------
/libs/forms/ui-native/src/controls/index.ts:
--------------------------------------------------------------------------------
1 | export * from './input/input.component';
2 | export * from './input/input.component.params';
3 |
--------------------------------------------------------------------------------
/libs/demos/dyn-forms/README.md:
--------------------------------------------------------------------------------
1 | # @myndpm/demos/dyn-forms
2 |
3 | Package with NgModules and Components to be loaded dynamically by the docs.
4 |
--------------------------------------------------------------------------------
/.husky/post-checkout:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | [ -n "$CI" ] && exit 0
4 |
5 | . "$(dirname -- "$0")/_/husky.sh"
6 |
7 | git fetch --tags --force
8 |
--------------------------------------------------------------------------------
/libs/demos/index.ts:
--------------------------------------------------------------------------------
1 | import EXAMPLE_COMPONENTS from './examples.json';
2 |
3 | export { EXAMPLE_COMPONENTS };
4 | export * from './example-data';
5 |
--------------------------------------------------------------------------------
/libs/utils/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './json';
2 | export * from './rxjs-fs';
3 | export * from './rxjs-shell';
4 | export * from './rxjs-tree';
5 |
--------------------------------------------------------------------------------
/libs/plugin/src/generators/nx/schema.d.ts:
--------------------------------------------------------------------------------
1 | export interface NxGeneratorSchema {
2 | name: string;
3 | tags?: string;
4 | directory?: string;
5 | }
6 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/wrappers/index.ts:
--------------------------------------------------------------------------------
1 | export * from './form-field/form-field.component';
2 | export * from './form-field/form-field.component.params';
3 |
--------------------------------------------------------------------------------
/libs/plugin/src/executors/deploy-npm/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './default-options';
2 | export * from './lib-paths';
3 | export * from './package-json';
4 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/divider/divider.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 |
4 | &.is-invisible {
5 | visibility: hidden;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/libs/forms/ui-native/index.ts:
--------------------------------------------------------------------------------
1 | export * from './src/dyn-forms-native.module';
2 | export * from './src/dyn-forms-native.factory';
3 | export * from './src/controls/index';
4 |
--------------------------------------------------------------------------------
/libs/plugin/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@nx/js/babel",
5 | {
6 | "useBuiltIns": "usage"
7 | }
8 | ]
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/libs/utils/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@nx/js/babel",
5 | {
6 | "useBuiltIns": "usage"
7 | }
8 | ]
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | command = "yarn build:prod"
3 | publish = "dist/website/browser"
4 | [[redirects]]
5 | from = "/*"
6 | to = "/index.html"
7 | status = 200
8 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/components/prompt/prompt.dialog.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | padding-bottom: 10px;
4 |
5 | h4 {
6 | margin-top: 0;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/components/section-badges/section-badge.interface.ts:
--------------------------------------------------------------------------------
1 | export interface SectionBadge {
2 | link: string;
3 | img: string;
4 | alt?: string;
5 | }
6 |
--------------------------------------------------------------------------------
/libs/demos/dyn-forms/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "./index.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/index.ts:
--------------------------------------------------------------------------------
1 | export * from './src/dyn-forms-bootstrap.module';
2 | export * from './src/dyn-forms-bootstrap.factory';
3 | export * from './src/controls/index';
4 |
--------------------------------------------------------------------------------
/libs/forms/lib/components/form/form.component.scss:
--------------------------------------------------------------------------------
1 | dyn-form {
2 | .dyn-invisible {
3 | visibility: hidden !important;
4 | }
5 | .dyn-hidden {
6 | display: none !important;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/container/container.component.html:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/select/select.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 |
4 | &.readonly {
5 | .mat-select {
6 | display: none;
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/libs/forms/ui-native/src/controls/input/input.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/libs/plugin/README.md:
--------------------------------------------------------------------------------
1 | # @myndpm/nx
2 |
3 | Plugin for Nx by Mynd.
4 |
5 | ## Acknowledgements
6 |
7 | - [ngx-deploy-npm][1]
8 |
9 | [1]: https://github.com/bikecoders/ngx-deploy-npm
10 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/container/container.component.params.ts:
--------------------------------------------------------------------------------
1 | import { DynParams } from '@myndpm/dyn-forms/core';
2 |
3 | export interface DynMatContainerParams extends DynParams {
4 | }
5 |
--------------------------------------------------------------------------------
/libs/forms/lib/components/index.ts:
--------------------------------------------------------------------------------
1 | export * from './factory/factory.directive';
2 | export * from './form/form.component';
3 | export * from './form/form.config';
4 | export * from './group/group.component';
5 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/card/card.component.scss:
--------------------------------------------------------------------------------
1 | // fix left-margin of .mat-card-header-text when there's no card-avatar
2 | mat-card-header ::ng-deep > :first-child {
3 | margin-left: 0;
4 | }
5 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/components/section-actions/section-action.interface.ts:
--------------------------------------------------------------------------------
1 | export interface SectionAction {
2 | link: string;
3 | icon?: string;
4 | ionicon?: string;
5 | tooltip?: string;
6 | }
7 |
--------------------------------------------------------------------------------
/apps/website/tsconfig.editor.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "include": ["**/*.ts"],
4 | "compilerOptions": {
5 | "types": ["jest", "node"]
6 | },
7 | "exclude": ["jest.config.ts"]
8 | }
9 |
--------------------------------------------------------------------------------
/libs/utils/README.md:
--------------------------------------------------------------------------------
1 | # @myndpm/utils
2 |
3 | NPM package with misc utilities.
4 |
5 | ## Usage
6 |
7 | It's a base `dependency` of other packages like `@myndpm/nx` for JSON and RxJS filesystem manipulations.
8 |
--------------------------------------------------------------------------------
/apps/website/tsconfig.app.prod.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.app.json",
3 | "compilerOptions": {
4 | "noUnusedLocals": true,
5 | "target": "ES2022",
6 | "useDefineForClassFields": false
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/libs/forms/core/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/libs/forms/core",
4 | "lib": {
5 | "entryFile": "./index.ts"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/libs/forms/logger/README.md:
--------------------------------------------------------------------------------
1 | # @myndpm/dyn-forms/logger
2 |
3 | Mini fork of [@ngworker/lumberjack](https://github.com/ngworker/lumberjack)
4 | coupled to the needs of the library and simplified override of providers.
5 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/index.ts:
--------------------------------------------------------------------------------
1 | export { DynFormsMaterialModule } from './src/dyn-forms-material.module';
2 | export { createMatConfig } from './src/dyn-forms-material.factory';
3 | export * from './src/controls/index';
4 |
--------------------------------------------------------------------------------
/apps/website/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-root',
5 | template: '',
6 | })
7 | export class AppComponent {}
8 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/containers/wrapper/wrapper.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/libs/forms/logger/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/libs/forms/logger",
4 | "lib": {
5 | "entryFile": "./index.ts"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/libs/forms/testing/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/libs/forms/testing",
4 | "lib": {
5 | "entryFile": "./index.ts"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/divider/divider.component.params.ts:
--------------------------------------------------------------------------------
1 | import { DynParams } from '@myndpm/dyn-forms/core';
2 |
3 | export interface DynMatDividerParams extends DynParams {
4 | invisible?: boolean;
5 | }
6 |
--------------------------------------------------------------------------------
/libs/forms/core/src/types/utils/tree.types.ts:
--------------------------------------------------------------------------------
1 | // generic type for hierarchical trees
2 | export type DynTree = T & {
3 | name?: string;
4 | dynId?: string;
5 | detached?: boolean;
6 | children?: DynTree[];
7 | }
8 |
--------------------------------------------------------------------------------
/libs/forms/lib/components/group/group.component.html:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/libs/forms/ui-native/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/libs/forms/ui-native",
4 | "lib": {
5 | "entryFile": "./index.ts"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/combo/combo.component.scss:
--------------------------------------------------------------------------------
1 | app-form-combo {
2 | .mat-card {
3 | margin-bottom: 0.5em;
4 | }
5 |
6 | .form-actions {
7 | margin-top: 1em;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/libs/forms/ui-bootstrap",
4 | "lib": {
5 | "entryFile": "./index.ts"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/libs/forms/ui-material",
4 | "lib": {
5 | "entryFile": "./index.ts"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/single/single.component.scss:
--------------------------------------------------------------------------------
1 | app-form-single {
2 | .mat-card {
3 | margin-bottom: 0.5em
4 | }
5 |
6 | .form-actions {
7 | margin-top: 1em
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/controls/checkbox/checkbox.component.params.ts:
--------------------------------------------------------------------------------
1 | import { DynParams } from '@myndpm/dyn-forms/core';
2 |
3 | export interface DynBsCheckboxParams extends DynParams {
4 | label: string;
5 | hint?: string;
6 | }
7 |
--------------------------------------------------------------------------------
/libs/forms/logger/index.ts:
--------------------------------------------------------------------------------
1 | export * from './src/log-levels.constant';
2 | export * from './src/log-level.token';
3 | export * from './src/log.interface';
4 |
5 | export * from './src/log-driver.service';
6 | export * from './src/logger.service';
7 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/checkbox/checkbox.component.html:
--------------------------------------------------------------------------------
1 |
5 | {{ params.label }}
6 |
7 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/single/success.control/success.component.scss:
--------------------------------------------------------------------------------
1 | // fix left-margin of .mat-card-header-text when there's no card-avatar
2 | mat-card-header ::ng-deep > :first-child {
3 | margin-left: 0;
4 | }
5 |
--------------------------------------------------------------------------------
/docs/dyn-forms/examples/basic/README.md:
--------------------------------------------------------------------------------
1 | # Basic Setup
2 |
3 | This is the most basic setup of dyn-forms.
4 |
5 | You can see how we consume the controls provided by a `ui-package`
6 | and with no CSS classes assigned the controls will take a whole row.
7 |
--------------------------------------------------------------------------------
/libs/demos/dyn-forms/basic/intro/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../../../../dist/libs/demos/dyn-forms",
4 | "lib": {
5 | "entryFile": "./index.ts"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/controls/radio/radio.component.params.ts:
--------------------------------------------------------------------------------
1 | import { DynParams, DynOption } from '@myndpm/dyn-forms/core';
2 |
3 | export interface DynBsRadioParams extends DynParams {
4 | options: DynOption[];
5 | inline?: boolean;
6 | }
7 |
--------------------------------------------------------------------------------
/libs/forms/lib/schematics/control/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.__style__.template:
--------------------------------------------------------------------------------
1 | <% if(displayBlock){ if(style != 'sass') { %>:host {
2 | display: block;
3 | }
4 | <% } else { %>:host
5 | display: block
6 | <% }} %>
--------------------------------------------------------------------------------
/libs/forms/logger/src/interfaces/node.interface.ts:
--------------------------------------------------------------------------------
1 | export interface DynNode {
2 | parent?: DynNode;
3 | index?: number;
4 | deep: number;
5 | path: string[];
6 | route: string[];
7 |
8 | dynId?: string;
9 | instance: string;
10 | }
11 |
--------------------------------------------------------------------------------
/libs/forms/logger/src/log-level.token.ts:
--------------------------------------------------------------------------------
1 | import { InjectionToken } from '@angular/core';
2 | import { DynLogLevel } from './log-levels.constant';
3 |
4 | export const DYN_LOG_LEVEL = new InjectionToken(
5 | '@myndpm/dyn-forms/logger'
6 | );
7 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/card/card.component.params.ts:
--------------------------------------------------------------------------------
1 | import { DynParams } from '@myndpm/dyn-forms/core';
2 |
3 | export interface DynMatCardParams extends DynParams {
4 | title?: string;
5 | subtitle?: string;
6 | avatar?: string;
7 | }
8 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/components/prompt/prompt-data.interface.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Prompt data
3 | */
4 | export interface PromptDialogData {
5 | title: string;
6 | content: string;
7 | no?: string;
8 | yes?: string;
9 | color?: string;
10 | }
11 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "nrwl.angular-console",
4 | "angular.ng-template",
5 | "ms-vscode.vscode-typescript-tslint-plugin",
6 | "esbenp.prettier-vscode",
7 | "firsttris.vscode-jest-runner"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/components/index.ts:
--------------------------------------------------------------------------------
1 | export * from './prompt/prompt.dialog';
2 | export * from './prompt/prompt-data.interface';
3 | export * from './section-actions/section-action.interface';
4 | export * from './section-badges/section-badge.interface';
5 |
--------------------------------------------------------------------------------
/libs/demos/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/libs/demos",
4 | "assets": [
5 | "examples.json"
6 | ],
7 | "lib": {
8 | "entryFile": "./index.ts"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/multicheckbox/multicheckbox.component.params.ts:
--------------------------------------------------------------------------------
1 | import { DynParams, DynOption } from '@myndpm/dyn-forms/core';
2 |
3 | export interface DynMatMulticheckboxParams extends DynParams {
4 | label?: string;
5 | options: DynOption[];
6 | }
7 |
--------------------------------------------------------------------------------
/libs/demos/dyn-forms/basic/intro/app.component.html:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/libs/forms/lib/components/form/form.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/radio/radio.component.params.ts:
--------------------------------------------------------------------------------
1 | import { DynParams, DynOption } from '@myndpm/dyn-forms/core';
2 |
3 | export interface DynMatRadioParams extends DynParams {
4 | label?: string;
5 | options: DynOption[];
6 | readonly?: boolean;
7 | }
8 |
--------------------------------------------------------------------------------
/docs/dyn-forms/examples/basic/README.es.md:
--------------------------------------------------------------------------------
1 | # Configuración Básica
2 |
3 | Esta es la configuración más elemental de dyn-forms.
4 |
5 | Puedes ver como se consumen los controles provistos por un `ui-package`
6 | y sin clases CSS asignadas, los controles tomarán la fila completa.
7 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/input/input.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 |
4 | .mat-input-element {
5 | line-height: 1.2em;
6 | }
7 |
8 | &.readonly {
9 | input,
10 | textarea {
11 | display: none;
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/libs/plugin/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.lib.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/multicheckbox/multicheckbox.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | margin: .25em 0;
4 | padding-bottom: 1.34375em; // spacing for mat-error
5 |
6 | mat-label {
7 | display: block;
8 | margin-bottom: .25em;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/libs/forms/ui-native/src/controls/input/input.component.params.ts:
--------------------------------------------------------------------------------
1 | import { DynParams } from '@myndpm/dyn-forms/core';
2 |
3 | export interface DynNatInputParams extends DynParams {
4 | type: 'email' | 'number' | 'password' | 'search' | 'tel' | 'text' | 'url';
5 | label?: string;
6 | }
7 |
--------------------------------------------------------------------------------
/apps/website/src/app/docs/interfaces/nav.interfaces.ts:
--------------------------------------------------------------------------------
1 | import { DynTree } from '@myndpm/dyn-forms/core';
2 |
3 | /**
4 | * Layout Navigation
5 | */
6 | export interface NavItem {
7 | text: string;
8 | link: string;
9 | }
10 |
11 | export type NavigationData = DynTree;
12 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/components/section-badges/section-badges.component.html:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/controls/select/select.component.params.ts:
--------------------------------------------------------------------------------
1 | import { DynParams, DynOption } from '@myndpm/dyn-forms/core';
2 |
3 | export interface DynBsSelectParams extends DynParams {
4 | label?: string;
5 | options: DynOption[];
6 | hint?: string;
7 | size?: 'large' | 'small';
8 | }
9 |
--------------------------------------------------------------------------------
/libs/plugin/src/executors/deploy-docker/executor.ts:
--------------------------------------------------------------------------------
1 | import { DeployDockerExecutorSchema } from './schema';
2 |
3 | export default async function runExecutor(options: DeployDockerExecutorSchema) {
4 | console.log('Executor ran for DeployDocker', options);
5 | return {
6 | success: true,
7 | };
8 | }
9 |
--------------------------------------------------------------------------------
/libs/plugin/src/executors/deploy-docker/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "outputCapture": "direct-nodejs",
4 | "$schema": "http://json-schema.org/schema",
5 | "title": "DeployDocker executor",
6 | "description": "",
7 | "type": "object",
8 | "properties": {},
9 | "required": []
10 | }
11 |
--------------------------------------------------------------------------------
/libs/forms/lib/schematics/control/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.params.ts.template:
--------------------------------------------------------------------------------
1 | import { DynParams } from '@myndpm/dyn-forms/core';
2 |
3 | export interface <%= prefixInterface %><%= prefixClass ? classify(prefix) : '' %><%= classify(name) %>Params extends DynParams {
4 | }
5 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | max_line_length = off
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/datepicker/datepicker.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 |
4 | .mat-input-element {
5 | line-height: 1.2em;
6 | }
7 |
8 | &.readonly {
9 | mat-datepicker-toggle,
10 | mat-datepicker,
11 | input {
12 | display: none;
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tools/tsconfig.tools.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.base.json",
3 | "compilerOptions": {
4 | "outDir": "../dist/out-tsc/tools",
5 | "rootDir": ".",
6 | "module": "commonjs",
7 | "target": "es5",
8 | "types": ["node"],
9 | "importHelpers": false
10 | },
11 | "include": ["**/*.ts"]
12 | }
13 |
--------------------------------------------------------------------------------
/libs/demos/tsconfig.lib.prod.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.lib.json",
3 | "compilerOptions": {
4 | "declarationMap": false,
5 | "noUnusedLocals": true,
6 | "target": "ES2022",
7 | "useDefineForClassFields": false
8 | },
9 | "angularCompilerOptions": {
10 | "compilationMode": "partial"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/controls/checkbox/checkbox.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ params.hint }}
6 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/multicheckbox/multicheckbox.component.html:
--------------------------------------------------------------------------------
1 | {{ params.label }}
2 |
3 |
4 |
5 | {{ option.value }}
6 |
7 |
8 |
--------------------------------------------------------------------------------
/libs/plugin/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "module": "commonjs",
5 | "outDir": "../../dist/out-tsc",
6 | "declaration": true,
7 | "types": ["node"]
8 | },
9 | "exclude": ["**/*.spec.ts", "**/*.test.ts", "jest.config.ts"],
10 | "include": ["**/*.ts"]
11 | }
12 |
--------------------------------------------------------------------------------
/libs/utils/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "module": "commonjs",
5 | "outDir": "../../dist/out-tsc",
6 | "declaration": true,
7 | "types": ["node"]
8 | },
9 | "exclude": ["**/*.spec.ts", "**/*.test.ts", "jest.config.ts"],
10 | "include": ["**/*.ts"]
11 | }
12 |
--------------------------------------------------------------------------------
/libs/plugin/generators.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "name": "nx",
4 | "version": "0.0.1",
5 | "generators": {
6 | "nx": {
7 | "factory": "./src/generators/nx/generator",
8 | "schema": "./src/generators/nx/schema.json",
9 | "description": "nx generator"
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/apps/website/src/main.server.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { environment } from './environments/environment';
3 |
4 | if (environment.production) {
5 | enableProdMode();
6 | }
7 |
8 | export { AppServerModule } from './app/app.server.module';
9 | export { renderModuleFactory } from '@angular/platform-server';
10 |
--------------------------------------------------------------------------------
/apps/website/src/app/pages/components/not-found/not-found.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Not Found
4 |
5 |
The requested URL was not found.
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/libs/forms/tsconfig.schematics.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.schematics.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/libs/forms",
5 | "rootDir": "."
6 | },
7 | "exclude": [
8 | "lib/schematics/*/files/**/*"
9 | ],
10 | "include": [
11 | "lib/migrations/**/*",
12 | "lib/schematics/**/*"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/libs/forms/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "target": "es2016",
7 | "types": ["jest", "node"]
8 | },
9 | "files": ["index.tests.ts"],
10 | "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts", "jest.config.ts"]
11 | }
12 |
--------------------------------------------------------------------------------
/apps/website/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "target": "es2016",
7 | "types": ["jest", "node"]
8 | },
9 | "files": ["src/test-setup.ts"],
10 | "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts", "jest.config.ts"]
11 | }
12 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/components/section-actions/section-actions.component.scss:
--------------------------------------------------------------------------------
1 | .section-actions {
2 | display: block;
3 | position: absolute;
4 | top: 16px;
5 | right: 8px;
6 |
7 | @media (min-width: 576px) {
8 | top: 32px;
9 | }
10 |
11 | a {
12 | color: #0a253a;
13 | }
14 |
15 | ion-icon {
16 | font-size: 24px;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/apps/website/src/app/pages/components/not-found/not-found.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | display: flex;
3 | padding: 120px 0;
4 |
5 | .container {
6 | text-align: center;
7 | }
8 |
9 | h2 {
10 | color: #0A253A;
11 | font-size: 40px;
12 | font-weight: 700;
13 | margin-top: 60px;
14 | }
15 |
16 | p {
17 | font-size: 18px;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/libs/forms/tsconfig.lib.prod.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.lib.json",
3 | "compilerOptions": {
4 | "declarationMap": false,
5 | "noUnusedLocals": true,
6 | "target": "ES2022",
7 | "useDefineForClassFields": false
8 | },
9 | "angularCompilerOptions": {
10 | "compilationMode": "partial"
11 | },
12 | "exclude": ["jest.config.ts"]
13 | }
14 |
--------------------------------------------------------------------------------
/apps/website/src/app/docs/services/i18n.service.ts:
--------------------------------------------------------------------------------
1 | import { Inject, Injectable, LOCALE_ID } from '@angular/core';
2 |
3 | @Injectable({
4 | providedIn: 'root'
5 | })
6 | export class I18nService {
7 | get lang(): string {
8 | return this.locale?.slice(0, 2) ?? 'en';
9 | }
10 |
11 | constructor(
12 | @Inject(LOCALE_ID) private locale: string,
13 | ) {}
14 | }
15 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/components/footer/footer.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-layout-footer',
5 | templateUrl: './footer.component.html',
6 | styleUrls: ['./footer.component.scss'],
7 | changeDetection: ChangeDetectionStrategy.OnPush
8 | })
9 | export class FooterComponent {}
10 |
--------------------------------------------------------------------------------
/libs/forms/core/src/types/events.types.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * callHook contract
3 | */
4 | export interface DynHook {
5 | hook: string;
6 | payload?: any;
7 | plain?: boolean; // propagate the payload without modifications
8 | }
9 |
10 | /**
11 | * hook parameters
12 | */
13 | export interface DynHookUpdateValidity {
14 | onlySelf?: boolean;
15 | emitEvent?: boolean;
16 | }
17 |
--------------------------------------------------------------------------------
/apps/website/src/app/pages/components/homepage/homepage.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-homepage',
5 | templateUrl: './homepage.component.html',
6 | styleUrls: ['./homepage.component.scss'],
7 | changeDetection: ChangeDetectionStrategy.OnPush
8 | })
9 | export class HomepageComponent {}
10 |
--------------------------------------------------------------------------------
/libs/utils/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4 |
5 | ## [0.1.4](https://github.com/myndpm/open-source/compare/@myndpm/utils@0.1.3...@myndpm/utils@0.1.4) (2022-10-28)
6 |
7 |
8 |
9 | ## [0.1.3](https://github.com/myndpm/open-source/compare/@myndpm/utils@0.1.2...@myndpm/utils@0.1.3) (2022-10-12)
10 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/containers/wrapper/wrapper.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-layout-wrapper',
5 | templateUrl: './wrapper.component.html',
6 | styleUrls: ['./wrapper.component.scss'],
7 | changeDetection: ChangeDetectionStrategy.OnPush
8 | })
9 | export class LayoutWrapperComponent {}
10 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/datepicker/datepicker.component.params.ts:
--------------------------------------------------------------------------------
1 | import { DynNode } from '@myndpm/dyn-forms/core';
2 | import { DynMatFormFieldParams } from '../../wrappers';
3 |
4 | export interface DynMatDatepickerParams extends Partial {
5 | placeholder: string;
6 | readonly?: boolean;
7 | // paramFns
8 | getValue?: (node: DynNode) => string;
9 | }
10 |
--------------------------------------------------------------------------------
/apps/website/src/app/docs/components/stackblitz/stackblitz.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-docs-stackblitz',
5 | templateUrl: './stackblitz.component.html',
6 | styleUrls: ['./stackblitz.component.scss'],
7 | changeDetection: ChangeDetectionStrategy.OnPush
8 | })
9 | export class StackblitzComponent {}
10 |
--------------------------------------------------------------------------------
/libs/plugin/src/executors/deploy-docker/executor.spec.ts:
--------------------------------------------------------------------------------
1 | import { DeployDockerExecutorSchema } from './schema';
2 | import executor from './executor';
3 |
4 | const options: DeployDockerExecutorSchema = {};
5 |
6 | describe('DeployDocker Executor', () => {
7 | it('can run', async () => {
8 | const output = await executor(options);
9 | expect(output.success).toBe(true);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/apps/website/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.app.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | },
12 | {
13 | "path": "./tsconfig.editor.json"
14 | }
15 | ],
16 | "compilerOptions": {
17 | "target": "es2020"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/libs/plugin/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "overrides": [
5 | {
6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7 | "rules": {}
8 | },
9 | {
10 | "files": ["*.ts", "*.tsx"],
11 | "rules": {}
12 | },
13 | {
14 | "files": ["*.js", "*.jsx"],
15 | "rules": {}
16 | }
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/libs/utils/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "overrides": [
5 | {
6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7 | "rules": {}
8 | },
9 | {
10 | "files": ["*.ts", "*.tsx"],
11 | "rules": {}
12 | },
13 | {
14 | "files": ["*.js", "*.jsx"],
15 | "rules": {}
16 | }
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/controls/input/input.component.params.ts:
--------------------------------------------------------------------------------
1 | import { DynParams } from '@myndpm/dyn-forms/core';
2 |
3 | export interface DynBsInputParams extends DynParams {
4 | type: 'color' | 'email' | 'number' | 'password' | 'search' | 'tel' | 'text' | 'url' | 'textarea';
5 | label?: string;
6 | placeholder?: string;
7 | rows?: number;
8 | hint?: string;
9 | size?: 'large' | 'small';
10 | }
11 |
--------------------------------------------------------------------------------
/apps/website/tsconfig.server.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.app.json",
3 | "compilerOptions": {
4 | "outDir": "../../out-tsc/server",
5 | "target": "ES2022",
6 | "types": ["node"],
7 | "useDefineForClassFields": false
8 | },
9 | "files": ["src/main.server.ts", "server.ts"],
10 | "angularCompilerOptions": {
11 | "entryModule": "./src/app/app.server.module#AppServerModule"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/controls/radio/radio.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/stepper/summary/summary.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-form-stepper-summary',
5 | templateUrl: './summary.component.html',
6 | styleUrls: ['./summary.component.scss'],
7 | changeDetection: ChangeDetectionStrategy.OnPush,
8 | })
9 | export class StepperSummaryComponent {}
10 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/containers/wrapper/wrapper.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | display: flex;
3 | flex-direction: column;
4 | height: 100%;
5 |
6 | div {
7 | flex: 1;
8 |
9 | ::ng-deep {
10 | section {
11 | padding: 24px 0;
12 | position: relative;
13 |
14 | @media (min-width: 576px) {
15 | padding: 42px 0;
16 | }
17 | }
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/ui-package.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: UI Package
3 | about: Add or Extend UI controls
4 | title: ''
5 | labels: 'enhancement'
6 | assignees: ''
7 | ---
8 |
9 | ## Which UI Framework do you want?
10 |
11 | Framework name, links to its documentation and demos of its controls.
12 |
13 | ## Describe the controls we could support
14 |
15 | Please describe the Controls and the Parameters we could need to support for them.
16 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/components/index/index.component.scss:
--------------------------------------------------------------------------------
1 | .col {
2 | img {
3 | box-shadow: 2px 2px 4px 1px rgba(0, 0, 0, 0.2);
4 | }
5 |
6 | .col-body {
7 | position: relative;
8 | text-align: center; // FIXME restore if we add images per demo
9 |
10 | h2 a {
11 | text-decoration: none;
12 | }
13 |
14 | p {
15 | font-size: 14px;
16 | line-height: 24px;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/apps/website/src/app/pages/components/docs/docs.component.scss:
--------------------------------------------------------------------------------
1 | .col {
2 | img {
3 | box-shadow: 2px 2px 4px 1px rgba(0, 0, 0, 0.2);
4 | }
5 |
6 | .col-body {
7 | position: relative;
8 | text-align: center; // FIXME restore if we add images per demo
9 |
10 | h2 a {
11 | text-decoration: none;
12 | }
13 |
14 | p {
15 | font-size: 14px;
16 | line-height: 24px;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/controls/index.ts:
--------------------------------------------------------------------------------
1 | export * from './checkbox/checkbox.component';
2 | export * from './checkbox/checkbox.component.params';
3 | export * from './input/input.component';
4 | export * from './input/input.component.params';
5 | export * from './radio/radio.component';
6 | export * from './radio/radio.component.params';
7 | export * from './select/select.component';
8 | export * from './select/select.component.params';
9 |
--------------------------------------------------------------------------------
/libs/forms/core/src/hidden/control.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component } from '@angular/core';
2 | import { DynFormControl } from '../dyn-form-control.class';
3 |
4 | @Component({
5 | selector: 'dyn-hidden-control',
6 | template: '',
7 | changeDetection: ChangeDetectionStrategy.OnPush,
8 | })
9 | export class DynHiddenControlComponent extends DynFormControl {
10 | static dynControl: 'HIDDEN' = 'HIDDEN';
11 | }
12 |
--------------------------------------------------------------------------------
/libs/forms/core/src/hidden/group.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component } from '@angular/core';
2 | import { DynFormGroup } from '../dyn-form-group.class';
3 |
4 | @Component({
5 | selector: 'dyn-hidden-group',
6 | template: '',
7 | changeDetection: ChangeDetectionStrategy.OnPush,
8 | })
9 | export class DynHiddenGroupComponent extends DynFormGroup {
10 | static dynControl: 'HIDDEN-GROUP' = 'HIDDEN-GROUP';
11 | }
12 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/stepper/step1/step1.component.html:
--------------------------------------------------------------------------------
1 | Personal Information
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/stepper/summary/summary.component.html:
--------------------------------------------------------------------------------
1 | Summary
2 |
3 |
4 |
5 |
6 |
Filled information:
7 |
8 |
{{ dyn.control.value | json }}
9 |
10 |
11 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/apps/website/src/app/docs/components/content/content.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 |
4 | .content-wrapper {
5 | padding: 1em;
6 |
7 | ::ng-deep {
8 |
9 | > .mat-tab-group {
10 |
11 | > .mat-tab-header {
12 | margin-bottom: 24px;
13 |
14 | .mat-tab-label-content {
15 | text-transform: uppercase;
16 | }
17 | }
18 | }
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/components/section-actions/section-actions.component.html:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/libs/forms/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/libs/forms",
4 | "lib": {
5 | "entryFile": "index.ts"
6 | },
7 | "assets": [
8 | "migrations.json",
9 | "schematics.json"
10 | ],
11 | "deleteDestPath": true,
12 | "allowedNonPeerDependencies": [
13 | "fast-deep-equal",
14 | "is-callable",
15 | "merge",
16 | "ramda"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/single/success.control/success.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Thank you!
4 | You are now subscribed
5 |
6 |
7 |
8 |
9 | You will receive our emails to {{ control.value }}
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/libs/plugin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@myndpm/nx",
3 | "version": "0.2.7",
4 | "description": "Plugin for Nx by Mynd",
5 | "repository": {
6 | "type": "git",
7 | "url": "git@github.com:myndpm/open-source.git",
8 | "directory": "libs/plugin"
9 | },
10 | "main": "src/index.js",
11 | "generators": "./generators.json",
12 | "executors": "./executors.json",
13 | "dependencies": {
14 | "@myndpm/utils": "*"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/libs/utils/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.lib.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | }
12 | ],
13 | "compilerOptions": {
14 | "forceConsistentCasingInFileNames": true,
15 | "strict": true,
16 | "noImplicitReturns": true,
17 | "noFallthroughCasesInSwitch": true
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/components/prompt/prompt.dialog.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/libs/forms/core/src/utils/hidden.util.ts:
--------------------------------------------------------------------------------
1 | import { DynControlConfig } from '../types/control.types';
2 |
3 | export function isDynHidden(control: string | DynControlConfig): boolean {
4 | const id: string = typeof control !== 'string'
5 | ? control.control
6 | : control;
7 | return id === 'HIDDEN' || id === 'HIDDEN-GROUP';
8 | }
9 |
10 | export function isNotDynHidden(control: string | DynControlConfig): boolean {
11 | return !isDynHidden(control);
12 | }
13 |
--------------------------------------------------------------------------------
/apps/website/src/app/docs/interfaces/metadata.interfaces.ts:
--------------------------------------------------------------------------------
1 | export type DocsLocalized = { [lang: string]: string };
2 |
3 | /**
4 | * Documentation JSON index
5 | */
6 |
7 | export interface DocsIndex {
8 | [url: string]: DocsMetadata;
9 | }
10 |
11 | export interface DocsMetadata {
12 | title: DocsLocalized;
13 | content?: DocsLocalized; // README[.lang].md
14 | examples?: string[]; // example IDs
15 | redirectTo?: string;
16 | sourceLink?: string;
17 | }
18 |
--------------------------------------------------------------------------------
/libs/forms/index.tests.ts:
--------------------------------------------------------------------------------
1 | import 'jest-preset-angular';
2 |
3 | import { getTestBed } from '@angular/core/testing';
4 | import {
5 | BrowserDynamicTestingModule,
6 | platformBrowserDynamicTesting,
7 | } from '@angular/platform-browser-dynamic/testing';
8 |
9 | getTestBed().resetTestEnvironment();
10 | getTestBed().initTestEnvironment(
11 | BrowserDynamicTestingModule,
12 | platformBrowserDynamicTesting(),
13 | { teardown: { destroyAfterEach: false } }
14 | );
15 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/checkbox/checkbox.component.params.ts:
--------------------------------------------------------------------------------
1 | import { ThemePalette } from '@angular/material/core';
2 | import { DynNode, DynParams } from '@myndpm/dyn-forms/core';
3 |
4 | export interface DynMatCheckboxParams extends DynParams {
5 | label: string;
6 | labelPosition: 'before' | 'after';
7 | color?: ThemePalette;
8 | indeterminate?: boolean;
9 | readonly?: boolean;
10 | // paramFns
11 | getValue?: (node: DynNode) => string;
12 | }
13 |
--------------------------------------------------------------------------------
/libs/utils/jest.config.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | export default {
3 | displayName: 'utils',
4 | preset: '../../jest.preset.js',
5 | globals: {},
6 | testEnvironment: 'node',
7 | transform: {
8 | '^.+\\.[tj]sx?$': [
9 | 'ts-jest',
10 | {
11 | tsconfig: '/tsconfig.spec.json',
12 | },
13 | ],
14 | },
15 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
16 | coverageDirectory: '../../coverage/libs/tools/utils',
17 | };
18 |
--------------------------------------------------------------------------------
/libs/forms/core/src/types/utils/option.types.ts:
--------------------------------------------------------------------------------
1 | import { DynTree } from './tree.types';
2 |
3 | // map that could be converted with KeyValue pipe
4 | export type DynOptionsMap = Map;
5 |
6 | // generic type for selectors/radios/etc
7 | export interface DynOption {
8 | key: T;
9 | value: string;
10 | disabled?: boolean;
11 | [field: string]: any;
12 | }
13 |
14 | // tree of options
15 | export type DynOptionTree = DynTree>;
16 |
--------------------------------------------------------------------------------
/apps/website/src/test-setup.ts:
--------------------------------------------------------------------------------
1 | import 'jest-preset-angular/setup-jest';
2 |
3 | import { getTestBed } from '@angular/core/testing';
4 | import {
5 | BrowserDynamicTestingModule,
6 | platformBrowserDynamicTesting,
7 | } from '@angular/platform-browser-dynamic/testing';
8 |
9 | getTestBed().resetTestEnvironment();
10 | getTestBed().initTestEnvironment(
11 | BrowserDynamicTestingModule,
12 | platformBrowserDynamicTesting(),
13 | { teardown: { destroyAfterEach: false } }
14 | );
15 |
--------------------------------------------------------------------------------
/libs/forms/logger/src/log.interface.ts:
--------------------------------------------------------------------------------
1 | import { DynLogLevel } from './log-levels.constant';
2 |
3 | export interface DynLog {
4 | /**
5 | * Indent level.
6 | */
7 | readonly deep?: number;
8 | /**
9 | * Level of severity.
10 | */
11 | readonly level: DynLogLevel;
12 | /**
13 | * Log message describing an event.
14 | */
15 | readonly message: string;
16 | /**
17 | * Optional payload related to the event.
18 | */
19 | readonly payload?: any;
20 | }
21 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/array/array.component.params.ts:
--------------------------------------------------------------------------------
1 | import { ThemePalette } from '@angular/material/core';
2 | import { DynParams } from '@myndpm/dyn-forms/core';
3 |
4 | export interface DynMatArrayParams extends DynParams {
5 | title?: string;
6 | subtitle?: string;
7 | avatar?: string;
8 | initItem?: boolean;
9 | addButton?: string;
10 | addColor?: ThemePalette;
11 | removeIcon?: string;
12 | removeColor?: ThemePalette;
13 | readonly?: boolean;
14 | }
15 |
--------------------------------------------------------------------------------
/libs/plugin/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "include": [
9 | "**/*.test.ts",
10 | "**/*.spec.ts",
11 | "**/*.test.tsx",
12 | "**/*.spec.tsx",
13 | "**/*.test.js",
14 | "**/*.spec.js",
15 | "**/*.test.jsx",
16 | "**/*.spec.jsx",
17 | "**/*.d.ts",
18 | "jest.config.ts"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/libs/utils/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "include": [
9 | "**/*.test.ts",
10 | "**/*.spec.ts",
11 | "**/*.test.tsx",
12 | "**/*.spec.tsx",
13 | "**/*.test.js",
14 | "**/*.spec.js",
15 | "**/*.test.jsx",
16 | "**/*.spec.jsx",
17 | "**/*.d.ts",
18 | "jest.config.ts"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/stepper/step1/step1.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component } from '@angular/core';
2 | import { step1Form } from '../stepper.form';
3 |
4 | @Component({
5 | selector: 'app-form-stepper-step1',
6 | templateUrl: './step1.component.html',
7 | styleUrls: ['./step1.component.scss'],
8 | changeDetection: ChangeDetectionStrategy.OnPush,
9 | })
10 | export class StepperStep1Component {
11 | config = step1Form();
12 | }
13 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/stepper/step2/step2.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component } from '@angular/core';
2 | import { step2Form } from '../stepper.form';
3 |
4 | @Component({
5 | selector: 'app-form-stepper-step2',
6 | templateUrl: './step2.component.html',
7 | styleUrls: ['./step2.component.scss'],
8 | changeDetection: ChangeDetectionStrategy.OnPush,
9 | })
10 | export class StepperStep2Component {
11 | config = step2Form();
12 | }
13 |
--------------------------------------------------------------------------------
/libs/forms/lib/components/form/form.config.ts:
--------------------------------------------------------------------------------
1 | import {
2 | DynBaseConfig,
3 | DynConfig,
4 | DynFormConfigErrors,
5 | DynMode,
6 | DynModes,
7 | } from '@myndpm/dyn-forms/core';
8 |
9 | // typed config with any set of supported modes
10 | export interface DynFormConfig<
11 | M extends DynMode = DynMode,
12 | > extends DynFormConfigErrors {
13 | controls: Array | DynConfig>;
14 | modes?: DynModes; // default partial configs per mode
15 | debug?: number;
16 | }
17 |
--------------------------------------------------------------------------------
/apps/website/src/app/app.server.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { FlexLayoutServerModule } from '@angular/flex-layout/server';
3 | import { ServerModule } from '@angular/platform-server';
4 |
5 | import { AppModule } from './app.module';
6 | import { AppComponent } from './app.component';
7 |
8 | @NgModule({
9 | imports: [
10 | AppModule,
11 | ServerModule,
12 | FlexLayoutServerModule,
13 | ],
14 | bootstrap: [AppComponent],
15 | })
16 | export class AppServerModule {}
17 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/controls/select/select.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 | {{ params.hint }}
15 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/wrappers/form-field/form-field.component.params.ts:
--------------------------------------------------------------------------------
1 | import { LegacyFloatLabelType as FloatLabelType } from '@angular/material/legacy-form-field';
2 |
3 | export interface DynMatFormFieldParams {
4 | floatLabel?: FloatLabelType; // readonly mode uses 'always' floating label
5 | hideRequiredMarker?: boolean;
6 | readonly?: boolean;
7 | label?: string;
8 | hint?: string;
9 | hintEnd?: string;
10 | iconPrefix?: string;
11 | iconSuffix?: string;
12 | textSuffix?: string;
13 | }
14 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/stepper/step2/step2.component.html:
--------------------------------------------------------------------------------
1 | Traveler Information
2 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/apps/website/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | document.addEventListener('DOMContentLoaded', () => {
12 | platformBrowserDynamic()
13 | .bootstrapModule(AppModule)
14 | .catch((err) => console.error(err));
15 | });
16 |
--------------------------------------------------------------------------------
/libs/forms/core/src/utils/config.utils.ts:
--------------------------------------------------------------------------------
1 | import { DynConfigWrapper, DynWrapperId } from '../types/wrapper.types';
2 |
3 | /**
4 | * DynWrapperId extract util
5 | */
6 | export function getWrapperId(config: DynConfigWrapper): DynWrapperId {
7 | return typeof config !== 'string' ? config.wrapper : config;
8 | }
9 |
10 | /**
11 | * Coerce boolean value
12 | */
13 | export function coerceBoolean(value: any): boolean {
14 | const falsy = /^(?:f(?:alse)?|no?|0+)$/i;
15 | return !falsy.test(value) && !!value;
16 | }
17 |
--------------------------------------------------------------------------------
/libs/forms/migrations.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../@angular-devkit/schematics/collection-schema.json",
3 | "schematics": {
4 | "myndpm-forms-01": {
5 | "description": "Refactoring before the first official release",
6 | "version": "12.4.1",
7 | "factory": "./lib/migrations/12_4_1/index"
8 | },
9 | "myndpm-forms-02": {
10 | "description": "DynFactory from component to directive",
11 | "version": "12.6.1",
12 | "factory": "./lib/migrations/12_6_1/index"
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/radio/radio.component.html:
--------------------------------------------------------------------------------
1 | {{ params.label }}
2 |
3 |
4 |
9 | {{ option.value }}
10 |
11 |
12 |
13 |
14 | {{ (params.getValue ? params.getValue(node) : control.value) || '-' }}
15 |
16 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/radio/radio.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | margin: .25em 0;
4 | padding-bottom: 1.34375em; // spacing for mat-error
5 |
6 | mat-label {
7 | display: block;
8 | margin-bottom: .5em;
9 | }
10 |
11 | .mat-radio-button {
12 | margin-right: 1em;
13 | }
14 |
15 | &.readonly {
16 | .mat-radio-group {
17 | display: none;
18 | }
19 |
20 | span {
21 | display: block;
22 | padding: 1.4em 0 0.74625em;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/libs/plugin/jest.config.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | export default {
3 | displayName: 'nx',
4 | preset: '../../jest.preset.js',
5 | globals: {},
6 | testEnvironment: 'node',
7 | transform: {
8 | '^.+\\.[tj]sx?$': [
9 | 'ts-jest',
10 | {
11 | tsconfig: '/tsconfig.spec.json',
12 | },
13 | ],
14 | },
15 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
16 | coverageDirectory: '../../coverage/libs/nx',
17 | coverageReporters: [['lcov', { projectRoot: 'libs/nx' }]],
18 | };
19 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/components/section-badges/section-badges.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
2 | import { SectionBadge } from './section-badge.interface';
3 |
4 | @Component({
5 | selector: 'app-section-badges',
6 | templateUrl: './section-badges.component.html',
7 | styleUrls: ['./section-badges.component.scss'],
8 | changeDetection: ChangeDetectionStrategy.OnPush
9 | })
10 | export class SectionBadgesComponent {
11 | @Input() badges: SectionBadge[] = [];
12 | }
13 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/datepicker/datepicker.component.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | {{ (params.getValue ? params.getValue(node) : control.value) || '-' }}
14 |
15 |
--------------------------------------------------------------------------------
/libs/forms/core/src/utils/rxjs.utils.ts:
--------------------------------------------------------------------------------
1 | import { Observable, Subject } from 'rxjs';
2 |
3 | export function onComplete(
4 | observable: Observable,
5 | next?: (value: T) => void,
6 | error?: (error: any) => void,
7 | complete?: () => void,
8 | ): Observable {
9 | const observe = new Subject();
10 |
11 | observable.subscribe(
12 | next,
13 | error,
14 | () => {
15 | complete?.();
16 | observe.next();
17 | observe.complete();
18 | },
19 | );
20 |
21 | return observe;
22 | }
23 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/components/section-actions/section-actions.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
2 | import { SectionAction } from './section-action.interface';
3 |
4 | @Component({
5 | selector: 'app-section-actions',
6 | templateUrl: './section-actions.component.html',
7 | styleUrls: ['./section-actions.component.scss'],
8 | changeDetection: ChangeDetectionStrategy.OnPush
9 | })
10 | export class SectionActionsComponent {
11 | @Input() actions: SectionAction[] = [];
12 | }
13 |
--------------------------------------------------------------------------------
/libs/forms/core/src/types/mode.types.ts:
--------------------------------------------------------------------------------
1 | import { DynControlConfig } from './control.types';
2 |
3 | // display, edit, filter, etc
4 | export type DynMode = string; // Mode ID
5 |
6 | // config overrides per mode, handled by DynFormResolver
7 | export type DynModes = {
8 | [K in TMode]?: Partial;
9 | }
10 |
11 | /**
12 | * @deprecated use DynMode
13 | */
14 | export type DynControlMode = DynMode;
15 |
16 | /**
17 | * @deprecated use DynModes
18 | */
19 | export type DynControlModes = DynModes;
20 |
--------------------------------------------------------------------------------
/DEVELOPMENT.md:
--------------------------------------------------------------------------------
1 | # Development
2 |
3 | ## Considerations
4 |
5 | The `postinstall` script builds the `util` and `plugin` packages to setup the workspace from the `dist` folder.
6 | The compiled packages and their dependencies are available from /node_modules and consumed by the monorepo.
7 |
8 | To be able to run the website, build the demo package first with `yarn build`.
9 |
10 | ## Publishing to npm
11 |
12 | With GitHub Actions, there's a `release` workflow which needs to be manually triggered
13 | to publish the latest changes in the packages to NPM.
14 |
--------------------------------------------------------------------------------
/libs/utils/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@myndpm/utils",
3 | "version": "0.1.4",
4 | "repository": {
5 | "type": "git",
6 | "url": "git@github.com:myndpm/open-source.git",
7 | "directory": "libs/utils"
8 | },
9 | "dependencies": {
10 | "@ckapp/rxjs-node-fs": "^0.6.1",
11 | "chalk": "^4.0.0",
12 | "cross-spawn": "^7.0.3",
13 | "rxjs": "7.8.1",
14 | "rxjs-shell": "~3.1.3",
15 | "tslib": "^2.3.0"
16 | },
17 | "devDependencies": {
18 | "@types/cross-spawn": "^6.0.2"
19 | },
20 | "sideEffects": false
21 | }
22 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/components/header/header.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-layout-header',
5 | templateUrl: './header.component.html',
6 | styleUrls: ['./header.component.scss'],
7 | changeDetection: ChangeDetectionStrategy.OnPush
8 | })
9 | export class HeaderComponent {
10 | menu = [
11 | {
12 | title: 'Docs',
13 | link: '/docs/dyn-forms',
14 | },
15 | {
16 | title: 'Demos',
17 | link: '/demos',
18 | },
19 | ];
20 | }
21 |
--------------------------------------------------------------------------------
/libs/demos/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "target": "ES2022",
6 | "declaration": true,
7 | "declarationMap": true,
8 | "inlineSources": true,
9 | "lib": ["dom", "es2018"],
10 | "types": [],
11 | "useDefineForClassFields": false
12 | },
13 | "angularCompilerOptions": {
14 | "skipTemplateCodegen": true,
15 | "strictMetadataEmit": true,
16 | "enableResourceInlining": true
17 | },
18 | "exclude": [],
19 | "include": ["**/*.ts"]
20 | }
21 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/simple/simple.component.scss:
--------------------------------------------------------------------------------
1 | app-form-simple {
2 | .mat-card {
3 | margin-bottom: 0.5em;
4 | }
5 |
6 | .mat-radio-group {
7 | display: block;
8 | // equalize to mat-form-field(outline)
9 | padding: 1.4em 0 0.74625em;
10 | }
11 |
12 | .array-item {
13 | position: relative;
14 |
15 | // let the row to use 100%
16 | button {
17 | position: absolute;
18 | right: 0;
19 | top: 8px;
20 | }
21 | }
22 |
23 | .form-actions {
24 | margin-top: 1em;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/apps/website/src/app/pages/components/docs/docs.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
11 |
{{ item.description }}
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/select/select.component.html:
--------------------------------------------------------------------------------
1 |
9 |
10 | {{ option.value }}
11 |
12 |
13 |
14 |
15 | {{ (params.getValue ? params.getValue(node) : control.value) || '-' }}
16 |
17 |
--------------------------------------------------------------------------------
/apps/website/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "es2020",
6 | "target": "ES2022",
7 | "useDefineForClassFields": false,
8 | "types": []
9 | },
10 | "angularCompilerOptions": {
11 | "fullTemplateTypeCheck": true,
12 | "strictInjectionParameters": true,
13 | "strictInputAccessModifiers": true,
14 | "strictTemplates": true
15 | },
16 | "files": ["src/main.ts", "src/polyfills.ts"],
17 | "exclude": ["**/*.spec.ts", "**/*.test.ts", "jest.config.ts"]
18 | }
19 |
--------------------------------------------------------------------------------
/libs/forms/schematics.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../@angular-devkit/schematics/collection-schema.json",
3 | "schematics": {
4 | "module": {
5 | "description": "Create a DynControls Module",
6 | "factory": "./lib/schematics/module/index",
7 | "schema": "./lib/schematics/module/schema.json",
8 | "aliases": ["m"]
9 | },
10 | "control": {
11 | "description": "Create a DynControl",
12 | "factory": "./lib/schematics/control/index",
13 | "schema": "./lib/schematics/control/schema.json",
14 | "aliases": ["c"]
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/array/array.component.scss:
--------------------------------------------------------------------------------
1 | // fix left-margin of .mat-card-header-text when there's no card-avatar
2 | mat-card-header ::ng-deep > :first-child {
3 | margin-left: 0;
4 | }
5 |
6 | .array-item {
7 | display: flex;
8 | flex-direction: row;
9 | place-content: center space-between;
10 | align-items: center;
11 |
12 | dyn-group {
13 | display: flex;
14 | flex: 1;
15 | }
16 |
17 | .mat-icon-button {
18 | margin-bottom: 20px;
19 | }
20 | }
21 |
22 | :host {
23 | &.readonly button {
24 | visibility: hidden;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/card/card.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ params.title }}
5 | {{ params.subtitle }}
6 |
7 |
8 |
9 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/components/index/index.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
11 |
{{ item.description }}
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/libs/demos/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@myndpm/demos",
3 | "version": "0.0.1",
4 | "description": "Mynd Components Examples",
5 | "keywords": [
6 | "angular",
7 | "demos"
8 | ],
9 | "license": "MIT",
10 | "homepage": "https://mynd.netlify.app/",
11 | "repository": {
12 | "type": "git",
13 | "url": "git@github.com:myndpm/open-source.git",
14 | "directory": "libs/demos"
15 | },
16 | "peerDependencies": {
17 | "@angular/common": ">=16.0.0",
18 | "@angular/core": ">=16.0.0"
19 | },
20 | "dependencies": {
21 | "tslib": "^2.0.0"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/libs/demos/dyn-forms/basic/intro/app.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component } from "@angular/core";
2 | import { FormGroup } from "@angular/forms";
3 | import { formConfig } from "./form.config";
4 |
5 | @Component({
6 | selector: "dyn-forms-basic",
7 | templateUrl: "./app.component.html",
8 | styleUrls: ["./app.component.scss"],
9 | changeDetection: ChangeDetectionStrategy.OnPush,
10 | })
11 | export class DynFormsBasicComponent {
12 | form = new FormGroup({});
13 | config = formConfig();
14 |
15 | doSubmit(): void {
16 | console.log(this.form.value);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/table/table.component.params.ts:
--------------------------------------------------------------------------------
1 | import { Observable } from 'rxjs';
2 |
3 | export interface DynMatTableParams {
4 | headers: string[];
5 | trackBy: string;
6 | title?: string;
7 | addNewButtonText?: string;
8 | emptyText?: string;
9 | disableRemove?: boolean;
10 | confirmDelete?: (payload: any) => Observable;
11 | }
12 |
13 | /**
14 | * Hooks
15 | */
16 |
17 | export interface DynMatTableAddItemHook {
18 | userAction?: boolean;
19 | }
20 |
21 | export interface DynMatTableRemoveItemHook {
22 | index: number;
23 | doConfirm?: boolean;
24 | }
25 |
--------------------------------------------------------------------------------
/apps/website/src/assets/logos/fb.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/builder/builder.component.scss:
--------------------------------------------------------------------------------
1 | app-form-builder {
2 | dyn-form,
3 | dyn-group {
4 | display: flex;
5 | flex-wrap: wrap;
6 |
7 | .dyn-control {
8 | flex: 45%;
9 | margin-right: 5%;
10 |
11 | &.dyn-control-agentShowing,
12 | &.dyn-control-codeBox,
13 | &.dyn-control-smartLock {
14 | flex: 100%;
15 | margin-right: 0;
16 | }
17 | }
18 | }
19 |
20 | .mat-checkbox {
21 | display: block;
22 | // equalize to mat-form-field(outline)
23 | padding: 1.2em 0 2.65625em;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/libs/forms/core/src/types/wrapper.types.ts:
--------------------------------------------------------------------------------
1 | import { Observable } from 'rxjs';
2 | import { DynFunctionFn, DynParams } from './params.types';
3 | import { DynConfigMap, DynConfigProvider } from './provider.types';
4 |
5 | export type DynWrapperId = string; // Wrapper ID
6 |
7 | export interface DynWrapperConfig {
8 | wrapper: DynWrapperId;
9 | params?: TParams | Observable;
10 | paramFns?: DynConfigMap>;
11 | }
12 |
13 | export type DynConfigWrapper = DynWrapperId | DynWrapperConfig;
14 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/input/input.component.params.ts:
--------------------------------------------------------------------------------
1 | import { ErrorStateMatcher } from '@angular/material/core';
2 | import { DynNode } from '@myndpm/dyn-forms/core';
3 | import { DynMatFormFieldParams } from '../../wrappers';
4 |
5 | export interface DynMatInputParams extends Partial {
6 | type: 'color' | 'email' | 'number' | 'password' | 'search' | 'tel' | 'text' | 'url' | 'textarea';
7 | placeholder: string;
8 | readonly?: boolean;
9 | rows?: number; // for textarea type
10 | errorStateMatcher: ErrorStateMatcher;
11 | // paramFns
12 | getValue?: (node: DynNode) => string;
13 | }
14 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/components/footer/footer.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | background-color: #0a253a;
3 | display: block;
4 |
5 | .container {
6 | padding-top: 48px;
7 | padding-bottom: 72px;
8 | }
9 |
10 | .footer-logo {
11 | display: block;
12 | margin-bottom: 8px;
13 | }
14 |
15 | .footer-legal {
16 | color: #84929c;
17 | font-size: 12px;
18 | line-height: 16px;
19 | }
20 |
21 | .footer-logos {
22 | a {
23 | display: inline-block;
24 | max-width: 100%;
25 |
26 | img {
27 | margin-left: 8px;
28 | margin-right: 8px;
29 | }
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/apps/website/src/app/pages/components/docs/docs.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-docs',
5 | templateUrl: './docs.component.html',
6 | styleUrls: ['./docs.component.scss'],
7 | changeDetection: ChangeDetectionStrategy.OnPush,
8 | })
9 | export class DocsIndexComponent {
10 | items = [
11 | {
12 | title: '@myndpm/dyn-forms',
13 | link: './dyn-forms',
14 | description: 'Abstract layer to easily generate Dynamic Forms for Angular with a brand-new standard opened for community contributions and feedback!',
15 | },
16 | ];
17 | }
18 |
--------------------------------------------------------------------------------
/libs/demos/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.lib.json"
8 | },
9 | {
10 | "path": "./tsconfig.lib.prod.json"
11 | }
12 | ],
13 | "compilerOptions": {
14 | "forceConsistentCasingInFileNames": true,
15 | "noImplicitReturns": true,
16 | "noFallthroughCasesInSwitch": true,
17 | "strict": true,
18 | "target": "es2020"
19 | },
20 | "angularCompilerOptions": {
21 | "strictMetadataEmit": true,
22 | "strictInjectionParameters": true,
23 | "strictTemplates": false
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/docs/dyn-forms/ui/packages/README.md:
--------------------------------------------------------------------------------
1 | # UI Packages
2 |
3 | The `ui-packages` are subpackages of `@myndpm/dyn-forms` to provide some `DynControls` based on popular UI frameworks out there. The idea is that the community helps to support their preferred tools by working together and add support to most of their features.
4 |
5 | ## Example Pull Requests
6 |
7 | - [DynModule](https://github.com/myndpm/open-source/pull/22) example implementing `ui-native`.
8 | - [DynControl](https://github.com/myndpm/open-source/pull/19) DATEPICKER example in `ui-material`.
9 | - [DynControl](https://github.com/myndpm/open-source/pull/15) MULTICKECK example in `ui-material`.
10 |
--------------------------------------------------------------------------------
/apps/website/src/app/docs/components/viewer/viewer.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | font-size: 16px;
4 |
5 | .content-wrapper {
6 | padding: 1em;
7 | }
8 |
9 | ::ng-deep {
10 | .mat-tab-label-content {
11 | text-transform: uppercase;
12 | }
13 |
14 | .mat-tab-header {
15 | margin-bottom: 24px;
16 | }
17 |
18 | h1 {
19 | font-size: 26px;
20 | }
21 | h2 {
22 | font-size: 24px;
23 | }
24 | h3 {
25 | font-size: 20px;
26 | text-align: left;
27 | &:after {
28 | display: none;
29 | }
30 | }
31 |
32 | p {
33 | font-size: 16px;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/libs/demos/dyn-forms/basic/intro/index.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "dyn-forms.basic.intro",
4 | "title": {
5 | "en": "Basic Setup",
6 | "es": "Configuración Básica"
7 | },
8 | "packagePath": "dyn-forms/basic/intro",
9 | "componentName": "AppComponent",
10 | "selector": "app-root",
11 | "primaryFile": "app.component.ts",
12 | "files": [
13 | "form.config.ts",
14 | "app.component.ts",
15 | "app.component.html",
16 | "app.module.ts"
17 | ],
18 | "additionalComponents": [],
19 | "module": {
20 | "name": "DynFormsExampleIntro",
21 | "importSpecifier": "dyn-forms/basic/intro"
22 | }
23 | }
24 | ]
25 |
--------------------------------------------------------------------------------
/libs/forms/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "target": "ES2022",
6 | "declaration": true,
7 | "declarationMap": true,
8 | "inlineSources": true,
9 | "lib": ["dom", "es2018"],
10 | "types": [],
11 | "useDefineForClassFields": false
12 | },
13 | "angularCompilerOptions": {
14 | "skipTemplateCodegen": true,
15 | "strictMetadataEmit": true,
16 | "enableResourceInlining": true
17 | },
18 | "exclude": [
19 | "index.tests.ts",
20 | "**/*.spec.ts",
21 | "**/*.test.ts",
22 | "jest.config.ts"
23 | ],
24 | "include": ["**/*.ts"]
25 | }
26 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature-request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature Request
3 | about: Suggest an idea for a library
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 | ---
8 |
9 | ## Is your feature request related to a problem? Please describe
10 |
11 | A clear and concise description of what the problem is.
12 |
13 | ## Describe the solution you'd like
14 |
15 | A clear and concise description of what you want to happen.
16 |
17 | ## Describe alternatives you've considered
18 |
19 | A clear and concise description of any alternative solutions or features you've considered.
20 |
21 | ## Additional context
22 |
23 | Add any other context or screenshots about the feature request here.
24 |
--------------------------------------------------------------------------------
/libs/demos/examples.json:
--------------------------------------------------------------------------------
1 | {
2 | "dyn-forms.basic.intro": {
3 | "id": "dyn-forms.basic.intro",
4 | "title": {
5 | "en": "Basic Setup",
6 | "es": "Configuración Básica"
7 | },
8 | "componentName": "DynFormsBasicComponent",
9 | "selector": "dyn-forms-basic",
10 | "filesPath": "dyn-forms/basic/intro",
11 | "primaryFile": "app.component.ts",
12 | "files": [
13 | "form.config.ts",
14 | "app.component.ts",
15 | "app.component.html",
16 | "app.module.ts"
17 | ],
18 | "additionalComponents": [],
19 | "module": {
20 | "name": "DemoFormsModule",
21 | "importSpecifier": "dyn-forms/basic/intro"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/libs/forms/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.lib.json"
8 | },
9 | {
10 | "path": "./tsconfig.lib.prod.json"
11 | },
12 | {
13 | "path": "./tsconfig.spec.json"
14 | }
15 | ],
16 | "compilerOptions": {
17 | "forceConsistentCasingInFileNames": true,
18 | "noImplicitReturns": true,
19 | "noFallthroughCasesInSwitch": true,
20 | "strict": true,
21 | "target": "es2020"
22 | },
23 | "angularCompilerOptions": {
24 | "strictMetadataEmit": true,
25 | "strictInjectionParameters": true,
26 | "strictTemplates": true
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/libs/plugin/src/generators/nx/generator.spec.ts:
--------------------------------------------------------------------------------
1 | import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
2 | import { Tree, readProjectConfiguration } from '@nx/devkit';
3 |
4 | import generator from './generator';
5 | import { NxGeneratorSchema } from './schema';
6 |
7 | describe('nx generator', () => {
8 | let appTree: Tree;
9 | const options: NxGeneratorSchema = { name: 'test' };
10 |
11 | beforeEach(() => {
12 | appTree = createTreeWithEmptyWorkspace();
13 | });
14 |
15 | it('should run successfully', async () => {
16 | await generator(appTree, options);
17 | const config = readProjectConfiguration(appTree, 'test');
18 | expect(config).toBeDefined();
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 |
8 | # dependencies
9 | node_modules
10 |
11 | # IDEs and editors
12 | /.idea
13 | .project
14 | .classpath
15 | .c9/
16 | *.launch
17 | .settings/
18 | *.sublime-workspace
19 |
20 | # IDE - VSCode
21 | .vscode/*
22 | !.vscode/settings.json
23 | !.vscode/tasks.json
24 | !.vscode/launch.json
25 | !.vscode/extensions.json
26 |
27 | # misc
28 | /.angular/cache
29 | /.sass-cache
30 | /connect.lock
31 | /coverage
32 | /libpeerconnection.log
33 | npm-debug.log
34 | yarn-error.log
35 | testem.log
36 | /typings
37 | .npmrc
38 |
39 | # System Files
40 | .DS_Store
41 | Thumbs.db
42 |
--------------------------------------------------------------------------------
/apps/website/.browserslistrc:
--------------------------------------------------------------------------------
1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
2 | # For additional information regarding the format and rule options, please see:
3 | # https://github.com/browserslist/browserslist#queries
4 |
5 | # For the full list of supported browsers by the Angular framework, please see:
6 | # https://angular.io/guide/browser-support
7 |
8 | # You can see what browsers were selected by your queries by running:
9 | # npx browserslist
10 |
11 | last 2 Chrome version
12 | last 1 Firefox version
13 | last 2 Edge major versions
14 | last 2 Safari major versions
15 | last 2 iOS major versions
16 | Firefox ESR
17 | not ios_saf 15.2-15.3
18 | not safari 15.2-15.3
19 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/select/select.component.params.ts:
--------------------------------------------------------------------------------
1 | import { MatLegacyOption as MatOption } from '@angular/material/legacy-core';
2 | import { DynNode, DynOption } from '@myndpm/dyn-forms/core';
3 | import { DynMatFormFieldParams } from '../../wrappers';
4 |
5 | export interface DynMatSelectParams extends Partial {
6 | label?: string;
7 | placeholder: string;
8 | multiple?: boolean;
9 | options: DynOption[];
10 | compareWith: (o1: any, o2: any) => boolean;
11 | sortComparator: (a: MatOption, b: MatOption, options: MatOption[]) => number;
12 | panelClass: string | string[] | Set | { [key: string]: any };
13 | // paramFns
14 | getValue?: (node: DynNode) => string;
15 | }
16 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/stepper/stepper.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
20 |
21 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/stepper/stepper.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | .blockquote {
3 | background: #eee;
4 | border-left: 4px solid #ddd;
5 | border-radius: 4px;
6 | font-size: 90%;
7 | padding: 16px;
8 | }
9 |
10 | ::ng-deep {
11 | // a bit of grid spacing
12 | .dyn-control {
13 | margin-bottom: 0.25em;
14 | }
15 |
16 | // space-between buttons
17 | .form-actions {
18 | margin-top: 1em;
19 |
20 | display: flex;
21 | flex-direction: row;
22 | place-content: center space-between;
23 | align-items: center;
24 | }
25 |
26 | // final step summary
27 | pre {
28 | background: #f5f5f5;
29 | padding: 16px;
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/apps/website/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // This file can be replaced during build by using the `fileReplacements` array.
2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
3 | // The list of file replacements can be found in `angular.json`.
4 |
5 | export const environment = {
6 | production: false,
7 | };
8 |
9 | /*
10 | * For easier debugging in development mode, you can import the following file
11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
12 | *
13 | * This import should be commented out in production mode because it will have a negative impact
14 | * on performance if an error is thrown.
15 | */
16 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
17 |
--------------------------------------------------------------------------------
/libs/plugin/src/executors/deploy-npm/utils/default-options.ts:
--------------------------------------------------------------------------------
1 | import { DeployNpmExecutorSchema } from '../schema';
2 |
3 | export enum npmAccess {
4 | public = 'public',
5 | restricted = 'restricted',
6 | }
7 |
8 | export type NpmPublishOptions = Pick<
9 | DeployNpmExecutorSchema,
10 | 'access' | 'tag' | 'otp' | 'dryRun' | 'exception'
11 | >;
12 |
13 | export const defaults: NpmPublishOptions = {
14 | tag: undefined,
15 | access: npmAccess.public,
16 | otp: undefined,
17 | dryRun: false,
18 | exception: false,
19 | };
20 |
21 | export function prepareOptions(
22 | origOptions: DeployNpmExecutorSchema
23 | ): DeployNpmExecutorSchema {
24 | const options = {
25 | ...defaults,
26 | ...origOptions,
27 | };
28 |
29 | return options;
30 | }
31 |
--------------------------------------------------------------------------------
/libs/plugin/src/generators/nx/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "$id": "Nx",
4 | "title": "",
5 | "type": "object",
6 | "properties": {
7 | "name": {
8 | "type": "string",
9 | "description": "",
10 | "$default": {
11 | "$source": "argv",
12 | "index": 0
13 | },
14 | "x-prompt": "What name would you like to use?"
15 | },
16 | "tags": {
17 | "type": "string",
18 | "description": "Add tags to the project (used for linting)",
19 | "alias": "t"
20 | },
21 | "directory": {
22 | "type": "string",
23 | "description": "A directory where the project is placed",
24 | "alias": "d"
25 | }
26 | },
27 | "required": [
28 | "name"
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/libs/utils/src/rxjs-tree.ts:
--------------------------------------------------------------------------------
1 | import { join } from 'path';
2 | import { from, Observable, of, throwError } from 'rxjs';
3 | import { mergeMap } from 'rxjs/operators';
4 | import { readDir, stat } from './rxjs-fs';
5 |
6 | /**
7 | * Similar to @angular-devkit's Tree.visit.
8 | */
9 |
10 | export function treeVisit(path: string): Observable {
11 | return stat(path).pipe(
12 | mergeMap((stats) => {
13 | if (stats.isDirectory()) {
14 | return readDir(path).pipe(
15 | mergeMap((files) => from(files)),
16 | mergeMap((file) => treeVisit(join(path, file)))
17 | );
18 | } else if (stats.isFile()) {
19 | return of(path);
20 | }
21 | return throwError(`Not a directory nor file: ${path}`);
22 | })
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: matheo
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
14 |
--------------------------------------------------------------------------------
/apps/website/src/app/pages/components/not-found/not-found.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component, Inject, Optional } from '@angular/core';
2 | import { RESPONSE } from '@nguniversal/express-engine/tokens';
3 | import { Response } from 'express';
4 |
5 | @Component({
6 | selector: 'app-not-found',
7 | templateUrl: './not-found.component.html',
8 | styleUrls: ['./not-found.component.scss'],
9 | changeDetection: ChangeDetectionStrategy.OnPush
10 | })
11 | export class NotFoundComponent {
12 | constructor(
13 | @Optional() @Inject(RESPONSE) private response: Response,
14 | ) {}
15 |
16 | ngOnInit() {
17 | if (this.response) {
18 | this.response.statusCode = 404;
19 | this.response.statusMessage = 'Page Not Found';
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/libs/forms/logger/src/log-levels.constant.ts:
--------------------------------------------------------------------------------
1 |
2 | export enum DynLogLevel {
3 | /** meant to be used with bitwise OR */
4 | Testing = 2**10,
5 | All = 2**9 - 1,
6 | Runtime = 2**8,
7 | Ready = 2**7,
8 | Load = 2**6,
9 | Lifecycle = 2**5,
10 | Hierarchy = 2**4,
11 | Debug = 2**3,
12 | Warning = 2**2,
13 | Error = 2**1,
14 | Fatal = 2**0,
15 | None = 0,
16 | }
17 |
18 | export const dynLogLevels = new Map([
19 | [DynLogLevel.Runtime, 'Runtime'],
20 | [DynLogLevel.Ready, 'READY'],
21 | [DynLogLevel.Load, 'LOAD'],
22 | [DynLogLevel.Lifecycle, 'CYCLE'],
23 | [DynLogLevel.Hierarchy, 'SETUP'],
24 | [DynLogLevel.Debug, 'DEBUG'],
25 | [DynLogLevel.Warning, 'WARN'],
26 | [DynLogLevel.Error, 'ERROR'],
27 | [DynLogLevel.Fatal, 'FATAL'],
28 | ]);
29 |
--------------------------------------------------------------------------------
/libs/forms/core/src/types/templates.types.ts:
--------------------------------------------------------------------------------
1 | import { TemplateRef } from '@angular/core';
2 |
3 | /**
4 | * Used to communicate templates with its parameters to the Wrappers
5 | */
6 | export interface DynTemplate {
7 | template: TemplateRef;
8 | params: Record;
9 | }
10 |
11 | /**
12 | * A custom Map of template+params grouped by different sections (id) like prefix, suffix.
13 | */
14 | export class DynTemplates extends Map {
15 | add(id: string, template: TemplateRef, params: Record): void {
16 | if (!this.has(id)) {
17 | this.set(id, []);
18 | }
19 | this.get(id).push({ template, params });
20 | }
21 |
22 | override get(id: string): DynTemplate[] {
23 | return super.get(id) ?? [];
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/libs/plugin/executors.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "builders": {
4 | "deploy-npm": {
5 | "implementation": "./src/executors/deploy-npm/executor",
6 | "schema": "./src/executors/deploy-npm/schema.json",
7 | "description": "Publish packages to NPM"
8 | }
9 | },
10 | "executors": {
11 | "deploy-docker": {
12 | "implementation": "./src/executors/deploy-docker/executor",
13 | "schema": "./src/executors/deploy-docker/schema.json",
14 | "description": "Publish applications to Docker"
15 | },
16 | "deploy-npm": {
17 | "implementation": "./src/executors/deploy-npm/executor",
18 | "schema": "./src/executors/deploy-npm/schema.json",
19 | "description": "Publish packages to NPM"
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/combo/combo.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { ComboComponent } from './combo.component';
4 |
5 | describe('ComboComponent', () => {
6 | let component: ComboComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async () => {
10 | await TestBed.configureTestingModule({
11 | declarations: [ ComboComponent ]
12 | })
13 | .compileComponents();
14 | });
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(ComboComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/libs/forms/jest.config.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | export default {
3 | displayName: 'forms',
4 | preset: '../../jest.preset.js',
5 | setupFilesAfterEnv: ['/index.tests.ts'],
6 | globals: {},
7 | coverageDirectory: '../../coverage/libs/forms',
8 | snapshotSerializers: [
9 | 'jest-preset-angular/build/serializers/no-ng-attributes',
10 | 'jest-preset-angular/build/serializers/ng-snapshot',
11 | 'jest-preset-angular/build/serializers/html-comment',
12 | ],
13 | transform: {
14 | '^.+.(ts|mjs|js|html)$': [
15 | 'jest-preset-angular',
16 | {
17 | stringifyContentPathRegex: '\\.(html|svg)$',
18 |
19 | tsconfig: '/tsconfig.spec.json',
20 | },
21 | ],
22 | },
23 | transformIgnorePatterns: ['node_modules/(?!.*.mjs$)'],
24 | };
25 |
--------------------------------------------------------------------------------
/apps/website/jest.config.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | export default {
3 | displayName: 'website',
4 | preset: '../../jest.preset.js',
5 | setupFilesAfterEnv: ['/src/test-setup.ts'],
6 | globals: {},
7 | coverageDirectory: '../../coverage/apps/website',
8 | snapshotSerializers: [
9 | 'jest-preset-angular/build/serializers/no-ng-attributes',
10 | 'jest-preset-angular/build/serializers/ng-snapshot',
11 | 'jest-preset-angular/build/serializers/html-comment',
12 | ],
13 | transform: {
14 | '^.+.(ts|mjs|js|html)$': [
15 | 'jest-preset-angular',
16 | {
17 | stringifyContentPathRegex: '\\.(html|svg)$',
18 |
19 | tsconfig: '/tsconfig.spec.json',
20 | },
21 | ],
22 | },
23 | transformIgnorePatterns: ['node_modules/(?!.*.mjs$)'],
24 | };
25 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/builder/builder.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { BuilderComponent } from './builder.component';
4 |
5 | describe('BuilderComponent', () => {
6 | let component: BuilderComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async () => {
10 | await TestBed.configureTestingModule({
11 | declarations: [ BuilderComponent ]
12 | }).compileComponents();
13 | });
14 |
15 | beforeEach(() => {
16 | fixture = TestBed.createComponent(BuilderComponent);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | });
20 |
21 | it('should create', () => {
22 | expect(component).toBeTruthy();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/simple/simple.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { SimpleComponent } from './simple.component';
4 |
5 | describe('SimpleComponent', () => {
6 | let component: SimpleComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async () => {
10 | await TestBed.configureTestingModule({
11 | declarations: [ SimpleComponent ]
12 | })
13 | .compileComponents();
14 | });
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(SimpleComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/single/single.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { SingleComponent } from './single.component';
4 |
5 | describe('SingleComponent', () => {
6 | let component: SingleComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async () => {
10 | await TestBed.configureTestingModule({
11 | declarations: [ SingleComponent ]
12 | })
13 | .compileComponents();
14 | });
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(SingleComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/stepper/stepper.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { StepperComponent } from './stepper.component';
4 |
5 | describe('StepperComponent', () => {
6 | let component: StepperComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async () => {
10 | await TestBed.configureTestingModule({
11 | declarations: [StepperComponent],
12 | }).compileComponents();
13 | });
14 |
15 | beforeEach(() => {
16 | fixture = TestBed.createComponent(StepperComponent);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | });
20 |
21 | it('should create', () => {
22 | expect(component).toBeTruthy();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/libs/utils/src/rxjs-fs.ts:
--------------------------------------------------------------------------------
1 | import { readFile as rxReadFile } from '@ckapp/rxjs-node-fs';
2 | import { rename } from 'fs';
3 | import { bindNodeCallback, Observable } from 'rxjs';
4 | import { map } from 'rxjs/operators';
5 |
6 | /**
7 | * RxJs filesystem utilities.
8 | */
9 |
10 | export {
11 | appendFile,
12 | readDir,
13 | stat,
14 | watch,
15 | writeFile,
16 | } from '@ckapp/rxjs-node-fs';
17 |
18 | export function readFile(
19 | filepath: string,
20 | options?: { encoding?: BufferEncoding; flag?: string } | null
21 | ): Observable {
22 | return rxReadFile(filepath, options as any).pipe(
23 | map((buffer) => buffer?.toString())
24 | );
25 | }
26 |
27 | export const renameFile: (
28 | oldPath: string,
29 | newPath: string
30 | ) => Observable = bindNodeCallback(rename);
31 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/single/single.component.html:
--------------------------------------------------------------------------------
1 |
23 |
--------------------------------------------------------------------------------
/libs/forms/core/src/types/params.types.ts:
--------------------------------------------------------------------------------
1 | import { DynBaseHandler } from './provider.types';
2 |
3 | /**
4 | * control params
5 | */
6 | export interface DynParams {
7 | // once merged with the paramFns they can have any type
8 | [key: string]: any;
9 | }
10 |
11 | /**
12 | * control functions
13 | * ie. { paramFns: { getValue: 'getOptionText' }}
14 | */
15 | export type DynFunctionFn = (...args: any[]) => T;
16 | export type DynFunction = DynBaseHandler>;
17 |
18 | /**
19 | * @deprecated use DynParams
20 | */
21 | export type DynControlParams = DynParams;
22 |
23 | /**
24 | * @deprecated use DynFunctionFn
25 | */
26 | export type DynControlFunctionFn = DynFunctionFn;
27 |
28 | /**
29 | * @deprecated use DynFunction
30 | */
31 | export type DynControlFunction = DynFunction;
32 |
--------------------------------------------------------------------------------
/libs/forms/testing/form/form-testing.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component, Input, ViewChild } from '@angular/core';
2 | import { FormGroup } from '@angular/forms';
3 | import { DynFormComponent, DynFormConfig } from '@myndpm/dyn-forms';
4 | import { DynMode } from '@myndpm/dyn-forms/core';
5 |
6 | @Component({
7 | selector: 'dyn-form-testing',
8 | template: `
9 |
15 | `,
16 | changeDetection: ChangeDetectionStrategy.OnPush,
17 | })
18 | export class DynFormTestingComponent {
19 | @Input() config!: DynFormConfig;
20 | @Input() mode!: DynMode;
21 |
22 | @ViewChild(DynFormComponent, { static: true })
23 | dynForm!: DynFormComponent;
24 |
25 | form = new FormGroup({});
26 | }
27 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/input/input.component.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
12 |
13 |
14 |
21 |
22 |
23 |
24 | {{ (params.getValue ? params.getValue(node) : control.value) || '-' }}
25 |
26 |
--------------------------------------------------------------------------------
/libs/forms/core/src/types/forms.types.ts:
--------------------------------------------------------------------------------
1 | import { Observable } from 'rxjs';
2 |
3 | // form control type
4 | export enum DynInstanceType {
5 | Wrapper = 'WRAPPER',
6 | Group = 'GROUP',
7 | Array = 'ARRAY',
8 | Control = 'CONTROL',
9 | Container = 'CONTAINER',
10 | }
11 |
12 | // plain/serializable arguments (non-functions)
13 | export type DynConfigPrimitive = undefined | string | boolean | number | Set | RegExp | DynConfigPrimitive[] | { [k: string]: DynConfigPrimitive } | Observable;
14 | export type DynConfigArgs = DynConfigPrimitive | DynConfigPrimitive[] | null;
15 |
16 | /**
17 | * Visibility handled by DynControl
18 | */
19 | export type DynVisibility = 'VISIBLE' | 'INVISIBLE' | 'HIDDEN';
20 |
21 | /**
22 | * @deprecated use DynVisibility
23 | */
24 | export type DynControlVisibility = DynVisibility;
25 |
--------------------------------------------------------------------------------
/libs/forms/ui-native/src/dyn-forms-native.factory.ts:
--------------------------------------------------------------------------------
1 | import {
2 | DynConfig,
3 | DynControlId,
4 | DynMode,
5 | DynPartialControlConfig,
6 | } from '@myndpm/dyn-forms/core';
7 | import {
8 | DynNatInputComponent,
9 | DynNatInputParams,
10 | } from './controls';
11 |
12 | // control overloads
13 | export function createMatConfig(
14 | control: typeof DynNatInputComponent.dynControl,
15 | partial: DynPartialControlConfig>
16 | ): DynConfig;
17 |
18 | // factory
19 | export function createMatConfig(
20 | control: DynControlId,
21 | partial: any,
22 | ): DynConfig {
23 | switch (control) {
24 | // controls
25 | case DynNatInputComponent.dynControl:
26 | default:
27 | return DynNatInputComponent.createConfig(partial);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/stepper/step1/step1.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { StepperStep1Component } from './step1.component';
4 |
5 | describe('StepperStep1Component', () => {
6 | let component: StepperStep1Component;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async () => {
10 | await TestBed.configureTestingModule({
11 | declarations: [StepperStep1Component],
12 | }).compileComponents();
13 | });
14 |
15 | beforeEach(() => {
16 | fixture = TestBed.createComponent(StepperStep1Component);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | });
20 |
21 | it('should create', () => {
22 | expect(component).toBeTruthy();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/stepper/step2/step2.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { StepperStep2Component } from './step2.component';
4 |
5 | describe('StepperStep2Component', () => {
6 | let component: StepperStep2Component;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async () => {
10 | await TestBed.configureTestingModule({
11 | declarations: [StepperStep2Component],
12 | }).compileComponents();
13 | });
14 |
15 | beforeEach(() => {
16 | fixture = TestBed.createComponent(StepperStep2Component);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | });
20 |
21 | it('should create', () => {
22 | expect(component).toBeTruthy();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug-report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug Report
3 | about: Report a problem with a library
4 | title: ''
5 | labels: 'bug / fix'
6 | assignees: ''
7 | ---
8 |
9 | ## Describe the bug
10 |
11 | A clear and concise description of what the bug is.
12 |
13 | ## To Reproduce
14 |
15 | Steps to reproduce the behavior:
16 |
17 | 1. Go to '...'
18 | 2. Click on '....'
19 | 3. Scroll down to '....'
20 | 4. See error
21 |
22 | ## Expected behavior
23 |
24 | A clear and concise description of what you expected to happen.
25 |
26 | ## Screenshots
27 |
28 | If applicable, add screenshots to help explain your problem.
29 |
30 | ## Desktop (please complete the following information)
31 |
32 | ```bash
33 | Copy the output of `ng version` here.
34 | ```
35 |
36 | ## Additional context
37 |
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/apps/website/src/app/docs/components/layout/layout.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ parent.text }}
7 |
8 |
9 |
10 |
11 | {{ option.text }}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/single/single.form.ts:
--------------------------------------------------------------------------------
1 | import { DynFormConfig } from '@myndpm/dyn-forms';
2 | import { createMatConfig } from '@myndpm/dyn-forms/ui-material';
3 | import { SingleSuccessComponent } from './success.control/success.component';
4 |
5 | export function singleForm(): DynFormConfig<'form'|'success'> {
6 | return {
7 | controls: [
8 | createMatConfig('INPUT', {
9 | name: 'email',
10 | validators: ['required', 'email'],
11 | cssClass: 'col-sm-6 col-md-4',
12 | params: {
13 | label: 'Email',
14 | type: 'email',
15 | },
16 | modes: {
17 | success: SingleSuccessComponent.createConfig(),
18 | }
19 | }),
20 | ],
21 | errorMsgs: {
22 | email: 'Valid email is mandatory',
23 | },
24 | };
25 | }
26 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/stepper/summary/summary.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { StepperSummaryComponent } from './summary.component';
4 |
5 | describe('StepperSummaryComponent', () => {
6 | let component: StepperSummaryComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async () => {
10 | await TestBed.configureTestingModule({
11 | declarations: [StepperSummaryComponent],
12 | }).compileComponents();
13 | });
14 |
15 | beforeEach(() => {
16 | fixture = TestBed.createComponent(StepperSummaryComponent);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | });
20 |
21 | it('should create', () => {
22 | expect(component).toBeTruthy();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/apps/website/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Mynd.co Open Source
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/libs/forms/lib/schematics/module/schema.ts:
--------------------------------------------------------------------------------
1 |
2 | export class Schema {
3 | /**
4 | * Angular options.
5 | */
6 | path?: string;
7 | project?: string;
8 | prefix?: string;
9 | /**
10 | * The name of the DynModule.
11 | */
12 | name!: string;
13 | /**
14 | * Default control options.
15 | */
16 | controlPath?: string;
17 | controlName!: string;
18 | type?: string;
19 | id!: string;
20 | instance?: string;
21 | /**
22 | * The prefix to apply to the params interface.
23 | */
24 | prefixInterface?: string;
25 | /**
26 | * Whether to prefix the control class name.
27 | */
28 | prefixClass?: boolean;
29 | /**
30 | * Flag to indicate if a directory is created.
31 | */
32 | flat?: boolean;
33 | /**
34 | * The declaring NgModule.
35 | */
36 | module?: string;
37 | /**
38 | * Apply lint fixes after generating the module.
39 | */
40 | lintFix?: boolean;
41 | }
42 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/components/prompt/prompt.dialog.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
2 | import { MAT_LEGACY_DIALOG_DATA as MAT_DIALOG_DATA, MatLegacyDialogRef as MatDialogRef } from '@angular/material/legacy-dialog';
3 | import { PromptDialogData } from './prompt-data.interface';
4 |
5 | @Component({
6 | selector: 'app-prompt',
7 | templateUrl: 'prompt.dialog.html',
8 | styleUrls: ['./prompt.dialog.scss'],
9 | changeDetection: ChangeDetectionStrategy.OnPush,
10 | })
11 | // tslint:disable-next-line: component-class-suffix
12 | export class PromptDialog {
13 | title = '';
14 | content = '';
15 |
16 | constructor(
17 | public dialogRef: MatDialogRef,
18 | @Inject(MAT_DIALOG_DATA) public data: PromptDialogData
19 | ) {
20 | this.data = {
21 | no: 'No',
22 | yes: 'Yes',
23 | color: 'accent',
24 | ...data
25 | };
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/apps/website/src/app/docs/components/content/content.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/libs/forms/core/src/types/provider.types.ts:
--------------------------------------------------------------------------------
1 | import { DynConfigArgs } from './forms.types';
2 |
3 | // a given id to a validator/async-validator/error-handler/function
4 | export type DynConfigId = string;
5 |
6 | /**
7 | * Base types
8 | */
9 | export interface DynBaseProvider {
10 | priority?: number;
11 | }
12 |
13 | export type DynHandlerFactory = (...args: any[]) => F;
14 |
15 | export interface DynBaseHandler> extends DynBaseProvider {
16 | id: DynConfigId;
17 | fn: H;
18 | }
19 |
20 | // handlers provided can be referenced by id or [id with args]
21 | export type DynConfigProvider = F | DynConfigId | [DynConfigId, DynConfigArgs];
22 |
23 | // object map of handlers
24 | export type DynConfigMap = Record;
25 |
26 | // collection of handlers to be used
27 | export type DynConfigCollection = Record | Array>;
28 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/card/card.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component } from '@angular/core';
2 | import {
3 | DynBaseConfig,
4 | DynFormContainer,
5 | DynMode,
6 | DynPartialControlConfig,
7 | } from '@myndpm/dyn-forms/core';
8 | import { DynMatCardParams } from './card.component.params';
9 |
10 | @Component({
11 | selector: 'dyn-mat-card',
12 | templateUrl: './card.component.html',
13 | styleUrls: ['./card.component.scss'],
14 | changeDetection: ChangeDetectionStrategy.OnPush,
15 | })
16 | export class DynMatCardComponent
17 | extends DynFormContainer {
18 |
19 | static dynControl: 'CARD' = 'CARD';
20 |
21 | static createConfig(
22 | partial: DynPartialControlConfig
23 | ): DynBaseConfig {
24 | return {
25 | ...partial,
26 | control: DynMatCardComponent.dynControl,
27 | };
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/apps/website/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "overrides": [
5 | {
6 | "files": ["*.ts"],
7 | "extends": [
8 | "plugin:@nx/angular",
9 | "plugin:@angular-eslint/template/process-inline-templates"
10 | ],
11 | "rules": {
12 | "@angular-eslint/directive-selector": [
13 | "error",
14 | {
15 | "type": "attribute",
16 | "prefix": "app",
17 | "style": "camelCase"
18 | }
19 | ],
20 | "@angular-eslint/component-selector": [
21 | "error",
22 | {
23 | "type": "element",
24 | "prefix": "app",
25 | "style": "kebab-case"
26 | }
27 | ]
28 | }
29 | },
30 | {
31 | "files": ["*.html"],
32 | "extends": ["plugin:@nx/angular-template"],
33 | "rules": {}
34 | }
35 | ]
36 | }
37 |
--------------------------------------------------------------------------------
/libs/demos/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "overrides": [
5 | {
6 | "files": ["*.ts"],
7 | "extends": [
8 | "plugin:@nx/angular",
9 | "plugin:@angular-eslint/template/process-inline-templates"
10 | ],
11 | "rules": {
12 | "@angular-eslint/directive-selector": [
13 | "error",
14 | {
15 | "type": "attribute",
16 | "prefix": "myndpm",
17 | "style": "camelCase"
18 | }
19 | ],
20 | "@angular-eslint/component-selector": [
21 | "error",
22 | {
23 | "type": "element",
24 | "prefix": "myndpm",
25 | "style": "kebab-case"
26 | }
27 | ]
28 | }
29 | },
30 | {
31 | "files": ["*.html"],
32 | "extends": ["plugin:@nx/angular-template"],
33 | "rules": {}
34 | }
35 | ]
36 | }
37 |
--------------------------------------------------------------------------------
/apps/website/src/app/docs/components/layout/layout.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | height: 100%;
4 |
5 | ::ng-deep {
6 |
7 | .mat-expansion-panel {
8 | border-radius: 0 !important;
9 | box-shadow: none;
10 | margin: 0;
11 | }
12 |
13 | .mat-expansion-panel-header {
14 | font-size: 16px;
15 | font-weight: 500;
16 | padding: 0 24px 0 16px;
17 |
18 | .mat-expansion-indicator {
19 | padding: 0 0 8px;
20 | }
21 |
22 | &.mat-expanded {
23 | height: 48px;
24 | }
25 | }
26 |
27 | .mat-expansion-panel-body {
28 | padding: 0;
29 | }
30 |
31 | .mat-list-base {
32 | padding: 0;
33 | }
34 |
35 | .mat-list-item {
36 | font-size: 14px;
37 |
38 | &.active {
39 | background: rgba(#38B87C, 0.5);
40 | }
41 | }
42 | }
43 | }
44 |
45 | .mat-accordion {
46 | border-right: 1px solid rgba(0, 0, 0, 0.12);
47 | }
48 |
--------------------------------------------------------------------------------
/tsconfig.schematics.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowSyntheticDefaultImports": true,
4 | "declaration": true,
5 | "emitDecoratorMetadata": true,
6 | "experimentalDecorators": true,
7 | "forceConsistentCasingInFileNames": true,
8 | "noFallthroughCasesInSwitch": true,
9 | "noEmitOnError": true,
10 | "noImplicitAny": true,
11 | "noImplicitReturns": false,
12 | "noImplicitThis": true,
13 | "noUnusedLocals": false,
14 | "noUnusedParameters": true,
15 | "skipDefaultLibCheck": true,
16 | "skipLibCheck": true,
17 | "sourceMap": false,
18 | "strict": false,
19 | "strictBindCallApply": true,
20 | "strictFunctionTypes": true,
21 | "strictNullChecks": true,
22 | "moduleResolution": "node",
23 | "module": "commonjs",
24 | "target": "es6",
25 | "lib": [
26 | "es2019",
27 | "dom"
28 | ],
29 | "types": []
30 | },
31 | "exclude": [
32 | "**/*.spec.ts"
33 | ]
34 | }
35 |
--------------------------------------------------------------------------------
/apps/website/src/app/layout/components/header/header.component.html:
--------------------------------------------------------------------------------
1 | Mynd.co Open Source
2 |
3 |
25 |
--------------------------------------------------------------------------------
/libs/forms/lib/components/factory/factory.directive.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { DynFormRegistry } from '@myndpm/dyn-forms/core';
3 | import { MockProvider } from 'ng-mocks';
4 | import { DynFactoryDirective } from './factory.directive';
5 |
6 | describe('DynFactoryDirective', () => {
7 | let component: DynFactoryDirective;
8 | let fixture: ComponentFixture;
9 |
10 | beforeEach(async () => {
11 | await TestBed.configureTestingModule({
12 | declarations: [DynFactoryDirective],
13 | providers: [
14 | MockProvider(DynFormRegistry),
15 | ],
16 | }).compileComponents();
17 | });
18 |
19 | beforeEach(() => {
20 | fixture = TestBed.createComponent(DynFactoryDirective);
21 | component = fixture.componentInstance;
22 | fixture.detectChanges();
23 | });
24 |
25 | it('should create', () => {
26 | expect(component).toBeTruthy();
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/apps/website/src/assets/logos/github.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/controls/input/input.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
17 |
18 |
19 |
26 |
27 |
28 | {{ params.hint }}
29 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/container/container.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, ChangeDetectionStrategy } from '@angular/core';
2 | import {
3 | DynConfig,
4 | DynFormContainer,
5 | DynMode,
6 | DynPartialControlConfig,
7 | } from '@myndpm/dyn-forms/core';
8 | import { DynMatContainerParams } from './container.component.params';
9 |
10 | @Component({
11 | selector: 'dyn-mat-container',
12 | templateUrl: './container.component.html',
13 | styleUrls: ['./container.component.scss'],
14 | changeDetection: ChangeDetectionStrategy.OnPush
15 | })
16 | export class DynMatContainerComponent
17 | extends DynFormContainer {
18 |
19 | static dynControl: 'CONTAINER' = 'CONTAINER';
20 |
21 | static createConfig(
22 | partial: DynPartialControlConfig
23 | ): DynConfig {
24 | return {
25 | ...partial,
26 | control: DynMatContainerComponent.dynControl,
27 | };
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/.all-contributorsrc:
--------------------------------------------------------------------------------
1 | {
2 | "files": [
3 | "README.md"
4 | ],
5 | "imageSize": 100,
6 | "commit": false,
7 | "contributors": [
8 | {
9 | "login": "matheo",
10 | "name": "Mateo Tibaquirá",
11 | "avatar_url": "https://avatars.githubusercontent.com/u/260185?v=4",
12 | "profile": "http://matheo.co",
13 | "contributions": [
14 | "projectManagement",
15 | "example",
16 | "ideas",
17 | "code",
18 | "doc"
19 | ]
20 | },
21 | {
22 | "login": "nikita-emelianov",
23 | "name": "Nikita Emelianov",
24 | "avatar_url": "https://avatars.githubusercontent.com/u/42650220?v=4",
25 | "profile": "https://github.com/nikita-emelianov",
26 | "contributions": [
27 | "code"
28 | ]
29 | }
30 | ],
31 | "contributorsPerLine": 7,
32 | "projectName": "open-source",
33 | "projectOwner": "myndpm",
34 | "repoType": "github",
35 | "repoHost": "https://github.com",
36 | "skipCi": true
37 | }
38 |
--------------------------------------------------------------------------------
/libs/forms/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@myndpm/dyn-forms",
3 | "version": "16.0.1",
4 | "description": "Abstract layer to easily generate Dynamic Forms for Angular",
5 | "keywords": [
6 | "angular",
7 | "dynamic",
8 | "forms"
9 | ],
10 | "license": "MIT",
11 | "homepage": "https://mynd.dev/",
12 | "repository": {
13 | "type": "git",
14 | "url": "git@github.com:myndpm/open-source.git",
15 | "directory": "libs/forms"
16 | },
17 | "schematics": "./schematics.json",
18 | "ng-update": {
19 | "packageGroup": [],
20 | "migrations": "./migrations.json"
21 | },
22 | "peerDependencies": {
23 | "@angular/common": ">=16.0.0",
24 | "@angular/core": ">=16.0.0",
25 | "@angular/forms": ">=16.0.0",
26 | "rxjs": "*"
27 | },
28 | "dependencies": {
29 | "ramda": "^0.29.0",
30 | "fast-deep-equal": "~3.1.3",
31 | "is-callable": "~1.2.7",
32 | "tslib": "^2.3.0"
33 | },
34 | "devDependencies": {
35 | "@types/ramda": "^0.29.3"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/libs/forms/ui-native/src/dyn-forms-native.module.ts:
--------------------------------------------------------------------------------
1 | import { CommonModule } from '@angular/common';
2 | import { ModuleWithProviders, NgModule } from '@angular/core';
3 | import { ReactiveFormsModule } from '@angular/forms';
4 | import { DynFormsModule } from '@myndpm/dyn-forms';
5 | import { getModuleProviders } from '@myndpm/dyn-forms/core';
6 | import {
7 | DynNatInputComponent,
8 | } from './controls';
9 |
10 | @NgModule({
11 | imports: [
12 | CommonModule,
13 | ReactiveFormsModule,
14 | DynFormsModule,
15 | ],
16 | declarations: [
17 | DynNatInputComponent,
18 | ],
19 | exports: [
20 | // reduce the boilerplate
21 | DynFormsModule,
22 | ]
23 | })
24 | export class DynFormsNativeModule {
25 | static forFeature(): ModuleWithProviders {
26 | return {
27 | ngModule: DynFormsNativeModule,
28 | providers: getModuleProviders({
29 | controls: [
30 | DynNatInputComponent,
31 | ],
32 | }),
33 | };
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/docs/dyn-forms/ui/ui-material/README.md:
--------------------------------------------------------------------------------
1 | # @myndpm/dyn-forms/ui-material
2 |
3 | This subpackage provides the `DynControls` to use the Angular Material components.
4 |
5 | ## Usage
6 |
7 | To provide it in your module you just need to import it:
8 |
9 | ```typescript
10 | import { ReactiveFormsModule } from '@angular/forms';
11 | import { DynFormsMaterialModule } from '@myndpm/dyn-forms/ui-material`;
12 |
13 | @NgModule({
14 | imports: [
15 | ReactiveFormsModule,
16 | DynFormsMaterialModule.forFeature(),
17 | ]
18 | })
19 | ```
20 |
21 | and build your config with the provided Factory:
22 |
23 | ```typescript
24 | import { DynFormConfig } from '@myndpm/dyn-forms';
25 | import { createMatConfig } from '@myndpm/dyn-forms/ui-material';
26 |
27 | const config: DynFormConfig = {
28 | controls: [
29 | createMatConfig('INPUT', {
30 | params: { label: 'My text input' }
31 | }),
32 | ],
33 | }
34 | ```
35 |
36 | You can check the [demos](https://mynd.dev/demos) built with the Material `DynControls`.
37 |
--------------------------------------------------------------------------------
/libs/plugin/src/executors/deploy-npm/executor.ts:
--------------------------------------------------------------------------------
1 | import { ExecutorContext, logger } from '@nx/devkit';
2 | import deployer from './lib/deployer';
3 | import * as engine from './lib/engine';
4 | import { DeployNpmExecutorSchema } from './schema';
5 |
6 | export default async function runExecutor(
7 | options: DeployNpmExecutorSchema,
8 | context: ExecutorContext
9 | ) {
10 | const buildTarget = `${context.projectName}${
11 | options.target ? `:${options.target}` : ':build'
12 | }`;
13 | const outputTarget = `${context.projectName}${
14 | options.outputTarget ? `:${options.outputTarget}` : ':build'
15 | }`;
16 |
17 | try {
18 | await deployer(engine, context, buildTarget, outputTarget, options);
19 | logger.info(`\n🚀 ${context.projectName} published successfully!`);
20 | } catch (e) {
21 | logger.error(`\n❌ error while trying to publish ${context.projectName}`);
22 | logger.error(e.stderr || e);
23 | return { success: false };
24 | }
25 |
26 | return { success: true };
27 | }
28 |
--------------------------------------------------------------------------------
/libs/plugin/src/executors/deploy-npm/utils/package-json.ts:
--------------------------------------------------------------------------------
1 | import { jsonRead, jsonWrite } from '@myndpm/utils';
2 | import * as path from 'path';
3 |
4 | export function setPackageVersion(
5 | dir: string,
6 | version: string,
7 | dryRun = false
8 | ) {
9 | if (dryRun) {
10 | console.log(`setting ${version} into ${path.join(dir, 'package.json')}`);
11 | }
12 |
13 | const metadata = jsonRead(path.join(dir, 'package.json'));
14 |
15 | metadata.version = version;
16 |
17 | jsonWrite(path.join(dir, 'package.json'), metadata);
18 | }
19 |
20 | export function copyPackageVersion(
21 | origin: string,
22 | dest: string,
23 | dryRun = false
24 | ) {
25 | const metadata = jsonRead(path.join(origin, 'package.json'));
26 |
27 | if (dryRun) {
28 | console.log(
29 | `copying ${metadata.version} from ${path.join(
30 | origin,
31 | 'package.json'
32 | )} to ${path.join(dest, 'package.json')}`
33 | );
34 | }
35 |
36 | setPackageVersion(dest, metadata.version);
37 | }
38 |
--------------------------------------------------------------------------------
/apps/website/src/assets/logos/linkedin.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/libs/forms/lib/schematics/module/files/__name@dasherize@if-flat__/__name@dasherize__.module.ts.template:
--------------------------------------------------------------------------------
1 | import { CommonModule } from '@angular/common';
2 | import { ModuleWithProviders, NgModule } from '@angular/core';
3 | import { ReactiveFormsModule } from '@angular/forms';
4 | import { DynFormsModule } from '@myndpm/dyn-forms';
5 | import { getModuleProviders } from '@myndpm/dyn-forms/core';
6 |
7 | @NgModule({
8 | imports: [
9 | CommonModule,
10 | ReactiveFormsModule,
11 | DynFormsModule,
12 | ],
13 | declarations: [],
14 | exports: [
15 | DynFormsModule, // reduce the boilerplate
16 | ],
17 | })
18 | export class <%= classify(name) %>Module {
19 | static forFeature(): ModuleWithProviders<<%= classify(name) %>Module> {
20 | return {
21 | ngModule: <%= classify(name) %>Module,
22 | providers: getModuleProviders({
23 | controls: [
24 | <%= prefixClass ? classify(prefix) : '' %><%= classify(controlName) %>Component,
25 | ],
26 | }),
27 | };
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/libs/forms/lib/components/form/form.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { DynControlNode } from '@myndpm/dyn-forms/core';
3 | import { DynLogger } from '@myndpm/dyn-forms/logger';
4 | import { MockProvider } from 'ng-mocks';
5 | import { DynFormComponent } from './form.component';
6 |
7 | describe('DynFormComponent', () => {
8 | let component: DynFormComponent;
9 | let fixture: ComponentFixture;
10 |
11 | beforeEach(async () => {
12 | await TestBed.configureTestingModule({
13 | declarations: [DynFormComponent],
14 | providers: [
15 | MockProvider(DynLogger),
16 | MockProvider(DynControlNode),
17 | ],
18 | }).compileComponents();
19 | });
20 |
21 | beforeEach(() => {
22 | fixture = TestBed.createComponent(DynFormComponent);
23 | component = fixture.componentInstance;
24 | fixture.detectChanges();
25 | });
26 |
27 | it('should create', () => {
28 | expect(component).toBeTruthy();
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/single/success.control/success.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component } from '@angular/core';
2 | import {
3 | DynBaseConfig,
4 | DynFormContainer,
5 | DynMode,
6 | DynParams,
7 | DynPartialControlConfig,
8 | } from '@myndpm/dyn-forms/core';
9 |
10 | @Component({
11 | selector: 'app-form-single-success',
12 | templateUrl: './success.component.html',
13 | styleUrls: ['./success.component.scss'],
14 | changeDetection: ChangeDetectionStrategy.OnPush,
15 | })
16 | export class SingleSuccessComponent
17 | extends DynFormContainer {
18 |
19 | static dynControl: 'SUCCESS' = 'SUCCESS';
20 |
21 | static createConfig(
22 | partial?: DynPartialControlConfig
23 | ): DynBaseConfig {
24 | return {
25 | ...partial,
26 | control: SingleSuccessComponent.dynControl,
27 | // reset unsupported options
28 | wrappers: [],
29 | controls: [],
30 | };
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/libs/forms/lib/components/group/group.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { DynControlNode } from '@myndpm/dyn-forms/core';
3 | import { DynLogger } from '@myndpm/dyn-forms/logger';
4 | import { MockProvider } from 'ng-mocks';
5 | import { DynGroupComponent } from './group.component';
6 |
7 | describe('DynGroupComponent', () => {
8 | let component: DynGroupComponent;
9 | let fixture: ComponentFixture;
10 |
11 | beforeEach(async () => {
12 | await TestBed.configureTestingModule({
13 | declarations: [DynGroupComponent],
14 | providers: [
15 | MockProvider(DynLogger),
16 | MockProvider(DynControlNode),
17 | ],
18 | }).compileComponents();
19 | });
20 |
21 | beforeEach(() => {
22 | fixture = TestBed.createComponent(DynGroupComponent);
23 | component = fixture.componentInstance;
24 | fixture.detectChanges();
25 | });
26 |
27 | it('should create', () => {
28 | expect(component).toBeTruthy();
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Code of Conduct
2 |
3 | As contributors and maintainers of the @myndpm/open-source project, we pledge to respect everyone who contributes by posting issues, updating documentation, submitting pull requests, providing feedback in comments, and any other activities.
4 |
5 | Communication through any channel must be constructive and never resort to personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
6 |
7 | We promise to extend courtesy and respect to everyone involved in this project regardless of gender, gender identity, sexual orientation, disability, age, race, ethnicity, religion, or level of experience. We expect anyone contributing to the project to do the same.
8 |
9 | If any member of the community violates this code of conduct, the maintainers of the project may take action, removing issues, comments, and PRs or blocking accounts as deemed appropriate.
10 |
11 | If you are subject to or witness unacceptable behavior, or have any other concerns, please contact opensource at mynd.co.
12 |
--------------------------------------------------------------------------------
/libs/forms/lib/migrations/12_6_1/index.ts:
--------------------------------------------------------------------------------
1 | import { Rule, Tree } from '@angular-devkit/schematics';
2 |
3 | export default function (): Rule {
4 | return (tree: Tree) => {
5 | return tree.visit((path) => {
6 | if (path.includes('node_modules')) {
7 | return;
8 | }
9 |
10 | if (path.endsWith('.html') || path.endsWith('.scss') || path.endsWith('.sass')) {
11 | const buffer = tree.read(path);
12 | if (!buffer) {
13 | return;
14 | }
15 |
16 | const content = buffer.toString('utf-8');
17 |
18 | let newContent = content
19 | // update the class renames
20 | .replace(//g, '')
22 | // css renames
23 | .replace(/dyn-factory/g, '.dyn-control');
24 |
25 | // overwrite the tree only if there was a replacement
26 | if (content !== newContent) {
27 | tree.overwrite(path, newContent);
28 | }
29 | }
30 | });
31 | };
32 | }
33 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/wrappers/form-field/form-field.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 |
4 | // FIXME https://github.com/angular/components/pull/7083
5 | .mat-form-field {
6 | width: 100%;
7 | }
8 |
9 | &.readonly ::ng-deep {
10 |
11 | .mat-form-field-label-wrapper,
12 | .mat-form-field-outline,
13 | .mat-form-field-underline,
14 | .mat-error,
15 | .mat-hint {
16 | visibility: hidden;
17 | }
18 |
19 | .not-readonly {
20 | display: none;
21 | }
22 |
23 | .mat-form-field-appearance-fill .mat-form-field-flex {
24 | background: transparent;
25 | }
26 |
27 | // reset invalid colors in readonly
28 | .mat-form-field-invalid {
29 | &.mat-form-field {
30 | .mat-form-field-label {
31 | color: rgba(0, 0, 0, 0.6); // TODO mat-color
32 | }
33 | }
34 | &.mat-form-field-appearance-outline {
35 | .mat-form-field-outline-thick {
36 | color: rgba(0, 0, 0, 0.87); // TODO mat-color
37 | }
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/divider/divider.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, ChangeDetectionStrategy, HostBinding } from '@angular/core';
2 | import { DynConfig, DynFormContainer, DynMode, DynPartialControlConfig } from '@myndpm/dyn-forms/core';
3 | import { DynMatDividerParams } from './divider.component.params';
4 |
5 | @Component({
6 | selector: 'dyn-mat-divider',
7 | templateUrl: './divider.component.html',
8 | styleUrls: ['./divider.component.scss'],
9 | changeDetection: ChangeDetectionStrategy.OnPush
10 | })
11 | export class DynMatDividerComponent
12 | extends DynFormContainer {
13 |
14 | static dynControl: 'DIVIDER' = 'DIVIDER';
15 |
16 | static createConfig(
17 | partial: DynPartialControlConfig
18 | ): DynConfig {
19 | return {
20 | ...partial,
21 | control: DynMatDividerComponent.dynControl,
22 | };
23 | }
24 |
25 | @HostBinding('class.is-invisible')
26 | get isInvisible(): boolean {
27 | return Boolean(this.params.invisible);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/libs/forms/lib/schematics/control/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.html.template:
--------------------------------------------------------------------------------
1 | <% if(instance == 'Container') { %>
2 |
3 |
8 |
9 | <% }else if(instance == 'Array') { %>
10 |
20 | <% }else if(instance == 'Group') { %>
21 |
22 |
27 |
28 | <% }else if(instance == 'Control') { %>
29 |
30 |
31 |
32 |
33 |
34 | <% } %>
35 |
--------------------------------------------------------------------------------
/libs/forms/ui-native/src/controls/input/input.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component } from '@angular/core';
2 | import {
3 | DynConfig,
4 | DynFormControl,
5 | DynMode,
6 | DynPartialControlConfig,
7 | } from '@myndpm/dyn-forms/core';
8 | import { DynNatInputParams } from './input.component.params';
9 |
10 | @Component({
11 | selector: 'dyn-nat-input',
12 | templateUrl: './input.component.html',
13 | styleUrls: ['./input.component.scss'],
14 | changeDetection: ChangeDetectionStrategy.OnPush,
15 | })
16 | export class DynNatInputComponent
17 | extends DynFormControl {
18 |
19 | static dynControl: 'INPUT' = 'INPUT';
20 |
21 | static createConfig(
22 | partial: DynPartialControlConfig
23 | ): DynConfig {
24 | return {
25 | ...partial,
26 | control: DynNatInputComponent.dynControl,
27 | };
28 | }
29 |
30 | completeParams(params: Partial): DynNatInputParams {
31 | return {
32 | ...params,
33 | type: params.type || 'text',
34 | };
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/combo/combo.component.html:
--------------------------------------------------------------------------------
1 |
31 |
--------------------------------------------------------------------------------
/apps/website/src/assets/logos/tw.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/controls/input/input.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, ChangeDetectionStrategy } from '@angular/core';
2 | import {
3 | DynBaseConfig,
4 | DynFormControl,
5 | DynMode,
6 | DynPartialControlConfig,
7 | } from '@myndpm/dyn-forms/core';
8 | import { DynBsInputParams } from './input.component.params';
9 |
10 | @Component({
11 | selector: 'dyn-bs-input',
12 | templateUrl: './input.component.html',
13 | styleUrls: ['./input.component.scss'],
14 | changeDetection: ChangeDetectionStrategy.OnPush,
15 | })
16 | export class DynBsInputComponent
17 | extends DynFormControl {
18 |
19 | static dynControl: 'INPUT' = 'INPUT';
20 |
21 | static createConfig(
22 | partial: DynPartialControlConfig,
23 | ): DynBaseConfig {
24 | return {
25 | ...partial,
26 | control: DynBsInputComponent.dynControl,
27 | };
28 | }
29 |
30 | completeParams(params: Partial): DynBsInputParams {
31 | return {
32 | ...params,
33 | type: params.type || 'text',
34 | };
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/controls/radio/radio.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, ChangeDetectionStrategy } from '@angular/core';
2 | import {
3 | DynBaseConfig,
4 | DynFormControl,
5 | DynMode,
6 | DynPartialControlConfig,
7 | } from '@myndpm/dyn-forms/core';
8 | import { DynBsRadioParams } from './radio.component.params';
9 |
10 | @Component({
11 | selector: 'dyn-bs-radio',
12 | templateUrl: './radio.component.html',
13 | styleUrls: ['./radio.component.scss'],
14 | changeDetection: ChangeDetectionStrategy.OnPush,
15 | })
16 | export class DynBsRadioComponent
17 | extends DynFormControl {
18 |
19 | static dynControl: 'RADIO' = 'RADIO';
20 |
21 | static createConfig(
22 | partial: DynPartialControlConfig,
23 | ): DynBaseConfig {
24 | return {
25 | ...partial,
26 | control: DynBsRadioComponent.dynControl,
27 | };
28 | }
29 |
30 | completeParams(params: Partial): DynBsRadioParams {
31 | return {
32 | ...params,
33 | options: params.options || [],
34 | };
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/table-row/table-row.component.html:
--------------------------------------------------------------------------------
1 |
2 |
8 | |
9 |
10 |
11 |
17 |
18 |
24 |
25 |
32 |
33 |
39 | |
40 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/demos.module.ts:
--------------------------------------------------------------------------------
1 | import { CommonModule } from '@angular/common';
2 | import { NgModule } from '@angular/core';
3 | import { FlexLayoutModule } from '@angular/flex-layout';
4 | import { RouterModule, Routes } from '@angular/router';
5 | import { LayoutModule, LayoutWrapperComponent } from '../layout';
6 | import { IndexComponent } from './components/index/index.component';
7 |
8 | const routes: Routes = [
9 | {
10 | path: '',
11 | component: LayoutWrapperComponent,
12 | children: [
13 | {
14 | path: '',
15 | pathMatch: 'full',
16 | component: IndexComponent,
17 | },
18 | {
19 | path: 'dyn-forms',
20 | loadChildren: () =>
21 | import('./submodules/dyn-forms/dyn-forms.module').then(
22 | (m) => m.DemoFormsModule
23 | ),
24 | },
25 | ],
26 | },
27 | ];
28 |
29 | @NgModule({
30 | imports: [
31 | CommonModule,
32 | FlexLayoutModule,
33 | RouterModule.forChild(routes),
34 | LayoutModule,
35 | ],
36 | declarations: [IndexComponent],
37 | })
38 | export class DemosModule {}
39 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/builder/business.types.ts:
--------------------------------------------------------------------------------
1 | import { DynOption } from '@myndpm/dyn-forms/core';
2 |
3 | /**
4 | * Access Types
5 | */
6 | export enum MyndAccessType {
7 | CodeBox = "CODE_BOX",
8 | SmartLock = "SMART_LOCK"
9 | }
10 |
11 | export const accessTypes: DynOption[] = [
12 | {
13 | key: null,
14 | value: 'None',
15 | },
16 | {
17 | key: MyndAccessType.CodeBox,
18 | value: 'Code Box',
19 | },
20 | {
21 | key: MyndAccessType.SmartLock,
22 | value: 'Smart Lock',
23 | },
24 | ];
25 |
26 | /**
27 | * Unit Types
28 | */
29 | export enum MyndUnitType {
30 | Normal = "NORMAL",
31 | Parking = "PARKING",
32 | Storage = "STORAGE"
33 | }
34 |
35 | export const unitTypes: DynOption[] = [
36 | {
37 | key: MyndUnitType.Normal,
38 | value: 'Normal',
39 | },
40 | {
41 | key: MyndUnitType.Parking,
42 | value: 'Parking',
43 | },
44 | {
45 | key: MyndUnitType.Storage,
46 | value: 'Storage',
47 | },
48 | ];
49 |
50 | /**
51 | * Unit
52 | */
53 | export interface IMyndUnit {
54 | unitType: MyndUnitType;
55 | }
56 |
--------------------------------------------------------------------------------
/apps/website/src/app/pages/components/homepage/homepage.component.scss:
--------------------------------------------------------------------------------
1 | @import 'bootstrap/scss/functions';
2 | @import 'bootstrap/scss/variables';
3 | @import 'bootstrap/scss/mixins/breakpoints';
4 |
5 | header {
6 | background-color: #f2f2f7;
7 | height: 320px;
8 | margin-bottom: 20px;
9 | overflow: hidden;
10 | text-align: center;
11 |
12 | @include media-breakpoint-down(md) {
13 | height: 240px;
14 | }
15 |
16 | h2 {
17 | color: #38b87c;
18 | font-size: 56px;
19 | font-weight: 700;
20 | letter-spacing: -0.02em;
21 | line-height: 56px;
22 | margin: 15px 5px;
23 |
24 | @include media-breakpoint-down(lg) {
25 | font-size: 48px;
26 | }
27 | @include media-breakpoint-down(md) {
28 | font-size: 36px;
29 | }
30 | }
31 |
32 | span {
33 | font-size: 20px;
34 | font-weight: 300;
35 | line-height: 28px;
36 | }
37 | }
38 |
39 | main {
40 | p {
41 | text-align: center;
42 | }
43 |
44 | .call-to-action {
45 | margin: 20px 0 40px;
46 |
47 | button {
48 | font-size: 16px;
49 | line-height: 48px;
50 | }
51 | }
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/controls/select/select.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, ChangeDetectionStrategy } from '@angular/core';
2 | import {
3 | DynBaseConfig,
4 | DynFormControl,
5 | DynMode,
6 | DynPartialControlConfig,
7 | } from '@myndpm/dyn-forms/core';
8 | import { DynBsSelectParams } from './select.component.params';
9 |
10 | @Component({
11 | selector: 'dyn-bs-select',
12 | templateUrl: './select.component.html',
13 | styleUrls: ['./select.component.scss'],
14 | changeDetection: ChangeDetectionStrategy.OnPush,
15 | })
16 | export class DynBsSelectComponent
17 | extends DynFormControl {
18 |
19 | static dynControl: 'SELECT' = 'SELECT';
20 |
21 | static createConfig(
22 | partial: DynPartialControlConfig,
23 | ): DynBaseConfig {
24 | return {
25 | ...partial,
26 | control: DynBsSelectComponent.dynControl,
27 | };
28 | }
29 |
30 | completeParams(params: Partial): DynBsSelectParams {
31 | return {
32 | ...params,
33 | options: params.options || [],
34 | };
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/docs/dyn-forms/intro/9-schematics.md:
--------------------------------------------------------------------------------
1 | # Schematics
2 |
3 | We have schematics since the [v11.2.9-beta.9](https://github.com/myndpm/open-source/releases/tag/%40myndpm%2Fdyn-forms%4011.2.9-beta.9) release.
4 |
5 | In VSCode we can use the NxConsole plugin to run the schematics with a friendly UI.
6 |
7 | ## DynModules
8 |
9 | We can easily create new modules to store our DynControls with:
10 |
11 | ```bash
12 | ng generate @myndpm/dyn-forms:module
13 | --project=forms
14 | --path=libs/forms/ui-taiga/src
15 | --prefix=dyn-tui
16 | --prefixClass
17 | --name=DynFormsTaiga
18 | --controlName=input
19 | --id=INPUT
20 | ```
21 |
22 | ## DynControls
23 |
24 | And we can create the DynControl boilerplate with:
25 |
26 | ```bash
27 | ng generate @myndpm/dyn-forms:control
28 | --project=forms
29 | --path=libs/forms/ui-material/src/components
30 | --prefix=dyn-mat
31 | --prefixInterface=I
32 | --name=slider
33 | --id=SLIDER
34 | ```
35 |
36 | We saved a lot of time with these ones :)
37 |
38 | ## Next
39 |
40 | - Learn about the [ui-packages](/docs/dyn-forms/ui).
41 | - Check the [live examples](/docs/dyn-forms/examples).
42 |
--------------------------------------------------------------------------------
/libs/forms/testing/dyn-forms-testing.module.ts:
--------------------------------------------------------------------------------
1 | import { CommonModule } from '@angular/common';
2 | import { ModuleWithProviders, NgModule } from '@angular/core';
3 | import { ReactiveFormsModule } from '@angular/forms';
4 | import { DynFormsModule } from '@myndpm/dyn-forms';
5 | import { DynModuleProviders, getModuleProviders } from '@myndpm/dyn-forms/core';
6 | import { DynLogLevel } from '@myndpm/dyn-forms/logger';
7 | import { DynFormTestingComponent } from './form/form-testing.component';
8 |
9 | @NgModule({
10 | imports: [
11 | CommonModule,
12 | ReactiveFormsModule,
13 | DynFormsModule,
14 | ],
15 | declarations: [
16 | DynFormTestingComponent,
17 | ],
18 | exports: [
19 | ReactiveFormsModule,
20 | DynFormsModule,
21 | ],
22 | })
23 | export class DynFormsTestingModule {
24 | static forTest(args?: DynModuleProviders): ModuleWithProviders {
25 | return {
26 | ngModule: DynFormsTestingModule,
27 | providers: getModuleProviders({
28 | ...args,
29 | debug: args?.debug ? args.debug | DynLogLevel.Testing : undefined,
30 | }),
31 | };
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Mynd Property Management Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/controls/checkbox/checkbox.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, ChangeDetectionStrategy } from '@angular/core';
2 | import {
3 | DynBaseConfig,
4 | DynMode,
5 | DynFormControl,
6 | DynPartialControlConfig,
7 | } from '@myndpm/dyn-forms/core';
8 | import { DynBsCheckboxParams } from './checkbox.component.params';
9 |
10 | @Component({
11 | selector: 'dyn-bs-checkbox',
12 | templateUrl: './checkbox.component.html',
13 | styleUrls: ['./checkbox.component.scss'],
14 | changeDetection: ChangeDetectionStrategy.OnPush,
15 | })
16 | export class DynBsCheckboxComponent
17 | extends DynFormControl {
18 |
19 | static dynControl: 'CHECKBOX' = 'CHECKBOX';
20 |
21 | static createConfig(
22 | partial: DynPartialControlConfig,
23 | ): DynBaseConfig {
24 | return {
25 | ...partial,
26 | control: DynBsCheckboxComponent.dynControl,
27 | };
28 | }
29 |
30 | completeParams(params: Partial): DynBsCheckboxParams {
31 | return {
32 | ...params,
33 | label: params.label || '',
34 | };
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/array/array.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ params.title }}
5 | {{ params.subtitle }}
6 |
7 |
8 |
9 |
10 |
16 |
17 |
23 |
24 |
25 |
26 |
27 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/apps/website/src/app/docs/components/example/example.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | margin: 0 0 24px 0;
4 |
5 | app-docs-viewer {
6 | background: #1e1e1e;
7 | overflow: hidden;
8 | }
9 | }
10 |
11 |
12 |
13 | .docs-example-viewer-wrapper {
14 | border: 1px solid rgba(0, 0, 0, 0.2);
15 | border-radius: 4px;
16 | margin: 24px 0;
17 | h3 {
18 | margin-top: 10px;
19 | }
20 | }
21 |
22 |
23 |
24 | .docs-example-viewer-title {
25 | align-content: center;
26 | align-items: center;
27 | border-bottom: 1px solid rgba(0, 0, 0, 0.1);
28 | display: flex;
29 | justify-content: center;
30 | padding: 8px 8px 8px 16px;
31 | }
32 |
33 |
34 | .docs-example-viewer-title-spacer {
35 | flex: 1 1 auto;
36 | }
37 |
38 |
39 | .docs-example-viewer-body {
40 | padding: 30px;
41 | }
42 |
43 |
44 | .button-bar {
45 | color: #fff;
46 | position: absolute;
47 | padding: 8px;
48 | right: 0;
49 | }
50 |
51 |
52 | code-snippet {
53 | padding: 20px;
54 | }
55 |
56 |
57 | .docs-example-source {
58 | // TODO(annieyw): remove when standalone snippets are removed
59 | padding: 0;
60 | margin: 0;
61 | border: none;
62 | background: none;
63 | }
64 |
--------------------------------------------------------------------------------
/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "rootDir": ".",
5 | "sourceMap": true,
6 | "allowSyntheticDefaultImports": true,
7 | "declaration": false,
8 | "moduleResolution": "node",
9 | "experimentalDecorators": true,
10 | "importHelpers": true,
11 | "target": "es2015",
12 | "module": "esnext",
13 | "lib": ["es2018", "dom"],
14 | "esModuleInterop": true,
15 | "resolveJsonModule": true,
16 | "skipLibCheck": true,
17 | "skipDefaultLibCheck": true,
18 | "baseUrl": ".",
19 | "paths": {
20 | "@myndpm/demos": ["dist/libs/demos", "libs/demos/index.ts"],
21 | "@myndpm/demos/*": ["dist/libs/demos/*", "libs/demos/*"],
22 | "@myndpm/dyn-forms": ["libs/forms/index.ts"],
23 | "@myndpm/dyn-forms/core": ["libs/forms/core"],
24 | "@myndpm/dyn-forms/logger": ["libs/forms/logger"],
25 | "@myndpm/dyn-forms/ui-material": ["libs/forms/ui-material"],
26 | "@myndpm/dyn-forms/ui-native": ["libs/forms/ui-native"],
27 | "@myndpm/nx": ["libs/nx/src/index.ts"],
28 | "@myndpm/utils": ["libs/tools/utils/src/index.ts"]
29 | }
30 | },
31 | "exclude": ["node_modules", "tmp"]
32 | }
33 |
--------------------------------------------------------------------------------
/libs/forms/core/src/dyn-form-group.class.ts:
--------------------------------------------------------------------------------
1 | import { Directive, OnInit } from '@angular/core';
2 | import { UntypedFormGroup } from '@angular/forms';
3 | import { DynConfig } from './types/config.types';
4 | import { DynInstanceType } from './types/forms.types';
5 | import { DynMode } from './types/mode.types';
6 | import { DynParams } from './types/params.types';
7 | import { DynControl } from './dyn-control.class';
8 |
9 | @Directive()
10 | export abstract class DynFormGroup<
11 | TMode extends DynMode = DynMode,
12 | TParams extends DynParams = DynParams,
13 | TConfig extends DynConfig = DynConfig
14 | >
15 | extends DynControl
16 | implements OnInit {
17 |
18 | static dynInstance = DynInstanceType.Group;
19 |
20 | // auto-register in the form hierarchy
21 | ngOnInit(): void {
22 | // initialize the node
23 | this.node.init({
24 | ...this.config,
25 | instance: DynInstanceType.Group,
26 | component: this,
27 | });
28 |
29 | // provide the parameters
30 | super.ngOnInit();
31 |
32 | // log the successful initialization
33 | this._logger.nodeLoaded('dyn-form-group', this.node);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/index.ts:
--------------------------------------------------------------------------------
1 | export * from './array/array.component';
2 | export * from './array/array.component.params';
3 | export * from './card/card.component';
4 | export * from './card/card.component.params';
5 | export * from './checkbox/checkbox.component';
6 | export * from './checkbox/checkbox.component.params';
7 | export * from './container/container.component';
8 | export * from './container/container.component.params';
9 | export * from './datepicker/datepicker.component';
10 | export * from './datepicker/datepicker.component.params';
11 | export * from './divider/divider.component';
12 | export * from './divider/divider.component.params';
13 | export * from './input/input.component';
14 | export * from './input/input.component.params';
15 | export * from './multicheckbox/multicheckbox.component';
16 | export * from './multicheckbox/multicheckbox.component.params';
17 | export * from './radio/radio.component';
18 | export * from './radio/radio.component.params';
19 | export * from './select/select.component';
20 | export * from './select/select.component.params';
21 | export * from './table/table.component';
22 | export * from './table/table.component.params';
23 | export * from './table-row/table-row.component';
24 |
--------------------------------------------------------------------------------
/libs/utils/src/json.ts:
--------------------------------------------------------------------------------
1 | import { existsSync, readFileSync, writeFileSync } from 'fs';
2 |
3 | /**
4 | * Sync operations to manipulate JSON files.
5 | */
6 |
7 | const defaultPath = 'package.json';
8 |
9 | export function jsonExists(path: string = defaultPath): boolean {
10 | return existsSync(path);
11 | }
12 |
13 | export function jsonRead(path: string = defaultPath, field?: string): any {
14 | if (jsonExists(path)) {
15 | const jsonFile = jsonParse(readFileSync(path, { encoding: 'utf8' }));
16 | if (field && jsonFile.hasOwnProperty(field)) {
17 | return jsonFile[field];
18 | }
19 | return jsonFile;
20 | }
21 | return field ? null : {};
22 | }
23 |
24 | export function jsonParse(content: string): any {
25 | try {
26 | // parse the data
27 | return JSON.parse(content);
28 | } catch (e) {
29 | // filter any existing comments
30 | return JSON.parse(
31 | content
32 | .split('\n')
33 | .filter((line) => !line.match(/^\s*?\//))
34 | .join('\n')
35 | );
36 | }
37 | }
38 |
39 | export function jsonWrite(path: string, packageJson: any): void {
40 | return writeFileSync(path, `${JSON.stringify(packageJson, null, 2)}\n`, {
41 | encoding: 'utf8',
42 | });
43 | }
44 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/radio/radio.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component, HostBinding } from '@angular/core';
2 | import {
3 | DynConfig,
4 | DynFormControl,
5 | DynMode,
6 | DynPartialControlConfig,
7 | } from '@myndpm/dyn-forms/core';
8 | import { DynMatRadioParams } from './radio.component.params';
9 |
10 | @Component({
11 | selector: 'dyn-mat-radio',
12 | templateUrl: './radio.component.html',
13 | styleUrls: ['./radio.component.scss'],
14 | changeDetection: ChangeDetectionStrategy.OnPush,
15 | })
16 | export class DynMatRadioComponent
17 | extends DynFormControl {
18 |
19 | static dynControl: 'RADIO' = 'RADIO';
20 |
21 | static createConfig(
22 | partial: DynPartialControlConfig
23 | ): DynConfig {
24 | return {
25 | ...partial,
26 | control: DynMatRadioComponent.dynControl,
27 | };
28 | }
29 |
30 | @HostBinding('class.readonly')
31 | get isReadonly(): boolean {
32 | return Boolean(this.params.readonly);
33 | }
34 |
35 | completeParams(params: Partial): DynMatRadioParams {
36 | return {
37 | ...params,
38 | options: params.options || [],
39 | };
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/libs/demos/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demos",
3 | "$schema": "../../node_modules/nx/schemas/project-schema.json",
4 | "projectType": "library",
5 | "sourceRoot": "libs/demos/src",
6 | "prefix": "demo",
7 | "targets": {
8 | "prebuild": {
9 | "executor": "@nx/angular:package",
10 | "options": {
11 | "updateBuildableProjectDepsInPackageJson": true,
12 | "tsConfig": "libs/demos/tsconfig.lib.json",
13 | "project": "libs/demos/ng-package.json"
14 | },
15 | "configurations": {
16 | "production": {
17 | "tsConfig": "libs/demos/tsconfig.lib.prod.json"
18 | }
19 | }
20 | },
21 | "build": {
22 | "executor": "nx:run-commands",
23 | "options": {
24 | "parallel": false,
25 | "commands": [
26 | "yarn nx run demos:prebuild:production",
27 | "yarn install --ignore-scripts"
28 | ]
29 | }
30 | },
31 | "lint": {
32 | "executor": "@nx/linter:eslint",
33 | "options": {
34 | "lintFilePatterns": [
35 | "libs/demos/src/**/*.ts",
36 | "libs/demos/src/**/*.html"
37 | ]
38 | },
39 | "outputs": ["{options.outputFile}"]
40 | }
41 | },
42 | "tags": ["workspace"]
43 | }
44 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "ignorePatterns": ["**/*"],
4 | "plugins": ["@nx"],
5 | "overrides": [
6 | {
7 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
8 | "rules": {
9 | "@nx/enforce-module-boundaries": [
10 | "error",
11 | {
12 | "enforceBuildableLibDependency": true,
13 | "allow": [
14 | "@myndpm/dyn-forms",
15 | "@myndpm/dyn-forms/core",
16 | "@myndpm/dyn-forms/logger"
17 | ],
18 | "depConstraints": [
19 | {
20 | "sourceTag": "*",
21 | "onlyDependOnLibsWithTags": ["*"]
22 | }
23 | ]
24 | }
25 | ],
26 | "@typescript-eslint/ban-types": [
27 | "error",
28 | {
29 | "types": {
30 | "Function": false
31 | },
32 | "extendDefaults": true
33 | }
34 | ]
35 | }
36 | },
37 | {
38 | "files": ["*.ts", "*.tsx"],
39 | "extends": ["plugin:@nx/typescript"],
40 | "rules": {}
41 | },
42 | {
43 | "files": ["*.js", "*.jsx"],
44 | "extends": ["plugin:@nx/javascript"],
45 | "rules": {}
46 | }
47 | ]
48 | }
49 |
--------------------------------------------------------------------------------
/apps/website/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
4 | import { RouterModule, Routes } from '@angular/router';
5 | import { AppComponent } from './app.component';
6 | import { CustomBreakPointsProvider } from './bootstrap-breakpoints';
7 | import { LayoutModule } from './layout';
8 | import { PagesModule } from './pages/pages.module';
9 |
10 | const routes: Routes = [
11 | {
12 | path: 'demos',
13 | loadChildren: () =>
14 | import('./demos/demos.module').then((m) => m.DemosModule),
15 | },
16 | {
17 | path: '',
18 | loadChildren: () => import('./docs/docs.module').then((m) => m.DocsModule),
19 | },
20 | ];
21 |
22 | @NgModule({
23 | declarations: [AppComponent],
24 | imports: [
25 | BrowserModule.withServerTransition({
26 | appId: 'myndOpenSource',
27 | }),
28 | BrowserAnimationsModule,
29 | RouterModule.forRoot(routes, {
30 | initialNavigation: 'enabledBlocking',
31 | }),
32 | LayoutModule,
33 | PagesModule,
34 | ],
35 | providers: [CustomBreakPointsProvider],
36 | bootstrap: [AppComponent],
37 | })
38 | export class AppModule {}
39 |
--------------------------------------------------------------------------------
/libs/forms/core/src/dyn-form-container.class.ts:
--------------------------------------------------------------------------------
1 | import { Directive, OnInit } from '@angular/core';
2 | import { UntypedFormGroup } from '@angular/forms';
3 | import { DynBaseConfig } from './types/config.types';
4 | import { DynInstanceType } from './types/forms.types';
5 | import { DynMode } from './types/mode.types';
6 | import { DynParams } from './types/params.types';
7 | import { DynControl } from './dyn-control.class';
8 |
9 | @Directive()
10 | export abstract class DynFormContainer<
11 | TMode extends DynMode = DynMode,
12 | TParams extends DynParams = DynParams,
13 | TConfig extends DynBaseConfig = DynBaseConfig
14 | >
15 | extends DynControl
16 | implements OnInit {
17 |
18 | static dynInstance = DynInstanceType.Container;
19 |
20 | // auto-register in the form hierarchy
21 | ngOnInit(): void {
22 | // containers can initialize the node differently
23 | this.node.init({
24 | ...this.config,
25 | instance: DynInstanceType.Container,
26 | component: this,
27 | });
28 |
29 | // provide the parameters
30 | super.ngOnInit();
31 |
32 | // log the successful initialization
33 | this._logger.nodeLoaded('dyn-form-container', this.node);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/libs/demos/dyn-forms/basic/intro/form.config.ts:
--------------------------------------------------------------------------------
1 | import { DynFormConfig } from "@myndpm/dyn-forms";
2 | import { createMatConfig } from "@myndpm/dyn-forms/ui-material";
3 |
4 | export function formConfig(): DynFormConfig {
5 | return {
6 | controls: [
7 | createMatConfig('INPUT', {
8 | name: 'fullName',
9 | params: { label: 'Full Name' },
10 | }),
11 | createMatConfig('INPUT', {
12 | name: 'address',
13 | params: { label: 'Address' },
14 | }),
15 | createMatConfig('SELECT', {
16 | name: 'country',
17 | params: {
18 | label: 'Country',
19 | options: [
20 | { value: '- Choose one -', key: null },
21 | { value: 'Colombia', key: 'CO' },
22 | { value: 'United States', key: 'US' },
23 | { value: 'China', key: 'CN' },
24 | { value: 'Russia', key: 'RU' },
25 | { value: 'Other', key: 'XX' },
26 | ],
27 | },
28 | }),
29 | createMatConfig('RADIO', {
30 | name: 'terms',
31 | params: {
32 | options: [
33 | { value: 'Speaker', key: 'SPEAKER' },
34 | { value: 'Attendant', key: 'ATTENDANT' },
35 | ],
36 | },
37 | }),
38 | ],
39 | };
40 | }
41 |
--------------------------------------------------------------------------------
/libs/forms/ui-bootstrap/src/dyn-forms-bootstrap.module.ts:
--------------------------------------------------------------------------------
1 | import { CommonModule } from '@angular/common';
2 | import { ModuleWithProviders, NgModule } from '@angular/core';
3 | import { ReactiveFormsModule } from '@angular/forms';
4 | import { DynFormsModule } from '@myndpm/dyn-forms';
5 | import { getModuleProviders } from '@myndpm/dyn-forms/core';
6 | import {
7 | DynBsCheckboxComponent,
8 | DynBsInputComponent,
9 | DynBsRadioComponent,
10 | DynBsSelectComponent,
11 | } from './controls';
12 |
13 | @NgModule({
14 | imports: [
15 | CommonModule,
16 | ReactiveFormsModule,
17 | DynFormsModule,
18 | ],
19 | declarations: [
20 | DynBsCheckboxComponent,
21 | DynBsInputComponent,
22 | DynBsRadioComponent,
23 | DynBsSelectComponent,
24 | ],
25 | exports: [
26 | DynFormsModule, // reduce the boilerplate
27 | ],
28 | })
29 | export class DynFormsBootstrapModule {
30 | static forFeature(): ModuleWithProviders {
31 | return {
32 | ngModule: DynFormsBootstrapModule,
33 | providers: getModuleProviders({
34 | controls: [
35 | DynBsCheckboxComponent,
36 | DynBsInputComponent,
37 | DynBsRadioComponent,
38 | DynBsSelectComponent,
39 | ],
40 | }),
41 | };
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/components/index/index.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-demos-index',
5 | templateUrl: './index.component.html',
6 | styleUrls: ['./index.component.scss'],
7 | changeDetection: ChangeDetectionStrategy.OnPush,
8 | })
9 | export class IndexComponent {
10 | items = [
11 | {
12 | title: 'Simple Subscription Form',
13 | link: './dyn-forms/single-form',
14 | description: 'Simple dyn-forms demo with custom modes.',
15 | },
16 | {
17 | title: 'Simple Dynamic Form',
18 | link: './dyn-forms/simple-form',
19 | description: 'Simple dyn-forms demo with display mode.',
20 | },
21 | {
22 | title: 'Combo Selectors Form',
23 | link: './dyn-forms/combo-form',
24 | description: 'Demo of selector updated with another selection.',
25 | },
26 | {
27 | title: 'Dynamic Stepper Form',
28 | link: './dyn-forms/stepper-form',
29 | description: 'Demo of dyn-forms under different router-outlets.',
30 | },
31 | {
32 | title: 'Config Builder Form',
33 | link: './dyn-forms/builder',
34 | description: 'Real use-case building a configuration with a custom condition and matcher.',
35 | },
36 | ];
37 | }
38 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/constants/dyn-forms.links.ts:
--------------------------------------------------------------------------------
1 | import { SectionAction, SectionBadge } from '../../../../layout';
2 |
3 | export const badges: SectionBadge[] = [
4 | {
5 | link: "https://github.com/myndpm/open-source/tree/master/libs/forms",
6 | img: "https://img.shields.io/badge/%40myndpm-dyn--forms-brightgreen",
7 | alt: "Package",
8 | },
9 | {
10 | link: "https://www.npmjs.com/package/@myndpm/dyn-forms",
11 | img: "https://badge.fury.io/js/%40myndpm%2Fdyn-forms.svg",
12 | alt: "NPM Badge",
13 | },
14 | {
15 | link: "https://npmcharts.com/compare/@myndpm/dyn-forms?minimal=true",
16 | img: "https://img.shields.io/npm/dm/@myndpm/dyn-forms.svg?style=flat",
17 | alt: "NPM Downloads",
18 | },
19 | ];
20 |
21 | export const actions: SectionAction[] = [
22 | {
23 | link: "https://prezi.com/view/4Ok1bgCWvf0g26FMVwfx/",
24 | ionicon: 'easel-outline',
25 | tooltip: 'Prezi',
26 | },
27 | {
28 | link: "https://dev.to/myndpm/a-new-approach-to-have-dynamic-forms-in-angular-5d11",
29 | icon: 'article',
30 | tooltip: 'Article',
31 | },
32 | {
33 | link: "https://stackblitz.com/edit/myndpm-dyn-forms?file=src/app/simple-form/simple.form.ts",
34 | ionicon: 'logo-angular',
35 | tooltip: 'Stackblitz',
36 | },
37 | ];
38 |
--------------------------------------------------------------------------------
/apps/website/src/app/pages/components/homepage/homepage.component.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
High Quality
12 |
13 | Clear and consistent code, inline documented
14 | to easily understand the purpose of each section.
15 |
16 |
17 |
18 |
19 |
Flexible
20 |
21 | Generic software for multiple purposes and use cases,
22 | to save time and avoid boilerplate.
23 |
24 |
25 |
26 |
27 |
Supported
28 |
29 | Backed by a big company with a large number
30 | of Senior Software Developers.
31 |
32 |
33 |
34 |
35 |
36 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/libs/forms/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "overrides": [
5 | {
6 | "files": ["*.ts"],
7 | "extends": [
8 | "plugin:@nx/angular",
9 | "plugin:@angular-eslint/template/process-inline-templates"
10 | ],
11 | "rules": {
12 | "@angular-eslint/directive-selector": [
13 | "error",
14 | {
15 | "type": "attribute",
16 | "prefix": "dyn",
17 | "style": "camelCase"
18 | }
19 | ],
20 | "@angular-eslint/component-selector": [
21 | "error",
22 | {
23 | "type": "element",
24 | "prefix": "dyn",
25 | "style": "kebab-case"
26 | }
27 | ],
28 | "@angular-eslint/directive-class-suffix": 0,
29 | "@typescript-eslint/member-ordering": 0,
30 | "@typescript-eslint/no-empty-function": 0,
31 | "@typescript-eslint/no-empty-interface": 0,
32 | "@typescript-eslint/no-explicit-any": 0,
33 | "@typescript-eslint/no-non-null-assertion": 0,
34 | "@typescript-eslint/no-unused-vars": 0
35 | }
36 | },
37 | {
38 | "files": ["*.html"],
39 | "extends": ["plugin:@nx/angular-template"],
40 | "rules": {}
41 | }
42 | ]
43 | }
44 |
--------------------------------------------------------------------------------
/libs/forms/ui-native/src/controls/input/input.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { ReactiveFormsModule } from '@angular/forms';
3 | import { DynFormsModule } from '@myndpm/dyn-forms';
4 | import { DynControlNode } from '@myndpm/dyn-forms/core';
5 | import { DynLogger } from '@myndpm/dyn-forms/logger';
6 | import { MockProvider } from 'ng-mocks';
7 | import { DynNatInputComponent } from './input.component';
8 |
9 | describe('DynNatInputComponent', () => {
10 | let component: DynNatInputComponent;
11 | let fixture: ComponentFixture;
12 |
13 | beforeEach(async () => {
14 | await TestBed.configureTestingModule({
15 | imports: [
16 | ReactiveFormsModule,
17 | DynFormsModule.forFeature({
18 | controls: [],
19 | }),
20 | ],
21 | declarations: [DynNatInputComponent],
22 | providers: [
23 | MockProvider(DynLogger),
24 | MockProvider(DynControlNode),
25 | ],
26 | }).compileComponents();
27 | });
28 |
29 | beforeEach(() => {
30 | fixture = TestBed.createComponent(DynNatInputComponent);
31 | component = fixture.componentInstance;
32 | fixture.detectChanges();
33 | });
34 |
35 | it('should create', () => {
36 | expect(component).toBeTruthy();
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/combo/combo.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from "@angular/core";
2 | import { DynOption } from "@myndpm/dyn-forms/core";
3 |
4 | @Injectable()
5 | export class ComboService {
6 |
7 | getCountries(): DynOption[] {
8 | return [
9 | { key: null, value: '- Choose one -' },
10 | { key: 'CO', value: 'Colombia' },
11 | { key: 'US', value: 'United States' },
12 | { key: 'RU', value: 'Rusia' },
13 | { key: 'UA', value: 'Ukraine' },
14 | ];
15 | }
16 |
17 | getCities(country?: string): DynOption[] {
18 | if (!country) {
19 | return [];
20 | }
21 |
22 | switch (country) {
23 | case 'CO':
24 | return [
25 | { key: 'MDE', value: 'Medellin' },
26 | { key: 'BOG', value: 'Bogotá' },
27 | ];
28 | case 'US':
29 | return [
30 | { key: 'NYC', value: 'New York' },
31 | { key: 'OAK', value: 'Oakland' },
32 | ];
33 | case 'RU':
34 | return [
35 | { key: 'MSK', value: 'Moscow' },
36 | { key: 'SPB', value: 'Saint Petersburg' },
37 | ];
38 | case 'UA':
39 | return [
40 | { key: 'IEV', value: 'Kiev' },
41 | { key: 'KIV', value: 'Kharkiv' },
42 | ];
43 | }
44 | }
45 |
46 | }
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/card/card.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { MatLegacyCardModule as MatCardModule } from '@angular/material/legacy-card';
3 | import { DynFormsModule } from '@myndpm/dyn-forms';
4 | import { DynControlNode } from '@myndpm/dyn-forms/core';
5 | import { DynLogger } from '@myndpm/dyn-forms/logger';
6 | import { MockProvider } from 'ng-mocks';
7 | import { DynMatCardComponent } from './card.component';
8 |
9 | describe('DynMatCardComponent', () => {
10 | let component: DynMatCardComponent;
11 | let fixture: ComponentFixture;
12 |
13 | beforeEach(async () => {
14 | await TestBed.configureTestingModule({
15 | imports: [
16 | DynFormsModule.forFeature({
17 | controls: [],
18 | }),
19 | MatCardModule,
20 | ],
21 | declarations: [DynMatCardComponent],
22 | providers: [
23 | MockProvider(DynLogger),
24 | MockProvider(DynControlNode),
25 | ],
26 | }).compileComponents();
27 | });
28 |
29 | beforeEach(() => {
30 | fixture = TestBed.createComponent(DynMatCardComponent);
31 | component = fixture.componentInstance;
32 | fixture.detectChanges();
33 | });
34 |
35 | it('should create', () => {
36 | expect(component).toBeTruthy();
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/array/array.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { MatLegacyCardModule as MatCardModule } from '@angular/material/legacy-card';
3 | import { DynLogger } from '@myndpm/dyn-forms/logger';
4 | import { DynFormsModule } from '@myndpm/dyn-forms';
5 | import { DynControlNode } from '@myndpm/dyn-forms/core';
6 | import { MockProvider } from 'ng-mocks';
7 | import { DynMatArrayComponent } from './array.component';
8 |
9 | describe('DynMatArrayComponent', () => {
10 | let component: DynMatArrayComponent;
11 | let fixture: ComponentFixture;
12 |
13 | beforeEach(async () => {
14 | await TestBed.configureTestingModule({
15 | imports: [
16 | DynFormsModule.forFeature({
17 | controls: [],
18 | }),
19 | MatCardModule,
20 | ],
21 | declarations: [DynMatArrayComponent],
22 | providers: [
23 | MockProvider(DynLogger),
24 | MockProvider(DynControlNode),
25 | ],
26 | }).compileComponents();
27 | });
28 |
29 | beforeEach(() => {
30 | fixture = TestBed.createComponent(DynMatArrayComponent);
31 | component = fixture.componentInstance;
32 | fixture.detectChanges();
33 | });
34 |
35 | it('should create', () => {
36 | expect(component).toBeTruthy();
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/radio/radio.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { MatLegacyRadioModule as MatRadioModule } from '@angular/material/legacy-radio';
3 | import { DynFormsModule } from '@myndpm/dyn-forms';
4 | import { DynControlNode } from '@myndpm/dyn-forms/core';
5 | import { DynLogger } from '@myndpm/dyn-forms/logger';
6 | import { MockProvider } from 'ng-mocks';
7 | import { DynMatRadioComponent } from './radio.component';
8 |
9 | describe('DynMatRadioComponent', () => {
10 | let component: DynMatRadioComponent;
11 | let fixture: ComponentFixture;
12 |
13 | beforeEach(async () => {
14 | await TestBed.configureTestingModule({
15 | imports: [
16 | DynFormsModule.forFeature({
17 | controls: [],
18 | }),
19 | MatRadioModule,
20 | ],
21 | declarations: [DynMatRadioComponent],
22 | providers: [
23 | MockProvider(DynLogger),
24 | MockProvider(DynControlNode),
25 | ],
26 | }).compileComponents();
27 | });
28 |
29 | beforeEach(() => {
30 | fixture = TestBed.createComponent(DynMatRadioComponent);
31 | component = fixture.componentInstance;
32 | fixture.detectChanges();
33 | });
34 |
35 | it('should create', () => {
36 | expect(component).toBeTruthy();
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/checkbox/checkbox.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component, HostBinding } from '@angular/core';
2 | import {
3 | DynConfig,
4 | DynFormControl,
5 | DynMode,
6 | DynPartialControlConfig,
7 | } from '@myndpm/dyn-forms/core';
8 | import { DynMatCheckboxParams } from './checkbox.component.params';
9 |
10 | @Component({
11 | selector: 'dyn-mat-checkbox',
12 | templateUrl: './checkbox.component.html',
13 | styleUrls: ['./checkbox.component.scss'],
14 | changeDetection: ChangeDetectionStrategy.OnPush,
15 | })
16 | export class DynMatCheckboxComponent
17 | extends DynFormControl {
18 |
19 | static dynControl: 'CHECKBOX' = 'CHECKBOX';
20 |
21 | static createConfig(
22 | partial: DynPartialControlConfig
23 | ): DynConfig {
24 | return {
25 | ...partial,
26 | control: DynMatCheckboxComponent.dynControl,
27 | };
28 | }
29 |
30 | @HostBinding('class.readonly')
31 | get isReadonly(): boolean {
32 | return Boolean(this.params.readonly);
33 | }
34 |
35 | completeParams(params: Partial): DynMatCheckboxParams {
36 | return {
37 | ...params,
38 | label: params.label || '-missing label-',
39 | labelPosition: params.labelPosition || 'after',
40 | };
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/select/select.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { MatLegacySelectModule as MatSelectModule } from '@angular/material/legacy-select';
3 | import { DynFormsModule } from '@myndpm/dyn-forms';
4 | import { DynControlNode } from '@myndpm/dyn-forms/core';
5 | import { DynLogger } from '@myndpm/dyn-forms/logger';
6 | import { MockProvider } from 'ng-mocks';
7 | import { DynMatSelectComponent } from './select.component';
8 |
9 | describe('DynMatSelectComponent', () => {
10 | let component: DynMatSelectComponent;
11 | let fixture: ComponentFixture;
12 |
13 | beforeEach(async () => {
14 | await TestBed.configureTestingModule({
15 | imports: [
16 | DynFormsModule.forFeature({
17 | controls: [],
18 | }),
19 | MatSelectModule,
20 | ],
21 | declarations: [DynMatSelectComponent],
22 | providers: [
23 | MockProvider(DynLogger),
24 | MockProvider(DynControlNode),
25 | ],
26 | }).compileComponents();
27 | });
28 |
29 | beforeEach(() => {
30 | fixture = TestBed.createComponent(DynMatSelectComponent);
31 | component = fixture.componentInstance;
32 | fixture.detectChanges();
33 | });
34 |
35 | it('should create', () => {
36 | expect(component).toBeTruthy();
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/input/input.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { MatLegacyFormFieldModule as MatFormFieldModule } from '@angular/material/legacy-form-field';
3 | import { DynFormsModule } from '@myndpm/dyn-forms';
4 | import { DynControlNode } from '@myndpm/dyn-forms/core';
5 | import { DynLogger } from '@myndpm/dyn-forms/logger';
6 | import { MockProvider } from 'ng-mocks';
7 | import { DynMatInputComponent } from './input.component';
8 |
9 | describe('DynMatInputComponent', () => {
10 | let component: DynMatInputComponent;
11 | let fixture: ComponentFixture;
12 |
13 | beforeEach(async () => {
14 | await TestBed.configureTestingModule({
15 | imports: [
16 | DynFormsModule.forFeature({
17 | controls: [],
18 | }),
19 | MatFormFieldModule,
20 | ],
21 | declarations: [DynMatInputComponent],
22 | providers: [
23 | MockProvider(DynLogger),
24 | MockProvider(DynControlNode),
25 | ],
26 | }).compileComponents();
27 | });
28 |
29 | beforeEach(() => {
30 | fixture = TestBed.createComponent(DynMatInputComponent);
31 | component = fixture.componentInstance;
32 | fixture.detectChanges();
33 | });
34 |
35 | it('should create', () => {
36 | expect(component).toBeTruthy();
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/libs/forms/core/src/types/config.types.ts:
--------------------------------------------------------------------------------
1 | import { DynControlConfig } from './control.types';
2 | import { DynVisibility } from './forms.types';
3 | import { DynMode, DynModes } from './mode.types';
4 | import { DynParams } from './params.types';
5 |
6 | // single form container/group/array config
7 | export interface DynBaseConfig<
8 | TMode extends DynMode = DynMode,
9 | TParams extends DynParams = DynParams,
10 | > extends DynControlConfig {
11 | // form/data hierarchy
12 | name?: string; // optional fieldName
13 | controls?: DynBaseConfig[];
14 | modes?: DynModes;
15 | visibility?: DynVisibility;
16 | isolated?: boolean; // not part of the form hierarchy
17 | debug?: number;
18 | }
19 |
20 | // single form control config
21 | export interface DynConfig<
22 | TMode extends DynMode = DynMode,
23 | TParams extends DynParams = DynParams,
24 | > extends DynBaseConfig {
25 | // form/data hierarchy
26 | name: string; // mandatory fieldName
27 | }
28 |
29 | // useful types for Factory Method partial params
30 | export type DynPartialGroupConfig<
31 | TMode extends DynMode = DynMode,
32 | TParams extends DynParams = DynParams,
33 | > = Omit, 'control'>;
34 |
35 | export type DynPartialControlConfig<
36 | TMode extends DynMode = DynMode,
37 | TParams extends DynParams = DynParams,
38 | > = Omit, 'control'>;
39 |
--------------------------------------------------------------------------------
/libs/forms/ui-material/src/controls/checkbox/checkbox.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { MatLegacyFormFieldModule as MatFormFieldModule } from '@angular/material/legacy-form-field';
3 | import { DynFormsModule } from '@myndpm/dyn-forms';
4 | import { DynControlNode } from '@myndpm/dyn-forms/core';
5 | import { DynLogger } from '@myndpm/dyn-forms/logger';
6 | import { MockProvider } from 'ng-mocks';
7 | import { DynMatCheckboxComponent } from './checkbox.component';
8 |
9 | describe('DynMatCheckboxComponent', () => {
10 | let component: DynMatCheckboxComponent;
11 | let fixture: ComponentFixture;
12 |
13 | beforeEach(async () => {
14 | await TestBed.configureTestingModule({
15 | imports: [
16 | DynFormsModule.forFeature({
17 | controls: [],
18 | }),
19 | MatFormFieldModule,
20 | ],
21 | declarations: [DynMatCheckboxComponent],
22 | providers: [
23 | MockProvider(DynLogger),
24 | MockProvider(DynControlNode),
25 | ],
26 | }).compileComponents();
27 | });
28 |
29 | beforeEach(() => {
30 | fixture = TestBed.createComponent(DynMatCheckboxComponent);
31 | component = fixture.componentInstance;
32 | fixture.detectChanges();
33 | });
34 |
35 | it('should create', () => {
36 | expect(component).toBeTruthy();
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/simple/simple.component.html:
--------------------------------------------------------------------------------
1 |
39 |
--------------------------------------------------------------------------------
/apps/website/src/app/demos/submodules/dyn-forms/components/stepper/stepper.component.ts:
--------------------------------------------------------------------------------
1 | import {
2 | AfterViewInit,
3 | ChangeDetectionStrategy,
4 | Component,
5 | OnDestroy,
6 | ViewChild,
7 | } from '@angular/core';
8 | import { UntypedFormGroup } from '@angular/forms';
9 | import { DynFormComponent } from '@myndpm/dyn-forms';
10 | import { actions, badges } from '../../constants/dyn-forms.links';
11 |
12 | @Component({
13 | selector: 'app-form-stepper',
14 | templateUrl: './stepper.component.html',
15 | styleUrls: ['./stepper.component.scss'],
16 | changeDetection: ChangeDetectionStrategy.OnPush,
17 | })
18 | export class StepperComponent implements AfterViewInit, OnDestroy {
19 | // ref links
20 | badges = badges;
21 | actions = [
22 | {
23 | link: "https://github.com/myndpm/open-source/tree/master/apps/website/src/app/demos/submodules/dyn-forms/components/stepper",
24 | icon: 'code',
25 | tooltip: 'See source code',
26 | },
27 | ...actions,
28 | ];
29 |
30 | form = new UntypedFormGroup({});
31 |
32 | @ViewChild(DynFormComponent, { static: true })
33 | dynForm: DynFormComponent;
34 |
35 | ngAfterViewInit(): void {
36 | this.form.patchValue({ choices: [1] });
37 | // logs each change in the console just to demo
38 | this.dynForm.valueChanges().subscribe(console.log);
39 | }
40 |
41 | ngOnDestroy(): void {
42 | console.clear();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------