@@ -133,6 +155,7 @@
{#if changes.length > 0}
+ dependency.locks.some((lock) => lock.stackId !== currentStack)
+ );
+}
+
+/**
+ * Retrieves a list of selectable files based on the provided changes, file dependencies, and stack ID.
+ *
+ * @param changes - An array of `TreeChange` objects representing the changes in the file tree.
+ * If undefined or empty, an empty array is returned.
+ * @param fileDependencies - A map where the keys are file paths and the values are `FileDependencies` objects.
+ * This is used to determine if a file is locked to a specific stack.
+ * @param stackId - The ID of the current stack. Will be used to determine locks to other stacks.
+ *
+ * @returns An array of `SelectedFile` objects representing the files that can be selected.
+ * Files that are locked to other stacks are excluded from the result.
+ */
+export function getSelectableFiles(
+ changes: TreeChange[] | undefined,
+ fileDependencies: Map | undefined,
+ currentStack: string | undefined
+): SelectedFile[] {
+ if (!currentStack) {
+ // Should not happen, but just in case.
+ throw new Error('Current stack is undefined');
+ }
+
+ if (changes === undefined || changes.length === 0) {
+ // No changes
+ return [];
+ }
+ const selectedFiles: SelectedFile[] = [];
+
+ for (const change of changes) {
+ const fileDependency = fileDependencies?.get(change.path)?.dependencies;
+ if (
+ fileDependency &&
+ fileDependency.length > 0 &&
+ hunkIsLockedToOtherStack(fileDependency, currentStack)
+ ) {
+ // The files are at least partially locked to other stacks,
+ // so we don't want to select them.
+
+ // TODO: Support partial selection of files and hunks.
+ continue;
+ }
+
+ const fullFile = {
+ path: change.path,
+ pathBytes: change.pathBytes,
+ type: 'full'
+ } as const;
+
+ selectedFiles.push(fullFile);
+ }
+ return selectedFiles;
+}
diff --git a/apps/desktop/src/lib/dependencies/dependencyService.svelte.ts b/apps/desktop/src/lib/dependencies/dependencyService.svelte.ts
index 6a8968f481..b4e1585e39 100644
--- a/apps/desktop/src/lib/dependencies/dependencyService.svelte.ts
+++ b/apps/desktop/src/lib/dependencies/dependencyService.svelte.ts
@@ -3,7 +3,7 @@ import {
type FileDependencies,
type HunkDependencies
} from '$lib/dependencies/dependencies';
-import { createSelectByIds } from '$lib/state/customSelectors';
+import { createSelectByIds, createSelectByIdsWithKey } from '$lib/state/customSelectors';
import { createEntityAdapter, type EntityState } from '@reduxjs/toolkit';
import type { BackendApi, ClientState } from '$lib/state/clientState.svelte';
@@ -28,8 +28,19 @@ export default class DependencyService {
return this.api.endpoints.dependencies.useQuery(
{ projectId, worktreeChangesKey },
{
- transform: ({ fileDependencies }) =>
- fileDependencySelectors.selectByIds(fileDependencies, filePaths)
+ transform: ({ fileDependencies }) => {
+ const keyedDepdendencies = fileDependencySelectors.createSelectByIdsWithKey(
+ fileDependencies,
+ filePaths
+ );
+ const dependecyMap = new Map();
+ for (const { key, value } of keyedDepdendencies) {
+ if (value) {
+ dependecyMap.set(key, value);
+ }
+ }
+ return dependecyMap;
+ }
}
);
}
@@ -68,5 +79,6 @@ const fileDependenciesAdapter = createEntityAdapter({
const fileDependencySelectors = {
...fileDependenciesAdapter.getSelectors(),
- selectByIds: createSelectByIds()
+ selectByIds: createSelectByIds(),
+ createSelectByIdsWithKey: createSelectByIdsWithKey()
};
diff --git a/apps/desktop/src/lib/state/customSelectors.ts b/apps/desktop/src/lib/state/customSelectors.ts
index 499087bff2..2dff18b2c2 100644
--- a/apps/desktop/src/lib/state/customSelectors.ts
+++ b/apps/desktop/src/lib/state/customSelectors.ts
@@ -28,6 +28,18 @@ export function createSelectByIds() {
);
}
+export function createSelectByIdsWithKey() {
+ return createSelector(
+ [(state: EntityState) => state, (state_, ids: string[]) => ids],
+ (state, ids) => {
+ return ids.map((id) => {
+ const entity = state.entities[id];
+ return { key: id, value: entity };
+ });
+ }
+ );
+}
+
/**
* The main purpose of this function is to enable selecting e.g. the
* parent of a branch, or commit.