@cardstack/boxel-cli 0.2.0 → 0.3.0-unstable.58
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.
- package/bundled-types/base/-private.d.ts +1 -0
- package/bundled-types/base/address.d.ts +17 -0
- package/bundled-types/base/ai-app-generator.d.ts +14 -0
- package/bundled-types/base/amount-with-currency.d.ts +10 -0
- package/bundled-types/base/avif-image-def.d.ts +12 -0
- package/bundled-types/base/avif-meta-extractor.d.ts +4 -0
- package/bundled-types/base/base64-image.d.ts +25 -0
- package/bundled-types/base/big-integer.d.ts +12 -0
- package/bundled-types/base/boolean.d.ts +14 -0
- package/bundled-types/base/brand-functional-palette.d.ts +16 -0
- package/bundled-types/base/brand-guide.d.ts +26 -0
- package/bundled-types/base/brand-logo.d.ts +29 -0
- package/bundled-types/base/card-api.d.ts +513 -0
- package/bundled-types/base/card-serialization.d.ts +47 -0
- package/bundled-types/base/cards-grid.d.ts +10 -0
- package/bundled-types/base/code-ref.d.ts +14 -0
- package/bundled-types/base/codemirror-editor.d.ts +135 -0
- package/bundled-types/base/color-field/components/advanced-color-picker.d.ts +66 -0
- package/bundled-types/base/color-field/components/color-picker-field.d.ts +22 -0
- package/bundled-types/base/color-field/components/color-wheel-picker.d.ts +44 -0
- package/bundled-types/base/color-field/components/contrast-checker-addon.d.ts +14 -0
- package/bundled-types/base/color-field/components/recent-colors-addon.d.ts +19 -0
- package/bundled-types/base/color-field/components/slider-picker.d.ts +40 -0
- package/bundled-types/base/color-field/components/swatches-picker.d.ts +5 -0
- package/bundled-types/base/color-field/modifiers/setup-element-modifier.d.ts +10 -0
- package/bundled-types/base/color-field/util/color-field-signature.d.ts +9 -0
- package/bundled-types/base/color-field/util/color-utils.d.ts +96 -0
- package/bundled-types/base/color-field/util/css-color-parsers.d.ts +11 -0
- package/bundled-types/base/color.d.ts +10 -0
- package/bundled-types/base/command.d.ts +593 -0
- package/bundled-types/base/commands/search-card-result.d.ts +36 -0
- package/bundled-types/base/components/age.d.ts +22 -0
- package/bundled-types/base/components/business-days.d.ts +16 -0
- package/bundled-types/base/components/card-list.d.ts +25 -0
- package/bundled-types/base/components/cards-grid-layout.d.ts +58 -0
- package/bundled-types/base/components/countdown.d.ts +31 -0
- package/bundled-types/base/components/expiration-warning.d.ts +24 -0
- package/bundled-types/base/components/time-ago.d.ts +24 -0
- package/bundled-types/base/components/time-slots.d.ts +20 -0
- package/bundled-types/base/components/timeline.d.ts +22 -0
- package/bundled-types/base/contains-many-component.d.ts +7 -0
- package/bundled-types/base/coordinate.d.ts +7 -0
- package/bundled-types/base/country.d.ts +23 -0
- package/bundled-types/base/css-value.d.ts +6 -0
- package/bundled-types/base/csv-file-def.d.ts +29 -0
- package/bundled-types/base/currency.d.ts +16 -0
- package/bundled-types/base/date/day.d.ts +9 -0
- package/bundled-types/base/date/month-day.d.ts +10 -0
- package/bundled-types/base/date/month-year.d.ts +9 -0
- package/bundled-types/base/date/month.d.ts +9 -0
- package/bundled-types/base/date/quarter.d.ts +10 -0
- package/bundled-types/base/date/week.d.ts +9 -0
- package/bundled-types/base/date/year.d.ts +9 -0
- package/bundled-types/base/date-range-field.d.ts +12 -0
- package/bundled-types/base/date.d.ts +12 -0
- package/bundled-types/base/datetime-stamp.d.ts +7 -0
- package/bundled-types/base/datetime.d.ts +12 -0
- package/bundled-types/base/default-templates/atom.d.ts +10 -0
- package/bundled-types/base/default-templates/card-info.d.ts +32 -0
- package/bundled-types/base/default-templates/embedded.d.ts +11 -0
- package/bundled-types/base/default-templates/field-edit.d.ts +10 -0
- package/bundled-types/base/default-templates/file-def-edit.d.ts +8 -0
- package/bundled-types/base/default-templates/fitted.d.ts +12 -0
- package/bundled-types/base/default-templates/head.d.ts +13 -0
- package/bundled-types/base/default-templates/image-def-atom.d.ts +8 -0
- package/bundled-types/base/default-templates/image-def-embedded.d.ts +8 -0
- package/bundled-types/base/default-templates/image-def-fitted.d.ts +8 -0
- package/bundled-types/base/default-templates/image-def-isolated.d.ts +8 -0
- package/bundled-types/base/default-templates/isolated-and-edit.d.ts +15 -0
- package/bundled-types/base/default-templates/markdown-fallback.d.ts +19 -0
- package/bundled-types/base/default-templates/markdown.d.ts +60 -0
- package/bundled-types/base/default-templates/missing-template.d.ts +13 -0
- package/bundled-types/base/default-templates/theme-dashboard.d.ts +126 -0
- package/bundled-types/base/detailed-style-reference.d.ts +48 -0
- package/bundled-types/base/email.d.ts +10 -0
- package/bundled-types/base/enum.d.ts +30 -0
- package/bundled-types/base/ethereum-address.d.ts +13 -0
- package/bundled-types/base/field-component.d.ts +65 -0
- package/bundled-types/base/field-support.d.ts +55 -0
- package/bundled-types/base/file-api.d.ts +2 -0
- package/bundled-types/base/file-menu-items.d.ts +4 -0
- package/bundled-types/base/gif-image-def.d.ts +12 -0
- package/bundled-types/base/gif-meta-extractor.d.ts +4 -0
- package/bundled-types/base/gts-file-def.d.ts +7 -0
- package/bundled-types/base/helpers/country.d.ts +3198 -0
- package/bundled-types/base/helpers/sanitized-html.d.ts +2 -0
- package/bundled-types/base/helpers/set-background-image.d.ts +2 -0
- package/bundled-types/base/image-file-def.d.ts +1 -0
- package/bundled-types/base/image.d.ts +8 -0
- package/bundled-types/base/index.d.ts +1 -0
- package/bundled-types/base/join-the-community.d.ts +14 -0
- package/bundled-types/base/jpg-image-def.d.ts +12 -0
- package/bundled-types/base/jpg-meta-extractor.d.ts +4 -0
- package/bundled-types/base/json-file-def.d.ts +23 -0
- package/bundled-types/base/links-to-editor.d.ts +22 -0
- package/bundled-types/base/links-to-many-component.d.ts +7 -0
- package/bundled-types/base/llm-model.d.ts +6 -0
- package/bundled-types/base/markdown-file-def.d.ts +25 -0
- package/bundled-types/base/markdown-helpers.d.ts +26 -0
- package/bundled-types/base/markdown.d.ts +1 -0
- package/bundled-types/base/matrix-event.d.ts +400 -0
- package/bundled-types/base/menu-items.d.ts +21 -0
- package/bundled-types/base/number/components/badge-counter.d.ts +32 -0
- package/bundled-types/base/number/components/badge-metric.d.ts +34 -0
- package/bundled-types/base/number/components/badge-notification.d.ts +38 -0
- package/bundled-types/base/number/components/gauge.d.ts +45 -0
- package/bundled-types/base/number/components/number-input.d.ts +27 -0
- package/bundled-types/base/number/components/progress-bar.d.ts +44 -0
- package/bundled-types/base/number/components/progress-circle.d.ts +41 -0
- package/bundled-types/base/number/components/score.d.ts +41 -0
- package/bundled-types/base/number/components/stat.d.ts +38 -0
- package/bundled-types/base/number/util/index.d.ts +29 -0
- package/bundled-types/base/number.d.ts +52 -0
- package/bundled-types/base/percentage.d.ts +9 -0
- package/bundled-types/base/phone-number.d.ts +25 -0
- package/bundled-types/base/png-image-def.d.ts +12 -0
- package/bundled-types/base/png-meta-extractor.d.ts +4 -0
- package/bundled-types/base/positioned-card.d.ts +7 -0
- package/bundled-types/base/query-field-support.d.ts +6 -0
- package/bundled-types/base/realm-config.d.ts +16 -0
- package/bundled-types/base/realm.d.ts +7 -0
- package/bundled-types/base/resources/command-data.d.ts +43 -0
- package/bundled-types/base/response-field.d.ts +6 -0
- package/bundled-types/base/rich-markdown.d.ts +30 -0
- package/bundled-types/base/shared-state.d.ts +1 -0
- package/bundled-types/base/skill-plus.d.ts +79 -0
- package/bundled-types/base/skill-reference.d.ts +12 -0
- package/bundled-types/base/skill-set.d.ts +18 -0
- package/bundled-types/base/skill.d.ts +21 -0
- package/bundled-types/base/spec.d.ts +108 -0
- package/bundled-types/base/string.d.ts +2 -0
- package/bundled-types/base/structured-theme-variables.d.ts +85 -0
- package/bundled-types/base/structured-theme.d.ts +32 -0
- package/bundled-types/base/style-reference.d.ts +14 -0
- package/bundled-types/base/svg-image-def.d.ts +12 -0
- package/bundled-types/base/svg-meta-extractor.d.ts +12 -0
- package/bundled-types/base/system-card.d.ts +17 -0
- package/bundled-types/base/tag.d.ts +15 -0
- package/bundled-types/base/text-area.d.ts +2 -0
- package/bundled-types/base/text-file-def.d.ts +23 -0
- package/bundled-types/base/text-input-validator.d.ts +13 -0
- package/bundled-types/base/theme.d.ts +2 -0
- package/bundled-types/base/time/duration.d.ts +14 -0
- package/bundled-types/base/time/relative-time.d.ts +10 -0
- package/bundled-types/base/time/time-range.d.ts +11 -0
- package/bundled-types/base/time.d.ts +9 -0
- package/bundled-types/base/ts-file-def.d.ts +26 -0
- package/bundled-types/base/ts-highlight.d.ts +1 -0
- package/bundled-types/base/types/@cardstack/boxel-host/index.d.ts +5 -0
- package/bundled-types/base/types/ember-css-url/index.d.ts +15 -0
- package/bundled-types/base/typography.d.ts +14 -0
- package/bundled-types/base/url.d.ts +13 -0
- package/bundled-types/base/watched-array.d.ts +7 -0
- package/bundled-types/base/webp-image-def.d.ts +12 -0
- package/bundled-types/base/webp-meta-extractor.d.ts +4 -0
- package/bundled-types/base/website.d.ts +8 -0
- package/bundled-types/base/welcome-to-boxel.d.ts +22 -0
- package/bundled-types/boxel-ui/components/accordion/index.gts +50 -0
- package/bundled-types/boxel-ui/components/accordion/item/index.gts +156 -0
- package/bundled-types/boxel-ui/components/accordion/usage.gts +157 -0
- package/bundled-types/boxel-ui/components/add-button/index.gts +46 -0
- package/bundled-types/boxel-ui/components/add-button/usage.gts +54 -0
- package/bundled-types/boxel-ui/components/alert/index.gts +151 -0
- package/bundled-types/boxel-ui/components/alert/usage.gts +66 -0
- package/bundled-types/boxel-ui/components/avatar/index.gts +79 -0
- package/bundled-types/boxel-ui/components/avatar/usage.gts +96 -0
- package/bundled-types/boxel-ui/components/basic-fitted/index.gts +340 -0
- package/bundled-types/boxel-ui/components/basic-fitted/usage.gts +223 -0
- package/bundled-types/boxel-ui/components/button/index.gts +416 -0
- package/bundled-types/boxel-ui/components/button/usage.gts +334 -0
- package/bundled-types/boxel-ui/components/card-container/index.gts +251 -0
- package/bundled-types/boxel-ui/components/card-container/usage.gts +53 -0
- package/bundled-types/boxel-ui/components/card-header/index.gts +473 -0
- package/bundled-types/boxel-ui/components/card-header/usage.gts +295 -0
- package/bundled-types/boxel-ui/components/circle-spinner/index.gts +42 -0
- package/bundled-types/boxel-ui/components/circle-spinner/usage.gts +48 -0
- package/bundled-types/boxel-ui/components/color-palette/index.gts +134 -0
- package/bundled-types/boxel-ui/components/color-palette/usage.gts +69 -0
- package/bundled-types/boxel-ui/components/color-picker/index.gts +125 -0
- package/bundled-types/boxel-ui/components/color-picker/usage.gts +56 -0
- package/bundled-types/boxel-ui/components/container/index.gts +67 -0
- package/bundled-types/boxel-ui/components/container/usage.gts +59 -0
- package/bundled-types/boxel-ui/components/context-button/index.gts +184 -0
- package/bundled-types/boxel-ui/components/context-button/usage.gts +125 -0
- package/bundled-types/boxel-ui/components/copy-button/index.gts +79 -0
- package/bundled-types/boxel-ui/components/copy-button/usage.gts +25 -0
- package/bundled-types/boxel-ui/components/date-range-picker/index.gts +211 -0
- package/bundled-types/boxel-ui/components/date-range-picker/setup.gts +11 -0
- package/bundled-types/boxel-ui/components/date-range-picker/usage.gts +52 -0
- package/bundled-types/boxel-ui/components/drag-and-drop/index.gts +256 -0
- package/bundled-types/boxel-ui/components/drag-and-drop/usage.gts +142 -0
- package/bundled-types/boxel-ui/components/dropdown/index.gts +478 -0
- package/bundled-types/boxel-ui/components/dropdown/trigger/index.gts +70 -0
- package/bundled-types/boxel-ui/components/dropdown/trigger/usage.gts +54 -0
- package/bundled-types/boxel-ui/components/dropdown/usage.gts +119 -0
- package/bundled-types/boxel-ui/components/email-input/index.gts +111 -0
- package/bundled-types/boxel-ui/components/email-input/usage.gts +75 -0
- package/bundled-types/boxel-ui/components/entity-icon-display/index.gts +144 -0
- package/bundled-types/boxel-ui/components/entity-icon-display/usage.gts +54 -0
- package/bundled-types/boxel-ui/components/entity-thumbnail-display/index.gts +148 -0
- package/bundled-types/boxel-ui/components/entity-thumbnail-display/usage.gts +76 -0
- package/bundled-types/boxel-ui/components/field-container/index.gts +150 -0
- package/bundled-types/boxel-ui/components/field-container/usage.gts +188 -0
- package/bundled-types/boxel-ui/components/filter-list/index.gts +255 -0
- package/bundled-types/boxel-ui/components/filter-list/usage.gts +153 -0
- package/bundled-types/boxel-ui/components/fitted-card-container/index.gts +66 -0
- package/bundled-types/boxel-ui/components/fitted-card-container/usage.gts +81 -0
- package/bundled-types/boxel-ui/components/grid-container/grid-item-container/index.gts +37 -0
- package/bundled-types/boxel-ui/components/grid-container/index.gts +116 -0
- package/bundled-types/boxel-ui/components/grid-container/usage.gts +105 -0
- package/bundled-types/boxel-ui/components/header/index.gts +101 -0
- package/bundled-types/boxel-ui/components/header/usage.gts +116 -0
- package/bundled-types/boxel-ui/components/icon-button/index.gts +148 -0
- package/bundled-types/boxel-ui/components/icon-button/usage.gts +249 -0
- package/bundled-types/boxel-ui/components/input/index.gts +560 -0
- package/bundled-types/boxel-ui/components/input/usage.gts +449 -0
- package/bundled-types/boxel-ui/components/input-group/accessories/index.gts +191 -0
- package/bundled-types/boxel-ui/components/input-group/controls/index.gts +54 -0
- package/bundled-types/boxel-ui/components/input-group/index.gts +347 -0
- package/bundled-types/boxel-ui/components/input-group/usage.gts +437 -0
- package/bundled-types/boxel-ui/components/kanban/card.gts +89 -0
- package/bundled-types/boxel-ui/components/kanban/column-header.gts +151 -0
- package/bundled-types/boxel-ui/components/kanban/drag.gts +1007 -0
- package/bundled-types/boxel-ui/components/kanban/engine.ts +247 -0
- package/bundled-types/boxel-ui/components/kanban/ghost.gts +64 -0
- package/bundled-types/boxel-ui/components/kanban/index.gts +16 -0
- package/bundled-types/boxel-ui/components/kanban/modifiers.gts +42 -0
- package/bundled-types/boxel-ui/components/kanban/plane-inner.gts +525 -0
- package/bundled-types/boxel-ui/components/kanban/plane.gts +163 -0
- package/bundled-types/boxel-ui/components/kanban/usage.gts +392 -0
- package/bundled-types/boxel-ui/components/label/index.gts +64 -0
- package/bundled-types/boxel-ui/components/loading-indicator/index.gts +78 -0
- package/bundled-types/boxel-ui/components/loading-indicator/usage.gts +72 -0
- package/bundled-types/boxel-ui/components/menu/index.gts +267 -0
- package/bundled-types/boxel-ui/components/menu/usage.gts +100 -0
- package/bundled-types/boxel-ui/components/message/index.gts +146 -0
- package/bundled-types/boxel-ui/components/message/usage.gts +263 -0
- package/bundled-types/boxel-ui/components/modal/index.gts +159 -0
- package/bundled-types/boxel-ui/components/modal/usage.gts +206 -0
- package/bundled-types/boxel-ui/components/multi-select/after-options.gts +59 -0
- package/bundled-types/boxel-ui/components/multi-select/index.gts +230 -0
- package/bundled-types/boxel-ui/components/multi-select/selected-item.gts +91 -0
- package/bundled-types/boxel-ui/components/multi-select/trigger.gts +190 -0
- package/bundled-types/boxel-ui/components/multi-select/usage.gts +420 -0
- package/bundled-types/boxel-ui/components/phone-input/index.gts +149 -0
- package/bundled-types/boxel-ui/components/phone-input/usage.gts +73 -0
- package/bundled-types/boxel-ui/components/picker/before-options-with-search.gts +340 -0
- package/bundled-types/boxel-ui/components/picker/index.gts +427 -0
- package/bundled-types/boxel-ui/components/picker/option-row.gts +270 -0
- package/bundled-types/boxel-ui/components/picker/selected-item.gts +171 -0
- package/bundled-types/boxel-ui/components/picker/trigger-labeled.gts +216 -0
- package/bundled-types/boxel-ui/components/picker/usage.gts +179 -0
- package/bundled-types/boxel-ui/components/pill/index.gts +231 -0
- package/bundled-types/boxel-ui/components/pill/usage.gts +230 -0
- package/bundled-types/boxel-ui/components/progress-bar/index.gts +124 -0
- package/bundled-types/boxel-ui/components/progress-bar/usage.gts +131 -0
- package/bundled-types/boxel-ui/components/progress-radial/index.gts +95 -0
- package/bundled-types/boxel-ui/components/progress-radial/usage.gts +79 -0
- package/bundled-types/boxel-ui/components/radio-input/index.gts +143 -0
- package/bundled-types/boxel-ui/components/radio-input/item.gts +210 -0
- package/bundled-types/boxel-ui/components/radio-input/usage.gts +303 -0
- package/bundled-types/boxel-ui/components/realm-icon/index.gts +129 -0
- package/bundled-types/boxel-ui/components/realm-icon/usage.gts +62 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/handle.gts +180 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/index.gts +341 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/panel.gts +86 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/usage.gts +350 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/adjust-layout-by-delta.ts +231 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/assert.ts +10 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/calculate-delta-percentage.ts +41 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/calculate-unsafe-default-layout.ts +53 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/compare-layouts.ts +12 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/const.ts +6 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/determine-pivot-indices.ts +15 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/dom/get-panel-element.ts +10 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/dom/get-panel-elements-for-group.ts +8 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/dom/get-panel-group-element.ts +21 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/dom/get-resize-handle-element-index.ts +14 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/dom/get-resize-handle-element.ts +12 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/dom/get-resize-handle-elements-for-group.ts +10 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/fuzzy-layouts-equal.ts +22 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/fuzzy-numbers.ts +21 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/get-resize-event-coordinates.ts +8 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/get-resize-event-cursor-position.ts +10 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/panel-resize-handle-registry.ts +446 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/resize-panel.ts +35 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/types.ts +23 -0
- package/bundled-types/boxel-ui/components/resizable-panel-group/utils/validate-panel-group-layout.ts +86 -0
- package/bundled-types/boxel-ui/components/select/index.gts +882 -0
- package/bundled-types/boxel-ui/components/select/trigger.gts +132 -0
- package/bundled-types/boxel-ui/components/select/usage.gts +353 -0
- package/bundled-types/boxel-ui/components/skeleton-placeholder/index.gts +89 -0
- package/bundled-types/boxel-ui/components/skeleton-placeholder/usage.gts +102 -0
- package/bundled-types/boxel-ui/components/sort-dropdown/index.gts +91 -0
- package/bundled-types/boxel-ui/components/sort-dropdown/usage.gts +77 -0
- package/bundled-types/boxel-ui/components/swatch/index.gts +81 -0
- package/bundled-types/boxel-ui/components/swatch/usage.gts +57 -0
- package/bundled-types/boxel-ui/components/switch/index.gts +95 -0
- package/bundled-types/boxel-ui/components/switch/usage.gts +79 -0
- package/bundled-types/boxel-ui/components/tabbed-header/index.gts +141 -0
- package/bundled-types/boxel-ui/components/tabbed-header/usage.gts +103 -0
- package/bundled-types/boxel-ui/components/tag/index.gts +50 -0
- package/bundled-types/boxel-ui/components/tag/usage.gts +89 -0
- package/bundled-types/boxel-ui/components/tag-list/index.gts +85 -0
- package/bundled-types/boxel-ui/components/tag-list/usage.gts +129 -0
- package/bundled-types/boxel-ui/components/tooltip/index.gts +306 -0
- package/bundled-types/boxel-ui/components/tooltip/usage.gts +168 -0
- package/bundled-types/boxel-ui/components/view-selector/index.gts +166 -0
- package/bundled-types/boxel-ui/components/view-selector/usage.gts +149 -0
- package/bundled-types/boxel-ui/components.ts +169 -0
- package/bundled-types/boxel-ui/helpers/add-class-to-svg.ts +8 -0
- package/bundled-types/boxel-ui/helpers/clipboard.ts +21 -0
- package/bundled-types/boxel-ui/helpers/cn.ts +12 -0
- package/bundled-types/boxel-ui/helpers/color-tools.ts +331 -0
- package/bundled-types/boxel-ui/helpers/compact.ts +3 -0
- package/bundled-types/boxel-ui/helpers/contrast-color.ts +32 -0
- package/bundled-types/boxel-ui/helpers/css-var.ts +41 -0
- package/bundled-types/boxel-ui/helpers/currency-format.ts +25 -0
- package/bundled-types/boxel-ui/helpers/dayjs-format.ts +27 -0
- package/bundled-types/boxel-ui/helpers/deterministic-color-from-string.ts +45 -0
- package/bundled-types/boxel-ui/helpers/element.ts +16 -0
- package/bundled-types/boxel-ui/helpers/extract-css-variables.ts +126 -0
- package/bundled-types/boxel-ui/helpers/format-age.ts +72 -0
- package/bundled-types/boxel-ui/helpers/format-countdown.ts +110 -0
- package/bundled-types/boxel-ui/helpers/format-currency.ts +95 -0
- package/bundled-types/boxel-ui/helpers/format-date-time.ts +567 -0
- package/bundled-types/boxel-ui/helpers/format-duration.ts +143 -0
- package/bundled-types/boxel-ui/helpers/format-file-size.ts +49 -0
- package/bundled-types/boxel-ui/helpers/format-list.ts +73 -0
- package/bundled-types/boxel-ui/helpers/format-names.ts +103 -0
- package/bundled-types/boxel-ui/helpers/format-number.ts +140 -0
- package/bundled-types/boxel-ui/helpers/format-ordinal.ts +115 -0
- package/bundled-types/boxel-ui/helpers/format-period.ts +188 -0
- package/bundled-types/boxel-ui/helpers/format-relative-time.ts +789 -0
- package/bundled-types/boxel-ui/helpers/generate-css-variables.ts +47 -0
- package/bundled-types/boxel-ui/helpers/markdown-escape.ts +36 -0
- package/bundled-types/boxel-ui/helpers/math-helpers.ts +18 -0
- package/bundled-types/boxel-ui/helpers/menu-divider.ts +15 -0
- package/bundled-types/boxel-ui/helpers/menu-item.ts +76 -0
- package/bundled-types/boxel-ui/helpers/optional.ts +7 -0
- package/bundled-types/boxel-ui/helpers/pick.ts +11 -0
- package/bundled-types/boxel-ui/helpers/sanitize-html.ts +45 -0
- package/bundled-types/boxel-ui/helpers/string.ts +15 -0
- package/bundled-types/boxel-ui/helpers/theme-css.ts +148 -0
- package/bundled-types/boxel-ui/helpers/truth-helpers.ts +48 -0
- package/bundled-types/boxel-ui/helpers/validate-email-format.ts +138 -0
- package/bundled-types/boxel-ui/helpers/validate-phone-format.ts +201 -0
- package/bundled-types/boxel-ui/helpers.ts +134 -0
- package/bundled-types/boxel-ui/icons/ai-bw.gts +22 -0
- package/bundled-types/boxel-ui/icons/arrow-left.gts +25 -0
- package/bundled-types/boxel-ui/icons/arrow-right.gts +28 -0
- package/bundled-types/boxel-ui/icons/arrow-top-left.gts +22 -0
- package/bundled-types/boxel-ui/icons/arrow-up.gts +25 -0
- package/bundled-types/boxel-ui/icons/atom.gts +26 -0
- package/bundled-types/boxel-ui/icons/boxel-icon-with-text.gts +29 -0
- package/bundled-types/boxel-ui/icons/boxel-icon.gts +34 -0
- package/bundled-types/boxel-ui/icons/card-definition.gts +26 -0
- package/bundled-types/boxel-ui/icons/card-instance.gts +26 -0
- package/bundled-types/boxel-ui/icons/card.gts +24 -0
- package/bundled-types/boxel-ui/icons/cardbot-lg.gts +24 -0
- package/bundled-types/boxel-ui/icons/caret-down.gts +23 -0
- package/bundled-types/boxel-ui/icons/caret-up.gts +23 -0
- package/bundled-types/boxel-ui/icons/check-mark.gts +23 -0
- package/bundled-types/boxel-ui/icons/chevron-right.gts +23 -0
- package/bundled-types/boxel-ui/icons/copy.gts +28 -0
- package/bundled-types/boxel-ui/icons/diagonal-arrow-left-up.gts +21 -0
- package/bundled-types/boxel-ui/icons/download.gts +19 -0
- package/bundled-types/boxel-ui/icons/dropdown-arrow-down.gts +20 -0
- package/bundled-types/boxel-ui/icons/dropdown-arrow-filled.gts +19 -0
- package/bundled-types/boxel-ui/icons/dropdown-arrow-up.gts +20 -0
- package/bundled-types/boxel-ui/icons/edit.gts +14 -0
- package/bundled-types/boxel-ui/icons/embedded.gts +34 -0
- package/bundled-types/boxel-ui/icons/exclamation-circle.gts +26 -0
- package/bundled-types/boxel-ui/icons/exclamation.gts +20 -0
- package/bundled-types/boxel-ui/icons/eye.gts +19 -0
- package/bundled-types/boxel-ui/icons/failure-bordered.gts +26 -0
- package/bundled-types/boxel-ui/icons/field.gts +26 -0
- package/bundled-types/boxel-ui/icons/file-alert.gts +28 -0
- package/bundled-types/boxel-ui/icons/file.gts +27 -0
- package/bundled-types/boxel-ui/icons/fitted.gts +42 -0
- package/bundled-types/boxel-ui/icons/folder.gts +26 -0
- package/bundled-types/boxel-ui/icons/form.gts +38 -0
- package/bundled-types/boxel-ui/icons/four-lines.gts +21 -0
- package/bundled-types/boxel-ui/icons/grid-3x3.gts +26 -0
- package/bundled-types/boxel-ui/icons/group.gts +22 -0
- package/bundled-types/boxel-ui/icons/head.gts +28 -0
- package/bundled-types/boxel-ui/icons/highlight-icon.gts +46 -0
- package/bundled-types/boxel-ui/icons/icon-circle-selected.gts +25 -0
- package/bundled-types/boxel-ui/icons/icon-circle.gts +25 -0
- package/bundled-types/boxel-ui/icons/icon-code.gts +22 -0
- package/bundled-types/boxel-ui/icons/icon-funnel.gts +23 -0
- package/bundled-types/boxel-ui/icons/icon-globe.gts +19 -0
- package/bundled-types/boxel-ui/icons/icon-grid.gts +68 -0
- package/bundled-types/boxel-ui/icons/icon-hexagon.gts +22 -0
- package/bundled-types/boxel-ui/icons/icon-inherit.gts +19 -0
- package/bundled-types/boxel-ui/icons/icon-link.gts +20 -0
- package/bundled-types/boxel-ui/icons/icon-list.gts +40 -0
- package/bundled-types/boxel-ui/icons/icon-minus-circle.gts +26 -0
- package/bundled-types/boxel-ui/icons/icon-pencil-crossed-out.gts +33 -0
- package/bundled-types/boxel-ui/icons/icon-pencil-not-crossed-out.gts +21 -0
- package/bundled-types/boxel-ui/icons/icon-pencil.gts +23 -0
- package/bundled-types/boxel-ui/icons/icon-plus-circle.gts +31 -0
- package/bundled-types/boxel-ui/icons/icon-plus-thin.gts +19 -0
- package/bundled-types/boxel-ui/icons/icon-plus.gts +20 -0
- package/bundled-types/boxel-ui/icons/icon-search-thick.gts +27 -0
- package/bundled-types/boxel-ui/icons/icon-search.gts +25 -0
- package/bundled-types/boxel-ui/icons/icon-table.gts +44 -0
- package/bundled-types/boxel-ui/icons/icon-trash.gts +24 -0
- package/bundled-types/boxel-ui/icons/icon-turn-down-right.gts +18 -0
- package/bundled-types/boxel-ui/icons/icon-x.gts +21 -0
- package/bundled-types/boxel-ui/icons/image-placeholder.gts +30 -0
- package/bundled-types/boxel-ui/icons/isolated.gts +20 -0
- package/bundled-types/boxel-ui/icons/loading-indicator.gts +26 -0
- package/bundled-types/boxel-ui/icons/lock.gts +23 -0
- package/bundled-types/boxel-ui/icons/markdown.gts +19 -0
- package/bundled-types/boxel-ui/icons/profile.gts +23 -0
- package/bundled-types/boxel-ui/icons/publish-site-icon.gts +25 -0
- package/bundled-types/boxel-ui/icons/rows-4.gts +26 -0
- package/bundled-types/boxel-ui/icons/select-all.gts +25 -0
- package/bundled-types/boxel-ui/icons/send.gts +21 -0
- package/bundled-types/boxel-ui/icons/sparkle.gts +21 -0
- package/bundled-types/boxel-ui/icons/star-filled.gts +25 -0
- package/bundled-types/boxel-ui/icons/star-half-fill.gts +27 -0
- package/bundled-types/boxel-ui/icons/star.gts +25 -0
- package/bundled-types/boxel-ui/icons/success-bordered.gts +30 -0
- package/bundled-types/boxel-ui/icons/three-dots-horizontal.gts +21 -0
- package/bundled-types/boxel-ui/icons/triangle-left.gts +23 -0
- package/bundled-types/boxel-ui/icons/triangle-right.gts +23 -0
- package/bundled-types/boxel-ui/icons/types.ts +10 -0
- package/bundled-types/boxel-ui/icons/upload.gts +20 -0
- package/bundled-types/boxel-ui/icons/warning.gts +19 -0
- package/bundled-types/boxel-ui/icons.gts +246 -0
- package/bundled-types/boxel-ui/modifiers/auto-focus.ts +7 -0
- package/bundled-types/boxel-ui/modifiers/set-css-var.ts +24 -0
- package/bundled-types/boxel-ui/modifiers.ts +14 -0
- package/bundled-types/boxel-ui/types/@cardstack/boxel-ui/index.d.ts +3 -0
- package/bundled-types/boxel-ui/types/ember-css-url/index.d.ts +15 -0
- package/bundled-types/boxel-ui/types/ember-draggable-modifiers/index.d.ts +109 -0
- package/bundled-types/boxel-ui/types/ember-draggable-modifiers/utils.d.ts +7 -0
- package/bundled-types/boxel-ui/types/ember-focus-trap/index.d.ts +20 -0
- package/bundled-types/boxel-ui/types/ember-power-calendar/components/index.d.ts +9 -0
- package/bundled-types/boxel-ui/types/ember-resize-modifier/index.d.ts +14 -0
- package/bundled-types/boxel-ui/types/ember-set-body-class/index.d.ts +12 -0
- package/bundled-types/boxel-ui/types/ember-sortable/index.d.ts +52 -0
- package/bundled-types/boxel-ui/types/global.d.ts +7 -0
- package/bundled-types/boxel-ui/usage.ts +112 -0
- package/bundled-types/boxel-ui/utils/date-utils.ts +192 -0
- package/bundled-types/boxel-ui/utils/fitted-formats.ts +161 -0
- package/bundled-types/host-app/app.ts +22 -0
- package/bundled-types/host-app/commands/add-field-to-card-definition.ts +74 -0
- package/bundled-types/host-app/commands/ai-assistant.ts +203 -0
- package/bundled-types/host-app/commands/apply-markdown-edit.ts +203 -0
- package/bundled-types/host-app/commands/apply-search-replace-block.ts +225 -0
- package/bundled-types/host-app/commands/ask-ai.ts +66 -0
- package/bundled-types/host-app/commands/authed-fetch.ts +53 -0
- package/bundled-types/host-app/commands/bot-requests/create-listing-pr-request.ts +77 -0
- package/bundled-types/host-app/commands/bot-requests/send-bot-trigger-event.ts +53 -0
- package/bundled-types/host-app/commands/can-read-realm.ts +34 -0
- package/bundled-types/host-app/commands/cancel-indexing-job.ts +29 -0
- package/bundled-types/host-app/commands/check-correctness.ts +309 -0
- package/bundled-types/host-app/commands/copy-and-edit.ts +311 -0
- package/bundled-types/host-app/commands/copy-card-as-markdown.ts +41 -0
- package/bundled-types/host-app/commands/copy-card-to-stack.ts +70 -0
- package/bundled-types/host-app/commands/copy-card.ts +67 -0
- package/bundled-types/host-app/commands/copy-file-to-realm.ts +82 -0
- package/bundled-types/host-app/commands/copy-source.ts +46 -0
- package/bundled-types/host-app/commands/create-ai-assistant-room.ts +144 -0
- package/bundled-types/host-app/commands/create-and-open-submission-workflow-card.ts +30 -0
- package/bundled-types/host-app/commands/create-specs.ts +422 -0
- package/bundled-types/host-app/commands/create-submission-workflow.ts +172 -0
- package/bundled-types/host-app/commands/evaluate-module.ts +119 -0
- package/bundled-types/host-app/commands/execute-atomic-operations.ts +44 -0
- package/bundled-types/host-app/commands/fetch-card-json.ts +33 -0
- package/bundled-types/host-app/commands/full-reindex-realm.ts +30 -0
- package/bundled-types/host-app/commands/generate-example-cards.ts +298 -0
- package/bundled-types/host-app/commands/generate-readme-spec.ts +116 -0
- package/bundled-types/host-app/commands/generate-theme-example.ts +147 -0
- package/bundled-types/host-app/commands/generate-thumbnail.ts +247 -0
- package/bundled-types/host-app/commands/get-all-realm-metas.ts +38 -0
- package/bundled-types/host-app/commands/get-available-realm-identifiers.ts +29 -0
- package/bundled-types/host-app/commands/get-card-type-schema.ts +59 -0
- package/bundled-types/host-app/commands/get-card.ts +34 -0
- package/bundled-types/host-app/commands/get-catalog-realm-identifiers.ts +29 -0
- package/bundled-types/host-app/commands/get-default-writable-realm.ts +28 -0
- package/bundled-types/host-app/commands/get-events-from-room.ts +70 -0
- package/bundled-types/host-app/commands/get-realm-of-resource-identifier.ts +37 -0
- package/bundled-types/host-app/commands/get-user-system-card.ts +38 -0
- package/bundled-types/host-app/commands/index.ts +590 -0
- package/bundled-types/host-app/commands/instantiate-card.ts +185 -0
- package/bundled-types/host-app/commands/invalidate-realm-identifiers.ts +33 -0
- package/bundled-types/host-app/commands/invite-user-to-room.ts +34 -0
- package/bundled-types/host-app/commands/lint-and-fix.ts +60 -0
- package/bundled-types/host-app/commands/listing-action-build.ts +79 -0
- package/bundled-types/host-app/commands/listing-action-init.ts +106 -0
- package/bundled-types/host-app/commands/listing-create.ts +632 -0
- package/bundled-types/host-app/commands/listing-generate-example.ts +83 -0
- package/bundled-types/host-app/commands/listing-install.ts +227 -0
- package/bundled-types/host-app/commands/listing-remix.ts +150 -0
- package/bundled-types/host-app/commands/listing-update-specs.ts +116 -0
- package/bundled-types/host-app/commands/listing-use.ts +97 -0
- package/bundled-types/host-app/commands/one-shot-llm-request.ts +209 -0
- package/bundled-types/host-app/commands/open-ai-assistant-room.ts +38 -0
- package/bundled-types/host-app/commands/open-create-listing-modal.ts +52 -0
- package/bundled-types/host-app/commands/open-in-interact-mode.ts +36 -0
- package/bundled-types/host-app/commands/open-workspace.ts +38 -0
- package/bundled-types/host-app/commands/patch-card-instance.ts +108 -0
- package/bundled-types/host-app/commands/patch-code.ts +243 -0
- package/bundled-types/host-app/commands/patch-fields.ts +304 -0
- package/bundled-types/host-app/commands/patch-theme.ts +52 -0
- package/bundled-types/host-app/commands/persist-module-inspector-view.ts +41 -0
- package/bundled-types/host-app/commands/populate-with-sample-data.ts +84 -0
- package/bundled-types/host-app/commands/preview-format.ts +52 -0
- package/bundled-types/host-app/commands/read-binary-file.ts +62 -0
- package/bundled-types/host-app/commands/read-card-for-ai-assistant.ts +50 -0
- package/bundled-types/host-app/commands/read-file-for-ai-assistant.ts +46 -0
- package/bundled-types/host-app/commands/read-source.ts +46 -0
- package/bundled-types/host-app/commands/read-text-file.ts +44 -0
- package/bundled-types/host-app/commands/register-bot.ts +42 -0
- package/bundled-types/host-app/commands/reindex-realm.ts +30 -0
- package/bundled-types/host-app/commands/retry-submission-workflow.ts +119 -0
- package/bundled-types/host-app/commands/sanitize-module-list.ts +83 -0
- package/bundled-types/host-app/commands/save-card.ts +44 -0
- package/bundled-types/host-app/commands/screenshot-card.ts +148 -0
- package/bundled-types/host-app/commands/search-and-choose.ts +180 -0
- package/bundled-types/host-app/commands/search-cards.ts +102 -0
- package/bundled-types/host-app/commands/search-google-images.ts +100 -0
- package/bundled-types/host-app/commands/send-ai-assistant-message.ts +122 -0
- package/bundled-types/host-app/commands/send-request-via-proxy.ts +70 -0
- package/bundled-types/host-app/commands/serialize-card.ts +45 -0
- package/bundled-types/host-app/commands/set-active-llm.ts +39 -0
- package/bundled-types/host-app/commands/set-user-system-card.ts +29 -0
- package/bundled-types/host-app/commands/show-card.ts +102 -0
- package/bundled-types/host-app/commands/show-file.ts +39 -0
- package/bundled-types/host-app/commands/store-add.ts +37 -0
- package/bundled-types/host-app/commands/summarize-session.ts +82 -0
- package/bundled-types/host-app/commands/switch-submode.ts +112 -0
- package/bundled-types/host-app/commands/sync-openrouter-models.ts +373 -0
- package/bundled-types/host-app/commands/transform-cards.ts +59 -0
- package/bundled-types/host-app/commands/unregister-bot.ts +29 -0
- package/bundled-types/host-app/commands/update-code-path-with-selection.ts +45 -0
- package/bundled-types/host-app/commands/update-playground-selection.ts +37 -0
- package/bundled-types/host-app/commands/update-room-skills.ts +231 -0
- package/bundled-types/host-app/commands/utils.ts +178 -0
- package/bundled-types/host-app/commands/validate-realm.ts +40 -0
- package/bundled-types/host-app/commands/write-binary-file.ts +142 -0
- package/bundled-types/host-app/commands/write-text-file.ts +104 -0
- package/bundled-types/host-app/components/.gitkeep +0 -0
- package/bundled-types/host-app/components/ai-assistant/action-bar.gts +188 -0
- package/bundled-types/host-app/components/ai-assistant/ai-assist-button-active-bg.webp +0 -0
- package/bundled-types/host-app/components/ai-assistant/ai-assist-button-active-bg@2x.webp +0 -0
- package/bundled-types/host-app/components/ai-assistant/ai-assist-button-active-bg@3x.webp +0 -0
- package/bundled-types/host-app/components/ai-assistant/ai-assist-icon-animated.webp +0 -0
- package/bundled-types/host-app/components/ai-assistant/ai-assist-icon-bw.png +0 -0
- package/bundled-types/host-app/components/ai-assistant/ai-assist-icon-bw@2x.png +0 -0
- package/bundled-types/host-app/components/ai-assistant/ai-assist-icon-bw@3x.png +0 -0
- package/bundled-types/host-app/components/ai-assistant/ai-assist-icon.webp +0 -0
- package/bundled-types/host-app/components/ai-assistant/ai-assist-icon@2x.webp +0 -0
- package/bundled-types/host-app/components/ai-assistant/ai-assist-icon@3x.webp +0 -0
- package/bundled-types/host-app/components/ai-assistant/apply-button/index.gts +226 -0
- package/bundled-types/host-app/components/ai-assistant/apply-button/usage.gts +81 -0
- package/bundled-types/host-app/components/ai-assistant/attached-file-dropdown-menu.gts +179 -0
- package/bundled-types/host-app/components/ai-assistant/attachment-picker/attach-button.gts +176 -0
- package/bundled-types/host-app/components/ai-assistant/attachment-picker/attached-items.gts +271 -0
- package/bundled-types/host-app/components/ai-assistant/attachment-picker/index.gts +144 -0
- package/bundled-types/host-app/components/ai-assistant/attachment-picker/usage.gts +127 -0
- package/bundled-types/host-app/components/ai-assistant/button.gts +60 -0
- package/bundled-types/host-app/components/ai-assistant/chat-input/index.gts +203 -0
- package/bundled-types/host-app/components/ai-assistant/chat-input/usage.gts +68 -0
- package/bundled-types/host-app/components/ai-assistant/code-block/actions.gts +58 -0
- package/bundled-types/host-app/components/ai-assistant/code-block/apply-code-patch-button.gts +66 -0
- package/bundled-types/host-app/components/ai-assistant/code-block/command-header.gts +115 -0
- package/bundled-types/host-app/components/ai-assistant/code-block/diff-editor-header.gts +209 -0
- package/bundled-types/host-app/components/ai-assistant/code-block/index.gts +228 -0
- package/bundled-types/host-app/components/ai-assistant/code-block/patch-footer.gts +32 -0
- package/bundled-types/host-app/components/ai-assistant/code-block/view-code-button.gts +73 -0
- package/bundled-types/host-app/components/ai-assistant/focus-pill/index.gts +60 -0
- package/bundled-types/host-app/components/ai-assistant/focus-pill/usage.gts +45 -0
- package/bundled-types/host-app/components/ai-assistant/llm-mode-toggle.gts +113 -0
- package/bundled-types/host-app/components/ai-assistant/llm-select.gts +158 -0
- package/bundled-types/host-app/components/ai-assistant/message/aibot-message.gts +374 -0
- package/bundled-types/host-app/components/ai-assistant/message/attachments.gts +153 -0
- package/bundled-types/host-app/components/ai-assistant/message/index.gts +678 -0
- package/bundled-types/host-app/components/ai-assistant/message/meta.gts +66 -0
- package/bundled-types/host-app/components/ai-assistant/message/text-content.gts +32 -0
- package/bundled-types/host-app/components/ai-assistant/message/usage.gts +182 -0
- package/bundled-types/host-app/components/ai-assistant/message/user-message.gts +52 -0
- package/bundled-types/host-app/components/ai-assistant/new-session-button.gts +126 -0
- package/bundled-types/host-app/components/ai-assistant/new-session-settings.gts +180 -0
- package/bundled-types/host-app/components/ai-assistant/new-session.gts +83 -0
- package/bundled-types/host-app/components/ai-assistant/panel-popover.gts +102 -0
- package/bundled-types/host-app/components/ai-assistant/panel.gts +453 -0
- package/bundled-types/host-app/components/ai-assistant/past-session-item.gts +323 -0
- package/bundled-types/host-app/components/ai-assistant/past-sessions.gts +115 -0
- package/bundled-types/host-app/components/ai-assistant/rename-session.gts +144 -0
- package/bundled-types/host-app/components/ai-assistant/restore-file-modal.gts +105 -0
- package/bundled-types/host-app/components/ai-assistant/skill-menu/index.gts +190 -0
- package/bundled-types/host-app/components/ai-assistant/skill-menu/skill-toggle.gts +168 -0
- package/bundled-types/host-app/components/ai-assistant/skill-menu/usage.gts +48 -0
- package/bundled-types/host-app/components/ai-assistant/toast.gts +293 -0
- package/bundled-types/host-app/components/card-catalog/modal.gts +579 -0
- package/bundled-types/host-app/components/card-error.gts +41 -0
- package/bundled-types/host-app/components/card-instance-picker/index.gts +54 -0
- package/bundled-types/host-app/components/card-pill.gts +189 -0
- package/bundled-types/host-app/components/card-prerender.gts +880 -0
- package/bundled-types/host-app/components/card-renderer.gts +84 -0
- package/bundled-types/host-app/components/card-search/constants.ts +76 -0
- package/bundled-types/host-app/components/card-search/item-button.gts +243 -0
- package/bundled-types/host-app/components/card-search/panel.gts +150 -0
- package/bundled-types/host-app/components/card-search/search-bar.gts +218 -0
- package/bundled-types/host-app/components/card-search/search-content.gts +604 -0
- package/bundled-types/host-app/components/card-search/search-result-header.gts +165 -0
- package/bundled-types/host-app/components/card-search/search-result-section.gts +545 -0
- package/bundled-types/host-app/components/card-search/section-header.gts +117 -0
- package/bundled-types/host-app/components/editor/directory.gts +308 -0
- package/bundled-types/host-app/components/editor/file-tree.gts +69 -0
- package/bundled-types/host-app/components/editor/import-module.gts +27 -0
- package/bundled-types/host-app/components/editor/indexed-file-tree.gts +572 -0
- package/bundled-types/host-app/components/editor/recent-files.gts +141 -0
- package/bundled-types/host-app/components/file-pill.gts +206 -0
- package/bundled-types/host-app/components/head-format-preview.gts +781 -0
- package/bundled-types/host-app/components/host-mode/breadcrumb-item.gts +150 -0
- package/bundled-types/host-app/components/host-mode/breadcrumbs.gts +131 -0
- package/bundled-types/host-app/components/host-mode/card.gts +199 -0
- package/bundled-types/host-app/components/host-mode/content.gts +195 -0
- package/bundled-types/host-app/components/host-mode/stack-item.gts +310 -0
- package/bundled-types/host-app/components/host-mode/stack.gts +91 -0
- package/bundled-types/host-app/components/matrix/auth-container.gts +66 -0
- package/bundled-types/host-app/components/matrix/auth.gts +73 -0
- package/bundled-types/host-app/components/matrix/forgot-password.gts +487 -0
- package/bundled-types/host-app/components/matrix/login.gts +241 -0
- package/bundled-types/host-app/components/matrix/register-user.gts +843 -0
- package/bundled-types/host-app/components/matrix/room-message-command.gts +330 -0
- package/bundled-types/host-app/components/matrix/room-message.gts +261 -0
- package/bundled-types/host-app/components/matrix/room.gts +1872 -0
- package/bundled-types/host-app/components/matrix/user-profile.gts +99 -0
- package/bundled-types/host-app/components/modal-container.gts +171 -0
- package/bundled-types/host-app/components/operator-mode/binary-file-info.gts +77 -0
- package/bundled-types/host-app/components/operator-mode/card-adoption-chain.gts +99 -0
- package/bundled-types/host-app/components/operator-mode/card-error-detail.gts +87 -0
- package/bundled-types/host-app/components/operator-mode/card-error.gts +177 -0
- package/bundled-types/host-app/components/operator-mode/card-schema-editor.gts +616 -0
- package/bundled-types/host-app/components/operator-mode/card-url-bar.gts +197 -0
- package/bundled-types/host-app/components/operator-mode/choose-file-modal.gts +562 -0
- package/bundled-types/host-app/components/operator-mode/choose-subscription-plan-modal.gts +517 -0
- package/bundled-types/host-app/components/operator-mode/code-editor.gts +736 -0
- package/bundled-types/host-app/components/operator-mode/code-submode/editor-indicator.gts +128 -0
- package/bundled-types/host-app/components/operator-mode/code-submode/format-chooser.gts +592 -0
- package/bundled-types/host-app/components/operator-mode/code-submode/inner-container.gts +162 -0
- package/bundled-types/host-app/components/operator-mode/code-submode/left-panel-toggle.gts +267 -0
- package/bundled-types/host-app/components/operator-mode/code-submode/module-inspector.gts +836 -0
- package/bundled-types/host-app/components/operator-mode/code-submode/playground/field-chooser-modal.gts +97 -0
- package/bundled-types/host-app/components/operator-mode/code-submode/playground/instance-chooser-dropdown.gts +346 -0
- package/bundled-types/host-app/components/operator-mode/code-submode/playground/playground-background.png +0 -0
- package/bundled-types/host-app/components/operator-mode/code-submode/playground/playground-panel.gts +1274 -0
- package/bundled-types/host-app/components/operator-mode/code-submode/playground/playground-preview.gts +155 -0
- package/bundled-types/host-app/components/operator-mode/code-submode/playground/playground.gts +98 -0
- package/bundled-types/host-app/components/operator-mode/code-submode/playground/spec-search.gts +70 -0
- package/bundled-types/host-app/components/operator-mode/code-submode/schema-editor.gts +205 -0
- package/bundled-types/host-app/components/operator-mode/code-submode/spec-preview-badge.gts +72 -0
- package/bundled-types/host-app/components/operator-mode/code-submode/spec-preview.gts +432 -0
- package/bundled-types/host-app/components/operator-mode/code-submode/toggle-button.gts +72 -0
- package/bundled-types/host-app/components/operator-mode/code-submode.gts +1030 -0
- package/bundled-types/host-app/components/operator-mode/container.gts +270 -0
- package/bundled-types/host-app/components/operator-mode/context-menu-button.gts +95 -0
- package/bundled-types/host-app/components/operator-mode/copy-button.gts +277 -0
- package/bundled-types/host-app/components/operator-mode/create-file-modal.gts +1087 -0
- package/bundled-types/host-app/components/operator-mode/create-listing-modal.gts +513 -0
- package/bundled-types/host-app/components/operator-mode/definition-container/base.gts +222 -0
- package/bundled-types/host-app/components/operator-mode/definition-container/clickable.gts +59 -0
- package/bundled-types/host-app/components/operator-mode/definition-container/divider.gts +48 -0
- package/bundled-types/host-app/components/operator-mode/definition-container/index.gts +108 -0
- package/bundled-types/host-app/components/operator-mode/delete-modal.gts +123 -0
- package/bundled-types/host-app/components/operator-mode/detail-panel-selector.gts +320 -0
- package/bundled-types/host-app/components/operator-mode/detail-panel.gts +834 -0
- package/bundled-types/host-app/components/operator-mode/edit-field-modal.gts +450 -0
- package/bundled-types/host-app/components/operator-mode/error-display.gts +590 -0
- package/bundled-types/host-app/components/operator-mode/host-submode/open-site-popover.gts +127 -0
- package/bundled-types/host-app/components/operator-mode/host-submode/publishing-realm-popover.gts +159 -0
- package/bundled-types/host-app/components/operator-mode/host-submode.gts +373 -0
- package/bundled-types/host-app/components/operator-mode/interact-submode/neighbor-stack-trigger.gts +116 -0
- package/bundled-types/host-app/components/operator-mode/interact-submode.gts +1021 -0
- package/bundled-types/host-app/components/operator-mode/new-file-button.gts +187 -0
- package/bundled-types/host-app/components/operator-mode/operator-mode-overlays.gts +511 -0
- package/bundled-types/host-app/components/operator-mode/overlays.gts +342 -0
- package/bundled-types/host-app/components/operator-mode/preview-panel/fitted-format-gallery.gts +127 -0
- package/bundled-types/host-app/components/operator-mode/preview-panel/index.gts +443 -0
- package/bundled-types/host-app/components/operator-mode/preview-panel/markdown-preview.gts +175 -0
- package/bundled-types/host-app/components/operator-mode/preview-panel/metadata-panel.gts +214 -0
- package/bundled-types/host-app/components/operator-mode/preview-panel/rendered-markdown.gts +718 -0
- package/bundled-types/host-app/components/operator-mode/private-dependency-violation.gts +70 -0
- package/bundled-types/host-app/components/operator-mode/profile/profile-email.gts +686 -0
- package/bundled-types/host-app/components/operator-mode/profile/profile-settings-modal.gts +454 -0
- package/bundled-types/host-app/components/operator-mode/profile/profile-subscription.gts +170 -0
- package/bundled-types/host-app/components/operator-mode/profile-info-popover.gts +263 -0
- package/bundled-types/host-app/components/operator-mode/publish-realm-modal.gts +1529 -0
- package/bundled-types/host-app/components/operator-mode/remove-field-modal.gts +135 -0
- package/bundled-types/host-app/components/operator-mode/send-error-to-ai-assistant.gts +195 -0
- package/bundled-types/host-app/components/operator-mode/stack-item.gts +1341 -0
- package/bundled-types/host-app/components/operator-mode/stack.gts +191 -0
- package/bundled-types/host-app/components/operator-mode/submode-layout.gts +781 -0
- package/bundled-types/host-app/components/operator-mode/syntax-error-display.gts +72 -0
- package/bundled-types/host-app/components/operator-mode/workspace-chooser/add-workspace.gts +282 -0
- package/bundled-types/host-app/components/operator-mode/workspace-chooser/index.gts +307 -0
- package/bundled-types/host-app/components/operator-mode/workspace-chooser/item-container.gts +50 -0
- package/bundled-types/host-app/components/operator-mode/workspace-chooser/workspace-loading-indicator.gts +50 -0
- package/bundled-types/host-app/components/operator-mode/workspace-chooser/workspace.gts +1092 -0
- package/bundled-types/host-app/components/pill-menu/index.gts +281 -0
- package/bundled-types/host-app/components/pill-menu/usage.gts +64 -0
- package/bundled-types/host-app/components/prerendered-card-search.gts +274 -0
- package/bundled-types/host-app/components/realm-dropdown.gts +209 -0
- package/bundled-types/host-app/components/realm-picker/index.gts +142 -0
- package/bundled-types/host-app/components/search-sheet/index.gts +426 -0
- package/bundled-types/host-app/components/search-sheet/usage.gts +99 -0
- package/bundled-types/host-app/components/submode-switcher.gts +260 -0
- package/bundled-types/host-app/components/type-picker/index.gts +111 -0
- package/bundled-types/host-app/components/with-known-realms-loaded.gts +47 -0
- package/bundled-types/host-app/components/with-loaded-realm.gts +39 -0
- package/bundled-types/host-app/components/with-subscription-data.gts +247 -0
- package/bundled-types/host-app/config/environment.ts +66 -0
- package/bundled-types/host-app/deprecation-workflow.js +30 -0
- package/bundled-types/host-app/lib/browser-queue.ts +198 -0
- package/bundled-types/host-app/lib/codemirror-context.ts +1081 -0
- package/bundled-types/host-app/lib/command-definitions.ts +41 -0
- package/bundled-types/host-app/lib/download-realm.ts +9 -0
- package/bundled-types/host-app/lib/example-card-helpers.ts +99 -0
- package/bundled-types/host-app/lib/externals.ts +247 -0
- package/bundled-types/host-app/lib/field-path-parser.ts +520 -0
- package/bundled-types/host-app/lib/file-def-manager.ts +712 -0
- package/bundled-types/host-app/lib/file-upload-state.ts +6 -0
- package/bundled-types/host-app/lib/formatted-message/utils.ts +272 -0
- package/bundled-types/host-app/lib/gc-card-store.ts +1084 -0
- package/bundled-types/host-app/lib/host-base-command.ts +29 -0
- package/bundled-types/host-app/lib/html-component.ts +144 -0
- package/bundled-types/host-app/lib/html-to-markdown.ts +96 -0
- package/bundled-types/host-app/lib/isolated-render.gts +90 -0
- package/bundled-types/host-app/lib/known-file-meta-urls.ts +17 -0
- package/bundled-types/host-app/lib/limited-set.ts +68 -0
- package/bundled-types/host-app/lib/matrix-classes/member.ts +28 -0
- package/bundled-types/host-app/lib/matrix-classes/message-builder.ts +444 -0
- package/bundled-types/host-app/lib/matrix-classes/message-code-patch-result.ts +44 -0
- package/bundled-types/host-app/lib/matrix-classes/message-command.ts +109 -0
- package/bundled-types/host-app/lib/matrix-classes/message.ts +239 -0
- package/bundled-types/host-app/lib/matrix-classes/room.ts +174 -0
- package/bundled-types/host-app/lib/matrix-utils.ts +114 -0
- package/bundled-types/host-app/lib/mutex.ts +62 -0
- package/bundled-types/host-app/lib/prerender-fetch-headers.ts +46 -0
- package/bundled-types/host-app/lib/prerender-util.ts +31 -0
- package/bundled-types/host-app/lib/public-path.ts +1 -0
- package/bundled-types/host-app/lib/random-name.ts +26 -0
- package/bundled-types/host-app/lib/realm-utils.ts +45 -0
- package/bundled-types/host-app/lib/search-cache-key.ts +33 -0
- package/bundled-types/host-app/lib/search-in-flight-key.ts +28 -0
- package/bundled-types/host-app/lib/search-replace-block-parsing.ts +101 -0
- package/bundled-types/host-app/lib/setup-globals.ts +15 -0
- package/bundled-types/host-app/lib/sqlite-adapter.ts +510 -0
- package/bundled-types/host-app/lib/stack-item.ts +164 -0
- package/bundled-types/host-app/lib/utils.ts +84 -0
- package/bundled-types/host-app/lib/window-error-handler.ts +132 -0
- package/bundled-types/host-app/router.ts +31 -0
- package/bundled-types/host-app/services/ai-assistant-panel-service.ts +850 -0
- package/bundled-types/host-app/services/billing-service.ts +208 -0
- package/bundled-types/host-app/services/card-service.ts +373 -0
- package/bundled-types/host-app/services/card-type-service.ts +226 -0
- package/bundled-types/host-app/services/code-semantics-service.ts +297 -0
- package/bundled-types/host-app/services/command-service.ts +975 -0
- package/bundled-types/host-app/services/environment-service.ts +26 -0
- package/bundled-types/host-app/services/error-display.ts +42 -0
- package/bundled-types/host-app/services/file-upload.ts +212 -0
- package/bundled-types/host-app/services/host-mode-service.ts +400 -0
- package/bundled-types/host-app/services/host-mode-state-service.ts +160 -0
- package/bundled-types/host-app/services/loader-service.ts +148 -0
- package/bundled-types/host-app/services/local-indexer.ts +68 -0
- package/bundled-types/host-app/services/local-persistence-service.ts +296 -0
- package/bundled-types/host-app/services/logger-service.ts +13 -0
- package/bundled-types/host-app/services/matrix-sdk-loader.ts +346 -0
- package/bundled-types/host-app/services/matrix-service.ts +2288 -0
- package/bundled-types/host-app/services/message-service.ts +84 -0
- package/bundled-types/host-app/services/module-contents-service.ts +333 -0
- package/bundled-types/host-app/services/monaco-service.ts +333 -0
- package/bundled-types/host-app/services/network.ts +101 -0
- package/bundled-types/host-app/services/operator-mode-state-service.ts +1593 -0
- package/bundled-types/host-app/services/playground-panel-service.ts +236 -0
- package/bundled-types/host-app/services/queue.ts +30 -0
- package/bundled-types/host-app/services/realm-info-service.ts +37 -0
- package/bundled-types/host-app/services/realm-server.ts +1211 -0
- package/bundled-types/host-app/services/realm.ts +1413 -0
- package/bundled-types/host-app/services/recent-cards-service.ts +174 -0
- package/bundled-types/host-app/services/recent-files-service.ts +224 -0
- package/bundled-types/host-app/services/render-error-state.ts +55 -0
- package/bundled-types/host-app/services/render-service.ts +362 -0
- package/bundled-types/host-app/services/render-store.ts +27 -0
- package/bundled-types/host-app/services/reset.ts +19 -0
- package/bundled-types/host-app/services/scroll-position-service.ts +81 -0
- package/bundled-types/host-app/services/spec-panel-service.ts +107 -0
- package/bundled-types/host-app/services/store.ts +2540 -0
- package/bundled-types/host-app/utils/assert-never.ts +3 -0
- package/bundled-types/host-app/utils/auth-error-guard.ts +183 -0
- package/bundled-types/host-app/utils/auth-service-worker-registration.ts +123 -0
- package/bundled-types/host-app/utils/card-search/query-builder.ts +169 -0
- package/bundled-types/host-app/utils/card-search/section-pagination.ts +57 -0
- package/bundled-types/host-app/utils/card-search/sections.ts +240 -0
- package/bundled-types/host-app/utils/card-search/type-filter.ts +124 -0
- package/bundled-types/host-app/utils/card-search/types.ts +11 -0
- package/bundled-types/host-app/utils/card-search/url.ts +27 -0
- package/bundled-types/host-app/utils/clipboard.ts +23 -0
- package/bundled-types/host-app/utils/editor/boxel-formatter.ts +65 -0
- package/bundled-types/host-app/utils/editor/editor-language.ts +88 -0
- package/bundled-types/host-app/utils/editor/monaco-test-waiter.ts +302 -0
- package/bundled-types/host-app/utils/file-def-attributes-extractor.ts +438 -0
- package/bundled-types/host-app/utils/file-name.ts +38 -0
- package/bundled-types/host-app/utils/id-from-card-or-url.ts +11 -0
- package/bundled-types/host-app/utils/lint-formatting.ts +57 -0
- package/bundled-types/host-app/utils/local-storage-keys.ts +28 -0
- package/bundled-types/host-app/utils/normalized-dir-path.ts +3 -0
- package/bundled-types/host-app/utils/prettify-messages.ts +21 -0
- package/bundled-types/host-app/utils/prettify-prompts.ts +21 -0
- package/bundled-types/host-app/utils/realm-index-boilerplate.ts +27 -0
- package/bundled-types/host-app/utils/register-boxel-transition.ts +17 -0
- package/bundled-types/host-app/utils/render-desync-detector.ts +362 -0
- package/bundled-types/host-app/utils/render-error.ts +455 -0
- package/bundled-types/host-app/utils/render-timer-stub.ts +249 -0
- package/bundled-types/host-app/utils/run-while-active.ts +14 -0
- package/bundled-types/host-app/utils/schema-editor.ts +25 -0
- package/bundled-types/host-app/utils/text-suggestion.ts +82 -0
- package/bundled-types/host-app/utils/titleize.ts +10 -0
- package/bundled-types/host-app/utils/uuid.ts +13 -0
- package/bundled-types/host-tests/helpers/adapter.ts +464 -0
- package/bundled-types/host-tests/helpers/base-realm.ts +464 -0
- package/bundled-types/host-tests/helpers/cards/view-card-demo.ts +119 -0
- package/bundled-types/host-tests/helpers/field-test-helpers.gts +54 -0
- package/bundled-types/host-tests/helpers/image-fixture.ts +3 -0
- package/bundled-types/host-tests/helpers/index.gts +2099 -0
- package/bundled-types/host-tests/helpers/indexer.ts +293 -0
- package/bundled-types/host-tests/helpers/interact-submode-setup.gts +551 -0
- package/bundled-types/host-tests/helpers/mock-matrix/_client.ts +1042 -0
- package/bundled-types/host-tests/helpers/mock-matrix/_sdk.ts +71 -0
- package/bundled-types/host-tests/helpers/mock-matrix/_server-state.ts +343 -0
- package/bundled-types/host-tests/helpers/mock-matrix/_sliding-sync.ts +140 -0
- package/bundled-types/host-tests/helpers/mock-matrix/_utils.ts +146 -0
- package/bundled-types/host-tests/helpers/mock-matrix.ts +200 -0
- package/bundled-types/host-tests/helpers/operator-mode-parameters-match.ts +71 -0
- package/bundled-types/host-tests/helpers/operator-mode-state.ts +18 -0
- package/bundled-types/host-tests/helpers/percy-snapshot.ts +228 -0
- package/bundled-types/host-tests/helpers/playground.ts +130 -0
- package/bundled-types/host-tests/helpers/realm-server-mock/index.ts +100 -0
- package/bundled-types/host-tests/helpers/realm-server-mock/routes.ts +617 -0
- package/bundled-types/host-tests/helpers/realm-server-mock/types.ts +24 -0
- package/bundled-types/host-tests/helpers/recent-files-cards.ts +86 -0
- package/bundled-types/host-tests/helpers/render-component.ts +40 -0
- package/bundled-types/host-tests/helpers/setup-qunit.js +164 -0
- package/bundled-types/host-tests/helpers/setup.ts +349 -0
- package/bundled-types/host-tests/helpers/shard-warmup.ts +72 -0
- package/bundled-types/host-tests/helpers/stream.ts +60 -0
- package/bundled-types/host-tests/helpers/test-auth.ts +27 -0
- package/bundled-types/host-tests/helpers/test-realm-registry.ts +23 -0
- package/bundled-types/host-tests/helpers/test-realm-service-worker.ts +92 -0
- package/bundled-types/host-tests/helpers/uncaught-exceptions.ts +16 -0
- package/bundled-types/host-tests/helpers/visit-operator-mode.ts +39 -0
- package/bundled-types/host-types/@cardstack/host/index.d.ts +3 -0
- package/bundled-types/host-types/@joplin/turndown-plugin-gfm/index.d.ts +15 -0
- package/bundled-types/host-types/@sqlite.org/sqlite-wasm/index.d.ts +122 -0
- package/bundled-types/host-types/ember-click-outside/modifiers/on-click-outside.ts +16 -0
- package/bundled-types/host-types/ember-concurrency/helpers/perform.d.ts +3 -0
- package/bundled-types/host-types/ember-css-url/index.d.ts +15 -0
- package/bundled-types/host-types/ember-data/types/registries/model.d.ts +6 -0
- package/bundled-types/host-types/ember-elsewhere/from-elsewhere.d.ts +12 -0
- package/bundled-types/host-types/ember-elsewhere/to-elsewhere.d.ts +16 -0
- package/bundled-types/host-types/ember-focus-trap/index.d.ts +4 -0
- package/bundled-types/host-types/ember-keyboard/modifiers/on-key.d.ts +15 -0
- package/bundled-types/host-types/index.d.ts +6 -0
- package/bundled-types/local-types/eslint-js.d.ts +5 -0
- package/bundled-types/local-types/index.d.ts +115 -0
- package/bundled-types/local-types/marked-gfm-heading-id.d.ts +12 -0
- package/bundled-types/local-types/matrix-js-sdk/index.d.ts +11 -0
- package/bundled-types/local-types/package.json +13 -0
- package/bundled-types/shims/boxel-cli-shims.d.ts +10 -0
- package/dist/index.js +100 -100
- package/package.json +13 -7
- package/src/commands/parse.ts +277 -34
- package/src/commands/realm/publish.ts +10 -1
- package/src/commands/realm/unpublish.ts +2 -3
- package/src/lib/describe-fetch-error.ts +25 -0
|
@@ -0,0 +1,1341 @@
|
|
|
1
|
+
import { fn } from '@ember/helper';
|
|
2
|
+
import { hash } from '@ember/helper';
|
|
3
|
+
import { on } from '@ember/modifier';
|
|
4
|
+
import { action } from '@ember/object';
|
|
5
|
+
import type Owner from '@ember/owner';
|
|
6
|
+
import { scheduleOnce } from '@ember/runloop';
|
|
7
|
+
import { service } from '@ember/service';
|
|
8
|
+
import type { SafeString } from '@ember/template';
|
|
9
|
+
import { htmlSafe } from '@ember/template';
|
|
10
|
+
|
|
11
|
+
import { isTesting } from '@embroider/macros';
|
|
12
|
+
|
|
13
|
+
import Component from '@glimmer/component';
|
|
14
|
+
|
|
15
|
+
import { tracked, cached } from '@glimmer/tracking';
|
|
16
|
+
|
|
17
|
+
import DeselectIcon from '@cardstack/boxel-icons/deselect';
|
|
18
|
+
import Maximize from '@cardstack/boxel-icons/maximize';
|
|
19
|
+
import SelectAllIcon from '@cardstack/boxel-icons/select-all';
|
|
20
|
+
import { restartableTask, timeout, dropTask } from 'ember-concurrency';
|
|
21
|
+
import Modifier from 'ember-modifier';
|
|
22
|
+
import { provide, consume } from 'ember-provide-consume-context';
|
|
23
|
+
|
|
24
|
+
import pluralize from 'pluralize';
|
|
25
|
+
import { TrackedSet } from 'tracked-built-ins';
|
|
26
|
+
|
|
27
|
+
import {
|
|
28
|
+
CardContainer,
|
|
29
|
+
CardHeader,
|
|
30
|
+
LoadingIndicator,
|
|
31
|
+
} from '@cardstack/boxel-ui/components';
|
|
32
|
+
import {
|
|
33
|
+
MenuDivider,
|
|
34
|
+
MenuItem,
|
|
35
|
+
getContrastColor,
|
|
36
|
+
toMenuItems,
|
|
37
|
+
} from '@cardstack/boxel-ui/helpers';
|
|
38
|
+
import { cn, cssVar, optional, not } from '@cardstack/boxel-ui/helpers';
|
|
39
|
+
|
|
40
|
+
import { IconTrash } from '@cardstack/boxel-ui/icons';
|
|
41
|
+
|
|
42
|
+
import type { CommandContext } from '@cardstack/runtime-common';
|
|
43
|
+
import {
|
|
44
|
+
type Permissions,
|
|
45
|
+
type getCard,
|
|
46
|
+
type getCards,
|
|
47
|
+
type getCardCollection,
|
|
48
|
+
isFileDefInstance,
|
|
49
|
+
cardTypeDisplayName,
|
|
50
|
+
PermissionsContextName,
|
|
51
|
+
RealmURLContextName,
|
|
52
|
+
GetCardContextName,
|
|
53
|
+
GetCardsContextName,
|
|
54
|
+
GetCardCollectionContextName,
|
|
55
|
+
cardTypeIcon,
|
|
56
|
+
isRealmIndexCardId,
|
|
57
|
+
realmURL,
|
|
58
|
+
localId as localIdSymbol,
|
|
59
|
+
CardContextName,
|
|
60
|
+
CardCrudFunctionsContextName,
|
|
61
|
+
getMenuItems,
|
|
62
|
+
baseCardRef,
|
|
63
|
+
} from '@cardstack/runtime-common';
|
|
64
|
+
|
|
65
|
+
import {
|
|
66
|
+
stackItemTypeToStoreReadType,
|
|
67
|
+
type StackItem,
|
|
68
|
+
} from '@cardstack/host/lib/stack-item';
|
|
69
|
+
import { urlForRealmLookup } from '@cardstack/host/lib/utils';
|
|
70
|
+
|
|
71
|
+
import type {
|
|
72
|
+
CardContext,
|
|
73
|
+
CardCrudFunctions,
|
|
74
|
+
CardDef,
|
|
75
|
+
} from 'https://cardstack.com/base/card-api';
|
|
76
|
+
|
|
77
|
+
import consumeContext from '../../helpers/consume-context';
|
|
78
|
+
import ElementTracker, {
|
|
79
|
+
type RenderedCardForOverlayActions,
|
|
80
|
+
} from '../../resources/element-tracker';
|
|
81
|
+
import CardRenderer from '../card-renderer';
|
|
82
|
+
|
|
83
|
+
import CardError from './card-error';
|
|
84
|
+
import DeleteModal from './delete-modal';
|
|
85
|
+
|
|
86
|
+
import OperatorModeOverlays from './operator-mode-overlays';
|
|
87
|
+
|
|
88
|
+
import type CardService from '../../services/card-service';
|
|
89
|
+
import type OperatorModeStateService from '../../services/operator-mode-state-service';
|
|
90
|
+
import type RealmService from '../../services/realm';
|
|
91
|
+
import type StoreService from '../../services/store';
|
|
92
|
+
|
|
93
|
+
export interface StackItemComponentAPI {
|
|
94
|
+
clearSelections: () => void;
|
|
95
|
+
scrollIntoView: (selector: string) => Promise<void>;
|
|
96
|
+
startAnimation: (type: 'closing' | 'movingForward') => Promise<void>;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
interface Signature {
|
|
100
|
+
Args: {
|
|
101
|
+
item: StackItem;
|
|
102
|
+
stackItems: StackItem[];
|
|
103
|
+
index: number;
|
|
104
|
+
requestDeleteCard?: (card: CardDef | URL | string) => Promise<void>;
|
|
105
|
+
commandContext: CommandContext;
|
|
106
|
+
close: (item: StackItem) => void;
|
|
107
|
+
dismissStackedCardsAbove: (stackIndex: number) => Promise<void>;
|
|
108
|
+
onSelectedCards: (
|
|
109
|
+
selectedCards: CardDefOrId[],
|
|
110
|
+
stackItem: StackItem,
|
|
111
|
+
) => void;
|
|
112
|
+
setupStackItem: (
|
|
113
|
+
model: StackItem,
|
|
114
|
+
componentAPI: StackItemComponentAPI,
|
|
115
|
+
) => void;
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export type CardDefOrId = CardDef | string;
|
|
120
|
+
|
|
121
|
+
export interface StackItemRenderedCardForOverlayActions extends RenderedCardForOverlayActions {
|
|
122
|
+
stackItem: StackItem;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export default class OperatorModeStackItem extends Component<Signature> {
|
|
126
|
+
@consume(GetCardContextName) declare private getCard: getCard;
|
|
127
|
+
@consume(GetCardsContextName) declare private getCards: getCards;
|
|
128
|
+
@consume(GetCardCollectionContextName)
|
|
129
|
+
declare private getCardCollection: getCardCollection;
|
|
130
|
+
@consume(CardContextName) declare private cardContext: CardContext;
|
|
131
|
+
@consume(CardCrudFunctionsContextName)
|
|
132
|
+
declare private cardCrudFunctions: CardCrudFunctions;
|
|
133
|
+
|
|
134
|
+
@service declare private cardService: CardService;
|
|
135
|
+
@service declare private operatorModeStateService: OperatorModeStateService;
|
|
136
|
+
@service declare private realm: RealmService;
|
|
137
|
+
@service declare private store: StoreService;
|
|
138
|
+
|
|
139
|
+
@tracked private selectedCards = new TrackedSet<string>();
|
|
140
|
+
|
|
141
|
+
private normalizeCardId(cardDefOrId: CardDefOrId): string {
|
|
142
|
+
if (typeof cardDefOrId === 'string') {
|
|
143
|
+
return cardDefOrId;
|
|
144
|
+
}
|
|
145
|
+
return cardDefOrId.id ?? cardDefOrId[localIdSymbol];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@tracked private showDeleteModal = false;
|
|
149
|
+
@tracked private numberOfCardsToDelete = 0;
|
|
150
|
+
@tracked private isDeletingCards = false;
|
|
151
|
+
@tracked private deleteError: string | undefined;
|
|
152
|
+
@tracked private animationType:
|
|
153
|
+
| 'opening'
|
|
154
|
+
| 'closing'
|
|
155
|
+
| 'movingForward'
|
|
156
|
+
| undefined = 'opening';
|
|
157
|
+
@tracked private cardResource: ReturnType<getCard> | undefined;
|
|
158
|
+
private contentEl: HTMLElement | undefined;
|
|
159
|
+
private containerEl: HTMLElement | undefined;
|
|
160
|
+
private itemEl: HTMLElement | undefined;
|
|
161
|
+
|
|
162
|
+
@provide(PermissionsContextName)
|
|
163
|
+
get permissions(): Permissions | undefined {
|
|
164
|
+
if (this.url) {
|
|
165
|
+
return this.realm.permissions(this.url);
|
|
166
|
+
} else if (this.card?.[realmURL]) {
|
|
167
|
+
return this.realm.permissions(this.card[realmURL]?.href);
|
|
168
|
+
}
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
@provide(RealmURLContextName)
|
|
173
|
+
get realmURL() {
|
|
174
|
+
return this.card ? this.card[realmURL] : undefined;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
cardTracker = new ElementTracker();
|
|
178
|
+
|
|
179
|
+
constructor(owner: Owner, args: Signature['Args']) {
|
|
180
|
+
super(owner, args);
|
|
181
|
+
this.args.setupStackItem(this.args.item, {
|
|
182
|
+
clearSelections: this.clearSelections,
|
|
183
|
+
scrollIntoView: this.scrollIntoViewTask.perform,
|
|
184
|
+
startAnimation: this.startAnimation.perform,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
private makeCardResource = () => {
|
|
189
|
+
this.cardResource = this.getCard(this, () => this.args.item.id, {
|
|
190
|
+
type: stackItemTypeToStoreReadType(this.args.item.type),
|
|
191
|
+
});
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
private get url() {
|
|
195
|
+
return this.card?.id ?? this.cardError?.id;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private get renderedCardsForOverlayActions(): StackItemRenderedCardForOverlayActions[] {
|
|
199
|
+
return this.cardTracker
|
|
200
|
+
.filter(
|
|
201
|
+
[
|
|
202
|
+
{ format: 'data' },
|
|
203
|
+
{ fieldType: 'linksTo' },
|
|
204
|
+
{ fieldType: 'linksToMany' },
|
|
205
|
+
],
|
|
206
|
+
'or',
|
|
207
|
+
// the only linksTo field with isolated format is in the index card,
|
|
208
|
+
// we don't want to show overlays for those cards here
|
|
209
|
+
{ exclude: [{ fieldType: 'linksTo', format: 'isolated' }] },
|
|
210
|
+
)
|
|
211
|
+
.map((entry) => ({
|
|
212
|
+
...entry,
|
|
213
|
+
stackItem: this.args.item,
|
|
214
|
+
}));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
private get isItemFullWidth() {
|
|
218
|
+
return !this.isBuried && this.isWideFormat;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
private get styleForStackedCard(): SafeString {
|
|
222
|
+
const stackItemMaxWidth = 50; // unit: rem, 800px for 16px base
|
|
223
|
+
const RATIO = 1.2;
|
|
224
|
+
// top card: 800px / (1.2 ^ 0) = 800px;
|
|
225
|
+
// buried card: 800px / (1.2 ^ 1) = ~666px;
|
|
226
|
+
// next buried card: 800px / (1.2 ^ 2) = ~555px;
|
|
227
|
+
const maxWidthReductionPercent = 10; // Every new card on the stack is 10% wider than the previous one (for narrow viewport)
|
|
228
|
+
const numberOfCards = this.args.stackItems.length;
|
|
229
|
+
const invertedIndex = numberOfCards - this.args.index - 1;
|
|
230
|
+
const isLastCard = this.args.index === numberOfCards - 1;
|
|
231
|
+
const isSecondLastCard = this.args.index === numberOfCards - 2;
|
|
232
|
+
|
|
233
|
+
// Expanded mode opts out of stacked-layout sizing — let natural
|
|
234
|
+
// flow size the card so .item.expanded CSS rules apply cleanly
|
|
235
|
+
// without fighting inline !important overrides. Mirrors host-mode
|
|
236
|
+
// pattern: parent constrains height, children inherit.
|
|
237
|
+
if (this.isExpanded) {
|
|
238
|
+
return htmlSafe(`z-index: calc(${this.args.index} + 1);`);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
let marginTopPx = 0;
|
|
242
|
+
|
|
243
|
+
if (invertedIndex > 2) {
|
|
244
|
+
marginTopPx = -5; // If there are more than 3 cards, those cards are buried behind the header
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (numberOfCards > 1) {
|
|
248
|
+
if (isLastCard) {
|
|
249
|
+
marginTopPx = numberOfCards === 2 ? 30 : 50;
|
|
250
|
+
} else if (isSecondLastCard && numberOfCards > 2) {
|
|
251
|
+
marginTopPx = 25;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
let maxWidthPercent = 100 - invertedIndex * maxWidthReductionPercent;
|
|
256
|
+
let width = this.isItemFullWidth
|
|
257
|
+
? '100%'
|
|
258
|
+
: `${stackItemMaxWidth / Math.pow(RATIO, invertedIndex)}rem`;
|
|
259
|
+
|
|
260
|
+
let styles = `
|
|
261
|
+
height: calc(100% - ${marginTopPx}px);
|
|
262
|
+
width: ${width};
|
|
263
|
+
max-width: ${maxWidthPercent}%;
|
|
264
|
+
z-index: calc(${this.args.index} + 1);
|
|
265
|
+
margin-top: ${marginTopPx}px;
|
|
266
|
+
`; // using margin-top instead of padding-top to hide scrolled content from view
|
|
267
|
+
// Transition (280ms ease-out, all geometric props) is on the .item
|
|
268
|
+
// CSS rule below — no inline override here, so expand/collapse
|
|
269
|
+
// morph + stacked-layout shifts all use the same curve.
|
|
270
|
+
|
|
271
|
+
return htmlSafe(styles);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
private get isBuried() {
|
|
275
|
+
return this.args.index + 1 < this.args.stackItems.length;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
private get isTopCard() {
|
|
279
|
+
return !this.isBuried;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
private get isIndexCard() {
|
|
283
|
+
return isRealmIndexCardId(this.url, this.realmURL);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Element ref captured by submode-layout's expanded-card-header-slot.
|
|
287
|
+
// Only used when isExpanded — projects the CardHeader into the top
|
|
288
|
+
// bar pill, replacing the inline card header for the expanded mode.
|
|
289
|
+
// Returns null when not expanded so the inline header renders as
|
|
290
|
+
// usual (and the if/else branch picks the inline path).
|
|
291
|
+
private get expandedCardHeaderSlot() {
|
|
292
|
+
if (!this.isExpanded) return null;
|
|
293
|
+
return this.operatorModeStateService.expandedCardHeaderElement;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
@provide(CardContextName)
|
|
297
|
+
// @ts-ignore "context" is declared but not used
|
|
298
|
+
private get context(): StackItemCardContext {
|
|
299
|
+
return {
|
|
300
|
+
...this.cardContext,
|
|
301
|
+
cardComponentModifier: this.cardTracker.trackElement,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
private closeItem = () => this._closeItem.perform();
|
|
306
|
+
|
|
307
|
+
// Per-card expanded state. Persisted on operatorModeStateService
|
|
308
|
+
// (keyed by stack-item instance) so the user's expand intent survives:
|
|
309
|
+
// - When this card is buried (pushed deeper in the stack),
|
|
310
|
+
// isExpanded reads as false (we render normally), but the
|
|
311
|
+
// stored intent is preserved.
|
|
312
|
+
// - When the card pops back to the top, isExpanded reads true
|
|
313
|
+
// again from storage and the card re-expands.
|
|
314
|
+
private get itemExpandKey(): string {
|
|
315
|
+
return this.args.item.instanceId;
|
|
316
|
+
}
|
|
317
|
+
private get isExpandedIntent(): boolean {
|
|
318
|
+
return this.operatorModeStateService.isStackItemExpanded(
|
|
319
|
+
this.itemExpandKey,
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
private get isExpanded(): boolean {
|
|
323
|
+
return this.isTopCard && this.isExpandedIntent;
|
|
324
|
+
}
|
|
325
|
+
private toggleExpanded = () => {
|
|
326
|
+
if (!this.isTopCard) return;
|
|
327
|
+
const cardEl = this.itemEl;
|
|
328
|
+
const cardFrom = cardEl?.getBoundingClientRect();
|
|
329
|
+
|
|
330
|
+
this.operatorModeStateService.setStackItemExpanded(
|
|
331
|
+
this.itemExpandKey,
|
|
332
|
+
!this.isExpandedIntent,
|
|
333
|
+
);
|
|
334
|
+
|
|
335
|
+
// FLIP via Web Animations on the card body: measure rect before
|
|
336
|
+
// state change, animate inverse transform back to identity after
|
|
337
|
+
// re-render. Works around CSS transitions not firing when changing
|
|
338
|
+
// properties cross from inline-style to CSS-rule sources mid-frame.
|
|
339
|
+
if (!cardEl || !cardFrom) return;
|
|
340
|
+
this.pendingFlipEl = cardEl;
|
|
341
|
+
this.pendingFlipFrom = cardFrom;
|
|
342
|
+
scheduleOnce('afterRender', this, this.runExpandAnimation);
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
private pendingFlipEl: HTMLElement | null = null;
|
|
346
|
+
private pendingFlipFrom: DOMRect | null = null;
|
|
347
|
+
|
|
348
|
+
private runExpandAnimation() {
|
|
349
|
+
const cardEl = this.pendingFlipEl;
|
|
350
|
+
const cardFrom = this.pendingFlipFrom;
|
|
351
|
+
this.pendingFlipEl = null;
|
|
352
|
+
this.pendingFlipFrom = null;
|
|
353
|
+
if (!cardEl || !cardFrom) return;
|
|
354
|
+
this.playFlip(cardEl, cardFrom, {
|
|
355
|
+
duration: 280,
|
|
356
|
+
easing: 'cubic-bezier(0.34, 1.56, 0.64, 1)',
|
|
357
|
+
});
|
|
358
|
+
// Header gets a lightweight fade + small Y slide — suggests
|
|
359
|
+
// direction without the full FLIP's visual noise. Expand: pill
|
|
360
|
+
// slides UP into the bar (starts 10px below). Restore: header
|
|
361
|
+
// slides DOWN onto the card (starts 10px above). A second afterRender
|
|
362
|
+
// pass lets {{#in-element}} settle before measuring.
|
|
363
|
+
scheduleOnce('afterRender', this, this.animateHeaderTransition);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
private animateHeaderTransition() {
|
|
367
|
+
const headerTo = this.findHeaderEl();
|
|
368
|
+
if (!headerTo) return;
|
|
369
|
+
const fromOffsetY = this.isExpandedIntent ? 28 : -28;
|
|
370
|
+
headerTo.animate(
|
|
371
|
+
[
|
|
372
|
+
{ opacity: 0, transform: `translateY(${fromOffsetY}px)` },
|
|
373
|
+
{ opacity: 1, transform: 'translateY(0)' },
|
|
374
|
+
],
|
|
375
|
+
{
|
|
376
|
+
duration: 280,
|
|
377
|
+
easing: 'cubic-bezier(0.34, 1.56, 0.64, 1)',
|
|
378
|
+
fill: 'none',
|
|
379
|
+
},
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
private findHeaderEl(): HTMLElement | null {
|
|
384
|
+
// After expand: the portaled .expanded-card-header-pill in the bar.
|
|
385
|
+
// Before expand (or after restore): the inline .stack-item-header
|
|
386
|
+
// inside this stack-item's DOM.
|
|
387
|
+
const slot = this.operatorModeStateService.expandedCardHeaderElement;
|
|
388
|
+
const portaled = slot?.querySelector(
|
|
389
|
+
'.expanded-card-header-pill',
|
|
390
|
+
) as HTMLElement | null;
|
|
391
|
+
if (portaled) return portaled;
|
|
392
|
+
return (
|
|
393
|
+
(this.itemEl?.querySelector(
|
|
394
|
+
'.stack-item-header',
|
|
395
|
+
) as HTMLElement | null) ?? null
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
private playFlip(
|
|
400
|
+
el: HTMLElement,
|
|
401
|
+
fromRect: DOMRect,
|
|
402
|
+
opts: { duration: number; easing: string },
|
|
403
|
+
) {
|
|
404
|
+
const toRect = el.getBoundingClientRect();
|
|
405
|
+
const dx = fromRect.left - toRect.left;
|
|
406
|
+
const dy = fromRect.top - toRect.top;
|
|
407
|
+
// Guard against zero target dimensions (e.g., during unmount or
|
|
408
|
+
// before layout settles) — Web Animations would NaN out otherwise.
|
|
409
|
+
if (toRect.width === 0 || toRect.height === 0) return;
|
|
410
|
+
const sx = fromRect.width / toRect.width;
|
|
411
|
+
const sy = fromRect.height / toRect.height;
|
|
412
|
+
el.animate(
|
|
413
|
+
[
|
|
414
|
+
{
|
|
415
|
+
transform: `translate(${dx}px, ${dy}px) scale(${sx}, ${sy})`,
|
|
416
|
+
transformOrigin: 'top left',
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
transform: 'translate(0, 0) scale(1, 1)',
|
|
420
|
+
transformOrigin: 'top left',
|
|
421
|
+
},
|
|
422
|
+
],
|
|
423
|
+
{
|
|
424
|
+
duration: opts.duration,
|
|
425
|
+
easing: opts.easing,
|
|
426
|
+
fill: 'none',
|
|
427
|
+
},
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
private _closeItem = dropTask(async () => {
|
|
432
|
+
// Clear any persisted expand intent for this item — the item is
|
|
433
|
+
// about to be removed from the stack, so the entry on the
|
|
434
|
+
// service map should not linger (would re-apply if a card with
|
|
435
|
+
// the same id ever returned).
|
|
436
|
+
this.operatorModeStateService.setStackItemExpanded(
|
|
437
|
+
this.itemExpandKey,
|
|
438
|
+
false,
|
|
439
|
+
);
|
|
440
|
+
await this.args.dismissStackedCardsAbove(this.args.index - 1);
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
@action private toggleSelect(cardDefOrId: CardDefOrId) {
|
|
444
|
+
const cardId = this.normalizeCardId(cardDefOrId);
|
|
445
|
+
|
|
446
|
+
if (this.selectedCards.has(cardId)) {
|
|
447
|
+
this.selectedCards.delete(cardId);
|
|
448
|
+
} else {
|
|
449
|
+
this.selectedCards.add(cardId);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// pass a copy of the array so that this doesn't become a
|
|
453
|
+
// back door into mutating the state of this component
|
|
454
|
+
this.args.onSelectedCards([...this.selectedCards], this.args.item);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
private clearSelections = () => {
|
|
458
|
+
this.selectedCards.clear();
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
private selectAll = () => {
|
|
462
|
+
// Get all selectable cards from the current view using cardTracker
|
|
463
|
+
const availableCards = this.renderedCardsForOverlayActions.map((entry) =>
|
|
464
|
+
this.normalizeCardId(entry.cardDefOrId),
|
|
465
|
+
);
|
|
466
|
+
|
|
467
|
+
// Add all available cards to the set (Set naturally handles duplicates)
|
|
468
|
+
availableCards.forEach((cardId) => {
|
|
469
|
+
this.selectedCards.add(cardId);
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
// Notify parent component of selection changes
|
|
473
|
+
this.args.onSelectedCards([...this.selectedCards], this.args.item);
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
private confirmAndDeleteSelected = () => {
|
|
477
|
+
this.numberOfCardsToDelete = this.selectedCards.size;
|
|
478
|
+
this.showDeleteModal = true;
|
|
479
|
+
this.deleteError = undefined;
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
private cancelDelete = () => {
|
|
483
|
+
this.showDeleteModal = false;
|
|
484
|
+
this.numberOfCardsToDelete = 0;
|
|
485
|
+
this.deleteError = undefined;
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
private performBulkDelete = async () => {
|
|
489
|
+
this.isDeletingCards = true;
|
|
490
|
+
this.deleteError = undefined;
|
|
491
|
+
|
|
492
|
+
const selectedIds = [...this.selectedCards];
|
|
493
|
+
const failedDeletes: string[] = [];
|
|
494
|
+
let successfulDeletes = 0;
|
|
495
|
+
|
|
496
|
+
try {
|
|
497
|
+
// Delete cards sequentially to avoid overwhelming the server
|
|
498
|
+
for (const cardId of selectedIds) {
|
|
499
|
+
try {
|
|
500
|
+
await this.operatorModeStateService.deleteCard(cardId);
|
|
501
|
+
successfulDeletes++;
|
|
502
|
+
|
|
503
|
+
// Remove successfully deleted card from selection
|
|
504
|
+
this.selectedCards.delete(cardId);
|
|
505
|
+
} catch (error) {
|
|
506
|
+
console.error('Failed to delete card:', error);
|
|
507
|
+
failedDeletes.push(cardId);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// Handle results and show appropriate message
|
|
512
|
+
if (failedDeletes.length === 0) {
|
|
513
|
+
// All deletions successful
|
|
514
|
+
this.showDeleteModal = false;
|
|
515
|
+
this.numberOfCardsToDelete = 0;
|
|
516
|
+
this.selectedCards.clear();
|
|
517
|
+
console.debug(`Successfully deleted ${successfulDeletes} items`);
|
|
518
|
+
} else if (successfulDeletes > 0) {
|
|
519
|
+
// Partial success
|
|
520
|
+
this.deleteError = `Deleted ${successfulDeletes} of ${selectedIds.length} items. ${failedDeletes.length} failed.`;
|
|
521
|
+
// Keep modal open for retry option
|
|
522
|
+
} else {
|
|
523
|
+
// All deletions failed
|
|
524
|
+
this.deleteError = `Failed to delete ${selectedIds.length} items. Please try again.`;
|
|
525
|
+
}
|
|
526
|
+
} catch (error) {
|
|
527
|
+
console.error('Bulk delete operation failed:', error);
|
|
528
|
+
this.deleteError = 'An unexpected error occurred. Please try again.';
|
|
529
|
+
} finally {
|
|
530
|
+
this.isDeletingCards = false;
|
|
531
|
+
|
|
532
|
+
// Notify parent component of selection changes
|
|
533
|
+
this.args.onSelectedCards([...this.selectedCards], this.args.item);
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
private get utilityMenu() {
|
|
538
|
+
if (this.selectedCards.size === 0) {
|
|
539
|
+
return undefined;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
const selectedCount = this.selectedCards.size;
|
|
543
|
+
const availableCards = this.renderedCardsForOverlayActions;
|
|
544
|
+
const totalAvailableCount = availableCards.length;
|
|
545
|
+
const allSelected = selectedCount >= totalAvailableCount;
|
|
546
|
+
|
|
547
|
+
const menuItems: (MenuItem | MenuDivider)[] = [];
|
|
548
|
+
|
|
549
|
+
// Add "Select All" option if not all cards are selected
|
|
550
|
+
if (!allSelected && totalAvailableCount > selectedCount) {
|
|
551
|
+
menuItems.push(
|
|
552
|
+
new MenuItem({
|
|
553
|
+
label: 'Select All',
|
|
554
|
+
icon: SelectAllIcon,
|
|
555
|
+
action: this.selectAll,
|
|
556
|
+
disabled: false,
|
|
557
|
+
}),
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// Add "Deselect All" option
|
|
562
|
+
menuItems.push(
|
|
563
|
+
new MenuItem({
|
|
564
|
+
label: 'Deselect All',
|
|
565
|
+
icon: DeselectIcon,
|
|
566
|
+
action: this.clearSelections,
|
|
567
|
+
}),
|
|
568
|
+
);
|
|
569
|
+
|
|
570
|
+
menuItems.push(new MenuDivider());
|
|
571
|
+
|
|
572
|
+
// Add "Delete N items" option
|
|
573
|
+
menuItems.push(
|
|
574
|
+
new MenuItem({
|
|
575
|
+
label: `Delete ${selectedCount} item${selectedCount > 1 ? 's' : ''}`,
|
|
576
|
+
action: this.confirmAndDeleteSelected,
|
|
577
|
+
icon: IconTrash,
|
|
578
|
+
dangerous: true,
|
|
579
|
+
}),
|
|
580
|
+
);
|
|
581
|
+
|
|
582
|
+
return {
|
|
583
|
+
triggerText: `${selectedCount} Selected`,
|
|
584
|
+
menuItems,
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
private get cardIdentifier() {
|
|
589
|
+
return this.url;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
private get headerType() {
|
|
593
|
+
if (this.isIndexCard) {
|
|
594
|
+
return 'Workspace';
|
|
595
|
+
} else if (this.card) {
|
|
596
|
+
return cardTypeDisplayName(this.card);
|
|
597
|
+
}
|
|
598
|
+
return undefined;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
private get headerTitle() {
|
|
602
|
+
let cardTitle = this.card?.cardTitle;
|
|
603
|
+
if (this.card && cardTitle?.startsWith('Untitled ')) {
|
|
604
|
+
let strippedTitle = cardTitle.slice('Untitled '.length);
|
|
605
|
+
if (strippedTitle === cardTypeDisplayName(this.card)) {
|
|
606
|
+
return 'Untitled';
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
return cardTitle;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
private get cardTitle() {
|
|
614
|
+
return this.card ? this.card.cardTitle : undefined;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
private get moreOptionsMenuItemsForErrorCard() {
|
|
618
|
+
if (this.isBuried) {
|
|
619
|
+
return undefined;
|
|
620
|
+
}
|
|
621
|
+
return [
|
|
622
|
+
new MenuItem({
|
|
623
|
+
label: 'Delete Card',
|
|
624
|
+
action: () =>
|
|
625
|
+
this.cardIdentifier &&
|
|
626
|
+
this.cardCrudFunctions.deleteCard?.(this.cardIdentifier),
|
|
627
|
+
icon: IconTrash,
|
|
628
|
+
dangerous: true,
|
|
629
|
+
disabled: !this.cardCrudFunctions.deleteCard,
|
|
630
|
+
}),
|
|
631
|
+
];
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
private get moreOptionsMenuItems() {
|
|
635
|
+
if (this.isBuried) {
|
|
636
|
+
return undefined;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
const items = toMenuItems(
|
|
640
|
+
this.card?.[getMenuItems]?.({
|
|
641
|
+
canEdit: this.url ? this.realm.canWrite(this.url as string) : false,
|
|
642
|
+
cardCrudFunctions: this.cardCrudFunctions,
|
|
643
|
+
menuContext: 'interact',
|
|
644
|
+
commandContext: this.args.commandContext,
|
|
645
|
+
format: this.cardFormat,
|
|
646
|
+
useBaseTemplate: this.args.item.useBaseTemplate,
|
|
647
|
+
}) ?? [],
|
|
648
|
+
);
|
|
649
|
+
|
|
650
|
+
if (this.isTopCard) {
|
|
651
|
+
let expandItem = new MenuItem({
|
|
652
|
+
label: this.isExpanded ? 'Restore Width' : 'Expand to Full Width',
|
|
653
|
+
icon: Maximize,
|
|
654
|
+
action: this.toggleExpanded,
|
|
655
|
+
});
|
|
656
|
+
let copyAsMarkdownIndex = items.findIndex(
|
|
657
|
+
(item) => item.label === 'Copy as Markdown',
|
|
658
|
+
);
|
|
659
|
+
|
|
660
|
+
if (copyAsMarkdownIndex > -1) {
|
|
661
|
+
items.splice(copyAsMarkdownIndex + 1, 0, expandItem);
|
|
662
|
+
} else {
|
|
663
|
+
items.push(expandItem);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
return items;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
@cached
|
|
671
|
+
private get card() {
|
|
672
|
+
return this.cardResource?.card;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
private get urlForRealmLookup() {
|
|
676
|
+
if (!this.card) {
|
|
677
|
+
throw new Error(
|
|
678
|
+
`bug: cannot determine url for card realm lookup when there is no card. this is likely a template error, card must be present before this is invoked in template`,
|
|
679
|
+
);
|
|
680
|
+
}
|
|
681
|
+
return urlForRealmLookup(this.card);
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
@cached
|
|
685
|
+
private get cardError() {
|
|
686
|
+
return this.cardResource?.cardError;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
private get isWideFormat() {
|
|
690
|
+
if (!this.card) {
|
|
691
|
+
return false;
|
|
692
|
+
}
|
|
693
|
+
let { constructor } = this.card;
|
|
694
|
+
return Boolean(
|
|
695
|
+
constructor &&
|
|
696
|
+
'prefersWideFormat' in constructor &&
|
|
697
|
+
constructor.prefersWideFormat,
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
private get headerColor() {
|
|
702
|
+
if (!this.card) {
|
|
703
|
+
return undefined;
|
|
704
|
+
}
|
|
705
|
+
let cardDef = this.card.constructor;
|
|
706
|
+
if (!cardDef || !('headerColor' in cardDef)) {
|
|
707
|
+
return undefined;
|
|
708
|
+
}
|
|
709
|
+
if (cardDef.headerColor == null) {
|
|
710
|
+
return undefined;
|
|
711
|
+
}
|
|
712
|
+
return cardDef.headerColor as string;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
private doneEditing = () => {
|
|
716
|
+
let item = this.args.item;
|
|
717
|
+
let { request } = item;
|
|
718
|
+
if (this.card) {
|
|
719
|
+
request?.fulfill(this.card.id);
|
|
720
|
+
}
|
|
721
|
+
// Mutate format in place — keeps the StackItem instance, so the
|
|
722
|
+
// CardRenderer subtree stays mounted (no remount, no scroll loss,
|
|
723
|
+
// no width snap from prefersWideFormat re-evaluation) for CardDefs
|
|
724
|
+
// that share a template between isolated + edit formats.
|
|
725
|
+
this.operatorModeStateService.setItemFormat(item, 'isolated', { request });
|
|
726
|
+
};
|
|
727
|
+
|
|
728
|
+
private scrollIntoViewTask = restartableTask(async (selector: string) => {
|
|
729
|
+
if (!this.contentEl || !this.containerEl) {
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
await timeout(500); // need to wait for DOM to update with new card(s)
|
|
733
|
+
|
|
734
|
+
let item = document.querySelector(selector);
|
|
735
|
+
if (!item) {
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
item.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
739
|
+
await timeout(1000);
|
|
740
|
+
// ember-velcro uses visibility: hidden to hide items (vs display: none).
|
|
741
|
+
// visibility:hidden alters the geometry of the DOM elements such that
|
|
742
|
+
// scrollIntoView thinks the container itself is scrollable (it's not) because of
|
|
743
|
+
// the additional height that the hidden velcro-ed items are adding and
|
|
744
|
+
// scrolls the entire container (including the header). this is a workaround
|
|
745
|
+
// to reset the scroll position for the container. I tried adding middleware to alter
|
|
746
|
+
// the hiding behavior for ember-velcro, but for some reason the state
|
|
747
|
+
// used to indicate if the item is visible is not available to middleware...
|
|
748
|
+
this.containerEl.scrollTop = 0;
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
private startAnimation = dropTask(
|
|
752
|
+
async (animationType: 'closing' | 'movingForward') => {
|
|
753
|
+
this.animationType = animationType;
|
|
754
|
+
await new Promise<void>((resolve) => {
|
|
755
|
+
scheduleOnce(
|
|
756
|
+
'afterRender',
|
|
757
|
+
this,
|
|
758
|
+
this.handleAnimationCompletion,
|
|
759
|
+
animationType,
|
|
760
|
+
resolve,
|
|
761
|
+
);
|
|
762
|
+
});
|
|
763
|
+
},
|
|
764
|
+
);
|
|
765
|
+
|
|
766
|
+
private handleAnimationCompletion(
|
|
767
|
+
animationName: 'opening' | 'closing' | 'movingForward',
|
|
768
|
+
resolve?: () => void,
|
|
769
|
+
) {
|
|
770
|
+
if (!this.itemEl) {
|
|
771
|
+
this.clearAnimationType(animationName);
|
|
772
|
+
resolve?.();
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
const animations = this.itemEl.getAnimations?.() ?? [];
|
|
776
|
+
if (animations.length === 0) {
|
|
777
|
+
this.clearAnimationType(animationName);
|
|
778
|
+
resolve?.();
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
781
|
+
Promise.all(animations.map((animation) => animation.finished))
|
|
782
|
+
.then(() => {
|
|
783
|
+
this.clearAnimationType(animationName);
|
|
784
|
+
resolve?.();
|
|
785
|
+
})
|
|
786
|
+
.catch((e) => {
|
|
787
|
+
// AbortError is expected in two scenarios:
|
|
788
|
+
// 1. Multiple stack items are animating in parallel (eg. closing and moving forward)
|
|
789
|
+
// and some elements get removed before their animations complete
|
|
790
|
+
// 2. Tests running with animation-duration: 0s can cause
|
|
791
|
+
// animations to abort before they're properly tracked
|
|
792
|
+
if (e.name === 'AbortError') {
|
|
793
|
+
this.clearAnimationType(animationName);
|
|
794
|
+
resolve?.();
|
|
795
|
+
} else {
|
|
796
|
+
console.error(e);
|
|
797
|
+
}
|
|
798
|
+
});
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
private clearAnimationType(
|
|
802
|
+
animationName: 'opening' | 'closing' | 'movingForward',
|
|
803
|
+
) {
|
|
804
|
+
if (this.animationType === animationName) {
|
|
805
|
+
this.animationType = undefined;
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
private trackOpeningAnimation = () => {
|
|
810
|
+
if (this.animationType !== 'opening') {
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
scheduleOnce('afterRender', this, this.finishOpeningAnimation);
|
|
814
|
+
};
|
|
815
|
+
|
|
816
|
+
private finishOpeningAnimation = () => {
|
|
817
|
+
this.handleAnimationCompletion('opening');
|
|
818
|
+
};
|
|
819
|
+
|
|
820
|
+
private setupContentEl = (el: HTMLElement) => {
|
|
821
|
+
this.contentEl = el;
|
|
822
|
+
};
|
|
823
|
+
|
|
824
|
+
private setupContainerEl = (el: HTMLElement) => {
|
|
825
|
+
this.containerEl = el;
|
|
826
|
+
};
|
|
827
|
+
|
|
828
|
+
private get canEdit() {
|
|
829
|
+
return (
|
|
830
|
+
this.card &&
|
|
831
|
+
this.card[realmURL] &&
|
|
832
|
+
!this.isBuried &&
|
|
833
|
+
!this.isEditing &&
|
|
834
|
+
!this.isFileCard &&
|
|
835
|
+
this.realm.canWrite(this.card[realmURL].href)
|
|
836
|
+
);
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
private get isEditing() {
|
|
840
|
+
return (
|
|
841
|
+
!this.isBuried && !this.isFileCard && this.args.item.format === 'edit'
|
|
842
|
+
);
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
private get isFileCard() {
|
|
846
|
+
return (
|
|
847
|
+
this.args.item.type === 'file' ||
|
|
848
|
+
(this.card ? isFileDefInstance(this.card) : false)
|
|
849
|
+
);
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
private get keyboardShortcutLabels() {
|
|
853
|
+
return {
|
|
854
|
+
// Pencil button in view mode → enter edit (Ctrl+E on every platform;
|
|
855
|
+
// Cmd+E is reserved by browsers for "Use Selection for Find").
|
|
856
|
+
edit: this.isFileCard ? undefined : 'Ctrl+E',
|
|
857
|
+
// Pencil button in edit mode → exit to view (Esc or Ctrl+E).
|
|
858
|
+
finishEditing: this.isFileCard ? undefined : 'Esc or Ctrl+E',
|
|
859
|
+
// Close button: Esc only closes when not editing — in edit mode
|
|
860
|
+
// Esc means "exit edit", so don't claim it in the close tooltip.
|
|
861
|
+
close: this.isEditing ? undefined : 'Esc',
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
private get cardFormat() {
|
|
866
|
+
return this.isFileCard ? 'isolated' : this.args.item.format;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
private get defaultCodeRef() {
|
|
870
|
+
return this.args.item.useBaseTemplate ? baseCardRef : undefined;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
private get showError() {
|
|
874
|
+
// in edit format, prefer showing the stale card if possible so user can
|
|
875
|
+
// attempt to fix the card error
|
|
876
|
+
if (this.cardError && this.args.item.format === 'edit' && this.card) {
|
|
877
|
+
return false;
|
|
878
|
+
}
|
|
879
|
+
return Boolean(this.cardError);
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
private setupItemEl = (el: HTMLElement) => {
|
|
883
|
+
this.itemEl = el;
|
|
884
|
+
this.trackOpeningAnimation();
|
|
885
|
+
};
|
|
886
|
+
|
|
887
|
+
private get doOpeningAnimation() {
|
|
888
|
+
return (
|
|
889
|
+
this.isTopCard &&
|
|
890
|
+
this.animationType === 'opening' &&
|
|
891
|
+
!this.isEditing &&
|
|
892
|
+
!(this.args.item.format === 'isolated' && this.args.item.request) // Skip animation if we have a request and we're in isolated format, it means we're completing an edit operation
|
|
893
|
+
);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
private get doClosingAnimation() {
|
|
897
|
+
return this.animationType === 'closing';
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
private get doMovingForwardAnimation() {
|
|
901
|
+
return this.animationType === 'movingForward';
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
private get isTesting() {
|
|
905
|
+
return isTesting();
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
private setWindowTitle = () => {
|
|
909
|
+
if (this.url && this.cardTitle) {
|
|
910
|
+
this.operatorModeStateService.setCardTitle(this.url, this.cardTitle);
|
|
911
|
+
}
|
|
912
|
+
};
|
|
913
|
+
|
|
914
|
+
private get cardErrorHeaderOptions() {
|
|
915
|
+
if (!this.cardError) {
|
|
916
|
+
return undefined;
|
|
917
|
+
}
|
|
918
|
+
return {
|
|
919
|
+
isTopCard: this.isTopCard,
|
|
920
|
+
moreOptionsMenuItems: this.moreOptionsMenuItemsForErrorCard,
|
|
921
|
+
onClose: !this.isBuried ? this.closeItem : undefined,
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
<template>
|
|
926
|
+
{{consumeContext this.makeCardResource}}
|
|
927
|
+
<div
|
|
928
|
+
class={{cn
|
|
929
|
+
'item'
|
|
930
|
+
buried=this.isBuried
|
|
931
|
+
expanded=this.isExpanded
|
|
932
|
+
opening-animation=this.doOpeningAnimation
|
|
933
|
+
closing-animation=this.doClosingAnimation
|
|
934
|
+
move-forward-animation=this.doMovingForwardAnimation
|
|
935
|
+
testing=this.isTesting
|
|
936
|
+
}}
|
|
937
|
+
data-test-stack-card-index={{@index}}
|
|
938
|
+
data-test-stack-card={{this.cardIdentifier}}
|
|
939
|
+
{{! In order to support scrolling cards into view
|
|
940
|
+
we use a selector that is not pruned out in production builds }}
|
|
941
|
+
data-stack-card={{this.cardIdentifier}}
|
|
942
|
+
style={{this.styleForStackedCard}}
|
|
943
|
+
{{ContentElement onSetup=this.setupItemEl}}
|
|
944
|
+
>
|
|
945
|
+
<CardContainer
|
|
946
|
+
class='stack-item-card'
|
|
947
|
+
style={{cssVar
|
|
948
|
+
card-error-header-height='var(--stack-item-header-height)'
|
|
949
|
+
}}
|
|
950
|
+
{{ContentElement onSetup=this.setupContainerEl}}
|
|
951
|
+
>
|
|
952
|
+
{{#if (not this.cardResource.isLoaded)}}
|
|
953
|
+
<div class='loading' data-test-stack-item-loading-card>
|
|
954
|
+
<LoadingIndicator @color='var(--boxel-dark)' />
|
|
955
|
+
<span class='loading__message'>Loading card...</span>
|
|
956
|
+
</div>
|
|
957
|
+
{{else if this.showError}}
|
|
958
|
+
{{! this is for types--this.cardError is always true in this case !}}
|
|
959
|
+
{{#if this.cardError}}
|
|
960
|
+
<CardError
|
|
961
|
+
@error={{this.cardError}}
|
|
962
|
+
@viewInCodeMode={{true}}
|
|
963
|
+
@headerOptions={{this.cardErrorHeaderOptions}}
|
|
964
|
+
class='stack-item-header'
|
|
965
|
+
style={{cssVar
|
|
966
|
+
boxel-card-header-icon-container-min-width=(if
|
|
967
|
+
this.isBuried '50px' '95px'
|
|
968
|
+
)
|
|
969
|
+
boxel-card-header-actions-min-width=(if
|
|
970
|
+
this.isBuried '50px' '95px'
|
|
971
|
+
)
|
|
972
|
+
boxel-card-header-background-color=this.headerColor
|
|
973
|
+
boxel-card-header-text-color=(getContrastColor this.headerColor)
|
|
974
|
+
realm-icon-background-color=(getContrastColor
|
|
975
|
+
this.headerColor 'transparent'
|
|
976
|
+
)
|
|
977
|
+
realm-icon-border-color=(getContrastColor
|
|
978
|
+
this.headerColor 'transparent' 'rgba(0 0 0 / 15%)'
|
|
979
|
+
)
|
|
980
|
+
}}
|
|
981
|
+
role={{if this.isBuried 'button' 'banner'}}
|
|
982
|
+
{{on
|
|
983
|
+
'click'
|
|
984
|
+
(optional
|
|
985
|
+
(if this.isBuried (fn @dismissStackedCardsAbove @index))
|
|
986
|
+
)
|
|
987
|
+
}}
|
|
988
|
+
data-test-stack-card-header
|
|
989
|
+
/>
|
|
990
|
+
{{/if}}
|
|
991
|
+
{{else if this.card}}
|
|
992
|
+
{{this.setWindowTitle}}
|
|
993
|
+
{{#let (this.realm.info this.urlForRealmLookup) as |realmInfo|}}
|
|
994
|
+
{{#if this.expandedCardHeaderSlot}}
|
|
995
|
+
{{#in-element this.expandedCardHeaderSlot}}
|
|
996
|
+
<CardHeader
|
|
997
|
+
@cardTypeDisplayName={{this.headerType}}
|
|
998
|
+
@cardTypeIcon={{cardTypeIcon this.card}}
|
|
999
|
+
@cardTitle={{this.headerTitle}}
|
|
1000
|
+
@isSaving={{this.cardResource.autoSaveState.isSaving}}
|
|
1001
|
+
@isTopCard={{this.isTopCard}}
|
|
1002
|
+
@lastSavedMessage={{this.cardResource.autoSaveState.lastSavedErrorMsg}}
|
|
1003
|
+
@moreOptionsMenuItems={{this.moreOptionsMenuItems}}
|
|
1004
|
+
@realmInfo={{realmInfo}}
|
|
1005
|
+
@utilityMenu={{this.utilityMenu}}
|
|
1006
|
+
@onEdit={{if
|
|
1007
|
+
this.canEdit
|
|
1008
|
+
(fn this.cardCrudFunctions.editCard this.card)
|
|
1009
|
+
}}
|
|
1010
|
+
@onExpand={{if this.isExpanded this.toggleExpanded}}
|
|
1011
|
+
@isExpanded={{this.isExpanded}}
|
|
1012
|
+
@onFinishEditing={{if this.isEditing this.doneEditing}}
|
|
1013
|
+
@onClose={{unless this.isBuried this.closeItem}}
|
|
1014
|
+
class='expanded-card-header-pill'
|
|
1015
|
+
data-test-stack-card-header
|
|
1016
|
+
/>
|
|
1017
|
+
{{/in-element}}
|
|
1018
|
+
{{else}}
|
|
1019
|
+
<CardHeader
|
|
1020
|
+
@cardTypeDisplayName={{this.headerType}}
|
|
1021
|
+
@cardTypeIcon={{cardTypeIcon this.card}}
|
|
1022
|
+
@cardTitle={{this.headerTitle}}
|
|
1023
|
+
@isSaving={{this.cardResource.autoSaveState.isSaving}}
|
|
1024
|
+
@isTopCard={{this.isTopCard}}
|
|
1025
|
+
@lastSavedMessage={{this.cardResource.autoSaveState.lastSavedErrorMsg}}
|
|
1026
|
+
@moreOptionsMenuItems={{this.moreOptionsMenuItems}}
|
|
1027
|
+
@realmInfo={{realmInfo}}
|
|
1028
|
+
@utilityMenu={{this.utilityMenu}}
|
|
1029
|
+
@onEdit={{if
|
|
1030
|
+
this.canEdit
|
|
1031
|
+
(fn this.cardCrudFunctions.editCard this.card)
|
|
1032
|
+
}}
|
|
1033
|
+
@onExpand={{if this.isExpanded this.toggleExpanded}}
|
|
1034
|
+
@isExpanded={{this.isExpanded}}
|
|
1035
|
+
@onFinishEditing={{if this.isEditing this.doneEditing}}
|
|
1036
|
+
@onClose={{unless this.isBuried this.closeItem}}
|
|
1037
|
+
@editShortcutHint={{this.keyboardShortcutLabels.edit}}
|
|
1038
|
+
@finishEditingShortcutHint={{this.keyboardShortcutLabels.finishEditing}}
|
|
1039
|
+
@closeShortcutHint={{this.keyboardShortcutLabels.close}}
|
|
1040
|
+
class='stack-item-header'
|
|
1041
|
+
style={{cssVar
|
|
1042
|
+
boxel-card-header-icon-container-min-width=(if
|
|
1043
|
+
this.isBuried '50px' '95px'
|
|
1044
|
+
)
|
|
1045
|
+
boxel-card-header-actions-min-width=(if
|
|
1046
|
+
this.isBuried '50px' '95px'
|
|
1047
|
+
)
|
|
1048
|
+
boxel-card-header-background-color=this.headerColor
|
|
1049
|
+
boxel-card-header-text-color=(getContrastColor
|
|
1050
|
+
this.headerColor
|
|
1051
|
+
)
|
|
1052
|
+
realm-icon-background-color=(getContrastColor
|
|
1053
|
+
this.headerColor 'transparent'
|
|
1054
|
+
)
|
|
1055
|
+
realm-icon-border-color=(getContrastColor
|
|
1056
|
+
this.headerColor 'transparent' 'rgba(0 0 0 / 15%)'
|
|
1057
|
+
)
|
|
1058
|
+
}}
|
|
1059
|
+
role={{if this.isBuried 'button' 'banner'}}
|
|
1060
|
+
{{on
|
|
1061
|
+
'click'
|
|
1062
|
+
(optional
|
|
1063
|
+
(if this.isBuried (fn @dismissStackedCardsAbove @index))
|
|
1064
|
+
)
|
|
1065
|
+
}}
|
|
1066
|
+
data-test-stack-card-header
|
|
1067
|
+
/>
|
|
1068
|
+
{{/if}}
|
|
1069
|
+
{{/let}}
|
|
1070
|
+
<div
|
|
1071
|
+
class='stack-item-content'
|
|
1072
|
+
{{ContentElement onSetup=this.setupContentEl}}
|
|
1073
|
+
data-test-stack-item-content
|
|
1074
|
+
>
|
|
1075
|
+
<CardRenderer
|
|
1076
|
+
class='stack-item-preview'
|
|
1077
|
+
@card={{this.card}}
|
|
1078
|
+
@format={{this.cardFormat}}
|
|
1079
|
+
@codeRef={{this.defaultCodeRef}}
|
|
1080
|
+
/>
|
|
1081
|
+
<OperatorModeOverlays
|
|
1082
|
+
@renderedCardsForOverlayActions={{this.renderedCardsForOverlayActions}}
|
|
1083
|
+
@requestDeleteCard={{@requestDeleteCard}}
|
|
1084
|
+
@toggleSelect={{this.toggleSelect}}
|
|
1085
|
+
@selectedCards={{this.selectedCards}}
|
|
1086
|
+
@viewCard={{this.cardCrudFunctions.viewCard}}
|
|
1087
|
+
/>
|
|
1088
|
+
</div>
|
|
1089
|
+
{{/if}}
|
|
1090
|
+
</CardContainer>
|
|
1091
|
+
</div>
|
|
1092
|
+
<style scoped>
|
|
1093
|
+
:global(:root) {
|
|
1094
|
+
--stack-card-footer-height: 6rem;
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
@keyframes scaleIn {
|
|
1098
|
+
from {
|
|
1099
|
+
transform: scale(0.1);
|
|
1100
|
+
opacity: 0;
|
|
1101
|
+
}
|
|
1102
|
+
to {
|
|
1103
|
+
transform: scale(1);
|
|
1104
|
+
opacity: 1;
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
@keyframes fadeOut {
|
|
1108
|
+
from {
|
|
1109
|
+
opacity: 1;
|
|
1110
|
+
transform: translateY(0);
|
|
1111
|
+
}
|
|
1112
|
+
to {
|
|
1113
|
+
opacity: 0;
|
|
1114
|
+
transform: translateY(100%);
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
@keyframes moveForward {
|
|
1119
|
+
from {
|
|
1120
|
+
transform: translateY(0);
|
|
1121
|
+
opacity: 0.8;
|
|
1122
|
+
}
|
|
1123
|
+
to {
|
|
1124
|
+
transform: translateY(25px);
|
|
1125
|
+
opacity: 1;
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
.item {
|
|
1130
|
+
--stack-item-header-height: 3rem;
|
|
1131
|
+
justify-self: center;
|
|
1132
|
+
position: absolute;
|
|
1133
|
+
width: 89%;
|
|
1134
|
+
height: inherit;
|
|
1135
|
+
z-index: 0;
|
|
1136
|
+
pointer-events: none;
|
|
1137
|
+
transition:
|
|
1138
|
+
margin-top var(--boxel-transition),
|
|
1139
|
+
width var(--boxel-transition);
|
|
1140
|
+
}
|
|
1141
|
+
.item.opening-animation {
|
|
1142
|
+
animation: scaleIn 0.2s forwards;
|
|
1143
|
+
}
|
|
1144
|
+
.item.closing-animation {
|
|
1145
|
+
animation: fadeOut 0.2s forwards;
|
|
1146
|
+
}
|
|
1147
|
+
.item.move-forward-animation {
|
|
1148
|
+
animation: moveForward 0.2s none;
|
|
1149
|
+
}
|
|
1150
|
+
.item.opening-animation.testing {
|
|
1151
|
+
animation-duration: 0s;
|
|
1152
|
+
}
|
|
1153
|
+
.item.closing-animation.testing {
|
|
1154
|
+
animation-duration: 0s;
|
|
1155
|
+
}
|
|
1156
|
+
.item.move-forward-animation.testing {
|
|
1157
|
+
animation-duration: 0s;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
.item.buried {
|
|
1161
|
+
--stack-item-header-height: 2.5rem;
|
|
1162
|
+
--realm-icon-border-radius: 4px;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
.item.expanded {
|
|
1166
|
+
top: 0;
|
|
1167
|
+
left: 0;
|
|
1168
|
+
width: 100%;
|
|
1169
|
+
pointer-events: auto;
|
|
1170
|
+
}
|
|
1171
|
+
/* Propagate height through the chain so bottom-docked chrome
|
|
1172
|
+
lands at the viewport's bottom edge. .stack-item-content
|
|
1173
|
+
and .stack-item-preview default to overflow: auto with no
|
|
1174
|
+
height — without min-height: 0 the chain breaks and the
|
|
1175
|
+
studio's flex: 1 has no defined parent height. Keep
|
|
1176
|
+
overflow: auto (matches host-mode pattern) so isolated
|
|
1177
|
+
content longer than the viewport can scroll. */
|
|
1178
|
+
.item.expanded .stack-item-content,
|
|
1179
|
+
.item.expanded .stack-item-preview {
|
|
1180
|
+
min-height: 0;
|
|
1181
|
+
}
|
|
1182
|
+
.item.expanded .stack-item-card {
|
|
1183
|
+
border-radius: 0;
|
|
1184
|
+
box-shadow: none;
|
|
1185
|
+
/* Tray "chrome" (rounded corners, shadow, white background)
|
|
1186
|
+
all dissolve at end of morph — the tray becomes a
|
|
1187
|
+
positioning anchor only. Body content (.stack-item-content)
|
|
1188
|
+
inside renders normally without inheriting transparency
|
|
1189
|
+
because background, not opacity, is what's faded. */
|
|
1190
|
+
background: transparent;
|
|
1191
|
+
/* Header is portaled into the top bar pill (see
|
|
1192
|
+
expanded-card-header-slot in submode-layout); the inline
|
|
1193
|
+
CardHeader is not rendered for expanded cards (the if/else
|
|
1194
|
+
in the template picks the in-element branch). Drop the
|
|
1195
|
+
grid header row so the body fills the entire card. */
|
|
1196
|
+
grid-template-rows: 1fr;
|
|
1197
|
+
}
|
|
1198
|
+
/* When the top card is expanded, fade out the underlying
|
|
1199
|
+
buried cards so the user isn't visually distracted by the
|
|
1200
|
+
stack history behind the expanded surface. Sibling selector
|
|
1201
|
+
within .operator-mode-stack > .inner; uses :has() to match
|
|
1202
|
+
buried items that have an expanded sibling AFTER them in the
|
|
1203
|
+
DOM (top card = last in DOM order). */
|
|
1204
|
+
.item:not(.expanded):has(~ .item.expanded) {
|
|
1205
|
+
opacity: 0;
|
|
1206
|
+
transition: opacity 380ms ease;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
.stack-item-card {
|
|
1210
|
+
position: relative;
|
|
1211
|
+
height: 100%;
|
|
1212
|
+
display: grid;
|
|
1213
|
+
grid-template-rows: var(--stack-item-header-height) auto;
|
|
1214
|
+
border-radius: var(--boxel-border-radius-xl);
|
|
1215
|
+
box-shadow: var(--boxel-deep-box-shadow);
|
|
1216
|
+
pointer-events: auto;
|
|
1217
|
+
overflow: hidden;
|
|
1218
|
+
}
|
|
1219
|
+
.stack-item-header {
|
|
1220
|
+
--boxel-card-header-padding: var(--boxel-sp-4xs) var(--boxel-sp-xs);
|
|
1221
|
+
border-radius: 0;
|
|
1222
|
+
z-index: 1;
|
|
1223
|
+
max-width: max-content;
|
|
1224
|
+
height: var(--stack-item-header-height);
|
|
1225
|
+
min-width: 100%;
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
.stack-item-content {
|
|
1229
|
+
overflow: auto;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
.stack-item-preview {
|
|
1233
|
+
border-radius: 0;
|
|
1234
|
+
box-shadow: none;
|
|
1235
|
+
overflow: auto;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
.buried > .stack-item-card {
|
|
1239
|
+
border-radius: var(--boxel-border-radius-lg);
|
|
1240
|
+
background-color: var(--boxel-200);
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
.buried .stack-item-header {
|
|
1244
|
+
font: 600 var(--boxel-font-xs);
|
|
1245
|
+
gap: var(--boxel-sp-xxxs);
|
|
1246
|
+
--boxel-card-header-text-font: var(--boxel-font-size-xs);
|
|
1247
|
+
--boxel-card-header-realm-icon-size: var(--boxel-icon-sm);
|
|
1248
|
+
--boxel-card-header-card-type-icon-size: var(--boxel-icon-xs);
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
.buried .stack-item-content {
|
|
1252
|
+
display: none;
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
.loading {
|
|
1256
|
+
grid-area: 2;
|
|
1257
|
+
display: flex;
|
|
1258
|
+
justify-content: center;
|
|
1259
|
+
align-items: center;
|
|
1260
|
+
height: calc(100% - var(--stack-item-header-height));
|
|
1261
|
+
padding: var(--boxel-sp);
|
|
1262
|
+
color: var(--boxel-dark);
|
|
1263
|
+
|
|
1264
|
+
--icon-color: var(--boxel-dark);
|
|
1265
|
+
}
|
|
1266
|
+
.loading__message {
|
|
1267
|
+
margin-left: var(--boxel-sp-5xs);
|
|
1268
|
+
}
|
|
1269
|
+
.loading :deep(.boxel-loading-indicator) {
|
|
1270
|
+
display: flex;
|
|
1271
|
+
justify: center;
|
|
1272
|
+
align-items: center;
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
/* The portaled CardHeader inside takes pill styling — white
|
|
1276
|
+
rounded box, realm icon left-docked, actions right-docked,
|
|
1277
|
+
left-justified type/title. Reuses CardHeader's existing
|
|
1278
|
+
actions structure; just re-skinned via this class. */
|
|
1279
|
+
.expanded-card-header-pill {
|
|
1280
|
+
--boxel-card-header-padding: var(--boxel-sp-4xs)
|
|
1281
|
+
var(--operator-mode-spacing);
|
|
1282
|
+
--boxel-card-header-gap: var(--operator-mode-spacing);
|
|
1283
|
+
height: var(--container-button-size);
|
|
1284
|
+
background: var(--boxel-light);
|
|
1285
|
+
border-radius: var(--boxel-border-radius-2xl);
|
|
1286
|
+
box-shadow: var(--submode-bar-item-box-shadow);
|
|
1287
|
+
outline: var(--submode-bar-item-outline);
|
|
1288
|
+
}
|
|
1289
|
+
/* Title in the expanded pill stays left-justified inside the
|
|
1290
|
+
center column (overrides CardHeader's default text-align: center). */
|
|
1291
|
+
.expanded-card-header-pill :deep(.card-type-display-name) {
|
|
1292
|
+
text-align: left;
|
|
1293
|
+
text-box-trim: trim-both;
|
|
1294
|
+
}
|
|
1295
|
+
/* Pencil button in expanded edit mode — solid green with dark
|
|
1296
|
+
icon for contrast (matches the active expand button). */
|
|
1297
|
+
.expanded-card-header-pill :deep(.icon-save),
|
|
1298
|
+
.expanded-card-header-pill :deep(.icon-save:hover) {
|
|
1299
|
+
background-color: var(--boxel-highlight);
|
|
1300
|
+
color: var(--boxel-dark);
|
|
1301
|
+
}
|
|
1302
|
+
</style>
|
|
1303
|
+
|
|
1304
|
+
{{! Delete confirmation modal }}
|
|
1305
|
+
{{#if this.showDeleteModal}}
|
|
1306
|
+
<DeleteModal
|
|
1307
|
+
@itemToDelete={{hash
|
|
1308
|
+
id='bulk-delete'
|
|
1309
|
+
selectedCount=this.numberOfCardsToDelete
|
|
1310
|
+
}}
|
|
1311
|
+
@isDeleteRunning={{this.isDeletingCards}}
|
|
1312
|
+
@error={{this.deleteError}}
|
|
1313
|
+
@onConfirm={{this.performBulkDelete}}
|
|
1314
|
+
@onCancel={{this.cancelDelete}}
|
|
1315
|
+
>
|
|
1316
|
+
<:content>
|
|
1317
|
+
Delete
|
|
1318
|
+
{{this.numberOfCardsToDelete}}
|
|
1319
|
+
{{pluralize 'card' this.numberOfCardsToDelete}}?
|
|
1320
|
+
</:content>
|
|
1321
|
+
</DeleteModal>
|
|
1322
|
+
{{/if}}
|
|
1323
|
+
</template>
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
interface ContentElementSignature {
|
|
1327
|
+
Args: {
|
|
1328
|
+
Named: {
|
|
1329
|
+
onSetup: (element: HTMLElement) => void;
|
|
1330
|
+
};
|
|
1331
|
+
};
|
|
1332
|
+
}
|
|
1333
|
+
class ContentElement extends Modifier<ContentElementSignature> {
|
|
1334
|
+
modify(
|
|
1335
|
+
element: HTMLElement,
|
|
1336
|
+
_positional: [],
|
|
1337
|
+
{ onSetup }: ContentElementSignature['Args']['Named'],
|
|
1338
|
+
) {
|
|
1339
|
+
onSetup(element);
|
|
1340
|
+
}
|
|
1341
|
+
}
|