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
19 changes: 19 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
boxel: ${{ steps.filter.outputs.boxel }}
ai-bot: ${{ steps.filter.outputs.ai-bot }}
bot-runner: ${{ steps.filter.outputs.bot-runner }}
eslint-plugin-boxel: ${{ steps.filter.outputs.eslint-plugin-boxel }}
postgres-migrations: ${{ steps.filter.outputs.postgres-migrations }}
boxel-icons: ${{ steps.filter.outputs.boxel-icons }}
boxel-motion: ${{ steps.filter.outputs.boxel-motion }}
Expand Down Expand Up @@ -67,6 +68,9 @@ jobs:
- *shared
- 'packages/bot-runner/**'
- 'packages/postgres/**'
eslint-plugin-boxel:
- *shared
- 'packages/eslint-plugin-boxel/**'
postgres-migrations:
- 'packages/postgres/migrations/**'
boxel-icons:
Expand Down Expand Up @@ -162,6 +166,21 @@ jobs:
run: pnpm test
working-directory: packages/bot-runner

eslint-plugin-boxel-test:
name: ESLint Plugin Boxel Tests
needs: change-check
if: needs.change-check.outputs.eslint-plugin-boxel == 'true' || github.ref == 'refs/heads/main' || needs.change-check.outputs.run_all == 'true'
runs-on: ubuntu-latest
concurrency:
group: eslint-plugin-boxel-test-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
- uses: ./.github/actions/init
- name: ESLint Plugin Boxel test suite
run: pnpm test
working-directory: packages/eslint-plugin-boxel

