mirror of https://github.com/rancher/dashboard.git
commit
87765eaea7
|
|
@ -13,7 +13,8 @@
|
|||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"envFile": "${workspaceFolder}/.env",
|
||||
"outputCapture": "std"
|
||||
}
|
||||
"outputCapture": "std",
|
||||
},
|
||||
]
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,8 +69,6 @@ BUTTON,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
A {
|
||||
@include link-color(var(--link-text), var(--link-hover-text));
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
$light : #6C6C76;
|
||||
|
||||
//dark secondary
|
||||
$ligher : #B6B6C2;
|
||||
$lighter : #B6B6C2;
|
||||
|
||||
// dark main text
|
||||
$lightest : #FFFFFF;
|
||||
|
|
@ -50,8 +50,9 @@
|
|||
|
||||
--login-bg : #{$darkest};
|
||||
--body-bg : #{$darker};
|
||||
--body-text : #{$lightest};
|
||||
--scrollbar-thumb : #{$lighter};
|
||||
--body-text : #{$lighter};
|
||||
--scrollbar-thumb : #{$medium};
|
||||
--scrollbar-thumb-dropdown : #{$darker};
|
||||
--header-bg : #{$primary};
|
||||
--box-bg : #{$darker};
|
||||
--border : #{$medium};
|
||||
|
|
@ -100,3 +101,4 @@
|
|||
--tabbed-border : #{$medium};
|
||||
--tabbed-container-bg : #{$darkest};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ $selected: rgba($primary, .5);
|
|||
--body-bg : white;
|
||||
--body-text : black;
|
||||
--scrollbar-thumb : #{$dark};
|
||||
--scrollbar-thumb-dropdown : #{$lighter};
|
||||
--scrollbar-track : transparent;
|
||||
--disabled-bg : #{$disabled};
|
||||
--header-bg : #{$primary};
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
font-family: inherit;
|
||||
}
|
||||
|
||||
|
||||
.v-select,
|
||||
.v-select * {
|
||||
box-sizing: border-box;
|
||||
|
|
@ -38,6 +39,11 @@
|
|||
text-align: left;
|
||||
list-style: none;
|
||||
background: var(--dropdown-bg);
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: var(--scrollbar-thumb-dropdown) !important;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.vs__dropdown-option {
|
||||
|
|
@ -80,6 +86,7 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
padding: 4px 6px 0 3px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.vs--searchable .vs__dropdown-toggle {
|
||||
|
|
@ -154,28 +161,6 @@ $transition-duration: 150ms;
|
|||
}
|
||||
}
|
||||
|
||||
.vs__selected {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #f0f0f0;
|
||||
border: 1px solid var(--dropdown-border);
|
||||
border-radius: 4px;
|
||||
color: #333;
|
||||
margin: 4px 2px 0px 2px;
|
||||
padding: 0 0.25em;
|
||||
}
|
||||
|
||||
.vs__deselect {
|
||||
display: inline-flex;
|
||||
appearance: none;
|
||||
margin-left: 4px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
fill: rgba(60,60,60,0.5);
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
}
|
||||
|
||||
/* States */
|
||||
|
||||
|
|
@ -192,3 +177,26 @@ $transition-duration: 150ms;
|
|||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.vs__selected {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #f0f0f0;
|
||||
border: 1px solid var(--dropdown-border);
|
||||
border-radius: 4px;
|
||||
color: var(--body-text);
|
||||
margin: 4px 2px 0px 2px;
|
||||
padding: 0 0.25em;
|
||||
}
|
||||
|
||||
.vs__deselect {
|
||||
display: inline-flex;
|
||||
appearance: none;
|
||||
margin-left: 4px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
fill: rgba(60,60,60,0.26);
|
||||
text-shadow: 0 1px 0 #fff
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,108 @@
|
|||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
export default {
|
||||
props: {
|
||||
// filter files displayed in dropdown - default to .yml and Dockerfile files
|
||||
filePattern: {
|
||||
type: RegExp,
|
||||
default: () => {
|
||||
new RegExp('^.*\.(yml)$|.*(Dockerfile)\..*', 'i');
|
||||
}
|
||||
},
|
||||
// page to redirect back to from GH
|
||||
path: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedRepo: null,
|
||||
selectedBranch: null,
|
||||
selectedFile: null
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState('github', ['repositories', 'branches', 'files', 'scopes']),
|
||||
hasPrivate() {
|
||||
return this.scopes.includes('repo');
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('github/getRepositories', { page: 0 });
|
||||
},
|
||||
methods: {
|
||||
selectRepo(repo) {
|
||||
this.selectedBranch = null;
|
||||
this.selectedRepo = repo;
|
||||
this.$emit('selectedRepo', repo);
|
||||
this.$store.dispatch('github/getBranches', { repo });
|
||||
},
|
||||
selectBranch(branch) {
|
||||
this.selectedBranch = branch;
|
||||
this.$emit('selectedBranch', branch);
|
||||
this.$store.dispatch('github/getContents', {
|
||||
repo: this.selectedRepo,
|
||||
branch: this.selectedBranch,
|
||||
filePattern: this.filePattern
|
||||
});
|
||||
},
|
||||
selectFile(file) {
|
||||
this.$emit('selectedFile', file);
|
||||
},
|
||||
expandScope() {
|
||||
this.$store.dispatch('auth/redirectToGithub', { scopes: ['repo'], route: this.path } );
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="!hasPrivate" class="expand-scope">
|
||||
<a
|
||||
href="#"
|
||||
class="text-primary bg-transparent"
|
||||
@click="expandScope"
|
||||
>
|
||||
grant access to private repos
|
||||
</a>
|
||||
</div>
|
||||
<div class="repo-dropdown">
|
||||
<v-select
|
||||
placeholder="Choose repository"
|
||||
:options="repositories"
|
||||
label="name"
|
||||
:value="selectedRepo"
|
||||
:clearable="false"
|
||||
@input="selectRepo"
|
||||
>
|
||||
</v-select>
|
||||
</div>
|
||||
<div class="branch-dropdown">
|
||||
<v-select
|
||||
v-if="selectedRepo"
|
||||
placeholder="Choose branch"
|
||||
:options="branches"
|
||||
label="name"
|
||||
:value="selectedBranch"
|
||||
:clearable="false"
|
||||
@input="selectBranch"
|
||||
>
|
||||
</v-select>
|
||||
</div>
|
||||
<div class="file-dropdown">
|
||||
<v-select
|
||||
v-if="selectedBranch"
|
||||
placeholder="Choose file"
|
||||
:options="files"
|
||||
label="path"
|
||||
:value="selectedFile"
|
||||
:clearable="false"
|
||||
@input="selectFile"
|
||||
>
|
||||
</v-select>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -28,7 +28,7 @@ export default {
|
|||
Security,
|
||||
Upgrading,
|
||||
Volumes,
|
||||
Footer,
|
||||
Footer
|
||||
},
|
||||
mixins: [CreateEditView],
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
"build": "./node_modules/.bin/nuxt build",
|
||||
"analyze": "./node_modules/.bin/nuxt build --analyze",
|
||||
"start": "./node_modules/.bin/nuxt start",
|
||||
"generate": "./node_modules/.bin/nuxt generate"
|
||||
"generate": "./node_modules/.bin/nuxt generate",
|
||||
"dev-debug": "node --inspect ./node_modules/.bin/nuxt"
|
||||
},
|
||||
"dependencies": {
|
||||
"@innologica/vue-dropdown-menu": "^0.1.3",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<script>
|
||||
export default {
|
||||
layout: 'unauthenticated',
|
||||
|
||||
layout: 'unauthenticated',
|
||||
async fetch({ store, route, redirect }) {
|
||||
const res = await store.dispatch('auth/verify', {
|
||||
code: route.query.code,
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ export const actions = {
|
|||
return authConfig;
|
||||
},
|
||||
|
||||
async redirectToGithub({ state, commit, dispatch }, opt) {
|
||||
async redirectToGithub({ state, commit, dispatch }, opt = {}) {
|
||||
const authConfig = await dispatch('getAuthProvider');
|
||||
|
||||
const nonce = randomStr(16);
|
||||
|
|
@ -71,10 +71,12 @@ export const actions = {
|
|||
if ( opt && opt.scopes ) {
|
||||
scopes.push(...opt.scopes);
|
||||
}
|
||||
|
||||
if (!opt.route) {
|
||||
opt.route = '/auth/verify';
|
||||
}
|
||||
const url = addParams(authConfig.redirectUrl, {
|
||||
scope: [...BASE_SCOPES, ...scopes].join(','),
|
||||
redirect_uri: `${ window.location.origin }/auth/verify${ (window.location.search || '').includes('spa') ? '?spa' : '' }`,
|
||||
redirect_uri: `${ window.location.origin }${ opt.route }${ (window.location.search || '').includes('spa') ? '?spa' : '' }`,
|
||||
state: nonce
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
export const state = function() {
|
||||
return {
|
||||
repositories: [],
|
||||
branches: [],
|
||||
files: [],
|
||||
scopes: []
|
||||
}
|
||||
;
|
||||
};
|
||||
|
||||
export const actions = {
|
||||
// queries on repos for which users have push permissions are paginated and unfilterable
|
||||
getRepositories({ commit }) {
|
||||
// eslint-disable-next-line prefer-const
|
||||
let page = 1;
|
||||
const getRepos = (page) => {
|
||||
let scopes;
|
||||
|
||||
fetch(`${ window.location.origin }/v1/github/user/repos?per_page=100&affiliation=owner,collaborator&page=${ page }`)
|
||||
.then((res) => {
|
||||
scopes = res.headers.get('x-oauth-scopes');
|
||||
|
||||
return res.json();
|
||||
})
|
||||
.then((json) => {
|
||||
if (json.length) {
|
||||
page++;
|
||||
commit('addToRepositories', { repos: json, scopes });
|
||||
|
||||
return getRepos(page);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
getRepos(page);
|
||||
},
|
||||
getBranches({ commit }, payload) {
|
||||
fetch(`${ window.location.origin }/v1/github/repos/${ payload.repo.owner.login }/${ payload.repo.name }/branches`)
|
||||
.then(res => res.json())
|
||||
.then((json) => {
|
||||
commit({ type: 'addBranches', branches: json });
|
||||
});
|
||||
},
|
||||
getContents({ commit }, payload) {
|
||||
fetch(`${ window.location.origin }/v1/github/repos/${ payload.repo.owner.login }/${ payload.repo.name }/git/trees/${ payload.branch.sha }?recursive=1`)
|
||||
.then(res => res.json())
|
||||
.then((json) => {
|
||||
const files = json.tree.filter(file => file.type === 'blob' && file.path.match(payload.filePattern));
|
||||
|
||||
commit({ type: 'addFiles', files });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const mutations = {
|
||||
addToRepositories(state, payload) {
|
||||
state.repositories = [...state.repositories, ...payload.repos];
|
||||
state.scopes = payload.scopes;
|
||||
},
|
||||
addBranches(state, payload) {
|
||||
state.branches = payload.branches;
|
||||
},
|
||||
addFiles(state, payload) {
|
||||
state.files = payload.files;
|
||||
}
|
||||
};
|
||||
Loading…
Reference in New Issue