Skip to content

Commit

Permalink
Merge branch 'develop' into wip/akirathan/11483-polyglot-lib
Browse files Browse the repository at this point in the history
  • Loading branch information
Akirathan committed Jan 1, 2025
2 parents e6956db + ea2d4e5 commit 7ea660e
Show file tree
Hide file tree
Showing 98 changed files with 3,587 additions and 1,512 deletions.
1 change: 0 additions & 1 deletion .github/workflows/gui-changed-files.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ jobs:
.prettierignore
vitest.workspace.ts
.github/workflows/gui*
.github/workflows/ide*
.github/workflows/storybook.yml
files_ignore: |
app/ide-desktop/**
Expand Down
44 changes: 44 additions & 0 deletions .github/workflows/ide-changed-files.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# This file is not auto-generated. Feel free to edit it.

name: IDE Changed Files

on:
workflow_call:
outputs:
all_changed_files:
description: "Returns all changed files"
value: ${{ jobs.ide-changed-files.outputs.all_changed_files }}
any_changed:
description: "Returns `true` when any of the filenames have changed"
value: ${{ jobs.ide-changed-files.outputs.any_changed }}

jobs:
ide-changed-files:
runs-on: ubuntu-latest
name: Changed Files
outputs:
all_changed_files: ${{ steps.ide-changed-files.outputs.all_changed_files }}
any_changed: ${{ steps.ide-changed-files.outputs.any_changed }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Get changed files
id: ide-changed-files
uses: tj-actions/changed-files@v45
with:
files: |
app/ide-desktop/**
package.json
pnpm-lock.yaml
.github/workflows/ide*
- name: List all changed files
env:
ALL_CHANGED_FILES: ${{ steps.ide-changed-files.outputs.all_changed_files }}
run: |
if [[ "${{ steps.ide-changed-files.outputs.any_changed }}" == "true" ]]; then
echo "Files changed:"
fi
for file in ${ALL_CHANGED_FILES}; do
echo "$file"
done
13 changes: 9 additions & 4 deletions .github/workflows/ide-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ jobs:
uses: ./.github/workflows/gui-changed-files.yml
secrets: inherit

ide-changed-files:
name: 🔍 IDE Files Changed
uses: ./.github/workflows/ide-changed-files.yml
secrets: inherit

engine-changed-files:
name: 🔍 Engine Files Changed
uses: ./.github/workflows/engine-changed-files.yml
Expand All @@ -26,15 +31,15 @@ jobs:
ide-packaging:
name: 📦 Package
uses: ./.github/workflows/ide-packaging.yml
needs: [gui-changed-files, engine-changed-files]
if: needs.gui-changed-files.outputs.any_changed == 'true' || needs.engine-changed-files.outputs.any_changed == 'true' || github.ref == 'refs/heads/develop'
needs: [gui-changed-files, ide-changed-files, engine-changed-files]
if: needs.gui-changed-files.outputs.any_changed == 'true' || needs.ide-changed-files.outputs.any_changed == 'true' || needs.engine-changed-files.outputs.any_changed == 'true' || github.ref == 'refs/heads/develop'
secrets: inherit

ide-packaging-optional:
name: 📦 Package (Optional)
uses: ./.github/workflows/ide-packaging-optional.yml
needs: [gui-changed-files, engine-changed-files]
if: needs.gui-changed-files.outputs.any_changed == 'true' || needs.engine-changed-files.outputs.any_changed == 'true' || github.ref == 'refs/heads/develop'
needs: [gui-changed-files, ide-changed-files, engine-changed-files]
if: needs.gui-changed-files.outputs.any_changed == 'true' || needs.ide-changed-files.outputs.any_changed == 'true' || needs.engine-changed-files.outputs.any_changed == 'true' || github.ref == 'refs/heads/develop'
secrets: inherit

required-checks:
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
previously allowed to use spaces in the argument definition without
parentheses. [This is now a syntax error.][11856]
- [Native libraries of projects can be added to `polyglot/lib` directory][11874]
- [Redo stack is no longer lost when interacting with text literals][11908].
- Symetric, transitive and reflexive [equality for intersection types][11897]

[11777]: https://github.com/enso-org/enso/pull/11777
[11600]: https://github.com/enso-org/enso/pull/11600
[11856]: https://github.com/enso-org/enso/pull/11856
[11874]: https://github.com/enso-org/enso/pull/11874
[11908]: https://github.com/enso-org/enso/pull/11908
[11897]: https://github.com/enso-org/enso/pull/11897

# Next Release
Expand Down
26 changes: 15 additions & 11 deletions app/common/src/detect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,17 +166,21 @@ export function isOnUnknownBrowser() {

let detectedArchitecture: string | null = null
// Only implemented by Chromium.
// @ts-expect-error This API exists, but no typings exist for it yet.
navigator.userAgentData?.getHighEntropyValues(['architecture']).then((values: unknown) => {
if (
typeof values === 'object' &&
values != null &&
'architecture' in values &&
typeof values.architecture === 'string'
) {
detectedArchitecture = String(values.architecture)
}
})
// navigator is undefined in Node.js, e.g. in integration tests(mock server).
// So we need to check if it is defined before using it.
if (typeof navigator !== 'undefined' && 'userAgentData' in navigator) {
// @ts-expect-error This API exists, but no typings exist for it yet.
navigator.userAgentData.getHighEntropyValues(['architecture']).then((values: unknown) => {
if (
typeof values === 'object' &&
values != null &&
'architecture' in values &&
typeof values.architecture === 'string'
) {
detectedArchitecture = String(values.architecture)
}
})
}

/** Possible processor architectures. */
export enum Architecture {
Expand Down
41 changes: 24 additions & 17 deletions app/common/src/services/Backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,36 @@ export const S3_CHUNK_SIZE_BYTES = 10_000_000
// ================

/** Unique identifier for an organization. */
export type OrganizationId = newtype.Newtype<string, 'OrganizationId'>
export type OrganizationId = newtype.Newtype<`organization-${string}`, 'OrganizationId'>
export const OrganizationId = newtype.newtypeConstructor<OrganizationId>()
/** Whether a given {@link string} is an {@link OrganizationId}. */
export function isOrganizationId(id: string): id is OrganizationId {
return id.startsWith('organization-')
}

/** Unique identifier for a user in an organization. */
export type UserId = newtype.Newtype<string, 'UserId'>
export const UserId = newtype.newtypeConstructor<UserId>()
/** Whether a given {@link string} is an {@link UserId}. */
export function isUserId(id: string): id is UserId {
return id.startsWith('user-')
}

/** Unique identifier for a user group. */
export type UserGroupId = newtype.Newtype<string, 'UserGroupId'>
export type UserGroupId = newtype.Newtype<`usergroup-${string}`, 'UserGroupId'>
export const UserGroupId = newtype.newtypeConstructor<UserGroupId>()
/** Whether a given {@link string} is an {@link UserGroupId}. */
export function isUserGroupId(id: string): id is UserGroupId {
return id.startsWith('usergroup-')
}

/** Unique identifier for a directory. */
export type DirectoryId = newtype.Newtype<string, 'DirectoryId'>
export type DirectoryId = newtype.Newtype<`directory-${string}`, 'DirectoryId'>
export const DirectoryId = newtype.newtypeConstructor<DirectoryId>()
/** Whether a given {@link string} is an {@link DirectoryId}. */
export function isDirectoryId(id: string): id is DirectoryId {
return id.startsWith('directory-')
}

/**
* Unique identifier for an asset representing the items inside a directory for which the
Expand Down Expand Up @@ -73,6 +89,7 @@ export const S3ObjectVersionId = newtype.newtypeConstructor<S3ObjectVersionId>()

/** Unique identifier for an arbitrary asset. */
export type AssetId = IdType[keyof IdType]
export const AssetId = newtype.newtypeConstructor<AssetId>()

/** Unique identifier for a payment checkout session. */
export type CheckoutSessionId = newtype.Newtype<string, 'CheckoutSessionId'>
Expand Down Expand Up @@ -117,16 +134,6 @@ export type UserPermissionIdentifier = UserGroupId | UserId
export type Path = newtype.Newtype<string, 'Path'>
export const Path = newtype.newtypeConstructor<Path>()

/** Whether a given {@link string} is an {@link UserId}. */
export function isUserId(id: string): id is UserId {
return id.startsWith('user-')
}

/** Whether a given {@link string} is an {@link UserGroupId}. */
export function isUserGroupId(id: string): id is UserGroupId {
return id.startsWith('usergroup-')
}

const PLACEHOLDER_USER_GROUP_PREFIX = 'usergroup-placeholder-'

/**
Expand All @@ -142,7 +149,7 @@ export function isPlaceholderUserGroupId(id: string) {
* being created on the backend.
*/
export function newPlaceholderUserGroupId() {
return UserGroupId(`${PLACEHOLDER_USER_GROUP_PREFIX}${uniqueString.uniqueString()}`)
return UserGroupId(`${PLACEHOLDER_USER_GROUP_PREFIX}${uniqueString.uniqueString()}` as const)
}

// =============
Expand Down Expand Up @@ -829,7 +836,7 @@ export function createRootDirectoryAsset(directoryId: DirectoryId): DirectoryAss
title: '(root)',
id: directoryId,
modifiedAt: dateTime.toRfc3339(new Date()),
parentId: DirectoryId(''),
parentId: DirectoryId('directory-'),
permissions: [],
projectState: null,
extension: null,
Expand Down Expand Up @@ -904,7 +911,7 @@ export function createPlaceholderDirectoryAsset(
): DirectoryAsset {
return {
type: AssetType.directory,
id: DirectoryId(createPlaceholderId()),
id: DirectoryId(`directory-${createPlaceholderId()}` as const),
title,
parentId,
permissions: assetPermissions,
Expand Down Expand Up @@ -1074,7 +1081,7 @@ export function createPlaceholderAssetId<Type extends AssetType>(
let result: AssetId
switch (assetType) {
case AssetType.directory: {
result = DirectoryId(id)
result = DirectoryId(`directory-${id}` as const)
break
}
case AssetType.project: {
Expand Down
9 changes: 7 additions & 2 deletions app/common/src/text/english.json
Original file line number Diff line number Diff line change
Expand Up @@ -495,13 +495,13 @@
"enableVersionCheckerDescription": "Show a dialog if the current version of the desktop app does not match the latest version.",
"disableAnimations": "Disable animations",
"disableAnimationsDescription": "Disable all animations in the app.",
"removeTheLocalDirectoryXFromFavorites": "remove the local folder '$0' from your favorites",
"removeTheLocalDirectoryXFromFavorites": "remove the local folder '$0' from your sidebar",
"changeLocalRootDirectoryInSettings": "Change the root folder",
"localStorage": "Local Storage",
"addLocalDirectory": "Add Folder",
"browseForNewLocalRootDirectory": "Browse for new Root Folder",
"resetLocalRootDirectory": "Reset Root Folder",
"removeDirectoryFromFavorites": "Remove folder from favorites",
"removeDirectoryFromFavorites": "Remove from Sidebar",
"organizationInviteTitle": "You have been invited!",
"organizationInvitePrefix": "The organization '",
"organizationInviteSuffix": "' is inviting you. Would you like to accept? All your assets will be moved with you to your personal space.",
Expand Down Expand Up @@ -692,6 +692,7 @@
"accessedDataColumnName": "Accessed data",
"docsColumnName": "Docs",
"rootFolderColumnName": "Root folder",
"pathColumnName": "Location",

"settingsShortcut": "Settings",
"closeTabShortcut": "Close Tab",
Expand Down Expand Up @@ -761,6 +762,10 @@
"accessedDataColumnHide": "Accessed Data",
"docsColumnShow": "Docs",
"docsColumnHide": "Docs",
"pathColumnShow": "Location",
"pathColumnHide": "Location",

"hideColumn": "Hide column",

"activityLog": "Activity Log",
"startDate": "Start Date",
Expand Down
64 changes: 64 additions & 0 deletions app/gui/integration-test/dashboard/actions/DrivePageActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,27 @@ export default class DrivePageActions<Context> extends PageActions<Context> {
)
}

/**
* Expect the category to be selected.
*/
expectCategory(category: string) {
return this.step(`Expect category '${category}'`, (page) =>
expect(page.getByRole('button', { name: category })).toHaveAttribute('data-selected', 'true'),
)
}

/**
* Expect the category to be not selected.
*/
expectCategoryNotSelected(category: string) {
return this.step(`Expect category '${category}' not selected`, (page) =>
expect(page.getByRole('button', { name: category })).toHaveAttribute(
'data-selected',
'false',
),
)
}

/** Actions specific to the Drive table. */
get driveTable() {
// eslint-disable-next-line @typescript-eslint/no-this-alias
Expand All @@ -147,6 +168,11 @@ export default class DrivePageActions<Context> extends PageActions<Context> {
.getByLabel(TEXT.sortByModificationDate)
.or(page.getByLabel(TEXT.sortByModificationDateDescending))
.or(page.getByLabel(TEXT.stopSortingByModificationDate))

const locatePathColumnHeading = (page: Page) => page.getByTestId('path-column-heading')
const locatePathColumnCell = (page: Page, title: string) =>
page.getByTestId(`path-column-cell-${title.toLowerCase().replace(/\s+/g, '-')}`)

return {
/** Click the column heading for the "name" column to change its sort order. */
clickNameColumnHeading() {
Expand All @@ -160,6 +186,16 @@ export default class DrivePageActions<Context> extends PageActions<Context> {
callback(locateNameColumnHeading(page), context),
)
},
withPathColumnHeading(callback: LocatorCallback<Context>) {
return self.step('Interact with "path" column heading', (page, context) =>
callback(locatePathColumnHeading(page), context),
)
},
withPathColumnCell(title: string, callback: LocatorCallback<Context>) {
return self.step(`Interact with "path" column cell '${title}'`, (page, context) =>
callback(locatePathColumnCell(page, title), context),
)
},
/** Click the column heading for the "modified" column to change its sort order. */
clickModifiedColumnHeading() {
return self.step('Click "modified" column heading', (page) =>
Expand Down Expand Up @@ -208,10 +244,16 @@ export default class DrivePageActions<Context> extends PageActions<Context> {
await callback(locateAssetRows(page), locateNonAssetRows(page), self.context, page)
})
},
withSelectedRows(callback: LocatorCallback<Context>) {
return self.step('Interact with selected drive table rows', async (page, context) => {
await callback(locateAssetRows(page).and(page.locator('[data-selected="true"]')), context)
})
},
/** Drag a row onto another row. */
dragRowToRow(from: number, to: number) {
return self.step(`Drag drive table row #${from} to row #${to}`, async (page) => {
const rows = locateAssetRows(page)
rows.nth(from).click()
await rows.nth(from).dragTo(rows.nth(to), {
sourcePosition: ASSET_ROW_SAFE_POSITION,
targetPosition: ASSET_ROW_SAFE_POSITION,
Expand All @@ -229,6 +271,28 @@ export default class DrivePageActions<Context> extends PageActions<Context> {
}),
)
},
expandDirectory(index: number) {
return self.step(`Expand drive table row #${index}`, async (page) => {
const expandButton = locateAssetRows(page)
.nth(index)
.getByTestId('directory-row-expand-button')

await expect(expandButton).toHaveAttribute('aria-label', TEXT.expand)

await expandButton.click()
})
},
collapseDirectory(index: number) {
return self.step(`Collapse drive table row #${index}`, async (page) => {
const collapseButton = locateAssetRows(page)
.nth(index)
.getByTestId('directory-row-expand-button')

await expect(collapseButton).toHaveAttribute('aria-label', TEXT.collapse)

return collapseButton.click()
})
},
/**
* A test assertion to confirm that there is only one row visible, and that row is the
* placeholder row displayed when there are no assets to show.
Expand Down
Loading

0 comments on commit 7ea660e

Please sign in to comment.