aboutsummaryrefslogtreecommitdiffhomepage
path: root/application/components/github/picker.vue
diff options
context:
space:
mode:
Diffstat (limited to 'application/components/github/picker.vue')
-rw-r--r--application/components/github/picker.vue158
1 files changed, 158 insertions, 0 deletions
diff --git a/application/components/github/picker.vue b/application/components/github/picker.vue
new file mode 100644
index 0000000..73520a1
--- /dev/null
+++ b/application/components/github/picker.vue
@@ -0,0 +1,158 @@
+<template>
+ <button v-if="!authorized()" @click="login">
+ <i class="fab fa-github" /> Login with GitHub
+ </button>
+ <span v-else>
+ <selector
+ id="repo"
+ label="Repository"
+ :choices="repositoryChoices"
+ v-model="repo"
+ />
+
+ <spinner v-if="loadingBranches" />
+ <selector
+ v-else
+ v-model="branch"
+ id="branch"
+ label="Branch"
+ :choices="branchChoices"
+ />
+
+ <spinner v-if="loadingKeyboard" />
+
+ <invalid-repo
+ v-if="loadKeyboardError === 'InvalidRepoError'"
+ :otherRepoOrBranchAvailable="repositoryChoices.length > 0 || branchChoices.length > 0"
+ @dismiss="clearSelection"
+ />
+
+ </span>
+
+</template>
+
+<script>
+import find from 'lodash/find'
+import map from 'lodash/map'
+
+import * as github from './api'
+import * as storage from './storage'
+import InvalidRepo from './invalid-repo.vue'
+import Selector from '../selector.vue'
+import Spinner from '../spinner.vue'
+
+export default {
+ name: 'GithubPicker',
+ components: { InvalidRepo, Selector, Spinner },
+ emits: ['select'],
+ data() {
+ return {
+ repo: null,
+ branch: null,
+ branches: [],
+ loadingBranches: false,
+ loadingKeyboard: false,
+ loadKeyboardError: null
+ }
+ },
+ mounted() {
+ if (!this.authorized()) {
+ return
+ }
+
+ const selectedRepository = storage.getPersistedRepository()
+
+ if (github.repositories.length === 1) {
+ this.repo = github.repositories[0].full_name
+ this.loadBranches()
+ } else if (selectedRepository && github.repositories.find(repo => repo.full_name === selectedRepository)) {
+ this.repo = selectedRepository
+ this.loadBranches()
+ }
+ },
+ watch: {
+ repo(value) {
+ storage.setPersistedRepository(value)
+ if (value) {
+ this.loadBranches()
+ }
+ },
+ branch(value) {
+ storage.setPersistedBranch(value)
+ if (value) {
+ this.loadKeyboard()
+ }
+ }
+ },
+ methods: {
+ authorized() {
+ return github.isGitHubAuthorized()
+ },
+ login() {
+ github.beginLoginFlow()
+ },
+ getRepositories() {
+ return github.repositories
+ },
+ async loadBranches() {
+ this.loadingBranches = true
+ this.branches = []
+
+ const repository = github.repositories.find(repo => repo.full_name === this.repo)
+ const branches = await github.fetchRepoBranches(repository)
+
+ this.loadingBranches = false
+ this.branches = branches
+
+ const available = map(branches, 'name')
+ const defaultBranch = repository.default_branch
+ const currentBranch = this.branch
+ const previousBranch = storage.getPersistedBranch()
+ const onlyBranch = branches.length === 1 ? branches[0].name : null
+
+ for (let branch of [onlyBranch, currentBranch, previousBranch, defaultBranch]) {
+ if (available.includes(branch)) {
+ this.branch = branch
+ break
+ }
+ }
+ },
+ async loadKeyboard() {
+ const available = this.getRepositories()
+ const repository = find(available, { full_name: this.repo })?.full_name
+ const branch = this.branch
+
+ this.loadingKeyboard = true
+ this.loadKeyboardError = null
+
+ const response = await github.fetchLayoutAndKeymap(repository, branch)
+
+ this.loadingKeyboard = false
+ if (response.error) {
+ this.loadKeyboardError = response.error
+ return
+ }
+
+ this.$emit('select', { github: { repository, branch }, ...response })
+ },
+ clearSelection() {
+ this.branch = null
+ this.loadKeyboardError = null
+ }
+ },
+ computed: {
+ repositoryChoices() {
+ return this.getRepositories().map(repo => ({
+ id: repo.full_name,
+ name: repo.full_name
+ }))
+ },
+ branchChoices() {
+ return this.branches.map(branch => ({
+ id: branch.name,
+ name: branch.name
+ }))
+ }
+ }
+}
+</script>