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
4 changes: 4 additions & 0 deletions packages/base/workspace.gts
Original file line number Diff line number Diff line change
Expand Up @@ -249,23 +249,27 @@ class Isolated extends Component<typeof Workspace> {
<template>
<section
class='card-grid'
data-test-workspace-index
{{this.setupRealmSubscription this.primaryRealm}}
>
<header class='frame'>
<nav class='tabs' aria-label='Sections'>
<button
type='button'
class='tab {{if (eq this.segment "home") "active"}}'
data-test-workspace-tab='home'
{{on 'click' (this.setSegment 'home')}}
><HouseIcon class='tab-icon' /> Home</button>
<button
type='button'
class='tab {{if (eq this.segment "library") "active"}}'
data-test-workspace-tab='library'
{{on 'click' (this.setSegment 'library')}}
><LayoutGridIcon class='tab-icon' /> Library</button>
<button
type='button'
class='tab {{if (eq this.segment "activity") "active"}}'
data-test-workspace-tab='activity'
{{on 'click' (this.setSegment 'activity')}}
><ActivityIcon class='tab-icon' />
Activity{{#if this.runningJobs.length}}<span
Expand Down
25 changes: 20 additions & 5 deletions packages/matrix/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -450,12 +450,27 @@ export async function enterWorkspace(
}

export async function showAllCards(page: Page) {
// A realm's index is either the legacy CardsGrid — whose "All Cards" filter
// lists every card — or the default Workspace, whose Library tab renders the
// same live card grid. `.count()` is point-in-time, so wait for the index to
// render one of its browse affordances before deciding; checking right after
// a `goto` would otherwise miss both and silently no-op. A bespoke index has
// neither — leave it be.
let allCardsFilter = page.locator(
`[data-test-boxel-filter-list-button="All Cards"]`,
);
let libraryTab = page.locator(`[data-test-workspace-tab="library"]`);
try {
await page
.locator(`[data-test-boxel-filter-list-button="All Cards"]`)
.click();
} catch (e) {
console.warn('all cards filter is not found');
await allCardsFilter.or(libraryTab).first().waitFor({ timeout: 30_000 });
} catch {
return;
}
if ((await allCardsFilter.count()) > 0) {
await allCardsFilter.click();
return;
}
if ((await libraryTab.count()) > 0) {
await libraryTab.click();
}
Comment thread
lukemelia marked this conversation as resolved.
}

Expand Down
5 changes: 2 additions & 3 deletions packages/matrix/tests/create-realm.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ test.describe('Create Realm via Dashboard', () => {
await expect(
page.locator(`[data-test-stack-card="${newRealmURL}index"]`),
).toBeVisible();
await expect(
page.locator(`[data-test-boxel-filter-list-button]`),
).toHaveCount(3);
// A newly created realm defaults to a Workspace index card.
await expect(page.locator(`[data-test-workspace-index]`)).toBeVisible();

await page.locator('[data-test-submode-switcher] button').click();
await page.locator('[data-test-boxel-menu-item-text="Host"]').click();
Expand Down
19 changes: 9 additions & 10 deletions packages/matrix/tests/live-cards.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,7 @@ test.describe('Live Cards', () => {
await page.goto(realmURL);
await showAllCards(page);

await expect(
page.locator(`[data-test-boxel-filter-list-button="All Cards"]`),
).toHaveCount(1);
await expect(page.locator(`[data-test-cards-grid-cards]`)).toBeVisible();

await postCardSource(
page,
Expand Down Expand Up @@ -228,14 +226,15 @@ test.describe('Live Cards', () => {
const realmURL = new URL(`${username}/${realmName}/`, serverIndexUrl).href;
await createRealm(page, realmName);

// Land on the realm's grid so the create-new-card affordance is present.
// Open the card chooser via the operator-mode "New" button — an
// index-agnostic affordance, so this doesn't depend on whether the realm
// index is a CardsGrid or a Workspace. Its "Choose a card type..." item
// opens the same chooser CardsGrid's create button did.
await page.goto(realmURL);
await showAllCards(page);
await expect(
page.locator(`[data-test-boxel-filter-list-button="All Cards"]`),
).toHaveCount(1);

await page.locator('[data-test-create-new-card-button]').click();
await page.locator('[data-test-new-file-button]').click();
await page
.locator('[data-test-boxel-menu-item-text="Choose a card type..."]')
.click();
await expect(page.locator('[data-test-card-chooser-modal]')).toBeVisible();
await expect(page.locator('[data-test-item-button]').first()).toBeVisible();

Expand Down
14 changes: 10 additions & 4 deletions packages/matrix/tests/skills.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,12 @@ test.describe('Skills', () => {
await page.goto(realmURL);
await showAllCards(page);

// create a skill card
await page.locator('[data-test-create-new-card-button]').click();
// create a skill card — open the chooser via the index-agnostic
// operator-mode "New" button rather than the CardsGrid-only + button.
await page.locator('[data-test-new-file-button]').click();
await page
.locator('[data-test-boxel-menu-item-text="Choose a card type..."]')
.click();
await page.locator('[data-test-search-field]').fill('Skill');
await page
.locator(
Expand Down Expand Up @@ -423,8 +427,10 @@ test.describe('Skills', () => {
)
.waitFor();

// Update the uploaded skill card
await page.locator('[data-test-filter-list-item="Skill"]').click();
// Update the uploaded skill card — reach the realm's card grid (CardsGrid's
// "All Cards" or the Workspace Library) and open the skill directly by its
// id, rather than the CardsGrid-only "Skill" type filter.
await showAllCards(page);
await page.locator(`[data-cards-grid-item="${skillCard}"]`).click();
await page.locator('[data-test-edit-button]').click();
await page
Expand Down
8 changes: 6 additions & 2 deletions packages/matrix/tests/tools.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,12 @@ test.describe('Commands', () => {
await page.goto(realmURL);
await showAllCards(page);

// create a skill card
await page.locator('[data-test-create-new-card-button]').click();
// create a skill card — open the chooser via the index-agnostic
// operator-mode "New" button rather than the CardsGrid-only + button.
await page.locator('[data-test-new-file-button]').click();
await page
.locator('[data-test-boxel-menu-item-text="Choose a card type..."]')
.click();
await page.locator('[data-test-search-field]').fill('Skill');
await page
.locator(
Expand Down
4 changes: 2 additions & 2 deletions packages/realm-server/handlers/create-realm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ export async function createRealm(
type: 'card',
meta: {
adoptsFrom: {
module: '@cardstack/base/cards-grid',
name: 'CardsGrid',
module: '@cardstack/base/workspace',
Comment thread
lukemelia marked this conversation as resolved.
name: 'Workspace',
Comment thread
lukemelia marked this conversation as resolved.
},
},
},
Expand Down
37 changes: 19 additions & 18 deletions packages/realm-server/tests/publish-unpublish-realm-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ module(basename(import.meta.filename), function () {
);
});

test('publishing a realm with the default CardsGrid index writes includePrerenderedDefaultRealmIndex into the published realm.json', async function (assert) {
test('publishing a realm with the default Workspace index writes includePrerenderedDefaultRealmIndex into the published realm.json', async function (assert) {
let response = await request
.post('/_publish-realm')
.set('Accept', 'application/vnd.api+json')
Expand All @@ -546,7 +546,7 @@ module(basename(import.meta.filename), function () {
JSON.stringify({
sourceRealmURL: sourceRealmUrlString,
publishedRealmURL:
'http://testuser.localhost:4445/cards-grid-default/',
'http://testuser.localhost:4445/workspace-default/',
}),
);
assert.strictEqual(response.status, 202, 'HTTP 202 status');
Expand Down Expand Up @@ -574,12 +574,12 @@ module(basename(import.meta.filename), function () {
);
});

test('publishing a realm whose index.json is not a CardsGrid leaves the published realm.json untouched', async function (assert) {
test('publishing a realm whose index.json is a bespoke card leaves the published realm.json untouched', async function (assert) {
let sourceRealmPath = new URL(sourceRealmUrlString).pathname;

// Replace the source realm's default CardsGrid index with a
// bespoke CardDef-adopting index so the publish handler should
// NOT set the opt-in flag.
// Replace the source realm's default index with a bespoke
// CardDef-adopting index (neither CardsGrid nor Workspace) so the
// publish handler should NOT set the opt-in flag.
let customIndexResponse = await request
.post(`${sourceRealmPath}index.json`)
.set('Accept', 'application/vnd.card+source')
Expand All @@ -600,7 +600,7 @@ module(basename(import.meta.filename), function () {
assert.strictEqual(
customIndexResponse.status,
204,
'custom non-CardsGrid index.json can be written',
'bespoke non-default index.json can be written',
);

let response = await request
Expand Down Expand Up @@ -642,16 +642,17 @@ module(basename(import.meta.filename), function () {
publishedRealmConfig?.data?.attributes
?.includePrerenderedDefaultRealmIndex,
true,
'published realm.json does NOT carry includePrerenderedDefaultRealmIndex when the source index is a non-CardsGrid card',
'published realm.json does NOT carry includePrerenderedDefaultRealmIndex when the source index is a bespoke, non-default card',
);
});

test('publishing a realm whose index adopts the default Workspace card writes includePrerenderedDefaultRealmIndex into the published realm.json', async function (assert) {
test('publishing a realm whose index adopts the legacy CardsGrid card writes includePrerenderedDefaultRealmIndex into the published realm.json', async function (assert) {
let sourceRealmPath = new URL(sourceRealmUrlString).pathname;

// Point the source realm's index at the base Workspace card — the
// other recognized default index besides CardsGrid.
let workspaceIndexResponse = await request
// Workspace is the default index now, so point this realm's index at
// the legacy CardsGrid card explicitly — it is still recognized as a
// default index alongside Workspace.
let cardsGridIndexResponse = await request
.post(`${sourceRealmPath}index.json`)
.set('Accept', 'application/vnd.card+source')
.send(
Expand All @@ -661,17 +662,17 @@ module(basename(import.meta.filename), function () {
attributes: {},
meta: {
adoptsFrom: {
module: '@cardstack/base/workspace',
name: 'Workspace',
module: '@cardstack/base/cards-grid',
name: 'CardsGrid',
},
},
},
}),
);
assert.strictEqual(
workspaceIndexResponse.status,
cardsGridIndexResponse.status,
204,
'Workspace index.json can be written',
'CardsGrid index.json can be written',
);

let response = await request
Expand All @@ -689,7 +690,7 @@ module(basename(import.meta.filename), function () {
JSON.stringify({
sourceRealmURL: sourceRealmUrlString,
publishedRealmURL:
'http://testuser.localhost:4445/workspace-default/',
'http://testuser.localhost:4445/cards-grid-legacy/',
}),
);
assert.strictEqual(response.status, 202, 'HTTP 202 status');
Expand All @@ -713,7 +714,7 @@ module(basename(import.meta.filename), function () {
assert.true(
publishedRealmConfig?.data?.attributes
?.includePrerenderedDefaultRealmIndex,
'published realm.json carries includePrerenderedDefaultRealmIndex: true for a Workspace index',
'published realm.json carries includePrerenderedDefaultRealmIndex: true for a CardsGrid index',
);
});

Expand Down
5 changes: 3 additions & 2 deletions packages/realm-server/tests/realm-routing-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,9 @@ module(basename(import.meta.filename), function () {
// realm. ensureMounted publishes the Realm into reconciler.mounted
// synchronously and then awaits realm.start(). For a brand-new
// realm, start() awaits the first full index, which prerenders
// index.json. The CardsGrid in index.json fires _federated-search
// against the new realm. If resolveRealmsForFederatedRequest were
// index.json. The Workspace index card in index.json fires
// _federated-search against the new realm. If
// resolveRealmsForFederatedRequest were
// to re-enter lookupOrMount() for the same URL, it would find the
// URL in pendingMounts and await the very start() it is nested
// inside — deadlocking until the prerender's 90s render timeout
Expand Down
6 changes: 3 additions & 3 deletions packages/software-factory/src/factory-entrypoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,9 +377,9 @@ export async function runFactoryEntrypoint(
let pullTargetRealm = dependencies?.pullTargetRealm ?? defaultPullTargetRealm;
await pullTargetRealm(client, targetRealm.url, workspaceDir);

// For a realm the factory just created, replace the default CardsGrid
// index page with a RealmDashboard instance so the realm opens to the
// factory dashboard. A pre-existing realm keeps its current index page.
// For a realm the factory just created, replace the default index page
// with a RealmDashboard instance so the realm opens to the factory
// dashboard. A pre-existing realm keeps its current index page.
if (targetRealm.createdRealm) {
let writeRealmIndex =
dependencies?.writeRealmIndex ?? writeRealmDashboardCard;
Expand Down
6 changes: 3 additions & 3 deletions packages/software-factory/src/factory-realm-index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ export function inferRealmDashboardModuleUrl(targetRealm: string): string {

/**
* Set the realm's index page to a `RealmDashboard` instance, overwriting
* the default `CardsGrid` index that `create-realm` seeded.
* the default index that `create-realm` seeded.
*
* Writes two files: a sibling `cards-grid.json` holding the `CardsGrid`
* instance (the same empty grid `create-realm` would have made), and
* Writes two files: a sibling `cards-grid.json` holding a `CardsGrid`
* instance (an empty grid), and
* `index.json` adopting `RealmDashboard` with its `cardsGrid` link
* pointing at that instance — so the dashboard's catalog tab shows the
* realm's cards. The `board` link is left for the bootstrap agent to wire
Expand Down
Loading