@@ -1,74 +1,64 @@
|
||||
<template>
|
||||
<v-card :loading="loading">
|
||||
<template slot="progress">
|
||||
<v-progress-linear indeterminate></v-progress-linear>
|
||||
</template>
|
||||
<div v-if="branch.name !== 'main'">
|
||||
<v-card-title>Edit Branch</v-card-title>
|
||||
<v-form ref="form" v-model="valid" lazy-validation @submit.prevent="updateBranch">
|
||||
<v-card-text>
|
||||
<v-text-field
|
||||
v-model="name"
|
||||
label="Name"
|
||||
:rules="nameRules"
|
||||
validate-on-blur
|
||||
required
|
||||
autofocus
|
||||
></v-text-field>
|
||||
<v-textarea v-model="description" rows="2" label="Description"></v-textarea>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn color="primary" block :disabled="!valid" type="submit">Save</v-btn>
|
||||
<v-dialog v-model="show" width="500" @keydown.esc="cancel">
|
||||
<v-card :loading="loading" class="pa-4">
|
||||
<template slot="progress">
|
||||
<v-progress-linear indeterminate></v-progress-linear>
|
||||
</template>
|
||||
<div v-if="branch && branch.name !== 'main'">
|
||||
<v-card-title>Edit Branch</v-card-title>
|
||||
<v-form ref="form" v-model="valid" lazy-validation @submit.prevent="agree">
|
||||
<v-card-text>
|
||||
<v-text-field
|
||||
v-model="branch.name"
|
||||
label="Name"
|
||||
:rules="nameRules"
|
||||
validate-on-blur
|
||||
required
|
||||
autofocus
|
||||
></v-text-field>
|
||||
<v-textarea v-model="branch.description" rows="2" label="Description"></v-textarea>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn text @click="cancel">Cancel</v-btn>
|
||||
<v-btn color="primary" text :disabled="!valid" type="submit">Save</v-btn>
|
||||
</v-card-actions>
|
||||
</v-form>
|
||||
<v-card-actions class="error--text body-2 pa-2">
|
||||
<v-btn block x-small text color="error" @click="showDelete = true">Delete Branch</v-btn>
|
||||
<v-dialog v-model="showDelete" max-width="500">
|
||||
<v-card>
|
||||
<v-card-title>Are you sure?</v-card-title>
|
||||
<v-card-text>
|
||||
You cannot undo this action. The branch
|
||||
<b>{{ branch.name }}</b>
|
||||
will be permanently deleted.
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn @click="showDelete = false">Cancel</v-btn>
|
||||
<v-btn color="error" text @click="deleteBranch">Delete</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-card-actions>
|
||||
</v-form>
|
||||
<v-card-actions class="error--text body-2 pa-2">
|
||||
<v-btn block x-small text color="error" @click="showDelete = true">Delete Branch</v-btn>
|
||||
<v-dialog v-model="showDelete" max-width="500">
|
||||
<v-card>
|
||||
<v-card-title>Are you sure?</v-card-title>
|
||||
<v-card-text>
|
||||
You cannot undo this action. The branch
|
||||
<b>{{ name }}</b>
|
||||
will be permanently deleted.
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn @click="showDelete = false">Cancel</v-btn>
|
||||
<v-btn color="error" text @click="deleteBranch">Delete</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-card-actions>
|
||||
</div>
|
||||
<div v-else>
|
||||
<v-card-text>You cannot edit the main branch.</v-card-text>
|
||||
</div>
|
||||
</v-card>
|
||||
</div>
|
||||
<div v-else>
|
||||
<v-card-text>You cannot edit the main branch.</v-card-text>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
streamId: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
branch: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
name: null,
|
||||
description: null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialog: false,
|
||||
branch: null,
|
||||
valid: true,
|
||||
loading: false,
|
||||
name: this.branch.name,
|
||||
showDelete: false,
|
||||
nameRules: [
|
||||
(v) => !!v || 'Branches need a name too!',
|
||||
@@ -78,7 +68,6 @@ export default {
|
||||
(v) => (v && v.length <= 100) || 'Name must be less than 100 characters',
|
||||
(v) => (v && v.length >= 3) || 'Name must be at least 3 characters'
|
||||
],
|
||||
description: this.branch.description,
|
||||
isEdit: false,
|
||||
pendingDelete: false,
|
||||
allBranchNames: []
|
||||
@@ -104,13 +93,26 @@ export default {
|
||||
}
|
||||
},
|
||||
update(data) {
|
||||
return data.stream.branches.items
|
||||
.map((b) => b.name)
|
||||
.filter((name) => name !== this.branch.name)
|
||||
return data.stream.branches.items.filter((b) => b.name !== this.branch.name)
|
||||
},
|
||||
skip() {
|
||||
return this.branch == null
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
show: {
|
||||
get() {
|
||||
return this.dialog
|
||||
},
|
||||
set(value) {
|
||||
this.dialog = value
|
||||
if (value === false) {
|
||||
this.cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
methods: {
|
||||
async deleteBranch() {
|
||||
this.loading = true
|
||||
@@ -132,10 +134,27 @@ export default {
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
this.$emit('close', { deleted: true })
|
||||
|
||||
this.loading = false
|
||||
|
||||
this.resolve({
|
||||
result: true,
|
||||
deleted: true
|
||||
})
|
||||
this.dialog = false
|
||||
},
|
||||
async updateBranch() {
|
||||
open(branch) {
|
||||
this.dialog = true
|
||||
if (this.$refs.form) this.$refs.form.resetValidation()
|
||||
|
||||
this.branch = { ...branch }
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.resolve = resolve
|
||||
this.reject = reject
|
||||
})
|
||||
},
|
||||
async agree() {
|
||||
if (!this.$refs.form.validate()) return
|
||||
|
||||
this.loading = true
|
||||
@@ -150,13 +169,25 @@ export default {
|
||||
params: {
|
||||
streamId: this.$route.params.streamId,
|
||||
id: this.branch.id,
|
||||
name: this.name,
|
||||
description: this.description
|
||||
name: this.branch.name,
|
||||
description: this.branch.description
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
this.loading = false
|
||||
this.$emit('close', { name: this.name })
|
||||
|
||||
this.resolve({
|
||||
result: true,
|
||||
name: this.branch.name
|
||||
})
|
||||
this.dialog = false
|
||||
},
|
||||
cancel() {
|
||||
this.resolve({
|
||||
result: false
|
||||
})
|
||||
this.dialog = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +1,39 @@
|
||||
<template>
|
||||
<v-card :loading="loading">
|
||||
<template slot="progress">
|
||||
<v-progress-linear indeterminate></v-progress-linear>
|
||||
</template>
|
||||
<v-card-title>New Branch</v-card-title>
|
||||
<v-form ref="form" v-model="valid" lazy-validation @submit.prevent="createBranch">
|
||||
<v-card-text>
|
||||
<v-text-field
|
||||
v-model="name"
|
||||
label="Name"
|
||||
:rules="nameRules"
|
||||
validate-on-blur
|
||||
required
|
||||
autofocus
|
||||
></v-text-field>
|
||||
<v-textarea v-model="description" rows="2" label="Description"></v-textarea>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="primary" text :disabled="!valid" type="submit">Save</v-btn>
|
||||
</v-card-actions>
|
||||
</v-form>
|
||||
</v-card>
|
||||
<v-dialog v-model="show" width="500" @keydown.esc="cancel">
|
||||
<v-card :loading="loading">
|
||||
<template slot="progress">
|
||||
<v-progress-linear indeterminate></v-progress-linear>
|
||||
</template>
|
||||
<v-card-title>New Branch</v-card-title>
|
||||
<v-form ref="form" v-model="valid" lazy-validation @submit.prevent="agree">
|
||||
<v-card-text>
|
||||
<v-text-field
|
||||
v-model="name"
|
||||
label="Name"
|
||||
:rules="nameRules"
|
||||
validate-on-blur
|
||||
required
|
||||
autofocus
|
||||
></v-text-field>
|
||||
<v-textarea v-model="description" rows="2" label="Description"></v-textarea>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="primary" text :disabled="!valid" type="submit">Save</v-btn>
|
||||
</v-card-actions>
|
||||
</v-form>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
streamId: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
branchNames: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialog: false,
|
||||
streamId: null,
|
||||
branchNames: [],
|
||||
valid: false,
|
||||
loading: false,
|
||||
name: null,
|
||||
@@ -58,9 +53,33 @@ export default {
|
||||
pendingDelete: false
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
computed: {
|
||||
show: {
|
||||
get() {
|
||||
return this.dialog
|
||||
},
|
||||
set(value) {
|
||||
this.dialog = value
|
||||
if (value === false) {
|
||||
this.cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async createBranch() {
|
||||
open(streamId, branchNames) {
|
||||
this.dialog = true
|
||||
if (this.$refs.form) this.$refs.form.resetValidation()
|
||||
|
||||
this.branchNames = branchNames
|
||||
this.streamId = streamId
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.resolve = resolve
|
||||
this.reject = reject
|
||||
})
|
||||
},
|
||||
async agree() {
|
||||
if (!this.$refs.form.validate()) return
|
||||
|
||||
this.loading = true
|
||||
@@ -80,8 +99,19 @@ export default {
|
||||
}
|
||||
})
|
||||
this.loading = false
|
||||
this.$emit('close')
|
||||
|
||||
this.resolve({
|
||||
result: true,
|
||||
name: this.name
|
||||
})
|
||||
this.dialog = false
|
||||
}
|
||||
},
|
||||
cancel() {
|
||||
this.resolve({
|
||||
result: false
|
||||
})
|
||||
this.dialog = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -5,13 +5,8 @@
|
||||
<v-skeleton-loader type="article"></v-skeleton-loader>
|
||||
</v-card>
|
||||
<v-card v-else rounded="lg" class="pa-4 mb-4" elevation="0">
|
||||
<v-dialog v-model="dialogBranch" max-width="500">
|
||||
<new-branch-dialog
|
||||
:branch-names="branches.map((b) => b.name)"
|
||||
:stream-id="$route.params.streamId"
|
||||
@close="closeBranchDialog"
|
||||
/>
|
||||
</v-dialog>
|
||||
<branch-new-dialog ref="newBranchDialog" />
|
||||
|
||||
<v-card-title>
|
||||
<v-icon class="mr-2">mdi-source-branch</v-icon>
|
||||
Branches
|
||||
@@ -24,7 +19,7 @@
|
||||
text
|
||||
class="px-0"
|
||||
small
|
||||
@click="dialogBranch = true"
|
||||
@click="newBranch"
|
||||
>
|
||||
<v-icon small class="mr-2 float-left">mdi-plus-circle-outline</v-icon>
|
||||
New branch
|
||||
@@ -71,14 +66,14 @@
|
||||
</v-row>
|
||||
</template>
|
||||
<script>
|
||||
import NewBranchDialog from '../components/dialogs/BranchNewDialog'
|
||||
import BranchNewDialog from '../components/dialogs/BranchNewDialog'
|
||||
import streamBranchesQuery from '../graphql/streamBranches.gql'
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export default {
|
||||
name: 'StreamMain',
|
||||
components: {
|
||||
NewBranchDialog
|
||||
BranchNewDialog
|
||||
},
|
||||
props: {
|
||||
userRole: {
|
||||
@@ -87,9 +82,7 @@ export default {
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogBranch: false
|
||||
}
|
||||
return {}
|
||||
},
|
||||
apollo: {
|
||||
stream: {
|
||||
@@ -170,9 +163,18 @@ export default {
|
||||
this.$apollo.queries.stream.refetch()
|
||||
},
|
||||
methods: {
|
||||
closeBranchDialog() {
|
||||
this.dialogBranch = false
|
||||
this.$apollo.queries.stream.refetch()
|
||||
newBranch() {
|
||||
this.$refs.newBranchDialog
|
||||
.open(
|
||||
this.$route.params.streamId,
|
||||
this.branches.map((b) => b.name)
|
||||
)
|
||||
.then((dialog) => {
|
||||
if (!dialog.result) return
|
||||
else {
|
||||
this.$apollo.queries.stream.refetch()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
</v-col>
|
||||
<v-col v-else-if="stream.branch" cols="12">
|
||||
<v-card class="pa-4" elevation="0" rounded="lg">
|
||||
<v-dialog v-model="dialogEdit" max-width="500">
|
||||
<branch-edit-dialog :branch="stream.branch" @close="closeEdit" />
|
||||
</v-dialog>
|
||||
<branch-edit-dialog ref="editBranchDialog" />
|
||||
|
||||
<v-card-title class="mr-8">
|
||||
<v-icon class="mr-2">mdi-source-branch</v-icon>
|
||||
<span class="d-inline-block">{{ stream.branch.name }}</span>
|
||||
@@ -20,7 +19,7 @@
|
||||
color="primary"
|
||||
text
|
||||
class="px-0"
|
||||
@click="dialogEdit = true"
|
||||
@click="editBranch"
|
||||
>
|
||||
<v-icon small class="mr-2 float-left">mdi-cog-outline</v-icon>
|
||||
Edit branch
|
||||
@@ -144,19 +143,21 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
closeEdit({ name, deleted }) {
|
||||
this.dialogEdit = false
|
||||
if (deleted) {
|
||||
this.$router.push({ path: `/streams/${this.streamId}` })
|
||||
return
|
||||
}
|
||||
if (name !== this.$route.params.branchName) {
|
||||
this.$router.push({
|
||||
path: `/streams/${this.streamId}/branches/${encodeURIComponent(name)}/commits`
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$apollo.queries.stream.refetch()
|
||||
editBranch() {
|
||||
this.$refs.editBranchDialog.open(this.stream.branch).then((dialog) => {
|
||||
if (!dialog.result) return
|
||||
else if (dialog.deleted) {
|
||||
this.$router.push({ path: `/streams/${this.streamId}` })
|
||||
} else if (dialog.name !== this.$route.params.branchName) {
|
||||
//this.$router.push does not work, refresh entire window
|
||||
|
||||
this.$router.push({
|
||||
path: `/streams/${this.streamId}/branches/${encodeURIComponent(dialog.name)}/commits`
|
||||
})
|
||||
} else {
|
||||
this.$apollo.queries.stream.refetch()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,82 @@
|
||||
<v-icon class="mr-2 float-left">mdi-source-branch</v-icon>
|
||||
{{ branches.length }} branch{{ branches.length > 1 ? 'es' : '' }}
|
||||
</v-btn>
|
||||
|
||||
<!-- DIALOGS -->
|
||||
<branch-new-dialog ref="newBranchDialog" />
|
||||
<branch-edit-dialog ref="editBranchDialog" />
|
||||
|
||||
<!-- MENU -->
|
||||
|
||||
<v-menu
|
||||
v-if="userRole === 'contributor' || userRole === 'owner'"
|
||||
offset-y
|
||||
class="mx-2 mb-5"
|
||||
>
|
||||
<template #activator="{ on, attrs }">
|
||||
<v-btn
|
||||
style="position: absolute; top: 36px; right: 20px"
|
||||
color="primary"
|
||||
v-bind="attrs"
|
||||
icon
|
||||
v-on="on"
|
||||
>
|
||||
<v-icon>mdi-dots-vertical</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-list>
|
||||
<v-list-item @click="newBranch">
|
||||
<v-list-item-action class="mr-2">
|
||||
<v-icon>mdi-plus-circle-outline</v-icon>
|
||||
</v-list-item-action>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>New branch</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
<v-list-item
|
||||
v-if="selectedBranch && selectedBranch.name != 'main'"
|
||||
@click="editBranch"
|
||||
>
|
||||
<v-list-item-action class="mr-2">
|
||||
<v-icon>mdi-cog-outline</v-icon>
|
||||
</v-list-item-action>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>Edit {{ selectedBranch.name }}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
<div
|
||||
v-if="
|
||||
stream &&
|
||||
stream.commit &&
|
||||
stream.commit.branchName != 'main' &&
|
||||
stream.commit.branchName != selectedBranch.name
|
||||
"
|
||||
class="pb-2 caption"
|
||||
>
|
||||
<v-alert color="primary" class="caption" dense text type="info">
|
||||
The last commit of this stream is on the
|
||||
<v-btn
|
||||
text
|
||||
x-small
|
||||
color="primary darken-1"
|
||||
:to="'/streams/' + $route.params.streamId + '/branches/' + stream.commit.branchName"
|
||||
>
|
||||
{{ stream.commit.branchName }}
|
||||
</v-btn>
|
||||
branch, see
|
||||
<v-btn
|
||||
x-small
|
||||
text
|
||||
color="primary darken-1"
|
||||
:to="'/streams/' + $route.params.streamId + '/commits/' + stream.commit.id"
|
||||
>
|
||||
{{ stream.commit.message }}
|
||||
</v-btn>
|
||||
</v-alert>
|
||||
</div>
|
||||
</v-sheet>
|
||||
|
||||
<div v-if="latestCommit" style="height: 50vh">
|
||||
@@ -152,7 +228,7 @@
|
||||
/>
|
||||
</v-dialog>
|
||||
<v-card-title>
|
||||
Description
|
||||
Stream Description
|
||||
<v-spacer />
|
||||
<v-btn
|
||||
v-if="userRole === 'owner'"
|
||||
@@ -193,6 +269,8 @@ import streamBranchesQuery from '../graphql/streamBranches.gql'
|
||||
import Renderer from '../components/Renderer'
|
||||
import UserAvatar from '../components/UserAvatar'
|
||||
import ErrorBlock from '../components/ErrorBlock'
|
||||
import BranchNewDialog from '../components/dialogs/BranchNewDialog'
|
||||
import BranchEditDialog from '../components/dialogs/BranchEditDialog'
|
||||
|
||||
export default {
|
||||
name: 'StreamMain',
|
||||
@@ -202,7 +280,9 @@ export default {
|
||||
SourceAppAvatar,
|
||||
NoDataPlaceholder,
|
||||
Renderer,
|
||||
ErrorBlock
|
||||
ErrorBlock,
|
||||
BranchNewDialog,
|
||||
BranchEditDialog
|
||||
},
|
||||
props: {
|
||||
userRole: {
|
||||
@@ -213,10 +293,11 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
dialogDescription: false,
|
||||
dialogBranch: false,
|
||||
selectedBranch: null,
|
||||
clearRendererTrigger: 0,
|
||||
error: ''
|
||||
error: '',
|
||||
dialogBranchNew: false,
|
||||
dialogBranchEdit: false
|
||||
}
|
||||
},
|
||||
apollo: {
|
||||
@@ -247,6 +328,26 @@ export default {
|
||||
},
|
||||
update: (data) => data.stream.description
|
||||
},
|
||||
stream: {
|
||||
query: gql`
|
||||
query($id: String!) {
|
||||
stream(id: $id) {
|
||||
id
|
||||
commit {
|
||||
branchName
|
||||
id
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables() {
|
||||
return {
|
||||
id: this.$route.params.streamId
|
||||
}
|
||||
}
|
||||
//update: (data) => data.stream.description
|
||||
},
|
||||
$subscribe: {
|
||||
branchCreated: {
|
||||
query: gql`
|
||||
@@ -337,9 +438,42 @@ export default {
|
||||
this.dialogDescription = false
|
||||
this.$apollo.queries.description.refetch()
|
||||
},
|
||||
closeBranchDialog() {
|
||||
this.dialogBranch = false
|
||||
this.$apollo.queries.branches.refetch()
|
||||
editBranch() {
|
||||
this.$refs.editBranchDialog.open(this.selectedBranch).then((dialog) => {
|
||||
if (!dialog.result) return
|
||||
else if (dialog.deleted) {
|
||||
this.$router.push({ path: `/streams/${this.$route.params.streamId}` })
|
||||
} else if (dialog.name !== this.selectedBranch.name) {
|
||||
//this.$router.push does not work, refresh entire window
|
||||
window.location =
|
||||
window.origin +
|
||||
'/streams/' +
|
||||
this.$route.params.streamId +
|
||||
'/branches/' +
|
||||
encodeURIComponent(dialog.name)
|
||||
} else {
|
||||
this.$apollo.queries.branches.refetch()
|
||||
}
|
||||
})
|
||||
},
|
||||
newBranch() {
|
||||
this.$refs.newBranchDialog
|
||||
.open(
|
||||
this.$route.params.streamId,
|
||||
this.branches.map((b) => b.name)
|
||||
)
|
||||
.then((dialog) => {
|
||||
if (!dialog.result) return
|
||||
else {
|
||||
//this.$router.push does not work, refresh entire window
|
||||
window.location =
|
||||
window.origin +
|
||||
'/streams/' +
|
||||
this.$route.params.streamId +
|
||||
'/branches/' +
|
||||
encodeURIComponent(dialog.name)
|
||||
}
|
||||
})
|
||||
},
|
||||
selectBranch() {
|
||||
if (!this.branches) return
|
||||
|
||||
Reference in New Issue
Block a user