postgres-migration-test:
name: Postgres Migration Test
needs: change-check
Expand Down
19 changes: 11 additions & 8 deletions packages/billing/billing-queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -562,14 +562,17 @@ export async function spendCredits(
if (!subscriptionCycle) {
throw new Error('subscription cycle not found');
}
let availablePlanAllowanceCredits = await sumUpCreditsLedger(dbAdapter, {
creditType: [
'plan_allowance',
'plan_allowance_used',
'plan_allowance_expired',
],
userId,
});
let availablePlanAllowanceCredits = Math.max(
0,
await sumUpCreditsLedger(dbAdapter, {
creditType: [
'plan_allowance',
'plan_allowance_used',
'plan_allowance_expired',
],
subscriptionCycleId: subscriptionCycle.id,
}),
);

if (availablePlanAllowanceCredits >= creditsToSpend) {
await addToCreditsLedger(dbAdapter, {
Expand Down
40 changes: 40 additions & 0 deletions packages/eslint-plugin-boxel/lib/rules/no-css-position-fixed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
meta: {
type: 'problem',
docs: {
description:
'disallow `position: fixed` in card CSS because cards should not break out of their bounding box',
category: 'Ember Octane',
recommended: true,
},
schema: [],
messages: {
'no-css-position-fixed':
'Do not use `position: fixed` in card CSS. Cards should not break out of their bounding box. Consider using `position: absolute` or `position: sticky` instead.',
},
},

create: (context) => {
return {
GlimmerElementNode(node) {
if (node.tag !== 'style') {
return;
}
for (const child of node.children) {
if (child.type === 'GlimmerTextNode') {
const text = child.value;
const regex = /position\s*:\s*fixed/gi;
let match;
while ((match = regex.exec(text)) !== null) {
context.report({
node: child,
messageId: 'no-css-position-fixed',
});
}
}
}
},
};
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
const rule = require('../../../lib/rules/no-css-position-fixed');
const RuleTester = require('eslint').RuleTester;

const ruleTester = new RuleTester({
parser: require.resolve('ember-eslint-parser'),
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
});
ruleTester.run('no-css-position-fixed', rule, {
valid: [
`
<template>
<div class="my-card">Hello</div>
<style scoped>
.my-card {
position: relative;
top: 0;
}
</style>
</template>
`,
`
<template>
<div class="my-card">Hello</div>
<style scoped>
.my-card {
position: absolute;
top: 0;
}
</style>
</template>
`,
`
<template>
<div class="my-card">Hello</div>
<style scoped>
.my-card {
position: sticky;
top: 0;
}
</style>
</template>
`,
// No style tag at all
`
<template>
<div class="my-card">Hello</div>
</template>
`,
],

invalid: [
{
code: `
<template>
<div class="my-card">Hello</div>
<style scoped>
.my-card {
position: fixed;
top: 0;
}
</style>
</template>
`,
errors: [
{
type: 'GlimmerTextNode',
message: rule.meta.messages['no-css-position-fixed'],
},
],
},
// Without space after colon
{
code: `
<template>
<style scoped>
.my-card {
position:fixed;
}
</style>
</template>
`,
errors: [
{
type: 'GlimmerTextNode',
message: rule.meta.messages['no-css-position-fixed'],
},
],
},
// With extra whitespace
{
code: `
<template>
<style scoped>
.my-card {
position: fixed;
}
</style>
</template>
`,
errors: [
{
type: 'GlimmerTextNode',
message: rule.meta.messages['no-css-position-fixed'],
},
],
},
// Multiple occurrences
{
code: `
<template>
<style scoped>
.my-card {
position: fixed;
}
.another {
position: fixed;
}
</style>
</template>
`,
errors: [
{
type: 'GlimmerTextNode',
message: rule.meta.messages['no-css-position-fixed'],
},
{
type: 'GlimmerTextNode',
message: rule.meta.messages['no-css-position-fixed'],
},
],
},
],
});
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ interface Signature {
Args: {
items: (CardDef | FileDef | CardErrorJSONAPI)[];
autoAttachedCardIds?: TrackedSet<string>;
autoAttachedFile?: FileDef;
autoAttachedFiles?: FileDef[];
removeCard: (cardId: string) => void;
removeFile: (file: FileDef) => void;
chooseCard?: (cardId: string) => void;
Expand Down Expand Up @@ -63,7 +63,11 @@ export default class AttachedItems extends Component<Signature> {
};

private isAutoAttachedFile = (file: FileDef): boolean => {
return this.args.autoAttachedFile?.sourceUrl === file.sourceUrl;
return (
this.args.autoAttachedFiles?.some(
(autoFile) => autoFile.sourceUrl === file.sourceUrl,
) ?? false
);
};

@action
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface Signature {
Args: {
autoAttachedCardIds?: TrackedSet<string>;
cardIdsToAttach: string[] | undefined;
autoAttachedFile?: FileDef;
autoAttachedFiles?: FileDef[];
filesToAttach: FileDef[] | undefined;
chooseCard: (cardId: string) => void;
removeCard: (cardId: string) => void;
Expand All @@ -37,7 +37,7 @@ interface Signature {
typeof AttachedItems,
| 'items'
| 'autoAttachedCardIds'
| 'autoAttachedFile'
| 'autoAttachedFiles'
| 'removeCard'
| 'removeFile'
| 'chooseCard'
Expand All @@ -59,7 +59,7 @@ export default class AiAssistantAttachmentPicker extends Component<Signature> {
isLoaded=this.isLoaded
items=this.items
autoAttachedCardIds=@autoAttachedCardIds
autoAttachedFile=@autoAttachedFile
autoAttachedFiles=@autoAttachedFiles
removeCard=@removeCard
removeFile=@removeFile
chooseCard=@chooseCard
Expand Down Expand Up @@ -109,18 +109,20 @@ export default class AiAssistantAttachmentPicker extends Component<Signature> {
private get files() {
let files = this.args.filesToAttach ?? [];

if (!this.args.autoAttachedFile) {
let autoAttachedFiles = this.args.autoAttachedFiles ?? [];

if (autoAttachedFiles.length === 0) {
return files;
}

if (
files.some(
(file) => file.sourceUrl === this.args.autoAttachedFile?.sourceUrl,
)
) {
let autoFilesToPrepend = autoAttachedFiles.filter(
(file) => !files.some((item) => item.sourceUrl === file.sourceUrl),
);

if (autoFilesToPrepend.length === 0) {
return files;
}

return [this.args.autoAttachedFile, ...files];
return [...autoFilesToPrepend, ...files];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default class AiAssistantCardPickerUsage extends Component {
cardIds: TrackedArray<string> = new TrackedArray([]);
@tracked maxNumberOfCards: number | undefined = undefined;
@tracked autoAttachedCardIds?: TrackedSet<string> = new TrackedSet();
@tracked autoAttachedFile?: FileDef | undefined;
@tracked autoAttachedFiles?: FileDef[];
@tracked filesToAttach: TrackedArray<FileDef> = new TrackedArray([]);

@action chooseCard(cardId: string) {
Expand Down Expand Up @@ -60,7 +60,7 @@ export default class AiAssistantCardPickerUsage extends Component {
@removeCard={{this.removeCard}}
@chooseFile={{this.chooseFile}}
@removeFile={{this.removeFile}}
@autoAttachedFile={{this.autoAttachedFile}}
@autoAttachedFiles={{this.autoAttachedFiles}}
@filesToAttach={{this.filesToAttach}}
as |AttachedItems AttachButton|
>
Expand All @@ -81,9 +81,9 @@ export default class AiAssistantCardPickerUsage extends Component {
@value={{this.autoAttachedCardIds}}
/>
<Args.Object
@name='autoAttachedFile'
@description='A file automatically attached to the message.'
@value={{this.autoAttachedFile}}
@name='autoAttachedFiles'
@description='Files automatically attached to the message.'
@value={{this.autoAttachedFiles}}
/>
<Args.Object
@name='filesToAttach'
Expand Down
1 change: 1 addition & 0 deletions packages/host/app/components/host-mode/card.gts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export default class HostModeCard extends Component<Signature> {
padding: var(--host-mode-card-padding);
border-radius: var(--host-mode-card-border-radius, 20px);
flex: 1;
z-index: 0;
overflow: auto;
}

Expand Down
14 changes: 13 additions & 1 deletion packages/host/app/components/host-mode/content.gts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ export default class HostModeContent extends Component<Signature> {
align-items: center;
justify-content: center;
width: 100%;
min-height: 100vh;
overflow: hidden;
padding: var(--boxel-sp);
position: relative;
Expand All @@ -136,6 +135,19 @@ export default class HostModeContent extends Component<Signature> {
background-repeat: no-repeat;
}

@media screen {
.host-mode-content {
height: 100%;
overscroll-behavior: none;
}
}

@media print {
.host-mode-content {
min-height: 100vh;
}
}

.breadcrumb-container {
position: absolute;
top: var(--boxel-sp);
Expand Down
Loading
Loading