ecoportal-api-graphql 1.3.4 → 1.3.9
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/.ai-assistance/bridge/CLAUDE.md +338 -0
- data/.ai-assistance/bridge/archive/.gitkeep +0 -0
- data/.ai-assistance/bridge/archive/oscar-a1b2c3d-gitlab-mcp-doc-update.inbox.md +29 -0
- data/.ai-assistance/bridge/archive/oscar-a1b2c3d-gitlab-mcp-doc-update.outbox.md +18 -0
- data/.ai-assistance/bridge/archive/oscar-c912c25-gemini-design-review.inbox.md +42 -0
- data/.ai-assistance/bridge/archive/oscar-c912c25-gemini-design-review.outbox.md +115 -0
- data/.ai-assistance/bridge/context/gemini-review-prompt.txt +48 -0
- data/.ai-assistance/bridge/context/gemini-review-response.md +104 -0
- data/.ai-assistance/bridge/context/project.md +42 -0
- data/.ai-assistance/bridge/inbox/.gitkeep +0 -0
- data/.ai-assistance/bridge/outbox/.gitkeep +0 -0
- data/.ai-assistance/bridge/outbox/request-for-standards-discovery.md +48 -0
- data/.ai-assistance/bridge/queue/.gitkeep +1 -0
- data/.ai-assistance/capabilities/CLAUDE.md +27 -0
- data/.ai-assistance/capabilities/assumptions-log.md +80 -0
- data/.ai-assistance/capabilities/code.md +47 -0
- data/.ai-assistance/capabilities/connectors.md +37 -0
- data/.ai-assistance/capabilities/cowork.md +55 -0
- data/.ai-assistance/code/OVERVIEW.md +155 -0
- data/.ai-assistance/code/data_fields.md +242 -0
- data/.ai-assistance/code/dependencies.md +151 -0
- data/.ai-assistance/code/diff_as_input.md +234 -0
- data/.ai-assistance/code/diff_service_deep_dive.md +192 -0
- data/.ai-assistance/code/ecoPortal_architecture/00_overview_and_index.md +55 -0
- data/.ai-assistance/code/ecoPortal_architecture/01_terminology_dictionary.md +181 -0
- data/.ai-assistance/code/ecoPortal_architecture/02_data_model.md +192 -0
- data/.ai-assistance/code/ecoPortal_architecture/03_api_layers.md +147 -0
- data/.ai-assistance/code/ecoPortal_architecture/04_graphql_queries_mutations.md +277 -0
- data/.ai-assistance/code/ecoPortal_architecture/05_page_workflows.md +200 -0
- data/.ai-assistance/code/ecoPortal_architecture/06_search_and_filters.md +228 -0
- data/.ai-assistance/code/ecoPortal_architecture/07_data_fields.md +197 -0
- data/.ai-assistance/code/ecoPortal_architecture/08_stages_sections.md +243 -0
- data/.ai-assistance/code/ecoPortal_architecture/09_people_contractors_locations.md +196 -0
- data/.ai-assistance/code/ecoPortal_architecture/10_forces_workflow_builder.md +132 -0
- data/.ai-assistance/code/ecoPortal_architecture/11_integration_gems.md +187 -0
- data/.ai-assistance/code/ecoPortal_architecture/12_ai_documentation_sources_gaps.md +236 -0
- data/.ai-assistance/code/ecoPortal_architecture/13_ai_infrastructure.md +183 -0
- data/.ai-assistance/code/ecoportal_schema_reference.md +240 -0
- data/.ai-assistance/code/graphql_domain_knowledge.md +230 -0
- data/.ai-assistance/code/refactoring/datafield-readwrite-shape-asymmetry.md +71 -0
- data/.ai-assistance/code/refactoring/opportunities.md +251 -0
- data/.ai-assistance/code/schema_analysis.md +321 -0
- data/.ai-assistance/code/search_filters.md +868 -0
- data/.ai-assistance/code/spec_coverage.md +73 -0
- data/.ai-assistance/code/workflow-command-guide.md +438 -0
- data/.ai-assistance/code/workflow-space.md +353 -0
- data/.ai-assistance/conventions/CLAUDE.md +30 -0
- data/.ai-assistance/conventions/code-working-tree-protocol.md +199 -0
- data/.ai-assistance/conventions/gitignore-rules.md +42 -0
- data/.ai-assistance/conventions/permission-guidance.md +120 -0
- data/.ai-assistance/integrations/README.md +70 -0
- data/.ai-assistance/integrations/gitkraken-mcp.md +107 -0
- data/.ai-assistance/integrations/gitlab-mcp.md +123 -0
- data/.ai-assistance/integrations/local-git.md +60 -0
- data/.ai-assistance/local_paths.example.md +17 -0
- data/.ai-assistance/projects/TODO.md +97 -0
- data/.ai-assistance/projects/api-v2-to-graphql-migration/DECISIONS.md +168 -0
- data/.ai-assistance/projects/api-v2-to-graphql-migration/INTENT.md +60 -0
- data/.ai-assistance/projects/api-v2-to-graphql-migration/TODO.md +267 -0
- data/.ai-assistance/projects/api-v2-to-graphql-migration/UPSTREAM.md +53 -0
- data/.ai-assistance/projects/api-v2-to-graphql-migration/notes/csv-template-pipeline-design.md +102 -0
- data/.ai-assistance/projects/api-v2-to-graphql-migration/notes/cutover-usecase-gap-audit.md +139 -0
- data/.ai-assistance/projects/dynamic-model-generation/INTENT.md +93 -0
- data/.ai-assistance/projects/eco-helpers-compat/INTENT.md +244 -0
- data/.ai-assistance/projects/eco-helpers-compat/MIGRATION_GUIDE.md +266 -0
- data/.ai-assistance/projects/eco-helpers-compat/TODO.md +86 -0
- data/.ai-assistance/projects/ecoportal-api-v2-doublemodel-review/INTENT.md +101 -0
- data/.ai-assistance/projects/graphql-agent/GAP_ANALYSIS.md +177 -0
- data/.ai-assistance/projects/ooze-graphql-native-migration/DECISIONS.md +161 -0
- data/.ai-assistance/projects/ooze-graphql-native-migration/INTENT.md +125 -0
- data/.ai-assistance/projects/ooze-graphql-native-migration/RISKS.md +126 -0
- data/.ai-assistance/projects/ooze-graphql-native-migration/TODO.md +256 -0
- data/.ai-assistance/projects/ooze-graphql-native-migration/analysis/2026-06-30-cutover-workflow-deep-review.md +122 -0
- data/.ai-assistance/projects/ooze-graphql-native-migration/analysis/2026-07-01-forces-via-workflow-commands-miss-rca.md +148 -0
- data/.ai-assistance/projects/page-model/DECISIONS.md +245 -0
- data/.ai-assistance/projects/page-model/TODO.md +190 -0
- data/.ai-assistance/projects/search-filter-builder/INTENT.md +107 -0
- data/.ai-assistance/projects/search-filter-builder/TODO.md +131 -0
- data/.ai-assistance/projects/template-maintenance/DESIGN.md +134 -0
- data/.ai-assistance/projects/workflow-space/TODO.md +213 -0
- data/.ai-assistance/reinstall-claude-desktop-windows.md +136 -0
- data/.ai-assistance/scripts/CLAUDE.md +150 -0
- data/.ai-assistance/scripts/bridge-init.sh +86 -0
- data/.ai-assistance/scripts/bridge-status.sh +44 -0
- data/.ai-assistance/scripts/capabilities-check.ts +104 -0
- data/.ai-assistance/scripts/check-outbox.sh +43 -0
- data/.ai-assistance/scripts/dep_graph.rb +91 -0
- data/.ai-assistance/scripts/lock-acquire.sh +103 -0
- data/.ai-assistance/scripts/lock-multi.sh +124 -0
- data/.ai-assistance/scripts/lock-queue.sh +94 -0
- data/.ai-assistance/scripts/setup-mcps.test.ts +188 -0
- data/.ai-assistance/scripts/setup-mcps.ts +234 -0
- data/.ai-assistance/scripts/task-complete.ts +74 -0
- data/.ai-assistance/scripts/task-create.ts +75 -0
- data/.ai-assistance/scripts/task-read.ts +125 -0
- data/.ai-assistance/scripts/token-logger.js +220 -0
- data/.ai-assistance/scripts/token-report.ts +158 -0
- data/.ai-assistance/scripts/token-session-start.js +66 -0
- data/.ai-assistance/skills/ai-instructions/SKILL.md +48 -0
- data/.ai-assistance/skills/code-specs/SKILL.md +69 -0
- data/.ai-assistance/skills/corporate-policies/SKILL.md +201 -0
- data/.ai-assistance/skills/dep-graph/SKILL.md +139 -0
- data/.ai-assistance/skills/ep-ai-manager/SKILL.md +417 -0
- data/.ai-assistance/skills/gemini-assist/SKILL.md +63 -0
- data/.ai-assistance/skills/gemini-assist/gemini-mcp-server.js +205 -0
- data/.ai-assistance/skills/gemini-assist/gemini_ask.py +1 -0
- data/.ai-assistance/skills/gemini-assist/gemini_ask.rb +240 -0
- data/.ai-assistance/skills/gemini-assist/prompts/cycle_end_review.txt +25 -0
- data/.ai-assistance/skills/graphql-schema-analysis/SKILL.md +261 -0
- data/.ai-assistance/skills/project-cycle/SKILL.md +177 -0
- data/.ai-assistance/skills/refactor/SKILL.md +62 -0
- data/.ai-assistance/skills/rubocop/SKILL.md +93 -0
- data/.ai-assistance/skills/ruby-scripting/SKILL.md +215 -0
- data/.ai-assistance/skills/spec-generation/SKILL.md +72 -0
- data/.ai-assistance/standards-version.json +21 -0
- data/.ai-assistance/token-budget.json +32 -0
- data/.ai-assistance/version.json +39 -0
- data/.claude/settings.json +146 -0
- data/.env.example +18 -0
- data/.gitattributes +15 -0
- data/.gitignore +13 -0
- data/.rubocop.yml +121 -97
- data/CHANGELOG.md +673 -470
- data/CLAUDE.md +232 -0
- data/Gemfile +30 -6
- data/Rakefile +90 -38
- data/docs/worklog.md +574 -0
- data/ecoportal-api-graphql.gemspec +40 -40
- data/lib/ecoportal/api/common/graphql/CLAUDE.md +36 -0
- data/lib/ecoportal/api/common/graphql/auth_service.rb +12 -14
- data/lib/ecoportal/api/common/graphql/client.rb +11 -3
- data/lib/ecoportal/api/common/graphql/http_client.rb +117 -29
- data/lib/ecoportal/api/common/graphql/model/CLAUDE.md +28 -0
- data/lib/ecoportal/api/common/graphql/model/as_input.rb +8 -5
- data/lib/ecoportal/api/common/graphql/model/diffable/classic_diff_service.rb +3 -1
- data/lib/ecoportal/api/common/graphql/model/diffable/diff_service.rb +31 -23
- data/lib/ecoportal/api/common/graphql/model/diffable/hash_diff_nesting.rb +54 -1
- data/lib/ecoportal/api/common/graphql.rb +1 -1
- data/lib/ecoportal/api/graphql/CLAUDE.md +37 -0
- data/lib/ecoportal/api/graphql/base/CLAUDE.md +50 -0
- data/lib/ecoportal/api/graphql/base/ai_summary_version.rb +17 -0
- data/lib/ecoportal/api/graphql/base/delta_result.rb +16 -0
- data/lib/ecoportal/api/graphql/base/force/binding.rb +19 -0
- data/lib/ecoportal/api/graphql/base/force/binding_collection.rb +62 -0
- data/lib/ecoportal/api/graphql/base/force/collection.rb +47 -0
- data/lib/ecoportal/api/graphql/base/force.rb +65 -0
- data/lib/ecoportal/api/graphql/base/kickstand/job.rb +17 -0
- data/lib/ecoportal/api/graphql/base/kickstand/workflow.rb +18 -0
- data/lib/ecoportal/api/graphql/base/kickstand.rb +13 -0
- data/lib/ecoportal/api/graphql/base/page/basic.rb +38 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/actions_list.rb +9 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/ai_summary.rb +18 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/checklist.rb +29 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/collection.rb +112 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/contractor_entities.rb +28 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/cross_reference.rb +54 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/date_field.rb +23 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/file_field.rb +25 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/gauge.rb +19 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/geo.rb +24 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/image_gallery.rb +24 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/law.rb +8 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/mailbox.rb +9 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/number.rb +20 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/people.rb +35 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/plain_text.rb +17 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/rich_text.rb +26 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/select.rb +41 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/signature.rb +9 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/smart_fill.rb +17 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/table.rb +9 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/tag_field.rb +21 -0
- data/lib/ecoportal/api/graphql/base/page/data_field.rb +137 -0
- data/lib/ecoportal/api/graphql/base/page/phased/stage.rb +68 -0
- data/lib/ecoportal/api/graphql/base/page/phased.rb +15 -0
- data/lib/ecoportal/api/graphql/base/page/section.rb +48 -0
- data/lib/ecoportal/api/graphql/base/page/section_collection.rb +79 -0
- data/lib/ecoportal/api/graphql/base/page.rb +7 -1
- data/lib/ecoportal/api/graphql/base/pages_workflow/action_type_selection.rb +17 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/callback_type.rb +28 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/command_change.rb +17 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/command_change_message.rb +15 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/command_es_change.rb +17 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/command_interface.rb +36 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/email_config.rb +18 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/escalation_level.rb +19 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/in_system_config.rb +16 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/mailbox_field_selection.rb +17 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/operation_interface.rb +39 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/operations/assign_to.rb +27 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/operations/create_page.rb +21 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/operations/send_notification.rb +30 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/people_field_selection.rb +17 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/recipient_config.rb +34 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/register_field.rb +17 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/task_config_selection.rb +17 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/time_delay_config.rb +16 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/trigger_interface.rb +26 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/triggers/conditional_logic.rb +17 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/user_selection.rb +16 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow.rb +35 -0
- data/lib/ecoportal/api/graphql/base/preset_view.rb +17 -0
- data/lib/ecoportal/api/graphql/base/preview_page.rb +23 -0
- data/lib/ecoportal/api/graphql/base/register.rb +18 -0
- data/lib/ecoportal/api/graphql/base.rb +26 -15
- data/lib/ecoportal/api/graphql/builder/CLAUDE.md +65 -0
- data/lib/ecoportal/api/graphql/builder/kickstand.rb +73 -0
- data/lib/ecoportal/api/graphql/builder/page.rb +210 -0
- data/lib/ecoportal/api/graphql/builder/register/preset_view.rb +84 -0
- data/lib/ecoportal/api/graphql/builder/register.rb +49 -0
- data/lib/ecoportal/api/graphql/builder/template.rb +80 -0
- data/lib/ecoportal/api/graphql/builder.rb +7 -3
- data/lib/ecoportal/api/graphql/compat/filter_translator.rb +107 -0
- data/lib/ecoportal/api/graphql/compat/page_reference.rb +23 -0
- data/lib/ecoportal/api/graphql/compat/pages.rb +212 -0
- data/lib/ecoportal/api/graphql/compat/registers.rb +84 -0
- data/lib/ecoportal/api/graphql/compat/response.rb +35 -0
- data/lib/ecoportal/api/graphql/compat/search_results.rb +33 -0
- data/lib/ecoportal/api/graphql/compat/stage_collection.rb +70 -0
- data/lib/ecoportal/api/graphql/compat/stage_view.rb +76 -0
- data/lib/ecoportal/api/graphql/compat.rb +17 -0
- data/lib/ecoportal/api/graphql/concerns/data_field_access.rb +71 -0
- data/lib/ecoportal/api/graphql/concerns/deprecation.rb +20 -0
- data/lib/ecoportal/api/graphql/concerns/fragment_definitions.rb +68 -0
- data/lib/ecoportal/api/graphql/concerns/page_compat.rb +51 -0
- data/lib/ecoportal/api/graphql/concerns/snake_camel_access.rb +60 -0
- data/lib/ecoportal/api/graphql/concerns.rb +14 -0
- data/lib/ecoportal/api/graphql/connection/page.rb +11 -0
- data/lib/ecoportal/api/graphql/connection/pages_workflow_command.rb +13 -0
- data/lib/ecoportal/api/graphql/connection/preset_view.rb +11 -0
- data/lib/ecoportal/api/graphql/connection/preview_page.rb +11 -0
- data/lib/ecoportal/api/graphql/connection.rb +8 -4
- data/lib/ecoportal/api/graphql/error.rb +3 -3
- data/lib/ecoportal/api/graphql/file_upload/client.rb +181 -0
- data/lib/ecoportal/api/graphql/file_upload.rb +10 -0
- data/lib/ecoportal/api/graphql/fragment/action.rb +1 -1
- data/lib/ecoportal/api/graphql/fragment/action_category.rb +1 -1
- data/lib/ecoportal/api/graphql/fragment/contractor_entity.rb +1 -1
- data/lib/ecoportal/api/graphql/fragment/force.rb +30 -0
- data/lib/ecoportal/api/graphql/fragment/location_draft.rb +2 -2
- data/lib/ecoportal/api/graphql/fragment/location_node.rb +1 -1
- data/lib/ecoportal/api/graphql/fragment/locations_error.rb +1 -1
- data/lib/ecoportal/api/graphql/fragment/page.rb +85 -0
- data/lib/ecoportal/api/graphql/fragment/pages/common_page_union.rb +395 -0
- data/lib/ecoportal/api/graphql/fragment/pages.rb +15 -0
- data/lib/ecoportal/api/graphql/fragment/pages_workflow.rb +172 -0
- data/lib/ecoportal/api/graphql/fragment/pagination.rb +1 -1
- data/lib/ecoportal/api/graphql/fragment.rb +37 -71
- data/lib/ecoportal/api/graphql/helpers/locations_tree.rb +1 -0
- data/lib/ecoportal/api/graphql/helpers.rb +1 -1
- data/lib/ecoportal/api/graphql/input/contractor_entity/update.rb +25 -0
- data/lib/ecoportal/api/graphql/input/delta_input.rb +16 -0
- data/lib/ecoportal/api/graphql/input/page/archive.rb +14 -0
- data/lib/ecoportal/api/graphql/input/page/build_from_template.rb +13 -0
- data/lib/ecoportal/api/graphql/input/page/create_draft.rb +13 -0
- data/lib/ecoportal/api/graphql/input/page/create_from_template.rb +18 -0
- data/lib/ecoportal/api/graphql/input/page/delete_draft.rb +13 -0
- data/lib/ecoportal/api/graphql/input/page/publish_draft.rb +13 -0
- data/lib/ecoportal/api/graphql/input/page/review_task.rb +14 -0
- data/lib/ecoportal/api/graphql/input/page/unarchive.rb +14 -0
- data/lib/ecoportal/api/graphql/input/page/update.rb +140 -0
- data/lib/ecoportal/api/graphql/input/page.rb +26 -0
- data/lib/ecoportal/api/graphql/input/preset_view/create.rb +18 -0
- data/lib/ecoportal/api/graphql/input/preset_view/permission.rb +16 -0
- data/lib/ecoportal/api/graphql/input/preset_view/update.rb +16 -0
- data/lib/ecoportal/api/graphql/input/preset_view.rb +14 -0
- data/lib/ecoportal/api/graphql/input/register/create.rb +18 -0
- data/lib/ecoportal/api/graphql/input/register/update.rb +15 -0
- data/lib/ecoportal/api/graphql/input/register.rb +13 -0
- data/lib/ecoportal/api/graphql/input/search_conf/ai_generator.rb +234 -0
- data/lib/ecoportal/api/graphql/input/search_conf.rb +367 -0
- data/lib/ecoportal/api/graphql/input/variable_binding.rb +20 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_action_tag.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_binding.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_comment_tagging_user_group.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_default_direct_strategy_user.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_default_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_direct_strategy_user.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_field.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_force.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_gauge_field_stop.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_linked_field_config.rb +23 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_linked_helper.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_operation.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_operation_direct_strategy_user.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_operation_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_action_type.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_filter.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_people_field.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_task_config.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_user.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_scheduled_callback.rb +23 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_scheduled_callback_action.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_section.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_select_field_option.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_stage.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_stage_section.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_stage_tag.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_task.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_task_assignment_user_group.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_workflow_callback.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/collapse_section.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_binding.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_creator_permissions.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_default_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_field_configuration.rb +21 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_force.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_gauge_field_stop.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_linked_field_config.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_linked_helper.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_operation.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_operation_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_page.rb +28 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_page_creator_permissions.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_reminder.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_required_sign_offs.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_restrict_comment_tagging.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_restrict_task_assignment.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_scheduled_callback.rb +22 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_section_header.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_select_field_option.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_stage.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_task_due.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_trigger.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/expand_section.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/contractor_entities.rb +24 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/cross_reference.rb +23 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/date.rb +20 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/gauge.rb +20 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/image_gallery.rb +20 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/location_field.rb +24 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/people.rb +24 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/plain_text.rb +20 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/rich_text.rb +20 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/select.rb +20 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/signature.rb +20 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/table.rb +25 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/move_field.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/move_stage.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_action_tag.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_binding.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_callback.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_comment_tagging_user_group.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_default_direct_strategy_user.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_default_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_direct_strategy_user.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_field.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_force.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_gauge_field_stop.rb +17 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_linked_field_config.rb +17 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_linked_helper.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation_direct_strategy_user.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_action_type.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_filter.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_people_field.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_task_config.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_user.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_scheduled_callback.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_section.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_select_field_option.rb +17 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage_section.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage_tag.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_task.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_assignment_user_group.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_due.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_priority_level.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/reorder_forces.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/reorder_section.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command.rb +251 -0
- data/lib/ecoportal/api/graphql/input.rb +15 -7
- data/lib/ecoportal/api/graphql/interface/base_page.rb +100 -58
- data/lib/ecoportal/api/graphql/interface/location_structure/nodes.rb +27 -28
- data/lib/ecoportal/api/graphql/logic/base_model.rb +2 -0
- data/lib/ecoportal/api/graphql/logic/base_query.rb +45 -2
- data/lib/ecoportal/api/graphql/logic/input.rb +15 -0
- data/lib/ecoportal/api/graphql/logic/mutation.rb +6 -1
- data/lib/ecoportal/api/graphql/logic/query_array.rb +1 -0
- data/lib/ecoportal/api/graphql/logic/query_connection.rb +2 -0
- data/lib/ecoportal/api/graphql/logic.rb +9 -9
- data/lib/ecoportal/api/graphql/model/ai_summary_version.rb +10 -0
- data/lib/ecoportal/api/graphql/model/organization.rb +65 -52
- data/lib/ecoportal/api/graphql/model/page/basic.rb +14 -0
- data/lib/ecoportal/api/graphql/model/page/data_field.rb +12 -0
- data/lib/ecoportal/api/graphql/model/page/phased/stage.rb +14 -0
- data/lib/ecoportal/api/graphql/model/page/phased.rb +82 -0
- data/lib/ecoportal/api/graphql/model/page/section.rb +12 -0
- data/lib/ecoportal/api/graphql/model/page.rb +6 -7
- data/lib/ecoportal/api/graphql/model/page_union.rb +21 -0
- data/lib/ecoportal/api/graphql/model/pages_workflow.rb +20 -0
- data/lib/ecoportal/api/graphql/model/preset_view.rb +10 -0
- data/lib/ecoportal/api/graphql/model/preview_page.rb +10 -0
- data/lib/ecoportal/api/graphql/model/register.rb +10 -0
- data/lib/ecoportal/api/graphql/model/resource.rb +1 -1
- data/lib/ecoportal/api/graphql/model.rb +21 -13
- data/lib/ecoportal/api/graphql/mutation/ai_summary/generate.rb +45 -0
- data/lib/ecoportal/api/graphql/mutation/ai_summary/submit_feedback.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/ai_summary.rb +13 -0
- data/lib/ecoportal/api/graphql/mutation/kickstand/bulk_update_jobs.rb +43 -0
- data/lib/ecoportal/api/graphql/mutation/kickstand/bulk_update_workflows.rb +43 -0
- data/lib/ecoportal/api/graphql/mutation/kickstand/fail_job.rb +39 -0
- data/lib/ecoportal/api/graphql/mutation/kickstand/fail_workflow.rb +39 -0
- data/lib/ecoportal/api/graphql/mutation/kickstand/start_job.rb +39 -0
- data/lib/ecoportal/api/graphql/mutation/kickstand/start_workflow.rb +39 -0
- data/lib/ecoportal/api/graphql/mutation/kickstand/stop_workflow.rb +39 -0
- data/lib/ecoportal/api/graphql/mutation/kickstand.rb +18 -0
- data/lib/ecoportal/api/graphql/mutation/location_structure/apply_commands.rb +3 -3
- data/lib/ecoportal/api/graphql/mutation/location_structure/draft/add_commands.rb +2 -2
- data/lib/ecoportal/api/graphql/mutation/location_structure/draft/create.rb +2 -2
- data/lib/ecoportal/api/graphql/mutation/location_structure/draft/drop_bad_commands.rb +3 -3
- data/lib/ecoportal/api/graphql/mutation/location_structure/draft/publish.rb +3 -3
- data/lib/ecoportal/api/graphql/mutation/page/approve_review_task.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/archive.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/batch_update_review_task.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/build_from_template.rb +50 -0
- data/lib/ecoportal/api/graphql/mutation/page/create_draft.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/create_from_template.rb +43 -0
- data/lib/ecoportal/api/graphql/mutation/page/delete_draft.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/execute_force_commands.rb +69 -0
- data/lib/ecoportal/api/graphql/mutation/page/execute_workflow_commands.rb +51 -0
- data/lib/ecoportal/api/graphql/mutation/page/publish_draft.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/reject_review_task.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/restart_review_task.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/unarchive.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/undo_review_task.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/update.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/update_variable_bindings.rb +44 -0
- data/lib/ecoportal/api/graphql/mutation/page.rb +28 -0
- data/lib/ecoportal/api/graphql/mutation/preset_view/create.rb +35 -0
- data/lib/ecoportal/api/graphql/mutation/preset_view/destroy.rb +35 -0
- data/lib/ecoportal/api/graphql/mutation/preset_view/permission.rb +37 -0
- data/lib/ecoportal/api/graphql/mutation/preset_view/update.rb +35 -0
- data/lib/ecoportal/api/graphql/mutation/preset_view.rb +15 -0
- data/lib/ecoportal/api/graphql/mutation/register/create.rb +35 -0
- data/lib/ecoportal/api/graphql/mutation/register/destroy.rb +35 -0
- data/lib/ecoportal/api/graphql/mutation/register/update.rb +35 -0
- data/lib/ecoportal/api/graphql/mutation/register.rb +14 -0
- data/lib/ecoportal/api/graphql/mutation/smart_fill/generate.rb +36 -0
- data/lib/ecoportal/api/graphql/mutation/smart_fill/submit_feedback.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/smart_fill.rb +13 -0
- data/lib/ecoportal/api/graphql/mutation/template/create.rb +39 -0
- data/lib/ecoportal/api/graphql/mutation/template/create_related_page.rb +46 -0
- data/lib/ecoportal/api/graphql/mutation/template/destroy_related_page.rb +43 -0
- data/lib/ecoportal/api/graphql/mutation/template/publish.rb +39 -0
- data/lib/ecoportal/api/graphql/mutation/template/unpublish.rb +39 -0
- data/lib/ecoportal/api/graphql/mutation/template/update.rb +43 -0
- data/lib/ecoportal/api/graphql/mutation/template/update_information.rb +43 -0
- data/lib/ecoportal/api/graphql/mutation/template.rb +18 -0
- data/lib/ecoportal/api/graphql/mutation.rb +11 -3
- data/lib/ecoportal/api/graphql/payload/ai_summary_generate.rb +12 -0
- data/lib/ecoportal/api/graphql/payload/execute_workflow_commands.rb +36 -0
- data/lib/ecoportal/api/graphql/payload/force_commands.rb +31 -0
- data/lib/ecoportal/api/graphql/payload/kickstand/bulk_update_jobs.rb +36 -0
- data/lib/ecoportal/api/graphql/payload/kickstand/bulk_update_workflows.rb +36 -0
- data/lib/ecoportal/api/graphql/payload/kickstand/job.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/kickstand/workflow.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/kickstand.rb +15 -0
- data/lib/ecoportal/api/graphql/payload/location_structure/draft/create.rb +33 -34
- data/lib/ecoportal/api/graphql/payload/ok_payload.rb +21 -0
- data/lib/ecoportal/api/graphql/payload/page/archive.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/page/build_from_template.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/page/create_from_template.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/page/draft.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/page/review_task.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/page/unarchive.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/page/update.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/page/update_variable_bindings.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/page.rb +19 -0
- data/lib/ecoportal/api/graphql/payload/preset_view.rb +11 -0
- data/lib/ecoportal/api/graphql/payload/register.rb +11 -0
- data/lib/ecoportal/api/graphql/payload/template/create.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/template/create_related_page.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/template/destroy_related_page.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/template/publish.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/template/unpublish.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/template/update.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/template/update_information.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/template.rb +18 -0
- data/lib/ecoportal/api/graphql/payload.rb +14 -3
- data/lib/ecoportal/api/graphql/query/action.rb +1 -1
- data/lib/ecoportal/api/graphql/query/action_categories.rb +2 -1
- data/lib/ecoportal/api/graphql/query/actions.rb +2 -2
- data/lib/ecoportal/api/graphql/query/contractor_entities.rb +2 -1
- data/lib/ecoportal/api/graphql/query/file_upload_signature.rb +76 -0
- data/lib/ecoportal/api/graphql/query/location_structure/draft.rb +2 -2
- data/lib/ecoportal/api/graphql/query/location_structure.rb +1 -1
- data/lib/ecoportal/api/graphql/query/location_structures.rb +1 -1
- data/lib/ecoportal/api/graphql/query/page.rb +45 -0
- data/lib/ecoportal/api/graphql/query/page_delta.rb +47 -0
- data/lib/ecoportal/api/graphql/query/page_with_forces.rb +43 -0
- data/lib/ecoportal/api/graphql/query/pages.rb +59 -0
- data/lib/ecoportal/api/graphql/query/pages_workflow_commands.rb +59 -0
- data/lib/ecoportal/api/graphql/query/register_preset_views.rb +78 -0
- data/lib/ecoportal/api/graphql/query/register_preview_pages.rb +83 -0
- data/lib/ecoportal/api/graphql/query/templates.rb +53 -0
- data/lib/ecoportal/api/graphql/query.rb +18 -7
- data/lib/ecoportal/api/graphql.rb +70 -2
- data/lib/ecoportal/api/graphql_version.rb +5 -5
- data/scripts/auto-worker-scheduler.sh +386 -0
- data/tests/contractor_entity_create.rb +19 -19
- data/tests/contractor_entity_udpate.rb +20 -20
- data/tests/dump_page_model.rb +74 -0
- data/tests/loc_structure_get.rb +1 -2
- data/tests/loc_structure_update.rb +51 -51
- data/tests/loc_structures_get.rb +15 -15
- data/tests/local_libs.rb +7 -7
- metadata +450 -11
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
# Cross-reference field — links to pages in another register.
|
|
4
|
+
class CrossReference < DataField
|
|
5
|
+
passarray :pages # staged writes; the READ response uses `references` (a connection)
|
|
6
|
+
|
|
7
|
+
# Current reference ids. The GraphQL response carries them under `references.nodes`
|
|
8
|
+
# (CommonPageUnion's crossReferenceField), NOT `pages` — so read from there. After a
|
|
9
|
+
# page_ids= write, prefer the staged `pages` value.
|
|
10
|
+
def page_ids
|
|
11
|
+
ref_ids_from(doc)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def page_ids=(ids)
|
|
15
|
+
doc['pages'] = Array(ids).map { |id_val| { 'id' => id_val } }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Dirty only when the effective reference-id SET actually changed.
|
|
19
|
+
#
|
|
20
|
+
# The field is READ into `references.nodes` but WRITTEN via `pages` (page_ids=). The
|
|
21
|
+
# default key-level leaf diff therefore sees a brand-new `pages` key the moment any
|
|
22
|
+
# setter runs and flags a change — even when the set is unchanged. The common offender
|
|
23
|
+
# is `clear` on an already-empty field ([] -> []): eco-helpers scripts clear a reference
|
|
24
|
+
# whenever the source value is blank, which under APIv2 was a no-op but on GraphQL
|
|
25
|
+
# emitted a phantom `referenceIds: []` update. Compare id SETS against the server
|
|
26
|
+
# baseline (`original_doc`) instead — restoring v2 parity (empty->empty / same->same
|
|
27
|
+
# is not dirty).
|
|
28
|
+
def dirty?
|
|
29
|
+
ref_ids_from(doc).sort != ref_ids_from(original_doc).sort
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def as_input
|
|
33
|
+
return nil unless dirty?
|
|
34
|
+
|
|
35
|
+
# CrossReferenceInput uses `referenceIds` (schema-confirmed) — NOT pageIds.
|
|
36
|
+
{ crossReference: { id: id, referenceIds: page_ids } }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
# Extract the reference id set from a doc snapshot. `original_doc` is the server baseline
|
|
42
|
+
# (the diff prev_doc — see Diffable::ClassicDiffService), `doc` carries client changes.
|
|
43
|
+
# Both prefer the staged `pages` (write shape) and fall back to `references.nodes` (read
|
|
44
|
+
# shape) — so the comparison is shape-agnostic and stays correct after `consolidate!`
|
|
45
|
+
# copies `doc` (with `pages`) into `original_doc`.
|
|
46
|
+
def ref_ids_from(source_doc)
|
|
47
|
+
return [] unless source_doc
|
|
48
|
+
|
|
49
|
+
src = source_doc.key?('pages') ? source_doc['pages'] : Array(source_doc.dig('references', 'nodes'))
|
|
50
|
+
Array(src).map { |r| r.is_a?(Hash) ? r['id'] : r }.compact
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
# Wraps Date data field. Mapped from __typename 'Date'.
|
|
4
|
+
# value is an ISO8601DateTime string (e.g. "2024-11-25T08:30:00+13:00").
|
|
5
|
+
class DateField < DataField
|
|
6
|
+
# value is nested: { dateTime: "...", timeZone: "..." } or raw string
|
|
7
|
+
def value
|
|
8
|
+
v = doc['value']
|
|
9
|
+
v.is_a?(Hash) ? v['dateTime'] : v
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def value=(iso8601_string)
|
|
13
|
+
doc['value'] = iso8601_string
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def as_input
|
|
17
|
+
return nil unless dirty?
|
|
18
|
+
|
|
19
|
+
{ date: { id: id, value: value } }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
# File attachment field.
|
|
4
|
+
# Writing requires a prior file upload to the REST upload endpoint
|
|
5
|
+
# to obtain fileContainerIds — see the file-upload TODO in projects/TODO.md.
|
|
6
|
+
# The file_container_ids= setter can be used once IDs are available.
|
|
7
|
+
class FileField < DataField
|
|
8
|
+
passarray :fileContainers # each: { id:, fileName:, ... }
|
|
9
|
+
|
|
10
|
+
def file_container_ids
|
|
11
|
+
Array(fileContainers).map { |c| c.is_a?(Hash) ? c['id'] : c }.compact
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def file_container_ids=(ids)
|
|
15
|
+
doc['fileContainers'] = Array(ids).map { |id_val| { 'id' => id_val } }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def as_input
|
|
19
|
+
return nil unless dirty?
|
|
20
|
+
|
|
21
|
+
{ file: { id: id, fileContainerIds: file_container_ids } }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
class Gauge < DataField
|
|
4
|
+
passthrough :value, :max
|
|
5
|
+
|
|
6
|
+
# Blank (empty / whitespace CSV cell) → nil, NOT 0.0 — see DataField#numeric_or_nil
|
|
7
|
+
# (mirrors Number; `"".to_f` would otherwise silently write a real zero).
|
|
8
|
+
def value=(numeric)
|
|
9
|
+
doc['value'] = numeric_or_nil(numeric)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def as_input
|
|
13
|
+
return nil unless dirty?
|
|
14
|
+
|
|
15
|
+
{ gauge: { id: id, value: value } }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
class Geo < DataField
|
|
4
|
+
passthrough :address, :coordinates # coordinates: { lat:, lon: }
|
|
5
|
+
|
|
6
|
+
def address=(new_address)
|
|
7
|
+
doc['address'] = new_address
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def coordinates=(lat_lon_hash)
|
|
11
|
+
doc['coordinates'] = lat_lon_hash
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def as_input
|
|
15
|
+
return nil unless dirty?
|
|
16
|
+
|
|
17
|
+
payload = { id: id }
|
|
18
|
+
payload[:address] = address if address
|
|
19
|
+
payload[:coordinates] = coordinates if coordinates
|
|
20
|
+
{ geo: payload }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
# Image gallery field.
|
|
4
|
+
# Writing requires a prior file upload to the REST upload endpoint
|
|
5
|
+
# to obtain fileContainerIds — see the file-upload TODO in projects/TODO.md.
|
|
6
|
+
class ImageGallery < DataField
|
|
7
|
+
passarray :fileContainers # each: { id:, fileName:, url:, ... }
|
|
8
|
+
|
|
9
|
+
def file_container_ids
|
|
10
|
+
Array(fileContainers).map { |c| c.is_a?(Hash) ? c['id'] : c }.compact
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def file_container_ids=(ids)
|
|
14
|
+
doc['fileContainers'] = Array(ids).map { |id_val| { 'id' => id_val } }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def as_input
|
|
18
|
+
return nil unless dirty?
|
|
19
|
+
|
|
20
|
+
{ imageGallery: { id: id, fileContainerIds: file_container_ids } }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
class Number < DataField
|
|
4
|
+
passthrough :value
|
|
5
|
+
|
|
6
|
+
# Blank (empty / whitespace CSV cell) → nil, NOT 0.0 — see DataField#numeric_or_nil.
|
|
7
|
+
# Whether a blank should CLEAR the field or be LEFT UNTOUCHED is the caller's policy;
|
|
8
|
+
# this only guarantees a blank never becomes the value 0.0.
|
|
9
|
+
def value=(numeric)
|
|
10
|
+
doc['value'] = numeric_or_nil(numeric)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def as_input
|
|
14
|
+
return nil unless dirty?
|
|
15
|
+
|
|
16
|
+
{ number: { id: id, value: value } }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
class People < DataField
|
|
4
|
+
passarray :peopleIds
|
|
5
|
+
|
|
6
|
+
def people_ids
|
|
7
|
+
ids = Array(peopleIds)
|
|
8
|
+
return ids unless ids.empty?
|
|
9
|
+
|
|
10
|
+
# Fallback: the read fragment populates `peopleIds`, but if a response ever returns it
|
|
11
|
+
# null/empty while the expanded `people { id }` nodes ARE present (a partial / non-
|
|
12
|
+
# $content read), seed from the nodes. The backend write replaces peopleIds wholesale,
|
|
13
|
+
# so a `people_ids << x` append must start from the existing set or it would WIPE the
|
|
14
|
+
# field. Mirrors CrossReference's references.nodes fallback. Read key == write key
|
|
15
|
+
# (peopleIds), so this only widens the read; it never creates phantom-dirty.
|
|
16
|
+
Array(doc['people']).map { |p| p.is_a?(Hash) ? p['id'] : p }.compact
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def people_ids=(ids)
|
|
20
|
+
doc['peopleIds'] = Array(ids).compact
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# v2 compat: scripts may set via people_ids= or direct assignment
|
|
24
|
+
def value=(ids)
|
|
25
|
+
self.people_ids = ids
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def as_input
|
|
29
|
+
return nil unless dirty?
|
|
30
|
+
|
|
31
|
+
{ people: { id: id, peopleIds: Array(peopleIds) } }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
class PlainText < DataField
|
|
4
|
+
passthrough :value
|
|
5
|
+
|
|
6
|
+
def value=(new_value)
|
|
7
|
+
doc['value'] = new_value
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def as_input
|
|
11
|
+
return nil unless dirty?
|
|
12
|
+
|
|
13
|
+
{ plainText: { id: id, value: value } }
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
class RichText < DataField
|
|
4
|
+
passthrough :content
|
|
5
|
+
|
|
6
|
+
def content=(new_content)
|
|
7
|
+
doc['content'] = new_content
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# v2 compat alias — RichText value is stored as content
|
|
11
|
+
def value
|
|
12
|
+
content
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def value=(new_value)
|
|
16
|
+
self.content = new_value
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def as_input
|
|
20
|
+
return nil unless dirty?
|
|
21
|
+
|
|
22
|
+
{ richText: { id: id, content: content } }
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
class Select < DataField
|
|
4
|
+
passarray :options # each: { id:, name:, value:, selected: }
|
|
5
|
+
passthrough :other, :otherDesc, :multiple, :dataType
|
|
6
|
+
|
|
7
|
+
# Select an option by id, name, or value. Deselects all others (single-select).
|
|
8
|
+
# For multi-select fields, call with multiple values.
|
|
9
|
+
def select_option(*id_or_values)
|
|
10
|
+
targets = id_or_values.flatten.map(&:to_s)
|
|
11
|
+
(doc['options'] || []).each do |opt|
|
|
12
|
+
opt['selected'] = targets.include?(opt['id'].to_s) ||
|
|
13
|
+
targets.include?(opt['name'].to_s) ||
|
|
14
|
+
targets.include?(opt['value'].to_s)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Deselect all options.
|
|
19
|
+
def clear_selection
|
|
20
|
+
(doc['options'] || []).each { |opt| opt['selected'] = false }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def selected_options
|
|
24
|
+
(doc['options'] || []).select { |opt| opt['selected'] }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def as_input
|
|
28
|
+
return nil unless dirty?
|
|
29
|
+
|
|
30
|
+
{
|
|
31
|
+
select: {
|
|
32
|
+
id: id,
|
|
33
|
+
# rubocop:disable Style/DoubleNegation
|
|
34
|
+
options: (doc['options'] || []).map { |opt| { id: opt['id'], selected: !!opt['selected'] } }
|
|
35
|
+
# rubocop:enable Style/DoubleNegation
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
# Digital signature capture field — read access only.
|
|
4
|
+
# Signatures are captured through the UI; not settable via script.
|
|
5
|
+
class Signature < DataField
|
|
6
|
+
passthrough :signedAt, :signerName
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
# SmartFill field — AI-auto-populated field using a template-defined prompt.
|
|
4
|
+
# Value is generated server-side via Bedrock; trigger_type controls when.
|
|
5
|
+
#
|
|
6
|
+
# Read-only for DataFieldInput — use the generateSmartFill GraphQL mutation
|
|
7
|
+
# (or its trigger) to populate. The instructions field is template-configured
|
|
8
|
+
# and can be reviewed/updated via template management.
|
|
9
|
+
class SmartFill < DataField
|
|
10
|
+
passthrough :status # pending | generating | success | failed
|
|
11
|
+
passthrough :trigger_type # manual | snapshot | live
|
|
12
|
+
passthrough :instructions # the AI prompt configured on the template field
|
|
13
|
+
passboolean :edit_enabled
|
|
14
|
+
passthrough :generated_at
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
# Location/tag field — mapped from __typename 'TagField'.
|
|
4
|
+
class TagField < DataField
|
|
5
|
+
passarray :locations # each: { id:, name: }
|
|
6
|
+
|
|
7
|
+
def location_ids
|
|
8
|
+
Array(locations).map { |l| l['id'] }.compact
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def location_ids=(ids)
|
|
12
|
+
doc['locations'] = Array(ids).map { |id_val| { 'id' => id_val } }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# NOTE: LocationFieldInput has NO location-value field — page locations are set at the
|
|
16
|
+
# PAGE level (UpdatePageInput.page.locations, via Interface::BasePage#location_ids=),
|
|
17
|
+
# not via the data field. So this field contributes no value to dataFields.updates;
|
|
18
|
+
# it inherits DataField#as_input (nil). location_ids/= stay as field-level read/staging.
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Base
|
|
5
|
+
module Page
|
|
6
|
+
# Base class for all data field types.
|
|
7
|
+
# Subclasses expose typed value accessors and serialise to DataFieldInput format.
|
|
8
|
+
class DataField < Logic::BaseModel
|
|
9
|
+
# Diff strategy for leaf data fields.
|
|
10
|
+
#
|
|
11
|
+
# A DataField's array attributes (`options`, `peopleIds`, `contractors`,
|
|
12
|
+
# `pages`, `fileContainers`, `items`, ...) are declared with `passarray`,
|
|
13
|
+
# which registers them as *cascaded* attributes. The default `DiffService`
|
|
14
|
+
# strips cascaded keys from the flat classic diff (`doc_with_non_cascaded_attributes`)
|
|
15
|
+
# on the assumption that a later `diff_reduce` pass re-adds them by cascading
|
|
16
|
+
# into nested `GraphQL::Model` children. DataField arrays are plain hashes /
|
|
17
|
+
# strings, not `GraphQL::Model` objects, so that re-add never happens and the
|
|
18
|
+
# array change becomes invisible to the diff (scalar `passthrough` fields are
|
|
19
|
+
# unaffected). For a leaf model we want every doc key diffed inline, so this
|
|
20
|
+
# service keeps cascaded keys in place.
|
|
21
|
+
class LeafDiffService < Ecoportal::API::Common::GraphQL::Model::Diffable::DiffService
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
# Keep all doc keys: leaf-field arrays are data, not nested models.
|
|
25
|
+
def doc_with_non_cascaded_attributes(json)
|
|
26
|
+
json
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
DIFF_CLASS = LeafDiffService
|
|
31
|
+
# Map GraphQL __typename values to subclass names.
|
|
32
|
+
TYPE_MAP = {
|
|
33
|
+
'PlainText' => 'PlainText',
|
|
34
|
+
'RichText' => 'RichText',
|
|
35
|
+
'Date' => 'DateField',
|
|
36
|
+
'Number' => 'Number',
|
|
37
|
+
'Gauge' => 'Gauge',
|
|
38
|
+
'People' => 'People',
|
|
39
|
+
'Select' => 'Select',
|
|
40
|
+
'Checklist' => 'Checklist',
|
|
41
|
+
'TagField' => 'TagField',
|
|
42
|
+
'Geo' => 'Geo',
|
|
43
|
+
'Signature' => 'Signature',
|
|
44
|
+
'ContractorEntities' => 'ContractorEntities',
|
|
45
|
+
'CrossReference' => 'CrossReference',
|
|
46
|
+
'ImageGallery' => 'ImageGallery',
|
|
47
|
+
'File' => 'FileField',
|
|
48
|
+
'Mailbox' => 'Mailbox',
|
|
49
|
+
'ActionsList' => 'ActionsList',
|
|
50
|
+
'Law' => 'Law',
|
|
51
|
+
'AiSummary' => 'AiSummary',
|
|
52
|
+
'Table' => 'Table',
|
|
53
|
+
'SmartFill' => 'SmartFill'
|
|
54
|
+
}.freeze
|
|
55
|
+
|
|
56
|
+
passkey :id
|
|
57
|
+
passthrough :label, :deindex
|
|
58
|
+
# __typename is stored under the 'type' key after mapping
|
|
59
|
+
passthrough :type
|
|
60
|
+
|
|
61
|
+
class << self
|
|
62
|
+
# Build the correct subclass from a raw field doc.
|
|
63
|
+
def from_doc(raw_doc)
|
|
64
|
+
type = raw_doc.is_a?(Hash) ? (raw_doc['__typename'] || raw_doc['type']) : nil
|
|
65
|
+
subname = TYPE_MAP[type]
|
|
66
|
+
klass = subname ? const_get(subname) : self
|
|
67
|
+
klass.new(raw_doc)
|
|
68
|
+
rescue NameError
|
|
69
|
+
new(raw_doc)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def initialize(raw_doc = {})
|
|
74
|
+
# Normalise __typename → type for passthrough accessor
|
|
75
|
+
raw_doc = raw_doc.dup if raw_doc.is_a?(Hash)
|
|
76
|
+
raw_doc['type'] ||= raw_doc['__typename'] if raw_doc.is_a?(Hash)
|
|
77
|
+
super
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# DataField is a leaf model: it has no nested GraphQL::Model children.
|
|
81
|
+
# flat: true skips diff_reduce — required here, since diff_reduce would
|
|
82
|
+
# dig_delete! the (cascaded) array keys and never re-add them. The flat
|
|
83
|
+
# classic diff still sees those keys because LeafDiffService keeps them.
|
|
84
|
+
def dirty?
|
|
85
|
+
super(flat: true)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Produces the DataFieldInput hash for this field.
|
|
89
|
+
# Returns nil if the field has not been modified.
|
|
90
|
+
# Subclasses override to produce typed payloads.
|
|
91
|
+
def as_input
|
|
92
|
+
nil
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
private
|
|
96
|
+
|
|
97
|
+
# Coerce a value to Float for numeric fields (Number, Gauge), treating a BLANK
|
|
98
|
+
# (nil / empty / whitespace-only string) as nil — NOT 0.0. Ruby's `"".to_f` is 0.0,
|
|
99
|
+
# so a naive `numeric&.to_f` silently wrote a real zero whenever a CSV cell was an
|
|
100
|
+
# empty string (Eco::CSV keeps quoted-empty `""` as "", not nil). A genuine number,
|
|
101
|
+
# or a numeric string like "0" / "15", still becomes a Float. Shared here so Number
|
|
102
|
+
# and Gauge cannot drift apart.
|
|
103
|
+
def numeric_or_nil(value)
|
|
104
|
+
return value.to_f if value.is_a?(Numeric)
|
|
105
|
+
|
|
106
|
+
str = value.to_s.strip
|
|
107
|
+
str.empty? ? nil : str.to_f
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
require_relative 'data_field/plain_text'
|
|
117
|
+
require_relative 'data_field/rich_text'
|
|
118
|
+
require_relative 'data_field/date_field'
|
|
119
|
+
require_relative 'data_field/number'
|
|
120
|
+
require_relative 'data_field/gauge'
|
|
121
|
+
require_relative 'data_field/people'
|
|
122
|
+
require_relative 'data_field/select'
|
|
123
|
+
require_relative 'data_field/checklist'
|
|
124
|
+
require_relative 'data_field/tag_field'
|
|
125
|
+
require_relative 'data_field/geo'
|
|
126
|
+
require_relative 'data_field/signature'
|
|
127
|
+
require_relative 'data_field/contractor_entities'
|
|
128
|
+
require_relative 'data_field/cross_reference'
|
|
129
|
+
require_relative 'data_field/image_gallery'
|
|
130
|
+
require_relative 'data_field/file_field'
|
|
131
|
+
require_relative 'data_field/mailbox'
|
|
132
|
+
require_relative 'data_field/actions_list'
|
|
133
|
+
require_relative 'data_field/law'
|
|
134
|
+
require_relative 'data_field/ai_summary'
|
|
135
|
+
require_relative 'data_field/table'
|
|
136
|
+
require_relative 'data_field/smart_fill'
|
|
137
|
+
require_relative 'data_field/collection'
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Base
|
|
5
|
+
module Page
|
|
6
|
+
class Phased
|
|
7
|
+
# Model for a single stage on a PhasedPage.
|
|
8
|
+
# Fields match those returned by the stageAttrs fragment in CommonPageUnion.
|
|
9
|
+
class Stage < Logic::BaseModel
|
|
10
|
+
passkey :id
|
|
11
|
+
passthrough :name, :ordering, :state
|
|
12
|
+
passboolean :active, :started
|
|
13
|
+
|
|
14
|
+
class_resolver :callback_type_class, 'Ecoportal::API::GraphQL::Base::PagesWorkflow::CallbackType'
|
|
15
|
+
|
|
16
|
+
# Injected by Model::Page::Phased so this stage's #components returns the page's
|
|
17
|
+
# canonical field objects (filtered to this stage) rather than fresh dups.
|
|
18
|
+
attr_writer :page_field_collection
|
|
19
|
+
|
|
20
|
+
def workflow_callbacks
|
|
21
|
+
@workflow_callbacks ||= Array(doc['workflowCallbacks'] || []).map { |cb| callback_type_class.from_doc(cb) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Predicate aliases — eco-helpers scripts call stage.active? / stage.started?
|
|
25
|
+
def active?
|
|
26
|
+
!!doc['active']
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def started?
|
|
30
|
+
!!doc['started']
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Sections in this stage as a SectionCollection.
|
|
34
|
+
def sections
|
|
35
|
+
@sections ||= SectionCollection.from_doc(doc['sections'] || [])
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# All data fields across all sections in this stage (v2 compat: stage.components).
|
|
39
|
+
# If the parent page injected its canonical field_collection, return THOSE field
|
|
40
|
+
# objects (filtered to this stage by id) so mutations made via the stage are the
|
|
41
|
+
# same objects the page serialises in data_fields_updates. Else build from docs.
|
|
42
|
+
def components
|
|
43
|
+
@components ||= if @page_field_collection
|
|
44
|
+
ids = stage_field_ids
|
|
45
|
+
DataField::Collection.new(@page_field_collection.select { |f| ids.include?(f.id) })
|
|
46
|
+
else
|
|
47
|
+
sections.components
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Field ids belonging to this stage (across its sections' data/left/right fields).
|
|
52
|
+
def stage_field_ids
|
|
53
|
+
(doc['sections'] || []).flat_map do |sec|
|
|
54
|
+
(sec['dataFields'] || []) + (sec['leftDataFields'] || []) + (sec['rightDataFields'] || [])
|
|
55
|
+
end.map { |f| f['id'] }.compact
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Hash-style access to raw doc — for backwards-compatible scripts.
|
|
59
|
+
def [](key)
|
|
60
|
+
doc[key.to_s]
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Base
|
|
5
|
+
module Page
|
|
6
|
+
# Wraps a SectionUnion doc (ContentSection or SplitSection).
|
|
7
|
+
# Provides access to heading, type, and data fields within the section.
|
|
8
|
+
class Section < Logic::BaseModel
|
|
9
|
+
read_only!
|
|
10
|
+
|
|
11
|
+
passkey :id
|
|
12
|
+
passthrough :heading
|
|
13
|
+
|
|
14
|
+
# __typename normalised to 'type' during initialisation
|
|
15
|
+
passthrough :type
|
|
16
|
+
|
|
17
|
+
def initialize(raw_doc = {})
|
|
18
|
+
raw_doc = raw_doc.dup if raw_doc.is_a?(Hash)
|
|
19
|
+
raw_doc['type'] ||= raw_doc['__typename'] if raw_doc.is_a?(Hash)
|
|
20
|
+
super
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# All data fields in this section.
|
|
24
|
+
# ContentSection → dataFields
|
|
25
|
+
# SplitSection → leftDataFields + rightDataFields (merged)
|
|
26
|
+
def components
|
|
27
|
+
all = (doc['dataFields'] || []) +
|
|
28
|
+
(doc['leftDataFields'] || []) +
|
|
29
|
+
(doc['rightDataFields'] || [])
|
|
30
|
+
DataField::Collection.from_doc(all)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# v2 compat alias
|
|
34
|
+
alias_method :data_fields, :components
|
|
35
|
+
|
|
36
|
+
def content_section?
|
|
37
|
+
type.to_s == 'ContentSection'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def split_section?
|
|
41
|
+
type.to_s == 'SplitSection'
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|