lcp 0.1.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 +7 -0
- data/.claude/skills/lcp-custom-field/SKILL.md +205 -0
- data/.claude/skills/lcp-getting-started/SKILL.md +332 -0
- data/.claude/skills/lcp-host-binding/SKILL.md +287 -0
- data/.claude/skills/lcp-model/SKILL.md +185 -0
- data/.claude/skills/lcp-permissions/SKILL.md +176 -0
- data/.claude/skills/lcp-presenter/SKILL.md +194 -0
- data/.claude/skills/lcp-workflow/SKILL.md +281 -0
- data/CHANGELOG.md +69 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +17 -0
- data/app/assets/javascripts/lcp_ruby/application.js +58 -0
- data/app/assets/javascripts/lcp_ruby/controllers/advanced_filter_controller.js +1521 -0
- data/app/assets/javascripts/lcp_ruby/controllers/approval_actions_controller.js +24 -0
- data/app/assets/javascripts/lcp_ruby/controllers/array_input_controller.js +156 -0
- data/app/assets/javascripts/lcp_ruby/controllers/batch_select_controller.js +405 -0
- data/app/assets/javascripts/lcp_ruby/controllers/cascading_selects_controller.js +436 -0
- data/app/assets/javascripts/lcp_ruby/controllers/char_counter_controller.js +28 -0
- data/app/assets/javascripts/lcp_ruby/controllers/clipboard_controller.js +62 -0
- data/app/assets/javascripts/lcp_ruby/controllers/conditional_rendering_controller.js +178 -0
- data/app/assets/javascripts/lcp_ruby/controllers/confirm_dialog_controller.js +131 -0
- data/app/assets/javascripts/lcp_ruby/controllers/custom_fields_manage_controller.js +80 -0
- data/app/assets/javascripts/lcp_ruby/controllers/dialog_controller.js +421 -0
- data/app/assets/javascripts/lcp_ruby/controllers/dialog_nested_controller.js +182 -0
- data/app/assets/javascripts/lcp_ruby/controllers/direct_upload_controller.js +100 -0
- data/app/assets/javascripts/lcp_ruby/controllers/drawer_controller.js +205 -0
- data/app/assets/javascripts/lcp_ruby/controllers/dropdown_controller.js +160 -0
- data/app/assets/javascripts/lcp_ruby/controllers/export_dialog_controller.js +15 -0
- data/app/assets/javascripts/lcp_ruby/controllers/field_picker_controller.js +290 -0
- data/app/assets/javascripts/lcp_ruby/controllers/file_upload_controller.js +135 -0
- data/app/assets/javascripts/lcp_ruby/controllers/filter_auto_submit_controller.js +46 -0
- data/app/assets/javascripts/lcp_ruby/controllers/filter_dirty_controller.js +94 -0
- data/app/assets/javascripts/lcp_ruby/controllers/form_actions_controller.js +68 -0
- data/app/assets/javascripts/lcp_ruby/controllers/form_handling_controller.js +67 -0
- data/app/assets/javascripts/lcp_ruby/controllers/import_dialog_controller.js +142 -0
- data/app/assets/javascripts/lcp_ruby/controllers/import_mapper_controller.js +322 -0
- data/app/assets/javascripts/lcp_ruby/controllers/index_sortable_controller.js +388 -0
- data/app/assets/javascripts/lcp_ruby/controllers/inline_create_controller.js +137 -0
- data/app/assets/javascripts/lcp_ruby/controllers/kanban_board_controller.js +290 -0
- data/app/assets/javascripts/lcp_ruby/controllers/menu_controller.js +19 -0
- data/app/assets/javascripts/lcp_ruby/controllers/nested_forms_controller.js +261 -0
- data/app/assets/javascripts/lcp_ruby/controllers/responsive_sidebar_controller.js +161 -0
- data/app/assets/javascripts/lcp_ruby/controllers/responsive_top_nav_controller.js +394 -0
- data/app/assets/javascripts/lcp_ruby/controllers/saved_filters_controller.js +129 -0
- data/app/assets/javascripts/lcp_ruby/controllers/search_controller.js +82 -0
- data/app/assets/javascripts/lcp_ruby/controllers/selection_controller.js +33 -0
- data/app/assets/javascripts/lcp_ruby/controllers/sidebar_controller.js +83 -0
- data/app/assets/javascripts/lcp_ruby/controllers/sidebar_toggle_controller.js +66 -0
- data/app/assets/javascripts/lcp_ruby/controllers/slider_controller.js +26 -0
- data/app/assets/javascripts/lcp_ruby/controllers/submenu_controller.js +55 -0
- data/app/assets/javascripts/lcp_ruby/controllers/tom_select_controller.js +168 -0
- data/app/assets/javascripts/lcp_ruby/controllers/tree_index_controller.js +106 -0
- data/app/assets/javascripts/lcp_ruby/controllers/tree_reparent_controller.js +182 -0
- data/app/assets/javascripts/lcp_ruby/controllers/tree_select_controller.js +119 -0
- data/app/assets/javascripts/lcp_ruby/controllers/ui_components_controller.js +135 -0
- data/app/assets/javascripts/lcp_ruby/controllers/zone_tabs_controller.js +66 -0
- data/app/assets/javascripts/lcp_ruby/dev_toolbar.js +494 -0
- data/app/assets/javascripts/lcp_ruby/i18n.js.erb +29 -0
- data/app/assets/javascripts/lcp_ruby/lucide_init.js +24 -0
- data/app/assets/javascripts/lcp_ruby/stimulus_bootstrap.js +7 -0
- data/app/assets/javascripts/lcp_ruby/utils.js +119 -0
- data/app/assets/javascripts/lcp_ruby/xhr_fetch.js +411 -0
- data/app/assets/stylesheets/lcp_ruby/application.css +1940 -0
- data/app/assets/stylesheets/lcp_ruby/dev_toolbar.css +355 -0
- data/app/controllers/concerns/lcp_ruby/dialog_rendering.rb +167 -0
- data/app/controllers/concerns/lcp_ruby/form_action_execution.rb +249 -0
- data/app/controllers/concerns/lcp_ruby/page_authorization.rb +105 -0
- data/app/controllers/concerns/lcp_ruby/zone_resolution.rb +199 -0
- data/app/controllers/lcp_ruby/actions_controller.rb +481 -0
- data/app/controllers/lcp_ruby/application_controller.rb +59 -0
- data/app/controllers/lcp_ruby/approval_tasks_controller.rb +98 -0
- data/app/controllers/lcp_ruby/auth/base_controller.rb +58 -0
- data/app/controllers/lcp_ruby/auth/callbacks_controller.rb +103 -0
- data/app/controllers/lcp_ruby/auth/passwords_controller.rb +15 -0
- data/app/controllers/lcp_ruby/auth/registrations_controller.rb +37 -0
- data/app/controllers/lcp_ruby/auth/sessions_controller.rb +112 -0
- data/app/controllers/lcp_ruby/custom_fields_controller.rb +370 -0
- data/app/controllers/lcp_ruby/dev_toolbar_controller.rb +197 -0
- data/app/controllers/lcp_ruby/dialogs_controller.rb +199 -0
- data/app/controllers/lcp_ruby/health_controller.rb +23 -0
- data/app/controllers/lcp_ruby/impersonation_controller.rb +32 -0
- data/app/controllers/lcp_ruby/landing_controller.rb +49 -0
- data/app/controllers/lcp_ruby/metrics_controller.rb +17 -0
- data/app/controllers/lcp_ruby/resources_controller.rb +2218 -0
- data/app/controllers/lcp_ruby/saved_filters_controller.rb +221 -0
- data/app/helpers/lcp_ruby/condition_helper.rb +87 -0
- data/app/helpers/lcp_ruby/dashboard_helper.rb +45 -0
- data/app/helpers/lcp_ruby/dev_toolbar_helper.rb +17 -0
- data/app/helpers/lcp_ruby/dialog_helper.rb +27 -0
- data/app/helpers/lcp_ruby/display/card_helper.rb +317 -0
- data/app/helpers/lcp_ruby/display_helper.rb +63 -0
- data/app/helpers/lcp_ruby/display_template_helper.rb +100 -0
- data/app/helpers/lcp_ruby/form_helper.rb +1020 -0
- data/app/helpers/lcp_ruby/grouped_query_helper.rb +107 -0
- data/app/helpers/lcp_ruby/i18n_payload_helper.rb +197 -0
- data/app/helpers/lcp_ruby/layout_helper.rb +832 -0
- data/app/helpers/lcp_ruby/link_through_helper.rb +29 -0
- data/app/helpers/lcp_ruby/oidc_button_helper.rb +59 -0
- data/app/helpers/lcp_ruby/search_helper.rb +31 -0
- data/app/helpers/lcp_ruby/tree_helper.rb +140 -0
- data/app/helpers/lcp_ruby/view_slot_helper.rb +33 -0
- data/app/models/lcp_ruby/user.rb +61 -0
- data/app/views/layouts/lcp_ruby/application.html.erb +168 -0
- data/app/views/layouts/lcp_ruby/auth.html.erb +170 -0
- data/app/views/lcp_ruby/auth/callbacks/failure.html.erb +18 -0
- data/app/views/lcp_ruby/auth/mailer/reset_password_instructions.html.erb +9 -0
- data/app/views/lcp_ruby/auth/passwords/edit.html.erb +34 -0
- data/app/views/lcp_ruby/auth/passwords/new.html.erb +24 -0
- data/app/views/lcp_ruby/auth/registrations/edit.html.erb +48 -0
- data/app/views/lcp_ruby/auth/registrations/new.html.erb +46 -0
- data/app/views/lcp_ruby/auth/sessions/new.html.erb +55 -0
- data/app/views/lcp_ruby/auth/shared/_links.html.erb +13 -0
- data/app/views/lcp_ruby/custom_fields/_manage_row.html.erb +82 -0
- data/app/views/lcp_ruby/custom_fields/manage.html.erb +47 -0
- data/app/views/lcp_ruby/dialogs/_dialog_composite_frame.html.erb +87 -0
- data/app/views/lcp_ruby/dialogs/_dialog_frame.html.erb +60 -0
- data/app/views/lcp_ruby/dialogs/_dialog_show_frame.html.erb +14 -0
- data/app/views/lcp_ruby/dialogs/_show_secret.html.erb +10 -0
- data/app/views/lcp_ruby/dialogs/_success.html.erb +1 -0
- data/app/views/lcp_ruby/errors/not_found.html.erb +5 -0
- data/app/views/lcp_ruby/menu_renderers/_user_menu.html.erb +51 -0
- data/app/views/lcp_ruby/menu_renderers/_user_menu_panel.html.erb +32 -0
- data/app/views/lcp_ruby/navigation/_auto_top.html.erb +16 -0
- data/app/views/lcp_ruby/navigation/_both_sidebar.html.erb +1 -0
- data/app/views/lcp_ruby/navigation/_both_top.html.erb +1 -0
- data/app/views/lcp_ruby/navigation/_impersonation_banner.html.erb +14 -0
- data/app/views/lcp_ruby/navigation/_item_content.html.erb +23 -0
- data/app/views/lcp_ruby/navigation/_link_or_button.html.erb +51 -0
- data/app/views/lcp_ruby/navigation/_mobile_header.html.erb +23 -0
- data/app/views/lcp_ruby/navigation/_panel_item.html.erb +32 -0
- data/app/views/lcp_ruby/navigation/_sidebar.html.erb +38 -0
- data/app/views/lcp_ruby/navigation/_sidebar_item.html.erb +38 -0
- data/app/views/lcp_ruby/navigation/_sidebar_toggle.html.erb +32 -0
- data/app/views/lcp_ruby/navigation/_top.html.erb +26 -0
- data/app/views/lcp_ruby/navigation/_top_item.html.erb +112 -0
- data/app/views/lcp_ruby/navigation/_widget_item.html.erb +14 -0
- data/app/views/lcp_ruby/resources/_action_button.html.erb +138 -0
- data/app/views/lcp_ruby/resources/_advanced_filter.html.erb +55 -0
- data/app/views/lcp_ruby/resources/_api_status_banner.html.erb +11 -0
- data/app/views/lcp_ruby/resources/_association_list.html.erb +132 -0
- data/app/views/lcp_ruby/resources/_audit_history.html.erb +66 -0
- data/app/views/lcp_ruby/resources/_batch_toolbar.html.erb +54 -0
- data/app/views/lcp_ruby/resources/_filter_form.html.erb +57 -0
- data/app/views/lcp_ruby/resources/_form.html.erb +73 -0
- data/app/views/lcp_ruby/resources/_form_action_button.html.erb +20 -0
- data/app/views/lcp_ruby/resources/_form_action_dropdown_item.html.erb +17 -0
- data/app/views/lcp_ruby/resources/_form_actions.html.erb +38 -0
- data/app/views/lcp_ruby/resources/_form_section.html.erb +235 -0
- data/app/views/lcp_ruby/resources/_grid_page.html.erb +17 -0
- data/app/views/lcp_ruby/resources/_grouped_index.html.erb +61 -0
- data/app/views/lcp_ruby/resources/_inline_create_form.html.erb +50 -0
- data/app/views/lcp_ruby/resources/_json_items_list.html.erb +77 -0
- data/app/views/lcp_ruby/resources/_json_nested_fields.html.erb +30 -0
- data/app/views/lcp_ruby/resources/_kanban_card.html.erb +31 -0
- data/app/views/lcp_ruby/resources/_kanban_card_body.html.erb +17 -0
- data/app/views/lcp_ruby/resources/_kanban_column.html.erb +33 -0
- data/app/views/lcp_ruby/resources/_kanban_column_header.html.erb +10 -0
- data/app/views/lcp_ruby/resources/_kanban_index.html.erb +17 -0
- data/app/views/lcp_ruby/resources/_nested_field_cell.html.erb +33 -0
- data/app/views/lcp_ruby/resources/_nested_fields.html.erb +26 -0
- data/app/views/lcp_ruby/resources/_nested_row_content.html.erb +65 -0
- data/app/views/lcp_ruby/resources/_scope_filters.html.erb +71 -0
- data/app/views/lcp_ruby/resources/_semantic_index_page.html.erb +162 -0
- data/app/views/lcp_ruby/resources/_semantic_page.html.erb +121 -0
- data/app/views/lcp_ruby/resources/_show_sections.html.erb +128 -0
- data/app/views/lcp_ruby/resources/_table_index.html.erb +169 -0
- data/app/views/lcp_ruby/resources/_tile_card.html.erb +26 -0
- data/app/views/lcp_ruby/resources/_tile_card_body.html.erb +19 -0
- data/app/views/lcp_ruby/resources/_tiles_index.html.erb +15 -0
- data/app/views/lcp_ruby/resources/_transition_button.html.erb +33 -0
- data/app/views/lcp_ruby/resources/_tree_index.html.erb +61 -0
- data/app/views/lcp_ruby/resources/_view_switcher.html.erb +24 -0
- data/app/views/lcp_ruby/resources/edit.html.erb +9 -0
- data/app/views/lcp_ruby/resources/index.html.erb +80 -0
- data/app/views/lcp_ruby/resources/new.html.erb +9 -0
- data/app/views/lcp_ruby/resources/show.html.erb +37 -0
- data/app/views/lcp_ruby/shared/_breadcrumbs.html.erb +15 -0
- data/app/views/lcp_ruby/shared/_custom_partial_error.html.erb +3 -0
- data/app/views/lcp_ruby/shared/_flash_messages.html.erb +19 -0
- data/app/views/lcp_ruby/slots/index/_advanced_filter.html.erb +3 -0
- data/app/views/lcp_ruby/slots/index/_collection_actions.html.erb +50 -0
- data/app/views/lcp_ruby/slots/index/_manage_all.html.erb +4 -0
- data/app/views/lcp_ruby/slots/index/_pagination_footer.html.erb +71 -0
- data/app/views/lcp_ruby/slots/index/_predefined_filters.html.erb +8 -0
- data/app/views/lcp_ruby/slots/index/_saved_filters.html.erb +87 -0
- data/app/views/lcp_ruby/slots/index/_search.html.erb +52 -0
- data/app/views/lcp_ruby/slots/index/_search_parameter.html.erb +72 -0
- data/app/views/lcp_ruby/slots/index/_sort_dropdown.html.erb +21 -0
- data/app/views/lcp_ruby/slots/index/_summary_bar.html.erb +22 -0
- data/app/views/lcp_ruby/slots/index/_view_switcher.html.erb +1 -0
- data/app/views/lcp_ruby/slots/show/_approval_status.html.erb +8 -0
- data/app/views/lcp_ruby/slots/show/_back_to_list.html.erb +1 -0
- data/app/views/lcp_ruby/slots/show/_copy_url.html.erb +5 -0
- data/app/views/lcp_ruby/slots/show/_single_actions.html.erb +4 -0
- data/app/views/lcp_ruby/slots/show/_view_switcher.html.erb +1 -0
- data/app/views/lcp_ruby/widgets/_approval_status.html.erb +150 -0
- data/app/views/lcp_ruby/widgets/_chart.html.erb +36 -0
- data/app/views/lcp_ruby/widgets/_embed.html.erb +13 -0
- data/app/views/lcp_ruby/widgets/_kpi_card.html.erb +29 -0
- data/app/views/lcp_ruby/widgets/_list.html.erb +17 -0
- data/app/views/lcp_ruby/widgets/_presenter_zone.html.erb +84 -0
- data/app/views/lcp_ruby/widgets/_record_show_zone.html.erb +11 -0
- data/app/views/lcp_ruby/widgets/_text.html.erb +3 -0
- data/app/views/lcp_ruby/widgets/_workflow_graph.html.erb +32 -0
- data/app/views/lcp_ruby/zones/_custom_zone.html.erb +16 -0
- data/app/views/lcp_ruby/zones/_error.html.erb +5 -0
- data/app/views/lcp_ruby/zones/_zone_frame.html.erb +25 -0
- data/app/views/lcp_ruby/zones/_zone_search.html.erb +20 -0
- data/config/locales/cs.yml +859 -0
- data/config/locales/en.yml +731 -0
- data/config/routes.rb +119 -0
- data/docs/README.md +225 -0
- data/docs/architecture.md +212 -0
- data/docs/feature-catalog.md +763 -0
- data/docs/feature-catalog.yml +20911 -0
- data/docs/getting-started.md +1187 -0
- data/docs/guides/action-buttons.md +537 -0
- data/docs/guides/adding-locale.md +353 -0
- data/docs/guides/api-backed-models.md +478 -0
- data/docs/guides/attachments.md +399 -0
- data/docs/guides/auditing.md +333 -0
- data/docs/guides/batch-actions.md +342 -0
- data/docs/guides/composite-pages.md +1290 -0
- data/docs/guides/computed-fields.md +350 -0
- data/docs/guides/conditional-rendering.md +832 -0
- data/docs/guides/custom-actions.md +238 -0
- data/docs/guides/custom-fields.md +439 -0
- data/docs/guides/custom-renderers.md +234 -0
- data/docs/guides/custom-types.md +274 -0
- data/docs/guides/dashboards.md +504 -0
- data/docs/guides/debugging/README.md +38 -0
- data/docs/guides/debugging/controllers.md +147 -0
- data/docs/guides/debugging/data.md +165 -0
- data/docs/guides/debugging/metadata.md +143 -0
- data/docs/guides/debugging/models.md +126 -0
- data/docs/guides/debugging/permissions.md +147 -0
- data/docs/guides/debugging/presenters.md +151 -0
- data/docs/guides/developer-tools.md +418 -0
- data/docs/guides/dialogs.md +392 -0
- data/docs/guides/display-types.md +1430 -0
- data/docs/guides/eager-loading.md +230 -0
- data/docs/guides/event-handlers.md +135 -0
- data/docs/guides/export.md +305 -0
- data/docs/guides/extensibility.md +761 -0
- data/docs/guides/groups.md +220 -0
- data/docs/guides/hierarchical-authorization.md +427 -0
- data/docs/guides/host-application.md +556 -0
- data/docs/guides/host-controller-integration.md +473 -0
- data/docs/guides/impersonation.md +83 -0
- data/docs/guides/import.md +165 -0
- data/docs/guides/inherited-permissions.md +459 -0
- data/docs/guides/menu.md +373 -0
- data/docs/guides/monitoring.md +254 -0
- data/docs/guides/oidc-setup.md +399 -0
- data/docs/guides/permission-source.md +205 -0
- data/docs/guides/permissions.md +364 -0
- data/docs/guides/presenters.md +2324 -0
- data/docs/guides/record-aliases.md +303 -0
- data/docs/guides/rendering-extension-points.md +280 -0
- data/docs/guides/role-source.md +288 -0
- data/docs/guides/selectbox.md +516 -0
- data/docs/guides/sequences.md +291 -0
- data/docs/guides/soft-delete.md +460 -0
- data/docs/guides/theming.md +129 -0
- data/docs/guides/tiles.md +383 -0
- data/docs/guides/tree-structures.md +297 -0
- data/docs/guides/userstamps.md +288 -0
- data/docs/guides/view-groups.md +259 -0
- data/docs/guides/view-slots.md +352 -0
- data/docs/guides/virtual-columns.md +810 -0
- data/docs/guides/workflow.md +692 -0
- data/docs/reference/api-backed-models.md +404 -0
- data/docs/reference/api-tokens.md +128 -0
- data/docs/reference/auditing.md +277 -0
- data/docs/reference/boot_lifecycle.md +188 -0
- data/docs/reference/cascading_selects.md +189 -0
- data/docs/reference/condition-operators.md +445 -0
- data/docs/reference/custom-fields.md +483 -0
- data/docs/reference/dialogs.md +286 -0
- data/docs/reference/doctor.md +168 -0
- data/docs/reference/dynamic-references.md +95 -0
- data/docs/reference/eager-loading.md +192 -0
- data/docs/reference/engine-configuration.md +989 -0
- data/docs/reference/export.md +309 -0
- data/docs/reference/forms.md +68 -0
- data/docs/reference/groups.md +176 -0
- data/docs/reference/host-controller-integration.md +342 -0
- data/docs/reference/i18n.md +497 -0
- data/docs/reference/i18n_check.md +351 -0
- data/docs/reference/import.md +260 -0
- data/docs/reference/invariant_check.md +216 -0
- data/docs/reference/menu.md +985 -0
- data/docs/reference/model-dsl.md +1157 -0
- data/docs/reference/models.md +2972 -0
- data/docs/reference/monitoring.md +222 -0
- data/docs/reference/oidc-bearer.md +269 -0
- data/docs/reference/oidc.md +407 -0
- data/docs/reference/page_filters.md +328 -0
- data/docs/reference/pages.md +1375 -0
- data/docs/reference/permission-source.md +185 -0
- data/docs/reference/permissions.md +715 -0
- data/docs/reference/presenter-dsl.md +1719 -0
- data/docs/reference/presenters.md +3627 -0
- data/docs/reference/role-source.md +227 -0
- data/docs/reference/theme-variables.md +139 -0
- data/docs/reference/tree-structures.md +374 -0
- data/docs/reference/types.md +470 -0
- data/docs/reference/view-groups.md +347 -0
- data/docs/reference/view-slots.md +228 -0
- data/docs/reference/virtual_forms.md +196 -0
- data/docs/reference/workflow-approvals.md +387 -0
- data/docs/reference/workflow.md +651 -0
- data/examples/crm/Gemfile +9 -0
- data/examples/crm/Gemfile.lock +417 -0
- data/examples/crm/Rakefile +2 -0
- data/examples/crm/app/actions/activity/complete.rb +20 -0
- data/examples/crm/app/actions/deal/close_won.rb +20 -0
- data/examples/crm/app/assets/config/manifest.js +3 -0
- data/examples/crm/app/controllers/application_controller.rb +9 -0
- data/examples/crm/app/event_handlers/deal/on_stage_change.rb +17 -0
- data/examples/crm/app/lcp_services/computed/weighted_deal_value.rb +13 -0
- data/examples/crm/app/lcp_services/data_providers/active_contacts_count.rb +14 -0
- data/examples/crm/app/lcp_services/data_providers/open_deals_count.rb +14 -0
- data/examples/crm/app/lcp_services/data_providers/pending_activities_count.rb +15 -0
- data/examples/crm/app/lcp_services/data_providers/pipeline_value.rb +27 -0
- data/examples/crm/app/lcp_services/data_providers/won_deals_count.rb +14 -0
- data/examples/crm/app/lcp_services/defaults/thirty_days_out.rb +11 -0
- data/examples/crm/app/lcp_services/transforms/titlecase.rb +11 -0
- data/examples/crm/app/lcp_services/validators/deal_credit_limit.rb +19 -0
- data/examples/crm/app/lcp_services/validators/deal_documents_required.rb +17 -0
- data/examples/crm/app/renderers/conditional_badge.rb +39 -0
- data/examples/crm/bin/rails +4 -0
- data/examples/crm/bin/rake +4 -0
- data/examples/crm/config/application.rb +31 -0
- data/examples/crm/config/boot.rb +2 -0
- data/examples/crm/config/database.yml +12 -0
- data/examples/crm/config/environment.rb +2 -0
- data/examples/crm/config/initializers/lcp_ruby.rb +45 -0
- data/examples/crm/config/lcp_ruby/menu.yml +53 -0
- data/examples/crm/config/lcp_ruby/models/activity.rb +43 -0
- data/examples/crm/config/lcp_ruby/models/city.rb +19 -0
- data/examples/crm/config/lcp_ruby/models/company.rb +65 -0
- data/examples/crm/config/lcp_ruby/models/contact.rb +62 -0
- data/examples/crm/config/lcp_ruby/models/country.rb +22 -0
- data/examples/crm/config/lcp_ruby/models/custom_field_definition.rb +60 -0
- data/examples/crm/config/lcp_ruby/models/deal.rb +85 -0
- data/examples/crm/config/lcp_ruby/models/deal_category.rb +15 -0
- data/examples/crm/config/lcp_ruby/models/gapfree_sequence.rb +17 -0
- data/examples/crm/config/lcp_ruby/models/region.rb +15 -0
- data/examples/crm/config/lcp_ruby/models/saved_filter.rb +50 -0
- data/examples/crm/config/lcp_ruby/pages/activity_quick_log.yml +19 -0
- data/examples/crm/config/lcp_ruby/pages/company_detail.yml +127 -0
- data/examples/crm/config/lcp_ruby/pages/deals_overview.yml +65 -0
- data/examples/crm/config/lcp_ruby/permissions/activity.yml +40 -0
- data/examples/crm/config/lcp_ruby/permissions/custom_field_definition.yml +16 -0
- data/examples/crm/config/lcp_ruby/permissions/deal.yml +54 -0
- data/examples/crm/config/lcp_ruby/permissions/default.yml +16 -0
- data/examples/crm/config/lcp_ruby/permissions/gapfree_sequence.yml +6 -0
- data/examples/crm/config/lcp_ruby/permissions/saved_filter.yml +27 -0
- data/examples/crm/config/lcp_ruby/presenters/activity.rb +140 -0
- data/examples/crm/config/lcp_ruby/presenters/activity_quick_form.rb +36 -0
- data/examples/crm/config/lcp_ruby/presenters/activity_short.rb +16 -0
- data/examples/crm/config/lcp_ruby/presenters/activity_tiles.rb +35 -0
- data/examples/crm/config/lcp_ruby/presenters/city.rb +53 -0
- data/examples/crm/config/lcp_ruby/presenters/company.rb +147 -0
- data/examples/crm/config/lcp_ruby/presenters/company_activities_zone.rb +26 -0
- data/examples/crm/config/lcp_ruby/presenters/company_archive.rb +37 -0
- data/examples/crm/config/lcp_ruby/presenters/company_contacts_zone.rb +22 -0
- data/examples/crm/config/lcp_ruby/presenters/company_deals_zone.rb +36 -0
- data/examples/crm/config/lcp_ruby/presenters/company_short.rb +21 -0
- data/examples/crm/config/lcp_ruby/presenters/company_show_zone.rb +38 -0
- data/examples/crm/config/lcp_ruby/presenters/company_sidebar.rb +15 -0
- data/examples/crm/config/lcp_ruby/presenters/company_tiles.rb +35 -0
- data/examples/crm/config/lcp_ruby/presenters/contact.rb +120 -0
- data/examples/crm/config/lcp_ruby/presenters/contact_quick_form.rb +17 -0
- data/examples/crm/config/lcp_ruby/presenters/contact_short.rb +20 -0
- data/examples/crm/config/lcp_ruby/presenters/contact_tiles.rb +34 -0
- data/examples/crm/config/lcp_ruby/presenters/country.rb +44 -0
- data/examples/crm/config/lcp_ruby/presenters/custom_fields.rb +124 -0
- data/examples/crm/config/lcp_ruby/presenters/deal.rb +181 -0
- data/examples/crm/config/lcp_ruby/presenters/deal_category.rb +46 -0
- data/examples/crm/config/lcp_ruby/presenters/deal_overview.rb +6 -0
- data/examples/crm/config/lcp_ruby/presenters/deal_pipeline.rb +18 -0
- data/examples/crm/config/lcp_ruby/presenters/deal_short.rb +25 -0
- data/examples/crm/config/lcp_ruby/presenters/deal_tiles.rb +48 -0
- data/examples/crm/config/lcp_ruby/presenters/region.rb +42 -0
- data/examples/crm/config/lcp_ruby/presenters/save_filter_dialog.rb +17 -0
- data/examples/crm/config/lcp_ruby/presenters/saved_filters.rb +93 -0
- data/examples/crm/config/lcp_ruby/views/activities.yml +16 -0
- data/examples/crm/config/lcp_ruby/views/cities.yml +10 -0
- data/examples/crm/config/lcp_ruby/views/companies.yml +14 -0
- data/examples/crm/config/lcp_ruby/views/contacts.yml +16 -0
- data/examples/crm/config/lcp_ruby/views/countries.yml +8 -0
- data/examples/crm/config/lcp_ruby/views/custom_fields.rb +9 -0
- data/examples/crm/config/lcp_ruby/views/deal_categories.yml +8 -0
- data/examples/crm/config/lcp_ruby/views/deals.yml +19 -0
- data/examples/crm/config/lcp_ruby/views/pipeline.yml +10 -0
- data/examples/crm/config/lcp_ruby/views/regions.yml +10 -0
- data/examples/crm/config/lcp_ruby/views/saved_filters.yml +7 -0
- data/examples/crm/config/locales/cs.yml +338 -0
- data/examples/crm/config/locales/en.yml +353 -0
- data/examples/crm/config/routes.rb +4 -0
- data/examples/crm/config/storage.yml +3 -0
- data/examples/crm/config.ru +2 -0
- data/examples/crm/db/migrate/20260219104942_create_active_storage_tables.active_storage.rb +57 -0
- data/examples/crm/db/schema.rb +245 -0
- data/examples/crm/db/seeds.rb +1111 -0
- data/examples/crm/erd.md +163 -0
- data/examples/hr/Gemfile +9 -0
- data/examples/hr/Gemfile.lock +419 -0
- data/examples/hr/Rakefile +6 -0
- data/examples/hr/app/actions/asset/assign_asset.rb +20 -0
- data/examples/hr/app/actions/asset/return_asset.rb +20 -0
- data/examples/hr/app/actions/candidate/advance.rb +32 -0
- data/examples/hr/app/actions/candidate/hire.rb +20 -0
- data/examples/hr/app/actions/candidate/reject_candidate.rb +20 -0
- data/examples/hr/app/actions/expense_claim/approve.rb +21 -0
- data/examples/hr/app/actions/expense_claim/reject.rb +21 -0
- data/examples/hr/app/actions/expense_claim/submit.rb +20 -0
- data/examples/hr/app/actions/interview/complete_interview.rb +20 -0
- data/examples/hr/app/actions/leave_request/approve.rb +21 -0
- data/examples/hr/app/actions/leave_request/cancel.rb +20 -0
- data/examples/hr/app/actions/leave_request/reject.rb +21 -0
- data/examples/hr/app/assets/config/manifest.js +1 -0
- data/examples/hr/app/assets/stylesheets/application.css +10 -0
- data/examples/hr/app/condition_services/is_own_org_unit.rb +14 -0
- data/examples/hr/app/condition_services/is_own_record.rb +20 -0
- data/examples/hr/app/controllers/application_controller.rb +15 -0
- data/examples/hr/app/event_handlers/asset_assignment/on_create.rb +24 -0
- data/examples/hr/app/event_handlers/candidate/on_status_change.rb +18 -0
- data/examples/hr/app/event_handlers/leave_request/on_status_change.rb +45 -0
- data/examples/hr/app/helpers/application_helper.rb +2 -0
- data/examples/hr/app/javascript/application.js +1 -0
- data/examples/hr/app/jobs/application_job.rb +7 -0
- data/examples/hr/app/lcp_services/computed/employee_tenure.rb +28 -0
- data/examples/hr/app/lcp_services/computed/leave_remaining.rb +13 -0
- data/examples/hr/app/lcp_services/data_providers/headcount_text.rb +14 -0
- data/examples/hr/app/lcp_services/data_providers/open_positions_count.rb +14 -0
- data/examples/hr/app/lcp_services/data_providers/pending_expenses_count.rb +14 -0
- data/examples/hr/app/lcp_services/data_providers/pending_leaves_count.rb +14 -0
- data/examples/hr/app/lcp_services/defaults/current_year.rb +11 -0
- data/examples/hr/app/lcp_services/transforms/titlecase.rb +11 -0
- data/examples/hr/app/lcp_services/validators/expense_receipt_required.rb +17 -0
- data/examples/hr/app/lcp_services/validators/leave_balance_check.rb +37 -0
- data/examples/hr/app/models/application_record.rb +3 -0
- data/examples/hr/app/views/layouts/application.html.erb +29 -0
- data/examples/hr/app/views/pwa/manifest.json.erb +22 -0
- data/examples/hr/app/views/pwa/service-worker.js +26 -0
- data/examples/hr/bin/brakeman +7 -0
- data/examples/hr/bin/bundler-audit +6 -0
- data/examples/hr/bin/ci +6 -0
- data/examples/hr/bin/dev +2 -0
- data/examples/hr/bin/docker-entrypoint +8 -0
- data/examples/hr/bin/importmap +4 -0
- data/examples/hr/bin/jobs +6 -0
- data/examples/hr/bin/kamal +27 -0
- data/examples/hr/bin/rails +4 -0
- data/examples/hr/bin/rake +4 -0
- data/examples/hr/bin/rubocop +8 -0
- data/examples/hr/bin/setup +35 -0
- data/examples/hr/bin/thrust +5 -0
- data/examples/hr/config/application.rb +31 -0
- data/examples/hr/config/boot.rb +2 -0
- data/examples/hr/config/bundler-audit.yml +5 -0
- data/examples/hr/config/cache.yml +16 -0
- data/examples/hr/config/ci.rb +20 -0
- data/examples/hr/config/credentials.yml.enc +1 -0
- data/examples/hr/config/database.yml +36 -0
- data/examples/hr/config/deploy.yml +119 -0
- data/examples/hr/config/environment.rb +5 -0
- data/examples/hr/config/environments/development.rb +66 -0
- data/examples/hr/config/environments/production.rb +74 -0
- data/examples/hr/config/environments/test.rb +45 -0
- data/examples/hr/config/importmap.rb +3 -0
- data/examples/hr/config/initializers/assets.rb +7 -0
- data/examples/hr/config/initializers/content_security_policy.rb +29 -0
- data/examples/hr/config/initializers/filter_parameter_logging.rb +8 -0
- data/examples/hr/config/initializers/inflections.rb +16 -0
- data/examples/hr/config/initializers/lcp_ruby.rb +18 -0
- data/examples/hr/config/lcp_ruby/menu.yml +86 -0
- data/examples/hr/config/lcp_ruby/models/announcement.rb +33 -0
- data/examples/hr/config/lcp_ruby/models/asset.rb +73 -0
- data/examples/hr/config/lcp_ruby/models/asset_assignment.rb +39 -0
- data/examples/hr/config/lcp_ruby/models/audit_log.yml +57 -0
- data/examples/hr/config/lcp_ruby/models/candidate.rb +68 -0
- data/examples/hr/config/lcp_ruby/models/custom_field_definition.rb +60 -0
- data/examples/hr/config/lcp_ruby/models/dashboard.rb +17 -0
- data/examples/hr/config/lcp_ruby/models/document.rb +38 -0
- data/examples/hr/config/lcp_ruby/models/employee.rb +128 -0
- data/examples/hr/config/lcp_ruby/models/employee_skill.rb +29 -0
- data/examples/hr/config/lcp_ruby/models/expense_claim.rb +70 -0
- data/examples/hr/config/lcp_ruby/models/goal.rb +48 -0
- data/examples/hr/config/lcp_ruby/models/group.rb +37 -0
- data/examples/hr/config/lcp_ruby/models/group_membership.rb +26 -0
- data/examples/hr/config/lcp_ruby/models/interview.rb +54 -0
- data/examples/hr/config/lcp_ruby/models/job_posting.rb +67 -0
- data/examples/hr/config/lcp_ruby/models/leave_balance.rb +31 -0
- data/examples/hr/config/lcp_ruby/models/leave_request.rb +52 -0
- data/examples/hr/config/lcp_ruby/models/leave_type.rb +35 -0
- data/examples/hr/config/lcp_ruby/models/organization_unit.rb +42 -0
- data/examples/hr/config/lcp_ruby/models/performance_review.rb +59 -0
- data/examples/hr/config/lcp_ruby/models/position.rb +43 -0
- data/examples/hr/config/lcp_ruby/models/skill.rb +27 -0
- data/examples/hr/config/lcp_ruby/models/training_course.rb +53 -0
- data/examples/hr/config/lcp_ruby/models/training_enrollment.rb +35 -0
- data/examples/hr/config/lcp_ruby/pages/dashboard.yml +101 -0
- data/examples/hr/config/lcp_ruby/permissions/announcement.yml +25 -0
- data/examples/hr/config/lcp_ruby/permissions/asset.yml +35 -0
- data/examples/hr/config/lcp_ruby/permissions/audit_log.yml +28 -0
- data/examples/hr/config/lcp_ruby/permissions/candidate.yml +25 -0
- data/examples/hr/config/lcp_ruby/permissions/custom_field_definition.yml +28 -0
- data/examples/hr/config/lcp_ruby/permissions/dashboard.yml +25 -0
- data/examples/hr/config/lcp_ruby/permissions/default.yml +25 -0
- data/examples/hr/config/lcp_ruby/permissions/document.yml +37 -0
- data/examples/hr/config/lcp_ruby/permissions/employee.yml +55 -0
- data/examples/hr/config/lcp_ruby/permissions/expense_claim.yml +45 -0
- data/examples/hr/config/lcp_ruby/permissions/group.yml +27 -0
- data/examples/hr/config/lcp_ruby/permissions/job_posting.yml +34 -0
- data/examples/hr/config/lcp_ruby/permissions/leave_request.yml +45 -0
- data/examples/hr/config/lcp_ruby/permissions/performance_review.yml +42 -0
- data/examples/hr/config/lcp_ruby/presenters/announcement.rb +47 -0
- data/examples/hr/config/lcp_ruby/presenters/asset.rb +69 -0
- data/examples/hr/config/lcp_ruby/presenters/asset_assignment.rb +47 -0
- data/examples/hr/config/lcp_ruby/presenters/audit_logs.yml +43 -0
- data/examples/hr/config/lcp_ruby/presenters/candidate.rb +71 -0
- data/examples/hr/config/lcp_ruby/presenters/custom_fields.rb +124 -0
- data/examples/hr/config/lcp_ruby/presenters/dashboard.rb +37 -0
- data/examples/hr/config/lcp_ruby/presenters/document.rb +46 -0
- data/examples/hr/config/lcp_ruby/presenters/employee.rb +167 -0
- data/examples/hr/config/lcp_ruby/presenters/employee_archive.rb +38 -0
- data/examples/hr/config/lcp_ruby/presenters/employee_directory.rb +27 -0
- data/examples/hr/config/lcp_ruby/presenters/employee_skill.rb +57 -0
- data/examples/hr/config/lcp_ruby/presenters/expense_claim.rb +76 -0
- data/examples/hr/config/lcp_ruby/presenters/goal.rb +60 -0
- data/examples/hr/config/lcp_ruby/presenters/group.rb +48 -0
- data/examples/hr/config/lcp_ruby/presenters/interview.rb +59 -0
- data/examples/hr/config/lcp_ruby/presenters/job_posting.rb +73 -0
- data/examples/hr/config/lcp_ruby/presenters/leave_balance.rb +50 -0
- data/examples/hr/config/lcp_ruby/presenters/leave_request.rb +89 -0
- data/examples/hr/config/lcp_ruby/presenters/leave_type.rb +52 -0
- data/examples/hr/config/lcp_ruby/presenters/organization_unit.rb +56 -0
- data/examples/hr/config/lcp_ruby/presenters/performance_review.rb +87 -0
- data/examples/hr/config/lcp_ruby/presenters/position.rb +54 -0
- data/examples/hr/config/lcp_ruby/presenters/skill.rb +45 -0
- data/examples/hr/config/lcp_ruby/presenters/training_course.rb +61 -0
- data/examples/hr/config/lcp_ruby/presenters/training_enrollment.rb +49 -0
- data/examples/hr/config/lcp_ruby/views/announcements.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/asset_assignments.yml +10 -0
- data/examples/hr/config/lcp_ruby/views/assets.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/audit_logs.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/candidates.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/custom_fields.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/dashboard.yml +6 -0
- data/examples/hr/config/lcp_ruby/views/documents.yml +10 -0
- data/examples/hr/config/lcp_ruby/views/employee_skills.yml +10 -0
- data/examples/hr/config/lcp_ruby/views/employees.yml +14 -0
- data/examples/hr/config/lcp_ruby/views/expense_claims.yml +10 -0
- data/examples/hr/config/lcp_ruby/views/goals.yml +10 -0
- data/examples/hr/config/lcp_ruby/views/groups.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/interviews.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/job_postings.yml +6 -0
- data/examples/hr/config/lcp_ruby/views/leave_balances.yml +10 -0
- data/examples/hr/config/lcp_ruby/views/leave_requests.yml +10 -0
- data/examples/hr/config/lcp_ruby/views/leave_types.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/organization_units.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/performance_reviews.yml +10 -0
- data/examples/hr/config/lcp_ruby/views/positions.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/skills.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/training_courses.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/training_enrollments.yml +10 -0
- data/examples/hr/config/locales/cs.yml +496 -0
- data/examples/hr/config/locales/en.yml +740 -0
- data/examples/hr/config/locales/sk.yml +496 -0
- data/examples/hr/config/puma.rb +42 -0
- data/examples/hr/config/queue.yml +18 -0
- data/examples/hr/config/recurring.yml +15 -0
- data/examples/hr/config/routes.rb +4 -0
- data/examples/hr/config/storage.yml +27 -0
- data/examples/hr/config.ru +6 -0
- data/examples/hr/db/cache_schema.rb +12 -0
- data/examples/hr/db/migrate/20260303202825_create_active_storage_tables.active_storage.rb +57 -0
- data/examples/hr/db/queue_schema.rb +129 -0
- data/examples/hr/db/schema.rb +588 -0
- data/examples/hr/db/seeds.rb +932 -0
- data/examples/hr/erd.md +396 -0
- data/examples/hr/public/400.html +135 -0
- data/examples/hr/public/404.html +135 -0
- data/examples/hr/public/406-unsupported-browser.html +135 -0
- data/examples/hr/public/422.html +135 -0
- data/examples/hr/public/500.html +135 -0
- data/examples/hr/public/icon.svg +3 -0
- data/examples/hr/public/robots.txt +1 -0
- data/examples/showcase/Gemfile +15 -0
- data/examples/showcase/Gemfile.lock +425 -0
- data/examples/showcase/Rakefile +2 -0
- data/examples/showcase/app/actions/showcase_batch_task/assign_batch.rb +20 -0
- data/examples/showcase/app/actions/showcase_batch_task/close_task.rb +21 -0
- data/examples/showcase/app/actions/showcase_condition/approve.rb +20 -0
- data/examples/showcase/app/actions/showcase_permission/lock.rb +20 -0
- data/examples/showcase/app/assets/config/manifest.js +3 -0
- data/examples/showcase/app/assets/stylesheets/application.css +27 -0
- data/examples/showcase/app/condition_services/budget_threshold.rb +16 -0
- data/examples/showcase/app/condition_services/overdue_check.rb +11 -0
- data/examples/showcase/app/controllers/application_controller.rb +2 -0
- data/examples/showcase/app/controllers/docs_controller.rb +48 -0
- data/examples/showcase/app/controllers/host_inventory_items_managed_controller.rb +90 -0
- data/examples/showcase/app/controllers/host_inventory_items_report_controller.rb +39 -0
- data/examples/showcase/app/controllers/host_inventory_items_wizard_controller.rb +50 -0
- data/examples/showcase/app/data_providers/showcase_amount_provider.rb +52 -0
- data/examples/showcase/app/data_providers/weather_station_provider.rb +140 -0
- data/examples/showcase/app/event_handlers/showcase_model/on_status_change.rb +17 -0
- data/examples/showcase/app/event_handlers/showcase_permission/on_status_change.rb +17 -0
- data/examples/showcase/app/event_handlers/showcase_workflow/log_review_exit.rb +16 -0
- data/examples/showcase/app/event_handlers/showcase_workflow/notify_reviewers.rb +15 -0
- data/examples/showcase/app/event_handlers/showcase_workflow/request_submitted.rb +15 -0
- data/examples/showcase/app/lcp_metrics/showcase_metrics.rb +31 -0
- data/examples/showcase/app/lcp_services/computed/showcase_score.rb +18 -0
- data/examples/showcase/app/lcp_services/computed/showcase_total.rb +13 -0
- data/examples/showcase/app/lcp_services/defaults/one_week_from_now.rb +11 -0
- data/examples/showcase/app/lcp_services/menu_items/recent_announcements.rb +36 -0
- data/examples/showcase/app/lcp_services/virtual_columns/project_health.rb +26 -0
- data/examples/showcase/app/model_extensions/lcp_error_log_extension.rb +12 -0
- data/examples/showcase/app/models/host_inventory_item.rb +20 -0
- data/examples/showcase/app/models/platform_profile.rb +27 -0
- data/examples/showcase/app/models/platform_user.rb +5 -0
- data/examples/showcase/app/views/docs/show.html.erb +19 -0
- data/examples/showcase/app/views/host_inventory_items_report/index.html.erb +61 -0
- data/examples/showcase/app/views/host_inventory_items_report/show.html.erb +39 -0
- data/examples/showcase/app/views/layouts/docs.html.erb +46 -0
- data/examples/showcase/app/views/showcase/menu_renderers/_status_pill.html.erb +17 -0
- data/examples/showcase/app/views/showcase_custom/_activity_timeline.html.erb +37 -0
- data/examples/showcase/app/views/showcase_custom/_card_index.html.erb +74 -0
- data/examples/showcase/app/views/showcase_custom/_detail_show.html.erb +115 -0
- data/examples/showcase/app/views/showcase_custom/_location_map.html.erb +29 -0
- data/examples/showcase/app/views/showcase_custom/_location_view.html.erb +34 -0
- data/examples/showcase/app/views/showcase_custom/_quick_stats.html.erb +50 -0
- data/examples/showcase/app/views/showcase_custom/_stats_sidebar.html.erb +42 -0
- data/examples/showcase/app/views/showcase_custom/_tags_editor.html.erb +48 -0
- data/examples/showcase/bin/rails +4 -0
- data/examples/showcase/bin/rake +4 -0
- data/examples/showcase/config/application.rb +37 -0
- data/examples/showcase/config/boot.rb +2 -0
- data/examples/showcase/config/database.yml +12 -0
- data/examples/showcase/config/environment.rb +2 -0
- data/examples/showcase/config/initializers/devise.rb +5 -0
- data/examples/showcase/config/initializers/lcp_ruby.rb +175 -0
- data/examples/showcase/config/lcp_ruby/auth.yml +60 -0
- data/examples/showcase/config/lcp_ruby/jobs/data_import.yml +7 -0
- data/examples/showcase/config/lcp_ruby/jobs/showcase_cleanup.yml +11 -0
- data/examples/showcase/config/lcp_ruby/jobs/showcase_event_triggered.yml +11 -0
- data/examples/showcase/config/lcp_ruby/jobs/showcase_multi_step.yml +9 -0
- data/examples/showcase/config/lcp_ruby/jobs/showcase_webhook.yml +13 -0
- data/examples/showcase/config/lcp_ruby/menu.yml +249 -0
- data/examples/showcase/config/lcp_ruby/models/_base_document.rb +26 -0
- data/examples/showcase/config/lcp_ruby/models/_categorized_document.rb +19 -0
- data/examples/showcase/config/lcp_ruby/models/_contactable.rb +20 -0
- data/examples/showcase/config/lcp_ruby/models/api_token.rb +23 -0
- data/examples/showcase/config/lcp_ruby/models/article.rb +49 -0
- data/examples/showcase/config/lcp_ruby/models/article_tag.rb +10 -0
- data/examples/showcase/config/lcp_ruby/models/author.rb +16 -0
- data/examples/showcase/config/lcp_ruby/models/batch_operation.yml +79 -0
- data/examples/showcase/config/lcp_ruby/models/batch_operation_item.yml +45 -0
- data/examples/showcase/config/lcp_ruby/models/category.rb +23 -0
- data/examples/showcase/config/lcp_ruby/models/comment.rb +21 -0
- data/examples/showcase/config/lcp_ruby/models/custom_field_definition.rb +59 -0
- data/examples/showcase/config/lcp_ruby/models/department.rb +32 -0
- data/examples/showcase/config/lcp_ruby/models/employee.rb +52 -0
- data/examples/showcase/config/lcp_ruby/models/employee_emergency_contact.rb +24 -0
- data/examples/showcase/config/lcp_ruby/models/employee_profile.rb +18 -0
- data/examples/showcase/config/lcp_ruby/models/employee_skill.rb +10 -0
- data/examples/showcase/config/lcp_ruby/models/export_log.yml +27 -0
- data/examples/showcase/config/lcp_ruby/models/export_profile.yml +37 -0
- data/examples/showcase/config/lcp_ruby/models/feature.rb +76 -0
- data/examples/showcase/config/lcp_ruby/models/gapfree_sequence.rb +17 -0
- data/examples/showcase/config/lcp_ruby/models/group.rb +26 -0
- data/examples/showcase/config/lcp_ruby/models/group_membership.rb +21 -0
- data/examples/showcase/config/lcp_ruby/models/group_role_mapping.rb +14 -0
- data/examples/showcase/config/lcp_ruby/models/host_inventory_item.yml +111 -0
- data/examples/showcase/config/lcp_ruby/models/import_profile.rb +30 -0
- data/examples/showcase/config/lcp_ruby/models/import_row.rb +32 -0
- data/examples/showcase/config/lcp_ruby/models/ingredient_def.rb +11 -0
- data/examples/showcase/config/lcp_ruby/models/lcp_error_log.yml +61 -0
- data/examples/showcase/config/lcp_ruby/models/page_config.rb +19 -0
- data/examples/showcase/config/lcp_ruby/models/permission_config.rb +21 -0
- data/examples/showcase/config/lcp_ruby/models/pipeline.rb +15 -0
- data/examples/showcase/config/lcp_ruby/models/pipeline_stage.rb +17 -0
- data/examples/showcase/config/lcp_ruby/models/platform_profile.rb +104 -0
- data/examples/showcase/config/lcp_ruby/models/profile_setting.rb +17 -0
- data/examples/showcase/config/lcp_ruby/models/profile_tag.rb +19 -0
- data/examples/showcase/config/lcp_ruby/models/project.rb +23 -0
- data/examples/showcase/config/lcp_ruby/models/role.rb +24 -0
- data/examples/showcase/config/lcp_ruby/models/saved_filter.rb +50 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_aggregate.rb +93 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_aggregate_company.rb +14 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_aggregate_item.rb +25 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_announcement.rb +20 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_array.rb +45 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_attachment.rb +49 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_audit_log.yml +44 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_audited_record.rb +20 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_batch_task.rb +27 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_business_unit.rb +26 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_condition.rb +24 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_condition_category.rb +16 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_condition_task.rb +16 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_condition_threshold.rb +13 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_contact.rb +22 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_custom_render.rb +38 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_delete_reason.rb +11 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_division.rb +31 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_extensibility.rb +25 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_field.rb +53 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_form.rb +23 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_form_action.rb +38 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_grade.rb +18 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_hr_employee.rb +90 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_item_class.rb +31 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_job_execution.rb +49 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_memo.rb +23 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_model.rb +74 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_organization.rb +31 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_permission.rb +30 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_person.rb +23 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_positioning.rb +19 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_quick_note.rb +13 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_recipe.rb +17 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_report.rb +32 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_school_class.rb +17 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_search.rb +84 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_sequence.rb +46 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_soft_delete.rb +30 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_soft_delete_item.rb +21 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_student.rb +17 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_type_default.rb +49 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_userstamps.rb +26 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_virtual_field.rb +68 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_workflow.rb +54 -0
- data/examples/showcase/config/lcp_ruby/models/skill.rb +22 -0
- data/examples/showcase/config/lcp_ruby/models/tag.rb +16 -0
- data/examples/showcase/config/lcp_ruby/models/user.rb +54 -0
- data/examples/showcase/config/lcp_ruby/models/weather_station.rb +20 -0
- data/examples/showcase/config/lcp_ruby/models/workflow_approval_request.yml +77 -0
- data/examples/showcase/config/lcp_ruby/models/workflow_approval_step.yml +56 -0
- data/examples/showcase/config/lcp_ruby/models/workflow_approval_task.yml +51 -0
- data/examples/showcase/config/lcp_ruby/models/workflow_audit_log.yml +74 -0
- data/examples/showcase/config/lcp_ruby/pages/article_detail.yml +32 -0
- data/examples/showcase/config/lcp_ruby/pages/author_detail.yml +27 -0
- data/examples/showcase/config/lcp_ruby/pages/category_detail.yml +24 -0
- data/examples/showcase/config/lcp_ruby/pages/chart_showcase.yml +151 -0
- data/examples/showcase/config/lcp_ruby/pages/department_detail.yml +55 -0
- data/examples/showcase/config/lcp_ruby/pages/department_explorer.yml +60 -0
- data/examples/showcase/config/lcp_ruby/pages/employee_overview.yml +106 -0
- data/examples/showcase/config/lcp_ruby/pages/employee_transfer_dialog.yml +24 -0
- data/examples/showcase/config/lcp_ruby/pages/hr_turnover_dashboard.yml +288 -0
- data/examples/showcase/config/lcp_ruby/pages/main_dashboard.yml +142 -0
- data/examples/showcase/config/lcp_ruby/pages/monitoring_dashboard.yml +58 -0
- data/examples/showcase/config/lcp_ruby/pages/pipeline_detail.yml +16 -0
- data/examples/showcase/config/lcp_ruby/pages/showcase_custom_zones.yml +39 -0
- data/examples/showcase/config/lcp_ruby/pages/showcase_form_action_dialog.yml +11 -0
- data/examples/showcase/config/lcp_ruby/pages/workflow_request_detail.yml +34 -0
- data/examples/showcase/config/lcp_ruby/permissions/api_token.yml +26 -0
- data/examples/showcase/config/lcp_ruby/permissions/batch_operation.yml +36 -0
- data/examples/showcase/config/lcp_ruby/permissions/custom_field_definition.yml +15 -0
- data/examples/showcase/config/lcp_ruby/permissions/default.yml +28 -0
- data/examples/showcase/config/lcp_ruby/permissions/export_log.yml +23 -0
- data/examples/showcase/config/lcp_ruby/permissions/export_profile.yml +25 -0
- data/examples/showcase/config/lcp_ruby/permissions/gapfree_sequence.yml +6 -0
- data/examples/showcase/config/lcp_ruby/permissions/group.yml +20 -0
- data/examples/showcase/config/lcp_ruby/permissions/group_membership.yml +20 -0
- data/examples/showcase/config/lcp_ruby/permissions/group_role_mapping.yml +20 -0
- data/examples/showcase/config/lcp_ruby/permissions/host_inventory_item.yml +34 -0
- data/examples/showcase/config/lcp_ruby/permissions/import_profile.yml +29 -0
- data/examples/showcase/config/lcp_ruby/permissions/import_row.yml +17 -0
- data/examples/showcase/config/lcp_ruby/permissions/lcp_error_log.yml +8 -0
- data/examples/showcase/config/lcp_ruby/permissions/page_config.yml +15 -0
- data/examples/showcase/config/lcp_ruby/permissions/permission_config.yml +15 -0
- data/examples/showcase/config/lcp_ruby/permissions/platform_profile.yml +23 -0
- data/examples/showcase/config/lcp_ruby/permissions/profile_setting.yml +23 -0
- data/examples/showcase/config/lcp_ruby/permissions/profile_tag.yml +23 -0
- data/examples/showcase/config/lcp_ruby/permissions/role.yml +20 -0
- data/examples/showcase/config/lcp_ruby/permissions/saved_filter.yml +39 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_announcement.yml +22 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_audit_log.yml +15 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_audited_record.yml +15 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_batch_task.yml +31 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_condition.yml +54 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_contact.yml +21 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_custom_render.yml +21 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_delete_reason.yml +12 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_form_action.yml +26 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_grade.yml +33 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_job_execution.yml +23 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_permission.yml +47 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_quick_note.yml +12 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_school_class.yml +37 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_student.yml +43 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_workflow.yml +34 -0
- data/examples/showcase/config/lcp_ruby/permissions/workflow_approval_request.yml +18 -0
- data/examples/showcase/config/lcp_ruby/permissions/workflow_approval_step.yml +18 -0
- data/examples/showcase/config/lcp_ruby/permissions/workflow_approval_task.yml +18 -0
- data/examples/showcase/config/lcp_ruby/permissions/workflow_audit_log.yml +19 -0
- data/examples/showcase/config/lcp_ruby/presenters/announcements.rb +59 -0
- data/examples/showcase/config/lcp_ruby/presenters/approval_requests.rb +69 -0
- data/examples/showcase/config/lcp_ruby/presenters/approval_steps.rb +59 -0
- data/examples/showcase/config/lcp_ruby/presenters/approval_tasks.rb +65 -0
- data/examples/showcase/config/lcp_ruby/presenters/article_comments_zone.rb +12 -0
- data/examples/showcase/config/lcp_ruby/presenters/article_related_zone.rb +15 -0
- data/examples/showcase/config/lcp_ruby/presenters/articles.rb +149 -0
- data/examples/showcase/config/lcp_ruby/presenters/articles_tiles.rb +30 -0
- data/examples/showcase/config/lcp_ruby/presenters/author_articles_zone.rb +12 -0
- data/examples/showcase/config/lcp_ruby/presenters/author_show_zone.rb +12 -0
- data/examples/showcase/config/lcp_ruby/presenters/authors.rb +39 -0
- data/examples/showcase/config/lcp_ruby/presenters/batch_operation_items.yml +45 -0
- data/examples/showcase/config/lcp_ruby/presenters/batch_operations.yml +66 -0
- data/examples/showcase/config/lcp_ruby/presenters/categories.rb +50 -0
- data/examples/showcase/config/lcp_ruby/presenters/category_articles_zone.rb +20 -0
- data/examples/showcase/config/lcp_ruby/presenters/category_children_zone.rb +10 -0
- data/examples/showcase/config/lcp_ruby/presenters/comment_quick_add_dialog.rb +15 -0
- data/examples/showcase/config/lcp_ruby/presenters/custom_fields.rb +124 -0
- data/examples/showcase/config/lcp_ruby/presenters/dashboard_employees.rb +16 -0
- data/examples/showcase/config/lcp_ruby/presenters/delete_reason_dialog.rb +13 -0
- data/examples/showcase/config/lcp_ruby/presenters/departments.rb +55 -0
- data/examples/showcase/config/lcp_ruby/presenters/dept_add_employee_dialog.rb +19 -0
- data/examples/showcase/config/lcp_ruby/presenters/dept_children_zone.rb +10 -0
- data/examples/showcase/config/lcp_ruby/presenters/dept_detail_zone.rb +14 -0
- data/examples/showcase/config/lcp_ruby/presenters/dept_employees_zone.rb +16 -0
- data/examples/showcase/config/lcp_ruby/presenters/dept_list_selection_zone.rb +19 -0
- data/examples/showcase/config/lcp_ruby/presenters/employee_overview_index_zone.rb +36 -0
- data/examples/showcase/config/lcp_ruby/presenters/employee_quick_add_dialog.rb +14 -0
- data/examples/showcase/config/lcp_ruby/presenters/employee_show_zone.rb +20 -0
- data/examples/showcase/config/lcp_ruby/presenters/employee_transfer_form_zone.rb +19 -0
- data/examples/showcase/config/lcp_ruby/presenters/employees.rb +165 -0
- data/examples/showcase/config/lcp_ruby/presenters/employees_tiles.rb +33 -0
- data/examples/showcase/config/lcp_ruby/presenters/export_logs.yml +58 -0
- data/examples/showcase/config/lcp_ruby/presenters/export_profiles.yml +70 -0
- data/examples/showcase/config/lcp_ruby/presenters/extensibility_quick_edit_dialog.rb +13 -0
- data/examples/showcase/config/lcp_ruby/presenters/feature_kanban.rb +30 -0
- data/examples/showcase/config/lcp_ruby/presenters/features_card.rb +179 -0
- data/examples/showcase/config/lcp_ruby/presenters/features_hub.rb +44 -0
- data/examples/showcase/config/lcp_ruby/presenters/features_table.rb +37 -0
- data/examples/showcase/config/lcp_ruby/presenters/features_tiles.rb +48 -0
- data/examples/showcase/config/lcp_ruby/presenters/group_memberships.rb +54 -0
- data/examples/showcase/config/lcp_ruby/presenters/group_role_mappings.rb +48 -0
- data/examples/showcase/config/lcp_ruby/presenters/groups.rb +74 -0
- data/examples/showcase/config/lcp_ruby/presenters/host_inventory_items.rb +99 -0
- data/examples/showcase/config/lcp_ruby/presenters/host_inventory_items_managed.rb +84 -0
- data/examples/showcase/config/lcp_ruby/presenters/host_inventory_items_report.rb +40 -0
- data/examples/showcase/config/lcp_ruby/presenters/host_inventory_items_wizard.rb +76 -0
- data/examples/showcase/config/lcp_ruby/presenters/import_profiles.rb +61 -0
- data/examples/showcase/config/lcp_ruby/presenters/import_rows.rb +39 -0
- data/examples/showcase/config/lcp_ruby/presenters/lcp_error_logs.yml +46 -0
- data/examples/showcase/config/lcp_ruby/presenters/my_api_tokens.rb +35 -0
- data/examples/showcase/config/lcp_ruby/presenters/my_api_tokens_create_dialog.rb +27 -0
- data/examples/showcase/config/lcp_ruby/presenters/my_employee_profile.rb +24 -0
- data/examples/showcase/config/lcp_ruby/presenters/my_settings.rb +50 -0
- data/examples/showcase/config/lcp_ruby/presenters/page_configs.rb +56 -0
- data/examples/showcase/config/lcp_ruby/presenters/permission_configs.rb +58 -0
- data/examples/showcase/config/lcp_ruby/presenters/pipeline_edit_zone.rb +11 -0
- data/examples/showcase/config/lcp_ruby/presenters/pipeline_stages.rb +51 -0
- data/examples/showcase/config/lcp_ruby/presenters/pipeline_stages_zone.rb +11 -0
- data/examples/showcase/config/lcp_ruby/presenters/pipelines.rb +40 -0
- data/examples/showcase/config/lcp_ruby/presenters/platform_profiles.rb +90 -0
- data/examples/showcase/config/lcp_ruby/presenters/projects.rb +58 -0
- data/examples/showcase/config/lcp_ruby/presenters/quick_note_dialog.rb +14 -0
- data/examples/showcase/config/lcp_ruby/presenters/roles.rb +60 -0
- data/examples/showcase/config/lcp_ruby/presenters/save_filter_dialog.rb +17 -0
- data/examples/showcase/config/lcp_ruby/presenters/saved_filters.rb +94 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_aggregate_items.rb +61 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_aggregates.rb +115 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_aggregates_tiles.rb +44 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_amount_kanban.rb +31 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_arrays.rb +140 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_attachments.rb +66 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_audit_logs.rb +46 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_audited_records.rb +58 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_batch_tasks.rb +97 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_batch_tasks_archive.rb +52 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_business_units.rb +43 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_conditions.rb +195 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_contacts.rb +82 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_custom_render_with.rb +50 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_custom_sections.rb +88 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_custom_zones_main.rb +75 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_divisions.rb +53 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_extensibility.rb +48 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_fields_card.rb +34 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_fields_table.rb +128 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_fields_tiles.rb +42 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_form_action_dialog.rb +27 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_form_actions.rb +132 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_form_actions_overflow.rb +76 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_forms.rb +110 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_grades.rb +38 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_hr_employees.rb +84 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_item_classes.rb +120 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_job_executions.rb +150 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_memos.rb +96 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_models.rb +112 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_organizations.rb +106 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_people.rb +97 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_permissions.rb +84 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_positioning.rb +61 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_recipes.rb +105 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_recipes_raw.rb +32 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_reports.rb +109 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_school_classes.rb +34 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_searches.rb +226 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_sequences.rb +67 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_soft_delete.rb +88 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_soft_delete_archive.rb +52 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_soft_delete_items.rb +47 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_students.rb +33 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_type_defaults.rb +92 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_userstamps.rb +76 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_virtual_fields.rb +104 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_workflow_admin.rb +24 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_workflow_kanban.rb +36 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_workflows.rb +103 -0
- data/examples/showcase/config/lcp_ruby/presenters/tags.rb +35 -0
- data/examples/showcase/config/lcp_ruby/presenters/users.rb +61 -0
- data/examples/showcase/config/lcp_ruby/presenters/weather_stations.rb +60 -0
- data/examples/showcase/config/lcp_ruby/presenters/workflow_audit_logs.rb +76 -0
- data/examples/showcase/config/lcp_ruby/presenters/workflow_request_audit_zone.rb +28 -0
- data/examples/showcase/config/lcp_ruby/theme.yml +2 -0
- data/examples/showcase/config/lcp_ruby/types/currency.yml +15 -0
- data/examples/showcase/config/lcp_ruby/types/percentage.yml +16 -0
- data/examples/showcase/config/lcp_ruby/types/rating.yml +20 -0
- data/examples/showcase/config/lcp_ruby/views/announcements.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/approval_requests.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/approval_steps.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/approval_tasks.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/articles.yml +12 -0
- data/examples/showcase/config/lcp_ruby/views/authors.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/batch_operation_items.yml +6 -0
- data/examples/showcase/config/lcp_ruby/views/batch_operations.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/categories.yml +9 -0
- data/examples/showcase/config/lcp_ruby/views/custom_fields.rb +8 -0
- data/examples/showcase/config/lcp_ruby/views/dashboard.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/department_explorer.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/departments.yml +9 -0
- data/examples/showcase/config/lcp_ruby/views/employee_overview.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/employees.yml +12 -0
- data/examples/showcase/config/lcp_ruby/views/export_logs.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/export_profiles.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/features.yml +19 -0
- data/examples/showcase/config/lcp_ruby/views/group_memberships.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/group_role_mappings.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/groups.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/host_inventory_items.yml +16 -0
- data/examples/showcase/config/lcp_ruby/views/hr_turnover_dashboard.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/import_profiles.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/import_rows.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/lcp_error_logs.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/monitoring.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/my_api_tokens.rb +9 -0
- data/examples/showcase/config/lcp_ruby/views/page_configs.yml +11 -0
- data/examples/showcase/config/lcp_ruby/views/permission_configs.yml +11 -0
- data/examples/showcase/config/lcp_ruby/views/pipeline_stages.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/pipelines.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/platform_profiles.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/projects.yml +9 -0
- data/examples/showcase/config/lcp_ruby/views/roles.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/saved_filters.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_aggregate_items.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_aggregates.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_arrays.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_attachments.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_audit_logs.yml +11 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_audited_records.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_batch_tasks.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_business_units.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_conditions.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_contacts.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_custom_render_with.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_custom_sections.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_custom_zones.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_divisions.yml +9 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_extensibility.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_fields.yml +13 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_form_actions.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_forms.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_grades.yml +9 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_hr_employees.yml +9 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_item_classes.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_job_executions.yml +9 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_memos.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_models.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_organizations.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_people.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_permissions.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_positioning.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_recipes.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_reports.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_school_classes.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_searches.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_sequences.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_soft_delete.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_soft_delete_items.yml +8 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_students.yml +9 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_userstamps.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_virtual_fields.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_workflows.yml +16 -0
- data/examples/showcase/config/lcp_ruby/views/tags.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/users.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/weather_stations.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/workflow_audit_logs.yml +9 -0
- data/examples/showcase/config/lcp_ruby/workflows/showcase_form_action.rb +48 -0
- data/examples/showcase/config/lcp_ruby/workflows/showcase_workflow.rb +199 -0
- data/examples/showcase/config/locales/cs.yml +2818 -0
- data/examples/showcase/config/locales/en.yml +67 -0
- data/examples/showcase/config/locales/lcp_ruby/api_tokens.cs.yml +46 -0
- data/examples/showcase/config/locales/lcp_ruby/api_tokens.en.yml +49 -0
- data/examples/showcase/config/routes.rb +21 -0
- data/examples/showcase/config/storage.yml +3 -0
- data/examples/showcase/config.ru +2 -0
- data/examples/showcase/db/migrate/20260219124321_create_active_storage_tables.active_storage.rb +57 -0
- data/examples/showcase/db/migrate/20260220072723_create_lcp_ruby_users.rb +42 -0
- data/examples/showcase/db/migrate/20260406120000_create_host_inventory_items.rb +32 -0
- data/examples/showcase/db/migrate/20260428134542_add_oidc_columns_to_lcp_ruby_users.rb +13 -0
- data/examples/showcase/db/migrate/20260502120000_create_platform_profiles.rb +19 -0
- data/examples/showcase/db/schema.rb +1222 -0
- data/examples/showcase/db/seeds.rb +3085 -0
- data/examples/showcase/erd.md +567 -0
- data/examples/showcase/test/fixtures/import_articles.csv +4 -0
- data/examples/showcase/test/fixtures/import_employees.csv +4 -0
- data/examples/todo/Gemfile +8 -0
- data/examples/todo/Gemfile.lock +415 -0
- data/examples/todo/Rakefile +2 -0
- data/examples/todo/app/assets/config/manifest.js +1 -0
- data/examples/todo/app/controllers/application_controller.rb +6 -0
- data/examples/todo/app/lcp_services/defaults/one_week_from_now.rb +11 -0
- data/examples/todo/bin/rails +4 -0
- data/examples/todo/bin/rake +4 -0
- data/examples/todo/config/application.rb +31 -0
- data/examples/todo/config/boot.rb +2 -0
- data/examples/todo/config/database.yml +12 -0
- data/examples/todo/config/environment.rb +2 -0
- data/examples/todo/config/lcp_ruby/models/todo_item.yml +67 -0
- data/examples/todo/config/lcp_ruby/models/todo_list.yml +49 -0
- data/examples/todo/config/lcp_ruby/permissions/default.yml +10 -0
- data/examples/todo/config/lcp_ruby/permissions/todo_item.yml +21 -0
- data/examples/todo/config/lcp_ruby/presenters/todo_item.yml +75 -0
- data/examples/todo/config/lcp_ruby/presenters/todo_list.yml +68 -0
- data/examples/todo/config/lcp_ruby/views/todo_items.yml +11 -0
- data/examples/todo/config/lcp_ruby/views/todo_lists.yml +9 -0
- data/examples/todo/config/routes.rb +4 -0
- data/examples/todo/config/storage.yml +3 -0
- data/examples/todo/config.ru +2 -0
- data/examples/todo/db/migrate/20260219103416_create_active_storage_tables.active_storage.rb +57 -0
- data/examples/todo/db/schema.rb +63 -0
- data/examples/todo/db/seeds.rb +24 -0
- data/examples/todo/erd.md +21 -0
- data/exe/lcp +33 -0
- data/lib/generators/lcp_ruby/agent_setup_generator.rb +102 -0
- data/lib/generators/lcp_ruby/api_tokens_generator.rb +102 -0
- data/lib/generators/lcp_ruby/auditing_generator.rb +54 -0
- data/lib/generators/lcp_ruby/background_jobs_generator.rb +61 -0
- data/lib/generators/lcp_ruby/batch_operations_generator.rb +62 -0
- data/lib/generators/lcp_ruby/claude_skills_generator.rb +47 -0
- data/lib/generators/lcp_ruby/custom_fields_generator.rb +54 -0
- data/lib/generators/lcp_ruby/dsl_to_yaml.rb +72 -0
- data/lib/generators/lcp_ruby/entity/color_palette.rb +22 -0
- data/lib/generators/lcp_ruby/entity/field_descriptor.rb +24 -0
- data/lib/generators/lcp_ruby/entity/field_token_parser.rb +101 -0
- data/lib/generators/lcp_ruby/entity/role_discovery.rb +45 -0
- data/lib/generators/lcp_ruby/entity_generator.rb +1104 -0
- data/lib/generators/lcp_ruby/export_generator.rb +71 -0
- data/lib/generators/lcp_ruby/format_support.rb +56 -0
- data/lib/generators/lcp_ruby/gapfree_sequences_generator.rb +64 -0
- data/lib/generators/lcp_ruby/groups_generator.rb +94 -0
- data/lib/generators/lcp_ruby/host_controller_generator.rb +202 -0
- data/lib/generators/lcp_ruby/import_generator.rb +96 -0
- data/lib/generators/lcp_ruby/install_auth_generator.rb +432 -0
- data/lib/generators/lcp_ruby/install_generator.rb +319 -0
- data/lib/generators/lcp_ruby/monitoring_generator.rb +58 -0
- data/lib/generators/lcp_ruby/oidc_role_mappings_generator.rb +60 -0
- data/lib/generators/lcp_ruby/pages_generator.rb +66 -0
- data/lib/generators/lcp_ruby/permission_source_generator.rb +66 -0
- data/lib/generators/lcp_ruby/role_model_generator.rb +73 -0
- data/lib/generators/lcp_ruby/saved_filters_generator.rb +62 -0
- data/lib/generators/lcp_ruby/templates/add_oidc_columns_to_lcp_ruby_users.rb.erb +13 -0
- data/lib/generators/lcp_ruby/templates/agent_setup/agents_md.md +3 -0
- data/lib/generators/lcp_ruby/templates/agent_setup/claude_md.md +12 -0
- data/lib/generators/lcp_ruby/templates/api_tokens/create_dialog.rb +31 -0
- data/lib/generators/lcp_ruby/templates/api_tokens/locales.en.yml +43 -0
- data/lib/generators/lcp_ruby/templates/api_tokens/model.rb +23 -0
- data/lib/generators/lcp_ruby/templates/api_tokens/permissions.yml +30 -0
- data/lib/generators/lcp_ruby/templates/api_tokens/presenter.rb +38 -0
- data/lib/generators/lcp_ruby/templates/api_tokens/view_group.rb +13 -0
- data/lib/generators/lcp_ruby/templates/auditing/model.rb +34 -0
- data/lib/generators/lcp_ruby/templates/auditing/permissions.yml +19 -0
- data/lib/generators/lcp_ruby/templates/auditing/presenter.rb +41 -0
- data/lib/generators/lcp_ruby/templates/auditing/view_group.rb +10 -0
- data/lib/generators/lcp_ruby/templates/background_jobs/model.rb +59 -0
- data/lib/generators/lcp_ruby/templates/background_jobs/permissions.yml +22 -0
- data/lib/generators/lcp_ruby/templates/background_jobs/presenter.rb +82 -0
- data/lib/generators/lcp_ruby/templates/background_jobs/view_group.rb +9 -0
- data/lib/generators/lcp_ruby/templates/batch_operations/item_model.rb +28 -0
- data/lib/generators/lcp_ruby/templates/batch_operations/item_presenter.rb +43 -0
- data/lib/generators/lcp_ruby/templates/batch_operations/model.rb +42 -0
- data/lib/generators/lcp_ruby/templates/batch_operations/permissions.yml +44 -0
- data/lib/generators/lcp_ruby/templates/batch_operations/presenter.rb +61 -0
- data/lib/generators/lcp_ruby/templates/batch_operations/view_group.rb +9 -0
- data/lib/generators/lcp_ruby/templates/create_lcp_ruby_users.rb.erb +50 -0
- data/lib/generators/lcp_ruby/templates/custom_fields/model.rb +60 -0
- data/lib/generators/lcp_ruby/templates/custom_fields/permissions.yml +19 -0
- data/lib/generators/lcp_ruby/templates/custom_fields/presenter.rb +128 -0
- data/lib/generators/lcp_ruby/templates/custom_fields/view_group.rb +9 -0
- data/lib/generators/lcp_ruby/templates/entity/model.rb +42 -0
- data/lib/generators/lcp_ruby/templates/entity/permissions.yml +20 -0
- data/lib/generators/lcp_ruby/templates/entity/presenter.rb +55 -0
- data/lib/generators/lcp_ruby/templates/entity/view_group.rb +8 -0
- data/lib/generators/lcp_ruby/templates/export/export_log_model.rb +30 -0
- data/lib/generators/lcp_ruby/templates/export/export_log_permissions.yml +24 -0
- data/lib/generators/lcp_ruby/templates/export/export_logs_presenter.rb +51 -0
- data/lib/generators/lcp_ruby/templates/export/export_profile_model.rb +28 -0
- data/lib/generators/lcp_ruby/templates/export/export_profile_permissions.yml +26 -0
- data/lib/generators/lcp_ruby/templates/export/export_profiles_presenter.rb +59 -0
- data/lib/generators/lcp_ruby/templates/gapfree_sequences/model.rb +18 -0
- data/lib/generators/lcp_ruby/templates/gapfree_sequences/permissions.yml +19 -0
- data/lib/generators/lcp_ruby/templates/gapfree_sequences/presenter.rb +51 -0
- data/lib/generators/lcp_ruby/templates/gapfree_sequences/view_group.rb +9 -0
- data/lib/generators/lcp_ruby/templates/groups/group_membership_model.rb +17 -0
- data/lib/generators/lcp_ruby/templates/groups/group_model.rb +28 -0
- data/lib/generators/lcp_ruby/templates/groups/group_permissions.yml +19 -0
- data/lib/generators/lcp_ruby/templates/groups/group_presenter.rb +53 -0
- data/lib/generators/lcp_ruby/templates/groups/group_role_mapping_model.rb +15 -0
- data/lib/generators/lcp_ruby/templates/groups/group_view_group.rb +9 -0
- data/lib/generators/lcp_ruby/templates/host_controller/controller.rb.erb +131 -0
- data/lib/generators/lcp_ruby/templates/import/data_import_job.yml +7 -0
- data/lib/generators/lcp_ruby/templates/import/import_profile_model.rb +30 -0
- data/lib/generators/lcp_ruby/templates/import/import_profile_permissions.yml +29 -0
- data/lib/generators/lcp_ruby/templates/import/import_profiles_presenter.rb +57 -0
- data/lib/generators/lcp_ruby/templates/import/import_row_model.rb +32 -0
- data/lib/generators/lcp_ruby/templates/import/import_row_permissions.yml +11 -0
- data/lib/generators/lcp_ruby/templates/import/import_rows_presenter.rb +35 -0
- data/lib/generators/lcp_ruby/templates/install/default_permissions.yml +26 -0
- data/lib/generators/lcp_ruby/templates/install/menu.yml.tt +71 -0
- data/lib/generators/lcp_ruby/templates/install/model.rb +20 -0
- data/lib/generators/lcp_ruby/templates/install/permissions.yml +25 -0
- data/lib/generators/lcp_ruby/templates/install/presenter.rb +44 -0
- data/lib/generators/lcp_ruby/templates/install/view_group.rb +10 -0
- data/lib/generators/lcp_ruby/templates/install_auth/oidc/entra.yml.erb +46 -0
- data/lib/generators/lcp_ruby/templates/install_auth/oidc/generic.yml.erb +55 -0
- data/lib/generators/lcp_ruby/templates/install_auth/oidc/google.yml.erb +42 -0
- data/lib/generators/lcp_ruby/templates/install_auth/oidc/keycloak.yml.erb +45 -0
- data/lib/generators/lcp_ruby/templates/install_auth/oidc/okta.yml.erb +45 -0
- data/lib/generators/lcp_ruby/templates/install_auth/user.rb +36 -0
- data/lib/generators/lcp_ruby/templates/monitoring/model.rb +34 -0
- data/lib/generators/lcp_ruby/templates/monitoring/model_extension.rb +12 -0
- data/lib/generators/lcp_ruby/templates/monitoring/page.yml +49 -0
- data/lib/generators/lcp_ruby/templates/monitoring/permissions.yml +8 -0
- data/lib/generators/lcp_ruby/templates/monitoring/presenter.rb +44 -0
- data/lib/generators/lcp_ruby/templates/oidc_role_mappings/locales.en.yml +15 -0
- data/lib/generators/lcp_ruby/templates/oidc_role_mappings/model.rb +32 -0
- data/lib/generators/lcp_ruby/templates/oidc_role_mappings/permissions.yml +21 -0
- data/lib/generators/lcp_ruby/templates/oidc_role_mappings/presenter.rb +41 -0
- data/lib/generators/lcp_ruby/templates/pages/model.rb +19 -0
- data/lib/generators/lcp_ruby/templates/pages/permissions.yml +19 -0
- data/lib/generators/lcp_ruby/templates/pages/presenter.rb +51 -0
- data/lib/generators/lcp_ruby/templates/pages/view_group.rb +10 -0
- data/lib/generators/lcp_ruby/templates/permission_source/model.rb +21 -0
- data/lib/generators/lcp_ruby/templates/permission_source/permissions.yml +19 -0
- data/lib/generators/lcp_ruby/templates/permission_source/presenter.rb +51 -0
- data/lib/generators/lcp_ruby/templates/permission_source/view_group.rb +10 -0
- data/lib/generators/lcp_ruby/templates/role_model/model.rb +24 -0
- data/lib/generators/lcp_ruby/templates/role_model/permissions.yml +19 -0
- data/lib/generators/lcp_ruby/templates/role_model/presenter.rb +62 -0
- data/lib/generators/lcp_ruby/templates/role_model/view_group.rb +10 -0
- data/lib/generators/lcp_ruby/templates/saved_filters/model.rb +51 -0
- data/lib/generators/lcp_ruby/templates/saved_filters/permissions.yml +44 -0
- data/lib/generators/lcp_ruby/templates/saved_filters/presenter.rb +96 -0
- data/lib/generators/lcp_ruby/templates/saved_filters/save_dialog_presenter.rb +19 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/request_model.rb +50 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/request_permissions.yml +10 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/request_presenter.rb +44 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/request_view_group.rb +10 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/step_model.rb +36 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/step_permissions.yml +10 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/task_model.rb +34 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/task_permissions.yml +10 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/task_presenter.rb +39 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/task_view_group.rb +10 -0
- data/lib/generators/lcp_ruby/templates/workflow_audit_log/model.rb +48 -0
- data/lib/generators/lcp_ruby/templates/workflow_audit_log/permissions.yml +10 -0
- data/lib/generators/lcp_ruby/templates/workflow_audit_log/presenter.rb +44 -0
- data/lib/generators/lcp_ruby/templates/workflow_audit_log/view_group.rb +10 -0
- data/lib/generators/lcp_ruby/templates/workflow_definition/model.rb +43 -0
- data/lib/generators/lcp_ruby/templates/workflow_definition/permissions.yml +19 -0
- data/lib/generators/lcp_ruby/templates/workflow_definition/presenter.rb +70 -0
- data/lib/generators/lcp_ruby/templates/workflow_definition/view_group.rb +10 -0
- data/lib/generators/lcp_ruby/workflow_approvals_generator.rb +93 -0
- data/lib/generators/lcp_ruby/workflow_audit_log_generator.rb +54 -0
- data/lib/generators/lcp_ruby/workflow_definition_generator.rb +77 -0
- data/lib/lcp.rb +6 -0
- data/lib/lcp_ruby/actions/action_executor.rb +66 -0
- data/lib/lcp_ruby/actions/action_registry.rb +48 -0
- data/lib/lcp_ruby/actions/api_tokens/revoke.rb +13 -0
- data/lib/lcp_ruby/actions/base_action.rb +79 -0
- data/lib/lcp_ruby/actions/form_action_pipeline.rb +138 -0
- data/lib/lcp_ruby/aggregates/query_builder.rb +6 -0
- data/lib/lcp_ruby/api_tokens/model_extension.rb +41 -0
- data/lib/lcp_ruby/api_tokens/resolver_registry.rb +53 -0
- data/lib/lcp_ruby/api_tokens/token_generator.rb +27 -0
- data/lib/lcp_ruby/api_tokens/verifier.rb +38 -0
- data/lib/lcp_ruby/app_template.rb +181 -0
- data/lib/lcp_ruby/array_query.rb +120 -0
- data/lib/lcp_ruby/asset_copier.rb +62 -0
- data/lib/lcp_ruby/association_fk_type.rb +191 -0
- data/lib/lcp_ruby/association_join_column.rb +28 -0
- data/lib/lcp_ruby/association_options_builder.rb +231 -0
- data/lib/lcp_ruby/auditing/audit_writer.rb +258 -0
- data/lib/lcp_ruby/auditing/contract_validator.rb +95 -0
- data/lib/lcp_ruby/auditing/registry.rb +29 -0
- data/lib/lcp_ruby/auditing/setup.rb +49 -0
- data/lib/lcp_ruby/authentication/audit_subscriber.rb +51 -0
- data/lib/lcp_ruby/authentication/bearer_jwt_verifier.rb +139 -0
- data/lib/lcp_ruby/authentication/devise_setup.rb +47 -0
- data/lib/lcp_ruby/authentication/errors.rb +27 -0
- data/lib/lcp_ruby/authentication/http_fetcher.rb +36 -0
- data/lib/lcp_ruby/authentication/jwks_cache.rb +91 -0
- data/lib/lcp_ruby/authentication/oidc_bearer_resolver.rb +84 -0
- data/lib/lcp_ruby/authentication/omniauth_builder.rb +147 -0
- data/lib/lcp_ruby/authentication/provider.rb +108 -0
- data/lib/lcp_ruby/authentication/provider_registry.rb +227 -0
- data/lib/lcp_ruby/authentication/role_mapper.rb +94 -0
- data/lib/lcp_ruby/authentication/test_support.rb +257 -0
- data/lib/lcp_ruby/authentication/user_resolver.rb +169 -0
- data/lib/lcp_ruby/authentication.rb +40 -0
- data/lib/lcp_ruby/authorization/association_lookup.rb +56 -0
- data/lib/lcp_ruby/authorization/authorization_error.rb +12 -0
- data/lib/lcp_ruby/authorization/cache.rb +89 -0
- data/lib/lcp_ruby/authorization/codes.rb +17 -0
- data/lib/lcp_ruby/authorization/impersonated_user.rb +29 -0
- data/lib/lcp_ruby/authorization/includes_hint.rb +110 -0
- data/lib/lcp_ruby/authorization/inherited_parent_validator.rb +142 -0
- data/lib/lcp_ruby/authorization/invariant_check/configuration.rb +132 -0
- data/lib/lcp_ruby/authorization/invariant_error.rb +15 -0
- data/lib/lcp_ruby/authorization/misconfigured_page_error.rb +30 -0
- data/lib/lcp_ruby/authorization/page_gate.rb +57 -0
- data/lib/lcp_ruby/authorization/permission_evaluator.rb +343 -0
- data/lib/lcp_ruby/authorization/policy_factory.rb +91 -0
- data/lib/lcp_ruby/authorization/runtime_invariant_validator.rb +421 -0
- data/lib/lcp_ruby/authorization/scope_builder.rb +227 -0
- data/lib/lcp_ruby/authorization/scope_resolver.rb +28 -0
- data/lib/lcp_ruby/authorized_controller.rb +44 -0
- data/lib/lcp_ruby/background_jobs/base_handler.rb +113 -0
- data/lib/lcp_ruby/background_jobs/change_handler.rb +17 -0
- data/lib/lcp_ruby/background_jobs/contract.rb +16 -0
- data/lib/lcp_ruby/background_jobs/contract_validator.rb +112 -0
- data/lib/lcp_ruby/background_jobs/declarative/base_action.rb +11 -0
- data/lib/lcp_ruby/background_jobs/declarative/call_webhook_action.rb +174 -0
- data/lib/lcp_ruby/background_jobs/declarative/fire_event_action.rb +24 -0
- data/lib/lcp_ruby/background_jobs/declarative/registry.rb +34 -0
- data/lib/lcp_ruby/background_jobs/declarative/run_scope_action.rb +98 -0
- data/lib/lcp_ruby/background_jobs/declarative/send_notification_action.rb +13 -0
- data/lib/lcp_ruby/background_jobs/definition.rb +134 -0
- data/lib/lcp_ruby/background_jobs/enqueue.rb +83 -0
- data/lib/lcp_ruby/background_jobs/errors.rb +9 -0
- data/lib/lcp_ruby/background_jobs/executor_job.rb +111 -0
- data/lib/lcp_ruby/background_jobs/handler_factory.rb +46 -0
- data/lib/lcp_ruby/background_jobs/host_source.rb +33 -0
- data/lib/lcp_ruby/background_jobs/model_source.rb +93 -0
- data/lib/lcp_ruby/background_jobs/registry.rb +81 -0
- data/lib/lcp_ruby/background_jobs/resolver.rb +29 -0
- data/lib/lcp_ruby/background_jobs/schedule_adapter.rb +14 -0
- data/lib/lcp_ruby/background_jobs/setup.rb +145 -0
- data/lib/lcp_ruby/background_jobs/static_source.rb +19 -0
- data/lib/lcp_ruby/background_jobs/steps_executor.rb +52 -0
- data/lib/lcp_ruby/background_jobs/triggers/event_trigger.rb +97 -0
- data/lib/lcp_ruby/background_jobs/triggers/trigger_installer.rb +20 -0
- data/lib/lcp_ruby/background_jobs/unique_key_builder.rb +31 -0
- data/lib/lcp_ruby/batch_actions/base_service.rb +70 -0
- data/lib/lcp_ruby/batch_actions/batch_action_handler.rb +200 -0
- data/lib/lcp_ruby/batch_actions/custom_action_dispatcher.rb +133 -0
- data/lib/lcp_ruby/batch_actions/destroy_service.rb +37 -0
- data/lib/lcp_ruby/batch_actions/permanently_destroy_service.rb +33 -0
- data/lib/lcp_ruby/batch_actions/restore_service.rb +33 -0
- data/lib/lcp_ruby/batch_actions.rb +5 -0
- data/lib/lcp_ruby/bulk_updater.rb +25 -0
- data/lib/lcp_ruby/cli/docs_command.rb +29 -0
- data/lib/lcp_ruby/cli/examples_command.rb +29 -0
- data/lib/lcp_ruby/cli/new_command.rb +509 -0
- data/lib/lcp_ruby/cli/run_command.rb +155 -0
- data/lib/lcp_ruby/cli/skills_command.rb +54 -0
- data/lib/lcp_ruby/cli.rb +74 -0
- data/lib/lcp_ruby/condition_evaluator.rb +366 -0
- data/lib/lcp_ruby/condition_service_registry.rb +58 -0
- data/lib/lcp_ruby/condition_services/current_user_role.rb +28 -0
- data/lib/lcp_ruby/condition_services/feature_flag.rb +63 -0
- data/lib/lcp_ruby/condition_services/impersonating.rb +24 -0
- data/lib/lcp_ruby/conditions/validator.rb +35 -0
- data/lib/lcp_ruby/configuration.rb +431 -0
- data/lib/lcp_ruby/controller/authentication.rb +118 -0
- data/lib/lcp_ruby/controller/authorization.rb +198 -0
- data/lib/lcp_ruby/controller/bearer_authentication.rb +76 -0
- data/lib/lcp_ruby/controller/crud_helpers.rb +233 -0
- data/lib/lcp_ruby/controller/error_handling.rb +94 -0
- data/lib/lcp_ruby/controller/impersonation.rb +70 -0
- data/lib/lcp_ruby/controller/locale_binding.rb +62 -0
- data/lib/lcp_ruby/controller/path_helpers.rb +125 -0
- data/lib/lcp_ruby/controller/presenter_setup.rb +89 -0
- data/lib/lcp_ruby/controller/search.rb +321 -0
- data/lib/lcp_ruby/controller/view_helpers.rb +105 -0
- data/lib/lcp_ruby/current.rb +13 -0
- data/lib/lcp_ruby/custom_fields/applicator.rb +194 -0
- data/lib/lcp_ruby/custom_fields/contract_validator.rb +77 -0
- data/lib/lcp_ruby/custom_fields/definition_change_handler.rb +21 -0
- data/lib/lcp_ruby/custom_fields/query.rb +112 -0
- data/lib/lcp_ruby/custom_fields/registry.rb +70 -0
- data/lib/lcp_ruby/custom_fields/setup.rb +58 -0
- data/lib/lcp_ruby/custom_fields/utils.rb +40 -0
- data/lib/lcp_ruby/custom_fields.rb +9 -0
- data/lib/lcp_ruby/data_source/api_error_placeholder.rb +47 -0
- data/lib/lcp_ruby/data_source/api_filter_translator.rb +72 -0
- data/lib/lcp_ruby/data_source/api_model_concern.rb +131 -0
- data/lib/lcp_ruby/data_source/api_preloader.rb +44 -0
- data/lib/lcp_ruby/data_source/base.rb +85 -0
- data/lib/lcp_ruby/data_source/cached_wrapper.rb +107 -0
- data/lib/lcp_ruby/data_source/host.rb +71 -0
- data/lib/lcp_ruby/data_source/registry.rb +39 -0
- data/lib/lcp_ruby/data_source/resilient_wrapper.rb +67 -0
- data/lib/lcp_ruby/data_source/rest_json.rb +247 -0
- data/lib/lcp_ruby/data_source/setup.rb +57 -0
- data/lib/lcp_ruby/dev_toolbar.rb +8 -0
- data/lib/lcp_ruby/display/base_renderer.rb +21 -0
- data/lib/lcp_ruby/display/count_badge.rb +11 -0
- data/lib/lcp_ruby/display/icon_badge.rb +17 -0
- data/lib/lcp_ruby/display/renderer_registry.rb +138 -0
- data/lib/lcp_ruby/display/renderers/attachment_link.rb +26 -0
- data/lib/lcp_ruby/display/renderers/attachment_list.rb +32 -0
- data/lib/lcp_ruby/display/renderers/attachment_preview.rb +26 -0
- data/lib/lcp_ruby/display/renderers/avatar.rb +14 -0
- data/lib/lcp_ruby/display/renderers/badge.rb +43 -0
- data/lib/lcp_ruby/display/renderers/boolean_icon.rb +54 -0
- data/lib/lcp_ruby/display/renderers/code.rb +39 -0
- data/lib/lcp_ruby/display/renderers/collection.rb +34 -0
- data/lib/lcp_ruby/display/renderers/color_swatch.rb +25 -0
- data/lib/lcp_ruby/display/renderers/concerns/attachment_helpers.rb +73 -0
- data/lib/lcp_ruby/display/renderers/concerns/workflow_helpers.rb +35 -0
- data/lib/lcp_ruby/display/renderers/copy_code.rb +33 -0
- data/lib/lcp_ruby/display/renderers/currency.rb +14 -0
- data/lib/lcp_ruby/display/renderers/date.rb +17 -0
- data/lib/lcp_ruby/display/renderers/datetime.rb +17 -0
- data/lib/lcp_ruby/display/renderers/email_link.rb +15 -0
- data/lib/lcp_ruby/display/renderers/file_size.rb +11 -0
- data/lib/lcp_ruby/display/renderers/heading.rb +11 -0
- data/lib/lcp_ruby/display/renderers/image.rb +17 -0
- data/lib/lcp_ruby/display/renderers/internal_link.rb +23 -0
- data/lib/lcp_ruby/display/renderers/link.rb +15 -0
- data/lib/lcp_ruby/display/renderers/link_list.rb +90 -0
- data/lib/lcp_ruby/display/renderers/markdown.rb +33 -0
- data/lib/lcp_ruby/display/renderers/number.rb +14 -0
- data/lib/lcp_ruby/display/renderers/percentage.rb +12 -0
- data/lib/lcp_ruby/display/renderers/phone_link.rb +15 -0
- data/lib/lcp_ruby/display/renderers/progress_bar.rb +15 -0
- data/lib/lcp_ruby/display/renderers/rating.rb +15 -0
- data/lib/lcp_ruby/display/renderers/record_link.rb +101 -0
- data/lib/lcp_ruby/display/renderers/relative_date.rb +15 -0
- data/lib/lcp_ruby/display/renderers/rich_text.rb +15 -0
- data/lib/lcp_ruby/display/renderers/text.rb +12 -0
- data/lib/lcp_ruby/display/renderers/truncate.rb +17 -0
- data/lib/lcp_ruby/display/renderers/url_link.rb +22 -0
- data/lib/lcp_ruby/display/renderers/workflow_badge.rb +37 -0
- data/lib/lcp_ruby/display/renderers/workflow_timeline.rb +173 -0
- data/lib/lcp_ruby/display/renderers.rb +3 -0
- data/lib/lcp_ruby/display/text_badge.rb +15 -0
- data/lib/lcp_ruby/dsl/condition_builder.rb +190 -0
- data/lib/lcp_ruby/dsl/dsl_loader.rb +365 -0
- data/lib/lcp_ruby/dsl/field_builder.rb +35 -0
- data/lib/lcp_ruby/dsl/job_builder.rb +92 -0
- data/lib/lcp_ruby/dsl/model_builder.rb +544 -0
- data/lib/lcp_ruby/dsl/presenter_builder.rb +1272 -0
- data/lib/lcp_ruby/dsl/source_location_capture.rb +52 -0
- data/lib/lcp_ruby/dsl/type_builder.rb +88 -0
- data/lib/lcp_ruby/dsl/view_group_builder.rb +92 -0
- data/lib/lcp_ruby/dsl/workflow_builder.rb +319 -0
- data/lib/lcp_ruby/dynamic.rb +7 -0
- data/lib/lcp_ruby/dynamic_references/resolver.rb +154 -0
- data/lib/lcp_ruby/dynamic_references/validator.rb +92 -0
- data/lib/lcp_ruby/embed_providers/base.rb +18 -0
- data/lib/lcp_ruby/embed_providers/grafana.rb +38 -0
- data/lib/lcp_ruby/embed_providers/metabase.rb +37 -0
- data/lib/lcp_ruby/engine.rb +680 -0
- data/lib/lcp_ruby/events/async_handler_job.rb +21 -0
- data/lib/lcp_ruby/events/dispatcher.rb +52 -0
- data/lib/lcp_ruby/events/handler_base.rb +51 -0
- data/lib/lcp_ruby/events/handler_registry.rb +49 -0
- data/lib/lcp_ruby/export/data_generator.rb +158 -0
- data/lib/lcp_ruby/export/export_handler.rb +315 -0
- data/lib/lcp_ruby/export/field_tree_builder.rb +219 -0
- data/lib/lcp_ruby/export/setup.rb +94 -0
- data/lib/lcp_ruby/export/value_formatter.rb +223 -0
- data/lib/lcp_ruby/export.rb +9 -0
- data/lib/lcp_ruby/gem_paths.rb +51 -0
- data/lib/lcp_ruby/generators/entity_menu_writer.rb +258 -0
- data/lib/lcp_ruby/generators/feature_registry.rb +208 -0
- data/lib/lcp_ruby/generators/prerequisites.rb +90 -0
- data/lib/lcp_ruby/grouped_query/builder.rb +206 -0
- data/lib/lcp_ruby/grouped_query/result_wrapper.rb +72 -0
- data/lib/lcp_ruby/grouped_query/row.rb +31 -0
- data/lib/lcp_ruby/groups/change_handler.rb +18 -0
- data/lib/lcp_ruby/groups/contract.rb +42 -0
- data/lib/lcp_ruby/groups/contract_validator.rb +110 -0
- data/lib/lcp_ruby/groups/host_loader.rb +54 -0
- data/lib/lcp_ruby/groups/model_loader.rb +186 -0
- data/lib/lcp_ruby/groups/registry.rb +113 -0
- data/lib/lcp_ruby/groups/setup.rb +129 -0
- data/lib/lcp_ruby/groups/yaml_loader.rb +97 -0
- data/lib/lcp_ruby/hash_utils.rb +42 -0
- data/lib/lcp_ruby/i18n_check/configuration.rb +104 -0
- data/lib/lcp_ruby/i18n_check/heuristics.rb +26 -0
- data/lib/lcp_ruby/i18n_check/key_deriver.rb +136 -0
- data/lib/lcp_ruby/i18n_check/offense.rb +29 -0
- data/lib/lcp_ruby/i18n_check/registry_walker.rb +621 -0
- data/lib/lcp_ruby/i18n_check/reporter.rb +96 -0
- data/lib/lcp_ruby/i18n_check/runner.rb +46 -0
- data/lib/lcp_ruby/i18n_check.rb +15 -0
- data/lib/lcp_ruby/i18n_lint.rb +145 -0
- data/lib/lcp_ruby/import/auto_mapper.rb +98 -0
- data/lib/lcp_ruby/import/field_tree_builder.rb +178 -0
- data/lib/lcp_ruby/import/file_parser.rb +223 -0
- data/lib/lcp_ruby/import/import_dialog_handler.rb +410 -0
- data/lib/lcp_ruby/import/import_job_handler.rb +224 -0
- data/lib/lcp_ruby/import/row_processor.rb +281 -0
- data/lib/lcp_ruby/import/setup.rb +277 -0
- data/lib/lcp_ruby/import/value_coercer.rb +143 -0
- data/lib/lcp_ruby/import.rb +14 -0
- data/lib/lcp_ruby/json_item_wrapper.rb +152 -0
- data/lib/lcp_ruby/kanban/board.rb +28 -0
- data/lib/lcp_ruby/kanban/column.rb +28 -0
- data/lib/lcp_ruby/kanban/default_provider.rb +376 -0
- data/lib/lcp_ruby/kanban/host_provider.rb +94 -0
- data/lib/lcp_ruby/kanban/move_result.rb +52 -0
- data/lib/lcp_ruby/kanban/provider_test_harness.rb +54 -0
- data/lib/lcp_ruby/kanban/swimlane.rb +21 -0
- data/lib/lcp_ruby/menu.rb +46 -0
- data/lib/lcp_ruby/metadata/aggregate_definition.rb +6 -0
- data/lib/lcp_ruby/metadata/association_definition.rb +196 -0
- data/lib/lcp_ruby/metadata/auth_validator.rb +222 -0
- data/lib/lcp_ruby/metadata/configuration_validator.rb +7958 -0
- data/lib/lcp_ruby/metadata/contract_result.rb +9 -0
- data/lib/lcp_ruby/metadata/display_template_definition.rb +77 -0
- data/lib/lcp_ruby/metadata/enum_label_resolver.rb +27 -0
- data/lib/lcp_ruby/metadata/erd_generator.rb +274 -0
- data/lib/lcp_ruby/metadata/event_definition.rb +55 -0
- data/lib/lcp_ruby/metadata/field_definition.rb +267 -0
- data/lib/lcp_ruby/metadata/group_definition.rb +31 -0
- data/lib/lcp_ruby/metadata/i18n_label.rb +29 -0
- data/lib/lcp_ruby/metadata/loader.rb +916 -0
- data/lib/lcp_ruby/metadata/menu_definition.rb +116 -0
- data/lib/lcp_ruby/metadata/menu_item.rb +792 -0
- data/lib/lcp_ruby/metadata/menu_item_resolver.rb +105 -0
- data/lib/lcp_ruby/metadata/model_definition.rb +612 -0
- data/lib/lcp_ruby/metadata/model_hash_merger.rb +88 -0
- data/lib/lcp_ruby/metadata/model_inheritance_resolver.rb +165 -0
- data/lib/lcp_ruby/metadata/page_definition.rb +245 -0
- data/lib/lcp_ruby/metadata/path_template.rb +231 -0
- data/lib/lcp_ruby/metadata/permission_definition.rb +237 -0
- data/lib/lcp_ruby/metadata/permission_merger.rb +81 -0
- data/lib/lcp_ruby/metadata/presenter_definition.rb +689 -0
- data/lib/lcp_ruby/metadata/reserved_names.rb +79 -0
- data/lib/lcp_ruby/metadata/responsive_policy.rb +95 -0
- data/lib/lcp_ruby/metadata/schema_validator.rb +172 -0
- data/lib/lcp_ruby/metadata/validation_definition.rb +69 -0
- data/lib/lcp_ruby/metadata/view_group_definition.rb +208 -0
- data/lib/lcp_ruby/metadata/virtual_column_definition.rb +154 -0
- data/lib/lcp_ruby/metadata/zone_definition.rb +423 -0
- data/lib/lcp_ruby/metrics/collector.rb +123 -0
- data/lib/lcp_ruby/metrics/collector_registry.rb +57 -0
- data/lib/lcp_ruby/metrics/error_recorder.rb +70 -0
- data/lib/lcp_ruby/metrics/fingerprint.rb +33 -0
- data/lib/lcp_ruby/metrics/json_query.rb +47 -0
- data/lib/lcp_ruby/metrics/metric_definitions.rb +105 -0
- data/lib/lcp_ruby/metrics/prometheus_check.rb +9 -0
- data/lib/lcp_ruby/metrics/rate_limiter.rb +99 -0
- data/lib/lcp_ruby/metrics/setup.rb +71 -0
- data/lib/lcp_ruby/metrics/subscriber.rb +126 -0
- data/lib/lcp_ruby/model_factory/aggregate_applicator.rb +14 -0
- data/lib/lcp_ruby/model_factory/api_association_applicator.rb +119 -0
- data/lib/lcp_ruby/model_factory/api_builder.rb +85 -0
- data/lib/lcp_ruby/model_factory/array_type.rb +78 -0
- data/lib/lcp_ruby/model_factory/array_type_applicator.rb +33 -0
- data/lib/lcp_ruby/model_factory/association_applicator.rb +201 -0
- data/lib/lcp_ruby/model_factory/attachment_applicator.rb +160 -0
- data/lib/lcp_ruby/model_factory/auditing_applicator.rb +72 -0
- data/lib/lcp_ruby/model_factory/builder.rb +235 -0
- data/lib/lcp_ruby/model_factory/callback_applicator.rb +63 -0
- data/lib/lcp_ruby/model_factory/computed_applicator.rb +55 -0
- data/lib/lcp_ruby/model_factory/default_applicator.rb +85 -0
- data/lib/lcp_ruby/model_factory/enum_applicator.rb +24 -0
- data/lib/lcp_ruby/model_factory/inherited_parent_validator_applicator.rb +39 -0
- data/lib/lcp_ruby/model_factory/label_method_builder.rb +82 -0
- data/lib/lcp_ruby/model_factory/managed_tracking.rb +71 -0
- data/lib/lcp_ruby/model_factory/positioning_applicator.rb +23 -0
- data/lib/lcp_ruby/model_factory/ransack_applicator.rb +66 -0
- data/lib/lcp_ruby/model_factory/registry.rb +33 -0
- data/lib/lcp_ruby/model_factory/schema_manager.rb +655 -0
- data/lib/lcp_ruby/model_factory/scope_applicator.rb +87 -0
- data/lib/lcp_ruby/model_factory/sequence_applicator.rb +173 -0
- data/lib/lcp_ruby/model_factory/service_accessor_applicator.rb +40 -0
- data/lib/lcp_ruby/model_factory/soft_delete_applicator.rb +141 -0
- data/lib/lcp_ruby/model_factory/transform_applicator.rb +51 -0
- data/lib/lcp_ruby/model_factory/tree_applicator.rb +239 -0
- data/lib/lcp_ruby/model_factory/userstamps_applicator.rb +73 -0
- data/lib/lcp_ruby/model_factory/validation_applicator.rb +319 -0
- data/lib/lcp_ruby/model_factory/virtual_column_applicator.rb +79 -0
- data/lib/lcp_ruby/model_factory/workflow_applicator.rb +141 -0
- data/lib/lcp_ruby/pages/change_handler.rb +15 -0
- data/lib/lcp_ruby/pages/contract_validator.rb +74 -0
- data/lib/lcp_ruby/pages/definition_validator.rb +42 -0
- data/lib/lcp_ruby/pages/filter_form.rb +200 -0
- data/lib/lcp_ruby/pages/filter_form_validator.rb +636 -0
- data/lib/lcp_ruby/pages/registry.rb +133 -0
- data/lib/lcp_ruby/pages/resolver.rb +32 -0
- data/lib/lcp_ruby/pages/scope_context_resolver.rb +37 -0
- data/lib/lcp_ruby/pages/scope_filter_set.rb +57 -0
- data/lib/lcp_ruby/pages/setup.rb +46 -0
- data/lib/lcp_ruby/path_utils.rb +12 -0
- data/lib/lcp_ruby/permissions/change_handler.rb +22 -0
- data/lib/lcp_ruby/permissions/contract_validator.rb +74 -0
- data/lib/lcp_ruby/permissions/definition_validator.rb +119 -0
- data/lib/lcp_ruby/permissions/registry.rb +135 -0
- data/lib/lcp_ruby/permissions/setup.rb +51 -0
- data/lib/lcp_ruby/permissions/source_resolver.rb +56 -0
- data/lib/lcp_ruby/presenter/action_set.rb +236 -0
- data/lib/lcp_ruby/presenter/breadcrumb_builder.rb +183 -0
- data/lib/lcp_ruby/presenter/breadcrumb_path_helper.rb +17 -0
- data/lib/lcp_ruby/presenter/column_set.rb +268 -0
- data/lib/lcp_ruby/presenter/enrichment.rb +136 -0
- data/lib/lcp_ruby/presenter/field_value_resolver.rb +237 -0
- data/lib/lcp_ruby/presenter/includes_resolver/association_dependency.rb +59 -0
- data/lib/lcp_ruby/presenter/includes_resolver/dependency_collector.rb +394 -0
- data/lib/lcp_ruby/presenter/includes_resolver/loading_strategy.rb +70 -0
- data/lib/lcp_ruby/presenter/includes_resolver/strategy_resolver.rb +123 -0
- data/lib/lcp_ruby/presenter/includes_resolver.rb +42 -0
- data/lib/lcp_ruby/presenter/layout_builder.rb +467 -0
- data/lib/lcp_ruby/presenter/link_resolver.rb +65 -0
- data/lib/lcp_ruby/presenter/metadata_lookup.rb +28 -0
- data/lib/lcp_ruby/presenter/resolver.rb +25 -0
- data/lib/lcp_ruby/record_aliases/metadata_checker.rb +213 -0
- data/lib/lcp_ruby/record_aliases/setup.rb +212 -0
- data/lib/lcp_ruby/reserved_route_segments.rb +37 -0
- data/lib/lcp_ruby/roles/change_handler.rb +11 -0
- data/lib/lcp_ruby/roles/contract_validator.rb +67 -0
- data/lib/lcp_ruby/roles/registry.rb +89 -0
- data/lib/lcp_ruby/roles/setup.rb +50 -0
- data/lib/lcp_ruby/routing/presenter_routes.rb +104 -0
- data/lib/lcp_ruby/saved_filters/change_handler.rb +13 -0
- data/lib/lcp_ruby/saved_filters/contract_validator.rb +85 -0
- data/lib/lcp_ruby/saved_filters/registry.rb +36 -0
- data/lib/lcp_ruby/saved_filters/resolver.rb +108 -0
- data/lib/lcp_ruby/saved_filters/setup.rb +42 -0
- data/lib/lcp_ruby/saved_filters/stale_field_validator.rb +84 -0
- data/lib/lcp_ruby/schemas/auth.json +208 -0
- data/lib/lcp_ruby/schemas/menu.json +338 -0
- data/lib/lcp_ruby/schemas/model.json +1161 -0
- data/lib/lcp_ruby/schemas/page.json +877 -0
- data/lib/lcp_ruby/schemas/permission.json +454 -0
- data/lib/lcp_ruby/schemas/presenter.json +2274 -0
- data/lib/lcp_ruby/schemas/theme.json +62 -0
- data/lib/lcp_ruby/schemas/type.json +146 -0
- data/lib/lcp_ruby/schemas/view_group.json +163 -0
- data/lib/lcp_ruby/search/custom_field_filter.rb +171 -0
- data/lib/lcp_ruby/search/custom_filter_interceptor.rb +40 -0
- data/lib/lcp_ruby/search/filter_metadata_builder.rb +409 -0
- data/lib/lcp_ruby/search/filter_param_builder.rb +177 -0
- data/lib/lcp_ruby/search/operator_registry.rb +79 -0
- data/lib/lcp_ruby/search/param_sanitizer.rb +25 -0
- data/lib/lcp_ruby/search/parameter_definition.rb +187 -0
- data/lib/lcp_ruby/search/parameterized_scope_applicator.rb +129 -0
- data/lib/lcp_ruby/search/query_builder.rb +143 -0
- data/lib/lcp_ruby/search/query_language_parser.rb +549 -0
- data/lib/lcp_ruby/search/query_language_serializer.rb +193 -0
- data/lib/lcp_ruby/search/quick_search.rb +162 -0
- data/lib/lcp_ruby/search/relative_date_expander.rb +57 -0
- data/lib/lcp_ruby/search_result.rb +70 -0
- data/lib/lcp_ruby/sequences/sequence_manager.rb +51 -0
- data/lib/lcp_ruby/services/accessors/json_field.rb +23 -0
- data/lib/lcp_ruby/services/built_in_accessors.rb +17 -0
- data/lib/lcp_ruby/services/built_in_defaults.rb +22 -0
- data/lib/lcp_ruby/services/built_in_transforms.rb +20 -0
- data/lib/lcp_ruby/services/checker.rb +133 -0
- data/lib/lcp_ruby/services/registry.rb +83 -0
- data/lib/lcp_ruby/skills_installer.rb +73 -0
- data/lib/lcp_ruby/sort/enum_sort_order.rb +38 -0
- data/lib/lcp_ruby/tasks/destroy_order_resolver.rb +57 -0
- data/lib/lcp_ruby/tasks/doctor.rb +294 -0
- data/lib/lcp_ruby/tasks/permission_resolve_formatter.rb +245 -0
- data/lib/lcp_ruby/types/built_in_types.rb +157 -0
- data/lib/lcp_ruby/types/transforms/base_transform.rb +11 -0
- data/lib/lcp_ruby/types/transforms/downcase.rb +11 -0
- data/lib/lcp_ruby/types/transforms/normalize_phone.rb +19 -0
- data/lib/lcp_ruby/types/transforms/normalize_url.rb +16 -0
- data/lib/lcp_ruby/types/transforms/strip.rb +11 -0
- data/lib/lcp_ruby/types/type_definition.rb +112 -0
- data/lib/lcp_ruby/types/type_registry.rb +75 -0
- data/lib/lcp_ruby/url_safety.rb +97 -0
- data/lib/lcp_ruby/user_snapshot.rb +15 -0
- data/lib/lcp_ruby/version.rb +3 -0
- data/lib/lcp_ruby/view_slots/registry.rb +71 -0
- data/lib/lcp_ruby/view_slots/slot_component.rb +22 -0
- data/lib/lcp_ruby/view_slots/slot_context.rb +20 -0
- data/lib/lcp_ruby/virtual_columns/builder.rb +234 -0
- data/lib/lcp_ruby/virtual_columns/collector.rb +186 -0
- data/lib/lcp_ruby/virtual_columns.rb +4 -0
- data/lib/lcp_ruby/virtual_fields/synthetic_marker.rb +17 -0
- data/lib/lcp_ruby/virtual_fields/types/array_of.rb +49 -0
- data/lib/lcp_ruby/virtual_fields/virtual_field.rb +107 -0
- data/lib/lcp_ruby/virtual_fields/virtual_form.rb +144 -0
- data/lib/lcp_ruby/widgets/chart_palette.rb +25 -0
- data/lib/lcp_ruby/widgets/chartkick_check.rb +9 -0
- data/lib/lcp_ruby/widgets/data_resolver.rb +676 -0
- data/lib/lcp_ruby/widgets/date_grouper.rb +54 -0
- data/lib/lcp_ruby/widgets/presenter_zone_resolver.rb +170 -0
- data/lib/lcp_ruby/widgets/record_source_resolver.rb +56 -0
- data/lib/lcp_ruby/widgets/scope_applicator.rb +187 -0
- data/lib/lcp_ruby/workflow/approval/activation_handler.rb +39 -0
- data/lib/lcp_ruby/workflow/approval/approval_definition.rb +117 -0
- data/lib/lcp_ruby/workflow/approval/approver_resolver.rb +98 -0
- data/lib/lcp_ruby/workflow/approval/cleanup_handler.rb +37 -0
- data/lib/lcp_ruby/workflow/approval/contract_validator.rb +96 -0
- data/lib/lcp_ruby/workflow/approval/data_builder.rb +53 -0
- data/lib/lcp_ruby/workflow/approval/discard_handler.rb +51 -0
- data/lib/lcp_ruby/workflow/approval/engine.rb +314 -0
- data/lib/lcp_ruby/workflow/approval/registry.rb +40 -0
- data/lib/lcp_ruby/workflow/approval/resolution_handler.rb +103 -0
- data/lib/lcp_ruby/workflow/approval/setup.rb +138 -0
- data/lib/lcp_ruby/workflow/approval/step_definition.rb +52 -0
- data/lib/lcp_ruby/workflow/approval/step_evaluator.rb +163 -0
- data/lib/lcp_ruby/workflow/approval/system_evaluator.rb +29 -0
- data/lib/lcp_ruby/workflow/approval/task_manager.rb +202 -0
- data/lib/lcp_ruby/workflow/audit_contract_validator.rb +64 -0
- data/lib/lcp_ruby/workflow/audit_registry.rb +24 -0
- data/lib/lcp_ruby/workflow/audit_writer.rb +51 -0
- data/lib/lcp_ruby/workflow/change_handler.rb +14 -0
- data/lib/lcp_ruby/workflow/contract.rb +21 -0
- data/lib/lcp_ruby/workflow/contract_validator.rb +44 -0
- data/lib/lcp_ruby/workflow/errors.rb +12 -0
- data/lib/lcp_ruby/workflow/host_source.rb +19 -0
- data/lib/lcp_ruby/workflow/mermaid_builder.rb +217 -0
- data/lib/lcp_ruby/workflow/model_source.rb +79 -0
- data/lib/lcp_ruby/workflow/registry.rb +113 -0
- data/lib/lcp_ruby/workflow/resolver.rb +32 -0
- data/lib/lcp_ruby/workflow/setup.rb +135 -0
- data/lib/lcp_ruby/workflow/state_definition.rb +59 -0
- data/lib/lcp_ruby/workflow/state_machine.rb +78 -0
- data/lib/lcp_ruby/workflow/static_source.rb +20 -0
- data/lib/lcp_ruby/workflow/transition_action_builder.rb +46 -0
- data/lib/lcp_ruby/workflow/transition_definition.rb +70 -0
- data/lib/lcp_ruby/workflow/transition_executor.rb +140 -0
- data/lib/lcp_ruby/workflow/transition_label_resolver.rb +21 -0
- data/lib/lcp_ruby/workflow/transition_result.rb +20 -0
- data/lib/lcp_ruby/workflow/value_resolver.rb +58 -0
- data/lib/lcp_ruby/workflow/workflow_definition.rb +195 -0
- data/lib/lcp_ruby.rb +764 -0
- data/lib/rubocop/cop/lcp_ruby/no_hardcoded_i18n_string.rb +249 -0
- data/lib/tasks/lcp_ruby.rake +432 -0
- data/lib/tasks/lcp_ruby_assets.rake +37 -0
- data/lib/tasks/lcp_ruby_auth.rake +49 -0
- data/lib/tasks/lcp_ruby_db.rake +76 -0
- data/lib/tasks/lcp_ruby_doctor.rake +20 -0
- data/lib/tasks/lcp_ruby_feature_catalog.rake +61 -0
- data/lib/tasks/lcp_ruby_gapfree_sequences.rake +39 -0
- data/lib/tasks/lcp_ruby_i18n_check.rake +23 -0
- data/lib/tasks/lcp_ruby_i18n_lint.rake +20 -0
- data/lib/tasks/lcp_ruby_invariant_check.rake +72 -0
- data/vendor/assets/javascripts/lcp_ruby/activestorage.min.js +866 -0
- data/vendor/assets/javascripts/lcp_ruby/highlight.min.js +1244 -0
- data/vendor/assets/javascripts/lcp_ruby/lucide.min.js +12 -0
- data/vendor/assets/javascripts/lcp_ruby/stimulus.umd.js +2588 -0
- data/vendor/assets/javascripts/lcp_ruby/tom-select.complete.min.js +444 -0
- data/vendor/assets/stylesheets/lcp_ruby/highlight-github.min.css +12 -0
- data/vendor/assets/stylesheets/lcp_ruby/tom-select.css +412 -0
- metadata +1950 -0
|
@@ -0,0 +1,1940 @@
|
|
|
1
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
2
|
+
|
|
3
|
+
/* ===== Theme variables ===== */
|
|
4
|
+
|
|
5
|
+
/* Light theme (default) */
|
|
6
|
+
:root,
|
|
7
|
+
[data-lcp-theme="light"] {
|
|
8
|
+
color-scheme: light;
|
|
9
|
+
/* Core surfaces */
|
|
10
|
+
--lcp-bg-body: #f5f5f5;
|
|
11
|
+
--lcp-bg-surface: #fff;
|
|
12
|
+
--lcp-bg-surface-raised: #fff;
|
|
13
|
+
--lcp-bg-muted: #f8f9fa;
|
|
14
|
+
--lcp-bg-hover: #f8f9fa;
|
|
15
|
+
--lcp-bg-active: #e9ecef;
|
|
16
|
+
--lcp-bg-subtle: #f0f7ff;
|
|
17
|
+
/* Text */
|
|
18
|
+
--lcp-text: #212529;
|
|
19
|
+
--lcp-text-secondary: #495057;
|
|
20
|
+
--lcp-text-muted: #6c757d;
|
|
21
|
+
--lcp-text-on-primary: #fff;
|
|
22
|
+
--lcp-text-link: #0d6efd;
|
|
23
|
+
--lcp-text-link-hover: #0b5ed7;
|
|
24
|
+
--lcp-text-disabled: #adb5bd;
|
|
25
|
+
/* Primary / accent */
|
|
26
|
+
--lcp-primary: #0d6efd;
|
|
27
|
+
--lcp-primary-hover: #0b5ed7;
|
|
28
|
+
--lcp-primary-bg: #e8f0fe;
|
|
29
|
+
--lcp-focus-ring: rgba(13,110,253,0.25);
|
|
30
|
+
--lcp-focus-border: #86b7fe;
|
|
31
|
+
/* Borders */
|
|
32
|
+
--lcp-border-color: #dee2e6;
|
|
33
|
+
--lcp-border-color-input: #ced4da;
|
|
34
|
+
--lcp-border-color-subtle: #f0f0f0;
|
|
35
|
+
/* Semantic status */
|
|
36
|
+
--lcp-success: #198754;
|
|
37
|
+
--lcp-success-bg: #d1e7dd;
|
|
38
|
+
--lcp-success-border: #c3e6cb;
|
|
39
|
+
--lcp-success-text: #155724;
|
|
40
|
+
--lcp-danger: #dc3545;
|
|
41
|
+
--lcp-danger-hover: #bb2d3b;
|
|
42
|
+
--lcp-danger-bg: #f8d7da;
|
|
43
|
+
--lcp-danger-border: #f5c6cb;
|
|
44
|
+
--lcp-danger-text: #842029;
|
|
45
|
+
--lcp-warning: #856404;
|
|
46
|
+
--lcp-warning-bg: #fff3cd;
|
|
47
|
+
--lcp-warning-border: #ffc107;
|
|
48
|
+
--lcp-info: #004085;
|
|
49
|
+
--lcp-info-bg: #e8f4fd;
|
|
50
|
+
/* Shadows & overlays */
|
|
51
|
+
--lcp-shadow-sm: 0 1px 3px rgba(0,0,0,0.1);
|
|
52
|
+
--lcp-shadow-md: 0 2px 8px rgba(0,0,0,0.12);
|
|
53
|
+
--lcp-shadow-lg: 0 4px 16px rgba(0,0,0,0.15);
|
|
54
|
+
--lcp-overlay-bg: rgba(0,0,0,0.4);
|
|
55
|
+
/* Input aliases */
|
|
56
|
+
--lcp-input-bg: var(--lcp-bg-surface);
|
|
57
|
+
--lcp-input-border: var(--lcp-border-color-input);
|
|
58
|
+
--lcp-input-text: var(--lcp-text);
|
|
59
|
+
--lcp-input-placeholder: var(--lcp-text-muted);
|
|
60
|
+
--lcp-input-disabled-bg: var(--lcp-bg-active);
|
|
61
|
+
/* Navigation */
|
|
62
|
+
--lcp-sidebar-bg: var(--lcp-bg-surface);
|
|
63
|
+
--lcp-sidebar-active-bg: var(--lcp-bg-subtle);
|
|
64
|
+
--lcp-nav-bg: var(--lcp-bg-surface);
|
|
65
|
+
/* Special purpose */
|
|
66
|
+
--lcp-tree-guide: #ced4da;
|
|
67
|
+
--lcp-filter-depth-2: #6f42c1;
|
|
68
|
+
--lcp-filter-depth-3: #198754;
|
|
69
|
+
--lcp-badge-bg: var(--lcp-text-muted);
|
|
70
|
+
--lcp-menu-badge-bg: var(--lcp-danger);
|
|
71
|
+
--lcp-rating-color: #ffc107;
|
|
72
|
+
--lcp-toggle-off: #ccc;
|
|
73
|
+
--lcp-toggle-on: var(--lcp-primary);
|
|
74
|
+
--lcp-impersonation-bg: var(--lcp-warning-bg);
|
|
75
|
+
--lcp-impersonation-border: var(--lcp-warning-border);
|
|
76
|
+
--lcp-impersonation-text: var(--lcp-warning);
|
|
77
|
+
/* Row styling */
|
|
78
|
+
--lcp-selection-bg: #e8f0fe;
|
|
79
|
+
--lcp-info-bg-batch: var(--lcp-info-bg);
|
|
80
|
+
--lcp-toolbar-bg: var(--lcp-bg-surface);
|
|
81
|
+
--lcp-row-danger-bg: #f8d7da;
|
|
82
|
+
--lcp-row-warning-bg: #fff3cd;
|
|
83
|
+
--lcp-row-success-bg: #d1e7dd;
|
|
84
|
+
--lcp-row-info-bg: #cff4fc;
|
|
85
|
+
--lcp-row-muted-opacity: 0.55;
|
|
86
|
+
/* Density defaults (comfortable) */
|
|
87
|
+
--lcp-density-spacing: 0.75rem;
|
|
88
|
+
--lcp-density-cell-padding: 0.5rem 0.75rem;
|
|
89
|
+
--lcp-density-font-size: 0.9375rem;
|
|
90
|
+
--lcp-density-input-height: 2.375rem;
|
|
91
|
+
--lcp-density-row-height: auto;
|
|
92
|
+
/* Border radius defaults (rounded) */
|
|
93
|
+
--lcp-radius-sm: 0.25rem;
|
|
94
|
+
--lcp-radius-md: 0.375rem;
|
|
95
|
+
--lcp-radius-lg: 0.5rem;
|
|
96
|
+
--lcp-radius-pill: 50rem;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Dark theme */
|
|
100
|
+
[data-lcp-theme="dark"] {
|
|
101
|
+
color-scheme: dark;
|
|
102
|
+
--lcp-bg-body: #121212;
|
|
103
|
+
--lcp-bg-surface: #1e1e1e;
|
|
104
|
+
--lcp-bg-surface-raised: #252525;
|
|
105
|
+
--lcp-bg-muted: #2a2a2a;
|
|
106
|
+
--lcp-bg-hover: #2f2f2f;
|
|
107
|
+
--lcp-bg-active: #383838;
|
|
108
|
+
--lcp-bg-subtle: rgba(77,148,255,0.08);
|
|
109
|
+
--lcp-text: #e0e0e0;
|
|
110
|
+
--lcp-text-secondary: #a0a0a0;
|
|
111
|
+
--lcp-text-muted: #787878;
|
|
112
|
+
--lcp-text-on-primary: #fff;
|
|
113
|
+
--lcp-text-link: #6ea8fe;
|
|
114
|
+
--lcp-text-link-hover: #8bb9fe;
|
|
115
|
+
--lcp-text-disabled: #555;
|
|
116
|
+
--lcp-primary: #4d94ff;
|
|
117
|
+
--lcp-primary-hover: #6ea8fe;
|
|
118
|
+
--lcp-primary-bg: rgba(77,148,255,0.15);
|
|
119
|
+
--lcp-focus-ring: rgba(77,148,255,0.4);
|
|
120
|
+
--lcp-focus-border: #6ea8fe;
|
|
121
|
+
--lcp-border-color: #3a3a3a;
|
|
122
|
+
--lcp-border-color-input: #4a4a4a;
|
|
123
|
+
--lcp-border-color-subtle: #2e2e2e;
|
|
124
|
+
--lcp-success: #4caf7c;
|
|
125
|
+
--lcp-success-bg: rgba(76,175,124,0.15);
|
|
126
|
+
--lcp-success-border: rgba(76,175,124,0.3);
|
|
127
|
+
--lcp-success-text: #a3d9b1;
|
|
128
|
+
--lcp-danger: #e57373;
|
|
129
|
+
--lcp-danger-hover: #ef9a9a;
|
|
130
|
+
--lcp-danger-bg: rgba(229,115,115,0.15);
|
|
131
|
+
--lcp-danger-border: rgba(229,115,115,0.3);
|
|
132
|
+
--lcp-danger-text: #f5c6cb;
|
|
133
|
+
--lcp-warning: #ffc107;
|
|
134
|
+
--lcp-warning-bg: rgba(255,193,7,0.15);
|
|
135
|
+
--lcp-warning-border: rgba(255,193,7,0.3);
|
|
136
|
+
--lcp-info: #64b5f6;
|
|
137
|
+
--lcp-info-bg: rgba(100,181,246,0.15);
|
|
138
|
+
--lcp-shadow-sm: 0 1px 3px rgba(0,0,0,0.3);
|
|
139
|
+
--lcp-shadow-md: 0 2px 8px rgba(0,0,0,0.4);
|
|
140
|
+
--lcp-shadow-lg: 0 4px 16px rgba(0,0,0,0.5);
|
|
141
|
+
--lcp-overlay-bg: rgba(0,0,0,0.6);
|
|
142
|
+
--lcp-sidebar-bg: #1a1a1a;
|
|
143
|
+
--lcp-nav-bg: #1a1a1a;
|
|
144
|
+
--lcp-tree-guide: #4a4a4a;
|
|
145
|
+
--lcp-filter-depth-2: #b388ff;
|
|
146
|
+
--lcp-filter-depth-3: #4caf7c;
|
|
147
|
+
--lcp-rating-color: #ffd54f;
|
|
148
|
+
--lcp-toggle-off: #555;
|
|
149
|
+
--lcp-selection-bg: rgba(77,148,255,0.15);
|
|
150
|
+
--lcp-row-danger-bg: rgba(229,115,115,0.15);
|
|
151
|
+
--lcp-row-warning-bg: rgba(255,193,7,0.15);
|
|
152
|
+
--lcp-row-success-bg: rgba(76,175,124,0.15);
|
|
153
|
+
--lcp-row-info-bg: rgba(100,181,246,0.15);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* Density — compact override (comfortable defaults are in :root above) */
|
|
157
|
+
[data-lcp-density="compact"] {
|
|
158
|
+
--lcp-density-spacing: 0.375rem;
|
|
159
|
+
--lcp-density-cell-padding: 0.25rem 0.5rem;
|
|
160
|
+
--lcp-density-font-size: 0.8125rem;
|
|
161
|
+
--lcp-density-input-height: 1.875rem;
|
|
162
|
+
--lcp-density-row-height: auto;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* Border radius — sharp override (rounded defaults are in :root above) */
|
|
166
|
+
[data-lcp-radius="sharp"] {
|
|
167
|
+
--lcp-radius-sm: 0;
|
|
168
|
+
--lcp-radius-md: 0;
|
|
169
|
+
--lcp-radius-lg: 0;
|
|
170
|
+
--lcp-radius-pill: 0;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* ===== Base styles ===== */
|
|
174
|
+
|
|
175
|
+
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; color: var(--lcp-text); background: var(--lcp-bg-body); line-height: 1.5; }
|
|
176
|
+
.lcp-container { max-width: 1200px; margin: 0 auto; padding: 1rem 2rem; }
|
|
177
|
+
|
|
178
|
+
/* Flash messages */
|
|
179
|
+
.lcp-flash { padding: 0.75rem 1rem; margin-bottom: 1rem; border-radius: var(--lcp-radius-sm); }
|
|
180
|
+
.lcp-flash-notice { background: var(--lcp-success-bg); color: var(--lcp-success-text); border: 1px solid var(--lcp-success-border); }
|
|
181
|
+
.lcp-flash-alert { background: var(--lcp-danger-bg); color: var(--lcp-danger-text); border: 1px solid var(--lcp-danger-border); }
|
|
182
|
+
.lcp-flash-link { margin-left: 0.5rem; color: inherit; font-weight: 600; text-decoration: underline; }
|
|
183
|
+
.lcp-dialog-flash { padding: 0.5rem 0.75rem; margin-bottom: 0.75rem; font-size: 0.875rem; }
|
|
184
|
+
|
|
185
|
+
/* Breadcrumbs */
|
|
186
|
+
.lcp-breadcrumbs { margin-bottom: 0.75rem; font-size: 0.8125rem; color: var(--lcp-text-muted); }
|
|
187
|
+
.lcp-breadcrumbs ol { list-style: none; display: flex; flex-wrap: wrap; }
|
|
188
|
+
.lcp-breadcrumbs li { display: flex; align-items: center; }
|
|
189
|
+
.lcp-breadcrumbs li + li::before { content: "/"; margin: 0 0.5rem; color: var(--lcp-text-disabled); }
|
|
190
|
+
.lcp-breadcrumbs a { color: var(--lcp-text-link); text-decoration: none; }
|
|
191
|
+
.lcp-breadcrumbs a:hover { text-decoration: underline; }
|
|
192
|
+
.lcp-breadcrumbs [aria-current="page"] span { color: var(--lcp-text); font-weight: 500; }
|
|
193
|
+
|
|
194
|
+
/* Header */
|
|
195
|
+
.lcp-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; padding-bottom: 0.75rem; border-bottom: 2px solid var(--lcp-border-color); }
|
|
196
|
+
.lcp-header h1 { font-size: 1.5rem; font-weight: 600; }
|
|
197
|
+
.lcp-toolbar { display: flex; gap: 0.5rem; align-items: center; }
|
|
198
|
+
|
|
199
|
+
/* Buttons */
|
|
200
|
+
.btn { display: inline-block; padding: 0.4rem 0.9rem; border: 1px solid var(--lcp-border-color-input); border-radius: var(--lcp-radius-sm); background: var(--lcp-bg-surface); color: var(--lcp-text); text-decoration: none; font-size: 0.875rem; cursor: pointer; }
|
|
201
|
+
.btn:hover { background: var(--lcp-bg-active); }
|
|
202
|
+
.btn-primary { background: var(--lcp-primary); color: var(--lcp-text-on-primary); border-color: var(--lcp-primary); }
|
|
203
|
+
.btn-primary:hover { background: var(--lcp-primary-hover); }
|
|
204
|
+
.btn-danger, button.btn-danger { background: var(--lcp-danger); color: var(--lcp-text-on-primary); border-color: var(--lcp-danger); padding: 0.4rem 0.9rem; border-radius: var(--lcp-radius-sm); font-size: 0.875rem; cursor: pointer; }
|
|
205
|
+
.btn-danger:hover { background: var(--lcp-danger-hover); }
|
|
206
|
+
.btn-filter { margin-right: 0.25rem; }
|
|
207
|
+
.btn-filter.active { background: var(--lcp-primary); color: var(--lcp-text-on-primary); border-color: var(--lcp-primary); }
|
|
208
|
+
|
|
209
|
+
/* Tables */
|
|
210
|
+
.lcp-table { width: 100%; border-collapse: collapse; background: var(--lcp-bg-surface); border-radius: var(--lcp-radius-sm); box-shadow: var(--lcp-shadow-sm); }
|
|
211
|
+
.lcp-table th, .lcp-table td { padding: var(--lcp-density-cell-padding); text-align: left; border-bottom: 1px solid var(--lcp-border-color); }
|
|
212
|
+
.lcp-table th { background: var(--lcp-bg-muted); font-weight: 600; font-size: 0.8rem; text-transform: uppercase; color: var(--lcp-text-muted); }
|
|
213
|
+
.lcp-table thead th { position: sticky; top: 0; z-index: 10; background: var(--lcp-bg-muted); }
|
|
214
|
+
.lcp-table th a { color: var(--lcp-text-muted); text-decoration: none; }
|
|
215
|
+
.lcp-table th a:hover { color: var(--lcp-text); }
|
|
216
|
+
.lcp-table th a.lcp-sorted { color: var(--lcp-text); }
|
|
217
|
+
.lcp-sort-icon { display: inline-block; margin-left: 0.25rem; font-size: 0.65rem; vertical-align: middle; }
|
|
218
|
+
.lcp-sort-icon.lcp-sort-asc::after { content: "\25B2"; }
|
|
219
|
+
.lcp-sort-icon.lcp-sort-desc::after { content: "\25BC"; }
|
|
220
|
+
.lcp-table tr:hover { background: var(--lcp-bg-hover); }
|
|
221
|
+
.lcp-actions { white-space: nowrap; }
|
|
222
|
+
.lcp-actions a { color: var(--lcp-text-link); text-decoration: none; font-size: 0.875rem; margin-right: 0.5rem; }
|
|
223
|
+
.lcp-actions form { display: inline; margin-right: 0.5rem; }
|
|
224
|
+
.lcp-actions form:last-child, .lcp-actions a:last-child { margin-right: 0; }
|
|
225
|
+
.lcp-actions button { font-size: 0.8rem; padding: 0.2rem 0.5rem; }
|
|
226
|
+
|
|
227
|
+
/* Badges */
|
|
228
|
+
.badge { display: inline-block; padding: 0.2rem 0.6rem; border-radius: 12px; background: var(--lcp-badge-bg); color: var(--lcp-text-on-primary); font-size: 0.75rem; font-weight: 500; }
|
|
229
|
+
|
|
230
|
+
/* Search */
|
|
231
|
+
.lcp-search { margin-bottom: 1rem; }
|
|
232
|
+
.lcp-search-form { display: flex; flex-direction: column; gap: 0.75rem; }
|
|
233
|
+
/* Search parameter grid — outer grid uses repeat(N, auto 1fr); each parameter uses subgrid */
|
|
234
|
+
.lcp-search-parameter { display: grid; grid-template-columns: subgrid; grid-column: span 2; align-items: center; }
|
|
235
|
+
.lcp-search-parameter > :nth-child(2) { grid-column: 2 / -1; }
|
|
236
|
+
.lcp-search-parameter label { font-size: 0.75rem; color: var(--lcp-text-muted); white-space: nowrap; }
|
|
237
|
+
.lcp-search-parameter select,
|
|
238
|
+
.lcp-search-parameter input[type="text"],
|
|
239
|
+
.lcp-search-parameter input[type="number"],
|
|
240
|
+
.lcp-search-parameter input[type="date"] { padding: 0.35rem 0.5rem; border: 1px solid var(--lcp-border-color-input); border-radius: var(--lcp-radius-sm); font-size: 0.875rem; height: 2rem; box-sizing: border-box; width: 100%; }
|
|
241
|
+
.lcp-search-qs input[type="text"] { min-width: 200px; }
|
|
242
|
+
.lcp-search-range-group { display: flex; align-items: center; gap: 0.25rem; }
|
|
243
|
+
.lcp-search-range-input { width: 7rem; }
|
|
244
|
+
.lcp-range-separator { font-size: 0.85rem; color: var(--lcp-text-disabled); line-height: 2rem; }
|
|
245
|
+
.lcp-filters { margin-bottom: 1rem; display: flex; flex-wrap: wrap; gap: 0.25rem; }
|
|
246
|
+
|
|
247
|
+
/* Forms */
|
|
248
|
+
.lcp-form-section { border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); padding: var(--lcp-density-spacing); margin-bottom: var(--lcp-density-spacing); background: var(--lcp-bg-surface); }
|
|
249
|
+
.lcp-form-section legend { font-weight: 600; padding: 0 0.5rem; }
|
|
250
|
+
.lcp-form-field { margin-bottom: var(--lcp-density-spacing); }
|
|
251
|
+
.lcp-form-field label { display: block; font-weight: 500; margin-bottom: 0.25rem; font-size: 0.875rem; }
|
|
252
|
+
.lcp-form-field input, .lcp-form-field textarea, .lcp-form-field select { width: 100%; padding: var(--lcp-density-cell-padding); border: 1px solid var(--lcp-border-color-input); border-radius: var(--lcp-radius-sm); font-size: var(--lcp-density-font-size); background: var(--lcp-input-bg); color: var(--lcp-input-text); }
|
|
253
|
+
.lcp-form-field input[type="checkbox"] { width: auto; }
|
|
254
|
+
.lcp-form-field input[type="range"] { padding: 0; }
|
|
255
|
+
.lcp-form-field textarea { min-height: 80px; }
|
|
256
|
+
.lcp-form-actions { margin-top: 1rem; display: flex; gap: 0.5rem; }
|
|
257
|
+
|
|
258
|
+
/* Errors */
|
|
259
|
+
.lcp-errors { background: var(--lcp-danger-bg); border: 1px solid var(--lcp-danger-border); border-radius: var(--lcp-radius-sm); padding: 0.75rem 1rem; margin-bottom: 1rem; color: var(--lcp-danger-text); }
|
|
260
|
+
.lcp-errors h3 { font-size: 0.9rem; margin-bottom: 0.5rem; }
|
|
261
|
+
.lcp-errors ul { margin-left: 1.25rem; font-size: 0.875rem; }
|
|
262
|
+
|
|
263
|
+
/* Show view */
|
|
264
|
+
.lcp-section { background: var(--lcp-bg-surface); border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); padding: var(--lcp-density-spacing); margin-bottom: var(--lcp-density-spacing); }
|
|
265
|
+
.lcp-section h2 { font-size: 1.1rem; margin-bottom: var(--lcp-density-spacing); padding-bottom: 0.5rem; border-bottom: 1px solid var(--lcp-border-color-subtle); }
|
|
266
|
+
.lcp-field { margin-bottom: var(--lcp-density-spacing); }
|
|
267
|
+
.lcp-field label { display: block; font-size: 0.75rem; text-transform: uppercase; color: var(--lcp-text-muted); font-weight: 600; }
|
|
268
|
+
.lcp-field-value { font-size: var(--lcp-density-font-size); }
|
|
269
|
+
|
|
270
|
+
/* Display types */
|
|
271
|
+
.lcp-code { background: var(--lcp-bg-muted); padding: 0.1em 0.4em; border-radius: 3px; font-family: monospace; font-size: 0.875em; }
|
|
272
|
+
pre.lcp-code-block { display: block; padding: 0.75em 1em; overflow-x: auto; white-space: pre; margin: 0; }
|
|
273
|
+
|
|
274
|
+
/* Copy-code renderer (token display, recovery codes, etc.) */
|
|
275
|
+
.lcp-copy-code { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin: 0.75rem 0; }
|
|
276
|
+
.lcp-copy-code__value { flex: 1 1 auto; min-width: 0; background: var(--lcp-bg-muted); padding: 0.5rem 0.75rem; border-radius: var(--lcp-radius-sm); font-family: monospace; font-size: 0.875em; word-break: break-all; overflow-wrap: anywhere; user-select: all; }
|
|
277
|
+
.lcp-copy-code__btn { flex: 0 0 auto; }
|
|
278
|
+
.lcp-copy-code__btn--copied { color: var(--lcp-success); }
|
|
279
|
+
.lcp-bool-true { color: var(--lcp-success); font-weight: 500; }
|
|
280
|
+
.lcp-bool-false { color: var(--lcp-danger); font-weight: 500; }
|
|
281
|
+
.lcp-bool-glyph { font-weight: 600; font-size: 1.1em; line-height: 1; display: inline-flex; align-items: center; }
|
|
282
|
+
.lcp-bool-glyph svg { width: 1em; height: 1em; stroke-width: 2.5; }
|
|
283
|
+
.lcp-progress-bar { background: var(--lcp-bg-active); border-radius: var(--lcp-radius-sm); overflow: hidden; height: 1.25rem; }
|
|
284
|
+
.lcp-progress-fill { background: var(--lcp-primary); height: 100%; display: flex; align-items: center; justify-content: center; color: var(--lcp-text-on-primary); font-size: 0.7rem; font-weight: 500; min-width: 2em; transition: width 0.3s; }
|
|
285
|
+
.lcp-avatar { border-radius: 50%; object-fit: cover; }
|
|
286
|
+
.lcp-rating-display { color: var(--lcp-rating-color); font-size: 1.1em; letter-spacing: 0.1em; }
|
|
287
|
+
|
|
288
|
+
/* Input group (prefix/suffix) */
|
|
289
|
+
.lcp-input-group { display: flex; align-items: stretch; }
|
|
290
|
+
.lcp-input-group input, .lcp-input-group select { flex: 1; border-radius: 0; }
|
|
291
|
+
.lcp-input-prefix, .lcp-input-suffix { display: flex; align-items: center; padding: 0 0.5rem; background: var(--lcp-bg-active); border: 1px solid var(--lcp-border-color-input); font-size: 0.875rem; color: var(--lcp-text-muted); white-space: nowrap; }
|
|
292
|
+
.lcp-input-prefix { border-right: none; border-radius: var(--lcp-radius-sm) 0 0 var(--lcp-radius-sm); }
|
|
293
|
+
.lcp-input-suffix { border-left: none; border-radius: 0 var(--lcp-radius-sm) var(--lcp-radius-sm) 0; }
|
|
294
|
+
.lcp-input-group input:first-child, .lcp-input-group select:first-child { border-radius: var(--lcp-radius-sm) 0 0 var(--lcp-radius-sm); }
|
|
295
|
+
.lcp-input-group input:last-child, .lcp-input-group select:last-child { border-radius: 0 var(--lcp-radius-sm) var(--lcp-radius-sm) 0; }
|
|
296
|
+
|
|
297
|
+
/* Field hint */
|
|
298
|
+
.lcp-field-hint { display: block; font-size: 0.75rem; color: var(--lcp-text-muted); margin-top: 0.2rem; }
|
|
299
|
+
|
|
300
|
+
/* Readonly value */
|
|
301
|
+
.lcp-readonly-value { padding: 0.4rem 0; font-size: 0.875rem; color: var(--lcp-text-muted); }
|
|
302
|
+
|
|
303
|
+
/* Character counter */
|
|
304
|
+
.lcp-char-counter { display: block; font-size: 0.7rem; color: var(--lcp-text-muted); text-align: right; margin-top: 0.15rem; }
|
|
305
|
+
|
|
306
|
+
/* Radio group */
|
|
307
|
+
.lcp-radio-group { display: flex; gap: 1rem; flex-wrap: wrap; }
|
|
308
|
+
.lcp-radio-label { display: inline-flex; align-items: center; gap: 0.3rem; cursor: pointer; font-size: 0.875rem; }
|
|
309
|
+
|
|
310
|
+
/* Toggle switch */
|
|
311
|
+
.lcp-toggle { position: relative; display: inline-block; width: 44px; height: 24px; cursor: pointer; }
|
|
312
|
+
.lcp-toggle-input { opacity: 0; width: 0; height: 0; position: absolute; }
|
|
313
|
+
.lcp-toggle-slider { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: var(--lcp-toggle-off); border-radius: 24px; transition: background 0.2s; }
|
|
314
|
+
.lcp-toggle-slider::before { content: ""; position: absolute; width: 18px; height: 18px; left: 3px; bottom: 3px; background: var(--lcp-bg-surface); border-radius: 50%; transition: transform 0.2s; }
|
|
315
|
+
.lcp-toggle-input:checked + .lcp-toggle-slider { background: var(--lcp-toggle-on); }
|
|
316
|
+
.lcp-toggle-input:checked + .lcp-toggle-slider::before { transform: translateX(20px); }
|
|
317
|
+
|
|
318
|
+
/* Slider */
|
|
319
|
+
.lcp-slider-wrapper { display: flex; align-items: center; gap: 0.5rem; }
|
|
320
|
+
.lcp-slider { flex: 1; }
|
|
321
|
+
.lcp-slider-value { font-size: 0.875rem; color: var(--lcp-text); min-width: 2em; text-align: right; }
|
|
322
|
+
|
|
323
|
+
/* Divider */
|
|
324
|
+
.lcp-divider { position: relative; margin: 0.5rem 0; }
|
|
325
|
+
.lcp-divider hr { border: none; border-top: 1px solid var(--lcp-border-color); }
|
|
326
|
+
.lcp-divider-label { position: absolute; top: -0.6em; left: 1rem; background: var(--lcp-bg-surface); padding: 0 0.5rem; font-size: 0.75rem; color: var(--lcp-text-muted); }
|
|
327
|
+
|
|
328
|
+
/* Tabs */
|
|
329
|
+
.lcp-tabs { margin-bottom: 1rem; }
|
|
330
|
+
.lcp-tab-nav { display: flex; gap: 0; border-bottom: 2px solid var(--lcp-border-color); margin-bottom: 0; }
|
|
331
|
+
.lcp-tab-nav .btn { border: 1px solid transparent; border-bottom: none; border-radius: var(--lcp-radius-sm) var(--lcp-radius-sm) 0 0; background: transparent; color: var(--lcp-text-muted); margin-bottom: -2px; }
|
|
332
|
+
.lcp-tab-nav .btn.active { background: var(--lcp-bg-surface); color: var(--lcp-text); border-color: var(--lcp-border-color); border-bottom-color: var(--lcp-bg-surface); font-weight: 600; }
|
|
333
|
+
.lcp-tab-nav .btn:hover { color: var(--lcp-text); }
|
|
334
|
+
|
|
335
|
+
/* Collapsible */
|
|
336
|
+
.lcp-collapsible legend { cursor: pointer; }
|
|
337
|
+
.lcp-collapse-toggle { background: none; border: none; cursor: pointer; font-weight: 600; font-size: inherit; padding: 0; color: inherit; }
|
|
338
|
+
.lcp-collapse-icon::after { content: " \25BC"; font-size: 0.7em; }
|
|
339
|
+
.lcp-collapsed .lcp-collapse-icon::after { content: " \25B6"; }
|
|
340
|
+
|
|
341
|
+
/* View & section descriptions */
|
|
342
|
+
.lcp-view-description { color: var(--lcp-text-muted); font-size: 0.9rem; margin-bottom: 1rem; line-height: 1.5; }
|
|
343
|
+
.lcp-section-description { color: var(--lcp-text-muted); font-size: 0.85rem; margin-bottom: 0.75rem; line-height: 1.4; }
|
|
344
|
+
.lcp-info-text { background: var(--lcp-info-bg); border-left: 3px solid var(--lcp-primary); padding: 0.5rem 0.75rem; border-radius: 0 var(--lcp-radius-sm) var(--lcp-radius-sm) 0; font-size: 0.85rem; color: var(--lcp-text-secondary); line-height: 1.4; margin: 0.25rem 0; }
|
|
345
|
+
|
|
346
|
+
/* Empty state */
|
|
347
|
+
.lcp-empty-state { text-align: center; padding: 3rem 1rem; background: var(--lcp-bg-surface); border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); color: var(--lcp-text-muted); }
|
|
348
|
+
.lcp-empty-state p { font-size: 1rem; }
|
|
349
|
+
|
|
350
|
+
/* Row clickable */
|
|
351
|
+
.lcp-row-clickable { cursor: pointer; }
|
|
352
|
+
.lcp-row-clickable:hover { background: var(--lcp-bg-active) !important; }
|
|
353
|
+
|
|
354
|
+
/* Summary row */
|
|
355
|
+
.lcp-summary-row { background: var(--lcp-bg-muted); font-weight: 600; }
|
|
356
|
+
.lcp-summary-row td { border-top: 2px solid var(--lcp-border-color); }
|
|
357
|
+
|
|
358
|
+
/* Pinned column */
|
|
359
|
+
.lcp-pinned-left { position: sticky; left: 0; background: inherit; z-index: 1; }
|
|
360
|
+
|
|
361
|
+
/* Actions dropdown */
|
|
362
|
+
.lcp-actions-dropdown { position: relative; display: inline-block; }
|
|
363
|
+
.lcp-form-actions .lcp-dropdown-toggle { line-height: 21px; }
|
|
364
|
+
.lcp-form-actions .lcp-dropdown-toggle::after { content: "\25BE"; margin-left: 0.3em; }
|
|
365
|
+
.lcp-dropdown-menu { display: none; position: absolute; right: 0; top: 100%; background: var(--lcp-bg-surface-raised); border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); box-shadow: var(--lcp-shadow-md); min-width: 120px; z-index: 10; }
|
|
366
|
+
.lcp-actions-dropdown.open .lcp-dropdown-menu { display: block; }
|
|
367
|
+
.lcp-dropdown-item { display: block; padding: 0.4rem 0.75rem; text-decoration: none; color: var(--lcp-text); font-size: 0.875rem; border: none; background: none; width: 100%; text-align: left; cursor: pointer; }
|
|
368
|
+
.lcp-dropdown-item:hover { background: var(--lcp-bg-hover); }
|
|
369
|
+
.lcp-dropdown-item.btn-danger, .lcp-dropdown-menu button.btn-danger { background: none; border: none; color: var(--lcp-danger); padding: 0.4rem 0.75rem; font-size: 0.875rem; width: 100%; text-align: left; cursor: pointer; }
|
|
370
|
+
.lcp-dropdown-menu button.btn-danger:hover { background: var(--lcp-bg-hover); }
|
|
371
|
+
.lcp-dropdown-menu form.lcp-dropdown-item { padding: 0; margin: 0; }
|
|
372
|
+
.lcp-dropdown-menu button.lcp-dropdown-item { display: block; padding: 0.4rem 0.75rem; text-decoration: none; color: var(--lcp-text); font-size: 0.875rem; border: none; background: none; width: 100%; text-align: left; cursor: pointer; }
|
|
373
|
+
.lcp-dropdown-menu button.lcp-dropdown-item:hover { background: var(--lcp-bg-hover); }
|
|
374
|
+
|
|
375
|
+
/* Nested forms */
|
|
376
|
+
.lcp-nested-section { background: var(--lcp-bg-surface); }
|
|
377
|
+
.lcp-nested-container { margin-bottom: 0.5rem; }
|
|
378
|
+
.lcp-nested-row { display: flex; align-items: flex-end; gap: 0.5rem; padding: 0.5rem; border: 1px solid var(--lcp-bg-active); border-radius: var(--lcp-radius-sm); margin-bottom: 0.5rem; background: var(--lcp-bg-muted); }
|
|
379
|
+
.lcp-nested-row.removed { display: none !important; }
|
|
380
|
+
.lcp-nested-fields { flex: 1; }
|
|
381
|
+
.lcp-nested-remove { flex-shrink: 0; align-self: flex-end; margin-bottom: 0.75rem; }
|
|
382
|
+
.lcp-nested-add { margin-top: 0.5rem; }
|
|
383
|
+
.lcp-empty-nested { color: var(--lcp-text-muted); font-style: italic; padding: 0.5rem 0; }
|
|
384
|
+
|
|
385
|
+
/* Drag and drop */
|
|
386
|
+
.lcp-drag-handle { cursor: grab; font-size: 1.2rem; color: var(--lcp-text-disabled); user-select: none; flex-shrink: 0; align-self: center; padding: 0 0.25rem; }
|
|
387
|
+
.lcp-drag-handle:active { cursor: grabbing; }
|
|
388
|
+
.lcp-nested-row.dragging { opacity: 0.4; }
|
|
389
|
+
.lcp-nested-row.drag-over { border-top: 2px solid var(--lcp-primary); }
|
|
390
|
+
.lcp-nested-row.drag-over-bottom { border-bottom: 2px solid var(--lcp-primary); }
|
|
391
|
+
|
|
392
|
+
/* Conditionally disabled */
|
|
393
|
+
.lcp-conditionally-disabled { position: relative; opacity: 0.6; }
|
|
394
|
+
.lcp-conditionally-disabled input, .lcp-conditionally-disabled select,
|
|
395
|
+
.lcp-conditionally-disabled textarea { pointer-events: none; }
|
|
396
|
+
.lcp-conditionally-disabled::after {
|
|
397
|
+
content: ""; position: absolute; inset: 0; cursor: not-allowed;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/* Inline action buttons in tables (rendered without .btn class) */
|
|
401
|
+
.lcp-actions form button { cursor: pointer; }
|
|
402
|
+
|
|
403
|
+
/* Disabled action */
|
|
404
|
+
.btn.lcp-action-disabled { opacity: 0.5; pointer-events: none; cursor: not-allowed; }
|
|
405
|
+
|
|
406
|
+
/* Invisible form wrapper for button_to (prevents double border) */
|
|
407
|
+
.lcp-btn-form { display: inline; margin: 0; padding: 0; border: none; background: none; }
|
|
408
|
+
|
|
409
|
+
/* Workflow transition comment dropdown */
|
|
410
|
+
.lcp-transition-comment-wrapper { display: inline-block; position: relative; }
|
|
411
|
+
.lcp-transition-comment { display: inline-block; }
|
|
412
|
+
.lcp-transition-comment summary { list-style: none; }
|
|
413
|
+
.lcp-transition-comment summary::-webkit-details-marker { display: none; }
|
|
414
|
+
.lcp-transition-comment[open] .lcp-transition-comment-body {
|
|
415
|
+
display: flex; flex-direction: column; gap: 0.5rem;
|
|
416
|
+
position: absolute; right: 0; top: calc(100% + 4px); z-index: 10;
|
|
417
|
+
background: var(--lcp-bg-surface-raised); border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-md);
|
|
418
|
+
padding: 0.75rem; box-shadow: var(--lcp-shadow-md);
|
|
419
|
+
min-width: 260px;
|
|
420
|
+
}
|
|
421
|
+
.lcp-transition-comment-body textarea {
|
|
422
|
+
width: 100%; min-height: 60px; padding: 0.4rem 0.5rem;
|
|
423
|
+
border: 1px solid var(--lcp-border-color-input); border-radius: var(--lcp-radius-sm); font-size: 0.875rem;
|
|
424
|
+
resize: vertical;
|
|
425
|
+
}
|
|
426
|
+
.lcp-transition-comment-body button { align-self: flex-end; }
|
|
427
|
+
|
|
428
|
+
/* Loading state for dependent selects */
|
|
429
|
+
.lcp-loading { opacity: 0.5; cursor: wait; }
|
|
430
|
+
|
|
431
|
+
/* Multi-select validation error */
|
|
432
|
+
.lcp-multi-select-error { display: block; color: var(--lcp-danger); font-size: 0.75rem; margin-top: 0.2rem; }
|
|
433
|
+
|
|
434
|
+
/* Inline create dialog */
|
|
435
|
+
.lcp-inline-dialog { border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-lg); padding: 1.5rem; max-width: 500px; width: 90vw; background: var(--lcp-bg-surface-raised); }
|
|
436
|
+
.lcp-inline-dialog::backdrop { background: var(--lcp-overlay-bg); }
|
|
437
|
+
.lcp-inline-dialog h3 { margin-bottom: 1rem; font-size: 1.1rem; }
|
|
438
|
+
.lcp-inline-dialog .lcp-form-field { margin-bottom: var(--lcp-density-spacing); }
|
|
439
|
+
.lcp-inline-dialog .lcp-form-field label { display: block; font-weight: 500; margin-bottom: 0.25rem; font-size: 0.875rem; }
|
|
440
|
+
.lcp-inline-dialog .lcp-form-field input,
|
|
441
|
+
.lcp-inline-dialog .lcp-form-field textarea,
|
|
442
|
+
.lcp-inline-dialog .lcp-form-field select { width: 100%; padding: var(--lcp-density-cell-padding); border: 1px solid var(--lcp-border-color-input); border-radius: var(--lcp-radius-sm); font-size: var(--lcp-density-font-size); }
|
|
443
|
+
.lcp-inline-dialog .lcp-form-field input[type="checkbox"] { width: auto; }
|
|
444
|
+
.lcp-dialog-actions { display: flex; gap: 0.5rem; justify-content: flex-end; margin-top: 1rem; }
|
|
445
|
+
.lcp-dialog-errors { background: var(--lcp-danger-bg); border: 1px solid var(--lcp-danger-border); border-radius: var(--lcp-radius-sm); padding: 0.5rem 0.75rem; margin-bottom: 0.75rem; color: var(--lcp-danger-text); font-size: 0.875rem; display: none; }
|
|
446
|
+
.lcp-ts-add-new { border-top: 1px solid var(--lcp-border-color); padding: 0.4rem 0.5rem; }
|
|
447
|
+
.lcp-ts-add-new-btn { background: none; border: none; color: var(--lcp-text-link); cursor: pointer; font-size: 0.875rem; padding: 0.25rem 0.5rem; width: 100%; text-align: left; }
|
|
448
|
+
.lcp-ts-add-new-btn:hover { background: var(--lcp-bg-hover); }
|
|
449
|
+
|
|
450
|
+
/* Dialog modal */
|
|
451
|
+
.lcp-dialog { border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-lg); padding: 0; margin: auto; box-shadow: var(--lcp-shadow-lg); background: var(--lcp-bg-surface-raised); }
|
|
452
|
+
.lcp-dialog::backdrop { background: var(--lcp-overlay-bg); }
|
|
453
|
+
.lcp-dialog-small { width: 400px; max-width: 90vw; }
|
|
454
|
+
.lcp-dialog-medium { width: 600px; max-width: 90vw; }
|
|
455
|
+
.lcp-dialog-large { width: 800px; max-width: 90vw; }
|
|
456
|
+
.lcp-dialog-fullscreen { width: 95vw; height: 90vh; }
|
|
457
|
+
.lcp-dialog-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem 1.5rem; border-bottom: 1px solid var(--lcp-border-color); }
|
|
458
|
+
.lcp-dialog-header h3 { margin: 0; font-size: 1.1rem; font-weight: 600; }
|
|
459
|
+
.lcp-dialog-close { background: none; border: none; font-size: 1.5rem; cursor: pointer; color: var(--lcp-text-muted); padding: 0; line-height: 1; }
|
|
460
|
+
.lcp-dialog-close:hover { color: var(--lcp-text); }
|
|
461
|
+
.lcp-dialog-body { padding: 1.25rem 1.5rem; overflow-y: auto; max-height: 70vh; }
|
|
462
|
+
.lcp-dialog .lcp-dialog-actions { display: flex; gap: 0.5rem; justify-content: flex-end; margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--lcp-border-color); }
|
|
463
|
+
.lcp-dialog .lcp-form-field { margin-bottom: 0.5rem; }
|
|
464
|
+
.lcp-dialog .lcp-form-field:last-child { margin-bottom: 0; }
|
|
465
|
+
.lcp-dialog .lcp-form-section { border: none; padding: 0; margin-bottom: 0; background: transparent; }
|
|
466
|
+
.lcp-dialog .lcp-form-section legend { display: none; }
|
|
467
|
+
.lcp-dialog .lcp-form-field textarea { min-height: 44px; }
|
|
468
|
+
/* Export dialog: show section borders for visual grouping */
|
|
469
|
+
.lcp-dialog [data-controller="lcp-export-dialog"] .lcp-form-section { border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); padding: 0.75rem; margin-bottom: 0.75rem; background: var(--lcp-bg-muted); }
|
|
470
|
+
.lcp-dialog [data-controller="lcp-export-dialog"] .lcp-form-section legend { display: block; font-weight: 600; font-size: 0.85rem; padding: 0 0.35rem; color: var(--lcp-text-secondary); }
|
|
471
|
+
.lcp-dialog .lcp-form-field:has(.lcp-toggle) { display: flex; align-items: center; gap: 0.75rem; }
|
|
472
|
+
.lcp-dialog .lcp-form-field:has(.lcp-toggle) label:first-child { margin-bottom: 0; }
|
|
473
|
+
.lcp-dialog .lcp-errors { background: var(--lcp-danger-bg); border: 1px solid var(--lcp-danger-border); border-radius: var(--lcp-radius-sm); padding: 0.5rem 0.75rem; margin-bottom: 0.75rem; color: var(--lcp-danger-text); font-size: 0.875rem; }
|
|
474
|
+
.lcp-dialog .lcp-errors ul { margin: 0; padding-left: 1.25rem; }
|
|
475
|
+
|
|
476
|
+
/* Confirmation dialog */
|
|
477
|
+
#lcp-confirm-dialog .lcp-dialog-body p { margin-bottom: 0; font-size: 0.9375rem; color: var(--lcp-text-secondary); }
|
|
478
|
+
|
|
479
|
+
/* Legacy (archived) options */
|
|
480
|
+
.lcp-legacy-option { font-style: italic; color: var(--lcp-text-disabled); }
|
|
481
|
+
.ts-wrapper .ts-dropdown .option.lcp-legacy-option { font-style: italic; color: var(--lcp-text-disabled); }
|
|
482
|
+
|
|
483
|
+
/* Tree select */
|
|
484
|
+
.lcp-tree-select-wrapper { position: relative; width: 100%; }
|
|
485
|
+
.lcp-tree-trigger { width: 100%; padding: 0.4rem 0.75rem; border: 1px solid var(--lcp-border-color-input); border-radius: var(--lcp-radius-sm); background: var(--lcp-input-bg); cursor: pointer; text-align: left; font-size: 0.875rem; color: var(--lcp-text); }
|
|
486
|
+
.lcp-tree-trigger:hover { border-color: var(--lcp-focus-border); }
|
|
487
|
+
.lcp-tree-dropdown { display: none; position: absolute; z-index: 20; top: 100%; left: 0; right: 0; max-height: 300px; overflow-y: auto; background: var(--lcp-bg-surface-raised); border: 1px solid var(--lcp-border-color-input); border-radius: var(--lcp-radius-sm); box-shadow: var(--lcp-shadow-md); margin-top: 2px; }
|
|
488
|
+
.lcp-tree-dropdown.open { display: block; }
|
|
489
|
+
.lcp-tree-node { }
|
|
490
|
+
.lcp-tree-item { display: flex; align-items: center; padding: 0.35rem 0.5rem; cursor: pointer; font-size: 0.875rem; }
|
|
491
|
+
.lcp-tree-item:hover { background: var(--lcp-bg-active); }
|
|
492
|
+
.lcp-tree-item.selected { background: var(--lcp-primary); color: var(--lcp-text-on-primary); }
|
|
493
|
+
.lcp-tree-toggle { width: 1.2rem; text-align: center; flex-shrink: 0; font-size: 0.65rem; color: var(--lcp-text-muted); cursor: pointer; }
|
|
494
|
+
.lcp-tree-item.selected .lcp-tree-toggle { color: var(--lcp-text-on-primary); }
|
|
495
|
+
.lcp-tree-label { flex: 1; }
|
|
496
|
+
.lcp-tree-children { padding-left: 1.2rem; }
|
|
497
|
+
.lcp-tree-children.collapsed { display: none; }
|
|
498
|
+
|
|
499
|
+
/* Tom Select overrides */
|
|
500
|
+
.ts-wrapper { font-size: 0.875rem; }
|
|
501
|
+
.ts-wrapper .ts-control { border: 1px solid var(--lcp-border-color-input); border-radius: var(--lcp-radius-sm); padding: var(--lcp-density-cell-padding); min-height: var(--lcp-density-input-height); background: var(--lcp-input-bg); }
|
|
502
|
+
.ts-wrapper .ts-control input { font-size: 0.875rem; }
|
|
503
|
+
.lcp-form-field .ts-wrapper .ts-control > input { width: 0; min-width: 0; }
|
|
504
|
+
.ts-wrapper.focus .ts-control { border-color: var(--lcp-focus-border); box-shadow: 0 0 0 0.2rem var(--lcp-focus-ring); }
|
|
505
|
+
.ts-wrapper .ts-dropdown { border: 1px solid var(--lcp-border-color-input); border-radius: var(--lcp-radius-sm); font-size: 0.875rem; background: var(--lcp-bg-surface-raised); }
|
|
506
|
+
.ts-wrapper .ts-dropdown .active { background: var(--lcp-bg-active); color: var(--lcp-text); }
|
|
507
|
+
.ts-wrapper .ts-dropdown .option[data-disabled] { opacity: 0.5; cursor: not-allowed; }
|
|
508
|
+
.ts-wrapper .ts-dropdown .no-results { padding: 0.5rem 0.75rem; color: var(--lcp-text-muted); font-style: italic; }
|
|
509
|
+
.ts-wrapper .ts-dropdown .loading-more-results { padding: 0.5rem 0.75rem; color: var(--lcp-text-muted); text-align: center; }
|
|
510
|
+
.ts-wrapper.multi .ts-control .item { background: var(--lcp-bg-active); border: 1px solid var(--lcp-border-color-input); border-radius: 3px; padding: 0.1rem 0.4rem; font-size: 0.8rem; }
|
|
511
|
+
.ts-wrapper.multi .ts-control .item .remove { border-left: 1px solid var(--lcp-border-color-input); margin-left: 0.3rem; }
|
|
512
|
+
/* Tom Select base CSS hardcodes #303030 / #495c68 / etc. text colors which
|
|
513
|
+
are unreadable on dark surfaces. These overrides theme the text + active
|
|
514
|
+
row + dropdown header against the same theme variables the rest of the
|
|
515
|
+
project uses, so the selectbox follows light/dark mode like every other input. */
|
|
516
|
+
.ts-wrapper .ts-control,
|
|
517
|
+
.ts-wrapper .ts-control input,
|
|
518
|
+
.ts-wrapper .ts-dropdown,
|
|
519
|
+
.ts-wrapper .ts-dropdown .option,
|
|
520
|
+
.ts-wrapper .ts-dropdown .optgroup-header,
|
|
521
|
+
.ts-wrapper.multi .ts-control .item { color: var(--lcp-text); }
|
|
522
|
+
/* Tom Select resets a single-select .ts-control bg to #fff in `input-active`
|
|
523
|
+
(the dropdown-open state) — explicit override to keep the theme bg. */
|
|
524
|
+
.ts-wrapper.single.input-active .ts-control { background: var(--lcp-input-bg); }
|
|
525
|
+
.ts-wrapper .ts-control input::placeholder { color: var(--lcp-text-muted); }
|
|
526
|
+
.ts-wrapper .ts-dropdown .optgroup-header { background: var(--lcp-bg-muted); }
|
|
527
|
+
.ts-wrapper .ts-dropdown .create { color: var(--lcp-text-muted); }
|
|
528
|
+
|
|
529
|
+
/* Multi-select display modes */
|
|
530
|
+
.ts-wrapper.multi.lcp-single-line .ts-control { flex-wrap: nowrap; overflow: hidden; }
|
|
531
|
+
.ts-wrapper.multi.lcp-single-line .ts-control > input { min-width: 30px; }
|
|
532
|
+
.ts-wrapper.multi.lcp-single-line .ts-control .item { flex-shrink: 0; }
|
|
533
|
+
|
|
534
|
+
/* Navigation */
|
|
535
|
+
.lcp-nav { display: flex; align-items: stretch; justify-content: space-between; background: var(--lcp-nav-bg); border-bottom: 1px solid var(--lcp-border-color); margin-bottom: 1rem; padding: 0 2rem; }
|
|
536
|
+
.lcp-nav-list { display: flex; gap: 0; list-style: none; margin: 0; padding: 0; }
|
|
537
|
+
.lcp-nav-list--left { flex: 1 1 auto; min-width: 0; }
|
|
538
|
+
.lcp-nav-list--right { flex: 0 0 auto; }
|
|
539
|
+
/* Items in the left zone must report their natural unwrapped width so
|
|
540
|
+
the lcp-responsive-top-nav controller's overflow_more measurement
|
|
541
|
+
sees the real width budget. Without nowrap, long labels (e.g.
|
|
542
|
+
"Feature Catalog (Overview)") wrap to 2-3 lines and the <li> reports
|
|
543
|
+
a much smaller offsetWidth — the controller wrongly concludes the
|
|
544
|
+
item fits, leaves it visible, and items end up sitting on top of the
|
|
545
|
+
right-zone or wrapping in unpredictable ways. */
|
|
546
|
+
.lcp-nav-list--left > li,
|
|
547
|
+
.lcp-nav-list--right > li { flex-shrink: 0; white-space: nowrap; }
|
|
548
|
+
.lcp-nav-spacer { flex: 1 1 auto; list-style: none; }
|
|
549
|
+
|
|
550
|
+
/* Responsive menu (Phase 1) — FOUC mask while the lcp-responsive-top-nav
|
|
551
|
+
controller runs its initial measurement pass. CSS reserves layout
|
|
552
|
+
space (visibility: hidden rather than display: none) so removing the
|
|
553
|
+
attribute doesn't cause a reflow / jump. The controller removes the
|
|
554
|
+
attribute on first successful measure() OR after 100ms regardless,
|
|
555
|
+
so JS-less or slow-network users see the nav after a brief delay.
|
|
556
|
+
The noscript override in the layout's <head> defeats this rule when
|
|
557
|
+
JS is disabled entirely. */
|
|
558
|
+
nav[data-measuring] { visibility: hidden; }
|
|
559
|
+
|
|
560
|
+
/* Wrap mode — items overflow onto subsequent rows when the viewport is
|
|
561
|
+
too narrow. No JS measurement required; pure CSS. */
|
|
562
|
+
nav[data-responsive-mode="wrap"] .lcp-nav-list--left { flex-wrap: wrap; }
|
|
563
|
+
|
|
564
|
+
/* All-pinned degradation (design § 3 invariant) — when overflow_more
|
|
565
|
+
has no eligible items to collapse into *More* and pinned items still
|
|
566
|
+
overflow, the controller sets data-overflow="wrap" on the nav so
|
|
567
|
+
items wrap rather than clip. */
|
|
568
|
+
nav[data-overflow="wrap"] .lcp-nav-list--left { flex-wrap: wrap; }
|
|
569
|
+
|
|
570
|
+
/* Per-item viewport gates — `hide_below` / `show_below` controller
|
|
571
|
+
toggles this attribute via matchMedia. */
|
|
572
|
+
[data-hidden-responsive] { display: none !important; }
|
|
573
|
+
|
|
574
|
+
/* Hamburger mode (Phase 1) — below breakpoint, the leftZone collapses
|
|
575
|
+
into a drawer driven by lcp-drawer. CSS only manages the visibility
|
|
576
|
+
switch; the controller manages drawer state + focus trap. */
|
|
577
|
+
.lcp-nav-hamburger {
|
|
578
|
+
display: none;
|
|
579
|
+
background: none; border: none; cursor: pointer;
|
|
580
|
+
padding: 0.5rem 0.75rem;
|
|
581
|
+
color: var(--lcp-text);
|
|
582
|
+
font-size: 1rem;
|
|
583
|
+
}
|
|
584
|
+
.lcp-nav-hamburger .lcp-menu-icon { margin-right: 0; }
|
|
585
|
+
nav[data-responsive-mode="hamburger"][data-collapsed] .lcp-nav-hamburger { display: inline-flex; }
|
|
586
|
+
nav[data-responsive-mode="hamburger"][data-collapsed] .lcp-nav-list--left { display: none; }
|
|
587
|
+
|
|
588
|
+
/* Generic drawer styles (used by Phase 1 hamburger + Phase 2 sidebar
|
|
589
|
+
off-canvas). Slide in from the left; backdrop dims the rest of the
|
|
590
|
+
page. */
|
|
591
|
+
.lcp-drawer {
|
|
592
|
+
position: fixed; top: 0; left: 0; bottom: 0;
|
|
593
|
+
width: min(80vw, 320px);
|
|
594
|
+
background: var(--lcp-bg-surface);
|
|
595
|
+
border-right: 1px solid var(--lcp-border-color);
|
|
596
|
+
box-shadow: var(--lcp-shadow-lg, 0 8px 24px rgba(0,0,0,0.18));
|
|
597
|
+
transform: translateX(-100%);
|
|
598
|
+
transition: transform 200ms ease;
|
|
599
|
+
z-index: 1000;
|
|
600
|
+
overflow-y: auto;
|
|
601
|
+
padding: 1rem;
|
|
602
|
+
}
|
|
603
|
+
.lcp-drawer[data-open] { transform: translateX(0); }
|
|
604
|
+
.lcp-drawer-backdrop {
|
|
605
|
+
position: fixed; inset: 0;
|
|
606
|
+
background: rgba(0, 0, 0, 0.4);
|
|
607
|
+
opacity: 0;
|
|
608
|
+
pointer-events: none;
|
|
609
|
+
transition: opacity 200ms ease;
|
|
610
|
+
z-index: 999;
|
|
611
|
+
}
|
|
612
|
+
.lcp-drawer-backdrop[data-open] { opacity: 1; pointer-events: auto; }
|
|
613
|
+
@media (prefers-reduced-motion: reduce) {
|
|
614
|
+
.lcp-drawer { transition: none; }
|
|
615
|
+
.lcp-drawer-backdrop { transition: none; }
|
|
616
|
+
}
|
|
617
|
+
@media print {
|
|
618
|
+
.lcp-drawer, .lcp-drawer-backdrop { display: none !important; }
|
|
619
|
+
nav[data-responsive-mode="overflow_more"] .lcp-nav-list--left { flex-wrap: wrap; }
|
|
620
|
+
}
|
|
621
|
+
.lcp-nav-item a { display: block; padding: 0.75rem 1rem; text-decoration: none; color: var(--lcp-text-muted); font-size: 0.875rem; font-weight: 500; border-bottom: 2px solid transparent; }
|
|
622
|
+
.lcp-nav-item a:hover { color: var(--lcp-text); }
|
|
623
|
+
.lcp-nav-item a.active { color: var(--lcp-primary); border-bottom-color: var(--lcp-primary); }
|
|
624
|
+
|
|
625
|
+
/* View switcher */
|
|
626
|
+
.lcp-view-switcher { display: inline-flex; gap: 0; margin-right: 0.5rem; }
|
|
627
|
+
.lcp-view-btn { border-radius: 0; border-right-width: 0; }
|
|
628
|
+
.lcp-view-btn:first-child { border-radius: var(--lcp-radius-sm) 0 0 var(--lcp-radius-sm); }
|
|
629
|
+
.lcp-view-btn:last-child { border-radius: 0 var(--lcp-radius-sm) var(--lcp-radius-sm) 0; border-right-width: 1px; }
|
|
630
|
+
.lcp-view-btn.active { background: var(--lcp-primary); color: var(--lcp-text-on-primary); border-color: var(--lcp-primary); }
|
|
631
|
+
|
|
632
|
+
/* User menu (avatar + email + sign-out) */
|
|
633
|
+
.lcp-user-menu { display: inline-flex; align-items: center; gap: 0.6rem; padding: 0.25rem 0.6rem; border-left: 1px solid var(--lcp-border-color); }
|
|
634
|
+
.lcp-user-menu__avatar { width: 28px; height: 28px; border-radius: 50%; object-fit: cover; flex-shrink: 0; background: var(--lcp-bg-surface-alt, var(--lcp-bg-active)); }
|
|
635
|
+
.lcp-user-menu__avatar--initial { display: inline-flex; align-items: center; justify-content: center; font-weight: 600; font-size: 0.8125rem; color: var(--lcp-text-primary); border: 1px solid var(--lcp-border-color); }
|
|
636
|
+
.lcp-user-menu__label { font-size: 0.875rem; color: var(--lcp-text-primary); max-width: 14rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
637
|
+
.lcp-user-menu__signout-form { display: inline-flex; margin: 0; }
|
|
638
|
+
.lcp-user-menu__signout { background: transparent; border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); color: var(--lcp-text-muted); padding: 0.3rem 0.6rem; font-size: 0.8125rem; cursor: pointer; transition: background 120ms ease, color 120ms ease, border-color 120ms ease; }
|
|
639
|
+
.lcp-user-menu__signout:hover { background: var(--lcp-bg-hover, var(--lcp-bg-surface-alt, var(--lcp-bg-active))); color: var(--lcp-text-primary); }
|
|
640
|
+
.lcp-user-menu__signout:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--lcp-focus-ring, rgba(0, 120, 215, 0.35)); }
|
|
641
|
+
|
|
642
|
+
/* Impersonation banner */
|
|
643
|
+
.lcp-impersonation-banner { background: var(--lcp-impersonation-bg); border-bottom: 2px solid var(--lcp-impersonation-border); padding: 0.5rem 2rem; display: flex; align-items: center; justify-content: space-between; font-size: 0.875rem; color: var(--lcp-impersonation-text); }
|
|
644
|
+
.lcp-impersonation-banner form { display: inline-flex; align-items: center; gap: 0.5rem; }
|
|
645
|
+
.lcp-impersonation-banner select { padding: 0.2rem 0.5rem; border: 1px solid var(--lcp-impersonation-border); border-radius: var(--lcp-radius-sm); font-size: 0.8rem; }
|
|
646
|
+
.lcp-impersonation-banner .btn { padding: 0.2rem 0.6rem; font-size: 0.8rem; }
|
|
647
|
+
.lcp-impersonation-selector { background: var(--lcp-bg-active); border-color: var(--lcp-border-color); color: var(--lcp-text-muted); }
|
|
648
|
+
|
|
649
|
+
/* Display templates */
|
|
650
|
+
.lcp-display-template { display: flex; align-items: center; gap: 0.5rem; }
|
|
651
|
+
.lcp-display-template__icon { flex-shrink: 0; font-size: 0.85rem; color: var(--lcp-text-muted); }
|
|
652
|
+
.lcp-display-template__title { font-weight: 500; font-size: 0.9rem; }
|
|
653
|
+
.lcp-display-template__title a { color: var(--lcp-text-link); text-decoration: none; }
|
|
654
|
+
.lcp-display-template__title a:hover { text-decoration: underline; }
|
|
655
|
+
.lcp-display-template__subtitle { font-size: 0.8rem; color: var(--lcp-text-muted); }
|
|
656
|
+
.lcp-display-template__badge { display: inline-block; padding: 0.1rem 0.4rem; border-radius: 8px; background: var(--lcp-bg-active); color: var(--lcp-text-secondary); font-size: 0.7rem; font-weight: 500; }
|
|
657
|
+
|
|
658
|
+
/* Association list */
|
|
659
|
+
.lcp-association-list { }
|
|
660
|
+
.lcp-association-item { padding: 0.35rem 0; border-bottom: 1px solid var(--lcp-border-color-subtle); }
|
|
661
|
+
.lcp-association-item:last-child { border-bottom: none; }
|
|
662
|
+
.lcp-association-list__empty { font-style: italic; color: var(--lcp-text-muted); padding: 0.5rem 0; }
|
|
663
|
+
|
|
664
|
+
/* JSON items list (show page) */
|
|
665
|
+
.lcp-json-items-list { }
|
|
666
|
+
.lcp-json-items-list__empty { font-style: italic; color: var(--lcp-text-muted); padding: 0.5rem 0; }
|
|
667
|
+
.lcp-json-item { display: flex; gap: 0.75rem; padding: 0.75rem 0; border-bottom: 1px solid var(--lcp-border-color-subtle); }
|
|
668
|
+
.lcp-json-item:last-child { border-bottom: none; }
|
|
669
|
+
.lcp-json-item__number { flex-shrink: 0; width: 1.75rem; height: 1.75rem; display: flex; align-items: center; justify-content: center; background: var(--lcp-bg-active); color: var(--lcp-text-secondary); border-radius: 50%; font-size: 0.8rem; font-weight: 600; }
|
|
670
|
+
.lcp-json-item__body { flex: 1; min-width: 0; }
|
|
671
|
+
.lcp-json-item__group-title { font-size: 0.75rem; font-weight: 600; color: var(--lcp-text-muted); text-transform: uppercase; letter-spacing: 0.03em; margin: 0.5rem 0 0.25rem; }
|
|
672
|
+
.lcp-json-item__group-title:first-child { margin-top: 0; }
|
|
673
|
+
.lcp-json-item__field { }
|
|
674
|
+
.lcp-json-item__label { font-size: 0.7rem; color: var(--lcp-text-muted); margin-bottom: 0.1rem; }
|
|
675
|
+
.lcp-json-item__value { font-size: 0.875rem; }
|
|
676
|
+
.lcp-json-item__nil { color: var(--lcp-text-disabled); }
|
|
677
|
+
|
|
678
|
+
/* Responsive breakpoints */
|
|
679
|
+
@media (max-width: 640px) {
|
|
680
|
+
.lcp-grid[data-responsive-mobile="1"] { grid-template-columns: 1fr !important; }
|
|
681
|
+
.lcp-grid[data-responsive-mobile="2"] { grid-template-columns: repeat(2, 1fr) !important; }
|
|
682
|
+
.lcp-hidden-mobile { display: none !important; }
|
|
683
|
+
}
|
|
684
|
+
@media (min-width: 641px) and (max-width: 1024px) {
|
|
685
|
+
.lcp-grid[data-responsive-tablet="1"] { grid-template-columns: 1fr !important; }
|
|
686
|
+
.lcp-grid[data-responsive-tablet="2"] { grid-template-columns: repeat(2, 1fr) !important; }
|
|
687
|
+
.lcp-hidden-tablet { display: none !important; }
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/* File upload */
|
|
691
|
+
.lcp-file-upload { position: relative; }
|
|
692
|
+
.lcp-file-input { margin-top: 0.25rem; }
|
|
693
|
+
.lcp-drop-zone { border: 2px dashed var(--lcp-border-color-input); border-radius: var(--lcp-radius-md); padding: 2rem 1rem; text-align: center; color: var(--lcp-text-muted); cursor: pointer; transition: border-color 0.2s, background 0.2s; margin-top: 0.25rem; }
|
|
694
|
+
.lcp-drop-zone:hover { border-color: var(--lcp-focus-border); background: var(--lcp-bg-subtle); }
|
|
695
|
+
.lcp-drop-zone.dragover { border-color: var(--lcp-primary); background: var(--lcp-primary-bg); color: var(--lcp-text); }
|
|
696
|
+
.lcp-file-preview-container { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.5rem; }
|
|
697
|
+
.lcp-file-preview-item { position: relative; border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); padding: 0.25rem; max-width: 100px; }
|
|
698
|
+
.lcp-file-preview-item img { max-width: 100%; height: auto; border-radius: 3px; }
|
|
699
|
+
.lcp-file-preview-item .lcp-preview-name { font-size: 0.7rem; color: var(--lcp-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 90px; display: block; }
|
|
700
|
+
.lcp-existing-attachment { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem; border: 1px solid var(--lcp-bg-active); border-radius: var(--lcp-radius-sm); margin-bottom: 0.5rem; background: var(--lcp-bg-muted); }
|
|
701
|
+
.lcp-existing-attachments { margin-bottom: 0.5rem; }
|
|
702
|
+
.lcp-attachment-thumbnail { border-radius: var(--lcp-radius-sm); object-fit: cover; }
|
|
703
|
+
.lcp-attachment-filename { font-size: 0.875rem; font-weight: 500; }
|
|
704
|
+
.lcp-attachment-size { font-size: 0.75rem; color: var(--lcp-text-muted); }
|
|
705
|
+
.lcp-attachment-remove { display: inline-flex; align-items: center; gap: 0.25rem; font-size: 0.8rem; color: var(--lcp-danger); cursor: pointer; margin-left: auto; }
|
|
706
|
+
.lcp-attachment-remove input[type="checkbox"] { width: auto; }
|
|
707
|
+
.lcp-attachment-preview { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
|
708
|
+
.lcp-attachment-preview-item { max-width: 200px; }
|
|
709
|
+
.lcp-attachment-preview-item img { max-width: 100%; height: auto; border-radius: var(--lcp-radius-sm); }
|
|
710
|
+
.lcp-attachment-image { max-width: 100%; height: auto; border-radius: var(--lcp-radius-sm); }
|
|
711
|
+
.lcp-attachment-list { list-style: none; padding: 0; margin: 0; }
|
|
712
|
+
.lcp-attachment-list li { padding: 0.25rem 0; }
|
|
713
|
+
.lcp-attachment-list li a { color: var(--lcp-text-link); text-decoration: none; }
|
|
714
|
+
.lcp-attachment-list li a:hover { text-decoration: underline; }
|
|
715
|
+
.lcp-attachment-download { color: var(--lcp-text-link); text-decoration: none; }
|
|
716
|
+
.lcp-attachment-download:hover { text-decoration: underline; }
|
|
717
|
+
.lcp-no-attachment { color: var(--lcp-text-muted); font-style: italic; font-size: 0.875rem; }
|
|
718
|
+
.lcp-upload-progress { margin-top: 0.5rem; }
|
|
719
|
+
.lcp-upload-progress-bar { background: var(--lcp-bg-active); border-radius: var(--lcp-radius-sm); overflow: hidden; height: 0.5rem; }
|
|
720
|
+
.lcp-upload-progress-fill { background: var(--lcp-primary); height: 100%; transition: width 0.2s; }
|
|
721
|
+
.lcp-upload-progress-text { font-size: 0.7rem; color: var(--lcp-text-muted); margin-top: 0.15rem; }
|
|
722
|
+
|
|
723
|
+
/* JS-driven color state classes */
|
|
724
|
+
.lcp-upload-error { background: var(--lcp-danger) !important; }
|
|
725
|
+
.lcp-file-preview-error { border-color: var(--lcp-danger); }
|
|
726
|
+
.lcp-file-preview-error .lcp-preview-name { color: var(--lcp-danger); }
|
|
727
|
+
.lcp-tree-select-placeholder { color: var(--lcp-text-muted); }
|
|
728
|
+
|
|
729
|
+
/* ===== Menu system: sidebar + dropdown + both layout ===== */
|
|
730
|
+
|
|
731
|
+
/* Layout with sidebar */
|
|
732
|
+
.lcp-layout-with-sidebar { display: flex; min-height: calc(100vh - 3rem); }
|
|
733
|
+
.lcp-layout-with-sidebar .lcp-layout-main { flex: 1; min-width: 0; overflow-x: auto; }
|
|
734
|
+
.lcp-layout-sidebar .lcp-container { max-width: none; }
|
|
735
|
+
|
|
736
|
+
/* Sidebar */
|
|
737
|
+
/* z-index: 100 lifts the sidebar above sticky table headers (z:10) and
|
|
738
|
+
filter toggle chrome — the rail-collapsed flyout lives inside the
|
|
739
|
+
sidebar's stacking context, so without this it would be painted
|
|
740
|
+
below the table headers when extending into the main content area. */
|
|
741
|
+
.lcp-sidebar { width: 240px; flex-shrink: 0; background: var(--lcp-sidebar-bg); border-right: 1px solid var(--lcp-border-color); display: flex; flex-direction: column; position: sticky; top: 1rem; max-height: calc(100vh - 2rem); overflow-y: auto; transition: width 200ms ease, transform 200ms ease; z-index: 100; }
|
|
742
|
+
|
|
743
|
+
/* Phase 2 — rail mode (above breakpoint). Collapsed rail shows only
|
|
744
|
+
icons; the rail toggle button stays sticky at the top so it remains
|
|
745
|
+
reachable while the user scrolls through long menus. */
|
|
746
|
+
.lcp-sidebar[data-rail="collapsed"] {
|
|
747
|
+
width: var(--lcp-sidebar-rail-width, 60px);
|
|
748
|
+
/* Flyout panels (position: absolute) escape the rail's right edge.
|
|
749
|
+
The CSS spec forces overflow-x to compute as `auto` whenever
|
|
750
|
+
overflow-y is `auto`/`scroll` (visible cannot coexist with clip on
|
|
751
|
+
the other axis), so we drop overflow entirely in collapsed mode.
|
|
752
|
+
The rail is narrow and only shows top-level group icons — usually
|
|
753
|
+
fits without scrolling. If a host has 20+ groups they can keep the
|
|
754
|
+
sidebar in `above_breakpoint: none` to skip rail mode. */
|
|
755
|
+
overflow: visible;
|
|
756
|
+
}
|
|
757
|
+
/* Hide everything except icons and avatars when collapsed.
|
|
758
|
+
- .lcp-menu-icon — the standard Lucide icon
|
|
759
|
+
- .lcp-user-menu__avatar — custom renderer avatar (acts as icon for
|
|
760
|
+
user-menu trigger; image or initials)
|
|
761
|
+
The arrow is intentionally NOT excluded — collapsed rail hides
|
|
762
|
+
children, so the toggle indicator would be misleading; badges are
|
|
763
|
+
also hidden because they don't fit clearly next to icons. */
|
|
764
|
+
.lcp-sidebar[data-rail="collapsed"] .lcp-sidebar-link .lcp-nav-label,
|
|
765
|
+
.lcp-sidebar[data-rail="collapsed"] .lcp-sidebar-group-toggle .lcp-nav-label,
|
|
766
|
+
.lcp-sidebar[data-rail="collapsed"] .lcp-sidebar-link span:not(.lcp-menu-icon):not(.lcp-user-menu__avatar),
|
|
767
|
+
.lcp-sidebar[data-rail="collapsed"] .lcp-sidebar-group-toggle span:not(.lcp-menu-icon):not(.lcp-user-menu__avatar),
|
|
768
|
+
.lcp-sidebar[data-rail="collapsed"] .lcp-sidebar-group-arrow,
|
|
769
|
+
.lcp-sidebar[data-rail="collapsed"] .lcp-menu-badge {
|
|
770
|
+
display: none;
|
|
771
|
+
}
|
|
772
|
+
.lcp-sidebar[data-rail="collapsed"] .lcp-sidebar-group-children { display: none; }
|
|
773
|
+
|
|
774
|
+
/* Rail-collapsed flyout — clicking a group's icon opens its children as
|
|
775
|
+
an absolute-positioned panel to the right of the rail. Only one open
|
|
776
|
+
at a time; lcp-sidebar controller closes on outside-click + ESC. */
|
|
777
|
+
.lcp-sidebar[data-rail="collapsed"] .lcp-sidebar-group { position: relative; }
|
|
778
|
+
.lcp-sidebar[data-rail="collapsed"] .lcp-sidebar-group[data-open] > .lcp-sidebar-group-children {
|
|
779
|
+
display: block;
|
|
780
|
+
position: absolute;
|
|
781
|
+
left: 100%; /* anchored to the right edge of the rail */
|
|
782
|
+
top: 0;
|
|
783
|
+
width: 220px;
|
|
784
|
+
background: var(--lcp-bg-surface-raised, var(--lcp-bg-surface));
|
|
785
|
+
border: 1px solid var(--lcp-border-color);
|
|
786
|
+
border-radius: var(--lcp-radius-sm);
|
|
787
|
+
box-shadow: var(--lcp-shadow-md);
|
|
788
|
+
margin: 0; padding: 0.25rem 0;
|
|
789
|
+
/* Above page chrome (sticky table headers, filter toolbar, etc.) but
|
|
790
|
+
below the off-canvas drawer (1000) so future drawer-over-rail
|
|
791
|
+
interaction still layers correctly. */
|
|
792
|
+
z-index: 950;
|
|
793
|
+
}
|
|
794
|
+
/* Inside the flyout, restore label / badge / arrow visibility — they
|
|
795
|
+
were hidden by the global rail-collapsed rules above. */
|
|
796
|
+
.lcp-sidebar[data-rail="collapsed"] .lcp-sidebar-group[data-open] > .lcp-sidebar-group-children .lcp-sidebar-link {
|
|
797
|
+
justify-content: flex-start;
|
|
798
|
+
padding-left: 1rem; padding-right: 1rem;
|
|
799
|
+
}
|
|
800
|
+
.lcp-sidebar[data-rail="collapsed"] .lcp-sidebar-group[data-open] > .lcp-sidebar-group-children .lcp-sidebar-label,
|
|
801
|
+
.lcp-sidebar[data-rail="collapsed"] .lcp-sidebar-group[data-open] > .lcp-sidebar-group-children .lcp-menu-badge,
|
|
802
|
+
.lcp-sidebar[data-rail="collapsed"] .lcp-sidebar-group[data-open] > .lcp-sidebar-group-children .lcp-user-menu__label {
|
|
803
|
+
display: inline-flex;
|
|
804
|
+
}
|
|
805
|
+
/* The user-menu avatar acts as the rail icon. Centre it horizontally
|
|
806
|
+
in the ~60px wide rail and drop its right margin. */
|
|
807
|
+
.lcp-sidebar[data-rail="collapsed"] .lcp-user-menu__avatar {
|
|
808
|
+
margin-right: 0;
|
|
809
|
+
}
|
|
810
|
+
/* The button toggles get centred in collapsed mode so icons align with
|
|
811
|
+
the rail. Existing .lcp-sidebar-item--icon-only does this for items
|
|
812
|
+
with `label: false`; replicate it for collapsed-rail toggles. */
|
|
813
|
+
.lcp-sidebar[data-rail="collapsed"] .lcp-sidebar-group-toggle,
|
|
814
|
+
.lcp-sidebar[data-rail="collapsed"] .lcp-sidebar-link {
|
|
815
|
+
justify-content: center;
|
|
816
|
+
padding-left: 0; padding-right: 0;
|
|
817
|
+
}
|
|
818
|
+
.lcp-sidebar-rail-toggle {
|
|
819
|
+
position: sticky; top: 0;
|
|
820
|
+
display: block;
|
|
821
|
+
width: 100%; padding: 0.5rem;
|
|
822
|
+
background: var(--lcp-sidebar-bg);
|
|
823
|
+
border: none; border-bottom: 1px solid var(--lcp-border-color);
|
|
824
|
+
cursor: pointer;
|
|
825
|
+
color: var(--lcp-text-muted);
|
|
826
|
+
text-align: right;
|
|
827
|
+
z-index: 1;
|
|
828
|
+
}
|
|
829
|
+
.lcp-sidebar-rail-toggle::after { content: "\25C0"; font-size: 0.7em; }
|
|
830
|
+
.lcp-sidebar[data-rail="collapsed"] .lcp-sidebar-rail-toggle::after { content: "\25B6"; }
|
|
831
|
+
|
|
832
|
+
/* Phase 2 — off-canvas mode (below breakpoint). Sidebar slides off
|
|
833
|
+
screen via transform; the drawer controller handles open/close and
|
|
834
|
+
backdrop. */
|
|
835
|
+
.lcp-sidebar[data-mode="off_canvas"] {
|
|
836
|
+
position: fixed; top: 0; left: 0; bottom: 0;
|
|
837
|
+
z-index: 1000;
|
|
838
|
+
transform: translateX(-100%);
|
|
839
|
+
max-height: none; height: 100vh;
|
|
840
|
+
top: 0;
|
|
841
|
+
/* Off-canvas drawer width overrides rail-collapsed width — when the
|
|
842
|
+
user opens the drawer on a narrow viewport they want to read labels,
|
|
843
|
+
not see icon-only chrome (matches lcp-drawer's general approach). */
|
|
844
|
+
width: min(80vw, 280px);
|
|
845
|
+
}
|
|
846
|
+
.lcp-sidebar[data-mode="off_canvas"][data-open] { transform: translateX(0); }
|
|
847
|
+
/* Reveal labels even if the persisted rail state was collapsed when the
|
|
848
|
+
user opened the off-canvas drawer. */
|
|
849
|
+
.lcp-sidebar[data-mode="off_canvas"] .lcp-sidebar-link .lcp-nav-label,
|
|
850
|
+
.lcp-sidebar[data-mode="off_canvas"] .lcp-sidebar-group-toggle .lcp-nav-label,
|
|
851
|
+
.lcp-sidebar[data-mode="off_canvas"] .lcp-sidebar-link span:not(.lcp-menu-icon):not(.lcp-menu-badge),
|
|
852
|
+
.lcp-sidebar[data-mode="off_canvas"] .lcp-sidebar-group-toggle span:not(.lcp-menu-icon):not(.lcp-menu-badge):not(.lcp-sidebar-group-arrow) {
|
|
853
|
+
display: inline;
|
|
854
|
+
}
|
|
855
|
+
.lcp-sidebar[data-mode="off_canvas"] .lcp-sidebar-group-children { display: block; }
|
|
856
|
+
|
|
857
|
+
/* Mobile header for sidebar-only layouts.
|
|
858
|
+
Rendered always (by the layout) when policy enables off_canvas auto-
|
|
859
|
+
injection, but visually shown only while the matchMedia listener in
|
|
860
|
+
lcp-responsive-sidebar marks the body with .lcp-sidebar-off-canvas-active.
|
|
861
|
+
That same body class never gets added in 'both' layouts because the
|
|
862
|
+
auto-injected sidebar_toggle already lives in the top_menu there. */
|
|
863
|
+
.lcp-mobile-header { display: none; }
|
|
864
|
+
body.lcp-sidebar-off-canvas-active .lcp-mobile-header {
|
|
865
|
+
display: flex;
|
|
866
|
+
position: sticky; top: 0;
|
|
867
|
+
z-index: 900;
|
|
868
|
+
align-items: center;
|
|
869
|
+
padding: 0.5rem 0.75rem;
|
|
870
|
+
background: var(--lcp-bg-surface);
|
|
871
|
+
border-bottom: 1px solid var(--lcp-border-color);
|
|
872
|
+
}
|
|
873
|
+
.lcp-mobile-header__toggle {
|
|
874
|
+
display: inline-flex;
|
|
875
|
+
align-items: center; justify-content: center;
|
|
876
|
+
width: 2.5rem; height: 2.5rem;
|
|
877
|
+
background: none; border: none;
|
|
878
|
+
cursor: pointer;
|
|
879
|
+
color: var(--lcp-text);
|
|
880
|
+
border-radius: var(--lcp-radius-sm);
|
|
881
|
+
}
|
|
882
|
+
.lcp-mobile-header__toggle:hover { background: var(--lcp-bg-hover); }
|
|
883
|
+
.lcp-mobile-header__toggle:focus-visible {
|
|
884
|
+
outline: none;
|
|
885
|
+
box-shadow: 0 0 0 3px var(--lcp-focus-ring, rgba(0, 120, 215, 0.35));
|
|
886
|
+
}
|
|
887
|
+
.lcp-mobile-header__toggle .lcp-menu-icon { width: 1.25rem; height: 1.25rem; }
|
|
888
|
+
|
|
889
|
+
/* Auto-injected top_menu sidebar_toggle — only visible below the
|
|
890
|
+
sidebar breakpoint, the same way _mobile_header is gated. Above
|
|
891
|
+
breakpoint the sidebar is rendered as a rail/static panel and the
|
|
892
|
+
toggle would be a dead button. */
|
|
893
|
+
.lcp-nav-item--sidebar-toggle { display: none; }
|
|
894
|
+
body.lcp-sidebar-off-canvas-active .lcp-nav-item--sidebar-toggle { display: inline-flex; }
|
|
895
|
+
|
|
896
|
+
.lcp-sidebar-nav { display: flex; flex-direction: column; flex: 1; padding: 0.5rem 0; }
|
|
897
|
+
.lcp-sidebar-list { list-style: none; margin: 0; padding: 0; }
|
|
898
|
+
.lcp-sidebar-main { flex: 1; }
|
|
899
|
+
.lcp-sidebar-bottom { border-top: 1px solid var(--lcp-border-color); padding-top: 0.5rem; margin-top: 0.5rem; }
|
|
900
|
+
|
|
901
|
+
/* Sidebar items */
|
|
902
|
+
.lcp-sidebar-item { }
|
|
903
|
+
.lcp-sidebar-link { display: block; padding: 0.5rem 1rem; text-decoration: none; color: var(--lcp-text-muted); font-size: 0.875rem; font-weight: 500; border-left: 3px solid transparent; }
|
|
904
|
+
.lcp-sidebar-link:hover { color: var(--lcp-text); background: var(--lcp-bg-hover); }
|
|
905
|
+
.lcp-sidebar-link.active { color: var(--lcp-primary); border-left-color: var(--lcp-primary); background: var(--lcp-sidebar-active-bg); }
|
|
906
|
+
/* Reset native button defaults when .lcp-sidebar-link sits on a <button>
|
|
907
|
+
(button_to wrapper produced for items with `method: post|delete|patch|put`).
|
|
908
|
+
Keeps the rendering visually identical to an <a href>. */
|
|
909
|
+
button.lcp-sidebar-link {
|
|
910
|
+
background: transparent;
|
|
911
|
+
border-top: 0; border-right: 0; border-bottom: 0;
|
|
912
|
+
font: inherit;
|
|
913
|
+
text-align: left;
|
|
914
|
+
width: 100%;
|
|
915
|
+
cursor: pointer;
|
|
916
|
+
}
|
|
917
|
+
button.lcp-sidebar-link:hover { background: var(--lcp-bg-hover); }
|
|
918
|
+
.lcp-sidebar-label { display: inline; }
|
|
919
|
+
|
|
920
|
+
/* Sidebar separator */
|
|
921
|
+
.lcp-sidebar-separator { border-top: 1px solid var(--lcp-border-color); margin: 0.5rem 1rem; }
|
|
922
|
+
|
|
923
|
+
/* Sidebar collapsible groups */
|
|
924
|
+
.lcp-sidebar-group { }
|
|
925
|
+
.lcp-sidebar-group-toggle { display: flex; align-items: center; justify-content: space-between; width: 100%; padding: 0.5rem 1rem; border: none; background: none; cursor: pointer; font-size: 0.875rem; font-weight: 600; color: var(--lcp-text-secondary); text-align: left; }
|
|
926
|
+
.lcp-sidebar-group-toggle:hover { background: var(--lcp-bg-hover); color: var(--lcp-text); }
|
|
927
|
+
.lcp-sidebar-group-label { flex: 1; }
|
|
928
|
+
.lcp-sidebar-group-arrow::after { content: "\25BC"; font-size: 0.6em; color: var(--lcp-text-disabled); }
|
|
929
|
+
.lcp-sidebar-group.lcp-sidebar-collapsed .lcp-sidebar-group-arrow::after { content: "\25B6"; }
|
|
930
|
+
.lcp-sidebar-group.lcp-sidebar-collapsed .lcp-sidebar-group-children { display: none; }
|
|
931
|
+
.lcp-sidebar-group-children { list-style: none; margin: 0; padding: 0; }
|
|
932
|
+
.lcp-sidebar-group-children .lcp-sidebar-link { padding-left: 1.75rem; }
|
|
933
|
+
.lcp-sidebar-depth-1 > .lcp-sidebar-group-toggle { padding-left: 1.75rem; }
|
|
934
|
+
.lcp-sidebar-depth-1 > .lcp-sidebar-group-children > .lcp-sidebar-item > .lcp-sidebar-link { padding-left: 3rem; }
|
|
935
|
+
|
|
936
|
+
/* Top nav dropdown */
|
|
937
|
+
.lcp-nav-dropdown { position: relative; }
|
|
938
|
+
.lcp-nav-dropdown-toggle { display: block; padding: 0.75rem 1rem; border: none; background: none; cursor: pointer; color: var(--lcp-text-muted); font-size: 0.875rem; font-weight: 500; border-bottom: 2px solid transparent; }
|
|
939
|
+
.lcp-nav-dropdown-toggle:hover { color: var(--lcp-text); }
|
|
940
|
+
.lcp-nav-dropdown.active .lcp-nav-dropdown-toggle { color: var(--lcp-primary); border-bottom-color: var(--lcp-primary); }
|
|
941
|
+
.lcp-nav-caret::after { content: "\25BC"; font-size: 0.5em; margin-left: 0.25rem; vertical-align: middle; }
|
|
942
|
+
.lcp-nav-dropdown-menu { display: none; position: absolute; top: 100%; left: 0; background: var(--lcp-bg-surface-raised); border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); box-shadow: var(--lcp-shadow-md); min-width: 180px; z-index: 100; list-style: none; margin: 0; padding: 0.25rem 0; }
|
|
943
|
+
/* Hover reveal — direct child only so hovering the outer *More* dropdown
|
|
944
|
+
doesn't cascade-open every nested .lcp-nav-dropdown-menu (the moved-in
|
|
945
|
+
top-level groups each have their own). Guarded to true-mouse pointers;
|
|
946
|
+
touch devices fall through to the click path. */
|
|
947
|
+
@media (hover: hover) {
|
|
948
|
+
.lcp-nav-dropdown:hover:not(.lcp-nav-dropdown--disabled) > .lcp-nav-dropdown-menu { display: block; }
|
|
949
|
+
}
|
|
950
|
+
/* Click / keyboard reveal — driven by lcp-dropdown controller. */
|
|
951
|
+
.lcp-nav-dropdown[data-open]:not(.lcp-nav-dropdown--disabled) > .lcp-nav-dropdown-menu { display: block; }
|
|
952
|
+
/* Keyboard a11y — focus inside an open menu keeps it visible while
|
|
953
|
+
tabbing through items. Outside the hover media query intentionally. */
|
|
954
|
+
.lcp-nav-dropdown-menu:focus-within { display: block; }
|
|
955
|
+
.lcp-nav-dropdown-item a { display: block; padding: 0.4rem 1rem; text-decoration: none; color: var(--lcp-text); font-size: 0.875rem; }
|
|
956
|
+
.lcp-nav-dropdown-item a:hover { background: var(--lcp-bg-hover); }
|
|
957
|
+
.lcp-nav-dropdown-item a.active { color: var(--lcp-primary); font-weight: 500; }
|
|
958
|
+
.lcp-nav-dropdown-separator { border-top: 1px solid var(--lcp-border-color); margin: 0.25rem 0; }
|
|
959
|
+
.lcp-nav-item--right .lcp-nav-dropdown-menu { left: auto; right: 0; }
|
|
960
|
+
|
|
961
|
+
/* When a top-level .lcp-nav-dropdown is moved into the *More* overflow
|
|
962
|
+
menu, the *More* list is vertical so the nested menu should fly out
|
|
963
|
+
to the right (like a submenu), not down (which is the top-bar default
|
|
964
|
+
and would overlap subsequent items in the *More* list). */
|
|
965
|
+
.lcp-nav-dropdown-menu .lcp-nav-dropdown > .lcp-nav-dropdown-menu {
|
|
966
|
+
top: 0;
|
|
967
|
+
left: 100%;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
/* Nested submenu (flyout) */
|
|
971
|
+
.lcp-nav-submenu { position: relative; }
|
|
972
|
+
.lcp-nav-submenu-toggle { display: flex; align-items: center; justify-content: space-between; width: 100%; padding: 0.4rem 1rem; border: none; background: none; cursor: pointer; color: var(--lcp-text); font-size: 0.875rem; text-align: left; }
|
|
973
|
+
.lcp-nav-submenu-toggle:hover { background: var(--lcp-bg-hover); }
|
|
974
|
+
.lcp-nav-submenu-toggle.active { color: var(--lcp-primary); font-weight: 500; }
|
|
975
|
+
.lcp-nav-submenu-arrow::after { content: "\25B6"; font-size: 0.5em; margin-left: 0.5rem; color: var(--lcp-text-disabled); }
|
|
976
|
+
.lcp-nav-submenu-menu { display: none; position: absolute; left: 100%; top: 0; background: var(--lcp-bg-surface-raised); border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); box-shadow: var(--lcp-shadow-md); min-width: 180px; z-index: 101; list-style: none; margin: 0; padding: 0.25rem 0; }
|
|
977
|
+
/* Hover reveal — guarded to true-mouse pointers (see top-level dropdown
|
|
978
|
+
comment above for rationale). */
|
|
979
|
+
@media (hover: hover) {
|
|
980
|
+
.lcp-nav-submenu:hover > .lcp-nav-submenu-menu { display: block; }
|
|
981
|
+
}
|
|
982
|
+
/* Click / keyboard reveal — driven by lcp-dropdown controller. */
|
|
983
|
+
.lcp-nav-submenu[data-open] > .lcp-nav-submenu-menu { display: block; }
|
|
984
|
+
/* Keyboard a11y — focus inside an open submenu keeps it visible.
|
|
985
|
+
Intentionally outside the hover media query so touch-keyboard users
|
|
986
|
+
retain access. */
|
|
987
|
+
.lcp-nav-submenu-menu:focus-within { display: block; }
|
|
988
|
+
/* Invisible bridge prevents hover gap on diagonal mouse movement */
|
|
989
|
+
.lcp-nav-submenu::after { content: ""; position: absolute; top: 0; right: -6px; width: 6px; height: 100%; }
|
|
990
|
+
/* Viewport flip classes (set by Stimulus controller) */
|
|
991
|
+
.lcp-nav-submenu[data-flip-x] > .lcp-nav-submenu-menu { left: auto; right: 100%; }
|
|
992
|
+
.lcp-nav-submenu[data-flip-y] > .lcp-nav-submenu-menu { top: auto; bottom: 0; }
|
|
993
|
+
|
|
994
|
+
/* Top nav separator */
|
|
995
|
+
.lcp-nav-separator { width: 1px; background: var(--lcp-border-color); margin: 0.5rem 0.25rem; align-self: stretch; }
|
|
996
|
+
|
|
997
|
+
/* Menu badges */
|
|
998
|
+
.lcp-menu-badge {
|
|
999
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
1000
|
+
min-width: 1.25rem; height: 1.25rem; padding: 0 0.35rem;
|
|
1001
|
+
border-radius: 10px; background: var(--lcp-menu-badge-bg); color: var(--lcp-text-on-primary);
|
|
1002
|
+
font-size: 0.7rem; font-weight: 600; line-height: 1;
|
|
1003
|
+
margin-left: 0.35rem; vertical-align: middle;
|
|
1004
|
+
}
|
|
1005
|
+
.lcp-menu-badge-text { border-radius: var(--lcp-radius-sm); font-size: 0.65rem; text-transform: uppercase; }
|
|
1006
|
+
.lcp-menu-badge-icon { background: transparent; color: inherit; min-width: auto; padding: 0; }
|
|
1007
|
+
.lcp-sidebar-link .lcp-menu-badge { margin-left: auto; margin-right: 0.5rem; }
|
|
1008
|
+
.lcp-sidebar-group-toggle .lcp-menu-badge { margin-left: auto; margin-right: 0.5rem; }
|
|
1009
|
+
|
|
1010
|
+
/* Menu icons. Rendered as `<i data-lucide="…">` placeholders that the
|
|
1011
|
+
Lucide JS bundle swaps for inline SVGs at boot (and on every Turbo
|
|
1012
|
+
navigation). The wrapper carries `aria-hidden="true"` so the icon
|
|
1013
|
+
contributes nothing to the surrounding link/button's accessible
|
|
1014
|
+
name — the link's name comes from either the visible label or
|
|
1015
|
+
`aria_label`. SVG strokes use `currentColor`, so the icon
|
|
1016
|
+
automatically inherits the text colour of its container. */
|
|
1017
|
+
.lcp-menu-icon {
|
|
1018
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
1019
|
+
width: 1rem; height: 1rem; vertical-align: middle;
|
|
1020
|
+
}
|
|
1021
|
+
.lcp-menu-icon svg { width: 100%; height: 100%; stroke-width: 1.75; }
|
|
1022
|
+
.lcp-nav-item a .lcp-menu-icon,
|
|
1023
|
+
.lcp-nav-dropdown-toggle .lcp-menu-icon,
|
|
1024
|
+
.lcp-nav-submenu-toggle .lcp-menu-icon { margin-right: 0.4rem; }
|
|
1025
|
+
.lcp-nav-dropdown-item a .lcp-menu-icon { margin-right: 0.4rem; width: 0.9rem; height: 0.9rem; }
|
|
1026
|
+
.lcp-sidebar-link .lcp-menu-icon,
|
|
1027
|
+
.lcp-sidebar-group-toggle .lcp-menu-icon { margin-right: 0.5rem; width: 1.05rem; height: 1.05rem; }
|
|
1028
|
+
|
|
1029
|
+
/* Icon-only items: square hit area, no horizontal padding around text
|
|
1030
|
+
since there is no text. Icons stay centred in the original line
|
|
1031
|
+
height of the surrounding container so badges line up. */
|
|
1032
|
+
.lcp-nav-item--icon-only a,
|
|
1033
|
+
.lcp-nav-item--icon-only .lcp-nav-dropdown-toggle,
|
|
1034
|
+
.lcp-nav-item--icon-only .lcp-nav-submenu-toggle {
|
|
1035
|
+
padding-left: 0.6rem; padding-right: 0.6rem;
|
|
1036
|
+
}
|
|
1037
|
+
.lcp-nav-item--icon-only .lcp-menu-icon { margin-right: 0; }
|
|
1038
|
+
.lcp-sidebar-item--icon-only .lcp-sidebar-link,
|
|
1039
|
+
.lcp-sidebar-item--icon-only .lcp-sidebar-group-toggle {
|
|
1040
|
+
justify-content: center;
|
|
1041
|
+
}
|
|
1042
|
+
.lcp-sidebar-item--icon-only .lcp-menu-icon { margin-right: 0; }
|
|
1043
|
+
|
|
1044
|
+
/* Layout adjustments for "both" mode */
|
|
1045
|
+
.lcp-layout-both .lcp-layout-with-sidebar { min-height: calc(100vh - 3rem); }
|
|
1046
|
+
.lcp-layout-both .lcp-sidebar { border-top: none; }
|
|
1047
|
+
|
|
1048
|
+
/* Markdown display */
|
|
1049
|
+
.lcp-markdown { font-size: 0.9rem; line-height: 1.6; }
|
|
1050
|
+
.lcp-markdown h1, .lcp-markdown h2, .lcp-markdown h3 { margin: 0.75rem 0 0.5rem; font-weight: 600; }
|
|
1051
|
+
.lcp-markdown h1 { font-size: 1.25rem; }
|
|
1052
|
+
.lcp-markdown h2 { font-size: 1.1rem; }
|
|
1053
|
+
.lcp-markdown h3 { font-size: 1rem; }
|
|
1054
|
+
.lcp-markdown p { margin: 0 0 0.5rem; }
|
|
1055
|
+
.lcp-markdown ul, .lcp-markdown ol { margin: 0 0 0.5rem 1.25rem; }
|
|
1056
|
+
.lcp-markdown li { margin-bottom: 0.15rem; }
|
|
1057
|
+
.lcp-markdown code { background: var(--lcp-bg-muted); padding: 0.1em 0.35em; border-radius: 3px; font-size: 0.85em; }
|
|
1058
|
+
.lcp-markdown pre { background: var(--lcp-bg-muted); border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); padding: 0.75rem; overflow-x: auto; margin: 0 0 0.5rem; }
|
|
1059
|
+
.lcp-markdown pre code { background: none; padding: 0; font-size: 0.8rem; }
|
|
1060
|
+
.lcp-markdown table { border-collapse: collapse; margin: 0 0 0.5rem; }
|
|
1061
|
+
.lcp-markdown table th, .lcp-markdown table td { border: 1px solid var(--lcp-border-color); padding: 0.35rem 0.6rem; font-size: 0.85rem; }
|
|
1062
|
+
.lcp-markdown table th { background: var(--lcp-bg-muted); font-weight: 600; }
|
|
1063
|
+
.lcp-markdown blockquote { border-left: 3px solid var(--lcp-border-color); margin: 0 0 0.5rem; padding: 0.25rem 0.75rem; color: var(--lcp-text-muted); }
|
|
1064
|
+
.lcp-markdown input[type="checkbox"] { width: auto; margin-right: 0.3rem; }
|
|
1065
|
+
|
|
1066
|
+
/* Internal link */
|
|
1067
|
+
.lcp-internal-link { color: var(--lcp-text-link); text-decoration: none; }
|
|
1068
|
+
.lcp-internal-link:hover { text-decoration: underline; }
|
|
1069
|
+
|
|
1070
|
+
/* Manage page (bulk editor) */
|
|
1071
|
+
.lcp-resources-manage { max-width: 1200px; }
|
|
1072
|
+
.lcp-resources-manage .lcp-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; padding-bottom: 0.75rem; border-bottom: 2px solid var(--lcp-border-color); }
|
|
1073
|
+
.lcp-resources-manage .lcp-header h1 { font-size: 1.5rem; font-weight: 600; }
|
|
1074
|
+
.lcp-manage-container { margin-bottom: 0.5rem; }
|
|
1075
|
+
.lcp-manage-row { display: flex; flex-direction: column; align-items: stretch; border: 1px solid var(--lcp-bg-active); border-radius: var(--lcp-radius-sm); margin-bottom: 0.5rem; background: var(--lcp-bg-muted); padding: 0; }
|
|
1076
|
+
.lcp-manage-row.removed { display: none !important; }
|
|
1077
|
+
.lcp-manage-summary { display: flex; align-items: flex-end; gap: 0.5rem; padding: 0.5rem 0.75rem; flex-wrap: nowrap; }
|
|
1078
|
+
.lcp-manage-summary .lcp-drag-handle { flex-shrink: 0; align-self: center; }
|
|
1079
|
+
.lcp-manage-summary-fields { display: flex; align-items: flex-end; gap: 0.5rem; flex: 1; min-width: 0; flex-wrap: wrap; }
|
|
1080
|
+
.lcp-manage-field-summary { display: flex; flex-direction: column; min-width: 0; }
|
|
1081
|
+
.lcp-manage-field-summary:nth-child(1) { flex: 1; min-width: 120px; }
|
|
1082
|
+
.lcp-manage-field-summary:nth-child(2) { min-width: 100px; flex: 0 0 auto; }
|
|
1083
|
+
.lcp-manage-field-summary:nth-child(3) { flex: 1; min-width: 120px; }
|
|
1084
|
+
.lcp-manage-field-summary:nth-child(4) { flex: 1; min-width: 100px; }
|
|
1085
|
+
.lcp-manage-field-summary label { font-size: 0.75rem; font-weight: 500; margin-bottom: 0.15rem; color: var(--lcp-text-muted); }
|
|
1086
|
+
.lcp-manage-field-summary input[type="text"],
|
|
1087
|
+
.lcp-manage-field-summary select { padding: 0.3rem 0.5rem; border: 1px solid var(--lcp-border-color-input); border-radius: var(--lcp-radius-sm); font-size: 0.8rem; width: 100%; }
|
|
1088
|
+
.lcp-manage-expand { flex-shrink: 0; align-self: flex-end; margin-bottom: 0.15rem; padding: 0.25rem 0.6rem; font-size: 0.8rem; }
|
|
1089
|
+
.lcp-manage-remove-btn { flex-shrink: 0; align-self: flex-end; margin-bottom: 0.15rem; }
|
|
1090
|
+
.lcp-manage-detail { padding: 0.75rem; border-top: 1px solid var(--lcp-bg-active); background: var(--lcp-bg-surface); }
|
|
1091
|
+
.lcp-manage-detail .lcp-form-section { border: none; padding: 0.5rem 0; margin-bottom: 0.5rem; background: transparent; }
|
|
1092
|
+
.lcp-manage-detail .lcp-form-section legend { font-size: 0.8rem; color: var(--lcp-text-muted); font-weight: 600; margin-bottom: 0.25rem; }
|
|
1093
|
+
.lcp-manage-detail .lcp-form-field { margin-bottom: 0.4rem; }
|
|
1094
|
+
.lcp-manage-detail .lcp-form-field label { font-size: 0.75rem; font-weight: 500; margin-bottom: 0.1rem; color: var(--lcp-text-muted); }
|
|
1095
|
+
.lcp-manage-detail .lcp-form-field input[type="text"],
|
|
1096
|
+
.lcp-manage-detail .lcp-form-field input[type="number"],
|
|
1097
|
+
.lcp-manage-detail .lcp-form-field select,
|
|
1098
|
+
.lcp-manage-detail .lcp-form-field textarea { padding: 0.3rem 0.5rem; font-size: 0.8rem; }
|
|
1099
|
+
.lcp-manage-detail .lcp-form-field textarea { min-height: 40px; }
|
|
1100
|
+
.lcp-manage-detail .lcp-grid { gap: 0.5rem !important; }
|
|
1101
|
+
.lcp-manage-actions { display: flex; align-items: center; justify-content: space-between; padding-top: 0.75rem; border-top: 1px solid var(--lcp-border-color); margin-top: 0.5rem; }
|
|
1102
|
+
.lcp-manage-submit { display: flex; gap: 0.5rem; }
|
|
1103
|
+
|
|
1104
|
+
/* ===== Advanced Filter Builder ===== */
|
|
1105
|
+
.lcp-advanced-filter { margin-bottom: 1rem; }
|
|
1106
|
+
.lcp-filter-toggle-row { margin-bottom: 0.5rem; }
|
|
1107
|
+
.lcp-filter-toggle-btn { position: relative; }
|
|
1108
|
+
.lcp-filter-count { display: inline-flex; align-items: center; justify-content: center; min-width: 1.25rem; height: 1.25rem; padding: 0 0.35rem; border-radius: 10px; background: var(--lcp-primary); color: var(--lcp-text-on-primary); font-size: 0.7rem; font-weight: 600; line-height: 1; margin-left: 0.35rem; vertical-align: middle; }
|
|
1109
|
+
.lcp-filter-body { background: var(--lcp-bg-surface); border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); padding: 1rem; position: relative; z-index: 11; }
|
|
1110
|
+
.lcp-filter-rows { margin-bottom: 0.75rem; }
|
|
1111
|
+
.lcp-filter-row { display: flex; gap: 0.5rem; align-items: flex-start; margin-bottom: 0.5rem; flex-wrap: wrap; }
|
|
1112
|
+
.lcp-filter-row select, .lcp-filter-row input, .lcp-filter-row textarea { padding: 0.35rem 0.5rem; border: 1px solid var(--lcp-border-color-input); border-radius: var(--lcp-radius-sm); font-size: 0.85rem; }
|
|
1113
|
+
.lcp-filter-field-select { min-width: 180px; flex: 0 0 auto; }
|
|
1114
|
+
.lcp-filter-field-cascade { display: flex; align-items: center; gap: 0.25rem; flex-wrap: wrap; flex: 0 0 auto; }
|
|
1115
|
+
.lcp-filter-field-cascade select { min-width: 140px; max-width: 200px; }
|
|
1116
|
+
.lcp-filter-field-cascade .ts-wrapper { min-width: 140px; max-width: 200px; }
|
|
1117
|
+
.lcp-cascade-separator { color: var(--lcp-text-muted); font-size: 0.85rem; padding: 0 2px; }
|
|
1118
|
+
.lcp-filter-operator-select { min-width: 140px; flex: 0 0 auto; }
|
|
1119
|
+
.lcp-filter-value-input { min-width: 150px; flex: 1 1 auto; }
|
|
1120
|
+
.lcp-filter-value-input input, .lcp-filter-value-input select, .lcp-filter-value-input textarea { width: 100%; }
|
|
1121
|
+
.lcp-filter-remove-btn { background: none; border: 1px solid var(--lcp-border-color-input); border-radius: var(--lcp-radius-sm); color: var(--lcp-danger); cursor: pointer; padding: 0.35rem 0.5rem; font-size: 0.85rem; line-height: 1; flex: 0 0 auto; }
|
|
1122
|
+
.lcp-filter-remove-btn:hover { background: var(--lcp-danger-bg); border-color: var(--lcp-danger); }
|
|
1123
|
+
.lcp-filter-between { display: flex; gap: 0.35rem; align-items: center; flex: 1 1 auto; min-width: 150px; }
|
|
1124
|
+
.lcp-filter-between input { flex: 1; }
|
|
1125
|
+
.lcp-filter-between-separator { color: var(--lcp-text-muted); font-weight: 500; }
|
|
1126
|
+
.lcp-filter-parameterized { display: flex; gap: 0.35rem; align-items: center; flex: 1 1 auto; min-width: 100px; }
|
|
1127
|
+
.lcp-filter-parameterized input { width: 80px; }
|
|
1128
|
+
.lcp-filter-parameterized-suffix { color: var(--lcp-text-muted); font-size: 0.85rem; }
|
|
1129
|
+
.lcp-filter-combinator { font-size: 0.75rem; font-weight: 600; color: var(--lcp-text-muted); text-transform: uppercase; padding: 0.2rem 0; margin: 0.1rem 0 0.1rem 0.5rem; }
|
|
1130
|
+
.lcp-filter-group { border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); background: var(--lcp-bg-muted); padding: 0.75rem; margin-bottom: 0.5rem; margin-left: 1rem; }
|
|
1131
|
+
.lcp-filter-depth-1 { border-left: 3px solid var(--lcp-primary); padding-left: 1rem; }
|
|
1132
|
+
.lcp-filter-depth-2 { border-left: 3px solid var(--lcp-filter-depth-2); padding-left: 1rem; }
|
|
1133
|
+
.lcp-filter-depth-3 { border-left: 3px solid var(--lcp-filter-depth-3); padding-left: 1rem; }
|
|
1134
|
+
.lcp-filter-group-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem; }
|
|
1135
|
+
.lcp-filter-group-label { font-size: 0.8rem; font-weight: 600; color: var(--lcp-primary); text-transform: uppercase; }
|
|
1136
|
+
.lcp-filter-group-remove { background: none; border: none; color: var(--lcp-danger); cursor: pointer; font-size: 0.8rem; }
|
|
1137
|
+
.lcp-filter-group-remove:hover { text-decoration: underline; }
|
|
1138
|
+
.lcp-filter-group-rows { margin-bottom: 0.5rem; }
|
|
1139
|
+
.lcp-filter-group-add-btn { font-size: 0.8rem; padding: 0.25rem 0.5rem; }
|
|
1140
|
+
.lcp-filter-actions-row { display: flex; gap: 0.5rem; margin-bottom: 0.75rem; }
|
|
1141
|
+
.lcp-filter-actions-row .btn { font-size: 0.85rem; padding: 0.3rem 0.6rem; }
|
|
1142
|
+
.lcp-filter-submit-row { display: flex; gap: 0.5rem; padding-top: 0.75rem; border-top: 1px solid var(--lcp-border-color); }
|
|
1143
|
+
.lcp-ql-section { margin-bottom: 0.75rem; }
|
|
1144
|
+
.lcp-ql-input { width: 100%; padding: 0.5rem; border: 1px solid var(--lcp-border-color-input); border-radius: var(--lcp-radius-sm); font-family: monospace; font-size: 0.85rem; resize: vertical; }
|
|
1145
|
+
.lcp-ql-input:focus { border-color: var(--lcp-focus-border); outline: none; box-shadow: 0 0 0 0.2rem var(--lcp-focus-ring); }
|
|
1146
|
+
.lcp-ql-error { color: var(--lcp-danger); font-size: 0.85rem; margin-top: 0.35rem; padding: 0.35rem 0.5rem; background: var(--lcp-danger-bg); border-radius: var(--lcp-radius-sm); }
|
|
1147
|
+
.lcp-ql-help { font-size: 0.75rem; color: var(--lcp-text-muted); margin-top: 0.35rem; }
|
|
1148
|
+
.lcp-filter-presets { display: flex; align-items: center; gap: 0.35rem; flex-wrap: wrap; margin-bottom: 0.75rem; padding-bottom: 0.75rem; border-bottom: 1px solid var(--lcp-border-color); }
|
|
1149
|
+
.lcp-filter-presets-label { font-size: 0.8rem; font-weight: 500; color: var(--lcp-text-muted); margin-right: 0.15rem; }
|
|
1150
|
+
.lcp-preset-btn { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.25rem 0.6rem; font-size: 0.8rem; border: 1px solid var(--lcp-border-color); border-radius: 12px; background: var(--lcp-bg-surface); color: var(--lcp-text-secondary); cursor: pointer; transition: all 0.15s; white-space: nowrap; }
|
|
1151
|
+
.lcp-preset-btn:hover { background: var(--lcp-bg-active); border-color: var(--lcp-text-disabled); }
|
|
1152
|
+
.lcp-preset-btn.active { background: var(--lcp-primary); border-color: var(--lcp-primary); color: var(--lcp-text-on-primary); }
|
|
1153
|
+
|
|
1154
|
+
/* Index drag-and-drop reordering */
|
|
1155
|
+
.lcp-drag-column { width: 2rem; text-align: center; padding: 0.4rem 0.25rem !important; }
|
|
1156
|
+
th.lcp-drag-column { background: var(--lcp-bg-muted); }
|
|
1157
|
+
.lcp-table .lcp-drag-handle { cursor: grab; font-size: 1rem; color: var(--lcp-text-disabled); user-select: none; }
|
|
1158
|
+
.lcp-table .lcp-drag-handle:active { cursor: grabbing; }
|
|
1159
|
+
.lcp-table .lcp-drag-handle-disabled { cursor: not-allowed; opacity: 0.3; }
|
|
1160
|
+
.lcp-table tr.dragging { opacity: 0.4; background: var(--lcp-bg-active); }
|
|
1161
|
+
.lcp-table tr.drag-over { box-shadow: 0 -2px 0 0 var(--lcp-primary) inset; }
|
|
1162
|
+
.lcp-table tr.drag-over-top { box-shadow: 0 2px 0 0 var(--lcp-primary) inset; }
|
|
1163
|
+
.lcp-reorder-flash { margin-bottom: 1rem; }
|
|
1164
|
+
|
|
1165
|
+
/* Error pages */
|
|
1166
|
+
.lcp-error-page { text-align: center; padding: 3rem 1rem; }
|
|
1167
|
+
.lcp-error-page h1 { font-size: 2rem; margin-bottom: 1rem; color: var(--lcp-text-muted); }
|
|
1168
|
+
.lcp-error-message { color: var(--lcp-text-muted); margin-bottom: 1.5rem; }
|
|
1169
|
+
|
|
1170
|
+
/* Empty value placeholder */
|
|
1171
|
+
.lcp-empty-value { color: var(--lcp-text-disabled); font-style: italic; }
|
|
1172
|
+
|
|
1173
|
+
/* Tree index view */
|
|
1174
|
+
.lcp-tree-table .lcp-tree-row { transition: background-color 0.15s; }
|
|
1175
|
+
|
|
1176
|
+
/* Tree cell: first column holds the tree structure */
|
|
1177
|
+
.lcp-tree-cell { padding-top: 0 !important; padding-bottom: 0 !important; padding-left: 8px !important; overflow: visible; }
|
|
1178
|
+
.lcp-tree-node { display: flex; align-items: center; min-height: calc(1.5em + 1.2rem); }
|
|
1179
|
+
|
|
1180
|
+
/* Tree guide: fixed-width slot for each depth level */
|
|
1181
|
+
.lcp-tree-guide { flex-shrink: 0; width: 24px; align-self: stretch; position: relative; }
|
|
1182
|
+
|
|
1183
|
+
/* Vertical pipe - continues through full row height */
|
|
1184
|
+
.lcp-tree-guide-pipe::before { content: ''; position: absolute; left: 11px; top: -1px; bottom: -1px; width: 1px; background: var(--lcp-tree-guide); }
|
|
1185
|
+
|
|
1186
|
+
/* Tee connector (non-last child) */
|
|
1187
|
+
.lcp-tree-guide-tee::before { content: ''; position: absolute; left: 11px; top: -1px; bottom: -1px; width: 1px; background: var(--lcp-tree-guide); }
|
|
1188
|
+
.lcp-tree-guide-tee::after { content: ''; position: absolute; left: 11px; top: 50%; width: 13px; height: 1px; background: var(--lcp-tree-guide); }
|
|
1189
|
+
|
|
1190
|
+
/* Elbow connector (last child) */
|
|
1191
|
+
.lcp-tree-guide-elbow::before { content: ''; position: absolute; left: 11px; top: -1px; height: calc(50% + 1px); width: 1px; background: var(--lcp-tree-guide); }
|
|
1192
|
+
.lcp-tree-guide-elbow::after { content: ''; position: absolute; left: 11px; top: 50%; width: 13px; height: 1px; background: var(--lcp-tree-guide); }
|
|
1193
|
+
|
|
1194
|
+
/* Chevron toggle */
|
|
1195
|
+
.lcp-tree-chevron { background: none; border: none; cursor: pointer; padding: 0 4px; font-size: 0.7em; color: var(--lcp-text-muted); transition: transform 0.2s; display: inline-block; width: 20px; text-align: center; flex-shrink: 0; }
|
|
1196
|
+
.lcp-tree-chevron.expanded { transform: rotate(90deg); }
|
|
1197
|
+
.lcp-tree-leaf-spacer { display: inline-block; width: 20px; flex-shrink: 0; }
|
|
1198
|
+
|
|
1199
|
+
/* Ancestor context (search results) */
|
|
1200
|
+
.lcp-tree-ancestor-context { opacity: 0.5; }
|
|
1201
|
+
.lcp-tree-ancestor-context .lcp-actions { visibility: hidden; }
|
|
1202
|
+
.lcp-tree-drop-before { border-top: 2px solid var(--lcp-primary); }
|
|
1203
|
+
.lcp-tree-drop-child { background-color: var(--lcp-primary-bg); }
|
|
1204
|
+
.lcp-tree-drop-after { border-bottom: 2px solid var(--lcp-primary); }
|
|
1205
|
+
.lcp-tree-drop-invalid { border: 2px solid var(--lcp-danger); }
|
|
1206
|
+
.lcp-tree-root-drop-zone { padding: 8px; margin-top: 4px; border: 2px dashed var(--lcp-border-color); border-radius: var(--lcp-radius-sm); text-align: center; color: var(--lcp-text-muted); font-size: 0.85em; display: none; }
|
|
1207
|
+
.lcp-tree-root-drop-zone.active { display: block; border-color: var(--lcp-primary); background: var(--lcp-bg-subtle); }
|
|
1208
|
+
|
|
1209
|
+
/* Copy buttons */
|
|
1210
|
+
.lcp-copy-url.lcp-copied { background: var(--lcp-success-bg); border-color: var(--lcp-success-border); }
|
|
1211
|
+
.lcp-copy-field { background: none; border: none; cursor: pointer; color: var(--lcp-text-muted); padding: 0 0.25rem; vertical-align: middle; opacity: 0.6; }
|
|
1212
|
+
.lcp-copy-field:hover { opacity: 1; color: var(--lcp-text); }
|
|
1213
|
+
.lcp-copy-field.lcp-copied { color: var(--lcp-success); opacity: 1; }
|
|
1214
|
+
|
|
1215
|
+
/* Saved Filters */
|
|
1216
|
+
.lcp-saved-filters { display: flex; align-items: center; gap: 0.25rem; flex-wrap: wrap; margin-bottom: 0.5rem; }
|
|
1217
|
+
.lcp-saved-filter-btn { font-size: 0.85rem; }
|
|
1218
|
+
.lcp-saved-filter-btn.active { background: var(--lcp-primary); color: var(--lcp-text-on-primary); border-color: var(--lcp-primary); }
|
|
1219
|
+
.lcp-saved-filter-dropdown { position: relative; display: inline-block; }
|
|
1220
|
+
.lcp-saved-filter-dropdown-menu { position: absolute; top: 100%; left: 0; z-index: 1000; min-width: 200px; background: var(--lcp-bg-surface-raised); border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); box-shadow: var(--lcp-shadow-md); padding: 0.25rem 0; max-height: 300px; overflow-y: auto; }
|
|
1221
|
+
.lcp-filter-group-label { padding: 0.35rem 0.75rem; font-size: 0.75rem; color: var(--lcp-text-muted); text-transform: uppercase; font-weight: 600; }
|
|
1222
|
+
.lcp-saved-filter-item { display: block; padding: 0.35rem 0.75rem; color: var(--lcp-text); text-decoration: none; font-size: 0.85rem; }
|
|
1223
|
+
.lcp-saved-filter-item:hover { background: var(--lcp-bg-hover); }
|
|
1224
|
+
.lcp-saved-filter-item.active { background: var(--lcp-primary-bg); color: var(--lcp-primary); font-weight: 500; }
|
|
1225
|
+
.lcp-filter-icon { margin-right: 0.25rem; }
|
|
1226
|
+
.lcp-save-filter-btn { font-size: 0.85rem; color: var(--lcp-text-muted); border-style: dashed; }
|
|
1227
|
+
|
|
1228
|
+
/* Save dialog */
|
|
1229
|
+
.lcp-save-dialog { position: fixed; top: 0; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: center; z-index: 10000; }
|
|
1230
|
+
.lcp-save-dialog-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: var(--lcp-overlay-bg); }
|
|
1231
|
+
.lcp-save-dialog-content { position: relative; background: var(--lcp-bg-surface-raised); border-radius: var(--lcp-radius-lg); box-shadow: var(--lcp-shadow-lg); padding: 1.5rem; width: 100%; max-width: 480px; max-height: 90vh; overflow-y: auto; }
|
|
1232
|
+
.lcp-save-dialog-content h3 { margin-bottom: 1rem; font-size: 1.1rem; }
|
|
1233
|
+
.lcp-save-dialog-field { margin-bottom: 0.75rem; }
|
|
1234
|
+
.lcp-save-dialog-field label { display: block; font-size: 0.85rem; font-weight: 500; margin-bottom: 0.25rem; }
|
|
1235
|
+
.lcp-save-dialog-checkbox label { display: flex; align-items: center; gap: 0.5rem; font-weight: normal; }
|
|
1236
|
+
.lcp-save-dialog-actions { display: flex; gap: 0.5rem; margin-top: 1rem; justify-content: flex-end; }
|
|
1237
|
+
|
|
1238
|
+
/* Scope parameters */
|
|
1239
|
+
.lcp-scope-params { display: flex; flex-direction: column; gap: 0.5rem; }
|
|
1240
|
+
.lcp-scope-param { display: flex; align-items: center; gap: 0.5rem; }
|
|
1241
|
+
.lcp-scope-param label { font-size: 0.8rem; color: var(--lcp-text-secondary); white-space: nowrap; min-width: 80px; }
|
|
1242
|
+
.lcp-scope-param input, .lcp-scope-param select { flex: 1; }
|
|
1243
|
+
|
|
1244
|
+
/* --- Card (shared base for tile, kanban, and future card-based layouts) --- */
|
|
1245
|
+
.lcp-card {
|
|
1246
|
+
position: relative;
|
|
1247
|
+
display: flex;
|
|
1248
|
+
flex-direction: column;
|
|
1249
|
+
background: var(--lcp-bg-surface);
|
|
1250
|
+
border: 1px solid var(--lcp-border-color);
|
|
1251
|
+
border-left: 4px solid var(--lcp-card-accent, transparent);
|
|
1252
|
+
border-radius: var(--lcp-radius-md);
|
|
1253
|
+
/* No overflow: hidden — would clip the actions dropdown menu when it
|
|
1254
|
+
opens past the card edge. The banner image gets its own corner-radius
|
|
1255
|
+
below so it still respects the card's rounded top corners. */
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
.lcp-card-image {
|
|
1259
|
+
width: 100%;
|
|
1260
|
+
max-height: var(--lcp-card-image-max-height, 220px);
|
|
1261
|
+
overflow: hidden;
|
|
1262
|
+
border-top-left-radius: var(--lcp-radius-md);
|
|
1263
|
+
border-top-right-radius: var(--lcp-radius-md);
|
|
1264
|
+
}
|
|
1265
|
+
.lcp-card-image img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
1266
|
+
|
|
1267
|
+
.lcp-card-avatar { width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0; overflow: hidden; }
|
|
1268
|
+
.lcp-card-avatar img { width: 100%; height: 100%; object-fit: cover; }
|
|
1269
|
+
|
|
1270
|
+
.lcp-card-title { font-weight: 600; font-size: 1rem; line-height: 1.3; }
|
|
1271
|
+
.lcp-card-title a { color: var(--lcp-text-link); text-decoration: none; }
|
|
1272
|
+
.lcp-card-title a:hover { text-decoration: underline; }
|
|
1273
|
+
|
|
1274
|
+
.lcp-card-subtitle { font-size: 0.85rem; color: var(--lcp-text-muted); }
|
|
1275
|
+
|
|
1276
|
+
.lcp-card-description {
|
|
1277
|
+
padding: 0 1rem 0.5rem;
|
|
1278
|
+
font-size: 0.85rem;
|
|
1279
|
+
color: var(--lcp-text-secondary);
|
|
1280
|
+
display: -webkit-box;
|
|
1281
|
+
-webkit-line-clamp: var(--lcp-card-desc-lines, 3);
|
|
1282
|
+
-webkit-box-orient: vertical;
|
|
1283
|
+
overflow: hidden;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
.lcp-card-fields {
|
|
1287
|
+
padding: 0 1rem 0.75rem;
|
|
1288
|
+
display: grid;
|
|
1289
|
+
grid-template-columns: auto 1fr;
|
|
1290
|
+
gap: 0.25rem 0.75rem;
|
|
1291
|
+
font-size: 0.85rem;
|
|
1292
|
+
}
|
|
1293
|
+
.lcp-card-field-label { color: var(--lcp-text-muted); font-weight: 500; }
|
|
1294
|
+
.lcp-card-field-value { color: var(--lcp-text); }
|
|
1295
|
+
|
|
1296
|
+
.lcp-card-actions {
|
|
1297
|
+
padding: 0.5rem 1rem;
|
|
1298
|
+
border-top: 1px solid var(--lcp-border-color-subtle);
|
|
1299
|
+
display: flex;
|
|
1300
|
+
justify-content: flex-end;
|
|
1301
|
+
gap: 0.35rem;
|
|
1302
|
+
align-items: center;
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
/* --- Tile layout (grid + tile-card density) --- */
|
|
1306
|
+
.lcp-tiles-grid { display: grid; grid-template-columns: repeat(var(--lcp-tile-columns, 3), 1fr); gap: 1rem; margin-bottom: 1rem; }
|
|
1307
|
+
@media (max-width: 1200px) { .lcp-tiles-grid { grid-template-columns: repeat(2, 1fr); } }
|
|
1308
|
+
@media (max-width: 768px) { .lcp-tiles-grid { grid-template-columns: 1fr; } }
|
|
1309
|
+
|
|
1310
|
+
.lcp-tile-card { transition: box-shadow 0.15s ease; }
|
|
1311
|
+
.lcp-tile-card:hover { box-shadow: var(--lcp-shadow-md); }
|
|
1312
|
+
|
|
1313
|
+
.lcp-tile-header { display: flex; align-items: flex-start; gap: 0.75rem; padding: 0.75rem 1rem; }
|
|
1314
|
+
.lcp-tile-heading { flex: 1; display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
|
|
1315
|
+
|
|
1316
|
+
/* Inline action buttons inside .lcp-card-actions (parity with previous tile look). */
|
|
1317
|
+
.lcp-tile-action-btn { font-size: 0.8rem; padding: 0.25rem 0.6rem; border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); background: var(--lcp-bg-surface); color: var(--lcp-text); text-decoration: none; cursor: pointer; display: inline-block; line-height: 1.4; }
|
|
1318
|
+
.lcp-tile-action-btn:hover { background: var(--lcp-bg-hover); border-color: var(--lcp-text-disabled); }
|
|
1319
|
+
.lcp-card-actions form.lcp-tile-action-btn { border: none; padding: 0; background: none; display: inline; }
|
|
1320
|
+
.lcp-card-actions button.lcp-tile-action-btn.btn-danger { background: var(--lcp-bg-surface); color: var(--lcp-danger); border-color: var(--lcp-danger); font-size: 0.8rem; padding: 0.25rem 0.6rem; line-height: 1.4; }
|
|
1321
|
+
.lcp-card-actions button.lcp-tile-action-btn.btn-danger:hover { background: var(--lcp-danger); color: var(--lcp-text-on-primary); }
|
|
1322
|
+
|
|
1323
|
+
/* --- Kanban layout (Phase 1) --- */
|
|
1324
|
+
.lcp-kanban-board {
|
|
1325
|
+
display: flex;
|
|
1326
|
+
gap: 1rem;
|
|
1327
|
+
overflow-x: auto;
|
|
1328
|
+
padding-bottom: 0.5rem;
|
|
1329
|
+
align-items: flex-start;
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
.lcp-kanban-column {
|
|
1333
|
+
flex: 0 0 280px;
|
|
1334
|
+
display: flex;
|
|
1335
|
+
flex-direction: column;
|
|
1336
|
+
background: var(--lcp-bg-muted, var(--lcp-bg-surface));
|
|
1337
|
+
border: 1px solid var(--lcp-border-color);
|
|
1338
|
+
border-radius: var(--lcp-radius-md);
|
|
1339
|
+
max-height: 80vh;
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
.lcp-kanban-column-header {
|
|
1343
|
+
display: flex;
|
|
1344
|
+
align-items: center;
|
|
1345
|
+
justify-content: space-between;
|
|
1346
|
+
padding: 0.6rem 0.75rem;
|
|
1347
|
+
border-bottom: 1px solid var(--lcp-border-color);
|
|
1348
|
+
border-left: 4px solid var(--lcp-card-accent, transparent);
|
|
1349
|
+
position: sticky;
|
|
1350
|
+
top: 0;
|
|
1351
|
+
background: var(--lcp-bg-surface);
|
|
1352
|
+
z-index: 1;
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
.lcp-kanban-column-title { margin: 0; font-size: 0.95rem; font-weight: 600; color: var(--lcp-text); }
|
|
1356
|
+
.lcp-kanban-column-count { font-size: 0.8rem; color: var(--lcp-text-muted); padding: 0 0.4rem; border-radius: var(--lcp-radius-sm); background: var(--lcp-bg-muted, transparent); }
|
|
1357
|
+
|
|
1358
|
+
.lcp-kanban-column-body {
|
|
1359
|
+
display: flex;
|
|
1360
|
+
flex-direction: column;
|
|
1361
|
+
gap: 0.5rem;
|
|
1362
|
+
padding: 0.5rem;
|
|
1363
|
+
overflow-y: auto;
|
|
1364
|
+
flex: 1 1 auto;
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
.lcp-kanban-card {
|
|
1368
|
+
cursor: grab;
|
|
1369
|
+
padding: 0.6rem 0.75rem;
|
|
1370
|
+
transition: box-shadow 0.15s ease, transform 0.05s ease;
|
|
1371
|
+
}
|
|
1372
|
+
.lcp-kanban-card:hover { box-shadow: var(--lcp-shadow-md); }
|
|
1373
|
+
.lcp-kanban-card[draggable="false"] { cursor: not-allowed; opacity: 0.85; }
|
|
1374
|
+
|
|
1375
|
+
.lcp-kanban-header {
|
|
1376
|
+
display: flex;
|
|
1377
|
+
align-items: center;
|
|
1378
|
+
gap: 0.5rem;
|
|
1379
|
+
margin-bottom: 0.4rem;
|
|
1380
|
+
}
|
|
1381
|
+
.lcp-kanban-header .lcp-card-title { font-size: 0.9rem; flex: 1; min-width: 0; }
|
|
1382
|
+
.lcp-kanban-header .lcp-card-subtitle { font-size: 0.75rem; }
|
|
1383
|
+
|
|
1384
|
+
.lcp-kanban-load-more {
|
|
1385
|
+
display: block;
|
|
1386
|
+
text-align: center;
|
|
1387
|
+
padding: 0.4rem;
|
|
1388
|
+
font-size: 0.85rem;
|
|
1389
|
+
color: var(--lcp-link, var(--lcp-primary));
|
|
1390
|
+
text-decoration: none;
|
|
1391
|
+
border-top: 1px dashed var(--lcp-border-color-subtle, var(--lcp-border-color));
|
|
1392
|
+
}
|
|
1393
|
+
.lcp-kanban-load-more:hover { background: var(--lcp-bg-hover); }
|
|
1394
|
+
|
|
1395
|
+
/* Drag states. Phase 1 uses whole-column highlight only; per-card placement
|
|
1396
|
+
indicators below are dormant until Phase 5 (within-column reorder) sets
|
|
1397
|
+
data-lcp-kanban-board-positioning-enabled-value="true". */
|
|
1398
|
+
.lcp-kanban-card.lcp-dragging { opacity: 0.5; cursor: grabbing; }
|
|
1399
|
+
.lcp-kanban-column-body.lcp-drop-target {
|
|
1400
|
+
background: var(--lcp-primary-bg, rgba(37, 99, 235, 0.08));
|
|
1401
|
+
outline: 2px dashed var(--lcp-primary, var(--lcp-link, #2563eb));
|
|
1402
|
+
outline-offset: -4px;
|
|
1403
|
+
border-radius: var(--lcp-radius-md);
|
|
1404
|
+
}
|
|
1405
|
+
.lcp-kanban-column-body.lcp-drop-invalid {
|
|
1406
|
+
background: rgba(220, 53, 69, 0.08);
|
|
1407
|
+
outline: 2px dashed var(--lcp-danger);
|
|
1408
|
+
outline-offset: -4px;
|
|
1409
|
+
border-radius: var(--lcp-radius-md);
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
/* Phase 5: per-card placement preview (positioningEnabledValue=true). */
|
|
1413
|
+
.lcp-kanban-card.lcp-kanban-drop-before {
|
|
1414
|
+
position: relative;
|
|
1415
|
+
}
|
|
1416
|
+
.lcp-kanban-card.lcp-kanban-drop-before::before {
|
|
1417
|
+
content: "";
|
|
1418
|
+
position: absolute;
|
|
1419
|
+
top: -0.3rem;
|
|
1420
|
+
left: 0;
|
|
1421
|
+
right: 0;
|
|
1422
|
+
height: 0;
|
|
1423
|
+
border-top: 3px solid var(--lcp-primary, var(--lcp-link, #2563eb));
|
|
1424
|
+
border-radius: 2px;
|
|
1425
|
+
pointer-events: none;
|
|
1426
|
+
}
|
|
1427
|
+
.lcp-kanban-column-body.lcp-kanban-drop-end::after {
|
|
1428
|
+
content: "";
|
|
1429
|
+
display: block;
|
|
1430
|
+
margin: 0.25rem 0;
|
|
1431
|
+
height: 0;
|
|
1432
|
+
border-top: 3px solid var(--lcp-primary, var(--lcp-link, #2563eb));
|
|
1433
|
+
border-radius: 2px;
|
|
1434
|
+
opacity: 0.85;
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
/* Mobile: Phase 1 disables HTML5 drag on touch devices (Phase 5 brings dedicated mobile UX). */
|
|
1438
|
+
@media (hover: none) and (pointer: coarse) {
|
|
1439
|
+
.lcp-kanban-card { -webkit-user-drag: none; cursor: default; }
|
|
1440
|
+
}
|
|
1441
|
+
@media (max-width: 768px) {
|
|
1442
|
+
.lcp-kanban-column { flex: 0 0 85vw; }
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
/* Sort dropdown */
|
|
1446
|
+
.lcp-sort-dropdown { display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.85rem; }
|
|
1447
|
+
.lcp-sort-dropdown label { color: var(--lcp-text-muted); white-space: nowrap; }
|
|
1448
|
+
.lcp-sort-dropdown select { padding: 0.25rem 0.5rem; border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); font-size: 0.85rem; background: var(--lcp-bg-surface); }
|
|
1449
|
+
.lcp-sort-direction-btn { padding: 0.25rem 0.5rem; border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); background: var(--lcp-bg-surface); cursor: pointer; font-size: 0.85rem; }
|
|
1450
|
+
.lcp-sort-direction-btn:hover { background: var(--lcp-bg-hover); }
|
|
1451
|
+
|
|
1452
|
+
/* Per-page selector */
|
|
1453
|
+
.lcp-per-page-selector { display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.85rem; }
|
|
1454
|
+
.lcp-per-page-selector label { color: var(--lcp-text-muted); white-space: nowrap; }
|
|
1455
|
+
.lcp-per-page-selector select { padding: 0.25rem 0.5rem; border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); font-size: 0.85rem; background: var(--lcp-bg-surface); }
|
|
1456
|
+
|
|
1457
|
+
/* --- Pagination footer bar --- */
|
|
1458
|
+
.lcp-pagination-footer {
|
|
1459
|
+
display: flex;
|
|
1460
|
+
align-items: center;
|
|
1461
|
+
justify-content: space-between;
|
|
1462
|
+
flex-wrap: wrap;
|
|
1463
|
+
padding: 0.75rem 0;
|
|
1464
|
+
margin-top: 0.5rem;
|
|
1465
|
+
font-size: 0.85rem;
|
|
1466
|
+
gap: 0.75rem 1rem;
|
|
1467
|
+
}
|
|
1468
|
+
.lcp-pagination-footer__info { color: var(--lcp-text-muted); white-space: nowrap; }
|
|
1469
|
+
.lcp-pagination-footer__pages { margin-left: auto; }
|
|
1470
|
+
|
|
1471
|
+
/* --- Kaminari pagination links (shared between index footer and zone frames) --- */
|
|
1472
|
+
.lcp-pagination-footer nav.pagination,
|
|
1473
|
+
.lcp-zone-pagination nav.pagination {
|
|
1474
|
+
display: inline-flex;
|
|
1475
|
+
align-items: center;
|
|
1476
|
+
gap: 2px;
|
|
1477
|
+
list-style: none;
|
|
1478
|
+
margin: 0;
|
|
1479
|
+
padding: 0;
|
|
1480
|
+
}
|
|
1481
|
+
.lcp-pagination-footer nav.pagination span,
|
|
1482
|
+
.lcp-zone-pagination nav.pagination span {
|
|
1483
|
+
display: inline-flex;
|
|
1484
|
+
}
|
|
1485
|
+
.lcp-pagination-footer nav.pagination a,
|
|
1486
|
+
.lcp-pagination-footer nav.pagination span.current,
|
|
1487
|
+
.lcp-zone-pagination nav.pagination a,
|
|
1488
|
+
.lcp-zone-pagination nav.pagination span.current {
|
|
1489
|
+
display: inline-flex;
|
|
1490
|
+
align-items: center;
|
|
1491
|
+
justify-content: center;
|
|
1492
|
+
min-width: 2rem;
|
|
1493
|
+
height: 2rem;
|
|
1494
|
+
padding: 0 0.5rem;
|
|
1495
|
+
border: 1px solid var(--lcp-border-color);
|
|
1496
|
+
border-radius: var(--lcp-radius-sm);
|
|
1497
|
+
text-decoration: none;
|
|
1498
|
+
color: var(--lcp-text-secondary);
|
|
1499
|
+
font-size: 0.85rem;
|
|
1500
|
+
background: var(--lcp-bg-surface);
|
|
1501
|
+
transition: background 0.15s, color 0.15s;
|
|
1502
|
+
}
|
|
1503
|
+
.lcp-pagination-footer nav.pagination a:hover,
|
|
1504
|
+
.lcp-zone-pagination nav.pagination a:hover {
|
|
1505
|
+
background: var(--lcp-bg-active);
|
|
1506
|
+
color: var(--lcp-text);
|
|
1507
|
+
}
|
|
1508
|
+
.lcp-pagination-footer nav.pagination span.current,
|
|
1509
|
+
.lcp-zone-pagination nav.pagination span.current {
|
|
1510
|
+
background: var(--lcp-primary);
|
|
1511
|
+
color: var(--lcp-text-on-primary);
|
|
1512
|
+
border-color: var(--lcp-primary);
|
|
1513
|
+
font-weight: 600;
|
|
1514
|
+
}
|
|
1515
|
+
/* Disabled prev/next (Kaminari renders <span class="prev disabled"> etc.) */
|
|
1516
|
+
.lcp-pagination-footer nav.pagination .disabled,
|
|
1517
|
+
.lcp-pagination-footer nav.pagination .disabled a,
|
|
1518
|
+
.lcp-zone-pagination nav.pagination .disabled,
|
|
1519
|
+
.lcp-zone-pagination nav.pagination .disabled a {
|
|
1520
|
+
color: var(--lcp-text-disabled);
|
|
1521
|
+
pointer-events: none;
|
|
1522
|
+
cursor: default;
|
|
1523
|
+
background: var(--lcp-bg-muted);
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
/*
|
|
1527
|
+
* Hide First/Last links by default, show only when opted in.
|
|
1528
|
+
* The show rule below has higher specificity due to the extra class.
|
|
1529
|
+
*/
|
|
1530
|
+
.lcp-pagination-footer nav.pagination .first,
|
|
1531
|
+
.lcp-pagination-footer nav.pagination .last { display: none; }
|
|
1532
|
+
|
|
1533
|
+
.lcp-pagination-footer.lcp-pagination--with-ends nav.pagination .first,
|
|
1534
|
+
.lcp-pagination-footer.lcp-pagination--with-ends nav.pagination .last { display: inline-flex; }
|
|
1535
|
+
|
|
1536
|
+
/* Summary bar */
|
|
1537
|
+
.lcp-summary-bar { display: flex; flex-wrap: wrap; gap: 1.5rem; padding: 0.75rem 1rem; background: var(--lcp-bg-muted); border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); margin-bottom: 0.75rem; }
|
|
1538
|
+
.lcp-summary-bar-item { display: flex; flex-direction: column; }
|
|
1539
|
+
.lcp-summary-bar-label { font-size: 0.75rem; color: var(--lcp-text-muted); text-transform: uppercase; letter-spacing: 0.05em; }
|
|
1540
|
+
.lcp-summary-bar-value { font-size: 1.1rem; font-weight: 600; color: var(--lcp-text); }
|
|
1541
|
+
|
|
1542
|
+
/* Row styling utility classes */
|
|
1543
|
+
.lcp-row-danger { background: var(--lcp-row-danger-bg) !important; }
|
|
1544
|
+
.lcp-row-warning { background: var(--lcp-row-warning-bg) !important; }
|
|
1545
|
+
.lcp-row-success { background: var(--lcp-row-success-bg) !important; }
|
|
1546
|
+
.lcp-row-info { background: var(--lcp-row-info-bg) !important; }
|
|
1547
|
+
.lcp-row-muted { opacity: var(--lcp-row-muted-opacity); }
|
|
1548
|
+
.lcp-row-bold { font-weight: bold; }
|
|
1549
|
+
.lcp-row-strikethrough { text-decoration: line-through; }
|
|
1550
|
+
|
|
1551
|
+
/* Array input */
|
|
1552
|
+
.lcp-array-input-wrapper { position: relative; }
|
|
1553
|
+
.lcp-array-chips { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-bottom: 0.35rem; }
|
|
1554
|
+
.lcp-array-chip { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.2rem 0.5rem; background: var(--lcp-bg-active); border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); font-size: 0.85rem; }
|
|
1555
|
+
.lcp-array-chip-remove { background: none; border: none; cursor: pointer; font-size: 1rem; line-height: 1; color: var(--lcp-text-muted); padding: 0 0.15rem; }
|
|
1556
|
+
.lcp-array-chip-remove:hover { color: var(--lcp-danger); }
|
|
1557
|
+
.lcp-array-text-input { width: 100%; padding: 0.4rem 0.75rem; border: 1px solid var(--lcp-border-color-input); border-radius: var(--lcp-radius-sm); font-size: 0.875rem; }
|
|
1558
|
+
.lcp-array-text-input:focus { outline: none; border-color: var(--lcp-focus-border); box-shadow: 0 0 0 0.2rem var(--lcp-focus-ring); }
|
|
1559
|
+
.lcp-array-suggestions { position: absolute; z-index: 20; left: 0; right: 0; max-height: 200px; overflow-y: auto; background: var(--lcp-bg-surface-raised); border: 1px solid var(--lcp-border-color-input); border-radius: var(--lcp-radius-sm); box-shadow: var(--lcp-shadow-md); margin-top: 2px; }
|
|
1560
|
+
.lcp-array-suggestion-item { padding: 0.4rem 0.75rem; cursor: pointer; font-size: 0.875rem; }
|
|
1561
|
+
.lcp-array-suggestion-item:hover { background: var(--lcp-bg-active); }
|
|
1562
|
+
|
|
1563
|
+
/* Dashboard / Grid layout */
|
|
1564
|
+
.lcp-grid-container { display: grid; grid-template-columns: repeat(12, 1fr); gap: 1rem; margin-top: 1rem; }
|
|
1565
|
+
.lcp-grid-zone { min-height: 0; min-width: 0; overflow: hidden; }
|
|
1566
|
+
.lcp-widget { background: var(--lcp-bg-surface); border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-lg); padding: 1.25rem; height: 100%; min-width: 0; overflow-x: auto; }
|
|
1567
|
+
.lcp-widget-title { font-size: 0.875rem; font-weight: 600; color: var(--lcp-text-secondary); margin-bottom: 0.75rem; }
|
|
1568
|
+
.lcp-widget-empty { color: var(--lcp-text-muted); font-size: 0.8125rem; }
|
|
1569
|
+
|
|
1570
|
+
/* KPI card */
|
|
1571
|
+
.lcp-widget-kpi_card { text-align: center; display: flex; flex-direction: column; align-items: center; justify-content: center; }
|
|
1572
|
+
.lcp-kpi-content { display: flex; flex-direction: column; align-items: center; gap: 0.25rem; }
|
|
1573
|
+
.lcp-kpi-icon { font-size: 1.5rem; color: var(--lcp-primary); margin-bottom: 0.25rem; }
|
|
1574
|
+
.lcp-kpi-value { font-size: 2rem; font-weight: 700; color: var(--lcp-text); line-height: 1.2; }
|
|
1575
|
+
.lcp-kpi-label { font-size: 0.8125rem; color: var(--lcp-text-muted); text-transform: uppercase; letter-spacing: 0.05em; }
|
|
1576
|
+
.lcp-kpi-link { font-size: 0.75rem; color: var(--lcp-text-link); text-decoration: none; margin-top: 0.5rem; }
|
|
1577
|
+
.lcp-kpi-link:hover { text-decoration: underline; }
|
|
1578
|
+
|
|
1579
|
+
/* Text widget */
|
|
1580
|
+
.lcp-widget-text { font-size: 0.9375rem; line-height: 1.6; color: var(--lcp-text-secondary); }
|
|
1581
|
+
|
|
1582
|
+
/* List widget */
|
|
1583
|
+
.lcp-widget-list-items { list-style: none; }
|
|
1584
|
+
.lcp-widget-list-items li { padding: 0.375rem 0; border-bottom: 1px solid var(--lcp-border-color-subtle); font-size: 0.875rem; }
|
|
1585
|
+
.lcp-widget-list-items li:last-child { border-bottom: none; }
|
|
1586
|
+
.lcp-widget-link { display: inline-block; margin-top: 0.5rem; font-size: 0.75rem; color: var(--lcp-text-link); text-decoration: none; }
|
|
1587
|
+
.lcp-widget-link:hover { text-decoration: underline; }
|
|
1588
|
+
|
|
1589
|
+
/* Presenter zone (compact table) */
|
|
1590
|
+
/* Chart widget */
|
|
1591
|
+
.lcp-chart-content { display: flex; flex-direction: column; height: 100%; }
|
|
1592
|
+
.lcp-chart-container { flex: 1; min-height: 200px; }
|
|
1593
|
+
|
|
1594
|
+
/* KPI trend indicator */
|
|
1595
|
+
.lcp-kpi-trend { font-size: 0.85rem; margin-top: 0.25rem; }
|
|
1596
|
+
.lcp-kpi-trend-up { color: var(--lcp-success); }
|
|
1597
|
+
.lcp-kpi-trend-down { color: var(--lcp-danger); }
|
|
1598
|
+
.lcp-kpi-trend-neutral { color: var(--lcp-text-muted); }
|
|
1599
|
+
.lcp-trend-arrow { margin-right: 0.25rem; }
|
|
1600
|
+
|
|
1601
|
+
.lcp-widget-presenter-zone .lcp-table-compact { width: 100%; font-size: 0.8125rem; }
|
|
1602
|
+
.lcp-widget-presenter-zone .lcp-table-compact th { padding: 0.375rem 0.5rem; font-weight: 600; border-bottom: 2px solid var(--lcp-border-color); text-align: left; }
|
|
1603
|
+
.lcp-widget-presenter-zone .lcp-table-compact td { padding: 0.375rem 0.5rem; border-bottom: 1px solid var(--lcp-border-color-subtle); }
|
|
1604
|
+
|
|
1605
|
+
/* Dashboard responsive */
|
|
1606
|
+
@media (max-width: 768px) {
|
|
1607
|
+
.lcp-grid-container { grid-template-columns: 1fr; }
|
|
1608
|
+
.lcp-grid-zone { grid-column: 1 !important; grid-row: auto !important; }
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
/* Semantic / Composite page layout */
|
|
1612
|
+
.lcp-semantic-layout {
|
|
1613
|
+
display: grid;
|
|
1614
|
+
grid-template-columns: 1fr;
|
|
1615
|
+
gap: 1.5rem;
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1618
|
+
.lcp-semantic-layout.lcp-has-sidebar {
|
|
1619
|
+
grid-template-columns: 2fr 1fr;
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1622
|
+
.lcp-area-main { grid-column: 1; min-width: 0; overflow-x: auto; }
|
|
1623
|
+
.lcp-area-sidebar { grid-column: 2; grid-row: 1 / span 2; min-width: 0; }
|
|
1624
|
+
.lcp-area-tabs { grid-column: 1; min-width: 0; overflow-x: auto; }
|
|
1625
|
+
.lcp-area-below { grid-column: 1 / -1; min-width: 0; overflow-x: auto; }
|
|
1626
|
+
|
|
1627
|
+
/* Master-detail: sidebar on the left, main on the right */
|
|
1628
|
+
.lcp-semantic-layout.lcp-master-detail {
|
|
1629
|
+
grid-template-columns: 1fr 2fr;
|
|
1630
|
+
}
|
|
1631
|
+
.lcp-master-detail .lcp-area-sidebar { grid-column: 1; grid-row: 1 / span 2; }
|
|
1632
|
+
.lcp-master-detail .lcp-area-main { grid-column: 2; }
|
|
1633
|
+
.lcp-master-detail .lcp-area-tabs { grid-column: 2; }
|
|
1634
|
+
|
|
1635
|
+
/* Hide Actions column in selection sidebar */
|
|
1636
|
+
.lcp-selection-zone .lcp-actions,
|
|
1637
|
+
.lcp-selection-zone th:last-child { display: none; }
|
|
1638
|
+
|
|
1639
|
+
/* Tab bar */
|
|
1640
|
+
.lcp-tab-bar {
|
|
1641
|
+
display: flex;
|
|
1642
|
+
border-bottom: 2px solid var(--lcp-border-color);
|
|
1643
|
+
margin-bottom: 1rem;
|
|
1644
|
+
}
|
|
1645
|
+
|
|
1646
|
+
.lcp-tab {
|
|
1647
|
+
padding: 0.5rem 1rem;
|
|
1648
|
+
text-decoration: none;
|
|
1649
|
+
border-bottom: 2px solid transparent;
|
|
1650
|
+
margin-bottom: -2px;
|
|
1651
|
+
color: var(--lcp-text-muted);
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
.lcp-tab:hover {
|
|
1655
|
+
color: var(--lcp-text);
|
|
1656
|
+
border-bottom-color: var(--lcp-border-color);
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
.lcp-tab-active {
|
|
1660
|
+
border-bottom-color: var(--lcp-primary);
|
|
1661
|
+
color: var(--lcp-text);
|
|
1662
|
+
font-weight: 600;
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
.lcp-tab-content { margin-top: 0.5rem; }
|
|
1666
|
+
|
|
1667
|
+
/* Tab loading state — Turbo adds [busy] to turbo-frame during fetch */
|
|
1668
|
+
turbo-frame#lcp-zone-tab-content[busy],
|
|
1669
|
+
turbo-frame#lcp-master-detail-tab-content[busy] {
|
|
1670
|
+
position: relative;
|
|
1671
|
+
min-height: 4rem;
|
|
1672
|
+
opacity: 0.5;
|
|
1673
|
+
pointer-events: none;
|
|
1674
|
+
transition: opacity 0.15s ease;
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
turbo-frame#lcp-zone-tab-content[busy]::after,
|
|
1678
|
+
turbo-frame#lcp-master-detail-tab-content[busy]::after {
|
|
1679
|
+
content: "";
|
|
1680
|
+
position: absolute;
|
|
1681
|
+
top: 1.5rem;
|
|
1682
|
+
left: 50%;
|
|
1683
|
+
width: 1.5rem;
|
|
1684
|
+
height: 1.5rem;
|
|
1685
|
+
margin-left: -0.75rem;
|
|
1686
|
+
border: 3px solid var(--lcp-border-color);
|
|
1687
|
+
border-top-color: var(--lcp-primary);
|
|
1688
|
+
border-radius: 50%;
|
|
1689
|
+
animation: lcp-spin 0.6s linear infinite;
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
@keyframes lcp-spin { to { transform: rotate(360deg); } }
|
|
1693
|
+
|
|
1694
|
+
/* Initial loading placeholder (before first tab loads) */
|
|
1695
|
+
.lcp-tab-loading {
|
|
1696
|
+
padding: 2rem 1rem;
|
|
1697
|
+
text-align: center;
|
|
1698
|
+
color: var(--lcp-text-muted);
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
/* Tab load error */
|
|
1702
|
+
.lcp-tab-load-error {
|
|
1703
|
+
padding: 2rem 1rem;
|
|
1704
|
+
text-align: center;
|
|
1705
|
+
color: var(--lcp-danger-text);
|
|
1706
|
+
background: var(--lcp-danger-bg);
|
|
1707
|
+
border: 1px solid var(--lcp-danger-border);
|
|
1708
|
+
border-radius: var(--lcp-radius-sm);
|
|
1709
|
+
margin-top: 0.5rem;
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1712
|
+
/* Semantic layout responsive */
|
|
1713
|
+
@media (max-width: 768px) {
|
|
1714
|
+
.lcp-semantic-layout.lcp-has-sidebar {
|
|
1715
|
+
grid-template-columns: 1fr !important;
|
|
1716
|
+
}
|
|
1717
|
+
.lcp-area-sidebar { grid-column: 1; grid-row: auto; }
|
|
1718
|
+
.lcp-area-tabs { grid-column: 1; }
|
|
1719
|
+
.lcp-area-below { grid-column: 1; }
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
/* Zone search */
|
|
1723
|
+
.lcp-zone-search { margin-bottom: 0.75rem; }
|
|
1724
|
+
.lcp-zone-search-input { width: 100%; max-width: 300px; padding: 0.4rem 0.75rem; border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); font-size: 0.875rem; }
|
|
1725
|
+
|
|
1726
|
+
/* Batch selection */
|
|
1727
|
+
.lcp-select-column { width: 40px; text-align: center; }
|
|
1728
|
+
.lcp-select-row, .lcp-select-all { cursor: pointer; width: 16px; height: 16px; }
|
|
1729
|
+
tr.lcp-selected { background-color: var(--lcp-selection-bg); }
|
|
1730
|
+
tr.lcp-row-select-mode { cursor: default; }
|
|
1731
|
+
|
|
1732
|
+
/* Select all banner */
|
|
1733
|
+
.lcp-batch-select-all-banner { background-color: var(--lcp-info-bg); padding: 8px 16px; text-align: center; border-bottom: 1px solid var(--lcp-border-color); }
|
|
1734
|
+
.lcp-batch-select-all-banner a { font-weight: 600; margin-left: 8px; }
|
|
1735
|
+
|
|
1736
|
+
/* Batch toolbar — sticky footer */
|
|
1737
|
+
.lcp-batch-toolbar { position: fixed; bottom: 0; left: 0; right: 0; background: var(--lcp-toolbar-bg); border-top: 1px solid var(--lcp-border-color); padding: 12px 24px; display: flex; align-items: center; gap: 16px; box-shadow: var(--lcp-shadow-sm); z-index: 100; transition: transform 0.2s ease; }
|
|
1738
|
+
.lcp-batch-toolbar[hidden] { display: none; }
|
|
1739
|
+
.lcp-batch-count { font-weight: 600; white-space: nowrap; }
|
|
1740
|
+
.lcp-batch-actions { display: flex; gap: 8px; }
|
|
1741
|
+
.lcp-batch-clear { margin-left: auto; }
|
|
1742
|
+
|
|
1743
|
+
/* Theme toggle */
|
|
1744
|
+
.lcp-theme-toggle { background: none; border: 1px solid var(--lcp-border-color); border-radius: var(--lcp-radius-sm); cursor: pointer; padding: 0.35rem 0.5rem; font-size: 1rem; line-height: 1; color: var(--lcp-text-muted); }
|
|
1745
|
+
.lcp-theme-toggle:hover { background: var(--lcp-bg-hover); color: var(--lcp-text); }
|
|
1746
|
+
|
|
1747
|
+
/* ===== Form submit progress & loading state ===== */
|
|
1748
|
+
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
|
|
1749
|
+
|
|
1750
|
+
.lcp-submitting { opacity: 0.92; }
|
|
1751
|
+
.lcp-submitting-lockdown { /* marker class — ESC/backdrop guards read it */ }
|
|
1752
|
+
|
|
1753
|
+
.lcp-btn-submitting { cursor: progress; }
|
|
1754
|
+
.lcp-btn-submitting-icon { display: inline-block; margin-right: 0.3rem; }
|
|
1755
|
+
|
|
1756
|
+
.lcp-icon-spinner { display: inline-block; width: 0.9em; height: 0.9em; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; vertical-align: -0.15em; animation: lcp-spin 0.6s linear infinite; }
|
|
1757
|
+
@keyframes lcp-spin { to { transform: rotate(360deg); } }
|
|
1758
|
+
|
|
1759
|
+
.lcp-btn-progress-bar-wrapper { margin-top: 0.25rem; }
|
|
1760
|
+
.lcp-btn-progress-bar { position: relative; background: var(--lcp-bg-active); border-radius: 2px; overflow: hidden; height: 2px; width: 100%; }
|
|
1761
|
+
.lcp-btn-progress-bar-fill { background: var(--lcp-primary); height: 100%; width: 0%; transition: width 0.15s linear; }
|
|
1762
|
+
.lcp-btn-progress-bar-indeterminate .lcp-btn-progress-bar-fill { display: none; }
|
|
1763
|
+
.lcp-btn-progress-bar-indeterminate::after { content: ""; position: absolute; top: 0; left: 0; height: 100%; width: 33%; background: var(--lcp-primary); animation: lcp-indeterminate 1.1s infinite linear; }
|
|
1764
|
+
@keyframes lcp-indeterminate { 0% { left: -33%; } 100% { left: 100%; } }
|
|
1765
|
+
|
|
1766
|
+
.lcp-form-spinner { display: flex; align-items: center; gap: 0.4rem; margin-top: 0.75rem; font-size: 0.875rem; color: var(--lcp-text-muted); }
|
|
1767
|
+
.lcp-form-spinner .lcp-btn-progress-bar { margin-top: 0.25rem; flex: 0 0 8rem; }
|
|
1768
|
+
|
|
1769
|
+
/* Menu primitives (PR #2a — `method:` + `disable_when:`) */
|
|
1770
|
+
|
|
1771
|
+
/* `display: contents` makes the form element transparent in the menu
|
|
1772
|
+
flex layout, so a button_to renders visually identically to <a>. */
|
|
1773
|
+
.lcp-menu-item-form { display: contents; }
|
|
1774
|
+
|
|
1775
|
+
/* Disabled state for menu items — applies to both `<a aria-disabled>`
|
|
1776
|
+
(GET items wired with the lcp-menu Stimulus controller) and
|
|
1777
|
+
`<button disabled>` (non-GET items). */
|
|
1778
|
+
.lcp-menu-item--disabled,
|
|
1779
|
+
.lcp-nav-item a.lcp-menu-item--disabled,
|
|
1780
|
+
.lcp-nav-dropdown-item a.lcp-menu-item--disabled,
|
|
1781
|
+
.lcp-nav-dropdown-item button.lcp-menu-item--disabled,
|
|
1782
|
+
.lcp-sidebar-link.lcp-menu-item--disabled {
|
|
1783
|
+
opacity: 0.5;
|
|
1784
|
+
cursor: not-allowed;
|
|
1785
|
+
pointer-events: auto;
|
|
1786
|
+
}
|
|
1787
|
+
.lcp-menu-item--disabled:hover {
|
|
1788
|
+
background: transparent;
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
/* Shipped lcp_ruby/user_menu renderer styles */
|
|
1792
|
+
.lcp-user-menu__avatar {
|
|
1793
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
1794
|
+
width: 28px; height: 28px; border-radius: 50%;
|
|
1795
|
+
background: var(--lcp-bg-subtle); margin-right: 0.5rem;
|
|
1796
|
+
vertical-align: middle; overflow: hidden;
|
|
1797
|
+
}
|
|
1798
|
+
.lcp-user-menu__avatar--initial {
|
|
1799
|
+
font-size: 0.75rem; font-weight: 600; color: var(--lcp-text);
|
|
1800
|
+
}
|
|
1801
|
+
img.lcp-user-menu__avatar { object-fit: cover; }
|
|
1802
|
+
.lcp-user-menu__label { font-size: 0.875rem; font-weight: 500; vertical-align: middle; }
|
|
1803
|
+
.lcp-user-menu__caret { margin-left: 0.35rem; }
|
|
1804
|
+
.lcp-user-menu--disabled { opacity: 0.5; }
|
|
1805
|
+
|
|
1806
|
+
/* Shipped lcp_ruby/user_menu_panel renderer styles */
|
|
1807
|
+
.lcp-user-menu-panel__header {
|
|
1808
|
+
padding: 0.75rem 1rem; border-bottom: 1px solid var(--lcp-border-color);
|
|
1809
|
+
}
|
|
1810
|
+
.lcp-user-menu-panel__name { font-weight: 600; color: var(--lcp-text); }
|
|
1811
|
+
.lcp-user-menu-panel__email { font-size: 0.8125rem; color: var(--lcp-text-muted); margin-top: 0.125rem; }
|
|
1812
|
+
.lcp-user-menu-panel__items { list-style: none; padding: 0.25rem 0; margin: 0; }
|
|
1813
|
+
|
|
1814
|
+
/* Panel items rendered through render_menu_item(:panel) — match the
|
|
1815
|
+
visual layer of native dropdown items. */
|
|
1816
|
+
.lcp-panel-item { list-style: none; }
|
|
1817
|
+
.lcp-panel-item .lcp-panel-link {
|
|
1818
|
+
display: flex; align-items: center; padding: 0.5rem 1rem;
|
|
1819
|
+
color: var(--lcp-text); text-decoration: none; font-size: 0.875rem;
|
|
1820
|
+
}
|
|
1821
|
+
.lcp-panel-item .lcp-panel-link:hover { background: var(--lcp-bg-hover); }
|
|
1822
|
+
/* Non-GET items render as <button_to>; reset native button chrome so
|
|
1823
|
+
they visually match <a> siblings (Sign out vs My Settings, etc.). */
|
|
1824
|
+
.lcp-panel-item button.lcp-panel-link {
|
|
1825
|
+
background: none; border: 0; width: 100%; text-align: left;
|
|
1826
|
+
cursor: pointer; font: inherit;
|
|
1827
|
+
}
|
|
1828
|
+
.lcp-panel-separator { height: 1px; background: var(--lcp-border-color); margin: 0.25rem 0; list-style: none; }
|
|
1829
|
+
|
|
1830
|
+
/* Bare-widget container — drops the wrapper, framework still emits <li>.
|
|
1831
|
+
Flex-center vertically so the widget's content sits on the same baseline
|
|
1832
|
+
as surrounding nav links/buttons (which have padding, the <li> doesn't). */
|
|
1833
|
+
.lcp-menu-widget {
|
|
1834
|
+
list-style: none; padding: 0 1rem; margin: 0;
|
|
1835
|
+
display: flex; align-items: center;
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
/* Page filter form (PR 5).
|
|
1839
|
+
Sits above the main index zone; same visual idiom as the legacy
|
|
1840
|
+
parameter bar (horizontal field row with Apply button on the right). */
|
|
1841
|
+
.lcp-filter-form-wrapper {
|
|
1842
|
+
margin-bottom: 1rem;
|
|
1843
|
+
}
|
|
1844
|
+
.lcp-filter-form {
|
|
1845
|
+
display: flex;
|
|
1846
|
+
flex-wrap: wrap;
|
|
1847
|
+
align-items: flex-end;
|
|
1848
|
+
gap: 0.75rem;
|
|
1849
|
+
padding: 0.75rem 1rem;
|
|
1850
|
+
background: var(--lcp-bg-surface);
|
|
1851
|
+
border: 1px solid var(--lcp-border-color);
|
|
1852
|
+
border-radius: var(--lcp-radius-md);
|
|
1853
|
+
}
|
|
1854
|
+
.lcp-filter-form-field {
|
|
1855
|
+
display: flex;
|
|
1856
|
+
flex-direction: column;
|
|
1857
|
+
gap: 0.25rem;
|
|
1858
|
+
min-width: 12rem;
|
|
1859
|
+
}
|
|
1860
|
+
.lcp-filter-form-label {
|
|
1861
|
+
font-size: 0.75rem;
|
|
1862
|
+
color: var(--lcp-text-muted);
|
|
1863
|
+
font-weight: 600;
|
|
1864
|
+
text-transform: uppercase;
|
|
1865
|
+
letter-spacing: 0.03em;
|
|
1866
|
+
}
|
|
1867
|
+
.lcp-filter-form-actions {
|
|
1868
|
+
display: flex;
|
|
1869
|
+
align-items: center;
|
|
1870
|
+
gap: 0.5rem;
|
|
1871
|
+
margin-left: auto;
|
|
1872
|
+
}
|
|
1873
|
+
.lcp-filter-form-actions .lcp-filter-apply { font-size: 0.85rem; }
|
|
1874
|
+
.lcp-filter-form-actions .lcp-filter-apply.is-dirty {
|
|
1875
|
+
box-shadow: 0 0 0 2px var(--lcp-primary);
|
|
1876
|
+
}
|
|
1877
|
+
.lcp-filter-unapplied-count {
|
|
1878
|
+
display: inline-block;
|
|
1879
|
+
margin-left: 0.35rem;
|
|
1880
|
+
padding: 0 0.4rem;
|
|
1881
|
+
font-size: 0.7rem;
|
|
1882
|
+
background: var(--lcp-bg-hover);
|
|
1883
|
+
color: var(--lcp-text-muted);
|
|
1884
|
+
border-radius: 999px;
|
|
1885
|
+
}
|
|
1886
|
+
.lcp-filter-apply.is-dirty .lcp-filter-unapplied-count {
|
|
1887
|
+
background: var(--lcp-primary);
|
|
1888
|
+
color: var(--lcp-text-on-primary);
|
|
1889
|
+
}
|
|
1890
|
+
.lcp-filter-reset {
|
|
1891
|
+
font-size: 0.8rem;
|
|
1892
|
+
color: var(--lcp-text-muted);
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
/* date_range form input (PR 3 step 5). */
|
|
1896
|
+
.lcp-date-range {
|
|
1897
|
+
display: inline-flex;
|
|
1898
|
+
align-items: center;
|
|
1899
|
+
gap: 0.35rem;
|
|
1900
|
+
border: 0;
|
|
1901
|
+
padding: 0;
|
|
1902
|
+
margin: 0;
|
|
1903
|
+
}
|
|
1904
|
+
.lcp-date-range-separator { color: var(--lcp-text-muted); }
|
|
1905
|
+
|
|
1906
|
+
/* Scope filter widget (PR 5). */
|
|
1907
|
+
.lcp-scope-filters-wrapper {
|
|
1908
|
+
margin-bottom: 0.75rem;
|
|
1909
|
+
display: flex;
|
|
1910
|
+
gap: 1rem;
|
|
1911
|
+
flex-wrap: wrap;
|
|
1912
|
+
}
|
|
1913
|
+
.lcp-scope-filter {
|
|
1914
|
+
display: flex;
|
|
1915
|
+
align-items: center;
|
|
1916
|
+
gap: 0.5rem;
|
|
1917
|
+
}
|
|
1918
|
+
.lcp-scope-filter-label {
|
|
1919
|
+
font-size: 0.75rem;
|
|
1920
|
+
color: var(--lcp-text-muted);
|
|
1921
|
+
font-weight: 600;
|
|
1922
|
+
text-transform: uppercase;
|
|
1923
|
+
letter-spacing: 0.03em;
|
|
1924
|
+
}
|
|
1925
|
+
.lcp-scope-filter-button-group {
|
|
1926
|
+
display: inline-flex;
|
|
1927
|
+
border: 1px solid var(--lcp-border-color);
|
|
1928
|
+
border-radius: var(--lcp-radius-sm);
|
|
1929
|
+
overflow: hidden;
|
|
1930
|
+
}
|
|
1931
|
+
.lcp-scope-filter-button-group .lcp-scope-filter-button {
|
|
1932
|
+
border-radius: 0;
|
|
1933
|
+
border: 0;
|
|
1934
|
+
border-right: 1px solid var(--lcp-border-color);
|
|
1935
|
+
}
|
|
1936
|
+
.lcp-scope-filter-button-group .lcp-scope-filter-button:last-child { border-right: 0; }
|
|
1937
|
+
.lcp-scope-filter-button-group .lcp-scope-filter-button.lcp-scope-filter-active {
|
|
1938
|
+
background: var(--lcp-primary);
|
|
1939
|
+
color: var(--lcp-text-on-primary);
|
|
1940
|
+
}
|