Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions .github/workflows/ci-lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: CI Lint

on:
push:
branches: [main]
pull_request:

permissions:
checks: write
contents: read
id-token: write
pull-requests: write

jobs:
lint:
name: Lint
runs-on: ubuntu-latest
concurrency:
group: lint-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
steps:
# Checkout the boxel monorepo at root to get tooling and init action
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
with:
repository: cardstack/boxel

# Checkout this catalog repo into a temp location
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
with:
path: boxel-catalog-src

# Copy catalog files into the monorepo's catalog-realm location
- name: Copy catalog files into monorepo
run: |
# TODO: Simplify this step once catalog-realm content is fully migrated out of the monorepo
# Remove all files except config files we want to keep
cd packages/catalog-realm
find . -mindepth 1 \
! -name '.gitignore' \
! -name 'tsconfig.json' \
! -name 'package.json' \
! -name '.realm.json' \
! -name '.' \
-exec rm -rf {} + 2>/dev/null || true
cd ../..

# Copy catalog files
cp -r boxel-catalog-src/* packages/catalog-realm/

- uses: ./.github/actions/init

# Boxel UI and Boxel Icons need to be built first so that their
# linting outputs types are available for projects that depend on them
- name: Build common dependencies
if: always()
run: pnpm run build-common-deps

- name: Lint Catalog
if: always()
run: pnpm run lint
working-directory: packages/catalog-realm

- name: Lint Host
if: always()
run: pnpm run lint
working-directory: packages/host
51 changes: 42 additions & 9 deletions catalog-app/listing/listing.gts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
Component,
instanceOf,
realmURL,
type GetCardMenuItemParams,
type GetMenuItemParams,
} from 'https://cardstack.com/base/card-api';
import { commandData } from 'https://cardstack.com/base/resources/command-data';
import MarkdownField from 'https://cardstack.com/base/markdown';
Expand All @@ -34,6 +34,7 @@ import {
import { eq, type MenuItemOptions } from '@cardstack/boxel-ui/helpers';
import Refresh from '@cardstack/boxel-icons/refresh';
import Wand from '@cardstack/boxel-icons/wand';
import Package from '@cardstack/boxel-icons/package';

import AppListingHeader from '../components/app-listing-header';
import ChooseRealmAction from '../components/choose-realm-action';
Expand All @@ -44,8 +45,9 @@ import { listingActions, isReady } from '../resources/listing-actions';
import GetAllRealmMetasCommand from '@cardstack/boxel-host/commands/get-all-realm-metas';
import ListingGenerateExampleCommand from '@cardstack/boxel-host/commands/listing-generate-example';
import ListingUpdateSpecsCommand from '@cardstack/boxel-host/commands/listing-update-specs';
import CreateListingPRCommand from '@cardstack/boxel-host/commands/create-listing-pr';

import { getCardMenuItems } from '@cardstack/runtime-common';
import { getMenuItems } from '@cardstack/runtime-common';

import { Publisher } from './publisher';
import { Category } from './category';
Expand Down Expand Up @@ -180,9 +182,9 @@ class EmbeddedTemplate extends Component<typeof Listing> {
<template>
<div class='app-listing-embedded'>
<AppListingHeader
@thumbnailUrl={{@model.thumbnailURL}}
@thumbnailUrl={{@model.cardThumbnailURL}}
@name={{this.appName}}
@description={{@model.description}}
@description={{@model.cardDescription}}
@publisher={{this.publisherName}}
>
<:action>
Expand Down Expand Up @@ -562,6 +564,7 @@ class EmbeddedTemplate extends Component<typeof Listing> {
export class Listing extends CardDef {
static displayName = 'Listing';
static headerColor = '#6638ff';

@field name = contains(StringField);
@field summary = contains(MarkdownField);
@field specs = linksToMany(() => Spec);
Expand All @@ -573,14 +576,14 @@ export class Listing extends CardDef {
@field examples = linksToMany(() => CardDef);
@field skills = linksToMany(() => Skill);

@field title = contains(StringField, {
@field cardTitle = contains(StringField, {
computeVia(this: Listing) {
return this.name;
},
});

protected getGenerateExampleMenuItem(
params: GetCardMenuItemParams,
params: GetMenuItemParams,
): MenuItemOptions | undefined {
if (!params.commandContext) {
return undefined;
Expand Down Expand Up @@ -613,7 +616,7 @@ export class Listing extends CardDef {
}

private getUpdateSpecsMenuItem(
params: GetCardMenuItemParams,
params: GetMenuItemParams,
): MenuItemOptions | undefined {
if (params.menuContext !== 'interact') {
return;
Expand All @@ -635,9 +638,9 @@ export class Listing extends CardDef {
};
}

[getCardMenuItems](params: GetCardMenuItemParams): MenuItemOptions[] {
[getMenuItems](params: GetMenuItemParams): MenuItemOptions[] {
let menuItems = super
[getCardMenuItems](params)
[getMenuItems](params)
.filter((item) => item.label?.toLowerCase() !== 'create listing with ai');
if (params.menuContext === 'interact') {
const extra = this.getGenerateExampleMenuItem(params);
Expand All @@ -648,10 +651,40 @@ export class Listing extends CardDef {
if (updateSpecs) {
menuItems = [...menuItems, updateSpecs];
}
const createPRMenuItem = this.getCreatePRMenuItem(params);
if (createPRMenuItem) {
menuItems = [...menuItems, createPRMenuItem];
}
}
return menuItems;
}

private getCreatePRMenuItem(
params: GetMenuItemParams,
): MenuItemOptions | undefined {
if (params.menuContext !== 'interact') {
return;
}
if (!this[realmURL]?.href) {
return;
}
const commandContext = params.commandContext;
if (!commandContext) {
return;
}

return {
label: 'Make a PR',
action: async () => {
await new CreateListingPRCommand(commandContext).execute({
listing: this,
realm: this[realmURL]!.href,
});
},
icon: Package,
};
}

static isolated = EmbeddedTemplate;
static embedded = EmbeddedTemplate;
static fitted = ListingFittedTemplate;
Expand Down
22 changes: 22 additions & 0 deletions cloudflare-image.gts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import ImageCard from 'https://cardstack.com/base/image';
import { contains, field } from 'https://cardstack.com/base/card-api';
import StringField from 'https://cardstack.com/base/string';
import UrlField from 'https://cardstack.com/base/url';

export const CLOUDFLARE_ACCOUNT_ID = '4a94a1eb2d21bbbe160234438a49f687';

const CLOUDFLARE_VARIANT = 'public';

export class CloudflareImage extends ImageCard {
static displayName = 'Cloudflare Image';

@field cloudflareId = contains(StringField);
@field url = contains(UrlField, {
computeVia(this: CloudflareImage) {
if (!this.cloudflareId) {
return undefined;
}
return `https://i.boxel.site/${this.cloudflareId}/${CLOUDFLARE_VARIANT}`;
},
});
}
Loading