├── app
├── helpers
│ └── .keep
├── mailers
│ └── .keep
├── models
│ ├── .keep
│ └── flow_core
│ │ ├── application_record.rb
│ │ ├── end_place.rb
│ │ ├── start_place.rb
│ │ └── steps
│ │ ├── task.rb
│ │ ├── end.rb
│ │ └── redirection.rb
├── views
│ └── .keep
└── controllers
│ └── .keep
├── test
├── dummy
│ ├── log
│ │ └── .keep
│ ├── lib
│ │ └── assets
│ │ │ └── .keep
│ ├── mruby
│ │ ├── lib
│ │ │ ├── .keep
│ │ │ ├── harden.rb
│ │ │ ├── output.rb
│ │ │ ├── script_kernel.rb
│ │ │ ├── io.rb
│ │ │ └── input.rb
│ │ └── engine.gembox
│ ├── storage
│ │ └── .keep
│ ├── public
│ │ ├── favicon.ico
│ │ ├── apple-touch-icon.png
│ │ └── apple-touch-icon-precomposed.png
│ ├── app
│ │ ├── assets
│ │ │ ├── images
│ │ │ │ └── .keep
│ │ │ ├── config
│ │ │ │ └── manifest.js
│ │ │ ├── javascripts
│ │ │ │ └── application.es6
│ │ │ └── stylesheets
│ │ │ │ ├── selectize
│ │ │ │ └── plugins
│ │ │ │ │ ├── optgroup_columns.scss
│ │ │ │ │ ├── drag_drop.scss
│ │ │ │ │ └── dropdown_header.scss
│ │ │ │ └── application.scss
│ │ ├── models
│ │ │ ├── concerns
│ │ │ │ ├── .keep
│ │ │ │ └── form_kit
│ │ │ │ │ ├── validations
│ │ │ │ │ ├── presence.rb
│ │ │ │ │ ├── acceptance.rb
│ │ │ │ │ ├── confirmation.rb
│ │ │ │ │ └── uniqueness.rb
│ │ │ │ │ └── options
│ │ │ │ │ └── data_source.rb
│ │ │ ├── application_record.rb
│ │ │ ├── form_kit
│ │ │ │ ├── non_configurable.rb
│ │ │ │ ├── fields
│ │ │ │ │ ├── nested_form
│ │ │ │ │ │ ├── options.rb
│ │ │ │ │ │ └── validations.rb
│ │ │ │ │ ├── resource
│ │ │ │ │ │ ├── options.rb
│ │ │ │ │ │ └── validations.rb
│ │ │ │ │ ├── text
│ │ │ │ │ │ ├── options.rb
│ │ │ │ │ │ └── validations.rb
│ │ │ │ │ ├── select
│ │ │ │ │ │ ├── options.rb
│ │ │ │ │ │ ├── validations.rb
│ │ │ │ │ │ └── fakable.rb
│ │ │ │ │ ├── boolean
│ │ │ │ │ │ └── validations.rb
│ │ │ │ │ ├── date_range
│ │ │ │ │ │ └── validations.rb
│ │ │ │ │ ├── decimal_range
│ │ │ │ │ │ └── validations.rb
│ │ │ │ │ ├── integer_range
│ │ │ │ │ │ └── validations.rb
│ │ │ │ │ ├── multiple_resource
│ │ │ │ │ │ ├── options.rb
│ │ │ │ │ │ └── validations.rb
│ │ │ │ │ ├── datetime_range
│ │ │ │ │ │ └── validations.rb
│ │ │ │ │ ├── multiple_select
│ │ │ │ │ │ ├── options.rb
│ │ │ │ │ │ ├── validations.rb
│ │ │ │ │ │ └── fakable.rb
│ │ │ │ │ ├── date
│ │ │ │ │ │ └── validations.rb
│ │ │ │ │ ├── choice
│ │ │ │ │ │ ├── validations.rb
│ │ │ │ │ │ └── fakable.rb
│ │ │ │ │ ├── datetime
│ │ │ │ │ │ └── validations.rb
│ │ │ │ │ ├── multiple_choice
│ │ │ │ │ │ ├── validations.rb
│ │ │ │ │ │ └── fakable.rb
│ │ │ │ │ ├── resource_select
│ │ │ │ │ │ ├── validations.rb
│ │ │ │ │ │ └── options.rb
│ │ │ │ │ ├── multiple_nested_form
│ │ │ │ │ │ └── validations.rb
│ │ │ │ │ ├── multiple_resource_select
│ │ │ │ │ │ ├── validations.rb
│ │ │ │ │ │ └── options.rb
│ │ │ │ │ ├── text.rb
│ │ │ │ │ ├── decimal.rb
│ │ │ │ │ ├── boolean.rb
│ │ │ │ │ ├── decimal
│ │ │ │ │ │ ├── validations.rb
│ │ │ │ │ │ └── options.rb
│ │ │ │ │ ├── integer
│ │ │ │ │ │ ├── validations.rb
│ │ │ │ │ │ └── options.rb
│ │ │ │ │ ├── integer.rb
│ │ │ │ │ ├── date.rb
│ │ │ │ │ ├── datetime.rb
│ │ │ │ │ ├── date_range.rb
│ │ │ │ │ ├── datetime_range.rb
│ │ │ │ │ ├── decimal_range.rb
│ │ │ │ │ ├── integer_range.rb
│ │ │ │ │ ├── select.rb
│ │ │ │ │ ├── multiple_select.rb
│ │ │ │ │ ├── choice.rb
│ │ │ │ │ ├── resource.rb
│ │ │ │ │ ├── resource_select.rb
│ │ │ │ │ ├── multiple_choice.rb
│ │ │ │ │ ├── multiple_resource.rb
│ │ │ │ │ ├── multiple_resource_select.rb
│ │ │ │ │ ├── nested_form.rb
│ │ │ │ │ └── multiple_nested_form.rb
│ │ │ │ ├── nested_form.rb
│ │ │ │ ├── data_sources.rb
│ │ │ │ ├── form.rb
│ │ │ │ ├── field_options.rb
│ │ │ │ ├── field
│ │ │ │ │ ├── fakable.rb
│ │ │ │ │ └── helper.rb
│ │ │ │ ├── application_record.rb
│ │ │ │ ├── choice.rb
│ │ │ │ ├── field_override.rb
│ │ │ │ ├── data_sources
│ │ │ │ │ └── empty.rb
│ │ │ │ ├── embeds
│ │ │ │ │ ├── decimal_range.rb
│ │ │ │ │ ├── integer_range.rb
│ │ │ │ │ ├── date_range.rb
│ │ │ │ │ └── datetime_range.rb
│ │ │ │ ├── form_override.rb
│ │ │ │ ├── virtual_model.rb
│ │ │ │ └── fields.rb
│ │ │ ├── notification.rb
│ │ │ ├── user.rb
│ │ │ └── flow_kit
│ │ │ │ ├── arc_guards.rb
│ │ │ │ ├── transition_triggers.rb
│ │ │ │ ├── assignee_candidate.rb
│ │ │ │ ├── steps.rb
│ │ │ │ ├── arc_guards
│ │ │ │ ├── ruby_script
│ │ │ │ │ └── configuration.rb
│ │ │ │ └── ruby_script.rb
│ │ │ │ ├── business_pipeline.rb
│ │ │ │ ├── business_workflow.rb
│ │ │ │ └── transition_triggers
│ │ │ │ ├── timer.rb
│ │ │ │ ├── timer
│ │ │ │ └── configuration.rb
│ │ │ │ └── human_task
│ │ │ │ └── configuration.rb
│ │ ├── controllers
│ │ │ ├── concerns
│ │ │ │ └── .keep
│ │ │ ├── home_controller.rb
│ │ │ ├── instances
│ │ │ │ ├── application_controller.rb
│ │ │ │ └── tasks_controller.rb
│ │ │ ├── workflows
│ │ │ │ ├── application_controller.rb
│ │ │ │ ├── transitions
│ │ │ │ │ └── application_controller.rb
│ │ │ │ ├── arcs_controller.rb
│ │ │ │ ├── transitions_controller.rb
│ │ │ │ └── instances_controller.rb
│ │ │ ├── pipelines
│ │ │ │ ├── application_controller.rb
│ │ │ │ ├── steps
│ │ │ │ │ ├── application_controller.rb
│ │ │ │ │ ├── branches_controller.rb
│ │ │ │ │ └── redirections_controller.rb
│ │ │ │ ├── branches
│ │ │ │ │ ├── application_controller.rb
│ │ │ │ │ └── steps_controller.rb
│ │ │ │ └── branches_controller.rb
│ │ │ ├── session_controller.rb
│ │ │ ├── notifications_controller.rb
│ │ │ ├── application_controller.rb
│ │ │ ├── human_tasks_controller.rb
│ │ │ ├── forms
│ │ │ │ ├── application_controller.rb
│ │ │ │ └── previews_controller.rb
│ │ │ ├── fields
│ │ │ │ ├── options_controller.rb
│ │ │ │ ├── validations_controller.rb
│ │ │ │ └── data_source_options_controller.rb
│ │ │ └── instances_controller.rb
│ │ ├── views
│ │ │ ├── layouts
│ │ │ │ ├── mailer.text.erb
│ │ │ │ ├── _footer.html.erb
│ │ │ │ ├── mailer.html.erb
│ │ │ │ ├── _alert.html.erb
│ │ │ │ ├── application.html.erb
│ │ │ │ └── _breadcrumb.html.erb
│ │ │ ├── _form_core
│ │ │ │ ├── data_source_options
│ │ │ │ │ ├── _empty.html.erb
│ │ │ │ │ └── _dictionary.html.erb
│ │ │ │ ├── validations
│ │ │ │ │ ├── _exclusion.html.erb
│ │ │ │ │ ├── _inclusion.html.erb
│ │ │ │ │ ├── _presence.html.erb
│ │ │ │ │ ├── _uniqueness.html.erb
│ │ │ │ │ ├── _acceptance.html.erb
│ │ │ │ │ ├── _confirmation.html.erb
│ │ │ │ │ ├── _format.html.erb
│ │ │ │ │ └── _length.html.erb
│ │ │ │ ├── field_options
│ │ │ │ │ ├── _integer.html.erb
│ │ │ │ │ ├── _decimal.html.erb
│ │ │ │ │ ├── _resource.html.erb
│ │ │ │ │ ├── _text.html.erb
│ │ │ │ │ ├── _select.html.erb
│ │ │ │ │ ├── _multiple_select.html.erb
│ │ │ │ │ ├── _resource_select.html.erb
│ │ │ │ │ ├── _multiple_resource.html.erb
│ │ │ │ │ └── _multiple_resource_select.html.erb
│ │ │ │ ├── render
│ │ │ │ │ └── _form.html.erb
│ │ │ │ ├── _nested_form.html.erb
│ │ │ │ ├── fields
│ │ │ │ │ ├── _date.html.erb
│ │ │ │ │ ├── _datetime.html.erb
│ │ │ │ │ ├── _decimal.html.erb
│ │ │ │ │ ├── _integer.html.erb
│ │ │ │ │ ├── _boolean.html.erb
│ │ │ │ │ ├── _choice.html.erb
│ │ │ │ │ ├── _multiple_choice.html.erb
│ │ │ │ │ ├── _text.html.erb
│ │ │ │ │ ├── _resource.html.erb
│ │ │ │ │ ├── _select.html.erb
│ │ │ │ │ ├── _resource_select.html.erb
│ │ │ │ │ └── _multiple_resource.html.erb
│ │ │ │ └── preview
│ │ │ │ │ ├── _form.html.erb
│ │ │ │ │ └── _nested_form.html.erb
│ │ │ ├── forms
│ │ │ │ ├── edit.html.erb
│ │ │ │ ├── new.html.erb
│ │ │ │ ├── fields
│ │ │ │ │ ├── new.html.erb
│ │ │ │ │ └── edit.html.erb
│ │ │ │ ├── overrides
│ │ │ │ │ ├── new.html.erb
│ │ │ │ │ ├── edit.html.erb
│ │ │ │ │ └── index.html.erb
│ │ │ │ ├── previews
│ │ │ │ │ ├── create.html.erb
│ │ │ │ │ └── show.html.erb
│ │ │ │ ├── _form.html.erb
│ │ │ │ └── _tabs.html.erb
│ │ │ ├── fields
│ │ │ │ ├── options
│ │ │ │ │ ├── _form.html.erb
│ │ │ │ │ └── edit.html.erb
│ │ │ │ ├── data_source_options
│ │ │ │ │ ├── _form.html.erb
│ │ │ │ │ └── edit.html.erb
│ │ │ │ ├── choices
│ │ │ │ │ ├── new.html.erb
│ │ │ │ │ ├── edit.html.erb
│ │ │ │ │ └── _form.html.erb
│ │ │ │ └── validations
│ │ │ │ │ ├── edit.html.erb
│ │ │ │ │ └── _form.html.erb
│ │ │ ├── _flow_kit
│ │ │ │ ├── transition_triggers
│ │ │ │ │ └── _timer.html.erb
│ │ │ │ └── arc_guards
│ │ │ │ │ └── _ruby_script.html.erb
│ │ │ ├── users
│ │ │ │ ├── new.html.erb
│ │ │ │ ├── _form.html.erb
│ │ │ │ ├── edit.html.erb
│ │ │ │ └── index.html.erb
│ │ │ ├── pipelines
│ │ │ │ ├── new.html.erb
│ │ │ │ ├── steps
│ │ │ │ │ ├── new.html.erb
│ │ │ │ │ ├── transition_triggers
│ │ │ │ │ │ ├── _form.html.erb
│ │ │ │ │ │ ├── edit.html.erb
│ │ │ │ │ │ └── new.html.erb
│ │ │ │ │ ├── branches
│ │ │ │ │ │ ├── _form.html.erb
│ │ │ │ │ │ └── new.html.erb
│ │ │ │ │ ├── redirections
│ │ │ │ │ │ ├── edit.html.erb
│ │ │ │ │ │ └── _form.html.erb
│ │ │ │ │ └── _form.html.erb
│ │ │ │ ├── edit.html.erb
│ │ │ │ ├── branches
│ │ │ │ │ ├── arc_guards
│ │ │ │ │ │ ├── _form.html.erb
│ │ │ │ │ │ ├── edit.html.erb
│ │ │ │ │ │ └── new.html.erb
│ │ │ │ │ ├── steps
│ │ │ │ │ │ ├── new.html.erb
│ │ │ │ │ │ └── _form.html.erb
│ │ │ │ │ └── _form.html.erb
│ │ │ │ └── _form.html.erb
│ │ │ ├── workflows
│ │ │ │ ├── new.html.erb
│ │ │ │ ├── instances
│ │ │ │ │ ├── new.html.erb
│ │ │ │ │ └── _form.html.erb
│ │ │ │ ├── transitions
│ │ │ │ │ ├── triggers
│ │ │ │ │ │ ├── _form.html.erb
│ │ │ │ │ │ ├── edit.html.erb
│ │ │ │ │ │ └── new.html.erb
│ │ │ │ │ ├── _form.html.erb
│ │ │ │ │ └── show.html.erb
│ │ │ │ ├── edit.html.erb
│ │ │ │ └── _form.html.erb
│ │ │ ├── kaminari
│ │ │ │ ├── _gap.html.erb
│ │ │ │ ├── _last_page.html.erb
│ │ │ │ ├── _first_page.html.erb
│ │ │ │ ├── _next_page.html.erb
│ │ │ │ ├── _page.html.erb
│ │ │ │ ├── _prev_page.html.erb
│ │ │ │ └── _paginator.html.erb
│ │ │ ├── nested_forms
│ │ │ │ └── fields
│ │ │ │ │ ├── new.html.erb
│ │ │ │ │ └── edit.html.erb
│ │ │ ├── human_tasks
│ │ │ │ └── show.html.erb
│ │ │ ├── instances
│ │ │ │ └── index.html.erb
│ │ │ └── notifications
│ │ │ │ └── index.html.erb
│ │ ├── channels
│ │ │ └── application_cable
│ │ │ │ ├── channel.rb
│ │ │ │ └── connection.rb
│ │ ├── mailers
│ │ │ └── application_mailer.rb
│ │ ├── presenters
│ │ │ ├── form_kit
│ │ │ │ ├── fields
│ │ │ │ │ ├── decimal_presenter.rb
│ │ │ │ │ ├── nested_form_presenter.rb
│ │ │ │ │ ├── multiple_nested_form_presenter.rb
│ │ │ │ │ ├── text_presenter.rb
│ │ │ │ │ ├── integer_presenter.rb
│ │ │ │ │ ├── boolean_presenter.rb
│ │ │ │ │ ├── choice_presenter.rb
│ │ │ │ │ ├── multiple_choice_presenter.rb
│ │ │ │ │ ├── member_presenter.rb
│ │ │ │ │ ├── select_presenter.rb
│ │ │ │ │ ├── resource_select_presenter.rb
│ │ │ │ │ ├── multiple_select_presenter.rb
│ │ │ │ │ └── resource_presenter.rb
│ │ │ │ └── composite_field_presenter.rb
│ │ │ ├── application_presenter.rb
│ │ │ └── concerns
│ │ │ │ └── form_kit
│ │ │ │ └── fields
│ │ │ │ └── presenter_for_number_field.rb
│ │ ├── jobs
│ │ │ ├── timer_task_job.rb
│ │ │ └── application_job.rb
│ │ ├── helpers
│ │ │ ├── forms_helper.rb
│ │ │ ├── breadcrumbs_helper.rb
│ │ │ ├── workflows_helper.rb
│ │ │ └── fields_helper.rb
│ │ ├── javascript
│ │ │ └── packs
│ │ │ │ └── application.js
│ │ └── overrides
│ │ │ └── models
│ │ │ └── flow_core
│ │ │ └── steps
│ │ │ └── end_override.rb
│ ├── bin
│ │ ├── rake
│ │ ├── rails
│ │ └── setup
│ ├── config
│ │ ├── initializers
│ │ │ ├── action_view.rb
│ │ │ ├── mime_types.rb
│ │ │ ├── filter_parameter_logging.rb
│ │ │ ├── application_controller_renderer.rb
│ │ │ ├── cookies_serializer.rb
│ │ │ ├── backtrace_silencers.rb
│ │ │ ├── assets.rb
│ │ │ ├── wrap_parameters.rb
│ │ │ └── inflections.rb
│ │ ├── spring.rb
│ │ ├── environment.rb
│ │ ├── cable.yml
│ │ ├── boot.rb
│ │ ├── locales
│ │ │ ├── kaminari.en.yml
│ │ │ └── en.yml
│ │ ├── database.yml
│ │ └── database.yml.sqlite.example
│ ├── config.ru
│ ├── db
│ │ └── migrate
│ │ │ ├── 20200205175442_create_users.rb
│ │ │ ├── 20200205175444_create_notifications.rb
│ │ │ ├── 20200523233225_create_assignee_candidates.rb
│ │ │ ├── 20200523233221_create_human_tasks.rb
│ │ │ └── 20200205175443_add_columns_to_flow_core_tables.rb
│ └── Rakefile
├── fixtures
│ └── .keep
├── flow_core_test.rb
├── models
│ └── flow_core
│ │ ├── arc_test.rb
│ │ ├── place_test.rb
│ │ ├── task_test.rb
│ │ ├── token_test.rb
│ │ ├── instance_test.rb
│ │ ├── workflow_test.rb
│ │ └── transition_test.rb
├── integration
│ └── navigation_test.rb
└── test_helper.rb
├── .ruby-version
├── .gitattributes
├── config
└── routes.rb
├── lib
├── flow_core
│ ├── version.rb
│ ├── engine.rb
│ ├── arc_guardable.rb
│ ├── errors.rb
│ ├── definition.rb
│ ├── task_callbacks.rb
│ ├── definition
│ │ ├── place.rb
│ │ ├── guard.rb
│ │ └── trigger.rb
│ ├── task_executable.rb
│ └── locale
│ │ └── en.yml
├── tasks
│ └── flow_core_tasks.rake
└── flow_core.rb
├── guides
├── assets
│ ├── pipeline_step_end.png
│ ├── pipeline_step_task.png
│ ├── pipeline_step_end_compiled.png
│ ├── pipeline_step_redirection.png
│ ├── pipeline_step_task_compiled.png
│ ├── pipeline_step_parallel_split.png
│ ├── pipeline_step_exclusive_choice.png
│ ├── pipeline_step_redirection_note.png
│ ├── pipeline_step_redirection_compiled.png
│ ├── pipeline_step_parallel_split_compiled.png
│ └── pipeline_step_exclusive_choice_compiled.png
└── internals.zh-CN.md
├── .editorconfig
├── .vscode
└── launch.json
├── Rakefile
├── bin
└── rails
├── .gitignore
├── MIT-LICENSE
└── flow_core.gemspec
/app/helpers/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/mailers/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/models/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/views/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/controllers/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/dummy/log/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.ruby-version:
--------------------------------------------------------------------------------
1 | ruby-3.3.0
2 |
--------------------------------------------------------------------------------
/test/dummy/lib/assets/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/dummy/mruby/lib/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/dummy/storage/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/dummy/public/favicon.ico:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/dummy/app/assets/images/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/dummy/app/models/concerns/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/dummy/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/concerns/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/dummy/public/apple-touch-icon-precomposed.png:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.rb diff=ruby
2 | *.gemspec diff=ruby
3 |
4 |
--------------------------------------------------------------------------------
/test/dummy/app/views/layouts/mailer.text.erb:
--------------------------------------------------------------------------------
1 | <%= yield %>
2 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/data_source_options/_empty.html.erb:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/dummy/mruby/lib/harden.rb:
--------------------------------------------------------------------------------
1 | Kernel.remove_method :object_id
2 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/validations/_exclusion.html.erb:
--------------------------------------------------------------------------------
1 |
Exclusion
2 |
3 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/validations/_inclusion.html.erb:
--------------------------------------------------------------------------------
1 | Inclusion
2 |
3 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Rails.application.routes.draw do
4 | end
5 |
--------------------------------------------------------------------------------
/lib/flow_core/version.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowCore
4 | VERSION = "0.0.6"
5 | end
6 |
--------------------------------------------------------------------------------
/guides/assets/pipeline_step_end.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rails-engine/flow_core/HEAD/guides/assets/pipeline_step_end.png
--------------------------------------------------------------------------------
/test/dummy/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require_relative '../config/boot'
3 | require 'rake'
4 | Rake.application.run
5 |
--------------------------------------------------------------------------------
/guides/assets/pipeline_step_task.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rails-engine/flow_core/HEAD/guides/assets/pipeline_step_task.png
--------------------------------------------------------------------------------
/guides/assets/pipeline_step_end_compiled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rails-engine/flow_core/HEAD/guides/assets/pipeline_step_end_compiled.png
--------------------------------------------------------------------------------
/guides/assets/pipeline_step_redirection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rails-engine/flow_core/HEAD/guides/assets/pipeline_step_redirection.png
--------------------------------------------------------------------------------
/guides/assets/pipeline_step_task_compiled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rails-engine/flow_core/HEAD/guides/assets/pipeline_step_task_compiled.png
--------------------------------------------------------------------------------
/guides/assets/pipeline_step_parallel_split.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rails-engine/flow_core/HEAD/guides/assets/pipeline_step_parallel_split.png
--------------------------------------------------------------------------------
/test/dummy/app/assets/config/manifest.js:
--------------------------------------------------------------------------------
1 | //= link_tree ../images
2 | //= link_directory ../javascripts .js
3 | //= link_directory ../stylesheets .css
4 |
--------------------------------------------------------------------------------
/guides/assets/pipeline_step_exclusive_choice.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rails-engine/flow_core/HEAD/guides/assets/pipeline_step_exclusive_choice.png
--------------------------------------------------------------------------------
/guides/assets/pipeline_step_redirection_note.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rails-engine/flow_core/HEAD/guides/assets/pipeline_step_redirection_note.png
--------------------------------------------------------------------------------
/guides/assets/pipeline_step_redirection_compiled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rails-engine/flow_core/HEAD/guides/assets/pipeline_step_redirection_compiled.png
--------------------------------------------------------------------------------
/test/dummy/app/controllers/home_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class HomeController < ApplicationController
4 | def index; end
5 | end
6 |
--------------------------------------------------------------------------------
/guides/assets/pipeline_step_parallel_split_compiled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rails-engine/flow_core/HEAD/guides/assets/pipeline_step_parallel_split_compiled.png
--------------------------------------------------------------------------------
/guides/assets/pipeline_step_exclusive_choice_compiled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rails-engine/flow_core/HEAD/guides/assets/pipeline_step_exclusive_choice_compiled.png
--------------------------------------------------------------------------------
/guides/internals.zh-CN.md:
--------------------------------------------------------------------------------
1 | 技术内幕
2 | ====
3 |
4 | ## 工作流实例的生命周期
5 |
6 | 
7 |
8 | ## 数据库表结构说明
9 |
10 | WIP
11 |
--------------------------------------------------------------------------------
/lib/tasks/flow_core_tasks.rake:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # desc "Explaining what the task does"
4 | # task :flow_core do
5 | # # Task goes here
6 | # end
7 |
--------------------------------------------------------------------------------
/test/dummy/app/models/application_record.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ApplicationRecord < ActiveRecord::Base
4 | self.abstract_class = true
5 | end
6 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/non_configurable.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit
4 | class NonConfigurable < FormKit::FieldOptions
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/test/dummy/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | APP_PATH = File.expand_path('../config/application', __dir__)
3 | require_relative '../config/boot'
4 | require 'rails/commands'
5 |
--------------------------------------------------------------------------------
/test/dummy/mruby/lib/output.rb:
--------------------------------------------------------------------------------
1 | module Output
2 | class << self
3 | attr_accessor :value
4 |
5 | def pack
6 | value.pack
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/test/dummy/app/channels/application_cable/channel.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module ApplicationCable
4 | class Channel < ActionCable::Channel::Base
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/test/dummy/config/initializers/action_view.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | ActionView::Base.field_error_proc = Proc.new do |html_tag, _instance_tag|
4 | html_tag
5 | end
6 |
--------------------------------------------------------------------------------
/test/dummy/config/spring.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Spring.watch(
4 | ".ruby-version",
5 | ".rbenv-vars",
6 | "tmp/restart.txt",
7 | "tmp/caching-dev.txt"
8 | )
9 |
--------------------------------------------------------------------------------
/test/dummy/app/channels/application_cable/connection.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module ApplicationCable
4 | class Connection < ActionCable::Connection::Base
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/test/dummy/app/views/forms/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= render "forms/tabs" %>
3 |
4 |
5 |
6 | <%= render "form", form: @form %>
7 |
8 |
--------------------------------------------------------------------------------
/test/dummy/app/mailers/application_mailer.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ApplicationMailer < ActionMailer::Base
4 | default from: "from@example.com"
5 | layout "mailer"
6 | end
7 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/nested_form/options.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::NestedForm
4 | class Options < FormKit::FieldOptions
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/test/dummy/app/models/notification.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Notification < ApplicationRecord
4 | belongs_to :user
5 | belongs_to :task, class_name: "FlowCore::Task"
6 | end
7 |
--------------------------------------------------------------------------------
/app/models/flow_core/application_record.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowCore
4 | class ApplicationRecord < ActiveRecord::Base
5 | self.abstract_class = true
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/dummy/app/models/user.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class User < ApplicationRecord
4 | has_many :notifications, dependent: :delete_all
5 |
6 | validates :name, presence: true
7 | end
8 |
--------------------------------------------------------------------------------
/test/dummy/config.ru:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # This file is used by Rack-based servers to start the application.
4 |
5 | require_relative "config/environment"
6 |
7 | run Rails.application
8 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/nested_form.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit
4 | class NestedForm < MetalForm
5 | belongs_to :attachable, polymorphic: true, touch: true
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/dummy/config/environment.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Load the Rails application.
4 | require_relative "application"
5 |
6 | # Initialize the Rails application.
7 | Rails.application.initialize!
8 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/data_sources.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::DataSources
4 | %w[empty].each do |type|
5 | require_dependency "form_kit/data_sources/#{type}"
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/flow_core_test.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "test_helper"
4 |
5 | class FlowCore::Test < ActiveSupport::TestCase
6 | test "truth" do
7 | assert_kind_of Module, FlowCore
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/test/dummy/app/views/layouts/_footer.html.erb:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/test/models/flow_core/arc_test.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "test_helper"
4 |
5 | class FlowCore::ArcTest < ActiveSupport::TestCase
6 | # test "the truth" do
7 | # assert true
8 | # end
9 | end
10 |
--------------------------------------------------------------------------------
/test/dummy/app/models/flow_kit/arc_guards.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowKit::ArcGuards
4 | def self.all_types
5 | @all_types ||= [
6 | FlowKit::ArcGuards::RubyScript,
7 | ]
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/resource/options.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::Resource
4 | class Options < FormKit::FieldOptions
5 | include FormKit::Options::DataSource
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/text/options.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::Text
4 | class Options < FormKit::FieldOptions
5 | attribute :multiline, :boolean, default: false
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/form.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit
4 | class Form < MetalForm
5 | validates :name,
6 | presence: true
7 |
8 | include Fakable
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/test/models/flow_core/place_test.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "test_helper"
4 |
5 | class FlowCore::PlaceTest < ActiveSupport::TestCase
6 | # test "the truth" do
7 | # assert true
8 | # end
9 | end
10 |
--------------------------------------------------------------------------------
/test/models/flow_core/task_test.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "test_helper"
4 |
5 | class FlowCore::TaskTest < ActiveSupport::TestCase
6 | # test "the truth" do
7 | # assert true
8 | # end
9 | end
10 |
--------------------------------------------------------------------------------
/test/models/flow_core/token_test.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "test_helper"
4 |
5 | class FlowCore::TokenTest < ActiveSupport::TestCase
6 | # test "the truth" do
7 | # assert true
8 | # end
9 | end
10 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/select/options.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::Select
4 | class Options < FormKit::FieldOptions
5 | attribute :strict_select, :boolean, default: true
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/integration/navigation_test.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "test_helper"
4 |
5 | class NavigationTest < ActionDispatch::IntegrationTest
6 | # test "the truth" do
7 | # assert true
8 | # end
9 | end
10 |
--------------------------------------------------------------------------------
/test/models/flow_core/instance_test.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "test_helper"
4 |
5 | class FlowCore::InstanceTest < ActiveSupport::TestCase
6 | # test "the truth" do
7 | # assert true
8 | # end
9 | end
10 |
--------------------------------------------------------------------------------
/test/models/flow_core/workflow_test.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "test_helper"
4 |
5 | class FlowCore::WorkflowTest < ActiveSupport::TestCase
6 | # test "the truth" do
7 | # assert true
8 | # end
9 | end
10 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/boolean/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::Boolean
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Acceptance
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/date_range/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::DateRange
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/dummy/config/initializers/mime_types.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 | # Be sure to restart your server when you modify this file.
3 |
4 | # Add new mime types for use in respond_to blocks:
5 | # Mime::Type.register "text/richtext", :rtf
6 |
--------------------------------------------------------------------------------
/test/models/flow_core/transition_test.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "test_helper"
4 |
5 | class FlowCore::TransitionTest < ActiveSupport::TestCase
6 | # test "the truth" do
7 | # assert true
8 | # end
9 | end
10 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/field_options.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit
4 | class FieldOptions < SerializableModel::Base
5 | def interpret_to(_model, _field_name, _accessibility, _options = {}); end
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/decimal_range/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::DecimalRange
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/integer_range/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::IntegerRange
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/multiple_resource/options.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::MultipleResource
4 | class Options < FormKit::FieldOptions
5 | include FormKit::Options::DataSource
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/nested_form/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::NestedForm
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/dummy/app/presenters/form_kit/fields/decimal_presenter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class DecimalPresenter < FormKit::FieldPresenter
5 | include FormKit::Fields::PresenterForNumberField
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/datetime_range/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::DatetimeRange
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/multiple_select/options.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::MultipleSelect
4 | class Options < FormKit::FieldOptions
5 | attribute :strict_select, :boolean, default: true
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/dummy/config/cable.yml:
--------------------------------------------------------------------------------
1 | development:
2 | adapter: async
3 |
4 | test:
5 | adapter: test
6 |
7 | production:
8 | adapter: redis
9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
10 | channel_prefix: dummy_production
11 |
--------------------------------------------------------------------------------
/test/dummy/app/presenters/form_kit/fields/nested_form_presenter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class NestedFormPresenter < FormKit::CompositeFieldPresenter
5 | def nested_form_field?
6 | true
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/date/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::Date
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | # prepend FormKit::Validations::Uniqueness
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/test/dummy/db/migrate/20200205175442_create_users.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class CreateUsers < ActiveRecord::Migration[6.0]
4 | def change
5 | create_table :users do |t|
6 | t.string :name
7 |
8 | t.timestamps
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/field/fakable.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Field
4 | module Fakable
5 | extend ActiveSupport::Concern
6 |
7 | module ClassMethods
8 | def configure_fake_options_to(_field); end
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/choice/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::Choice
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | # prepend FormKit::Validations::Uniqueness
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/select/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::Select
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | # prepend FormKit::Validations::Uniqueness
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/field_options/_integer.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= f.label :step %>
3 | <%= f.number_field :step, min: 0, step: 1, class: "form-control", class_for_error: "is-invalid" %>
4 | <%= f.error_message :step, class: "invalid-feedback" %>
5 |
6 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/datetime/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::Datetime
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | # prepend FormKit::Validations::Uniqueness
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/resource/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::Resource
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | # prepend FormKit::Validations::Uniqueness
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/field_options/_decimal.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= f.label :step %>
3 | <%= f.number_field :step, min: 0, step: 0.01, class: "form-control", class_for_error: "is-invalid" %>
4 | <%= f.error_message :step, class: "invalid-feedback" %>
5 |
6 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/multiple_choice/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::MultipleChoice
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | prepend FormKit::Validations::Length
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/multiple_select/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::MultipleSelect
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | prepend FormKit::Validations::Length
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/test/dummy/app/presenters/form_kit/fields/multiple_nested_form_presenter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class MultipleNestedFormPresenter < FormKit::CompositeFieldPresenter
5 | def multiple_nested_form?
6 | true
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/test/dummy/config/initializers/filter_parameter_logging.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Be sure to restart your server when you modify this file.
4 |
5 | # Configure sensitive parameters which will be filtered from the log file.
6 | Rails.application.config.filter_parameters += [:password]
7 |
--------------------------------------------------------------------------------
/test/dummy/Rakefile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Add your own tasks in files placed in lib/tasks ending in .rake,
4 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
5 |
6 | require_relative "config/application"
7 |
8 | Rails.application.load_tasks
9 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/multiple_resource/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::MultipleResource
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | prepend FormKit::Validations::Length
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/resource_select/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::ResourceSelect
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | # prepend FormKit::Validations::Uniqueness
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/test/dummy/app/presenters/application_presenter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ApplicationPresenter < SimpleDelegator
4 | def initialize(model, view, options = {})
5 | super(model)
6 |
7 | @model = model
8 | @view = view
9 | @options = options
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/test/dummy/app/presenters/form_kit/fields/text_presenter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class TextPresenter < FormKit::FieldPresenter
5 | def multiline
6 | @model.options.multiline
7 | end
8 | alias multiline? multiline
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # This file is for unifying the coding style for different editors and IDEs
2 | # editorconfig.org
3 |
4 | root = true
5 |
6 | [*]
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 | indent_style = space
11 | indent_size = 2
12 | end_of_line = lf
13 |
--------------------------------------------------------------------------------
/test/dummy/app/models/flow_kit/transition_triggers.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowKit::TransitionTriggers
4 | def self.all_types
5 | @all_types ||= [
6 | FlowKit::TransitionTriggers::HumanTask,
7 | FlowKit::TransitionTriggers::Timer
8 | ]
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/multiple_nested_form/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::MultipleNestedForm
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | prepend FormKit::Validations::Length
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/test/dummy/config/boot.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Set up gems listed in the Gemfile.
4 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", __dir__)
5 |
6 | require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
7 | $LOAD_PATH.unshift File.expand_path("../../../lib", __dir__)
8 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/application_record.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit
4 | class ApplicationRecord < ::ApplicationRecord
5 | self.abstract_class = true
6 |
7 | include ModelKit::ActsAsDefaultValue
8 | include ModelKit::EnumAttributeLocalizable
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/multiple_resource_select/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::MultipleResourceSelect
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | prepend FormKit::Validations::Length
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/resource_select/options.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::ResourceSelect
4 | class Options < FormKit::FieldOptions
5 | include FormKit::Options::DataSource
6 |
7 | attribute :strict_select, :boolean, default: true
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/test/dummy/app/presenters/form_kit/fields/integer_presenter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class IntegerPresenter < FormKit::FieldPresenter
5 | include FormKit::Fields::PresenterForNumberField
6 |
7 | def integer_only?
8 | true
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/text.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class Text < FormKit::Field
5 | serialize :validations, coder: Validations
6 | serialize :options, coder: Options
7 |
8 | def stored_type
9 | :string
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/decimal.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class Decimal < FormKit::Field
5 | serialize :validations, coder: Validations
6 | serialize :options, coder: Options
7 |
8 | def stored_type
9 | :decimal
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/fields/options/_form.html.erb:
--------------------------------------------------------------------------------
1 | <%= form_with(model: options, scope: :options, url: field_options_path(field), method: :patch, local: true) do |f| %>
2 | <%= render "_form_core/field_options/#{field.type_key}", f: f, options: options %>
3 |
4 | <%= f.submit class: "btn btn-block btn-primary" %>
5 | <% end %>
6 |
--------------------------------------------------------------------------------
/lib/flow_core/engine.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowCore
4 | class Engine < ::Rails::Engine
5 | initializer "flow_core.load_default_i18n" do
6 | ActiveSupport.on_load(:i18n) do
7 | I18n.load_path << File.expand_path("locale/en.yml", __dir__)
8 | end
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/multiple_resource_select/options.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::MultipleResourceSelect
4 | class Options < FormKit::FieldOptions
5 | include FormKit::Options::DataSource
6 |
7 | attribute :strict_select, :boolean, default: true
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/test/dummy/app/views/layouts/mailer.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
11 | <%= yield %>
12 |
13 |
14 |
--------------------------------------------------------------------------------
/lib/flow_core/arc_guardable.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowCore
4 | module ArcGuardable
5 | extend ActiveSupport::Concern
6 |
7 | def permit?(_task)
8 | raise NotImplementedError
9 | end
10 |
11 | def description
12 | raise NotImplementedError
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/boolean.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class Boolean < FormKit::Field
5 | serialize :validations, coder: Validations
6 | serialize :options, coder: FormKit::NonConfigurable
7 |
8 | def stored_type
9 | :boolean
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/instances/application_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Instances::ApplicationController < ::ApplicationController
4 | before_action :set_instance
5 |
6 | protected
7 |
8 | def set_instance
9 | @instance = FlowCore::Instance.find(params[:instance_id])
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/workflows/application_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Workflows::ApplicationController < ::ApplicationController
4 | before_action :set_workflow
5 |
6 | protected
7 |
8 | def set_workflow
9 | @workflow = FlowCore::Workflow.find(params[:workflow_id])
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/test/dummy/config/initializers/application_controller_renderer.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 | # Be sure to restart your server when you modify this file.
3 |
4 | # ActiveSupport::Reloader.to_prepare do
5 | # ApplicationController.renderer.defaults.merge!(
6 | # http_host: 'example.org',
7 | # https: false
8 | # )
9 | # end
10 |
--------------------------------------------------------------------------------
/test/dummy/config/initializers/cookies_serializer.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Be sure to restart your server when you modify this file.
4 |
5 | # Specify a serializer for the signed and encrypted cookie jars.
6 | # Valid options are :json, :marshal, and :hybrid.
7 | Rails.application.config.action_dispatch.cookies_serializer = :json
8 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/pipelines/application_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pipelines::ApplicationController < ::ApplicationController
4 | before_action :set_pipeline
5 |
6 | protected
7 |
8 | def set_pipeline
9 | @pipeline = FlowKit::BusinessPipeline.find(params[:pipeline_id])
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/test/dummy/app/jobs/timer_task_job.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class TimerTaskJob < ApplicationJob
4 | queue_as :default
5 |
6 | def perform(task_id)
7 | task = FlowCore::Task.find(task_id)
8 | return unless task.enabled?
9 | return if task.errored? || task.suspended?
10 |
11 | task.finish!
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/decimal/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::Decimal
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | prepend FormKit::Validations::Numericality
7 | # prepend FormKit::Validations::Uniqueness
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/integer/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::Integer
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | prepend FormKit::Validations::Numericality
7 | # prepend FormKit::Validations::Uniqueness
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/test/dummy/app/presenters/form_kit/composite_field_presenter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit
4 | class CompositeFieldPresenter < FormKit::FieldPresenter
5 | def value
6 | target&.send(@model.key)
7 | end
8 |
9 | def value_for_preview
10 | target&.send(@model.key)
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/validations/_presence.html.erb:
--------------------------------------------------------------------------------
1 | Presence
2 |
3 |
4 | <%= f.check_box :presence, class: "form-check-input", id: "validations_presence", class_for_error: "is-invalid" %>
5 | <%= f.label :presence, "The field must not empty", for: "validations_presence" %>
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/pipelines/steps/application_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pipelines::Steps::ApplicationController < Pipelines::ApplicationController
4 | before_action :set_step
5 |
6 | protected
7 |
8 | def set_step
9 | @step = @pipeline.whole_steps.find(params[:step_id])
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/validations/_uniqueness.html.erb:
--------------------------------------------------------------------------------
1 | Uniqueness
2 |
3 |
4 | <%= f.check_box :uniqueness, class: "form-check-input", id: "validations_uniqueness", class_for_error: "is-invalid" %>
5 | <%= f.label :uniqueness, "The field must unique", for: "validations_uniqueness" %>
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/dummy/app/views/fields/data_source_options/_form.html.erb:
--------------------------------------------------------------------------------
1 | <%= form_with(model: options, scope: :options, url: field_data_source_options_path(field), method: :patch, local: true) do |f| %>
2 | <%= render "_form_core/data_source_options/#{options.type_key}", f: f, options: options %>
3 |
4 | <%= f.submit class: "btn btn-block btn-primary" %>
5 | <% end %>
6 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/pipelines/branches/application_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pipelines::Branches::ApplicationController < Pipelines::ApplicationController
4 | before_action :set_branch
5 |
6 | protected
7 |
8 | def set_branch
9 | @branch = @pipeline.branches.find(params[:branch_id])
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/validations/_acceptance.html.erb:
--------------------------------------------------------------------------------
1 | Acceptance
2 |
3 |
4 | <%= f.check_box :acceptance, class: "form-check-input", id: "validations_acceptance", class_for_error: "is-invalid" %>
5 | <%= f.label :acceptance, "The field must be checked", for: "validations_acceptance" %>
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/dummy/app/models/flow_kit/assignee_candidate.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowKit
4 | class AssigneeCandidate < FlowCore::ApplicationRecord
5 | self.table_name = "flow_kit_assignee_candidates"
6 |
7 | belongs_to :assignable, polymorphic: true
8 | belongs_to :trigger, class_name: "FlowCore::TransitionTrigger"
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/field_options/_resource.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= f.label :data_source_type %>
3 | <%= f.select :data_source_type, options_for_data_source_types(selected: options.data_source_type), { class_for_error: "is-invalid" }, class: "form-control" %>
4 | <%= f.error_message :data_source_type, class: "invalid-feedback" %>
5 |
6 |
--------------------------------------------------------------------------------
/test/dummy/app/jobs/application_job.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ApplicationJob < ActiveJob::Base
4 | # Automatically retry jobs that encountered a deadlock
5 | # retry_on ActiveRecord::Deadlocked
6 |
7 | # Most jobs are safe to ignore if the underlying records are no longer available
8 | # discard_on ActiveJob::DeserializationError
9 | end
10 |
--------------------------------------------------------------------------------
/test/dummy/app/models/flow_kit/steps.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowKit::Steps
4 | def self.all_types
5 | @all_types ||= [
6 | FlowCore::Steps::Task,
7 | FlowCore::Steps::ParallelSplit,
8 | FlowCore::Steps::ExclusiveChoice,
9 | FlowCore::Steps::Redirection,
10 | FlowCore::Steps::End
11 | ]
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/decimal/options.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::Decimal
4 | class Options < FormKit::FieldOptions
5 | attribute :step, :decimal, default: 0.01
6 |
7 | validates :step,
8 | numericality: {
9 | greater_than_or_equal_to: 0.0
10 | }
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/test/dummy/mruby/lib/script_kernel.rb:
--------------------------------------------------------------------------------
1 | def prepare
2 | input = @input || {}
3 | remove_instance_variable "@input"
4 |
5 | configuration = input[:configuration] || {}
6 | Time.formatted_offset = configuration[:time_zone_offset] || 0
7 |
8 | Input.load input[:payload]
9 | end
10 |
11 | def pack_output
12 | instance_variable_set "@output", Output.pack
13 | end
14 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/text/validations.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::Text
4 | class Validations < FormKit::FieldOptions
5 | prepend FormKit::Validations::Presence
6 | prepend FormKit::Validations::Length
7 | prepend FormKit::Validations::Format
8 | # prepend FormKit::Validations::Uniqueness
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/test/dummy/app/helpers/forms_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormsHelper
4 | def smart_form_fields_path(form)
5 | case form
6 | when FormKit::Form
7 | form_fields_path(form)
8 | when FormKit::NestedForm
9 | nested_form_fields_path(form)
10 | else
11 | raise "Unknown form: #{form.class}"
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/app/models/flow_core/end_place.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowCore
4 | class EndPlace < FlowCore::Place
5 | validates :type,
6 | uniqueness: {
7 | scope: :workflow
8 | }
9 |
10 | validates :output_arcs,
11 | length: { is: 0 }
12 |
13 | def end?
14 | true
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/flow_core/errors.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowCore
4 | # Generic base class for all Workflow Core exceptions.
5 | class Error < StandardError; end
6 |
7 | class UnverifiedWorkflow < Error; end
8 |
9 | class InvalidTransition < Error; end
10 |
11 | class NoNewTokenCreated < Error; end
12 |
13 | class ForbiddenOperation < Error; end
14 | end
15 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/workflows/transitions/application_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Workflows::Transitions::ApplicationController < Workflows::ApplicationController
4 | before_action :set_transition
5 |
6 | protected
7 |
8 | def set_transition
9 | @transition = @workflow.transitions.find(params[:transition_id])
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/test/dummy/app/presenters/form_kit/fields/boolean_presenter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class BooleanPresenter < FormKit::FieldPresenter
5 | def required
6 | @model.validations&.acceptance
7 | end
8 |
9 | def value_for_preview
10 | super ? I18n.t("values.true") : I18n.t("values.false")
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/app/models/flow_core/start_place.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowCore
4 | class StartPlace < FlowCore::Place
5 | validates :type,
6 | uniqueness: {
7 | scope: :workflow
8 | }
9 |
10 | validates :input_arcs,
11 | length: { is: 0 }
12 |
13 | def start?
14 | true
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/test/dummy/app/models/flow_kit/arc_guards/ruby_script/configuration.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowKit::ArcGuards
4 | class RubyScript
5 | class Configuration < SerializableModel::Base
6 | attribute :name, :string
7 | attribute :script, :string
8 |
9 | validates :name, :script,
10 | presence: true
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/validations/_confirmation.html.erb:
--------------------------------------------------------------------------------
1 | Confirmation
2 |
3 |
4 | <%= f.check_box :confirmation, class: "form-check-input", id: "validations_confirmation", class_for_error: "is-invalid" %>
5 | <%= f.label :confirmation, "The field must be repeated in confirmation field", for: "validations_confirmation" %>
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/session_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class SessionController < ApplicationController
4 | def sign_in_as
5 | session[:current_user_id] = params[:id]
6 | redirect_back fallback_location: root_url
7 | end
8 |
9 | def sign_out
10 | session[:current_user_id] = nil
11 | redirect_back fallback_location: root_url
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/test/dummy/db/migrate/20200205175444_create_notifications.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class CreateNotifications < ActiveRecord::Migration[6.0]
4 | def change
5 | create_table :notifications do |t|
6 | t.references :user, null: false, foreign_key: true
7 | t.references :task, null: false, foreign_key: false
8 |
9 | t.timestamps
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "type": "rdbg",
9 | "name": "Attach with rdbg",
10 | "request": "attach"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/test/dummy/app/assets/javascripts/application.es6:
--------------------------------------------------------------------------------
1 | //= require rails-ujs
2 | //= require turbolinks
3 | //= require popper
4 | //= require jquery3
5 | //= require bootstrap-sprockets
6 | //= require selectize
7 | //= require jquery-ui/widgets/sortable
8 | //= require selectize
9 | //= require cocoon
10 |
11 | $(document).on('turbolinks:load', function () {
12 | $('[data-toggle="tooltip"]').tooltip();
13 | });
14 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/integer/options.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::Integer
4 | class Options < FormKit::FieldOptions
5 | attribute :step, :integer, default: 0
6 |
7 | validates :step,
8 | numericality: {
9 | only_integer: true,
10 | greater_than_or_equal_to: 0
11 | }
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/test/dummy/mruby/lib/io.rb:
--------------------------------------------------------------------------------
1 | class << self
2 | attr_accessor :stdout_buffer
3 | end
4 |
5 | SCRIPT__TOP = self
6 | SCRIPT__TOP.stdout_buffer = ""
7 |
8 | module Kernel
9 | def puts(*args)
10 | if args.any?
11 | args.each do |arg|
12 | SCRIPT__TOP.stdout_buffer << "#{arg}\n"
13 | end
14 | else
15 | SCRIPT__TOP.stdout_buffer << "\n"
16 | end
17 |
18 | nil
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/test/dummy/app/models/flow_kit/business_pipeline.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowKit
4 | class BusinessPipeline < FlowCore::Pipeline
5 | belongs_to :form, class_name: "FormKit::Form"
6 |
7 | private
8 |
9 | def on_build_workflow(workflow)
10 | workflow.form = form
11 | end
12 |
13 | def workflow_class
14 | FlowKit::BusinessWorkflow
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/test/dummy/app/models/flow_kit/business_workflow.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowKit
4 | class BusinessWorkflow < FlowCore::Workflow
5 | belongs_to :form, class_name: "FormKit::Form"
6 |
7 | private
8 |
9 | def on_build_instance(instance)
10 | instance.form = form
11 | end
12 |
13 | def instance_class
14 | FlowKit::BusinessInstance
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_flow_kit/transition_triggers/_timer.html.erb:
--------------------------------------------------------------------------------
1 | <%= f.fields_for :configuration, trigger.configuration do |ff| %>
2 |
3 | <%= ff.label :countdown_in_seconds %>
4 | <%= ff.number_field :countdown_in_seconds, min: 0, step: 1, required: "required", class: "form-control", class_for_error: "is-invalid" %>
5 | <%= ff.error_message :name, class: "invalid-feedback" %>
6 |
7 | <% end %>
8 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/field_options/_text.html.erb:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/test/dummy/app/views/forms/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | New form
5 |
6 |
7 | <%= link_to 'Back', forms_path, class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", form: @form %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/notifications_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class NotificationsController < ApplicationController
4 | before_action :authenticate_user!
5 |
6 | def index
7 | @notifications = current_user
8 | .notifications
9 | .includes(task: { executable: %i[workflow transition] })
10 | .order(created_at: :desc)
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/users/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | New User
5 |
6 |
7 | <%= link_to 'Back', users_path, class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", user: @user %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/helpers/breadcrumbs_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module BreadcrumbsHelper
4 | def breadcrumbs
5 | @_breadcrumbs ||= []
6 | end
7 |
8 | def add_to_breadcrumbs(text, link = nil)
9 | breadcrumbs.push(
10 | text: text,
11 | link: link
12 | )
13 | end
14 |
15 | def render_breadcrumbs
16 | return unless breadcrumbs.any?
17 |
18 | render "layouts/breadcrumb"
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/test/dummy/app/assets/stylesheets/selectize/plugins/optgroup_columns.scss:
--------------------------------------------------------------------------------
1 | .selectize-dropdown.plugin-optgroup_columns {
2 | .optgroup {
3 | border-right: 1px solid #f2f2f2;
4 | border-top: 0 none;
5 | float: left;
6 | @include selectize-box-sizing(border-box);
7 | }
8 | .optgroup:last-child {
9 | border-right: 0 none;
10 | }
11 | .optgroup:before {
12 | display: none;
13 | }
14 | .optgroup-header {
15 | border-top: 0 none;
16 | }
17 | }
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/field_options/_select.html.erb:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/render/_form.html.erb:
--------------------------------------------------------------------------------
1 | <% options ||= {} %>
2 | <%= form_with(model: instance, **options, local: true) do |f| %>
3 | <% fields = form.fields.map { |field| present(field, target: instance) }.reject(&:access_hidden?) %>
4 |
5 | <% fields.each do |field| %>
6 | <%= render "_form_core/fields/#{field.type_key}", f: f, field: field %>
7 | <% end %>
8 |
9 | <%= f.submit "Submit", class: "btn btn-primary" %>
10 | <% end %>
11 |
--------------------------------------------------------------------------------
/test/dummy/app/models/flow_kit/transition_triggers/timer.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowKit::TransitionTriggers
4 | class Timer < FlowCore::TransitionTrigger
5 | serialize :configuration, coder: Configuration
6 |
7 | def configurable?
8 | true
9 | end
10 |
11 | def on_task_enable(task)
12 | TimerTaskJob.set(wait: configuration.countdown_in_seconds.seconds).perform_later(task.id)
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/test/dummy/app/presenters/form_kit/fields/choice_presenter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class ChoicePresenter < FormKit::FieldPresenter
5 | def value_for_preview
6 | id = value
7 | return if id.blank?
8 |
9 | if choices.loaded?
10 | choices.target.find { |choice| choice.id == id }&.label
11 | else
12 | choices.find_by(id: id)&.label
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/field_options/_multiple_select.html.erb:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | New Pipeline
5 |
6 |
7 | <%= link_to 'Back', pipelines_path, class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", pipeline: @pipeline %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/users/_form.html.erb:
--------------------------------------------------------------------------------
1 | <%= form_with(model: user, local: true) do |f| %>
2 |
3 | <%= f.label :name %>
4 | <%= f.text_field :name, autofocus: true, required: "required", class: "form-control", class_for_error: "is-invalid" %>
5 | <%= f.error_message :name, class: "invalid-feedback" %>
6 |
7 |
8 |
9 | <%= f.submit class: "btn btn-primary" %>
10 |
11 | <% end %>
12 |
--------------------------------------------------------------------------------
/test/dummy/app/views/users/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Editing <%= @user.name %>
5 |
6 |
7 | <%= link_to 'Back', users_path, class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", user: @user %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/workflows/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | New Workflow
5 |
6 |
7 | <%= link_to 'Back', workflows_path, class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", workflow: @workflow %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/forms/fields/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | New Field
5 |
6 |
7 | <%= link_to 'Back', form_fields_path(@form), class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", form: @form, field: @field %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/kaminari/_gap.html.erb:
--------------------------------------------------------------------------------
1 | <%# Non-link tag that stands for skipped pages...
2 | - available local variables
3 | current_page: a page object for the currently displayed page
4 | num_pages: total number of pages
5 | per_page: number of items to fetch per page
6 | remote: data-remote
7 | -%>
8 | <%= raw(t("views.pagination.truncate")) %>
9 |
--------------------------------------------------------------------------------
/test/dummy/app/views/forms/fields/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Editing Field
5 |
6 |
7 | <%= link_to 'Back', form_fields_path(@form), class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", form: @form, field: @field %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/fields/choices/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | New choice
5 |
6 |
7 | <%= link_to 'Back', field_choices_path(@field), class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", field: @field, choice: @choice %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/fields/choices/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Editing choice
5 |
6 |
7 | <%= link_to 'Back', field_choices_path(@field), class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", field: @field, choice: @choice %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/forms/overrides/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | New Override
5 |
6 |
7 | <%= link_to 'Back', form_overrides_path(@form), class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", form: @form, override: @override %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/forms/previews/create.html.erb:
--------------------------------------------------------------------------------
1 | <% content_for :actions do %>
2 | <%= link_to 'Back', form_preview_path(@form), class: "btn btn-primary" %>
3 | <% end %>
4 |
5 |
6 | <%= render "forms/tabs" %>
7 |
8 |
9 |
10 | <%= render "_form_core/preview/form", form: @form, instance: @instance %>
11 |
12 |
13 |
14 |
15 | <%= @instance.dump %>
16 |
17 |
18 |
--------------------------------------------------------------------------------
/lib/flow_core/definition.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "flow_core/definition/place"
4 | require "flow_core/definition/transition"
5 | require "flow_core/definition/net"
6 | require "flow_core/definition/trigger"
7 | require "flow_core/definition/guard"
8 |
9 | module FlowCore::Definition
10 | class << self
11 | def build(attributes = {}, &block)
12 | FlowCore::Definition::Net.new(attributes, &block)
13 | end
14 | alias new build
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/test/dummy/app/views/forms/overrides/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Edit Override
5 |
6 |
7 | <%= link_to 'Back', form_overrides_path(@form), class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", form: @form, override: @override %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/steps/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | New Step
5 |
6 |
7 | <%= link_to "Back", pipeline_path(@pipeline), class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", pipeline: @pipeline, step: @step %>
12 |
13 |
--------------------------------------------------------------------------------
/lib/flow_core/task_callbacks.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowCore
4 | module TaskCallbacks
5 | extend ActiveSupport::Concern
6 |
7 | def on_task_enable(_task); end
8 |
9 | def on_task_finish(_task); end
10 |
11 | def on_task_terminate(_task); end
12 |
13 | def on_task_suspend(_task); end
14 |
15 | def on_task_resume(_task); end
16 |
17 | def on_task_errored(_task, _error); end
18 |
19 | def on_task_rescue(_task); end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/test/dummy/app/views/nested_forms/fields/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | New Field
5 |
6 |
7 | <%= link_to 'Back', nested_form_fields_path(@nested_form), class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", form: @nested_form, field: @field %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/fields/options/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Editing field options
5 |
6 |
7 | <%= link_to 'Back', smart_form_fields_path(@field.form), class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", field: @field, options: @options %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/nested_forms/fields/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Editing Field
5 |
6 |
7 | <%= link_to 'Back', nested_form_fields_path(@nested_form), class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", form: @nested_form, field: @field %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/workflows/instances/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | New instance
5 |
6 |
7 | <%= link_to 'Back', workflow_path(@workflow), class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", workflow: @workflow, instance: @instance %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/config/initializers/backtrace_silencers.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 | # Be sure to restart your server when you modify this file.
3 |
4 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
5 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
6 |
7 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
8 | # Rails.backtrace_cleaner.remove_silencers!
9 |
--------------------------------------------------------------------------------
/test/dummy/app/models/concerns/form_kit/validations/presence.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Validations
4 | module Presence
5 | extend ActiveSupport::Concern
6 |
7 | prepended do
8 | attribute :presence, :boolean, default: false
9 | end
10 |
11 | def interpret_to(model, field_name, _accessibility, _options = {})
12 | super
13 | return unless presence
14 |
15 | model.validates field_name, presence: true
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/choice.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit
4 | class Choice < FormKit::ApplicationRecord
5 | self.table_name = "form_kit_choices"
6 |
7 | belongs_to :form, class_name: "FormKit::MetalForm"
8 | belongs_to :field
9 |
10 | validates :label,
11 | presence: true
12 |
13 | acts_as_list scope: [:field_id]
14 |
15 | before_validation do
16 | self.form ||= field&.form if new_record?
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/test/dummy/app/views/layouts/_alert.html.erb:
--------------------------------------------------------------------------------
1 | <% flash.each do |k, v| %>
2 | <% k = "info" if k == "notice" %>
3 | <% k = "warning" if k == "alert" %>
4 |
5 |
6 |
7 | ×
8 |
9 |
10 | <%= sanitize v.html_safe %>
11 |
12 |
13 | <% end %>
14 |
--------------------------------------------------------------------------------
/test/dummy/app/models/flow_kit/transition_triggers/timer/configuration.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowKit::TransitionTriggers
4 | class Timer
5 | class Configuration < SerializableModel::Base
6 | attribute :countdown_in_seconds, :integer, default: 0
7 |
8 | validates :countdown_in_seconds,
9 | numericality: {
10 | only_integer: true,
11 | greater_than_or_equal_to: 0
12 | }
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/data_source_options/_dictionary.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= f.label :scope %>
3 | <%= f.text_field :scope, required: "required", class: "form-control", class_for_error: "is-invalid" %>
4 | <%= f.error_message :scope, class: "invalid-feedback" %>
5 |
6 | The dictionary's scope you've created, go to <%= link_to "Dictionaries", tenant_admin_dictionaries_path(@tenant), target: "_blank" %> to check this out.
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/dummy/app/views/fields/validations/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Editing validations
5 |
6 |
7 | <%= link_to 'Back', smart_form_fields_path(@field.form), class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", field: @field, validations: @validations %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/models/concerns/form_kit/validations/acceptance.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Validations
4 | module Acceptance
5 | extend ActiveSupport::Concern
6 |
7 | prepended do
8 | attribute :acceptance, :boolean, default: false
9 | end
10 |
11 | def interpret_to(model, field_name, _accessibility, _options = {})
12 | super
13 | return unless acceptance
14 |
15 | model.validates field_name, acceptance: true
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/test/dummy/app/views/fields/data_source_options/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Editing data source options
5 |
6 |
7 | <%= link_to 'Back', smart_form_fields_path(@field.form), class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", field: @field, options: @options %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/models/concerns/form_kit/validations/confirmation.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Validations
4 | module Confirmation
5 | extend ActiveSupport::Concern
6 |
7 | prepended do
8 | attribute :confirmation, :boolean, default: false
9 | end
10 |
11 | def interpret_to(model, field_name, _accessibility, _options = {})
12 | super
13 | return unless confirmation
14 |
15 | model.validates field_name, confirmation: true
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/test/dummy/app/presenters/form_kit/fields/multiple_choice_presenter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class MultipleChoicePresenter < FormKit::FieldPresenter
5 | def value_for_preview
6 | ids = Array.wrap(value)
7 | return if ids.blank?
8 |
9 | if choices.loaded?
10 | choices.target.select { |choice| ids.include?(choice.id) }.map(&:label)
11 | else
12 | choices.where(id: ids).map(&:label)
13 | end.join(", ")
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/test/dummy/app/models/concerns/form_kit/validations/uniqueness.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Validations
4 | module Uniqueness
5 | extend ActiveSupport::Concern
6 |
7 | prepended do
8 | attribute :uniqueness, :boolean, default: false
9 | end
10 |
11 | def interpret_to(model, field_name, _accessibility, _options = {})
12 | super
13 | return unless uniqueness
14 |
15 | # TODO:
16 | # model.validates field_name, presence: true
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/test/dummy/db/migrate/20200523233225_create_assignee_candidates.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class CreateAssigneeCandidates < ActiveRecord::Migration[6.0]
4 | def change
5 | create_table :flow_kit_assignee_candidates do |t|
6 | t.references :assignable, polymorphic: true, null: false, index: { name: "index_flow_kit_assignee_candidates_on_assignable" }
7 | t.references :trigger, null: false, foreign_key: { to_table: :flow_core_transition_triggers }
8 |
9 | t.timestamps
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/lib/flow_core.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "rgl/adjacency"
4 | require "rgl/dijkstra"
5 | require "rgl/topsort"
6 | require "rgl/traversal"
7 | require "rgl/path"
8 |
9 | require "acts_as_list"
10 | require "ancestry"
11 |
12 | require "flow_core/engine"
13 |
14 | require "flow_core/errors"
15 | require "flow_core/arc_guardable"
16 | require "flow_core/task_callbacks"
17 | require "flow_core/task_executable"
18 |
19 | require "flow_core/definition"
20 | require "flow_core/violations"
21 |
22 | module FlowCore
23 | end
24 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/choice/fakable.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::Choice
4 | module Fakable
5 | extend ActiveSupport::Concern
6 |
7 | module ClassMethods
8 | def configure_fake_options_to(field)
9 | field.choices.build label: Faker::Artist.name
10 | field.choices.build label: Faker::Artist.name
11 | field.choices.build label: Faker::Artist.name
12 | field.choices.build label: Faker::Artist.name
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/select/fakable.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::Select
4 | module Fakable
5 | extend ActiveSupport::Concern
6 |
7 | module ClassMethods
8 | def configure_fake_options_to(field)
9 | field.choices.build label: Faker::Artist.name
10 | field.choices.build label: Faker::Artist.name
11 | field.choices.build label: Faker::Artist.name
12 | field.choices.build label: Faker::Artist.name
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/test/dummy/app/views/fields/choices/_form.html.erb:
--------------------------------------------------------------------------------
1 | <%- url = choice.new_record? ? field_choices_path(field) : field_choice_path(field, choice) %>
2 | <%= form_with(model: choice, scope: :choice, url: url, local: true) do |f| %>
3 |
4 | <%= f.label :label %>
5 | <%= f.text_field :label, required: "required", class: "form-control", class_for_error: "is-invalid" %>
6 | <%= f.error_message :label, class: "invalid-feedback" %>
7 |
8 |
9 | <%= f.submit class: "btn btn-block btn-primary" %>
10 | <% end %>
11 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ApplicationController < ActionController::Base
4 | helper_method :current_user
5 |
6 | private
7 |
8 | def current_user
9 | if session[:current_user_id].present?
10 | @_current_user ||=
11 | User.find_by(id: session[:current_user_id])
12 | end
13 | end
14 |
15 | def require_signed_in
16 | redirect_to users_url unless current_user
17 | end
18 | alias authenticate_user! require_signed_in
19 | end
20 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/multiple_choice/fakable.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::MultipleChoice
4 | module Fakable
5 | extend ActiveSupport::Concern
6 |
7 | module ClassMethods
8 | def configure_fake_options_to(field)
9 | field.choices.build label: Faker::Artist.name
10 | field.choices.build label: Faker::Artist.name
11 | field.choices.build label: Faker::Artist.name
12 | field.choices.build label: Faker::Artist.name
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/multiple_select/fakable.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Fields::MultipleSelect
4 | module Fakable
5 | extend ActiveSupport::Concern
6 |
7 | module ClassMethods
8 | def configure_fake_options_to(field)
9 | field.choices.build label: Faker::Artist.name
10 | field.choices.build label: Faker::Artist.name
11 | field.choices.build label: Faker::Artist.name
12 | field.choices.build label: Faker::Artist.name
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/test/dummy/app/views/forms/_form.html.erb:
--------------------------------------------------------------------------------
1 | <% url = form.new_record? ? forms_path : form_path(form) %>
2 | <% method = form.new_record? ? :post : :patch %>
3 | <%= form_with(model: form, scope: :form, url: url, method: method, local: true) do |f| %>
4 |
5 | <%= f.label :name %>
6 | <%= f.text_field :name, required: "required", class: "form-control", class_for_error: "is-invalid" %>
7 | <%= f.error_message :name, class: "invalid-feedback" %>
8 |
9 |
10 | <%= f.submit class: "btn btn-primary" %>
11 | <% end %>
12 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Editing Pipeline
5 |
6 |
7 | <%= link_to 'Show', pipeline_path(@pipeline), class: "btn btn-primary mr-2" %>
8 | <%= link_to 'Back', pipelines_path, class: "btn btn-primary" %>
9 |
10 |
11 |
12 | <%= render "form", pipeline: @pipeline %>
13 |
14 |
--------------------------------------------------------------------------------
/test/dummy/app/views/workflows/transitions/triggers/_form.html.erb:
--------------------------------------------------------------------------------
1 | <% url = workflow_transition_trigger_path(workflow, transition) %>
2 | <%= form_with(model: trigger, scope: :trigger, url: url, local: true) do |f| %>
3 | <%= f.hidden_field :type %>
4 |
5 | <% if trigger.configurable? %>
6 | <%= render partial: "_flow_kit/transition_triggers/#{trigger.type_key}", locals: { f: f, trigger: trigger, workflow: workflow } %>
7 | <% end %>
8 |
9 |
10 | <%= f.submit class: "btn btn-primary" %>
11 |
12 | <% end %>
13 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/field_override.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit
4 | class FieldOverride < FormKit::ApplicationRecord
5 | self.table_name = "form_kit_field_overrides"
6 |
7 | belongs_to :form_override, class_name: "FormKit::FormOverride"
8 | belongs_to :field, class_name: "FormKit::Field", foreign_key: "field_id"
9 |
10 | enum accessibility: { read_and_write: 0, readonly: 1, hidden: 2 },
11 | _prefix: :access
12 |
13 | validates :accessibility,
14 | presence: true
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/test/dummy/app/views/workflows/transitions/triggers/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Editing trigger
5 |
6 |
7 | <%= link_to 'Back', workflow_transition_path(@workflow, @transition), class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", workflow: @workflow, transition: @transition, trigger: @trigger %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/workflows/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Editing <%= @workflow.name %>
5 |
6 |
7 | <%= link_to 'Show', workflow_path(@workflow), class: "btn btn-primary mr-2" %>
8 | <%= link_to 'Back', workflows_path, class: "btn btn-primary" %>
9 |
10 |
11 |
12 | <%= render "form", workflow: @workflow %>
13 |
14 |
--------------------------------------------------------------------------------
/test/dummy/app/assets/stylesheets/selectize/plugins/drag_drop.scss:
--------------------------------------------------------------------------------
1 | .selectize-control.plugin-drag_drop {
2 | &.multi > .selectize-input > div.ui-sortable-placeholder {
3 | visibility: visible !important;
4 | background: #f2f2f2 !important;
5 | background: rgba(0,0,0,0.06) !important;
6 | border: 0 none !important;
7 | @include selectize-box-shadow(inset 0 0 12px 4px #fff);
8 | }
9 | .ui-sortable-placeholder::after {
10 | content: '!';
11 | visibility: hidden;
12 | }
13 | .ui-sortable-helper {
14 | @include selectize-box-shadow(0 2px 5px rgba(0,0,0,0.2));
15 | }
16 | }
--------------------------------------------------------------------------------
/test/dummy/app/views/kaminari/_last_page.html.erb:
--------------------------------------------------------------------------------
1 | <%# Link to the "Last" page
2 | - available local variables
3 | url: url to the last page
4 | current_page: a page object for the currently displayed page
5 | num_pages: total number of pages
6 | per_page: number of items to fetch per page
7 | remote: data-remote
8 | -%>
9 | <% unless current_page.last? %>
10 |
11 | <%= link_to_unless current_page.last?, raw(t("views.pagination.last")), url, class: "page-link", remote: remote %>
12 |
13 | <% end %>
14 |
--------------------------------------------------------------------------------
/test/dummy/app/views/workflows/_form.html.erb:
--------------------------------------------------------------------------------
1 | <% url = workflow.new_record? ? workflows_path : workflow_path(workflow) %>
2 | <%= form_with(model: workflow, scope: :workflow, url: url, local: true) do |f| %>
3 |
4 | <%= f.label :name %>
5 | <%= f.text_field :name, autofocus: true, required: "required", class: "form-control", class_for_error: "is-invalid" %>
6 | <%= f.error_message :name, class: "invalid-feedback" %>
7 |
8 |
9 |
10 | <%= f.submit class: "btn btn-primary" %>
11 |
12 | <% end %>
13 |
--------------------------------------------------------------------------------
/test/dummy/mruby/lib/input.rb:
--------------------------------------------------------------------------------
1 | module Input
2 | class << self
3 | def load(input)
4 | @input = input || {}
5 | @input.freeze
6 | end
7 |
8 | def value
9 | @input
10 | end
11 |
12 | def pack
13 | @input.pack
14 | end
15 |
16 | def [](key)
17 | @input[key]
18 | end
19 |
20 | def each(*args, &block)
21 | @input.each(*args, &block)
22 | end
23 |
24 | def map(*args, &block)
25 | @input.map(*args, &block)
26 | end
27 |
28 | def to_s
29 | @input.to_s
30 | end
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/integer.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class Integer < FormKit::Field
5 | serialize :validations, coder: Validations
6 | serialize :options, coder: Options
7 |
8 | def stored_type
9 | :integer
10 | end
11 |
12 | protected
13 |
14 | def interpret_extra_to(model, accessibility, _overrides = {})
15 | return if accessibility != :read_and_write
16 |
17 | model.validates key, numericality: { only_integer: true }, allow_blank: true
18 | end
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/test/dummy/app/views/kaminari/_first_page.html.erb:
--------------------------------------------------------------------------------
1 | <%# Link to the "First" page
2 | - available local variables
3 | url: url to the first page
4 | current_page: a page object for the currently displayed page
5 | num_pages: total number of pages
6 | per_page: number of items to fetch per page
7 | remote: data-remote
8 | -%>
9 | <% unless current_page.first? %>
10 |
11 | <%= link_to_unless current_page.first?, raw(t("views.pagination.first")), url, class: "page-link", remote: remote %>
12 |
13 | <% end %>
14 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/_nested_form.html.erb:
--------------------------------------------------------------------------------
1 | <% nesting ||= false %>
2 |
3 |
4 | <% form.fields.sort_by(&:position).each do |field| %>
5 | <% field = present(field, target: f.object) %>
6 | <% unless field.access_hidden? %>
7 | <%= render "_form_core/fields/#{field.type_key}", f: f, field: field, nesting: nesting %>
8 | <% end %>
9 | <% end %>
10 |
11 | <% if field.access_read_and_write? %>
12 | <%= link_to_remove_association "Remove", f, class: "text-danger", wrapper_class: "nested_form" %>
13 | <% end %>
14 |
15 |
--------------------------------------------------------------------------------
/test/dummy/app/views/kaminari/_next_page.html.erb:
--------------------------------------------------------------------------------
1 | <%# Link to the "Next" page
2 | - available local variables
3 | url: url to the next page
4 | current_page: a page object for the currently displayed page
5 | num_pages: total number of pages
6 | per_page: number of items to fetch per page
7 | remote: data-remote
8 | -%>
9 | <% unless current_page.last? %>
10 |
11 | <%= link_to_unless current_page.last?, raw(t("views.pagination.next")), url, class: "page-link", rel: "next", remote: remote %>
12 |
13 | <% end %>
14 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/data_sources/empty.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::DataSources
4 | class Empty < FormKit::DataSource
5 | def foreign_field_name_suffix
6 | ""
7 | end
8 |
9 | def foreign_field_name(field_name)
10 | field_name
11 | end
12 |
13 | def text_method
14 | nil
15 | end
16 |
17 | def interpret_to(_model, _field_name, _accessibility, _options = {}); end
18 |
19 | class << self
20 | def scoped_records(*)
21 | FormKit::ApplicationRecord.none
22 | end
23 | end
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/test/dummy/app/views/kaminari/_page.html.erb:
--------------------------------------------------------------------------------
1 | <%# Link showing page number
2 | - available local variables
3 | page: a page object for "this" page
4 | url: url to this page
5 | current_page: a page object for the currently displayed page
6 | num_pages: total number of pages
7 | per_page: number of items to fetch per page
8 | remote: data-remote
9 | -%>
10 | ">
11 | <%= link_to page, url, remote: remote, class: "page-link", rel: (page.next? ? "next" : (page.prev? ? "prev" : nil)) %>
12 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/instances/tasks_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Instances::TasksController < Instances::ApplicationController
4 | before_action :set_task, only: %i[finish]
5 |
6 | def finish
7 | unless @task.can_finish?
8 | redirect_to instance_url(@instance), notice: "Task can not finish."
9 | return
10 | end
11 |
12 | @task.finish!
13 |
14 | redirect_to instance_url(@instance), notice: "Task finished."
15 | end
16 |
17 | private
18 |
19 | def set_task
20 | @task = @instance.tasks.find(params[:id])
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/test/dummy/app/views/kaminari/_prev_page.html.erb:
--------------------------------------------------------------------------------
1 | <%# Link to the "Previous" page
2 | - available local variables
3 | url: url to the previous page
4 | current_page: a page object for the currently displayed page
5 | num_pages: total number of pages
6 | per_page: number of items to fetch per page
7 | remote: data-remote
8 | -%>
9 | <% unless current_page.first? %>
10 |
11 | <%= link_to_unless current_page.first?, raw(t("views.pagination.previous")), url, rel: "prev", remote: remote, class: "page-link" %>
12 |
13 | <% end %>
14 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/date.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class Date < FormKit::Field
5 | serialize :validations, coder: Validations
6 | serialize :options, coder: Options
7 |
8 | def stored_type
9 | :datetime
10 | end
11 |
12 | protected
13 |
14 | def interpret_extra_to(model, _accessibility, _overrides = {})
15 | model.class_eval <<-CODE, __FILE__, __LINE__ + 1
16 | def #{key}=(val)
17 | super(val.try(:in_time_zone)&.utc)
18 | end
19 | CODE
20 | end
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/branches/arc_guards/_form.html.erb:
--------------------------------------------------------------------------------
1 | <% url = arc_guard.new_record? ? pipeline_branch_arc_guards_path(pipeline, branch) : pipeline_branch_arc_guard_path(pipeline, branch, arc_guard) %>
2 | <%= form_with(model: arc_guard, scope: :arc_guard, url: url, local: true) do |f| %>
3 | <%= f.hidden_field :type %>
4 |
5 | <% if arc_guard.configurable? %>
6 | <%= render partial: "_flow_kit/arc_guards/#{arc_guard.type_key}", locals: { f: f, guard: arc_guard } %>
7 | <% end %>
8 |
9 |
10 | <%= f.submit class: "btn btn-primary" %>
11 |
12 | <% end %>
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/branches/steps/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | New Step
5 |
6 |
7 | <%= link_to "<<", pipeline_path(@pipeline), class: "btn btn-primary mr-2" %>
8 | <%= link_to "Back", pipeline_branch_path(@pipeline, @branch), class: "btn btn-primary" %>
9 |
10 |
11 |
12 | <%= render "form", pipeline: @pipeline, branch: @branch, step: @step %>
13 |
14 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/steps/transition_triggers/_form.html.erb:
--------------------------------------------------------------------------------
1 | <% url = pipeline_step_transition_trigger_path(pipeline, step) %>
2 | <%= form_with(model: transition_trigger, scope: :transition_trigger, url: url, local: true) do |f| %>
3 | <%= f.hidden_field :type %>
4 |
5 | <% if transition_trigger.configurable? %>
6 | <%= render partial: "_flow_kit/transition_triggers/#{transition_trigger.type_key}", locals: { f: f, pipeline: pipeline, trigger: transition_trigger } %>
7 | <% end %>
8 |
9 |
10 | <%= f.submit class: "btn btn-primary" %>
11 |
12 | <% end %>
13 |
--------------------------------------------------------------------------------
/test/dummy/app/models/flow_kit/arc_guards/ruby_script.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowKit::ArcGuards
4 | class RubyScript < FlowCore::ArcGuard
5 | serialize :configuration, coder: Configuration
6 |
7 | def permit?(task)
8 | result = ScriptEngine.run_inline configuration.script, payload: task.payload
9 | if result.errors.any?
10 | raise "Script has errored"
11 | end
12 |
13 | result.output
14 | end
15 |
16 | def description
17 | configuration.name
18 | end
19 |
20 | def configurable?
21 | true
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/datetime.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class Datetime < FormKit::Field
5 | serialize :validations, coder: Validations
6 | serialize :options, coder: Options
7 |
8 | def stored_type
9 | :datetime
10 | end
11 |
12 | protected
13 |
14 | def interpret_extra_to(model, _accessibility, _overrides = {})
15 | model.class_eval <<-CODE, __FILE__, __LINE__ + 1
16 | def #{key}=(val)
17 | super(val.try(:in_time_zone)&.utc)
18 | end
19 | CODE
20 | end
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/fields/_date.html.erb:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/fields/_datetime.html.erb:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/fields/_decimal.html.erb:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/fields/_integer.html.erb:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/fields/validations/_form.html.erb:
--------------------------------------------------------------------------------
1 | <%= form_with(model: validations, scope: :validations, url: field_validations_path(field), method: :patch, local: true) do |f| %>
2 | <% validations.class.attribute_names.each do |attribute_name| %>
3 | <%= render "_form_core/validations/#{attribute_name}", f: f, validations: validations %>
4 | <% end %>
5 | <% validations.class.reflections.keys.each do |attribute_name| %>
6 | <%= render "_form_core/validations/#{attribute_name}", f: f, validations: validations %>
7 | <% end %>
8 |
9 | <%= f.submit class: "btn btn-block btn-primary" %>
10 | <% end %>
11 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/branches/_form.html.erb:
--------------------------------------------------------------------------------
1 | <% url = branch.new_record? ? pipeline_step_branches_path(pipeline, step) : pipeline_branch_path(pipeline, branch) %>
2 | <%= form_with(model: branch, scope: :branch, url: url, local: true) do |f| %>
3 |
4 | <%= f.label :name %>
5 | <%= f.text_field :name, autofocus: true, required: "required", class: "form-control", class_for_error: "is-invalid" %>
6 | <%= f.error_message :name, class: "invalid-feedback" %>
7 |
8 |
9 |
10 | <%= f.submit class: "btn btn-primary" %>
11 |
12 | <% end %>
13 |
--------------------------------------------------------------------------------
/test/dummy/config/initializers/assets.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Be sure to restart your server when you modify this file.
4 |
5 | # Version of your assets, change this if you want to expire all your assets.
6 | Rails.application.config.assets.version = "1.0"
7 |
8 | # Add additional assets to the asset load path.
9 | # Rails.application.config.assets.paths << Emoji.images_path
10 |
11 | # Precompile additional assets.
12 | # application.js, application.css, and all non-JS/CSS in the app/assets
13 | # folder are already added.
14 | # Rails.application.config.assets.precompile += %w( admin.js admin.css )
15 |
--------------------------------------------------------------------------------
/test/dummy/config/initializers/wrap_parameters.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Be sure to restart your server when you modify this file.
4 |
5 | # This file contains settings for ActionController::ParamsWrapper which
6 | # is enabled by default.
7 |
8 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
9 | ActiveSupport.on_load(:action_controller) do
10 | wrap_parameters format: [:json]
11 | end
12 |
13 | # To enable root element in JSON for ActiveRecord objects.
14 | # ActiveSupport.on_load(:active_record) do
15 | # self.include_root_in_json = true
16 | # end
17 |
--------------------------------------------------------------------------------
/test/dummy/app/assets/stylesheets/application.scss:
--------------------------------------------------------------------------------
1 | @import "bootstrap";
2 | @import "./selectize/selectize.bootstrap";
3 |
4 | $header-height: 3.5rem;
5 |
6 | body {
7 | padding-top: $header-height;
8 | }
9 |
10 | .header-secondary {
11 | .has-toolbar {
12 | display: flex;
13 | }
14 |
15 | .nav {
16 | flex-direction: row;
17 |
18 | .nav-link {
19 | color: $secondary;
20 |
21 | &:hover {
22 | color: $dark;
23 | }
24 |
25 | .active {
26 | color: $dark;
27 | }
28 | }
29 | }
30 | }
31 |
32 | .nav-underline .active {
33 | border-bottom: 2px solid;
34 | }
35 |
--------------------------------------------------------------------------------
/test/dummy/app/models/flow_kit/transition_triggers/human_task/configuration.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowKit::TransitionTriggers
4 | class HumanTask
5 | class Configuration < SerializableModel::Base
6 | ASSIGN_TO_ENUM = {
7 | instance_creator: "instance_creator",
8 | candidate: "candidate"
9 | }.freeze
10 |
11 | attribute :assign_to, :string, default: ASSIGN_TO_ENUM[:instance_creator]
12 | enum assign_to: ASSIGN_TO_ENUM,
13 | _prefix: :assign_to
14 |
15 | validates :assign_to,
16 | presence: true
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/test/dummy/app/presenters/form_kit/fields/member_presenter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class MemberPresenter < FormKit::FieldPresenter
5 | def value_for_preview
6 | id = value
7 | return if id.blank?
8 |
9 | collection.find_by(id: id)&.name
10 | end
11 |
12 | def include_blank?
13 | required?
14 | end
15 |
16 | def collection
17 | @model.collection
18 | end
19 |
20 | def options_for_select
21 | @view.options_from_collection_for_select(
22 | collection, :id, :name, value
23 | )
24 | end
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/steps/branches/_form.html.erb:
--------------------------------------------------------------------------------
1 | <% url = branch.new_record? ? pipeline_step_branches_path(pipeline, step) : pipeline_branch_path(pipeline, branch) %>
2 | <%= form_with(model: branch, scope: :branch, url: url, local: true) do |f| %>
3 |
4 | <%= f.label :name %>
5 | <%= f.text_field :name, autofocus: true, required: "required", class: "form-control", class_for_error: "is-invalid" %>
6 | <%= f.error_message :name, class: "invalid-feedback" %>
7 |
8 |
9 |
10 | <%= f.submit class: "btn btn-primary" %>
11 |
12 | <% end %>
13 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/steps/branches/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | New Branch for <%= @step.name %>
5 |
6 |
7 | <%= link_to "<<", pipeline_path(@pipeline), class: "btn btn-primary mr-2" %>
8 | <%= link_to "Back", edit_pipeline_step_path(@pipeline, @step), class: "btn btn-primary" %>
9 |
10 |
11 |
12 | <%= render "form", pipeline: @pipeline, step: @step, branch: @branch %>
13 |
14 |
--------------------------------------------------------------------------------
/test/dummy/app/views/workflows/transitions/_form.html.erb:
--------------------------------------------------------------------------------
1 | <% url = transition.new_record? ? workflow_transitions_path(workflow) : workflow_transition_path(workflow, transition) %>
2 | <%= form_with(model: transition, scope: :transition, url: url, local: true) do |f| %>
3 |
4 | <%= f.label :name %>
5 | <%= f.text_field :name, autofocus: true, required: "required", class: "form-control", class_for_error: "is-invalid" %>
6 | <%= f.error_message :name, class: "invalid-feedback" %>
7 |
8 |
9 |
10 | <%= f.submit class: "btn btn-primary" %>
11 |
12 | <% end %>
13 |
--------------------------------------------------------------------------------
/test/dummy/config/locales/kaminari.en.yml:
--------------------------------------------------------------------------------
1 | en:
2 | helpers:
3 | page_entries_info:
4 | more_pages:
5 | display_entries: Displaying %{entry_name} %{first} - %{last} of %{total} in total
6 | one_page:
7 | display_entries:
8 | one: Displaying %{count} %{entry_name}
9 | other: Displaying all %{count} %{entry_name}
10 | zero: No %{entry_name} found
11 | views:
12 | pagination:
13 | first: "« First"
14 | last: Last »
15 | next: Next ›
16 | previous: "‹ Prev"
17 | truncate: "…"
18 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/embeds/decimal_range.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit
4 | module Embeds
5 | class DecimalRange < FormKit::VirtualModel
6 | attribute :begin, :decimal
7 | attribute :end, :decimal
8 |
9 | validates :begin, :end,
10 | numericality: { only_integer: false },
11 | allow_blank: true
12 |
13 | validates :end,
14 | numericality: {
15 | greater_than: :begin
16 | },
17 | allow_blank: true,
18 | if: -> { self[:begin].present? }
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/embeds/integer_range.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit
4 | module Embeds
5 | class IntegerRange < FormKit::VirtualModel
6 | attribute :begin, :integer
7 | attribute :end, :integer
8 |
9 | validates :begin, :end,
10 | numericality: { only_integer: true },
11 | allow_blank: true
12 |
13 | validates :end,
14 | numericality: {
15 | greater_than: :begin
16 | },
17 | allow_blank: true,
18 | if: -> { self[:begin].present? }
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/pipelines/steps/branches_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pipelines::Steps::BranchesController < Pipelines::Steps::ApplicationController
4 | def new
5 | @branch = @step.branches.new
6 | end
7 |
8 | def create
9 | @branch = @step.branches.new(branch_params)
10 |
11 | if @branch.save
12 | redirect_to pipeline_branch_url(@pipeline, @branch), notice: "Branch was successfully created."
13 | else
14 | render :new
15 | end
16 | end
17 |
18 | private
19 |
20 | def branch_params
21 | params.require(:branch).permit(:name, :type)
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/test/dummy/app/views/human_tasks/show.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Human Task
5 |
6 |
7 | <%= link_to 'Instance', instance_path(@human_task.instance), class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <%= render "form", human_task: @human_task %>
12 |
13 | <% if @human_task.finished? %>
14 |
15 |
16 |
17 | <%= @human_task.task.payload %>
18 |
19 | <% end %>
20 |
21 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/field/helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FormKit::Field
4 | module Helper
5 | extend ActiveSupport::Concern
6 |
7 | def options_configurable?
8 | options.is_a?(SerializableModel::Base) && options.attributes.any?
9 | end
10 |
11 | def validations_configurable?
12 | validations.is_a?(SerializableModel::Base) && validations.attributes.any?
13 | end
14 |
15 | def attached_choices?
16 | false
17 | end
18 |
19 | def attached_data_source?
20 | false
21 | end
22 |
23 | def attached_nested_form?
24 | false
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/steps/redirections/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Editing Redirection
5 |
6 |
7 | <%= link_to "<<", pipeline_path(@pipeline), class: "btn btn-primary mr-2" %>
8 | <%= link_to 'Back', edit_pipeline_step_path(@pipeline, @step), class: "btn btn-primary mr-2" %>
9 |
10 |
11 |
12 |
13 | <%= render "form", pipeline: @pipeline, step: @step %>
14 |
15 |
16 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/workflows/arcs_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Workflows::ArcsController < Workflows::ApplicationController
4 | before_action :set_arc, only: %i[edit update]
5 |
6 | def edit; end
7 |
8 | def update
9 | if @arc.update arc_params
10 | redirect_back fallback_location: workflow_transition_url(@workflow, @arc.transition), notice: "Arc updated."
11 | else
12 | render :edit
13 | end
14 | end
15 |
16 | private
17 |
18 | def set_arc
19 | @arc = @workflow.arcs.out.find(params[:id])
20 | end
21 |
22 | def arc_params
23 | params.require(:arc).permit!
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/test/dummy/app/views/workflows/instances/_form.html.erb:
--------------------------------------------------------------------------------
1 | <%= form_with(model: instance, scope: :instance, url: workflow_instances_path(workflow), method: :post, local: true) do |f| %>
2 | <%= f.fields_for :form_attributes, instance.form_record do |ff| %>
3 | <% fields = instance.form.fields.order(position: :asc).map { |field| present(field, target: instance.form_record) }.reject(&:access_hidden?) %>
4 |
5 | <% fields.each do |field| %>
6 | <%= render "_form_core/fields/#{field.type_key}", f: ff, field: field %>
7 | <% end %>
8 | <% end %>
9 |
10 |
11 | <%= f.submit class: "btn btn-primary" %>
12 |
13 | <% end %>
14 |
--------------------------------------------------------------------------------
/test/dummy/app/presenters/form_kit/fields/select_presenter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class SelectPresenter < FormKit::FieldPresenter
5 | def include_blank?
6 | required?
7 | end
8 |
9 | def can_custom_value?
10 | !@model.options.strict_select
11 | end
12 |
13 | def collection
14 | collection = @model.choices.map(&:label)
15 | if can_custom_value? && value.present?
16 | ([value] + collection).uniq
17 | else
18 | collection
19 | end
20 | end
21 |
22 | def options_for_select
23 | @view.options_for_select(collection, value)
24 | end
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/steps/redirections/_form.html.erb:
--------------------------------------------------------------------------------
1 | <%= form_with(model: step, scope: :step, url: pipeline_step_redirection_path(pipeline, step), local: true) do |f| %>
2 |
3 | <%= f.label :redirect_to_step_id %>
4 | <%= f.select :redirect_to_step_id, redirectable_steps_options_for_select(step), { include_blank: true }, ref_method: :redirect_to_step, class: "form-control", class_for_error: "is-invalid" %>
5 | <%= f.error_message :redirect_to_step_id, ref_method: :redirect_to_step, class: "invalid-feedback" %>
6 |
7 |
8 |
9 | <%= f.submit class: "btn btn-primary" %>
10 |
11 | <% end %>
12 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/pipelines/steps/redirections_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pipelines::Steps::RedirectionsController < Pipelines::Steps::ApplicationController
4 | def show
5 | redirect_to edit_pipeline_step_redirection_url(@pipeline, @step)
6 | end
7 |
8 | def edit; end
9 |
10 | def update
11 | if @step.update(step_params)
12 | redirect_to edit_pipeline_step_url(@pipeline, @step), notice: "Redirection step was successfully updated."
13 | else
14 | render :edit
15 | end
16 | end
17 |
18 | private
19 |
20 | def step_params
21 | params.require(:step).permit(:redirect_to_step_id)
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/app/models/flow_core/steps/task.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowCore::Steps
4 | class Task < FlowCore::Step
5 | def deploy_to_workflow!(workflow, input_place_or_transition)
6 | input_place = find_or_create_input_place(workflow, input_place_or_transition)
7 |
8 | transition = input_place.output_transitions.create! workflow: workflow, name: name, generated_by_step_id: id
9 | copy_transition_trigger_to transition
10 |
11 | transition
12 | end
13 |
14 | class << self
15 | def creatable?
16 | true
17 | end
18 |
19 | def transition_trigger_required?
20 | true
21 | end
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/date_range.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class DateRange < FormKit::Field
5 | serialize :validations, coder: Validations
6 | serialize :options, coder: Options
7 |
8 | protected
9 |
10 | def interpret_attribute_to(model, _accessibility, _overrides = {})
11 | nested_model = Class.new(FormKit::Embeds::DateRange)
12 | model.nested_models[key] = nested_model
13 |
14 | name = key.to_sym
15 | model.embeds_one name, anonymous_class: nested_model, validate: true
16 | model.accepts_nested_attributes_for name, reject_if: :all_blank
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/datetime_range.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class DatetimeRange < FormKit::Field
5 | serialize :validations, coder: Validations
6 | serialize :options, coder: Options
7 |
8 | protected
9 |
10 | def interpret_attribute_to(model, _accessibility, _overrides = {})
11 | nested_model = Class.new(FormKit::Embeds::DatetimeRange)
12 | model.nested_models[key] = nested_model
13 |
14 | name = key.to_sym
15 | model.embeds_one name, anonymous_class: nested_model, validate: true
16 | model.accepts_nested_attributes_for name, reject_if: :all_blank
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/decimal_range.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class DecimalRange < FormKit::Field
5 | serialize :validations, coder: Validations
6 | serialize :options, coder: Options
7 |
8 | protected
9 |
10 | def interpret_attribute_to(model, _accessibility, _overrides = {})
11 | nested_model = Class.new(FormKit::Embeds::DecimalRange)
12 | model.nested_models[key] = nested_model
13 |
14 | name = key.to_sym
15 | model.embeds_one name, anonymous_class: nested_model, validate: true
16 | model.accepts_nested_attributes_for name, reject_if: :all_blank
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/integer_range.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class IntegerRange < FormKit::Field
5 | serialize :validations, coder: Validations
6 | serialize :options, coder: Options
7 |
8 | protected
9 |
10 | def interpret_attribute_to(model, _accessibility, _overrides = {})
11 | nested_model = Class.new(FormKit::Embeds::IntegerRange)
12 | model.nested_models[key] = nested_model
13 |
14 | name = key.to_sym
15 | model.embeds_one name, anonymous_class: nested_model, validate: true
16 | model.accepts_nested_attributes_for name, reject_if: :all_blank
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/select.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class Select < FormKit::Field
5 | serialize :validations, coder: Validations
6 | serialize :options, coder: Options
7 |
8 | include Fakable
9 |
10 | def stored_type
11 | :string
12 | end
13 |
14 | def attached_choices?
15 | true
16 | end
17 |
18 | protected
19 |
20 | def interpret_extra_to(model, accessibility, _overrides = {})
21 | return if accessibility != :read_and_write || !options.strict_select
22 |
23 | model.validates key, inclusion: { in: choices.pluck(:label) }, allow_blank: true
24 | end
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/embeds/date_range.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit
4 | module Embeds
5 | class DateRange < FormKit::VirtualModel
6 | attribute :begin, :datetime
7 | attribute :end, :datetime
8 |
9 | validates :end,
10 | timeliness: {
11 | after: :begin,
12 | type: :date
13 | },
14 | allow_blank: true,
15 | if: -> { self[:begin].present? }
16 |
17 | def begin=(val)
18 | super(val.try(:in_time_zone)&.utc)
19 | end
20 |
21 | def end=(val)
22 | super(val.try(:in_time_zone)&.utc)
23 | end
24 | end
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/test/dummy/app/views/forms/previews/show.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= render "forms/tabs" %>
3 |
4 |
5 | <% if @instance.errors.any? %>
6 |
7 |
<%= pluralize(@instance.errors.count, "error") %> prohibited this form from being saved:
8 |
9 | <% @instance.errors.full_messages.each do |message| %>
10 | <%= message %>
11 | <% end %>
12 |
13 |
14 | <% end %>
15 |
16 |
17 | <%= render "_form_core/render/form",
18 | form: @form, instance: @instance,
19 | options: {scope: :preview, url: form_preview_path(@form), local: true} %>
20 |
21 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/fields/_boolean.html.erb:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "bundler/setup"
4 | require "rdoc/task"
5 |
6 | RDoc::Task.new(:rdoc) do |rdoc|
7 | rdoc.rdoc_dir = "rdoc"
8 | rdoc.title = "FlowCore"
9 | rdoc.options << "--line-numbers"
10 | rdoc.rdoc_files.include("README.md")
11 | rdoc.rdoc_files.include("lib/**/*.rb")
12 | end
13 |
14 | APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
15 | load "rails/tasks/engine.rake"
16 |
17 | load "rails/tasks/statistics.rake"
18 |
19 | require "bundler/gem_tasks"
20 |
21 | require "rake/testtask"
22 |
23 | Rake::TestTask.new(:test) do |t|
24 | t.libs << "test"
25 | t.pattern = "test/**/*_test.rb"
26 | t.verbose = false
27 | end
28 |
29 | task default: :test
30 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/embeds/datetime_range.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit
4 | module Embeds
5 | class DatetimeRange < FormKit::VirtualModel
6 | attribute :begin, :datetime
7 | attribute :end, :datetime
8 |
9 | validates :end,
10 | timeliness: {
11 | after: :begin,
12 | type: :datetime
13 | },
14 | allow_blank: true,
15 | if: -> { self[:begin].present? }
16 |
17 | def begin=(val)
18 | super(val.try(:in_time_zone)&.utc)
19 | end
20 |
21 | def end=(val)
22 | super(val.try(:in_time_zone)&.utc)
23 | end
24 | end
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/test/dummy/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | en:
2 | site:
3 | name: FlowCore
4 | description: FlowCore dummy app
5 | keywords: []
6 | copyright:
7 | html: >
8 |
9 | FlowCore
10 |
11 | crafted by Jun Jiang (jasl) .
12 |
13 | The source code and the dummy app are licensed under MIT license .
14 | transition_triggers:
15 | human_task:
16 | assign_to:
17 | instance_creator: "Instance creator"
18 | user: "User"
19 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/validations/_format.html.erb:
--------------------------------------------------------------------------------
1 | <% validations.build_format unless validations.format %>
2 | <% format = validations.format %>
3 |
4 | Format
5 |
6 | <%= f.fields_for :format, format do |ff| %>
7 |
8 | <%= ff.label :with %>
9 | <%= ff.text_field :with, class: "form-control", class_for_error: "is-invalid" %>
10 | <%= ff.error_message :with, class: "invalid-feedback" %>
11 |
12 |
13 |
14 | <%= ff.label :message %>
15 | <%= ff.text_field :message, class: "form-control", class_for_error: "is-invalid" %>
16 | <%= ff.error_message :message, class: "invalid-feedback" %>
17 |
18 | <% end %>
19 |
20 |
21 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/human_tasks_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class HumanTasksController < ApplicationController
4 | before_action :set_human_task
5 |
6 | def show; end
7 |
8 | def update
9 | if @human_task.fill_form!(human_task_params)
10 | @human_task.finish!
11 |
12 | redirect_to instance_url(@human_task.instance), notice: "Task finished."
13 | else
14 | render :show
15 | end
16 | end
17 |
18 | private
19 |
20 | def set_human_task
21 | @human_task = FlowKit::HumanTask.find(params[:id])
22 | end
23 |
24 | def human_task_params
25 | params.fetch(:human_task, {}).permit(form_attributes: {}, attached_form_attributes: {})
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/forms/application_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Forms::ApplicationController < ApplicationController
4 | before_action :set_form
5 | before_action :set_form_layout_data
6 |
7 | protected
8 |
9 | # Use callbacks to share common setup or constraints between actions.
10 | def set_form
11 | @form = FormKit::Form.find(params[:form_id])
12 | end
13 |
14 | def set_strict_loaded_fields
15 | @form.fields.includes(:choices)
16 | end
17 |
18 | def set_form_layout_data
19 | @_breadcrumbs =
20 | [
21 | { text: "Forms", link: forms_path },
22 | { text: @form.name, link: form_path(@form) }
23 | ]
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/workflows/transitions_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Workflows::TransitionsController < Workflows::ApplicationController
4 | before_action :set_transition, only: %i[show update]
5 |
6 | def show; end
7 |
8 | def update
9 | if @transition.update transition_params
10 | redirect_to workflow_transition_url(@workflow, @transition), notice: "Transition updated."
11 | else
12 | render :show
13 | end
14 | end
15 |
16 | private
17 |
18 | def set_transition
19 | @transition = @workflow.transitions.find(params[:id])
20 | end
21 |
22 | def transition_params
23 | params.require(:transition).permit(:name, :handler_class_name)
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/fields/_choice.html.erb:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/test/dummy/config/database.yml:
--------------------------------------------------------------------------------
1 | # SQLite. Versions 3.8.0 and up are supported.
2 | # gem install sqlite3
3 | #
4 | # Ensure the SQLite 3 gem is defined in your Gemfile
5 | # gem 'sqlite3'
6 | #
7 | default: &default
8 | adapter: sqlite3
9 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
10 | timeout: 5000
11 |
12 | development:
13 | <<: *default
14 | database: db/development.sqlite3
15 |
16 | # Warning: The database defined as "test" will be erased and
17 | # re-generated from your development database when you run "rake".
18 | # Do not set this db to the same as development or production.
19 | test:
20 | <<: *default
21 | database: db/test.sqlite3
22 |
23 | production:
24 | <<: *default
25 | database: db/production.sqlite3
26 |
--------------------------------------------------------------------------------
/test/dummy/config/database.yml.sqlite.example:
--------------------------------------------------------------------------------
1 | # SQLite. Versions 3.8.0 and up are supported.
2 | # gem install sqlite3
3 | #
4 | # Ensure the SQLite 3 gem is defined in your Gemfile
5 | # gem 'sqlite3'
6 | #
7 | default: &default
8 | adapter: sqlite3
9 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
10 | timeout: 5000
11 |
12 | development:
13 | <<: *default
14 | database: db/development.sqlite3
15 |
16 | # Warning: The database defined as "test" will be erased and
17 | # re-generated from your development database when you run "rake".
18 | # Do not set this db to the same as development or production.
19 | test:
20 | <<: *default
21 | database: db/test.sqlite3
22 |
23 | production:
24 | <<: *default
25 | database: db/production.sqlite3
26 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/multiple_select.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class MultipleSelect < FormKit::Field
5 | serialize :validations, coder: Validations
6 | serialize :options, coder: Options
7 |
8 | include Fakable
9 |
10 | def stored_type
11 | :string
12 | end
13 |
14 | def attached_choices?
15 | true
16 | end
17 |
18 | def array?
19 | true
20 | end
21 |
22 | protected
23 |
24 | def interpret_extra_to(model, accessibility, _overrides = {})
25 | return if accessibility != :read_and_write || !options.strict_select
26 |
27 | model.validates key, subset: { in: choices.pluck(:label) }, allow_blank: true
28 | end
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/choice.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class Choice < FormKit::Field
5 | serialize :validations, coder: Validations
6 | serialize :options, coder: FormKit::NonConfigurable
7 |
8 | include Fakable
9 |
10 | def stored_type
11 | :integer
12 | end
13 |
14 | def attached_choices?
15 | true
16 | end
17 |
18 | protected
19 |
20 | def interpret_extra_to(model, accessibility, _overrides = {})
21 | return if accessibility != :read_and_write
22 |
23 | choice_ids = choices.pluck(:id)
24 | return if choice_ids.empty?
25 |
26 | model.validates key, inclusion: { in: choice_ids }, allow_blank: true
27 | end
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/resource.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class Resource < FormKit::Field
5 | serialize :options, coder: Options
6 | serialize :validations, coder: Validations
7 |
8 | def stored_type
9 | :integer
10 | end
11 |
12 | delegate :data_source, to: :options
13 |
14 | def collection
15 | data_source.scoped_records
16 | end
17 |
18 | def attached_data_source?
19 | true
20 | end
21 |
22 | protected
23 |
24 | def interpret_extra_to(model, accessibility, _overrides = {})
25 | return if accessibility != :read_and_write
26 |
27 | model.validates key, inclusion: { in: -> { collection } }, allow_blank: true
28 | end
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/field_options/_resource_select.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= f.label :data_source_type %>
3 | <%= f.select :data_source_type, options_for_data_source_types(selected: options.data_source_type), { class_for_error: "is-invalid" }, class: "form-control" %>
4 | <%= f.error_message :data_source_type, class: "invalid-feedback" %>
5 |
6 |
7 |
16 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/fields/_multiple_choice.html.erb:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/field_options/_multiple_resource.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= f.label :data_source_type %>
3 | <%= f.select :data_source_type, options_for_data_source_types(selected: options.data_source_type), { class_for_error: "is-invalid" }, class: "form-control" %>
4 | <%= f.error_message :data_source_type, class: "invalid-feedback" %>
5 |
6 |
7 |
16 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/field_options/_multiple_resource_select.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= f.label :data_source_type %>
3 | <%= f.select :data_source_type, options_for_data_source_types(selected: options.data_source_type), { class_for_error: "is-invalid" }, class: "form-control" %>
4 | <%= f.error_message :data_source_type, class: "invalid-feedback" %>
5 |
6 |
7 |
16 |
--------------------------------------------------------------------------------
/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # This command will automatically be run when you run "rails" with Rails gems
3 | # installed from the root of your application.
4 |
5 | # Set environment variables for debugging
6 | ENV['RUBY_DEBUG_OPEN'] ||= 'true'
7 | ENV['RUBY_DEBUG_LAZY'] ||= 'true'
8 | ENV['PORT'] ||= '3003'
9 |
10 | # Continue with the standard Rails startup
11 | ENGINE_ROOT = File.expand_path('..', __dir__)
12 | ENGINE_PATH = File.expand_path('../lib/flow_core/engine', __dir__)
13 | APP_PATH = File.expand_path('../test/dummy/config/application', __dir__)
14 |
15 | # Set up gems listed in the Gemfile.
16 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
17 | require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
18 |
19 | require 'rails/all'
20 | require 'rails/engine/commands'
21 |
--------------------------------------------------------------------------------
/test/dummy/mruby/engine.gembox:
--------------------------------------------------------------------------------
1 | MRuby::GemBox.new do |conf|
2 | conf.gem(github: "jasl-lab/mruby-mpdecimal", branch: "master")
3 |
4 | conf.gem(core: "mruby-math")
5 | conf.gem(core: "mruby-time")
6 | conf.gem(core: "mruby-struct")
7 | conf.gem(core: "mruby-compar-ext")
8 | conf.gem(core: "mruby-enum-ext")
9 | conf.gem(core: "mruby-string-ext")
10 | conf.gem(core: "mruby-numeric-ext")
11 | conf.gem(core: "mruby-array-ext")
12 | conf.gem(core: "mruby-hash-ext")
13 | conf.gem(core: "mruby-range-ext")
14 | conf.gem(core: "mruby-proc-ext")
15 | conf.gem(core: "mruby-symbol-ext")
16 | conf.gem(core: "mruby-object-ext")
17 | conf.gem(core: "mruby-toplevel-ext")
18 | conf.gem(core: "mruby-kernel-ext")
19 | conf.gem(core: "mruby-compiler")
20 | conf.gem(core: "mruby-metaprog")
21 | end
22 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/fields/options_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Fields::OptionsController < Fields::ApplicationController
4 | before_action :set_options
5 | before_action :set_page_layout
6 |
7 | def edit; end
8 |
9 | def update
10 | @options.assign_attributes(options_params)
11 | if @options.valid? && @field.save(validate: false)
12 | redirect_to fields_url, notice: "Field was successfully updated."
13 | else
14 | render :edit
15 | end
16 | end
17 |
18 | private
19 |
20 | def set_options
21 | @options = @field.options
22 | end
23 |
24 | def set_page_layout
25 | @_breadcrumbs << { text: "Options" }
26 | end
27 |
28 | def options_params
29 | params.fetch(:options, {}).permit!
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/test/dummy/app/assets/stylesheets/selectize/plugins/dropdown_header.scss:
--------------------------------------------------------------------------------
1 | .selectize-dropdown-header {
2 | position: relative;
3 | padding: $selectize-padding-dropdown-item-y $selectize-padding-dropdown-item-x;
4 | border-bottom: 1px solid $selectize-color-border;
5 | background: mix($selectize-color-dropdown, $selectize-color-border, 85%);
6 | @include selectize-border-radius($selectize-border-radius $selectize-border-radius 0 0);
7 | }
8 | .selectize-dropdown-header-close {
9 | position: absolute;
10 | right: $selectize-padding-dropdown-item-x;
11 | top: 50%;
12 | color: $selectize-color-text;
13 | opacity: 0.4;
14 | margin-top: -12px;
15 | line-height: 20px;
16 | font-size: 20px !important;
17 | }
18 | .selectize-dropdown-header-close:hover {
19 | color: darken($selectize-color-text, 25%);
20 | }
--------------------------------------------------------------------------------
/test/dummy/app/javascript/packs/application.js:
--------------------------------------------------------------------------------
1 | // This is a manifest file that'll be compiled into application.js, which will include all the files
2 | // listed below.
3 | //
4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5 | // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6 | //
7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8 | // compiled file. JavaScript code in this file should be added after the last require_* statement.
9 | //
10 | // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11 | // about supported directives.
12 | //
13 | //= require rails-ujs
14 | //= require activestorage
15 | //= require_tree .
16 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/branches/arc_guards/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Editing guard
5 |
6 |
7 | <%= link_to "<<", pipeline_path(@pipeline), class: "btn btn-primary mr-2" %>
8 | <%= link_to "Back", edit_pipeline_branch_path(@pipeline, @branch), class: "btn btn-primary mr-2" %>
9 | <%= link_to "Destroy", pipeline_branch_arc_guard_path(@pipeline, @branch, @arc_guard), method: :delete, class: "btn btn-danger", data: { confirm: "Are you sure?" } %>
10 |
11 |
12 |
13 | <%= render "form", pipeline: @pipeline, branch: @branch, arc_guard: @arc_guard %>
14 |
15 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/resource_select.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class ResourceSelect < FormKit::Field
5 | serialize :options, coder: Options
6 | serialize :validations, coder: Validations
7 |
8 | def stored_type
9 | :string
10 | end
11 |
12 | delegate :data_source, to: :options
13 |
14 | def collection
15 | data_source.scoped_records
16 | end
17 |
18 | def attached_data_source?
19 | true
20 | end
21 |
22 | protected
23 |
24 | def interpret_extra_to(model, accessibility, _overrides = {})
25 | return if accessibility != :read_and_write || !options.strict_select
26 |
27 | model.validates key, inclusion: { in: -> { collection } }, allow_blank: true
28 | end
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/fields/_text.html.erb:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/test/dummy/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Be sure to restart your server when you modify this file.
4 |
5 | # Add new inflection rules using the following format. Inflections
6 | # are locale specific, and you may define rules for as many different
7 | # locales as you wish. All of these examples are active by default:
8 | ActiveSupport::Inflector.inflections(:en) do |inflect|
9 | # inflect.plural /^(ox)$/i, '\1en'
10 | # inflect.singular /^(ox)en/i, '\1'
11 | # inflect.irregular 'person', 'people'
12 | # inflect.uncountable %w( fish sheep )
13 | inflect.irregular "leave", "leaves"
14 | end
15 |
16 | # These inflection rules are supported but not enabled by default:
17 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
18 | # inflect.acronym 'RESTful'
19 | # end
20 |
--------------------------------------------------------------------------------
/lib/flow_core/definition/place.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowCore::Definition
4 | class Place
5 | attr_reader :tag, :attributes
6 |
7 | def initialize(tag, attributes = {})
8 | raise TypeError unless tag.is_a? Symbol
9 |
10 | @tag = tag
11 | @attributes = attributes.with_indifferent_access.except(FlowCore::Place::FORBIDDEN_ATTRIBUTES)
12 | @attributes[:name] ||= tag.to_s
13 | @attributes[:tag] ||= tag.to_s
14 | end
15 |
16 | def compile
17 | {
18 | tag: @tag,
19 | attributes: @attributes
20 | }
21 | end
22 |
23 | def eql?(other)
24 | if other.is_a? FlowCore::Definition::Place
25 | @tag == other.tag
26 | else
27 | false
28 | end
29 | end
30 |
31 | alias == eql?
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/steps/transition_triggers/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Editing trigger
5 |
6 |
7 | <%= link_to "<<", pipeline_path(@pipeline), class: "btn btn-primary mr-2" %>
8 | <%= link_to 'Back', edit_pipeline_step_path(@pipeline, @step), class: "btn btn-primary mr-2" %>
9 | <%= link_to "Destroy", pipeline_step_transition_trigger_path(@pipeline, @step), method: :delete, class: "btn btn-danger", data: { confirm: "Are you sure?" } %>
10 |
11 |
12 |
13 | <%= render "form", pipeline: @pipeline, step: @step, transition_trigger: @transition_trigger %>
14 |
15 |
--------------------------------------------------------------------------------
/test/dummy/app/views/workflows/transitions/show.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= @transition.name %>
5 |
6 |
7 | <%= link_to 'Back', workflow_path(@workflow), class: "btn btn-primary" %>
8 |
9 |
10 |
11 |
12 | <%= Graphviz::output(@workflow.to_graphviz, format: "svg").html_safe %>
13 |
14 |
15 | <%= render "form", workflow: @workflow, transition: @transition %>
16 |
17 |
18 |
19 | <% if @transition.trigger %>
20 | <%= render "workflows/transitions/triggers/form", workflow: @workflow, transition: @transition, trigger: @transition.trigger %>
21 | <% end %>
22 |
23 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/multiple_choice.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class MultipleChoice < FormKit::Field
5 | serialize :validations, coder: Validations
6 | serialize :options, coder: FormKit::NonConfigurable
7 |
8 | include Fakable
9 |
10 | def stored_type
11 | :integer
12 | end
13 |
14 | def attached_choices?
15 | true
16 | end
17 |
18 | def array?
19 | true
20 | end
21 |
22 | protected
23 |
24 | def interpret_extra_to(model, accessibility, _overrides = {})
25 | return if accessibility != :read_and_write
26 |
27 | choice_ids = choices.pluck(:id)
28 | return if choice_ids.empty?
29 |
30 | model.validates key, subset: { in: choice_ids }, allow_blank: true
31 | end
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/multiple_resource.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class MultipleResource < FormKit::Field
5 | serialize :validations, coder: Validations
6 | serialize :options, coder: Options
7 |
8 | def stored_type
9 | :string
10 | end
11 |
12 | delegate :data_source, to: :options
13 |
14 | def collection
15 | data_source.scoped_records
16 | end
17 |
18 | def attached_data_source?
19 | true
20 | end
21 |
22 | def array?
23 | true
24 | end
25 |
26 | protected
27 |
28 | def interpret_extra_to(model, accessibility, _overrides = {})
29 | return if accessibility != :read_and_write
30 |
31 | model.validates key, subset: { in: -> { collection } }, allow_blank: true
32 | end
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/fields/validations_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Fields::ValidationsController < Fields::ApplicationController
4 | before_action :set_validations
5 | before_action :set_page_layout
6 |
7 | def edit; end
8 |
9 | def update
10 | @validations.assign_attributes(validations_params)
11 | if @validations.valid? && @field.save(validate: false)
12 | redirect_to fields_url, notice: "Field was successfully updated."
13 | else
14 | render :edit
15 | end
16 | end
17 |
18 | private
19 |
20 | def set_validations
21 | @validations = @field.validations
22 | end
23 |
24 | def set_page_layout
25 | @_breadcrumbs << { text: "Validation" }
26 | end
27 |
28 | def validations_params
29 | params.fetch(:validations, {}).permit!
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/test/dummy/app/views/instances/index.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Instances
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | ID
14 | Workflow
15 |
16 |
17 |
18 |
19 |
20 | <% @instances.each do |instance| %>
21 |
22 | <%= instance.id %>
23 | <%= instance.workflow.name %>
24 |
25 | <%= link_to 'Show', instance_path(instance) %>
26 |
27 |
28 | <% end %>
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/forms/previews_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Forms::PreviewsController < Forms::ApplicationController
4 | before_action :set_strict_loaded_fields
5 | before_action :set_preview
6 | before_action :set_preview_page_layout
7 |
8 | def show
9 | @instance = @preview.new
10 | end
11 |
12 | def create
13 | @instance = @preview.new(preview_params)
14 | if @instance.valid?
15 | render :create
16 | else
17 | render :show, status: :unprocessable_entity
18 | end
19 | end
20 |
21 | private
22 |
23 | def set_preview
24 | @preview = @form.to_virtual_model
25 | end
26 |
27 | def set_preview_page_layout
28 | @_breadcrumbs << { text: "Preview" }
29 | end
30 |
31 | def preview_params
32 | params.fetch(:preview, {}).permit!
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/app/models/flow_core/steps/end.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowCore::Steps
4 | class End < FlowCore::Step
5 | def deploy_to_workflow!(workflow, input_place_or_transition)
6 | target_place = workflow.end_place || workflow.create_end_place!
7 |
8 | if input_place_or_transition.is_a? FlowCore::Transition
9 | target_place.input_transitions << input_place_or_transition
10 | else
11 | input_place_or_transition.input_arcs.update place: target_place
12 | input_place_or_transition.reload.destroy!
13 | end
14 |
15 | nil
16 | end
17 |
18 | class << self
19 | def creatable?
20 | true
21 | end
22 |
23 | def redirection_step?
24 | true
25 | end
26 |
27 | def redirection_configurable?
28 | false
29 | end
30 | end
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/test/dummy/app/presenters/form_kit/fields/resource_select_presenter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class ResourceSelectPresenter < FormKit::FieldPresenter
5 | def include_blank?
6 | required?
7 | end
8 |
9 | def can_custom_value?
10 | !@model.options.strict_select
11 | end
12 |
13 | def collection
14 | values =
15 | if @model.collection
16 | # TODO: limit 100 for performance
17 | @model.collection.limit(100).map(&@model.data_source.text_method)
18 | else
19 | []
20 | end
21 |
22 | if can_custom_value? && value.present?
23 | ([value] + values).uniq
24 | else
25 | values
26 | end
27 | end
28 |
29 | def options_for_select
30 | @view.options_for_select(collection, value)
31 | end
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/multiple_resource_select.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class MultipleResourceSelect < FormKit::Field
5 | serialize :validations, coder: Validations
6 | serialize :options, coder: Options
7 |
8 | def stored_type
9 | :string
10 | end
11 |
12 | delegate :data_source, to: :options
13 |
14 | def collection
15 | data_source.scoped_records
16 | end
17 |
18 | def attached_data_source?
19 | true
20 | end
21 |
22 | def array?
23 | true
24 | end
25 |
26 | protected
27 |
28 | def interpret_extra_to(model, accessibility, _overrides = {})
29 | return if accessibility != :read_and_write || !options.strict_select
30 |
31 | model.validates key, subset: { in: -> { collection } }, allow_blank: true
32 | end
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Configure Rails Environment
4 | ENV["RAILS_ENV"] = "test"
5 |
6 | require_relative "../test/dummy/config/environment"
7 | ActiveRecord::Migrator.migrations_paths = [File.expand_path("../test/dummy/db/migrate", __dir__)]
8 | require "rails/test_help"
9 |
10 | # Filter out the backtrace from minitest while preserving the one from other libraries.
11 | Minitest.backtrace_filter = Minitest::BacktraceFilter.new
12 |
13 | # Load fixtures from the engine
14 | if ActiveSupport::TestCase.respond_to?(:fixture_path=)
15 | ActiveSupport::TestCase.fixture_path = File.expand_path("fixtures", __dir__)
16 | ActionDispatch::IntegrationTest.fixture_path = ActiveSupport::TestCase.fixture_path
17 | ActiveSupport::TestCase.file_fixture_path = ActiveSupport::TestCase.fixture_path + "/files"
18 | ActiveSupport::TestCase.fixtures :all
19 | end
20 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/preview/_form.html.erb:
--------------------------------------------------------------------------------
1 | <% fields = form.fields.map { |field| present(field, target: instance) }.reject(&:access_hidden?) %>
2 |
3 | <% fields.each do |field| %>
4 | <% if field.nested_form_field? %>
5 | <% next unless field.value_for_preview %>
6 |
7 | <%= field.key %>:
8 | <%= render "_form_core/preview/nested_form", form: field.nested_form, instance: field.value_for_preview %>
9 | <% elsif field.multiple_nested_form? %>
10 | <% next if field.value_for_preview.empty? %>
11 |
12 | <%= field.key %>:
13 | <%= field.value_for_preview.map do |nested_instance| %>
14 | <% render "_form_core/preview/nested_form", form: field.nested_form, instance: nested_instance %>
15 | <% end.join(" ").html_safe %>
16 | <% else %>
17 | <%= field.key %>: <%= field.value_for_preview %>
18 | <% end %>
19 | <% end %>
20 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/form_override.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit
4 | class FormOverride < ApplicationRecord
5 | self.table_name = "form_kit_form_overrides"
6 |
7 | belongs_to :form, class_name: "FormKit::MetalForm", foreign_key: "form_id"
8 |
9 | has_many :field_overrides, class_name: "FormKit::FieldOverride", inverse_of: :form_override, dependent: :delete_all, validate: true, autosave: true
10 |
11 | accepts_nested_attributes_for :field_overrides, reject_if: proc { |attributes| attributes["accessibility"].blank? }
12 |
13 | def to_overrides_options
14 | hash = {}
15 |
16 | field_overrides.includes(:field).each do |field_override|
17 | hash[field_override.field.key] = {
18 | accessibility: field_override.accessibility.to_sym
19 | }
20 | end
21 |
22 | hash
23 | end
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/instances_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class InstancesController < ApplicationController
4 | before_action :set_instance, only: %i[show activate]
5 |
6 | def index
7 | @instances = FlowCore::Instance.all.includes(:workflow)
8 | end
9 |
10 | def show
11 | @human_tasks = FlowKit::HumanTask.where(instance: @instance).includes(:assignable)
12 | @tasks = @instance.tasks.includes(:transition)
13 | end
14 |
15 | def activate
16 | unless @instance.can_activate?
17 | redirect_to instance_url(@instance), notice: "Instance can not activate."
18 | return
19 | end
20 |
21 | @instance.activate!
22 |
23 | redirect_to instance_url(@instance), notice: "Instance activated."
24 | end
25 |
26 | private
27 |
28 | def set_instance
29 | @instance = FlowCore::Instance.find(params[:id])
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/nested_form.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class NestedForm < FormKit::Field
5 | after_create do
6 | build_nested_form.save!
7 | end
8 |
9 | serialize :validations, coder: Validations
10 | serialize :options, coder: FormKit::NonConfigurable
11 |
12 | def attached_nested_form?
13 | true
14 | end
15 |
16 | protected
17 |
18 | def interpret_attribute_to(model, accessibility, _overrides = {})
19 | nested_model = nested_form.to_virtual_model(overrides: { _global: { accessibility: accessibility } })
20 | model.nested_models[key] = nested_model
21 |
22 | name = key.to_sym
23 | model.embeds_one name, anonymous_class: nested_model, validate: true
24 | model.accepts_nested_attributes_for name, reject_if: :all_blank
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/test/dummy/db/migrate/20200523233221_create_human_tasks.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class CreateHumanTasks < ActiveRecord::Migration[6.0]
4 | def change
5 | create_table :flow_kit_human_tasks do |t|
6 | t.references :workflow, foreign_key: { to_table: :flow_core_workflows }, null: false
7 | t.references :instance, foreign_key: { to_table: :flow_core_instances }, null: false
8 |
9 | t.references :form_override, foreign_key: { to_table: :form_kit_form_overrides }
10 | t.references :attached_form, foreign_key: { to_table: :form_kit_forms }
11 |
12 | t.references :assignable, polymorphic: true, index: { name: "index_form_kit_human_tasks_assignable" }
13 | t.string :status, null: false
14 |
15 | t.datetime :assigned_at
16 | t.datetime :form_filled_at
17 | t.datetime :finished_at
18 |
19 | t.timestamps
20 | end
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/pipelines/branches_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pipelines::BranchesController < Pipelines::ApplicationController
4 | before_action :set_branch, only: %i[show edit update destroy]
5 |
6 | def show; end
7 |
8 | def edit; end
9 |
10 | def update
11 | if @branch.update(branch_params)
12 | redirect_to edit_pipeline_step_url(@pipeline, @branch.step), notice: "Branch was successfully updated."
13 | else
14 | render :edit
15 | end
16 | end
17 |
18 | def destroy
19 | @branch.destroy
20 |
21 | redirect_to edit_pipeline_step_url(@pipeline, @branch.step), notice: "Branch was successfully destroyed."
22 | end
23 |
24 | private
25 |
26 | def set_branch
27 | @branch = @pipeline.branches.find(params[:id])
28 | end
29 |
30 | def branch_params
31 | params.require(:branch).permit(:name)
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/test/dummy/db/migrate/20200205175443_add_columns_to_flow_core_tables.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AddColumnsToFlowCoreTables < ActiveRecord::Migration[6.0]
4 | def change
5 | change_table :flow_core_workflows do |t|
6 | t.references :form, foreign_key: { to_table: :form_kit_forms }
7 | end
8 |
9 | change_table :flow_core_pipelines do |t|
10 | t.references :form, foreign_key: { to_table: :form_kit_forms }
11 | end
12 |
13 | change_table :flow_core_transition_triggers do |t|
14 | t.references :attached_form, foreign_key: { to_table: :form_kit_forms }
15 | t.references :form_override, foreign_key: { to_table: :form_kit_form_overrides }
16 | end
17 |
18 | change_table :flow_core_instances do |t|
19 | t.references :creator, polymorphic: true
20 | t.references :form, foreign_key: { to_table: :form_kit_forms }
21 | end
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/pipelines/branches/steps_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pipelines::Branches::StepsController < Pipelines::Branches::ApplicationController
4 | def new
5 | @step = @branch.steps.new
6 | @step.append_to = params[:append_to]
7 | end
8 |
9 | def create
10 | @step = @branch.steps.new(step_params)
11 |
12 | if @step.save
13 | redirect_to pipeline_branch_url(@pipeline, @branch), notice: "Step was successfully created."
14 | else
15 | render :new
16 | end
17 | end
18 |
19 | def move
20 | step = @branch.steps.find(params[:step_id])
21 | if step && params[:position].present?
22 | index = params[:position].to_i
23 | step.insert_at(index)
24 | end
25 |
26 | head :no_content
27 | end
28 |
29 | private
30 |
31 | def step_params
32 | params.require(:step).permit(:name, :type, :append_to)
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/test/dummy/app/views/notifications/index.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Notifications
5 |
6 |
7 |
8 |
9 |
10 |
11 | Workflow
12 | Task
13 | Created at
14 |
15 |
16 |
17 |
18 | <% @notifications.each do |notification| %>
19 | <% task = notification.task %>
20 |
21 | <%= task.workflow.name %>
22 | <%= task.transition.name %>
23 | <%= time_tag task.created_at %>
24 |
25 | <%= link_to "Show", human_task_path(task.executable) %>
26 |
27 |
28 | <% end %>
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/workflows/instances_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Workflows::InstancesController < Workflows::ApplicationController
4 | def new
5 | if @workflow.type.blank?
6 | @instance = @workflow.create_instance!
7 | redirect_to instance_url(@instance), notice: "Instance created."
8 | return
9 | end
10 |
11 | unless current_user
12 | redirect_to users_url
13 | return
14 | end
15 |
16 | @instance = @workflow.build_instance
17 | end
18 |
19 | def create
20 | @instance = @workflow.build_instance instance_params
21 | @instance.creator = current_user
22 |
23 | if @instance.save
24 | redirect_to instance_url(@instance), notice: "Instance created."
25 | else
26 | render :new
27 | end
28 | end
29 |
30 | private
31 |
32 | def instance_params
33 | params.fetch(:instance, {}).permit(form_attributes: {})
34 | end
35 | end
36 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/virtual_model.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit
4 | class VirtualModel < FormCore::VirtualModel
5 | include SerializableModel::ActsAsDefaultValue
6 | include SerializableModel::EnumAttributeLocalizable
7 |
8 | def persisted?
9 | false
10 | end
11 |
12 | def dump
13 | self.class.dump(self)
14 | end
15 |
16 | class << self
17 | def reserved_attribute_names
18 | @reserved_attribute_names ||= Set.new(
19 | %i[def class module private public protected allocate new parent superclass] +
20 | instance_methods(true)
21 | )
22 | end
23 |
24 | def nested_models
25 | @nested_models ||= {}
26 | end
27 |
28 | def attr_readonly?(attr_name)
29 | readonly_attributes.include? attr_name.to_s
30 | end
31 |
32 | def metadata
33 | @metadata ||= {}
34 | end
35 | end
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/fields/_resource.html.erb:
--------------------------------------------------------------------------------
1 |
13 |
14 |
24 |
--------------------------------------------------------------------------------
/lib/flow_core/task_executable.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowCore
4 | module TaskExecutable
5 | extend ActiveSupport::Concern
6 |
7 | included do
8 | has_one :task, as: :executable, class_name: "FlowCore::Task", autosave: true, required: true
9 | has_one :transition, -> { readonly }, through: :task, class_name: "FlowCore::Transition"
10 |
11 | after_save :notify_workflow_task_finished!, if: :implicit_notify_workflow_task_finished
12 | end
13 |
14 | def finished?
15 | raise NotImplementedError
16 | end
17 |
18 | def on_flow_core_task_terminate(_task); end
19 |
20 | def on_flow_core_task_suspend(_task); end
21 |
22 | def on_flow_core_task_resume(_task); end
23 |
24 | private
25 |
26 | def implicit_notify_workflow_task_finished
27 | true
28 | end
29 |
30 | def notify_workflow_task_finished!
31 | task.finish! if finished?
32 | end
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields/multiple_nested_form.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class MultipleNestedForm < FormKit::Field
5 | after_create do
6 | build_nested_form.save!
7 | end
8 |
9 | serialize :validations, coder: Validations
10 | serialize :options, coder: FormKit::NonConfigurable
11 |
12 | def attached_nested_form?
13 | true
14 | end
15 |
16 | def array?
17 | true
18 | end
19 |
20 | protected
21 |
22 | def interpret_attribute_to(model, accessibility, _overrides = {})
23 | nested_model = nested_form.to_virtual_model(overrides: { _global: { accessibility: accessibility } })
24 | model.nested_models[key] = nested_model
25 |
26 | name = key.to_sym
27 | model.embeds_many name, anonymous_class: nested_model, validate: true
28 | model.accepts_nested_attributes_for name, reject_if: :all_blank
29 | end
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_flow_kit/arc_guards/_ruby_script.html.erb:
--------------------------------------------------------------------------------
1 | <%= f.fields_for :configuration, guard.configuration do |ff| %>
2 |
3 | <%= ff.label :name %>
4 | <%= ff.text_field :name, required: "required", class: "form-control", class_for_error: "is-invalid" %>
5 | <%= ff.error_message :name, class: "invalid-feedback" %>
6 |
7 |
8 |
9 | <%= ff.label :script %>
10 | <%= ff.text_area :script, rows: 10, class: "form-control", class_for_error: "is-invalid" %>
11 | <%= ff.error_message :script, class: "invalid-feedback" %>
12 |
13 | Ruby code here,
14 | you can use Input[:attached_form_attributes]["FORM_FIELD_KEY"] to get attached form field value,
15 | use Input[:form_attributes]["FORM_FIELD_KEY"] to get form field value.
16 | return value should be a bool.
17 |
18 |
19 | <% end %>
20 |
--------------------------------------------------------------------------------
/test/dummy/app/models/form_kit/fields.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | def self.all_types
5 | @all_types ||= [
6 | FormKit::Fields::Text,
7 | FormKit::Fields::Boolean,
8 | FormKit::Fields::Decimal,
9 | FormKit::Fields::Integer,
10 | FormKit::Fields::Date,
11 | FormKit::Fields::Datetime,
12 | FormKit::Fields::Choice,
13 | FormKit::Fields::MultipleChoice,
14 | FormKit::Fields::Select,
15 | FormKit::Fields::MultipleSelect,
16 | FormKit::Fields::IntegerRange,
17 | FormKit::Fields::DecimalRange,
18 | FormKit::Fields::DateRange,
19 | FormKit::Fields::DatetimeRange,
20 | FormKit::Fields::NestedForm,
21 | FormKit::Fields::MultipleNestedForm,
22 | # FormKit::Fields::ResourceSelect,
23 | # FormKit::Fields::MultipleResourceSelect,
24 | # FormKit::Fields::Resource,
25 | # FormKit::Fields::MultipleResource,
26 | ]
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/test/dummy/app/presenters/form_kit/fields/multiple_select_presenter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class MultipleSelectPresenter < FormKit::FieldPresenter
5 | MAX_HARD_CODE_ITEMS_SIZE = 20
6 |
7 | def include_blank?
8 | required?
9 | end
10 |
11 | def value_for_preview
12 | Array.wrap(value).join(", ")
13 | end
14 |
15 | def can_custom_value?
16 | !@model.options.strict_select
17 | end
18 |
19 | def collection
20 | collection = @model.choices.map(&:label)
21 | if can_custom_value? && value.present?
22 | (value + collection).uniq
23 | else
24 | collection
25 | end
26 | end
27 |
28 | def options_for_select
29 | @view.options_for_select(collection, value)
30 | end
31 |
32 | def max_items_size
33 | size = @model.validations.length.maximum
34 | size.positive? ? size : MAX_HARD_CODE_ITEMS_SIZE
35 | end
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2 | #
3 | # If you find yourself ignoring temporary files generated by your text editor
4 | # or operating system, you probably want to add a global ignore instead:
5 | # git config --global core.excludesfile '~/.gitignore_global'
6 |
7 | # Ignore bundler config.
8 | .bundle/
9 |
10 | # Ignore the default SQLite database.
11 | test/dummy/db/*.sqlite3
12 | test/dummy/db/*.sqlite3-journal
13 |
14 | # Ignore all logfiles and tempfiles.
15 | log/*.log
16 | !test/dummy/log/.keep
17 | !test/dummy/tmp/.keep
18 | test/dummy/log/*.log
19 | test/dummy/tmp/
20 |
21 | # Ignore uploaded files in development
22 | test/dummy/storage/*
23 | !test/dummy/storage/.keep
24 |
25 | pkg/
26 | .byebug_history
27 |
28 | node_modules/
29 | test/dummy/public/packs
30 | test/dummy/node_modules/
31 | yarn-error.log
32 |
33 | *.gem
34 |
35 | .generators
36 | .rakeTasks
37 |
38 | .env
39 |
40 | test/dummy/mruby/bin/
41 |
--------------------------------------------------------------------------------
/lib/flow_core/definition/guard.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowCore::Definition
4 | class Guard
5 | def initialize(attributes)
6 | constant_or_klass = attributes.is_a?(Hash) ? attributes.delete(:type) : attributes
7 | @klass =
8 | if constant_or_klass.is_a? String
9 | constant_or_klass.safe_constantize
10 | else
11 | constant_or_klass
12 | end
13 | unless @klass && @klass < FlowCore::ArcGuard
14 | raise TypeError, "First argument expect `FlowCore::TransitionTrigger` subclass or its constant name - #{constant_or_klass}"
15 | end
16 |
17 | @configuration = attributes.is_a?(Hash) ? attributes : nil
18 | end
19 |
20 | def compile
21 | if @configuration&.any?
22 | {
23 | type: @klass.to_s,
24 | configuration: @configuration
25 | }
26 | else
27 | {
28 | type: @klass.to_s
29 | }
30 | end
31 | end
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/test/dummy/app/views/forms/overrides/index.html.erb:
--------------------------------------------------------------------------------
1 | <% content_for :actions do %>
2 | <%= link_to "New override", new_form_override_path(@form), class: "btn btn-primary mr-2" %>
3 | <%= link_to "Back", forms_path, class: "btn btn-primary" %>
4 | <% end %>
5 |
6 |
7 | <%= render "forms/tabs" %>
8 |
9 |
10 |
11 |
12 |
13 |
14 | Name
15 | Type
16 |
17 |
18 |
19 |
20 | <% @overrides.each do |override| %>
21 |
22 | <%= override.name %>
23 |
24 | <%= link_to "Edit", edit_form_override_path(@form, override) %> |
25 | <%= link_to "Destroy", form_override_path(@form, override), method: :delete, data: { confirm: "Are you sure?" } %>
26 |
27 |
28 | <% end %>
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/lib/flow_core/locale/en.yml:
--------------------------------------------------------------------------------
1 | en:
2 | activerecord:
3 | models:
4 | flow_core/workflow: Workflow
5 | flow_core/place: Place
6 | flow_core/start_place: Start Place
7 | flow_core/end_place: End Place
8 | flow_core/transition: Transition
9 | # flow_core/transition_trigger: Transition Trigger
10 | flow_core/arc: Arc
11 | # flow_core/arc_guard: Arc Guard
12 | flow_core/instance: Instance
13 | flow_core/token: Token
14 | flow_core/task: Task
15 | flow_core:
16 | verify_status:
17 | unverify: Unverify
18 | verified: Verified
19 | invalid: Invalid
20 | violations:
21 | no_start_place: "No start place"
22 | no_end_place: "No end place"
23 | format: "%{model} %{name} %{message}"
24 | unreachable: "Unreachable from start place"
25 | impassable: "Impassable to end place"
26 | pipeline:
27 | synchronization_transition_name: "Synchronization"
28 | fallback_branch_name: "Default branch"
29 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/preview/_nested_form.html.erb:
--------------------------------------------------------------------------------
1 | <% fields = form.fields.map { |field| present(field, target: instance) }.reject(&:access_hidden?) %>
2 | <% return if fields.empty? %>
3 |
4 |
5 | <% fields.each do |field| %>
6 | <% if field.nested_form_field? %>
7 | <% next unless field.value_for_preview %>
8 |
9 |
<%= field.key %>:
10 | <%= render "_form_core/preview/nested_form", form: field.nested_form, instance: field.value_for_preview %>
11 | <% elsif field.multiple_nested_form? %>
12 | <% next if field.value_for_preview.empty? %>
13 |
14 |
<%= field.key %>:
15 | <%= field.value_for_preview.map do |nested_instance| %>
16 | <% render "_form_core/preview/nested_form", form: field.nested_form, instance: nested_instance %>
17 | <% end.join("
").html_safe %>
18 | <% else %>
19 |
<%= field.key %>: <%= field.value_for_preview %>
20 | <% end %>
21 | <% end %>
22 |
23 |
--------------------------------------------------------------------------------
/test/dummy/app/views/workflows/transitions/triggers/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | New trigger
5 |
6 |
7 | <%= link_to 'Back', workflow_transition_path(@workflow, @transition), class: "btn btn-primary" %>
8 |
9 |
10 |
11 | <% if @trigger %>
12 | <%= render "form", workflow: @workflow, transition: @transition, trigger: @trigger %>
13 | <% else %>
14 | <%= form_with url: new_workflow_transition_trigger_path(@workflow, @transition), method: :get, local: true do |f| %>
15 |
16 | <%= f.label :type %>
17 | <%= f.select :type, trigger_types_options_for_select, {}, class: "form-control" %>
18 |
19 |
20 | <%= f.submit "Next", class: "btn btn-block btn-primary" %>
21 | <% end %>
22 | <% end %>
23 |
24 |
--------------------------------------------------------------------------------
/lib/flow_core/definition/trigger.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowCore::Definition
4 | class Trigger
5 | def initialize(attributes)
6 | constant_or_klass = attributes.is_a?(Hash) ? attributes.delete(:type) : attributes
7 | @klass =
8 | if constant_or_klass.is_a? String
9 | constant_or_klass.safe_constantize
10 | else
11 | constant_or_klass
12 | end
13 | unless @klass && @klass < FlowCore::TransitionTrigger
14 | raise TypeError, "First argument expect `FlowCore::TransitionTrigger` subclass or its constant name - #{constant_or_klass}"
15 | end
16 |
17 | @configuration = attributes.is_a?(Hash) ? attributes : nil
18 | end
19 |
20 | def compile
21 | if @configuration&.any?
22 | {
23 | type: @klass.to_s,
24 | configuration: @configuration
25 | }
26 | else
27 | {
28 | type: @klass.to_s
29 | }
30 | end
31 | end
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/test/dummy/app/models/concerns/form_kit/options/data_source.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Options
4 | module DataSource
5 | extend ActiveSupport::Concern
6 |
7 | included do
8 | attribute :data_source_type, :string, default: FormKit::DataSources::Empty.to_s
9 |
10 | FormKit::DataSource.descendants.each do |klass|
11 | key = :"#{klass.type_key}_data_source"
12 | embeds_one key, class_name: klass.to_s
13 | accepts_nested_attributes_for key
14 | end
15 |
16 | validates :data_source_type,
17 | inclusion: { in: ->(_) { FormKit::DataSource.descendants.map(&:to_s) } },
18 | allow_blank: false
19 | end
20 |
21 | def data_source
22 | send(:"#{data_source_class.type_key}_data_source") || send(:"build_#{data_source_class.type_key}_data_source")
23 | end
24 |
25 | def data_source_class
26 | data_source_type.safe_constantize || FormKit::DataSources::Empty
27 | end
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/_form.html.erb:
--------------------------------------------------------------------------------
1 | <% url = pipeline.new_record? ? pipelines_path : pipeline_path(pipeline) %>
2 | <%= form_with(model: pipeline, scope: :pipeline, url: url, local: true) do |f| %>
3 |
4 | <%= f.label :name %>
5 | <%= f.text_field :name, autofocus: true, required: "required", class: "form-control", class_for_error: "is-invalid" %>
6 | <%= f.error_message :name, class: "invalid-feedback" %>
7 |
8 |
9 |
10 | <%= f.label :form_id %>
11 | <%= f.select :form_id, forms_options_for_select(selected: pipeline.form_id), { class_for_error: "is-invalid" }, disabled: pipeline.persisted?, class: "form-control" %>
12 | <%= f.error_message :form_id, class: "invalid-feedback" %>
13 |
14 | <%= link_to "Create a new form", new_form_path %>
15 |
16 |
17 |
18 |
19 | <%= f.submit class: "btn btn-primary" %>
20 |
21 | <% end %>
22 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/validations/_length.html.erb:
--------------------------------------------------------------------------------
1 | <% validations.build_length unless validations.length %>
2 | <% length = validations.length %>
3 |
4 | Length
5 |
6 | <%= f.fields_for :length, length do |ff| %>
7 |
8 | <%= ff.label :minimum %>
9 | <%= ff.number_field :minimum, min: 0, step: 1, class: "form-control", class_for_error: "is-invalid" %>
10 | <%= ff.error_message :minimum, class: "invalid-feedback" %>
11 |
12 |
13 |
14 | <%= ff.label :maximum %>
15 | <%= ff.number_field :maximum, min: 0, step: 1, class: "form-control", class_for_error: "is-invalid" %>
16 | <%= ff.error_message :maximum, class: "invalid-feedback" %>
17 |
18 |
19 |
20 | <%= ff.label :is %>
21 | <%= ff.number_field :is, min: 0, step: 1, class: "form-control", class_for_error: "is-invalid" %>
22 | <%= ff.error_message :is, class: "invalid-feedback" %>
23 |
24 | <% end %>
25 |
26 |
27 |
--------------------------------------------------------------------------------
/test/dummy/app/presenters/concerns/form_kit/fields/presenter_for_number_field.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | module PresenterForNumberField
5 | extend ActiveSupport::Concern
6 |
7 | def min
8 | return if @model.validations.numericality.lower_bound_check_disabled?
9 |
10 | min = @model.validations.numericality.lower_bound_value
11 | integer_only? ? min.to_i : min
12 | end
13 |
14 | def max
15 | return if @model.validations.numericality.upper_bound_check_disabled?
16 |
17 | max = @model.validations.numericality.upper_bound_value
18 | integer_only? ? max.to_i : max
19 | end
20 |
21 | def step
22 | step = @model.options.step
23 | return if step.zero?
24 |
25 | integer_only? ? step.to_i : step
26 | end
27 |
28 | def integer_only?
29 | false
30 | end
31 |
32 | def to_builder_options
33 | { min: min, max: max, step: step, required: required? }.reject { |_, v| v.blank? }
34 | end
35 | end
36 | end
37 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/fields/data_source_options_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Fields::DataSourceOptionsController < Fields::ApplicationController
4 | before_action :require_data_source_options
5 | before_action :set_options
6 | before_action :set_page_layout
7 |
8 | def edit; end
9 |
10 | def update
11 | @options.assign_attributes(options_params)
12 | if @options.valid? && @field.save(validate: false)
13 | redirect_to fields_url, notice: "Field was successfully updated."
14 | else
15 | render :edit
16 | end
17 | end
18 |
19 | private
20 |
21 | def require_data_source_options
22 | unless @field.respond_to?(:data_source)
23 | redirect_to fields_url
24 | end
25 | end
26 |
27 | def set_options
28 | @options = @field.data_source
29 | end
30 |
31 | def set_page_layout
32 | @_breadcrumbs << { text: "Data source" }
33 | end
34 |
35 | def options_params
36 | params.fetch(:options, {}).permit!
37 | end
38 | end
39 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/steps/_form.html.erb:
--------------------------------------------------------------------------------
1 | <% url = step.new_record? ? pipeline_steps_path(pipeline) : pipeline_step_path(pipeline, step) %>
2 | <%= form_with(model: step, scope: :step, url: url, local: true) do |f| %>
3 | <%= f.hidden_field :append_to if step.new_record? %>
4 |
5 |
6 | <%= f.label :name %>
7 | <%= f.text_field :name, autofocus: true, required: "required", class: "form-control", class_for_error: "is-invalid" %>
8 | <%= f.error_message :name, class: "invalid-feedback" %>
9 |
10 |
11 |
12 | <%= f.label :type %>
13 | <%= f.select :type, options_for_select(FlowKit::Steps.all_types.map { |klass| [klass.model_name.human, klass.to_s] }, step.type), {}, required: "required", disabled: step.persisted?, class: "form-control", class_for_error: "is-invalid" %>
14 | <%= f.error_message :type, class: "invalid-feedback" %>
15 |
16 |
17 |
18 | <%= f.submit class: "btn btn-primary" %>
19 |
20 | <% end %>
21 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/branches/steps/_form.html.erb:
--------------------------------------------------------------------------------
1 | <% url = step.new_record? ? pipeline_branch_steps_path(pipeline, branch) : pipeline_branch_step_path(pipeline, branch, step) %>
2 | <%= form_with(model: step, scope: :step, url: url, local: true) do |f| %>
3 | <%= f.hidden_field :append_to if step.new_record? %>
4 |
5 |
6 | <%= f.label :name %>
7 | <%= f.text_field :name, autofocus: true, required: "required", class: "form-control", class_for_error: "is-invalid" %>
8 | <%= f.error_message :name, class: "invalid-feedback" %>
9 |
10 |
11 |
12 | <%= f.label :type %>
13 | <%= f.select :type, options_for_select(FlowKit::Steps.all_types.map { |klass| [klass.model_name.human, klass.to_s] }, step.type), {}, required: "required", class: "form-control", class_for_error: "is-invalid" %>
14 | <%= f.error_message :type, class: "invalid-feedback" %>
15 |
16 |
17 |
18 | <%= f.submit class: "btn btn-primary" %>
19 |
20 | <% end %>
21 |
--------------------------------------------------------------------------------
/app/models/flow_core/steps/redirection.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FlowCore::Steps
4 | class Redirection < FlowCore::Step
5 | def deploy_to_workflow!(workflow, input_place_or_transition)
6 | target_transition = workflow.transitions.find_by! generated_by_step_id: redirect_to_step_id
7 | target_place = target_transition.input_places.first
8 |
9 | if input_place_or_transition.is_a? FlowCore::Transition
10 | target_place.input_transitions << input_place_or_transition
11 | else
12 | input_place_or_transition.input_arcs.update place: target_place
13 | input_place_or_transition.reload.destroy!
14 | end
15 |
16 | nil
17 | end
18 |
19 | def verify?
20 | super && redirect_to_step_id.present?
21 | end
22 |
23 | class << self
24 | def creatable?
25 | true
26 | end
27 |
28 | def redirection_step?
29 | true
30 | end
31 |
32 | def redirection_configurable?
33 | true
34 | end
35 | end
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/test/dummy/app/views/layouts/application.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Dummy
5 |
6 | <%= csrf_meta_tags %>
7 | <%= csp_meta_tag %>
8 |
9 |
10 |
11 |
12 | <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track": "reload" %>
13 | <%= javascript_include_tag "application", "data-turbolinks-track": "reload" %>
14 |
15 |
16 |
17 | <%= render "layouts/header" %>
18 | <%= yield(:custom_header) if content_for?(:custom_header) %>
19 | <%= render_breadcrumbs %>
20 | <%= render "layouts/alert" %>
21 |
22 | <%= content_for?(:content) ? yield(:content) : yield %>
23 |
24 | <%= render "layouts/footer" %>
25 |
26 |
27 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/fields/_select.html.erb:
--------------------------------------------------------------------------------
1 |
13 |
14 |
28 |
--------------------------------------------------------------------------------
/test/dummy/app/helpers/workflows_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module WorkflowsHelper
4 | def forms_options_for_select(selected: nil)
5 | forms = FormKit::Form.all
6 | options_from_collection_for_select(forms, :id, :name, selected)
7 | end
8 |
9 | def form_overrides_for_select(form, selected: nil)
10 | options_from_collection_for_select(form.overrides, :id, :name, selected)
11 | end
12 |
13 | def trigger_types_options_for_select(selected: nil)
14 | types = FlowKit::TransitionTriggers.all_types
15 | options_for_select(types.map { |klass| [klass.model_name.human, klass.to_s] }, selected)
16 | end
17 |
18 | def guard_types_options_for_select(selected: nil)
19 | types = FlowKit::ArcGuards.all_types
20 | options_for_select(types.map { |klass| [klass.model_name.human, klass.to_s] }, selected)
21 | end
22 |
23 | def redirectable_steps_options_for_select(current_step)
24 | options_from_collection_for_select(current_step.redirectable_steps.sort_by(&:depth), :id, :name, current_step.redirect_to_step_id)
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/test/dummy/app/presenters/form_kit/fields/resource_presenter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FormKit::Fields
4 | class ResourcePresenter < FormKit::FieldPresenter
5 | def value_for_preview
6 | return unless @model.collection
7 |
8 | id = value
9 | return if id.blank?
10 |
11 | collection
12 | .where(@model.data_source.value_method => id)
13 | .first
14 | &.send(@model.data_source.text_method)
15 | end
16 |
17 | def include_blank?
18 | required?
19 | end
20 |
21 | def collection
22 | return unless @model.collection
23 | return if @model.collection.none?
24 |
25 | # TODO: limit 100 for performance
26 | @model.collection.limit(100)
27 | end
28 |
29 | def options_for_select
30 | unless collection
31 | return @view.options_for_select([])
32 | end
33 |
34 | @view.options_from_collection_for_select(
35 | collection, @model.data_source.value_method, @model.data_source.text_method, value
36 | )
37 | end
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/test/dummy/app/views/forms/_tabs.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= nav_link_to({ controller: 'forms/fields', action: :index }, "Fields", form_fields_path(@form), class: "nav-link") %>
5 |
6 |
7 | <%= nav_link_to({ controller: 'forms/overrides', action: :index }, "Overrides", form_overrides_path(@form), class: "nav-link") %>
8 |
9 | <% unless @form.attachable_id.present? %>
10 |
11 | <%= nav_link_to({controller: 'forms', action: :edit}, "Edit", edit_form_path(@form), class: "nav-link") %>
12 |
13 |
14 | <%= nav_link_to({controller: 'forms/previews'}, "Preview", form_preview_path(@form), class: "nav-link") %>
15 |
16 | <% end %>
17 |
18 |
19 |
20 | <%= yield :actions if content_for?(:actions) %>
21 |
22 |
23 |
--------------------------------------------------------------------------------
/test/dummy/app/views/layouts/_breadcrumb.html.erb:
--------------------------------------------------------------------------------
1 |
30 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/branches/arc_guards/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | New trigger
5 |
6 |
7 | <%= link_to "<<", pipeline_path(@pipeline), class: "btn btn-primary mr-2" %>
8 | <%= link_to "Back", edit_pipeline_branch_path(@pipeline, @branch), class: "btn btn-primary" %>
9 |
10 |
11 |
12 | <% if @arc_guard %>
13 | <%= render "form", pipeline: @pipeline, branch: @branch, arc_guard: @arc_guard %>
14 | <% else %>
15 | <%= form_with url: new_pipeline_branch_arc_guard_path(@pipeline, @branch), method: :get, local: true do |f| %>
16 |
17 | <%= f.label :type %>
18 | <%= f.select :type, guard_types_options_for_select, {}, class: "form-control" %>
19 |
20 |
21 | <%= f.submit "Next", class: "btn btn-block btn-primary" %>
22 | <% end %>
23 | <% end %>
24 |
25 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/fields/_resource_select.html.erb:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
29 |
--------------------------------------------------------------------------------
/test/dummy/app/views/_form_core/fields/_multiple_resource.html.erb:
--------------------------------------------------------------------------------
1 |
13 |
14 |
28 |
--------------------------------------------------------------------------------
/test/dummy/app/views/pipelines/steps/transition_triggers/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | New trigger
5 |
6 |
7 | <%= link_to "<<", pipeline_path(@pipeline), class: "btn btn-primary mr-2" %>
8 | <%= link_to 'Back', edit_pipeline_step_path(@pipeline, @step), class: "btn btn-primary" %>
9 |
10 |
11 |
12 | <% if @transition_trigger %>
13 | <%= render "form", pipeline: @pipeline, step: @step, transition_trigger: @transition_trigger %>
14 | <% else %>
15 | <%= form_with url: new_pipeline_step_transition_trigger_path(@pipeline, @step), method: :get, local: true do |f| %>
16 |
17 | <%= f.label :type %>
18 | <%= f.select :type, trigger_types_options_for_select, {}, class: "form-control" %>
19 |
20 |
21 | <%= f.submit "Next", class: "btn btn-block btn-primary" %>
22 | <% end %>
23 | <% end %>
24 |
25 |
--------------------------------------------------------------------------------
/MIT-LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 jasl
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/test/dummy/app/views/users/index.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Mocking Users
5 |
6 |
7 | <%= link_to 'New user', new_user_path, class: "btn btn-primary" %>
8 |
9 |
10 |
11 |
12 |
13 |
14 | Id
15 | Name
16 |
17 |
18 |
19 |
20 | <% @users.each do |user| %>
21 |
22 | <%= user.id %>
23 | <%= user.name %>
24 |
25 | <% if current_user != user %>
26 | <%= link_to 'Sign in', sign_in_as_path(user.id) %> |
27 | <% end %>
28 | <%= link_to 'Edit', edit_user_path(user) %> |
29 | <%= link_to 'Destroy', user, method: :delete, data: {confirm: 'Are you sure?'} %>
30 |
31 |
32 | <% end %>
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/test/dummy/app/views/kaminari/_paginator.html.erb:
--------------------------------------------------------------------------------
1 | <%# The container tag
2 | - available local variables
3 | current_page: a page object for the currently displayed page
4 | num_pages: total number of pages
5 | per_page: number of items to fetch per page
6 | remote: data-remote
7 | paginator: the paginator that renders the pagination tags inside
8 | -%>
9 | <%- wrapper_class ||= "" %>
10 | <%- pagination_class ||= "" %>
11 | <%= paginator.render do -%>
12 |
13 |
26 |
27 | <% end -%>
28 |
--------------------------------------------------------------------------------
/test/dummy/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require 'fileutils'
3 |
4 | # path to your application root.
5 | APP_ROOT = File.expand_path('..', __dir__)
6 |
7 | def system!(*args)
8 | system(*args) || abort("\n== Command #{args} failed ==")
9 | end
10 |
11 | FileUtils.chdir APP_ROOT do
12 | # This script is a way to setup or update your development environment automatically.
13 | # This script is idempotent, so that you can run it at anytime and get an expectable outcome.
14 | # Add necessary setup steps to this file.
15 |
16 | puts '== Installing dependencies =='
17 | system! 'gem install bundler --conservative'
18 | system('bundle check') || system!('bundle install')
19 |
20 | # puts "\n== Copying sample files =="
21 | # unless File.exist?('config/database.yml')
22 | # FileUtils.cp 'config/database.yml.sample', 'config/database.yml'
23 | # end
24 |
25 | puts "\n== Preparing database =="
26 | system! 'bin/rails db:prepare'
27 |
28 | puts "\n== Removing old logs and tempfiles =="
29 | system! 'bin/rails log:clear tmp:clear'
30 |
31 | puts "\n== Restarting application server =="
32 | system! 'bin/rails restart'
33 | end
34 |
--------------------------------------------------------------------------------
/test/dummy/app/helpers/fields_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module FieldsHelper
4 | def options_for_field_types(form, selected: nil)
5 | fields = FormKit::Fields.all_types
6 | if form.attachable_id.present?
7 | fields -= [FormKit::Fields::NestedForm, FormKit::Fields::MultipleNestedForm]
8 | end
9 |
10 | options_for_select(fields.map { |klass| [klass.model_name.human, klass.to_s] }, selected)
11 | end
12 |
13 | def options_for_data_source_types(selected: nil)
14 | options_for_select(FormKit::DataSource.descendants.map { |klass| [klass.model_name.human, klass.to_s] }, selected)
15 | end
16 |
17 | def field_label(form, field_name:)
18 | field_name = field_name.to_s.split(".").first.to_sym
19 |
20 | form.fields.find do |field|
21 | field.name == field_name
22 | end&.label
23 | end
24 |
25 | def fields_path(field)
26 | form = field.form
27 |
28 | case form
29 | when FormKit::Form
30 | form_fields_path(form)
31 | when FormKit::NestedForm
32 | nested_form_fields_path(form)
33 | else
34 | raise "Unknown form: #{form.class}"
35 | end
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/flow_core.gemspec:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | $LOAD_PATH.push File.expand_path("lib", __dir__)
4 |
5 | # Maintain your gem's version:
6 | require "flow_core/version"
7 |
8 | # Describe your gem and declare its dependencies:
9 | Gem::Specification.new do |spec|
10 | spec.name = "flow_core"
11 | spec.version = FlowCore::VERSION
12 | spec.authors = ["jasl"]
13 | spec.email = ["jasl9187@hotmail.com"]
14 | spec.homepage = "https://github.com/rails-engine/flow_core"
15 | spec.summary = "FlowCore is a Rails engine to help you build your automation or business process application."
16 | spec.description = "A multi purpose, extendable, Workflow-net-based workflow engine for Rails applications, focusing on workflow definition and scheduling."
17 | spec.license = "MIT"
18 |
19 | spec.required_ruby_version = ">= 2.5.0"
20 |
21 | spec.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"]
22 |
23 | spec.add_dependency "acts_as_list", "~> 1.2.2"
24 | spec.add_dependency "ancestry", "~> 4.3.3"
25 | spec.add_dependency "rails", "~> 7.2.1"
26 | spec.add_dependency "rgl", "~> 0.6.6"
27 | end
28 |
--------------------------------------------------------------------------------
/test/dummy/app/overrides/models/flow_core/steps/end_override.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | FlowCore::Steps::End.class_eval do
4 | def graphviz_name
5 | "pipeline_#{pipeline_id}_step_#{id}"
6 | end
7 |
8 | def graphviz_node(graph, interactive: false)
9 | if graph.nodes[graphviz_name]
10 | return graph.nodes[graphviz_name]
11 | end
12 |
13 | attrs = {
14 | style: :filled, fillcolor: :white
15 | }
16 | attrs[:shape] = multi_branch_step? ? :diamond : :box
17 | attrs[:label] = multi_branch_step? ? "#{name}_START" : name
18 | if interactive
19 | attrs[:href] = Rails.application.routes.url_helpers.edit_pipeline_step_path(pipeline, self)
20 | end
21 |
22 | Graphviz::Node.new graphviz_name, graph, **attrs
23 | end
24 |
25 | def append_to_graphviz(graph)
26 | node = graphviz_node(graph)
27 |
28 | node.connect pipeline.end_graphviz_node(graph)
29 |
30 | [node, nil]
31 | end
32 |
33 | def append_to_designer_graphviz(graph)
34 | node = graphviz_node(graph, interactive: true)
35 |
36 | node.connect pipeline.end_graphviz_node(graph)
37 |
38 | [node, nil]
39 | end
40 | end
41 |
--------------------------------------------------------------------------------