diff --git a/package.json b/package.json index 5d2b86ab5..d6fc2a325 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "prettier:check": "prettier --check .", "prettier:fix": "prettier --write .", "circleci:check": "circleci config validate ./.circleci/config.yml", + "dev:docker": "docker-compose -f ./docker-compose-deps.yml", "dev:docker:up": "docker-compose -f ./docker-compose-deps.yml up -d", "dev:docker:down": "docker-compose -f ./docker-compose-deps.yml down", "dev": "yarn workspaces foreach -piv -j unlimited run dev", diff --git a/packages/frontend/src/graphql/branch.gql b/packages/frontend/src/graphql/branch.gql index 7ded0928f..b6ffda945 100644 --- a/packages/frontend/src/graphql/branch.gql +++ b/packages/frontend/src/graphql/branch.gql @@ -2,6 +2,7 @@ query StreamWithBranch($streamId: String!, $branchName: String!, $cursor: String stream(id: $streamId) { id name + role branch(name: $branchName) { id name diff --git a/packages/frontend/src/graphql/commits.ts b/packages/frontend/src/graphql/commits.ts new file mode 100644 index 000000000..34faed4ca --- /dev/null +++ b/packages/frontend/src/graphql/commits.ts @@ -0,0 +1,26 @@ +import { gql } from '@apollo/client/core' + +export const streamBranchesSelectorQuery = gql` + query StreamBranchesSelector($streamId: String!) { + stream(id: $streamId) { + id + branches(limit: 100) { + items { + name + } + } + } + } +` + +export const moveCommitsMutation = gql` + mutation MoveCommits($input: CommitsMoveInput!) { + commitsMove(input: $input) + } +` + +export const deleteCommitsMutation = gql` + mutation DeleteCommits($input: CommitsDeleteInput!) { + commitsDelete(input: $input) + } +` diff --git a/packages/frontend/src/graphql/generated/graphql.ts b/packages/frontend/src/graphql/generated/graphql.ts index 4de9eb418..1d9ff7fb7 100644 --- a/packages/frontend/src/graphql/generated/graphql.ts +++ b/packages/frontend/src/graphql/generated/graphql.ts @@ -166,7 +166,7 @@ export type BranchCommitsArgs = { export type BranchCollection = { __typename?: 'BranchCollection'; cursor?: Maybe; - items?: Maybe>>; + items?: Maybe>; totalCount: Scalars['Int']; }; @@ -346,8 +346,6 @@ export type CommitCreateInput = { message?: InputMaybe; objectId: Scalars['String']; parents?: InputMaybe>>; - /** **DEPRECATED** Use the `parents` field. */ - previousCommitIds?: InputMaybe>>; sourceApplication?: InputMaybe; streamId: Scalars['String']; totalChildrenCount?: InputMaybe; @@ -388,6 +386,15 @@ export type CommitUpdateInput = { streamId: Scalars['String']; }; +export type CommitsDeleteInput = { + commitIds: Array; +}; + +export type CommitsMoveInput = { + commitIds: Array; + targetBranch: Scalars['String']; +}; + export enum DiscoverableStreamsSortType { CreatedDate = 'CREATED_DATE', FavoritesCount = 'FAVORITES_COUNT' @@ -467,6 +474,10 @@ export type Mutation = { commitDelete: Scalars['Boolean']; commitReceive: Scalars['Boolean']; commitUpdate: Scalars['Boolean']; + /** Delete a batch of commits */ + commitsDelete: Scalars['Boolean']; + /** Move a batch of commits to a new branch */ + commitsMove: Scalars['Boolean']; /** Delete a pending invite */ inviteDelete: Scalars['Boolean']; /** Re-send a pending invite */ @@ -621,6 +632,16 @@ export type MutationCommitUpdateArgs = { }; +export type MutationCommitsDeleteArgs = { + input: CommitsDeleteInput; +}; + + +export type MutationCommitsMoveArgs = { + input: CommitsMoveInput; +}; + + export type MutationInviteDeleteArgs = { inviteId: Scalars['String']; }; @@ -1678,7 +1699,7 @@ export type StreamWithBranchQueryVariables = Exact<{ }>; -export type StreamWithBranchQuery = { __typename?: 'Query', stream?: { __typename?: 'Stream', id: string, name: string, branch?: { __typename?: 'Branch', id: string, name: string, description?: string | null, commits?: { __typename?: 'CommitCollection', totalCount: number, cursor?: string | null, items?: Array<{ __typename?: 'Commit', id: string, authorName?: string | null, authorId?: string | null, authorAvatar?: string | null, sourceApplication?: string | null, message?: string | null, referencedObject: string, createdAt?: string | null, commentCount: number } | null> | null } | null } | null } | null }; +export type StreamWithBranchQuery = { __typename?: 'Query', stream?: { __typename?: 'Stream', id: string, name: string, role?: string | null, branch?: { __typename?: 'Branch', id: string, name: string, description?: string | null, commits?: { __typename?: 'CommitCollection', totalCount: number, cursor?: string | null, items?: Array<{ __typename?: 'Commit', id: string, authorName?: string | null, authorId?: string | null, authorAvatar?: string | null, sourceApplication?: string | null, message?: string | null, referencedObject: string, createdAt?: string | null, commentCount: number } | null> | null } | null } | null } | null }; export type BranchCreatedSubscriptionVariables = Exact<{ streamId: Scalars['String']; @@ -1697,6 +1718,27 @@ export type StreamCommitQueryQueryVariables = Exact<{ export type StreamCommitQueryQuery = { __typename?: 'Query', stream?: { __typename?: 'Stream', id: string, name: string, role?: string | null, commit?: { __typename?: 'Commit', id: string, message?: string | null, referencedObject: string, authorName?: string | null, authorId?: string | null, authorAvatar?: string | null, createdAt?: string | null, branchName?: string | null, sourceApplication?: string | null } | null } | null }; +export type StreamBranchesSelectorQueryVariables = Exact<{ + streamId: Scalars['String']; +}>; + + +export type StreamBranchesSelectorQuery = { __typename?: 'Query', stream?: { __typename?: 'Stream', id: string, branches?: { __typename?: 'BranchCollection', items?: Array<{ __typename?: 'Branch', name: string }> | null } | null } | null }; + +export type MoveCommitsMutationVariables = Exact<{ + input: CommitsMoveInput; +}>; + + +export type MoveCommitsMutation = { __typename?: 'Mutation', commitsMove: boolean }; + +export type DeleteCommitsMutationVariables = Exact<{ + input: CommitsDeleteInput; +}>; + + +export type DeleteCommitsMutation = { __typename?: 'Mutation', commitsDelete: boolean }; + export type BasicStreamAccessRequestFieldsFragment = { __typename?: 'StreamAccessRequest', id: string, streamId: string, createdAt: string }; export type FullStreamAccessRequestFieldsFragment = { __typename?: 'StreamAccessRequest', id: string, streamId: string, createdAt: string, requester: { __typename?: 'LimitedUser', id: string, name?: string | null, bio?: string | null, company?: string | null, avatar?: string | null, verified?: boolean | null } }; @@ -2214,6 +2256,7 @@ export const StreamWithBranch = gql` stream(id: $streamId) { id name + role branch(name: $branchName) { id name @@ -2262,6 +2305,28 @@ export const StreamCommitQuery = gql` } } `; +export const StreamBranchesSelector = gql` + query StreamBranchesSelector($streamId: String!) { + stream(id: $streamId) { + id + branches(limit: 100) { + items { + name + } + } + } +} + `; +export const MoveCommits = gql` + mutation MoveCommits($input: CommitsMoveInput!) { + commitsMove(input: $input) +} + `; +export const DeleteCommits = gql` + mutation DeleteCommits($input: CommitsDeleteInput!) { + commitsDelete(input: $input) +} + `; export const StreamInvite = gql` query StreamInvite($streamId: String!, $token: String) { streamInvite(streamId: $streamId, token: $token) { @@ -2765,9 +2830,12 @@ export const CommonUserFieldsFragmentDoc = {"kind":"Document","definitions":[{"k export const GetStreamAccessRequestDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetStreamAccessRequest"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"streamAccessRequest"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"streamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BasicStreamAccessRequestFields"}}]}}]}},...BasicStreamAccessRequestFieldsFragmentDoc.definitions]} as unknown as DocumentNode; export const CreateStreamAccessRequestDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateStreamAccessRequest"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"streamAccessRequestCreate"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"streamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BasicStreamAccessRequestFields"}}]}}]}},...BasicStreamAccessRequestFieldsFragmentDoc.definitions]} as unknown as DocumentNode; export const UseStreamAccessRequestDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UseStreamAccessRequest"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"requestId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"accept"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"role"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"StreamRole"}},"defaultValue":{"kind":"EnumValue","value":"STREAM_CONTRIBUTOR"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"streamAccessRequestUse"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"requestId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"requestId"}}},{"kind":"Argument","name":{"kind":"Name","value":"accept"},"value":{"kind":"Variable","name":{"kind":"Name","value":"accept"}}},{"kind":"Argument","name":{"kind":"Name","value":"role"},"value":{"kind":"Variable","name":{"kind":"Name","value":"role"}}}]}]}}]} as unknown as DocumentNode; -export const StreamWithBranchDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"StreamWithBranch"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"branchName"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"stream"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"branch"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"branchName"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"commits"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"cursor"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}}},{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"4"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}},{"kind":"Field","name":{"kind":"Name","value":"cursor"}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"authorName"}},{"kind":"Field","name":{"kind":"Name","value":"authorId"}},{"kind":"Field","name":{"kind":"Name","value":"authorAvatar"}},{"kind":"Field","name":{"kind":"Name","value":"sourceApplication"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"referencedObject"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"commentCount"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; +export const StreamWithBranchDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"StreamWithBranch"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"branchName"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"stream"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"branch"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"branchName"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"commits"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"cursor"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}}},{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"4"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}},{"kind":"Field","name":{"kind":"Name","value":"cursor"}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"authorName"}},{"kind":"Field","name":{"kind":"Name","value":"authorId"}},{"kind":"Field","name":{"kind":"Name","value":"authorAvatar"}},{"kind":"Field","name":{"kind":"Name","value":"sourceApplication"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"referencedObject"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"commentCount"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const BranchCreatedDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"subscription","name":{"kind":"Name","value":"BranchCreated"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"branchCreated"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"streamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}}}]}]}}]} as unknown as DocumentNode; export const StreamCommitQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"StreamCommitQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"stream"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"commit"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"referencedObject"}},{"kind":"Field","name":{"kind":"Name","value":"authorName"}},{"kind":"Field","name":{"kind":"Name","value":"authorId"}},{"kind":"Field","name":{"kind":"Name","value":"authorAvatar"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"branchName"}},{"kind":"Field","name":{"kind":"Name","value":"sourceApplication"}}]}}]}}]}}]} as unknown as DocumentNode; +export const StreamBranchesSelectorDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"StreamBranchesSelector"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"stream"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"branches"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"100"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}}]} as unknown as DocumentNode; +export const MoveCommitsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"MoveCommits"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CommitsMoveInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"commitsMove"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode; +export const DeleteCommitsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteCommits"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CommitsDeleteInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"commitsDelete"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode; export const StreamInviteDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"StreamInvite"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"token"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"streamInvite"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"streamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}}},{"kind":"Argument","name":{"kind":"Name","value":"token"},"value":{"kind":"Variable","name":{"kind":"Name","value":"token"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"UsersOwnInviteFields"}}]}}]}},...UsersOwnInviteFieldsFragmentDoc.definitions,...LimitedUserFieldsFragmentDoc.definitions]} as unknown as DocumentNode; export const UserStreamInvitesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserStreamInvites"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"streamInvites"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"UsersOwnInviteFields"}}]}}]}},...UsersOwnInviteFieldsFragmentDoc.definitions,...LimitedUserFieldsFragmentDoc.definitions]} as unknown as DocumentNode; export const UseStreamInviteDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UseStreamInvite"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"accept"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"token"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"streamInviteUse"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"accept"},"value":{"kind":"Variable","name":{"kind":"Name","value":"accept"}}},{"kind":"Argument","name":{"kind":"Name","value":"streamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"streamId"}}},{"kind":"Argument","name":{"kind":"Name","value":"token"},"value":{"kind":"Variable","name":{"kind":"Name","value":"token"}}}]}]}}]} as unknown as DocumentNode; diff --git a/packages/frontend/src/main/components/common/CommitPreviewCard.vue b/packages/frontend/src/main/components/common/CommitPreviewCard.vue index 086994905..0f20aadf1 100644 --- a/packages/frontend/src/main/components/common/CommitPreviewCard.vue +++ b/packages/frontend/src/main/components/common/CommitPreviewCard.vue @@ -3,9 +3,7 @@ - - - mdi-source-commit - {{ commit.message }} - + + +
+ + mdi-source-commit + {{ commit.message }} + +
@@ -90,13 +96,37 @@ export default { commit: { type: Object, default: () => null }, previewHeight: { type: Number, default: () => 180 }, showStreamAndBranch: { type: Boolean, default: true }, - highlight: { type: Boolean, default: false } + highlight: { type: Boolean, default: false }, + allowSelect: { + type: Boolean, + default: false + }, + selected: { + type: Boolean, + default: false + } }, computed: { + highlighted() { + return this.highlight || this.selected + }, streamId() { return ( this.commit.streamId ?? this.$route.params.streamId ?? this.$route.query.stream ) + }, + selectedState: { + get() { + return this.selected + }, + set(val) { + this.$emit('update:selected', !!val) + } + } + }, + methods: { + onSelect() { + this.$emit('select', { value: this.selected }) } } } diff --git a/packages/frontend/src/main/components/common/layout/BaseDialog.vue b/packages/frontend/src/main/components/common/layout/BaseDialog.vue new file mode 100644 index 000000000..22d782624 --- /dev/null +++ b/packages/frontend/src/main/components/common/layout/BaseDialog.vue @@ -0,0 +1,70 @@ + + diff --git a/packages/frontend/src/main/components/stream/branch/BranchSelect.vue b/packages/frontend/src/main/components/stream/branch/BranchSelect.vue new file mode 100644 index 000000000..586e1a6e7 --- /dev/null +++ b/packages/frontend/src/main/components/stream/branch/BranchSelect.vue @@ -0,0 +1,53 @@ + + diff --git a/packages/frontend/src/main/components/stream/commit/CommitMultiSelectToolbar.vue b/packages/frontend/src/main/components/stream/commit/CommitMultiSelectToolbar.vue new file mode 100644 index 000000000..9de72b2f4 --- /dev/null +++ b/packages/frontend/src/main/components/stream/commit/CommitMultiSelectToolbar.vue @@ -0,0 +1,74 @@ + + diff --git a/packages/frontend/src/main/dialogs/BranchEditDialog.vue b/packages/frontend/src/main/dialogs/BranchEditDialog.vue index 177b10539..326fb096c 100644 --- a/packages/frontend/src/main/dialogs/BranchEditDialog.vue +++ b/packages/frontend/src/main/dialogs/BranchEditDialog.vue @@ -85,6 +85,7 @@ import { gql } from '@apollo/client/core' import isNull from 'lodash/isNull' import isUndefined from 'lodash/isUndefined' import clone from 'lodash/clone' +import { StreamEvents } from '@/main/lib/core/helpers/eventHubHelper' export default { props: { @@ -190,7 +191,7 @@ export default { this.$eventHub.$emit('notification', { text: 'Branch deleted' }) this.$router.push(`/streams/` + this.$route.params.streamId) this.$emit('close') - this.$eventHub.$emit('branch-refresh') + this.$eventHub.$emit(StreamEvents.RefetchBranches) }, async updateBranch() { if (!this.$refs.form.validate()) return @@ -227,7 +228,7 @@ export default { } this.loading = false - this.$eventHub.$emit('branch-refresh') + this.$eventHub.$emit(StreamEvents.RefetchBranches) this.$eventHub.$emit('notification', { text: 'Branch updated', action: { diff --git a/packages/frontend/src/main/dialogs/commit/CommitsBatchActionsDialog.vue b/packages/frontend/src/main/dialogs/commit/CommitsBatchActionsDialog.vue new file mode 100644 index 000000000..c0efde1b5 --- /dev/null +++ b/packages/frontend/src/main/dialogs/commit/CommitsBatchActionsDialog.vue @@ -0,0 +1,200 @@ + + diff --git a/packages/frontend/src/main/lib/core/composables/core.ts b/packages/frontend/src/main/lib/core/composables/core.ts index b5af0a1c3..b05898173 100644 --- a/packages/frontend/src/main/lib/core/composables/core.ts +++ b/packages/frontend/src/main/lib/core/composables/core.ts @@ -25,12 +25,12 @@ export function useMixpanel(): OverridedMixpanel { } /** - * Composable that resolves whether the user is logged in through an Apollo query + * Composable that resolves user auth information through an Apollo query */ export function useIsLoggedIn() { const { result } = useQuery(IsLoggedInDocument) - const isLoggedIn = computed(() => !!result.value?.user?.id) const userId = computed(() => result.value?.user?.id) + const isLoggedIn = computed(() => !!userId.value) return { isLoggedIn, userId } } diff --git a/packages/frontend/src/main/lib/core/helpers/eventHubHelper.ts b/packages/frontend/src/main/lib/core/helpers/eventHubHelper.ts index 5fabc15ad..92a48ffea 100644 --- a/packages/frontend/src/main/lib/core/helpers/eventHubHelper.ts +++ b/packages/frontend/src/main/lib/core/helpers/eventHubHelper.ts @@ -29,12 +29,17 @@ export const GlobalEvents = Object.freeze({ */ export const StreamEvents = Object.freeze({ /** - * For triggering a refetch of stream data + * For triggering a refetch of main stream data */ Refetch: 'stream:refetch', /** * For triggering a refetch of stream collaborator data */ - RefetchCollaborators: 'stream:refetch:collaborators' + RefetchCollaborators: 'stream:refetch:collaborators', + + /** + * For triggering a refetch of stream branch data + */ + RefetchBranches: 'stream:refetch:branches' }) diff --git a/packages/frontend/src/main/lib/stream/composables/commitMultiActions.ts b/packages/frontend/src/main/lib/stream/composables/commitMultiActions.ts new file mode 100644 index 000000000..41990aeb6 --- /dev/null +++ b/packages/frontend/src/main/lib/stream/composables/commitMultiActions.ts @@ -0,0 +1,52 @@ +import { reduce } from 'lodash' +import { ref, computed } from 'vue' + +export enum BatchActionType { + Move = 'move', + Delete = 'delete' +} + +/** + * Composable for setting up commit multi-select & actions like delete, move etc. + */ +export function useCommitMultiActions() { + const selectedCommitsState = ref({} as Record) + const selectedCommitIds = computed(() => + reduce( + selectedCommitsState.value, + (res, val, key) => { + if (val) { + res.push(key) + } + + return res + }, + [] as string[] + ) + ) + + const clearSelectedCommits = () => { + selectedCommitsState.value = {} + } + + const hasSelectedCommits = computed(() => selectedCommitIds.value.length > 0) + + return { + /** + * Selected commit IDs (read-only) + */ + selectedCommitIds, + /** + * Object with selected commit keys and bool values + */ + selectedCommitsState, + /** + * Whether there are any selected commit ids + */ + hasSelectedCommits, + /** + * Clear selected commits + */ + clearSelectedCommits + } +} diff --git a/packages/frontend/src/main/navigation/StreamNav.vue b/packages/frontend/src/main/navigation/StreamNav.vue index 2e74ec888..f2a4186b1 100644 --- a/packages/frontend/src/main/navigation/StreamNav.vue +++ b/packages/frontend/src/main/navigation/StreamNav.vue @@ -226,6 +226,7 @@ import { STANDARD_PORTAL_KEYS, buildPortalStateMixin } from '@/main/utils/portalStateManager' +import { StreamEvents } from '@/main/lib/core/helpers/eventHubHelper' export default { components: { @@ -301,7 +302,7 @@ export default { }, mounted() { this.branchMenuOpen = this.$route.name.toLowerCase().includes('branch') - this.$eventHub.$on('branch-refresh', async () => { + this.$eventHub.$on(StreamEvents.RefetchBranches, async () => { await this.refetchBranches() }) this.$eventHub.$on('show-new-branch-dialog', () => { diff --git a/packages/frontend/src/main/pages/TheCommits.vue b/packages/frontend/src/main/pages/TheCommits.vue index e033e1f78..52eda4091 100644 --- a/packages/frontend/src/main/pages/TheCommits.vue +++ b/packages/frontend/src/main/pages/TheCommits.vue @@ -1,15 +1,16 @@