mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-26 13:43:55 +03:00
parent
726afe8a9e
commit
04e97b8311
18 changed files with 384 additions and 606 deletions
771
package-lock.json
generated
771
package-lock.json
generated
File diff suppressed because it is too large
Load diff
10
package.json
10
package.json
|
@ -10,6 +10,7 @@
|
||||||
"@claviska/jquery-minicolors": "2.3.6",
|
"@claviska/jquery-minicolors": "2.3.6",
|
||||||
"@mcaptcha/vanilla-glue": "0.1.0-alpha-2",
|
"@mcaptcha/vanilla-glue": "0.1.0-alpha-2",
|
||||||
"@primer/octicons": "17.5.0",
|
"@primer/octicons": "17.5.0",
|
||||||
|
"@vue/compiler-sfc": "3.2.37",
|
||||||
"add-asset-webpack-plugin": "2.0.1",
|
"add-asset-webpack-plugin": "2.0.1",
|
||||||
"css-loader": "6.7.1",
|
"css-loader": "6.7.1",
|
||||||
"dropzone": "6.0.0-beta.2",
|
"dropzone": "6.0.0-beta.2",
|
||||||
|
@ -34,11 +35,10 @@
|
||||||
"tippy.js": "6.3.7",
|
"tippy.js": "6.3.7",
|
||||||
"tributejs": "5.1.3",
|
"tributejs": "5.1.3",
|
||||||
"uint8-to-base64": "0.2.0",
|
"uint8-to-base64": "0.2.0",
|
||||||
"vue": "2.6.14",
|
"vue": "3.2.37",
|
||||||
"vue-bar-graph": "1.3.1",
|
"vue-bar-graph": "2.0.0",
|
||||||
"vue-calendar-heatmap": "0.8.4",
|
"vue-loader": "17.0.0",
|
||||||
"vue-loader": "15.9.8",
|
"vue3-calendar-heatmap": "2.0.0",
|
||||||
"vue-template-compiler": "2.6.14",
|
|
||||||
"webpack": "5.74.0",
|
"webpack": "5.74.0",
|
||||||
"webpack-cli": "4.10.0",
|
"webpack-cli": "4.10.0",
|
||||||
"workbox-routing": "6.5.4",
|
"workbox-routing": "6.5.4",
|
||||||
|
|
|
@ -63,9 +63,9 @@
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
<div id="diff-file-list-container"></div>
|
<div id="diff-file-list"></div>
|
||||||
<div id="diff-container">
|
<div id="diff-container">
|
||||||
<div id="diff-file-tree-container"></div>
|
<div id="diff-file-tree"></div>
|
||||||
<div id="diff-file-boxes" class="sixteen wide column">
|
<div id="diff-file-boxes" class="sixteen wide column">
|
||||||
{{range $i, $file := .Diff.Files}}
|
{{range $i, $file := .Diff.Files}}
|
||||||
{{/*notice: the index of Diff.Files should not be used for element ID, because the index will be restarted from 0 when doing load-more for PRs with a lot of files*/}}
|
{{/*notice: the index of Diff.Files should not be used for element ID, because the index will be restarted from 0 when doing load-more for PRs with a lot of files*/}}
|
||||||
|
|
|
@ -19,7 +19,10 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
inline-template
|
inline-template
|
||||||
v-cloak
|
v-cloak
|
||||||
>
|
></repo-search>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template id="dashboard-repo-list-template">
|
||||||
<div>
|
<div>
|
||||||
<div v-if="!isOrganization" class="ui two item tabable menu">
|
<div v-if="!isOrganization" class="ui two item tabable menu">
|
||||||
<a :class="{item: true, active: tab === 'repos'}" @click="changeTab('repos')">{{.locale.Tr "repository"}}</a>
|
<a :class="{item: true, active: tab === 'repos'}" @click="changeTab('repos')">{{.locale.Tr "repository"}}</a>
|
||||||
|
@ -193,5 +196,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</repo-search>
|
</template>
|
||||||
</div>
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import {CalendarHeatmap} from 'vue-calendar-heatmap';
|
import {CalendarHeatmap} from 'vue3-calendar-heatmap';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ActivityHeatmap',
|
name: 'ActivityHeatmap',
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div ref="root">
|
||||||
<div v-if="loading" class="ui active centered inline loader"/>
|
<div v-if="loading" class="ui active centered inline loader"/>
|
||||||
<div v-if="!loading && issue !== null">
|
<div v-if="!loading && issue !== null">
|
||||||
<p><small>{{ issue.repository.full_name }} on {{ createdAt }}</small></p>
|
<p><small>{{ issue.repository.full_name }} on {{ createdAt }}</small></p>
|
||||||
|
@ -109,15 +109,16 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$root.$on('load-context-popup', (data, callback) => {
|
this.$refs.root.addEventListener('us-load-context-popup', (e) => {
|
||||||
|
const data = e.detail;
|
||||||
if (!this.loading && this.issue === null) {
|
if (!this.loading && this.issue === null) {
|
||||||
this.load(data, callback);
|
this.load(data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
load(data, callback) {
|
load(data) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.i18nErrorMessage = null;
|
this.i18nErrorMessage = null;
|
||||||
$.get(`${appSubUrl}/${data.owner}/${data.repo}/issues/${data.index}/info`).done((issue) => {
|
$.get(`${appSubUrl}/${data.owner}/${data.repo}/issues/${data.index}/info`).done((issue) => {
|
||||||
|
@ -130,9 +131,6 @@ export default {
|
||||||
}
|
}
|
||||||
}).always(() => {
|
}).always(() => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
if (callback) {
|
|
||||||
this.$nextTick(callback);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import Vue from 'vue';
|
import {createApp, nextTick} from 'vue';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import {initVueSvg, vueDelimiters} from './VueComponentLoader.js';
|
import {initVueSvg, vueDelimiters} from './VueComponentLoader.js';
|
||||||
import {initTooltip} from '../modules/tippy.js';
|
import {initTooltip} from '../modules/tippy.js';
|
||||||
|
|
||||||
const {appSubUrl, assetUrlPrefix, pageData} = window.config;
|
const {appSubUrl, assetUrlPrefix, pageData} = window.config;
|
||||||
|
|
||||||
function initVueComponents() {
|
function initVueComponents(app) {
|
||||||
Vue.component('repo-search', {
|
app.component('repo-search', {
|
||||||
delimiters: vueDelimiters,
|
delimiters: vueDelimiters,
|
||||||
props: {
|
props: {
|
||||||
searchLimit: {
|
searchLimit: {
|
||||||
|
@ -138,13 +138,14 @@ function initVueComponents() {
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
const el = document.getElementById('dashboard-repo-list');
|
||||||
this.changeReposFilter(this.reposFilter);
|
this.changeReposFilter(this.reposFilter);
|
||||||
for (const el of this.$el.querySelectorAll('.tooltip')) {
|
for (const elTooltip of el.querySelectorAll('.tooltip')) {
|
||||||
initTooltip(el);
|
initTooltip(elTooltip);
|
||||||
}
|
}
|
||||||
$(this.$el).find('.dropdown').dropdown();
|
$(el).find('.dropdown').dropdown();
|
||||||
this.setCheckboxes();
|
this.setCheckboxes();
|
||||||
Vue.nextTick(() => {
|
nextTick(() => {
|
||||||
this.$refs.search.focus();
|
this.$refs.search.focus();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -192,7 +193,7 @@ function initVueComponents() {
|
||||||
this.reposFilter = filter;
|
this.reposFilter = filter;
|
||||||
this.repos = [];
|
this.repos = [];
|
||||||
this.page = 1;
|
this.page = 1;
|
||||||
Vue.set(this.counts, `${filter}:${this.archivedFilter}:${this.privateFilter}`, 0);
|
this.counts[`${filter}:${this.archivedFilter}:${this.privateFilter}`] = 0;
|
||||||
this.searchRepos();
|
this.searchRepos();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -261,7 +262,7 @@ function initVueComponents() {
|
||||||
this.page = 1;
|
this.page = 1;
|
||||||
this.repos = [];
|
this.repos = [];
|
||||||
this.setCheckboxes();
|
this.setCheckboxes();
|
||||||
Vue.set(this.counts, `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`, 0);
|
this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = 0;
|
||||||
this.searchRepos();
|
this.searchRepos();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -283,7 +284,7 @@ function initVueComponents() {
|
||||||
this.page = 1;
|
this.page = 1;
|
||||||
this.repos = [];
|
this.repos = [];
|
||||||
this.setCheckboxes();
|
this.setCheckboxes();
|
||||||
Vue.set(this.counts, `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`, 0);
|
this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = 0;
|
||||||
this.searchRepos();
|
this.searchRepos();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -297,7 +298,7 @@ function initVueComponents() {
|
||||||
this.page = 1;
|
this.page = 1;
|
||||||
}
|
}
|
||||||
this.repos = [];
|
this.repos = [];
|
||||||
Vue.set(this.counts, `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`, 0);
|
this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = 0;
|
||||||
this.searchRepos();
|
this.searchRepos();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -331,7 +332,7 @@ function initVueComponents() {
|
||||||
if (searchedQuery === '' && searchedMode === '' && this.archivedFilter === 'both') {
|
if (searchedQuery === '' && searchedMode === '' && this.archivedFilter === 'both') {
|
||||||
this.reposTotalCount = count;
|
this.reposTotalCount = count;
|
||||||
}
|
}
|
||||||
Vue.set(this.counts, `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`, count);
|
this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = count;
|
||||||
this.finalPage = Math.ceil(count / this.searchLimit);
|
this.finalPage = Math.ceil(count / this.searchLimit);
|
||||||
this.updateHistory();
|
this.updateHistory();
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
|
@ -352,22 +353,20 @@ function initVueComponents() {
|
||||||
}
|
}
|
||||||
return 'octicon-repo';
|
return 'octicon-repo';
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
template: document.getElementById('dashboard-repo-list-template'),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function initDashboardRepoList() {
|
export function initDashboardRepoList() {
|
||||||
const el = document.getElementById('dashboard-repo-list');
|
const el = document.getElementById('dashboard-repo-list');
|
||||||
const dashboardRepoListData = pageData.dashboardRepoList || null;
|
const dashboardRepoListData = pageData.dashboardRepoList || null;
|
||||||
if (!el || !dashboardRepoListData) return;
|
if (!el || !dashboardRepoListData) return;
|
||||||
|
|
||||||
initVueSvg();
|
const app = createApp({
|
||||||
initVueComponents();
|
|
||||||
new Vue({
|
|
||||||
el,
|
|
||||||
delimiters: vueDelimiters,
|
delimiters: vueDelimiters,
|
||||||
data: () => {
|
data() {
|
||||||
return {
|
return {
|
||||||
searchLimit: dashboardRepoListData.searchLimit || 0,
|
searchLimit: dashboardRepoListData.searchLimit || 0,
|
||||||
subUrl: appSubUrl,
|
subUrl: appSubUrl,
|
||||||
|
@ -375,4 +374,7 @@ export function initDashboardRepoList() {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
initVueSvg(app);
|
||||||
|
initVueComponents(app);
|
||||||
|
app.mount(el);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<ol class="diff-detail-box diff-stats m-0" id="diff-files" v-if="fileListIsVisible">
|
<ol class="diff-detail-box diff-stats m-0" ref="root" v-if="fileListIsVisible">
|
||||||
<li v-for="file in files" :key="file.NameHash">
|
<li v-for="file in files" :key="file.NameHash">
|
||||||
<div class="bold df ac pull-right">
|
<div class="bold df ac pull-right">
|
||||||
<span v-if="file.IsBin" class="ml-1 mr-3">{{ binaryFileMessage }}</span>
|
<span v-if="file.IsBin" class="ml-1 mr-3">{{ binaryFileMessage }}</span>
|
||||||
|
@ -37,7 +37,7 @@ export default {
|
||||||
fileListIsVisible(newValue) {
|
fileListIsVisible(newValue) {
|
||||||
if (newValue === true) {
|
if (newValue === true) {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
for (const el of this.$el.querySelectorAll('.tooltip')) {
|
for (const el of this.$refs.root.querySelectorAll('.tooltip')) {
|
||||||
initTooltip(el);
|
initTooltip(el);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
v-show="fileTreeIsVisible"
|
v-if="fileTreeIsVisible"
|
||||||
id="diff-file-tree"
|
|
||||||
class="mr-3 mt-3 diff-detail-box"
|
class="mr-3 mt-3 diff-detail-box"
|
||||||
>
|
>
|
||||||
<!-- only render the tree if we're visible. in many cases this is something that doesn't change very often -->
|
<!-- only render the tree if we're visible. in many cases this is something that doesn't change very often -->
|
||||||
<div class="ui list" v-if="fileTreeIsVisible">
|
<div class="ui list">
|
||||||
<DiffFileTreeItem v-for="item in fileTree" :key="item.name" :item="item" />
|
<DiffFileTreeItem v-for="item in fileTree" :key="item.name" :item="item" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isIncomplete" id="diff-too-many-files-stats" class="pt-2">
|
<div v-if="isIncomplete" id="diff-too-many-files-stats" class="pt-2">
|
||||||
|
@ -117,6 +116,9 @@ export default {
|
||||||
const [toShow, toHide] = document.querySelectorAll('.diff-toggle-file-tree-button .icon');
|
const [toShow, toHide] = document.querySelectorAll('.diff-toggle-file-tree-button .icon');
|
||||||
toShow.classList.toggle('hide', visible); // hide the toShow icon if the tree is visible
|
toShow.classList.toggle('hide', visible); // hide the toShow icon if the tree is visible
|
||||||
toHide.classList.toggle('hide', !visible); // similarly
|
toHide.classList.toggle('hide', !visible); // similarly
|
||||||
|
|
||||||
|
const diffTree = document.getElementById('diff-file-tree');
|
||||||
|
diffTree.classList.toggle('hide', !visible);
|
||||||
},
|
},
|
||||||
loadMoreData() {
|
loadMoreData() {
|
||||||
this.isLoadingNewData = true;
|
this.isLoadingNewData = true;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Vue from 'vue';
|
import {createApp, nextTick} from 'vue';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import {vueDelimiters} from './VueComponentLoader.js';
|
import {vueDelimiters} from './VueComponentLoader.js';
|
||||||
|
|
||||||
|
@ -37,10 +37,14 @@ export function initRepoBranchTagDropdown(selector) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$data.remove();
|
$data.remove();
|
||||||
new Vue({
|
|
||||||
el: this,
|
// eslint-disable-next-line unicorn/no-this-assignment
|
||||||
|
const elRoot = this;
|
||||||
|
const view = createApp({
|
||||||
delimiters: vueDelimiters,
|
delimiters: vueDelimiters,
|
||||||
data,
|
data() {
|
||||||
|
return data;
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
filteredItems() {
|
filteredItems() {
|
||||||
const items = this.items.filter((item) => {
|
const items = this.items.filter((item) => {
|
||||||
|
@ -73,10 +77,10 @@ export function initRepoBranchTagDropdown(selector) {
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
this.noResults = this.$el.getAttribute('data-no-results');
|
this.noResults = elRoot.getAttribute('data-no-results');
|
||||||
this.canCreateBranch = this.$el.getAttribute('data-can-create-branch') === 'true';
|
this.canCreateBranch = elRoot.getAttribute('data-can-create-branch') === 'true';
|
||||||
this.branchForm = this.$el.getAttribute('data-branch-form');
|
this.branchForm = elRoot.getAttribute('data-branch-form');
|
||||||
switch (this.$el.getAttribute('data-view-type')) {
|
switch (elRoot.getAttribute('data-view-type')) {
|
||||||
case 'tree':
|
case 'tree':
|
||||||
this.isViewTree = true;
|
this.isViewTree = true;
|
||||||
break;
|
break;
|
||||||
|
@ -87,19 +91,19 @@ export function initRepoBranchTagDropdown(selector) {
|
||||||
this.isViewBranch = true;
|
this.isViewBranch = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.refName = this.$el.getAttribute('data-ref-name');
|
this.refName = elRoot.getAttribute('data-ref-name');
|
||||||
this.branchURLPrefix = this.$el.getAttribute('data-branch-url-prefix');
|
this.branchURLPrefix = elRoot.getAttribute('data-branch-url-prefix');
|
||||||
this.branchURLSuffix = this.$el.getAttribute('data-branch-url-suffix');
|
this.branchURLSuffix = elRoot.getAttribute('data-branch-url-suffix');
|
||||||
this.tagURLPrefix = this.$el.getAttribute('data-tag-url-prefix');
|
this.tagURLPrefix = elRoot.getAttribute('data-tag-url-prefix');
|
||||||
this.tagURLSuffix = this.$el.getAttribute('data-tag-url-suffix');
|
this.tagURLSuffix = elRoot.getAttribute('data-tag-url-suffix');
|
||||||
this.setAction = this.$el.getAttribute('data-set-action') === 'true';
|
this.setAction = elRoot.getAttribute('data-set-action') === 'true';
|
||||||
this.submitForm = this.$el.getAttribute('data-submit-form') === 'true';
|
this.submitForm = elRoot.getAttribute('data-submit-form') === 'true';
|
||||||
|
|
||||||
|
|
||||||
document.body.addEventListener('click', (event) => {
|
document.body.addEventListener('click', (event) => {
|
||||||
if (this.$el.contains(event.target)) return;
|
if (elRoot.contains(event.target)) return;
|
||||||
if (this.menuVisible) {
|
if (this.menuVisible) {
|
||||||
Vue.set(this, 'menuVisible', false);
|
this.menuVisible = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -135,7 +139,7 @@ export function initRepoBranchTagDropdown(selector) {
|
||||||
if (this.submitForm) {
|
if (this.submitForm) {
|
||||||
$(`#${this.branchForm}`).trigger('submit');
|
$(`#${this.branchForm}`).trigger('submit');
|
||||||
}
|
}
|
||||||
Vue.set(this, 'menuVisible', false);
|
this.menuVisible = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
createNewBranch() {
|
createNewBranch() {
|
||||||
|
@ -143,7 +147,7 @@ export function initRepoBranchTagDropdown(selector) {
|
||||||
$(this.$refs.newBranchForm).trigger('submit');
|
$(this.$refs.newBranchForm).trigger('submit');
|
||||||
},
|
},
|
||||||
focusSearchField() {
|
focusSearchField() {
|
||||||
Vue.nextTick(() => {
|
nextTick(() => {
|
||||||
this.$refs.searchField.focus();
|
this.$refs.searchField.focus();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -213,5 +217,6 @@ export function initRepoBranchTagDropdown(selector) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
view.mount(this);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Vue from 'vue';
|
import {createApp} from 'vue';
|
||||||
import {svgs} from '../svg.js';
|
import {svgs} from '../svg.js';
|
||||||
|
|
||||||
export const vueDelimiters = ['${', '}'];
|
export const vueDelimiters = ['${', '}'];
|
||||||
|
@ -8,13 +8,14 @@ export function initVueEnv() {
|
||||||
if (vueEnvInited) return;
|
if (vueEnvInited) return;
|
||||||
vueEnvInited = true;
|
vueEnvInited = true;
|
||||||
|
|
||||||
const isProd = window.config.runModeIsProd;
|
// As far as I could tell, this is no longer possible.
|
||||||
Vue.config.productionTip = false;
|
// But there seem not to be a guide what to do instead.
|
||||||
Vue.config.devtools = !isProd;
|
// const isProd = window.config.runModeIsProd;
|
||||||
|
// Vue.config.devtools = !isProd;
|
||||||
}
|
}
|
||||||
|
|
||||||
let vueSvgInited = false;
|
let vueSvgInited = false;
|
||||||
export function initVueSvg() {
|
export function initVueSvg(app) {
|
||||||
if (vueSvgInited) return;
|
if (vueSvgInited) return;
|
||||||
vueSvgInited = true;
|
vueSvgInited = true;
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ export function initVueSvg() {
|
||||||
.replace(/height="[0-9]+"/, 'v-bind:height="size"')
|
.replace(/height="[0-9]+"/, 'v-bind:height="size"')
|
||||||
.replace(/width="[0-9]+"/, 'v-bind:width="size"');
|
.replace(/width="[0-9]+"/, 'v-bind:width="size"');
|
||||||
|
|
||||||
Vue.component(name, {
|
app.component(name, {
|
||||||
props: {
|
props: {
|
||||||
size: {
|
size: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -42,8 +43,7 @@ export function initVueApp(el, opts = {}) {
|
||||||
}
|
}
|
||||||
if (!el) return null;
|
if (!el) return null;
|
||||||
|
|
||||||
return new Vue(Object.assign({
|
return createApp(
|
||||||
el,
|
Object.assign({delimiters: vueDelimiters}, opts)
|
||||||
delimiters: vueDelimiters,
|
).mount(el);
|
||||||
}, opts));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Vue from 'vue';
|
import {createApp} from 'vue';
|
||||||
import ContextPopup from '../components/ContextPopup.vue';
|
import ContextPopup from '../components/ContextPopup.vue';
|
||||||
import {parseIssueHref} from '../utils.js';
|
import {parseIssueHref} from '../utils.js';
|
||||||
import {createTippy} from '../modules/tippy.js';
|
import {createTippy} from '../modules/tippy.js';
|
||||||
|
@ -17,17 +17,12 @@ export default function initContextPopups() {
|
||||||
if (!owner) return;
|
if (!owner) return;
|
||||||
|
|
||||||
const el = document.createElement('div');
|
const el = document.createElement('div');
|
||||||
el.innerHTML = '<div></div>';
|
|
||||||
this.parentNode.insertBefore(el, this.nextSibling);
|
this.parentNode.insertBefore(el, this.nextSibling);
|
||||||
|
|
||||||
const View = Vue.extend({
|
const view = createApp(ContextPopup);
|
||||||
render: (createElement) => createElement(ContextPopup),
|
|
||||||
});
|
|
||||||
|
|
||||||
const view = new View();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
view.$mount(el.firstChild);
|
view.mount(el);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
el.textContent = 'ContextPopup failed to load';
|
el.textContent = 'ContextPopup failed to load';
|
||||||
|
@ -37,7 +32,7 @@ export default function initContextPopups() {
|
||||||
content: el,
|
content: el,
|
||||||
interactive: true,
|
interactive: true,
|
||||||
onShow: () => {
|
onShow: () => {
|
||||||
view.$emit('load-context-popup', {owner, repo, index});
|
el.firstChild.dispatchEvent(new CustomEvent('us-load-context-popup', {detail: {owner, repo, index}}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Vue from 'vue';
|
import {createApp} from 'vue';
|
||||||
import ActivityHeatmap from '../components/ActivityHeatmap.vue';
|
import ActivityHeatmap from '../components/ActivityHeatmap.vue';
|
||||||
|
|
||||||
export default function initHeatmap() {
|
export default function initHeatmap() {
|
||||||
|
@ -17,11 +17,9 @@ export default function initHeatmap() {
|
||||||
return {date: new Date(v), count: heatmap[v]};
|
return {date: new Date(v), count: heatmap[v]};
|
||||||
});
|
});
|
||||||
|
|
||||||
const View = Vue.extend({
|
const View = createApp(ActivityHeatmap, {values});
|
||||||
render: (createElement) => createElement(ActivityHeatmap, {props: {values}}),
|
|
||||||
});
|
|
||||||
|
|
||||||
new View().$mount(el);
|
View.mount(el);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Heatmap failed to load', err);
|
console.error('Heatmap failed to load', err);
|
||||||
el.textContent = 'Heatmap failed to load';
|
el.textContent = 'Heatmap failed to load';
|
||||||
|
|
|
@ -1,21 +1,17 @@
|
||||||
import Vue from 'vue';
|
import {createApp} from 'vue';
|
||||||
import DiffFileTree from '../components/DiffFileTree.vue';
|
import DiffFileTree from '../components/DiffFileTree.vue';
|
||||||
import DiffFileList from '../components/DiffFileList.vue';
|
import DiffFileList from '../components/DiffFileList.vue';
|
||||||
|
|
||||||
export default function initDiffFileTree() {
|
export default function initDiffFileTree() {
|
||||||
const el = document.getElementById('diff-file-tree-container');
|
const el = document.getElementById('diff-file-tree');
|
||||||
if (!el) return;
|
if (!el) return;
|
||||||
|
|
||||||
const View = Vue.extend({
|
const fileTreeView = createApp(DiffFileTree);
|
||||||
render: (createElement) => createElement(DiffFileTree),
|
fileTreeView.mount(el);
|
||||||
});
|
|
||||||
new View().$mount(el);
|
|
||||||
|
|
||||||
const fileListElement = document.getElementById('diff-file-list-container');
|
const fileListElement = document.getElementById('diff-file-list');
|
||||||
if (!fileListElement) return;
|
if (!fileListElement) return;
|
||||||
|
|
||||||
const fileListView = Vue.extend({
|
const fileListView = createApp(DiffFileList);
|
||||||
render: (createElement) => createElement(DiffFileList),
|
fileListView.mount(fileListElement);
|
||||||
});
|
|
||||||
new fileListView().$mount(fileListElement);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
import Vue from 'vue';
|
import {createApp} from 'vue';
|
||||||
import PullRequestMergeForm from '../components/PullRequestMergeForm.vue';
|
import PullRequestMergeForm from '../components/PullRequestMergeForm.vue';
|
||||||
|
|
||||||
export default function initPullRequestMergeForm() {
|
export default function initPullRequestMergeForm() {
|
||||||
const el = document.getElementById('pull-request-merge-form');
|
const el = document.getElementById('pull-request-merge-form');
|
||||||
if (!el) return;
|
if (!el) return;
|
||||||
|
|
||||||
const View = Vue.extend({
|
const view = createApp(PullRequestMergeForm);
|
||||||
render: (createElement) => createElement(PullRequestMergeForm),
|
view.mount(el);
|
||||||
});
|
|
||||||
new View().$mount(el);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,6 @@ import octiconSidebarExpand from '../../public/img/svg/octicon-sidebar-expand.sv
|
||||||
import octiconSidebarCollapse from '../../public/img/svg/octicon-sidebar-collapse.svg';
|
import octiconSidebarCollapse from '../../public/img/svg/octicon-sidebar-collapse.svg';
|
||||||
|
|
||||||
|
|
||||||
import Vue from 'vue';
|
|
||||||
|
|
||||||
export const svgs = {
|
export const svgs = {
|
||||||
'octicon-chevron-down': octiconChevronDown,
|
'octicon-chevron-down': octiconChevronDown,
|
||||||
'octicon-chevron-right': octiconChevronRight,
|
'octicon-chevron-right': octiconChevronRight,
|
||||||
|
@ -74,7 +72,8 @@ export function svg(name, size = 16, className = '') {
|
||||||
return serializer.serializeToString(svgNode);
|
return serializer.serializeToString(svgNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SvgIcon = Vue.component('SvgIcon', {
|
export const SvgIcon = {
|
||||||
|
name: 'SvgIcon',
|
||||||
props: {
|
props: {
|
||||||
name: {type: String, required: true},
|
name: {type: String, required: true},
|
||||||
size: {type: Number, default: 16},
|
size: {type: Number, default: 16},
|
||||||
|
@ -88,4 +87,4 @@ export const SvgIcon = Vue.component('SvgIcon', {
|
||||||
},
|
},
|
||||||
|
|
||||||
template: `<span v-html="svg" />`
|
template: `<span v-html="svg" />`
|
||||||
});
|
};
|
||||||
|
|
|
@ -3,10 +3,16 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
min-height: 125px;
|
min-height: 125px;
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
|
// for the "Less" and "More" legend
|
||||||
|
.vch__legend .vch__legend div:first-child,
|
||||||
|
.vch__legend .vch__legend div:last-child {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
> svg {
|
> svg {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,13 @@ import AddAssetPlugin from 'add-asset-webpack-plugin';
|
||||||
import LicenseCheckerWebpackPlugin from 'license-checker-webpack-plugin';
|
import LicenseCheckerWebpackPlugin from 'license-checker-webpack-plugin';
|
||||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
||||||
import MonacoWebpackPlugin from 'monaco-editor-webpack-plugin';
|
import MonacoWebpackPlugin from 'monaco-editor-webpack-plugin';
|
||||||
import VueLoader from 'vue-loader';
|
import {VueLoaderPlugin} from 'vue-loader';
|
||||||
import EsBuildLoader from 'esbuild-loader';
|
import EsBuildLoader from 'esbuild-loader';
|
||||||
import {parse, dirname} from 'path';
|
import {parse, dirname} from 'path';
|
||||||
import webpack from 'webpack';
|
import webpack from 'webpack';
|
||||||
import {fileURLToPath} from 'url';
|
import {fileURLToPath} from 'url';
|
||||||
import {readFileSync} from 'fs';
|
import {readFileSync} from 'fs';
|
||||||
|
|
||||||
const {VueLoaderPlugin} = VueLoader;
|
|
||||||
const {ESBuildMinifyPlugin} = EsBuildLoader;
|
const {ESBuildMinifyPlugin} = EsBuildLoader;
|
||||||
const {SourceMapDevToolPlugin} = webpack;
|
const {SourceMapDevToolPlugin} = webpack;
|
||||||
const formatLicenseText = (licenseText) => wrapAnsi(licenseText || '', 80).trim();
|
const formatLicenseText = (licenseText) => wrapAnsi(licenseText || '', 80).trim();
|
||||||
|
@ -242,9 +241,6 @@ export default {
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
symlinks: false,
|
symlinks: false,
|
||||||
alias: {
|
|
||||||
vue$: 'vue/dist/vue.esm.js', // needed because vue's default export is the runtime only
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
watchOptions: {
|
watchOptions: {
|
||||||
ignored: [
|
ignored: [
|
||||||
|
|
Loading…
Reference in a new issue