open-loam 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +48 -8
- data/LICENSE +1 -1
- data/README.md +24 -24
- data/app/jobs/{loam → open_loam}/custom_field_reindex_job.rb +6 -6
- data/app/jobs/{loam → open_loam}/event_delivery_job.rb +8 -8
- data/app/jobs/{loam → open_loam}/event_redelivery_sweep_job.rb +4 -4
- data/app/jobs/{loam → open_loam}/webhook_delivery_job.rb +7 -7
- data/app/models/{loam → open_loam}/api_token.rb +7 -7
- data/app/models/{loam → open_loam}/audit_record.rb +3 -3
- data/app/models/{loam → open_loam}/auth_attempt.rb +5 -5
- data/app/models/{loam → open_loam}/business_rule.rb +10 -10
- data/app/models/{loam → open_loam}/business_rule_run.rb +5 -5
- data/app/models/{loam → open_loam}/comment.rb +9 -9
- data/app/models/{loam → open_loam}/config.rb +7 -7
- data/app/models/{loam → open_loam}/custom_field_value.rb +5 -5
- data/app/models/{loam → open_loam}/dashboard_widget.rb +5 -5
- data/app/models/open_loam/dictionary.rb +20 -0
- data/app/models/{loam → open_loam}/dictionary_entry.rb +7 -7
- data/app/models/{loam → open_loam}/event_delivery.rb +4 -4
- data/app/models/{loam → open_loam}/field_definition.rb +8 -8
- data/app/models/{loam → open_loam}/inbound_webhook_delivery.rb +4 -4
- data/app/models/{loam → open_loam}/inbound_webhook_source.rb +13 -13
- data/app/models/{loam → open_loam}/membership.rb +6 -6
- data/app/models/{loam → open_loam}/mfa_credential.rb +8 -8
- data/app/models/{loam → open_loam}/notification.rb +10 -10
- data/app/models/{loam → open_loam}/pending_action.rb +23 -23
- data/app/models/{loam → open_loam}/perspective.rb +5 -5
- data/app/models/{loam → open_loam}/progress_job.rb +7 -7
- data/app/models/{loam → open_loam}/record_lock.rb +5 -5
- data/app/models/{loam → open_loam}/scheduled_job.rb +7 -7
- data/app/models/open_loam/search_token.rb +9 -0
- data/app/models/{loam → open_loam}/sso_identity.rb +4 -4
- data/app/models/{loam → open_loam}/sso_provider.rb +8 -8
- data/app/models/open_loam/tenant.rb +20 -0
- data/app/models/{loam → open_loam}/translation.rb +5 -5
- data/app/models/{loam → open_loam}/webhook_endpoint.rb +6 -6
- data/app/views/{loam → open_loam}/attachments/_attachments.html.erb +1 -1
- data/app/views/{loam → open_loam}/comments/_comments.html.erb +1 -1
- data/app/views/{loam → open_loam}/custom_fields/_fields.html.erb +2 -2
- data/lib/generators/{loam → open_loam}/entity/entity_generator.rb +9 -9
- data/lib/generators/{loam → open_loam}/entity/templates/api_controller.rb +1 -1
- data/lib/generators/{loam → open_loam}/entity/templates/controller.rb +21 -21
- data/lib/generators/{loam → open_loam}/entity/templates/entity_test.rb +12 -12
- data/lib/generators/{loam → open_loam}/entity/templates/migration.rb +5 -5
- data/lib/generators/{loam → open_loam}/entity/templates/model.rb +10 -10
- data/lib/generators/{loam → open_loam}/entity/templates/policy.rb +1 -1
- data/lib/generators/{loam → open_loam}/entity/templates/views/_form.html.erb +4 -4
- data/lib/generators/{loam → open_loam}/entity/templates/views/deleted.html.erb +7 -7
- data/lib/generators/open_loam/entity/templates/views/edit.html.erb +3 -0
- data/lib/generators/open_loam/entity/templates/views/index.html.erb +90 -0
- data/lib/generators/open_loam/entity/templates/views/new.html.erb +3 -0
- data/lib/generators/open_loam/entity/templates/views/show.html.erb +36 -0
- data/lib/generators/{loam → open_loam}/install/install_generator.rb +47 -47
- data/lib/generators/open_loam/install/templates/AGENTS.md +341 -0
- data/lib/generators/{loam → open_loam}/install/templates/admin/api_docs_controller.rb +2 -2
- data/lib/generators/{loam → open_loam}/install/templates/admin/api_docs_index.html.erb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/api_tokens_controller.rb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/base_controller.rb +38 -38
- data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_controller.rb +7 -7
- data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_form.html.erb +2 -2
- data/lib/generators/{loam → open_loam}/install/templates/admin/comments_controller.rb +4 -4
- data/lib/generators/{loam → open_loam}/install/templates/admin/configs_controller.rb +9 -9
- data/lib/generators/open_loam/install/templates/admin/dashboard_controller.rb +10 -0
- data/lib/generators/{loam → open_loam}/install/templates/admin/dashboard_widgets_controller.rb +5 -5
- data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_controller.rb +5 -5
- data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_form.html.erb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/dictionary_entries_controller.rb +2 -2
- data/lib/generators/{loam → open_loam}/install/templates/admin/event_deliveries_controller.rb +5 -5
- data/lib/generators/{loam → open_loam}/install/templates/admin/event_deliveries_index.html.erb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/events_controller.rb +5 -5
- data/lib/generators/{loam → open_loam}/install/templates/admin/features_controller.rb +9 -9
- data/lib/generators/{loam → open_loam}/install/templates/admin/field_definitions_controller.rb +5 -5
- data/lib/generators/{loam → open_loam}/install/templates/admin/field_definitions_new.html.erb +2 -2
- data/lib/generators/{loam → open_loam}/install/templates/admin/history_controller.rb +7 -7
- data/lib/generators/{loam → open_loam}/install/templates/admin/history_index.html.erb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/imports_controller.rb +12 -12
- data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_controller.rb +6 -6
- data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_new.html.erb +2 -2
- data/lib/generators/open_loam/install/templates/admin/layout.html.erb +76 -0
- data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_controller.rb +6 -6
- data/lib/generators/{loam → open_loam}/install/templates/admin/notifications_controller.rb +3 -3
- data/lib/generators/{loam → open_loam}/install/templates/admin/overrides_controller.rb +3 -3
- data/lib/generators/{loam → open_loam}/install/templates/admin/overrides_index.html.erb +2 -2
- data/lib/generators/{loam → open_loam}/install/templates/admin/pending_actions_controller.rb +3 -3
- data/lib/generators/{loam → open_loam}/install/templates/admin/perspectives_controller.rb +7 -7
- data/lib/generators/{loam → open_loam}/install/templates/admin/perspectives_index.html.erb +1 -1
- data/lib/generators/open_loam/install/templates/admin/progress_jobs_controller.rb +19 -0
- data/lib/generators/{loam → open_loam}/install/templates/admin/progress_jobs_index.html.erb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/record_locks_controller.rb +4 -4
- data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_controller.rb +7 -7
- data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_form.html.erb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_index.html.erb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/search_controller.rb +5 -5
- data/lib/generators/{loam → open_loam}/install/templates/admin/sessions_controller.rb +32 -32
- data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_controller.rb +6 -6
- data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_form.html.erb +2 -2
- data/lib/generators/{loam → open_loam}/install/templates/admin/sudo_controller.rb +5 -5
- data/lib/generators/{loam → open_loam}/install/templates/admin/sudo_new.html.erb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/translations_controller.rb +7 -7
- data/lib/generators/{loam → open_loam}/install/templates/admin/translations_index.html.erb +3 -3
- data/lib/generators/{loam → open_loam}/install/templates/admin/webhook_endpoints_controller.rb +4 -4
- data/lib/generators/{loam → open_loam}/install/templates/admin/webhook_endpoints_index.html.erb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin.css +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/api_base_controller.rb +15 -15
- data/lib/generators/{loam → open_loam}/install/templates/guardrails_test.rb +17 -17
- data/lib/generators/{loam → open_loam}/install/templates/import_job.rb +7 -7
- data/lib/generators/{loam → open_loam}/install/templates/inbound_webhooks_controller.rb +4 -4
- data/lib/generators/{loam → open_loam}/install/templates/initializer.rb +74 -74
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_api_tokens.rb +15 -0
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_audit_records.rb +14 -0
- data/lib/generators/{loam/install/templates/migrations/create_loam_auth_attempts.rb → open_loam/install/templates/migrations/create_open_loam_auth_attempts.rb} +3 -3
- data/lib/generators/{loam/install/templates/migrations/create_loam_business_rules.rb → open_loam/install/templates/migrations/create_open_loam_business_rules.rb} +10 -10
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_comments.rb +13 -0
- data/lib/generators/{loam/install/templates/migrations/create_loam_configs.rb → open_loam/install/templates/migrations/create_open_loam_configs.rb} +7 -7
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_custom_field_values.rb +19 -0
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_dashboard_widgets.rb +12 -0
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_dictionaries.rb +11 -0
- data/lib/generators/{loam/install/templates/migrations/create_loam_dictionary_entries.rb → open_loam/install/templates/migrations/create_open_loam_dictionary_entries.rb} +6 -6
- data/lib/generators/{loam/install/templates/migrations/create_loam_event_deliveries.rb → open_loam/install/templates/migrations/create_open_loam_event_deliveries.rb} +5 -5
- data/lib/generators/{loam/install/templates/migrations/create_loam_field_definitions.rb → open_loam/install/templates/migrations/create_open_loam_field_definitions.rb} +4 -4
- data/lib/generators/{loam/install/templates/migrations/create_loam_inbound_webhooks.rb → open_loam/install/templates/migrations/create_open_loam_inbound_webhooks.rb} +9 -9
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_memberships.rb +11 -0
- data/lib/generators/{loam/install/templates/migrations/create_loam_mfa_credentials.rb → open_loam/install/templates/migrations/create_open_loam_mfa_credentials.rb} +4 -4
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_notifications.rb +15 -0
- data/lib/generators/{loam/install/templates/migrations/create_loam_pending_actions.rb → open_loam/install/templates/migrations/create_open_loam_pending_actions.rb} +9 -9
- data/lib/generators/{loam/install/templates/migrations/create_loam_perspectives.rb → open_loam/install/templates/migrations/create_open_loam_perspectives.rb} +5 -5
- data/lib/generators/{loam/install/templates/migrations/create_loam_progress_jobs.rb → open_loam/install/templates/migrations/create_open_loam_progress_jobs.rb} +5 -5
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_record_locks.rb +16 -0
- data/lib/generators/{loam/install/templates/migrations/create_loam_scheduled_jobs.rb → open_loam/install/templates/migrations/create_open_loam_scheduled_jobs.rb} +5 -5
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_search_tokens.rb +18 -0
- data/lib/generators/{loam/install/templates/migrations/create_loam_sso_providers.rb → open_loam/install/templates/migrations/create_open_loam_sso_providers.rb} +12 -12
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_tenants.rb +9 -0
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_translations.rb +15 -0
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_webhook_endpoints.rb +13 -0
- data/lib/generators/{loam → open_loam}/install/templates/migrations/create_users.rb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/user.rb +5 -5
- data/lib/generators/{loam → open_loam}/primary_key_options.rb +23 -23
- data/lib/open-loam.rb +2 -2
- data/lib/{loam → open_loam}/attachable.rb +4 -4
- data/lib/{loam → open_loam}/auditable.rb +23 -23
- data/lib/{loam → open_loam}/auth_throttle.rb +10 -10
- data/lib/{loam → open_loam}/base32.rb +1 -1
- data/lib/{loam → open_loam}/bulk.rb +7 -7
- data/lib/{loam → open_loam}/business_rules/actions.rb +7 -7
- data/lib/{loam → open_loam}/business_rules/condition.rb +5 -5
- data/lib/{loam → open_loam}/business_rules.rb +19 -19
- data/lib/{loam → open_loam}/commentable.rb +6 -6
- data/lib/{loam → open_loam}/configs.rb +19 -19
- data/lib/{loam → open_loam}/cron.rb +2 -2
- data/lib/{loam → open_loam}/csv.rb +2 -2
- data/lib/{loam → open_loam}/current.rb +5 -5
- data/lib/{loam → open_loam}/custom_field_index.rb +23 -23
- data/lib/{loam → open_loam}/custom_fields.rb +17 -17
- data/lib/{loam → open_loam}/dashboard.rb +5 -5
- data/lib/{loam → open_loam}/dictionaries.rb +12 -12
- data/lib/{loam → open_loam}/durable_events.rb +19 -19
- data/lib/{loam → open_loam}/encryptable.rb +33 -33
- data/lib/{loam → open_loam}/encryption/cipher.rb +3 -3
- data/lib/{loam → open_loam}/encryption/key_provider.rb +3 -3
- data/lib/{loam → open_loam}/encryption.rb +11 -11
- data/lib/open_loam/engine.rb +57 -0
- data/lib/{loam → open_loam}/enrichers.rb +5 -5
- data/lib/{loam → open_loam}/errors.rb +10 -10
- data/lib/{loam → open_loam}/eval.rb +2 -2
- data/lib/{loam → open_loam}/event_stream.rb +14 -14
- data/lib/{loam → open_loam}/eventful.rb +12 -12
- data/lib/{loam → open_loam}/events.rb +5 -5
- data/lib/{loam → open_loam}/export.rb +8 -8
- data/lib/{loam → open_loam}/features.rb +15 -15
- data/lib/{loam → open_loam}/generated_key.rb +6 -6
- data/lib/{loam → open_loam}/import.rb +12 -12
- data/lib/{loam → open_loam}/inbound_webhooks.rb +7 -7
- data/lib/{loam → open_loam}/lifecycle.rb +25 -25
- data/lib/{loam/locales/loam.en.yml → open_loam/locales/open_loam.en.yml} +5 -5
- data/lib/{loam → open_loam}/mcp/server.rb +9 -9
- data/lib/{loam → open_loam}/mcp.rb +21 -21
- data/lib/{loam → open_loam}/notifications.rb +5 -5
- data/lib/{loam → open_loam}/open_api.rb +16 -16
- data/lib/{loam → open_loam}/overrides.rb +10 -10
- data/lib/{loam → open_loam}/pending_actions.rb +9 -9
- data/lib/{loam → open_loam}/permissions.rb +8 -8
- data/lib/{loam → open_loam}/perspectives.rb +9 -9
- data/lib/{loam → open_loam}/policy.rb +6 -6
- data/lib/{loam → open_loam}/progress.rb +6 -6
- data/lib/{loam → open_loam}/record_locks.rb +9 -9
- data/lib/{loam → open_loam}/scheduler.rb +20 -20
- data/lib/{loam → open_loam}/search/driver.rb +3 -3
- data/lib/{loam → open_loam}/search/like_driver.rb +5 -5
- data/lib/{loam → open_loam}/search/token_driver.rb +15 -15
- data/lib/{loam → open_loam}/search.rb +5 -5
- data/lib/{loam → open_loam}/searchable.rb +22 -22
- data/lib/{loam → open_loam}/soft_deletable.rb +10 -10
- data/lib/{loam → open_loam}/sso/claims.rb +1 -1
- data/lib/{loam → open_loam}/sso/fake_provider.rb +1 -1
- data/lib/{loam → open_loam}/sso/http_client.rb +3 -3
- data/lib/{loam → open_loam}/sso/oidc_provider.rb +2 -2
- data/lib/{loam → open_loam}/sso.rb +17 -17
- data/lib/{loam → open_loam}/telemetry.rb +6 -6
- data/lib/{loam → open_loam}/tenant_record.rb +10 -10
- data/lib/{loam → open_loam}/test_helpers.rb +4 -4
- data/lib/{loam → open_loam}/totp.rb +3 -3
- data/lib/{loam → open_loam}/translatable.rb +24 -24
- data/lib/{loam → open_loam}/undo.rb +11 -11
- data/lib/open_loam/version.rb +3 -0
- data/lib/{loam → open_loam}/webhooks.rb +4 -4
- data/lib/{loam → open_loam}/widgets.rb +9 -9
- data/lib/{loam → open_loam}/workflow.rb +45 -45
- data/lib/open_loam.rb +122 -0
- data/lib/tasks/{loam.rake → open_loam.rake} +43 -43
- data/lib/tasks/{loam_eval.rake → open_loam_eval.rake} +7 -7
- data/lib/tasks/open_loam_mcp.rake +20 -0
- metadata +242 -242
- data/app/models/loam/dictionary.rb +0 -20
- data/app/models/loam/search_token.rb +0 -9
- data/app/models/loam/tenant.rb +0 -20
- data/lib/generators/loam/entity/templates/views/edit.html.erb +0 -3
- data/lib/generators/loam/entity/templates/views/index.html.erb +0 -90
- data/lib/generators/loam/entity/templates/views/new.html.erb +0 -3
- data/lib/generators/loam/entity/templates/views/show.html.erb +0 -36
- data/lib/generators/loam/install/templates/AGENTS.md +0 -341
- data/lib/generators/loam/install/templates/admin/dashboard_controller.rb +0 -10
- data/lib/generators/loam/install/templates/admin/layout.html.erb +0 -76
- data/lib/generators/loam/install/templates/admin/progress_jobs_controller.rb +0 -19
- data/lib/generators/loam/install/templates/migrations/create_loam_api_tokens.rb +0 -15
- data/lib/generators/loam/install/templates/migrations/create_loam_audit_records.rb +0 -14
- data/lib/generators/loam/install/templates/migrations/create_loam_comments.rb +0 -13
- data/lib/generators/loam/install/templates/migrations/create_loam_custom_field_values.rb +0 -19
- data/lib/generators/loam/install/templates/migrations/create_loam_dashboard_widgets.rb +0 -12
- data/lib/generators/loam/install/templates/migrations/create_loam_dictionaries.rb +0 -11
- data/lib/generators/loam/install/templates/migrations/create_loam_memberships.rb +0 -11
- data/lib/generators/loam/install/templates/migrations/create_loam_notifications.rb +0 -15
- data/lib/generators/loam/install/templates/migrations/create_loam_record_locks.rb +0 -16
- data/lib/generators/loam/install/templates/migrations/create_loam_search_tokens.rb +0 -18
- data/lib/generators/loam/install/templates/migrations/create_loam_tenants.rb +0 -9
- data/lib/generators/loam/install/templates/migrations/create_loam_translations.rb +0 -15
- data/lib/generators/loam/install/templates/migrations/create_loam_webhook_endpoints.rb +0 -13
- data/lib/loam/engine.rb +0 -57
- data/lib/loam/version.rb +0 -3
- data/lib/loam.rb +0 -122
- data/lib/tasks/loam_mcp.rake +0 -20
- /data/lib/generators/{loam → open_loam}/install/templates/admin/api_tokens_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_edit.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_new.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/configs_edit.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/configs_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/dashboard_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/dashboard_widgets_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_edit.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_new.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/features_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/field_definitions_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/imports_new.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/imports_preview.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/imports_summary.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_activated.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_new.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_show.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/notifications_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/pagination.rb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/pending_actions_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_edit.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_new.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/search_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/sessions_mfa_challenge.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/sessions_new.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_edit.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_new.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/webhook_endpoints_new.html.erb +0 -0
|
@@ -2,7 +2,7 @@ module Admin
|
|
|
2
2
|
# Generic CSV importer, scoped by entity_type — manager-only (a privileged bulk
|
|
3
3
|
# mutation). Flow: new (upload) → preview (map columns) → create (dry-run
|
|
4
4
|
# summary, or a backgrounded run reporting live progress). The mapping only
|
|
5
|
-
# offers fields the manager may write (
|
|
5
|
+
# offers fields the manager may write (OpenLoam::Import.allowed_targets); a crafted
|
|
6
6
|
# target is refused by the engine.
|
|
7
7
|
class ImportsController < BaseController
|
|
8
8
|
before_action { require_role!(:manager) }
|
|
@@ -15,11 +15,11 @@ module Admin
|
|
|
15
15
|
# Parse the uploaded file, show the mapping form + a few sample rows.
|
|
16
16
|
def preview
|
|
17
17
|
@csv = read_upload
|
|
18
|
-
preview =
|
|
18
|
+
preview = OpenLoam::Import.preview(@csv)
|
|
19
19
|
@headers = preview[:headers]
|
|
20
20
|
@sample = preview[:rows]
|
|
21
|
-
@targets =
|
|
22
|
-
rescue
|
|
21
|
+
@targets = OpenLoam::Import.allowed_targets(@model, current_actor).to_a.sort
|
|
22
|
+
rescue OpenLoam::Error => error
|
|
23
23
|
redirect_to new_admin_import_path(entity_type: @entity_type), alert: error.message
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -35,19 +35,19 @@ module Admin
|
|
|
35
35
|
match_key: match_key, tenant_id: current_tenant.id, actor_id: current_actor.id)
|
|
36
36
|
redirect_to admin_progress_jobs_path, notice: "Import started — watch it progress under Tasks."
|
|
37
37
|
end
|
|
38
|
-
rescue
|
|
38
|
+
rescue OpenLoam::Error => error
|
|
39
39
|
redirect_to new_admin_import_path(entity_type: @entity_type), alert: error.message
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
# The failed rows as a fix-and-re-upload CSV.
|
|
43
43
|
def download_errors
|
|
44
44
|
@entity_type = params[:entity_type]
|
|
45
|
-
model =
|
|
45
|
+
model = OpenLoam::Import.allowed_model(@entity_type)
|
|
46
46
|
csv = params[:csv].to_s
|
|
47
47
|
mapping = params[:mapping].to_unsafe_h.reject { |_h, target| target.blank? }
|
|
48
|
-
result =
|
|
48
|
+
result = OpenLoam::Import.run(csv, model: model, mapping: mapping, actor: current_actor,
|
|
49
49
|
match_key: params[:match_key].presence, dry_run: true)
|
|
50
|
-
send_data
|
|
50
|
+
send_data OpenLoam::Import.error_csv(result, csv),
|
|
51
51
|
filename: "#{@entity_type.underscore}-import-errors.csv", type: "text/csv"
|
|
52
52
|
end
|
|
53
53
|
|
|
@@ -55,19 +55,19 @@ module Admin
|
|
|
55
55
|
|
|
56
56
|
def set_model
|
|
57
57
|
@entity_type = params[:entity_type]
|
|
58
|
-
@model =
|
|
58
|
+
@model = OpenLoam::Import.allowed_model(@entity_type)
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def run_dry(mapping, match_key)
|
|
62
|
-
@result =
|
|
62
|
+
@result = OpenLoam::Import.run(@csv, model: @model, mapping: mapping, actor: current_actor,
|
|
63
63
|
match_key: match_key, dry_run: true)
|
|
64
|
-
@headers =
|
|
64
|
+
@headers = OpenLoam::Import.preview(@csv)[:headers]
|
|
65
65
|
render :summary
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
def read_upload
|
|
69
69
|
file = params[:file]
|
|
70
|
-
raise
|
|
70
|
+
raise OpenLoam::Error, "choose a CSV file to upload" if file.blank?
|
|
71
71
|
|
|
72
72
|
file.read.force_encoding("UTF-8")
|
|
73
73
|
end
|
data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_controller.rb
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module Admin
|
|
2
2
|
# Manage the external systems allowed to POST webhooks into this tenant
|
|
3
|
-
# (
|
|
3
|
+
# (OpenLoam::InboundWebhookSource) — manager-only. Create a source (token + secret
|
|
4
4
|
# are generated), copy the receive URL and secret to the sender, rotate either,
|
|
5
5
|
# toggle active, and see the most recent received deliveries.
|
|
6
6
|
class InboundWebhookSourcesController < BaseController
|
|
@@ -8,16 +8,16 @@ module Admin
|
|
|
8
8
|
before_action :set_source, only: %i[destroy rotate_secret rotate_token toggle]
|
|
9
9
|
|
|
10
10
|
def index
|
|
11
|
-
@sources =
|
|
12
|
-
@recent =
|
|
11
|
+
@sources = OpenLoam::InboundWebhookSource.order(:name)
|
|
12
|
+
@recent = OpenLoam::InboundWebhookDelivery.order(received_at: :desc).limit(20)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def new
|
|
16
|
-
@source =
|
|
16
|
+
@source = OpenLoam::InboundWebhookSource.new(event_name: "inbound.webhook.received")
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def create
|
|
20
|
-
@source =
|
|
20
|
+
@source = OpenLoam::InboundWebhookSource.new(source_params)
|
|
21
21
|
if @source.save
|
|
22
22
|
redirect_to admin_inbound_webhook_sources_path, notice: "Source created. Copy the secret now — it signs every call."
|
|
23
23
|
else
|
|
@@ -48,7 +48,7 @@ module Admin
|
|
|
48
48
|
private
|
|
49
49
|
|
|
50
50
|
def set_source
|
|
51
|
-
@source =
|
|
51
|
+
@source = OpenLoam::InboundWebhookSource.find(params[:id])
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def source_params
|
data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_new.html.erb
RENAMED
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
<%%= f.text_field :event_name %>
|
|
15
15
|
</p>
|
|
16
16
|
<p>
|
|
17
|
-
<%%= f.label :signature_header, "Signature header (default X-
|
|
18
|
-
<%%= f.text_field :signature_header, placeholder: "X-
|
|
17
|
+
<%%= f.label :signature_header, "Signature header (default X-OpenLoam-Signature)" %><br>
|
|
18
|
+
<%%= f.text_field :signature_header, placeholder: "X-OpenLoam-Signature" %>
|
|
19
19
|
<small>e.g. X-Hub-Signature-256 for GitHub.</small>
|
|
20
20
|
</p>
|
|
21
21
|
<p>
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Admin</title>
|
|
5
|
+
<%%= csrf_meta_tags %>
|
|
6
|
+
<%%= stylesheet_link_tag "admin", media: "all" %>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<%% flash.each do |type, message| %>
|
|
10
|
+
<div class="flash flash-<%%= type.to_s == "alert" ? "alert" : "notice" %>"><%%= message %></div>
|
|
11
|
+
<%% end %>
|
|
12
|
+
<%% if defined?(current_tenant) && current_tenant %>
|
|
13
|
+
<div class="context">
|
|
14
|
+
<%%= t("open_loam.chrome.tenant") %>: <strong><%%= current_tenant.name %></strong> ·
|
|
15
|
+
<%%= t("open_loam.chrome.user") %>: <strong><%%= current_actor&.name %></strong> ·
|
|
16
|
+
<%%= button_to t("open_loam.chrome.sign_out"), admin_session_path, method: :delete, form: { style: "display:inline" } %>
|
|
17
|
+
</div>
|
|
18
|
+
<nav>
|
|
19
|
+
<%%= link_to t("open_loam.nav.dashboard"), admin_root_path %>
|
|
20
|
+
<%%= link_to admin_notifications_path do %><%%= t("open_loam.nav.notifications") %> (<span id="open-loam-notification-count"><%%= unread_notification_count %></span>)<%% end %>
|
|
21
|
+
<%%= link_to t("open_loam.nav.api_tokens"), admin_api_tokens_path %>
|
|
22
|
+
<%%= link_to t("open_loam.nav.security"), admin_mfa_path %>
|
|
23
|
+
<%%= link_to "#{t('open_loam.nav.approvals')} (#{pending_approval_count})", admin_pending_actions_path %>
|
|
24
|
+
<%%= link_to t("open_loam.nav.settings"), admin_configs_path %>
|
|
25
|
+
<%%= link_to t("open_loam.nav.features"), admin_features_path %>
|
|
26
|
+
<%%= link_to t("open_loam.nav.rules"), admin_business_rules_path %>
|
|
27
|
+
<%%= link_to t("open_loam.nav.sso"), admin_sso_providers_path %>
|
|
28
|
+
<%%= link_to t("open_loam.nav.dictionaries"), admin_dictionaries_path %>
|
|
29
|
+
<%%= link_to t("open_loam.nav.tasks"), admin_progress_jobs_path %>
|
|
30
|
+
<%%= link_to t("open_loam.nav.schedules"), admin_scheduled_jobs_path %>
|
|
31
|
+
<%%= link_to t("open_loam.nav.deliveries"), admin_event_deliveries_path %>
|
|
32
|
+
<%%= link_to t("open_loam.nav.inbound"), admin_inbound_webhook_sources_path %>
|
|
33
|
+
<%%= link_to t("open_loam.nav.api_docs"), admin_api_docs_path %>
|
|
34
|
+
<%%= link_to t("open_loam.nav.overrides"), admin_overrides_path %>
|
|
35
|
+
<%%= form_with url: admin_search_path, method: :get, class: "search" do %>
|
|
36
|
+
<%%= text_field_tag :q, params[:q], placeholder: t("open_loam.chrome.search") %>
|
|
37
|
+
<%% end %>
|
|
38
|
+
<%%# Locale switcher (OpenLoam::Translatable): overlays content onto the picked language. %>
|
|
39
|
+
<%% if OpenLoam.locales.size > 1 %>
|
|
40
|
+
<span class="locale">
|
|
41
|
+
<%% OpenLoam.locales.each do |loc| %><%%= link_to loc.upcase, "#{request.path}?locale=#{loc}", style: (loc == current_locale ? "font-weight:bold" : "") %> <%% end %>
|
|
42
|
+
</span>
|
|
43
|
+
<%% end %>
|
|
44
|
+
</nav>
|
|
45
|
+
|
|
46
|
+
<%%# Live updates over SSE (OpenLoam::EventStream). Degrades gracefully: if
|
|
47
|
+
EventSource is unavailable or the stream drops, the per-page-load bell
|
|
48
|
+
count above still works. %>
|
|
49
|
+
<script>
|
|
50
|
+
(function () {
|
|
51
|
+
if (typeof EventSource === "undefined") return;
|
|
52
|
+
var source = new EventSource("<%%= admin_events_stream_path %>");
|
|
53
|
+
source.addEventListener("open_loam.notification.created", function () {
|
|
54
|
+
var badge = document.getElementById("open-loam-notification-count");
|
|
55
|
+
if (badge) badge.textContent = (parseInt(badge.textContent, 10) || 0) + 1;
|
|
56
|
+
});
|
|
57
|
+
// Live task progress (OpenLoam::ProgressJob): move the matching bar. The
|
|
58
|
+
// frame carries only id/percent/status.
|
|
59
|
+
source.addEventListener("open_loam.progress.updated", function (e) {
|
|
60
|
+
var d = JSON.parse(e.data);
|
|
61
|
+
var fill = document.getElementById("progress-fill-" + d.id);
|
|
62
|
+
if (fill) fill.style.width = d.percent + "%";
|
|
63
|
+
var pct = document.getElementById("progress-percent-" + d.id);
|
|
64
|
+
if (pct) pct.textContent = d.percent + "%";
|
|
65
|
+
var st = document.getElementById("progress-status-" + d.id);
|
|
66
|
+
if (st) st.textContent = d.status;
|
|
67
|
+
});
|
|
68
|
+
source.onerror = function () {
|
|
69
|
+
if (source.readyState === EventSource.CLOSED) source.close();
|
|
70
|
+
};
|
|
71
|
+
})();
|
|
72
|
+
</script>
|
|
73
|
+
<%% end %>
|
|
74
|
+
<%%= yield %>
|
|
75
|
+
</body>
|
|
76
|
+
</html>
|
|
@@ -15,7 +15,7 @@ module Admin
|
|
|
15
15
|
before_action :require_sudo!, only: %i[create destroy], if: :active_mfa?
|
|
16
16
|
|
|
17
17
|
def show
|
|
18
|
-
@credential =
|
|
18
|
+
@credential = OpenLoam::MfaCredential.active_for(current_actor)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
# READ-ONLY: mint a candidate secret into the (encrypted cookie) session and
|
|
@@ -28,7 +28,7 @@ module Admin
|
|
|
28
28
|
# recovery codes once. The active secret is replaced only on success.
|
|
29
29
|
def create
|
|
30
30
|
secret = session[:mfa_enrollment_secret]
|
|
31
|
-
credential =
|
|
31
|
+
credential = OpenLoam::MfaCredential.find_or_initialize_by(user_id: current_actor.id)
|
|
32
32
|
@recovery_codes = secret && credential.activate_with!(secret, params[:code])
|
|
33
33
|
|
|
34
34
|
if @recovery_codes
|
|
@@ -42,7 +42,7 @@ module Admin
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def destroy
|
|
45
|
-
|
|
45
|
+
OpenLoam::MfaCredential.where(user_id: current_actor.id).delete_all
|
|
46
46
|
session.delete(:mfa_enrollment_secret)
|
|
47
47
|
redirect_to admin_mfa_path, notice: "Two-factor authentication disabled."
|
|
48
48
|
end
|
|
@@ -50,12 +50,12 @@ module Admin
|
|
|
50
50
|
private
|
|
51
51
|
|
|
52
52
|
def set_enrollment_secret
|
|
53
|
-
@secret = (session[:mfa_enrollment_secret] ||=
|
|
54
|
-
@provisioning_uri =
|
|
53
|
+
@secret = (session[:mfa_enrollment_secret] ||= OpenLoam::Totp.generate_secret)
|
|
54
|
+
@provisioning_uri = OpenLoam::Totp.provisioning_uri(@secret, account: current_actor.email, issuer: ISSUER)
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def active_mfa?
|
|
58
|
-
|
|
58
|
+
OpenLoam::MfaCredential.active_for(current_actor).present?
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
module Admin
|
|
2
2
|
# The bell. Every query here is scoped to the current actor, so there is no
|
|
3
3
|
# "read someone else's notifications" path to authorize and no per-record
|
|
4
|
-
# policy to write: tenancy is structural (
|
|
5
|
-
#
|
|
4
|
+
# policy to write: tenancy is structural (OpenLoam::Notification is a
|
|
5
|
+
# OpenLoam::TenantRecord) and BaseController has already established that this
|
|
6
6
|
# actor is signed in to this tenant. Recipient scoping is the whole rule.
|
|
7
7
|
class NotificationsController < BaseController
|
|
8
8
|
def index
|
|
@@ -17,7 +17,7 @@ module Admin
|
|
|
17
17
|
private
|
|
18
18
|
|
|
19
19
|
def notifications
|
|
20
|
-
|
|
20
|
+
OpenLoam::Notification.where(user_id: current_actor.id)
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module Admin
|
|
2
|
-
# Read-only view of the app's
|
|
2
|
+
# Read-only view of the app's OpenLoam::Overrides — which registry entries are
|
|
3
3
|
# disabled or replaced, plus any STALE overrides (a key that no longer exists).
|
|
4
4
|
# Manager-only, for legibility: it's config declared in an initializer, shown
|
|
5
5
|
# here so an operator can see what's been customized without reading code.
|
|
@@ -7,8 +7,8 @@ module Admin
|
|
|
7
7
|
before_action { require_role!(:manager) }
|
|
8
8
|
|
|
9
9
|
def index
|
|
10
|
-
@overrides =
|
|
11
|
-
@stale =
|
|
10
|
+
@overrides = OpenLoam::Overrides.all
|
|
11
|
+
@stale = OpenLoam::Overrides.stale
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<h1>Overrides</h1>
|
|
2
2
|
|
|
3
3
|
<p>Registry entries this app disables or replaces (declared in
|
|
4
|
-
<code>config/initializers/
|
|
4
|
+
<code>config/initializers/open_loam.rb</code> via <code>OpenLoam::Overrides</code>) —
|
|
5
5
|
customization without forking. Structural pieces (views, controllers, routes)
|
|
6
6
|
are overridden the Rails way (path shadowing), not here.</p>
|
|
7
7
|
|
|
@@ -18,7 +18,7 @@ are overridden the Rails way (path shadowing), not here.</p>
|
|
|
18
18
|
<tr>
|
|
19
19
|
<td><code><%%= registry %></code></td>
|
|
20
20
|
<td><code><%%= key %></code></td>
|
|
21
|
-
<td><%%= value ==
|
|
21
|
+
<td><%%= value == OpenLoam::Overrides::DISABLED ? "disabled" : "replaced" %></td>
|
|
22
22
|
</tr>
|
|
23
23
|
<%% end %>
|
|
24
24
|
<%% end %>
|
data/lib/generators/{loam → open_loam}/install/templates/admin/pending_actions_controller.rb
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module Admin
|
|
2
|
-
# The approval queue: staged mutations (
|
|
2
|
+
# The approval queue: staged mutations (OpenLoam::PendingAction) waiting on a
|
|
3
3
|
# human. Manager-only — approving EXECUTES the change. The workflow's role gate
|
|
4
4
|
# is the deeper enforcement (approve!/reject! raise for a non-manager); this
|
|
5
5
|
# screen is a manager screen on top of it.
|
|
@@ -8,7 +8,7 @@ module Admin
|
|
|
8
8
|
before_action :set_pending_action, only: %i[approve reject]
|
|
9
9
|
|
|
10
10
|
def index
|
|
11
|
-
@pending =
|
|
11
|
+
@pending = OpenLoam::PendingAction.pending.order(created_at: :desc)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def approve
|
|
@@ -24,7 +24,7 @@ module Admin
|
|
|
24
24
|
private
|
|
25
25
|
|
|
26
26
|
def set_pending_action
|
|
27
|
-
@pending_action =
|
|
27
|
+
@pending_action = OpenLoam::PendingAction.find(params[:id])
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def approval_notice(pending)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
module Admin
|
|
2
|
-
# Managing saved views (
|
|
2
|
+
# Managing saved views (OpenLoam::Perspective) for an entity. A view is CREATED by
|
|
3
3
|
# "save current view" on the entity index (capturing the live filters/sort); it
|
|
4
4
|
# starts private, owned by you. Here you rename it, widen its audience, make it
|
|
5
5
|
# the default, or delete it.
|
|
6
6
|
#
|
|
7
7
|
# Who may manage a view: its owner always; a manager for role/tenant-visibility
|
|
8
8
|
# ones. A private view of someone else's is invisible here by construction
|
|
9
|
-
# (
|
|
9
|
+
# (OpenLoam::Perspectives.visible_to never returns it).
|
|
10
10
|
class PerspectivesController < BaseController
|
|
11
11
|
before_action :set_perspective, only: %i[update destroy set_default]
|
|
12
12
|
before_action :authorize_manage!, only: %i[update destroy set_default]
|
|
@@ -18,12 +18,12 @@ module Admin
|
|
|
18
18
|
|
|
19
19
|
def index
|
|
20
20
|
@entity_type = params[:entity_type].to_s
|
|
21
|
-
@perspectives =
|
|
21
|
+
@perspectives = OpenLoam::Perspectives.visible_to(@entity_type, user: current_actor)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
# From the entity index: save the CURRENT filters/sort as a new private view.
|
|
25
25
|
def create
|
|
26
|
-
perspective =
|
|
26
|
+
perspective = OpenLoam::Perspective.create!(
|
|
27
27
|
entity_type: params[:entity_type].to_s,
|
|
28
28
|
name: params[:name].presence || "Saved view",
|
|
29
29
|
visibility: "private",
|
|
@@ -38,7 +38,7 @@ module Admin
|
|
|
38
38
|
# the audience clears the default flag so it is re-chosen deliberately.
|
|
39
39
|
attributes = perspective_params
|
|
40
40
|
if attributes[:visibility].present? && attributes[:visibility] != @perspective.visibility
|
|
41
|
-
raise
|
|
41
|
+
raise OpenLoam::NotAuthorizedError if attributes[:visibility] != "private" && current_role != :manager
|
|
42
42
|
|
|
43
43
|
attributes[:is_default] = false
|
|
44
44
|
end
|
|
@@ -64,11 +64,11 @@ module Admin
|
|
|
64
64
|
private
|
|
65
65
|
|
|
66
66
|
def set_perspective
|
|
67
|
-
@perspective =
|
|
67
|
+
@perspective = OpenLoam::Perspective.find(params[:id])
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
def authorize_manage!
|
|
71
|
-
raise
|
|
71
|
+
raise OpenLoam::NotAuthorizedError unless can_manage?(@perspective)
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
# Owner always; a manager for shared (role/tenant) views. A private view of
|
|
@@ -24,7 +24,7 @@ or delete it.</p>
|
|
|
24
24
|
<%% if perspective.owner_id == current_actor.id || (perspective.visibility != "private" && current_role == :manager) %>
|
|
25
25
|
<%%= form_with url: admin_perspective_path(perspective, entity_type: @entity_type), method: :patch, class: "inline" do %>
|
|
26
26
|
<%%= text_field_tag :"perspective[name]", perspective.name, size: 16 %>
|
|
27
|
-
<%%= select_tag :"perspective[visibility]", options_for_select(
|
|
27
|
+
<%%= select_tag :"perspective[visibility]", options_for_select(OpenLoam::Perspective::VISIBILITIES, perspective.visibility) %>
|
|
28
28
|
<%%= text_field_tag :"perspective[role]", perspective.role, placeholder: "role", size: 8 %>
|
|
29
29
|
<%%= submit_tag "Save" %>
|
|
30
30
|
<%% end %>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Admin
|
|
2
|
+
# Long-running task progress (OpenLoam::ProgressJob) — a tenant-scoped list of
|
|
3
|
+
# recent jobs with a live bar (the open_loam.progress.updated SSE event updates it).
|
|
4
|
+
# Your app starts jobs with OpenLoam::Progress.start in its own background jobs;
|
|
5
|
+
# a running one can be cancelled cooperatively here.
|
|
6
|
+
class ProgressJobsController < BaseController
|
|
7
|
+
def index
|
|
8
|
+
@jobs = OpenLoam::ProgressJob.recent.limit(20)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def cancel
|
|
12
|
+
job = OpenLoam::ProgressJob.find(params[:id])
|
|
13
|
+
# Manager-or-owner: a member must not cancel another user's job.
|
|
14
|
+
raise OpenLoam::NotAuthorizedError unless current_role == :manager || job.actor_id == current_actor&.id
|
|
15
|
+
job.cancel! if job.running?
|
|
16
|
+
redirect_to admin_progress_jobs_path, notice: "Job cancelled."
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<h1>Tasks</h1>
|
|
2
2
|
|
|
3
3
|
<p>Long-running jobs report progress here live (no reload — pushed over SSE).
|
|
4
|
-
Start one from your own code with <code>
|
|
4
|
+
Start one from your own code with <code>OpenLoam::Progress.start(name:, total:)</code>.</p>
|
|
5
5
|
|
|
6
6
|
<table>
|
|
7
7
|
<thead>
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
module Admin
|
|
2
|
-
# Manager take-over of an advisory edit lock (
|
|
2
|
+
# Manager take-over of an advisory edit lock (OpenLoam::RecordLocks). Only a
|
|
3
3
|
# manager may force-release someone else's lock; the record it points at is
|
|
4
|
-
# resolved through a whitelist (a
|
|
4
|
+
# resolved through a whitelist (a OpenLoam::TenantRecord subclass), never a raw
|
|
5
5
|
# constantize of user input.
|
|
6
6
|
class RecordLocksController < BaseController
|
|
7
7
|
before_action { require_role!(:manager) }
|
|
8
8
|
|
|
9
9
|
def destroy
|
|
10
10
|
klass = params[:lockable_type].to_s.safe_constantize
|
|
11
|
-
raise
|
|
11
|
+
raise OpenLoam::NotAuthorizedError unless klass && klass < OpenLoam::TenantRecord
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
OpenLoam::RecordLocks.force_release(klass.find(params[:lockable_id]))
|
|
14
14
|
redirect_back fallback_location: admin_root_path, notice: "Lock released — you can edit now."
|
|
15
15
|
end
|
|
16
16
|
end
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
module Admin
|
|
2
|
-
# Recurring schedules (
|
|
2
|
+
# Recurring schedules (OpenLoam::ScheduledJob) — manager-only. List/create/edit/
|
|
3
3
|
# delete a tenant's schedules, toggle active, and "run now". The runner
|
|
4
|
-
# (`
|
|
4
|
+
# (`open_loam:scheduler:tick`, wired to system cron) is what fires them on schedule.
|
|
5
5
|
class ScheduledJobsController < BaseController
|
|
6
6
|
before_action { require_role!(:manager) }
|
|
7
7
|
before_action :set_job, only: %i[edit update destroy run_now]
|
|
8
8
|
|
|
9
9
|
def index
|
|
10
|
-
@jobs =
|
|
10
|
+
@jobs = OpenLoam::ScheduledJob.order(:key)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def new
|
|
14
|
-
@job =
|
|
14
|
+
@job = OpenLoam::ScheduledJob.new(scope: "tenant", active: true, schedule: "0 3 * * *")
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def create
|
|
18
18
|
# scope is forced to "tenant": a tenant admin must never create a
|
|
19
19
|
# "system" schedule (which would run with no tenant context). System
|
|
20
20
|
# schedules are created only by the app/console.
|
|
21
|
-
@job =
|
|
21
|
+
@job = OpenLoam::ScheduledJob.new(job_params.merge(scope: "tenant"))
|
|
22
22
|
@job.next_run_at ||= safe_next_run(@job)
|
|
23
23
|
if @job.save
|
|
24
24
|
redirect_to admin_scheduled_jobs_path, notice: "Schedule created."
|
|
@@ -45,14 +45,14 @@ module Admin
|
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def run_now
|
|
48
|
-
|
|
48
|
+
OpenLoam::Scheduler.run_now(@job)
|
|
49
49
|
redirect_to admin_scheduled_jobs_path, notice: "#{@job.name} enqueued."
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
private
|
|
53
53
|
|
|
54
54
|
def set_job
|
|
55
|
-
@job =
|
|
55
|
+
@job = OpenLoam::ScheduledJob.find(params[:id])
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def job_params
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<%%#
|
|
1
|
+
<%%# OpenLoam::ScheduledJob is namespaced, so pin the URL + param scope. %>
|
|
2
2
|
<%%= form_with model: @job, scope: :scheduled_job,
|
|
3
3
|
url: (@job.persisted? ? admin_scheduled_job_path(@job) : admin_scheduled_jobs_path) do |f| %>
|
|
4
4
|
<%% if @job.errors.any? %>
|
data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_index.html.erb
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<h1>Schedules</h1>
|
|
2
2
|
|
|
3
|
-
<p>Recurring jobs for this tenant. The runner (<code>
|
|
3
|
+
<p>Recurring jobs for this tenant. The runner (<code>open_loam:scheduler:tick</code>,
|
|
4
4
|
wired to system cron) fires them on schedule. <%%= link_to "New schedule", new_admin_scheduled_job_path %></p>
|
|
5
5
|
|
|
6
6
|
<table>
|
|
@@ -16,9 +16,9 @@ module Admin
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
# The first searchable column that has a value, plus the id — enough to
|
|
19
|
-
# recognise a record without
|
|
19
|
+
# recognise a record without OpenLoam having to know what a "title" is.
|
|
20
20
|
def search_result_label(record)
|
|
21
|
-
value = record.class.
|
|
21
|
+
value = record.class.open_loam_searchable_columns.filter_map { |column| record.public_send(column).presence }.first
|
|
22
22
|
|
|
23
23
|
[ value || record.model_name.human, "##{record.id}" ].join(" ")
|
|
24
24
|
end
|
|
@@ -32,7 +32,7 @@ module Admin
|
|
|
32
32
|
end.to_h
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
# Every
|
|
35
|
+
# Every OpenLoam entity that opted into search, in name order.
|
|
36
36
|
#
|
|
37
37
|
# This eager loads, unlike Admin::CommentsController, and for the opposite
|
|
38
38
|
# reason: there is no user-supplied class name to check here, we need the
|
|
@@ -41,8 +41,8 @@ module Admin
|
|
|
41
41
|
def searchable_models
|
|
42
42
|
Rails.application.eager_load!
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
model.name.present? && model.respond_to?(:
|
|
44
|
+
OpenLoam::TenantRecord.descendants.select do |model|
|
|
45
|
+
model.name.present? && model.respond_to?(:open_loam_searchable?) && model.open_loam_searchable?
|
|
46
46
|
end.sort_by(&:name)
|
|
47
47
|
end
|
|
48
48
|
end
|