283 lines
6.9 KiB
Vue
283 lines
6.9 KiB
Vue
<template>
|
|
<Dialog
|
|
:options="{
|
|
title: '从 GitHub 添加应用',
|
|
size: 'xl',
|
|
actions: [
|
|
{
|
|
label: isAppOnBench ? '更新应用' : '添加应用',
|
|
variant: 'solid',
|
|
disabled: !app || !appValidated,
|
|
onClick: addAppHandler,
|
|
},
|
|
],
|
|
}"
|
|
v-model="show"
|
|
@update:modelValue="
|
|
() => {
|
|
show = false;
|
|
}
|
|
"
|
|
>
|
|
<template #body-content>
|
|
<FTabs :tabs="tabs" v-model="tabIndex">
|
|
<TabList v-slot="{ tab, selected }" class="pl-0">
|
|
<div
|
|
class="flex cursor-pointer items-center gap-1.5 border-b border-transparent py-3 text-base text-gray-600 duration-300 ease-in-out hover:border-gray-400 hover:text-gray-900 focus:outline-none focus:transition-none [&>div]:pl-0"
|
|
:class="{ 'text-gray-900': selected }"
|
|
>
|
|
<span>{{ tab.label }}</span>
|
|
</div>
|
|
</TabList>
|
|
<TabPanel v-slot="{ tab }">
|
|
<div class="-ml-0.5 p-1">
|
|
<div v-if="tab.value === 'public-github-app'" class="space-y-4">
|
|
<div class="mt-4 flex items-end space-x-2">
|
|
<FormControl
|
|
class="mb-0.5 grow"
|
|
label="GitHub URL"
|
|
v-model="githubAppLink"
|
|
autocomplete="off"
|
|
/>
|
|
<Button
|
|
v-if="!selectedBranch"
|
|
label="获取分支"
|
|
:loading="$resources.branches.loading"
|
|
@click="
|
|
$resources.branches.submit({
|
|
owner: appOwner,
|
|
name: appName,
|
|
})
|
|
"
|
|
/>
|
|
<Autocomplete
|
|
v-else
|
|
:options="branchOptions"
|
|
v-model="selectedBranch"
|
|
>
|
|
<template v-slot:target="{ togglePopover }">
|
|
<Button
|
|
:label="selectedBranch?.value || selectedBranch"
|
|
icon-right="chevron-down"
|
|
@click="() => togglePopover()"
|
|
/>
|
|
</template>
|
|
</Autocomplete>
|
|
</div>
|
|
</div>
|
|
<div v-else-if="tab.value === 'your-github-app'" class="pt-4">
|
|
<GitHubAppSelector
|
|
@validateApp="validateApp"
|
|
@fieldChange="appValidated = false"
|
|
/>
|
|
</div>
|
|
<div class="mt-4 space-y-2">
|
|
<div
|
|
v-if="$resources.validateApp.loading && !appValidated"
|
|
class="flex text-base text-gray-700"
|
|
>
|
|
<LoadingIndicator class="mr-2 w-4" />
|
|
正在验证应用...
|
|
</div>
|
|
<div
|
|
v-if="appValidated && app"
|
|
class="flex text-base text-gray-700"
|
|
>
|
|
<GreenCheckIcon class="mr-2 w-4" />
|
|
找到 {{ app.title }} ({{ app.name }})
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</TabPanel>
|
|
</FTabs>
|
|
<AlertBanner
|
|
v-if="isAppOnBench"
|
|
class="mt-4"
|
|
:show-icon="false"
|
|
:title="
|
|
`应用 <strong>${app.name}</strong> 已存在于当前工作台。` +
|
|
`点击更新应用将更改应用源为所选源。`
|
|
"
|
|
type="warning"
|
|
/>
|
|
|
|
<ErrorMessage
|
|
:message="$resources.validateApp.error || $resources.branches.error"
|
|
/>
|
|
</template>
|
|
</Dialog>
|
|
</template>
|
|
|
|
<script>
|
|
import { FormControl, Tabs, TabList, TabPanel } from 'jingrow-ui';
|
|
import { DashboardError } from '../utils/error';
|
|
import GitHubAppSelector from './GitHubAppSelector.vue';
|
|
import AlertBanner from './AlertBanner.vue';
|
|
|
|
export default {
|
|
name: 'NewAppDialog',
|
|
components: {
|
|
GitHubAppSelector,
|
|
FTabs: Tabs,
|
|
FormControl,
|
|
AlertBanner,
|
|
TabPanel,
|
|
TabList,
|
|
},
|
|
props: {
|
|
group: {
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
},
|
|
emits: ['app-added'],
|
|
data() {
|
|
return {
|
|
show: true,
|
|
app: {},
|
|
tabIndex: 0,
|
|
githubAppLink: '',
|
|
selectedBranch: '',
|
|
appValidated: false,
|
|
selectedGithubUser: null,
|
|
selectedGithubRepository: null,
|
|
tabs: [
|
|
{
|
|
label: '公共 GitHub 应用',
|
|
value: 'public-github-app',
|
|
},
|
|
{
|
|
label: '您的 GitHub 应用',
|
|
value: 'your-github-app',
|
|
},
|
|
],
|
|
};
|
|
},
|
|
watch: {
|
|
tabIndex() {
|
|
this.app = null;
|
|
this.appValidated = false;
|
|
this.selectedBranch = '';
|
|
this.githubAppLink = '';
|
|
this.selectedGithubUser = null;
|
|
this.selectedGithubRepository = null;
|
|
this.$resources.branches.reset();
|
|
},
|
|
githubAppLink() {
|
|
this.selectedBranch = '';
|
|
this.appValidated = false;
|
|
},
|
|
selectedBranch(newSelectedBranch) {
|
|
if (this.appOwner && this.appName && newSelectedBranch)
|
|
this.$resources.validateApp.submit({
|
|
owner: this.appOwner,
|
|
repository: this.appName,
|
|
branch: newSelectedBranch.value,
|
|
installation: this.selectedGithubUser?.id,
|
|
});
|
|
},
|
|
},
|
|
resources: {
|
|
validateApp() {
|
|
return {
|
|
url: 'jcloud.api.github.app',
|
|
onSuccess(data) {
|
|
this.appValidated = true;
|
|
if (!data) {
|
|
return;
|
|
}
|
|
|
|
let repository_url = this.githubAppLink;
|
|
if (!repository_url) {
|
|
const repo_owner = this.selectedGithubUser?.login;
|
|
const repo = this.selectedGithubRepository || data.name;
|
|
repository_url = `https://github.com/${repo_owner}/${repo}`;
|
|
}
|
|
|
|
this.app = {
|
|
name: data.name,
|
|
title: data.title,
|
|
repository_url,
|
|
github_installation_id: this.selectedGithubUser?.id,
|
|
branch: this.selectedBranch.value,
|
|
};
|
|
},
|
|
};
|
|
},
|
|
branches() {
|
|
return {
|
|
url: 'jcloud.api.github.branches',
|
|
validate() {
|
|
const githubUrlRegex =
|
|
/^(https?:\/\/)?(www\.)?github\.com\/([a-zA-Z0-9_.\-]+)\/([a-zA-Z0-9_.\-]+)(\/)?$/;
|
|
const isValidUrl = githubUrlRegex.test(this.githubAppLink);
|
|
|
|
if (!isValidUrl) {
|
|
throw new DashboardError('请输入有效的 GitHub 链接');
|
|
}
|
|
},
|
|
onSuccess(data) {
|
|
if (this.tabIndex === 0)
|
|
this.selectedBranch = {
|
|
label: data[0].name,
|
|
value: data[0].name,
|
|
};
|
|
},
|
|
};
|
|
},
|
|
},
|
|
computed: {
|
|
appOwner() {
|
|
if (this.tabIndex === 0) {
|
|
const urlParts = this.githubAppLink.split('/');
|
|
if (urlParts.length < 4) return;
|
|
|
|
return urlParts[3];
|
|
}
|
|
},
|
|
appName() {
|
|
if (this.tabIndex === 0) {
|
|
const urlParts = this.githubAppLink.split('/');
|
|
if (urlParts.length < 5) return;
|
|
|
|
return urlParts[4].replace('.git', '');
|
|
}
|
|
},
|
|
branchOptions() {
|
|
return (this.$resources.branches.data || []).map((branch) => ({
|
|
label: branch.name,
|
|
value: branch.name,
|
|
}));
|
|
},
|
|
isAppOnBench() {
|
|
if (!this.app) {
|
|
return false;
|
|
}
|
|
|
|
for (const app of this.group.apps) {
|
|
if (app.app == this.app.name) return true;
|
|
}
|
|
|
|
return false;
|
|
},
|
|
},
|
|
methods: {
|
|
validateApp(data) {
|
|
this.selectedBranch = {
|
|
label: data.branch,
|
|
value: data.branch,
|
|
};
|
|
this.selectedGithubRepository = data.repository;
|
|
this.selectedGithubUser = data.selectedGithubUser;
|
|
this.$resources.validateApp.submit({
|
|
...data,
|
|
installation: data.selectedGithubUser.id,
|
|
});
|
|
},
|
|
addAppHandler() {
|
|
this.$emit('app-added', this.app, this.isAppOnBench);
|
|
this.show = false;
|
|
},
|
|
},
|
|
};
|
|
</script> |