refactor: theme remote install. (halo-dev/console#249)

* refactor: theme remote install.

* refactor: theme remote install.
pull/3445/head
Ryan Wang 2020-09-22 22:23:56 +08:00 committed by GitHub
parent c06c9c6abe
commit 37ca43ad78
2 changed files with 283 additions and 240 deletions

View File

@ -105,6 +105,11 @@ Vue.use(Empty)
Vue.use(Result) Vue.use(Result)
Vue.use(Space) Vue.use(Space)
// message config
message.config({
maxCount: 1
})
Vue.prototype.$message = message Vue.prototype.$message = message
Vue.prototype.$notification = notification Vue.prototype.$notification = notification
Vue.prototype.$info = Modal.info Vue.prototype.$info = Modal.info

View File

@ -7,8 +7,8 @@
<a-button <a-button
key="2" key="2"
icon="reload" icon="reload"
:loading="themeLoading" :loading="list.loading"
@click="handleReload" @click="handleRefreshThemesCache"
> >
刷新 刷新
</a-button> </a-button>
@ -16,7 +16,7 @@
key="1" key="1"
type="primary" type="primary"
icon="plus" icon="plus"
@click="uploadThemeVisible = true" @click="installModal.visible = true"
> >
安装 安装
</a-button> </a-button>
@ -30,7 +30,7 @@
<a-list <a-list
:grid="{ gutter: 12, xs: 1, sm: 1, md: 2, lg: 4, xl: 4, xxl: 4 }" :grid="{ gutter: 12, xs: 1, sm: 1, md: 2, lg: 4, xl: 4, xxl: 4 }"
:dataSource="sortedThemes" :dataSource="sortedThemes"
:loading="themeLoading" :loading="list.loading"
> >
<a-list-item <a-list-item
slot="renderItem" slot="renderItem"
@ -69,7 +69,7 @@
style="margin-right:3px" style="margin-right:3px"
/> />
</div> </div>
<div @click="handleShowThemeSetting(item)"> <div @click="handleOpenThemeSettingDrawer(item)">
<a-icon <a-icon
type="setting" type="setting"
style="margin-right:3px" style="margin-right:3px"
@ -102,7 +102,7 @@
<a-menu-item <a-menu-item
:key="2" :key="2"
v-if="item.repo" v-if="item.repo"
@click="handleConfirmUpdate(item)" @click="handleConfirmRemoteUpdate(item)"
> >
<a-icon <a-icon
type="cloud" type="cloud"
@ -111,7 +111,7 @@
</a-menu-item> </a-menu-item>
<a-menu-item <a-menu-item
:key="3" :key="3"
@click="handleShowUpdateNewThemeModal(item)" @click="handleOpenLocalUpdateModal(item)"
> >
<a-icon <a-icon
type="file" type="file"
@ -128,18 +128,18 @@
</a-row> </a-row>
<ThemeSettingDrawer <ThemeSettingDrawer
:theme="selectedTheme" :theme="themeSettingDrawer.selected"
v-model="themeSettingVisible" v-model="themeSettingDrawer.visible"
@close="onThemeSettingsClose" @close="onThemeSettingsDrawerClose"
/> />
<a-modal <a-modal
title="安装主题" title="安装主题"
v-model="uploadThemeVisible" v-model="installModal.visible"
destroyOnClose destroyOnClose
:footer="null" :footer="null"
:bodyStyle="{ padding: '0 24px 24px' }" :bodyStyle="{ padding: '0 24px 24px' }"
:afterClose="onThemeUploadClose" :afterClose="onThemeInstallModalClose"
> >
<div class="custom-tab-wrapper"> <div class="custom-tab-wrapper">
<a-tabs> <a-tabs>
@ -152,8 +152,8 @@
name="file" name="file"
accept="application/zip" accept="application/zip"
label="点击选择主题包或将主题包拖拽到此处<br>仅支持 ZIP 格式的文件" label="点击选择主题包或将主题包拖拽到此处<br>仅支持 ZIP 格式的文件"
:uploadHandler="uploadHandler" :uploadHandler="installModal.local.uploadHandler"
@success="handleUploadSuccess" @success="handleUploadSucceed"
></FilePondUpload> ></FilePondUpload>
<a-alert <a-alert
type="info" type="info"
@ -172,84 +172,94 @@
tab="远程拉取" tab="远程拉取"
key="2" key="2"
> >
<a-form <a-form-model
v-if="!fetchBranches" ref="remoteInstallForm"
:model="installModal.remote"
:rules="installModal.remote.rules"
layout="vertical" layout="vertical"
> >
<a-form-item label="远程地址:"> <a-form-model-item
<a-input v-model="fetchingUrl" /> prop="url"
</a-form-item> label="Github 仓库地址:"
<a-form-item> >
<a-button <a-input-search
v-model="installModal.remote.url"
enter-button="获取版本"
@search="handleFetching"
:loading="installModal.remote.repoFetching"
/>
</a-form-model-item>
<a-form-model-item label="版本类型:">
<a-select v-model="installModal.remote.byBranchOrRelease">
<a-select-option value="release">发行版</a-select-option>
<a-select-option value="branch">开发版</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item
label="版本:"
v-show="installModal.remote.byBranchOrRelease ==='release'"
>
<a-select
v-model="installModal.remote.selectedRelease"
:loading="installModal.remote.repoFetching"
>
<a-select-option
v-for="(item, index) in installModal.remote.releases"
:key="index"
:value="item.branch"
>{{ item.branch }}</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item
label="分支:"
v-show="installModal.remote.byBranchOrRelease ==='branch'"
>
<a-select
v-model="installModal.remote.selectedBranch"
:loading="installModal.remote.repoFetching"
>
<a-select-option
v-for="(item, index) in installModal.remote.branches"
:key="index"
:value="item.branch"
>{{ item.branch }}</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item v-show="installModal.remote.byBranchOrRelease ==='release'">
<ReactiveButton
:disabled="!installModal.remote.selectedRelease"
type="primary" type="primary"
@click="handleFetching" @click="handleReleaseDownloading"
:loading="fetchButtonLoading" @callback="handleReleaseDownloadedCallback"
>获取</a-button> :loading="installModal.remote.releaseDownloading"
</a-form-item> :errored="installModal.remote.releaseDownloadErrored"
</a-form> text="下载"
<a-tabs v-else> loadedText="下载成功"
<a-tab-pane erroredText="下载失败"
tab="稳定版" ></ReactiveButton>
key="1" </a-form-model-item>
> <a-form-model-item v-show="installModal.remote.byBranchOrRelease ==='branch'">
<a-form layout="vertical"> <ReactiveButton
<a-form-item> type="primary"
<a-select @click="handleBranchPulling"
style="width: 120px" @callback="handleBranchPulledCallback"
@change="onSelectChange" :loading="installModal.remote.branchPulling"
> :errored="installModal.remote.branchPullErrored"
<a-select-option text="下载"
v-for="(item, index) in releases" loadedText="下载成功"
:key="index" erroredText="下载失败"
:value="index" ></ReactiveButton>
>{{ item.branch }}</a-select-option> </a-form-model-item>
</a-select> </a-form-model>
</a-form-item>
<a-form-item>
<a-button
type="primary"
@click="handleReleaseFetching"
>下载</a-button>
</a-form-item>
</a-form>
</a-tab-pane>
<a-tab-pane
tab="开发版"
key="2"
>
<a-form layout="vertical">
<a-form-item>
<a-select
style="width: 120px"
@change="onSelectChange"
>
<a-select-option
v-for="(item, index) in branches"
:key="index"
:value="index"
>{{ item.branch }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item>
<a-button
type="primary"
@click="handleBranchFetching"
>下载</a-button>
</a-form-item>
</a-form>
</a-tab-pane>
</a-tabs>
<a-alert <a-alert
type="info" type="info"
closable closable
> >
<template slot="message"> <template slot="message">
远程地址即主题仓库地址使用这种方式安装的一般为开发版本请谨慎使用 远程地址即主题仓库地址建议使用发行版本更多主题请访问
<br />更多主题请访问
<a <a
target="_blank" target="_blank"
href="https://halo.run/p/themes" href="https://halo.run/p/themes.html"
>https://halo.run/p/themes</a> >https://halo.run/p/themes</a>
</template> </template>
</a-alert> </a-alert>
@ -259,20 +269,20 @@
</a-modal> </a-modal>
<a-modal <a-modal
title="更新主题" title="更新主题"
v-model="uploadNewThemeVisible" v-model="localUpdateModel.visible"
:footer="null" :footer="null"
destroyOnClose destroyOnClose
:afterClose="onThemeUploadClose" :afterClose="onThemeInstallModalClose"
> >
<FilePondUpload <FilePondUpload
ref="updateByupload" ref="updateByupload"
name="file" name="file"
accept="application/zip" accept="application/zip"
label="点击选择主题更新包或将主题更新包拖拽到此处<br>仅支持 ZIP 格式的文件" label="点击选择主题更新包或将主题更新包拖拽到此处<br>仅支持 ZIP 格式的文件"
:uploadHandler="updateByUploadHandler" :uploadHandler="localUpdateModel.uploadHandler"
:filed="prepareUpdateTheme.id" :filed="localUpdateModel.selected.id"
:multiple="false" :multiple="false"
@success="handleUploadSuccess" @success="handleUploadSucceed"
></FilePondUpload> ></FilePondUpload>
</a-modal> </a-modal>
</page-view> </page-view>
@ -290,172 +300,194 @@ export default {
}, },
data() { data() {
return { return {
themeLoading: false, list: {
uploadThemeVisible: false, loading: false,
uploadNewThemeVisible: false, data: [],
fetchButtonLoading: false, },
fetchBranches: false,
themes: [], installModal: {
branches: [], visible: false,
releases: [], local: {
themeSettingVisible: false, uploadHandler: themeApi.upload,
selectedTheme: {}, },
selectedBranch: null,
fetchingUrl: null, remote: {
uploadHandler: themeApi.upload, url: null,
updateByUploadHandler: themeApi.updateByUpload,
prepareUpdateTheme: {}, repoFetching: false,
activatedTheme: null, repoFetchErrored: false,
branches: [],
selectedBranch: null,
branchPulling: false,
branchPullErrored: false,
releases: [],
selectedRelease: null,
releaseDownloading: false,
releaseDownloadErrored: false,
byBranchOrRelease: 'release', // release or branch, default is release
rules: {
url: [{ required: true, message: '* Github 仓库地址不能为空', trigger: ['change'] }],
},
},
},
localUpdateModel: {
visible: false,
uploadHandler: themeApi.updateByUpload,
selected: {},
},
themeSettingDrawer: {
visible: false,
selected: {},
},
} }
}, },
computed: { computed: {
sortedThemes() { sortedThemes() {
const data = this.themes.slice(0) const data = this.list.data.slice(0)
return data.sort((a, b) => { return data.sort((a, b) => {
return b.activated - a.activated return b.activated - a.activated
}) })
}, },
activatedTheme() {
if (this.sortedThemes.length > 0) {
return this.sortedThemes[0]
}
return null
},
}, },
created() { beforeMount() {
this.handleListThemes() this.handleListThemes()
this.handleGetActivatedTheme()
}, },
destroyed: function() { destroyed() {
this.$log.debug('Theme list destroyed.') this.$log.debug('Theme list destroyed.')
if (this.themeSettingVisible) { this.themeSettingDrawer.visible = false
this.themeSettingVisible = false this.installModal.visible = false
} this.localUpdateModel.visible = false
}, },
beforeRouteLeave(to, from, next) { beforeRouteLeave(to, from, next) {
if (this.themeSettingVisible) { this.themeSettingDrawer.visible = false
this.themeSettingVisible = false this.installModal.visible = false
} this.localUpdateModel.visible = false
next() next()
}, },
methods: { methods: {
handleGetActivatedTheme() {
themeApi.getActivatedTheme().then((response) => {
this.activatedTheme = response.data.data
})
},
handleListThemes() { handleListThemes() {
this.themeLoading = true this.list.loading = true
themeApi themeApi
.listAll() .listAll()
.then((response) => { .then((response) => {
this.themes = response.data.data this.list.data = response.data.data
}) })
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.themeLoading = false this.list.loading = false
}, 200) }, 200)
}) })
}, },
handleActiveTheme(theme) { handleRefreshThemesCache() {
themeApi
.active(theme.id)
.finally(() => {
this.handleListThemes()
})
.finally(() => {
this.handleGetActivatedTheme()
})
},
handleUpdateTheme(themeId) {
const hide = this.$message.loading('更新中...', 0)
themeApi
.update(themeId)
.then((response) => {
this.$message.success('更新成功!')
})
.finally(() => {
hide()
this.handleListThemes()
})
},
handleDeleteTheme(themeId) {
themeApi
.delete(themeId)
.then((response) => {
this.$message.success('删除成功!')
})
.finally(() => {
this.handleListThemes()
})
},
handleUploadSuccess() {
if (this.uploadThemeVisible) {
this.uploadThemeVisible = false
}
if (this.uploadNewThemeVisible) {
this.uploadNewThemeVisible = false
}
if (this.fetchBranches) {
this.fetchBranches = false
}
this.handleListThemes()
},
handleEditClick(theme) {
this.settingDrawer(theme)
},
handleFetching() {
if (!this.fetchingUrl) {
this.$notification['error']({
message: '提示',
description: '远程地址不能为空!',
})
return
}
this.fetchButtonLoading = true
themeApi.fetchingBranches(this.fetchingUrl).then((response) => {
this.branches = response.data.data
this.fetchBranches = true
})
themeApi
.fetchingReleases(this.fetchingUrl)
.then((response) => {
this.releases = response.data.data
})
.finally(() => {
setTimeout(() => {
this.fetchButtonLoading = false
}, 400)
})
},
handleBranchFetching() {
themeApi
.fetchingBranch(this.fetchingUrl, this.branches[this.selectedBranch].branch)
.then((response) => {
this.$message.success('拉取成功')
this.uploadThemeVisible = false
})
.finally(() => {
this.handleListThemes()
})
},
handleReleaseFetching() {
themeApi
.fetchingRelease(this.fetchingUrl, this.releases[this.selectedBranch].branch)
.then((response) => {
this.$message.success('拉取成功')
this.uploadThemeVisible = false
})
.finally(() => {
this.handleListThemes()
})
},
handleReload() {
themeApi.reload().finally(() => { themeApi.reload().finally(() => {
this.handleListThemes() this.handleListThemes()
}) })
}, },
handleShowUpdateNewThemeModal(item) { handleActiveTheme(theme) {
this.prepareUpdateTheme = item themeApi.active(theme.id).finally(() => {
this.uploadNewThemeVisible = true this.handleListThemes()
})
}, },
handleShowThemeSetting(theme) { handleDeleteTheme(themeId) {
this.selectedTheme = theme themeApi.delete(themeId).finally(() => {
this.themeSettingVisible = true this.handleListThemes()
})
},
handleUploadSucceed() {
this.installModal.visible = false
this.localUpdateModel.visible = false
this.handleListThemes()
},
handleFetching() {
const _this = this
_this.$refs.remoteInstallForm.validate((valid) => {
if (valid) {
_this.installModal.remote.repoFetching = true
themeApi.fetchingBranches(_this.installModal.remote.url).then((response) => {
const branches = response.data.data
_this.installModal.remote.branches = branches
if (branches && branches.length > 0) {
_this.installModal.remote.selectedBranch = branches[0].branch
}
})
themeApi
.fetchingReleases(_this.installModal.remote.url)
.then((response) => {
const releases = response.data.data
_this.installModal.remote.releases = releases
if (releases && releases.length > 0) {
_this.installModal.remote.selectedRelease = releases[0].branch
}
})
.finally(() => {
setTimeout(() => {
_this.installModal.remote.repoFetching = false
}, 400)
})
}
})
},
handleBranchPulling() {
this.installModal.remote.branchPulling = true
themeApi
.fetchingBranch(this.installModal.remote.url, this.installModal.remote.selectedBranch)
.catch(() => {
this.installModal.remote.branchPullErrored = true
})
.finally(() => {
setTimeout(() => {
this.installModal.remote.branchPulling = false
}, 400)
})
},
handleBranchPulledCallback() {
if (this.installModal.remote.branchPullErrored) {
this.installModal.remote.branchPullErrored = false
} else {
this.installModal.visible = false
this.handleListThemes()
}
},
handleReleaseDownloading() {
this.installModal.remote.releaseDownloading = true
themeApi
.fetchingRelease(this.installModal.remote.url, this.installModal.remote.selectedRelease)
.catch(() => {
this.installModal.remote.branchPullErrored = true
})
.finally(() => {
setTimeout(() => {
this.installModal.remote.releaseDownloading = false
}, 400)
})
},
handleReleaseDownloadedCallback() {
if (this.installModal.remote.releaseDownloadErrored) {
this.installModal.remote.releaseDownloadErrored = false
} else {
this.installModal.visible = false
this.handleListThemes()
}
},
handleOpenLocalUpdateModal(item) {
this.localUpdateModel.selected = item
this.localUpdateModel.visible = true
},
handleOpenThemeSettingDrawer(theme) {
this.themeSettingDrawer.selected = theme
this.themeSettingDrawer.visible = true
}, },
handleConfirmDelete(item) { handleConfirmDelete(item) {
const _this = this const _this = this
@ -469,39 +501,45 @@ export default {
onCancel() {}, onCancel() {},
}) })
}, },
handleConfirmUpdate(item) { handleConfirmRemoteUpdate(item) {
const that = this const _this = this
this.$confirm({ _this.$confirm({
title: '提示', title: '提示',
maskClosable: true, maskClosable: true,
content: '确定更新【' + item.name + '】主题?', content: '确定更新【' + item.name + '】主题?',
onOk() { onOk() {
that.handleUpdateTheme(item.id) const hide = _this.$message.loading('更新中...', 0)
themeApi
.update(item.id)
.then((response) => {
_this.$message.success('更新成功!')
})
.finally(() => {
hide()
_this.handleListThemes()
})
}, },
onCancel() {}, onCancel() {},
}) })
}, },
onSelectChange(value) { onThemeInstallModalClose() {
this.selectedBranch = value if (this.$refs.upload) {
},
onThemeUploadClose() {
if (this.uploadThemeVisible) {
this.$refs.upload.handleClearFileList() this.$refs.upload.handleClearFileList()
} }
if (this.uploadNewThemeVisible) { if (this.$refs.updateByupload) {
this.$refs.updateByupload.handleClearFileList() this.$refs.updateByupload.handleClearFileList()
} }
if (this.fetchBranches) { this.installModal.remote.branches = []
this.fetchBranches = false this.installModal.remote.selectedBranch = null
} this.installModal.remote.releases = []
if (this.selectedBranch) { this.installModal.remote.selectedRelease = null
this.selectedBranch = null this.installModal.remote.url = null
} this.installModal.remote.byBranchOrRelease = 'release'
this.handleListThemes() this.handleListThemes()
}, },
onThemeSettingsClose() { onThemeSettingsDrawerClose() {
this.themeSettingVisible = false this.themeSettingDrawer.visible = false
this.selectedTheme = {} this.themeSettingDrawer.selected = {}
}, },
}, },
} }