Enable Typescript noImplicitThis
(#33250)
- Enable https://www.typescriptlang.org/tsconfig/#noImplicitThis - Wrap Vue Template-Syntax SFCs in [`defineComponent`](https://vuejs.org/api/general#definecomponent) which makes type inference and linter work better - Move `createApp` calls outside the SFCs into separate files - Use [`PropType`](https://vuejs.org/api/utility-types#proptype-t) where appropriate - Some top-level component properties changed order as dictated by the linter - Fix all tsc and lint issues that popped up during these refactors
This commit is contained in:
parent
b15d01b0ce
commit
4b21a6c792
29 changed files with 209 additions and 190 deletions
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import {createApp, nextTick} from 'vue';
|
||||
import {nextTick, defineComponent} from 'vue';
|
||||
import {SvgIcon} from '../svg.ts';
|
||||
import {GET} from '../modules/fetch.ts';
|
||||
import {fomanticQuery} from '../modules/fomantic/base.ts';
|
||||
|
@ -24,7 +24,7 @@ const commitStatus: CommitStatusMap = {
|
|||
warning: {name: 'gitea-exclamation', color: 'yellow'},
|
||||
};
|
||||
|
||||
const sfc = {
|
||||
export default defineComponent({
|
||||
components: {SvgIcon},
|
||||
data() {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
|
@ -335,16 +335,8 @@ const sfc = {
|
|||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export function initDashboardRepoList() {
|
||||
const el = document.querySelector('#dashboard-repo-list');
|
||||
if (el) {
|
||||
createApp(sfc).mount(el);
|
||||
}
|
||||
}
|
||||
|
||||
export default sfc; // activate the IDE's Vue plugin
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<script lang="ts">
|
||||
import {defineComponent} from 'vue';
|
||||
import {SvgIcon} from '../svg.ts';
|
||||
import {GET} from '../modules/fetch.ts';
|
||||
import {generateAriaId} from '../modules/fomantic/base.ts';
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
components: {SvgIcon},
|
||||
data: () => {
|
||||
const el = document.querySelector('#diff-commit-select');
|
||||
|
@ -55,11 +56,11 @@ export default {
|
|||
switch (event.key) {
|
||||
case 'ArrowDown': // select next element
|
||||
event.preventDefault();
|
||||
this.focusElem(item.nextElementSibling, item);
|
||||
this.focusElem(item.nextElementSibling as HTMLElement, item);
|
||||
break;
|
||||
case 'ArrowUp': // select previous element
|
||||
event.preventDefault();
|
||||
this.focusElem(item.previousElementSibling, item);
|
||||
this.focusElem(item.previousElementSibling as HTMLElement, item);
|
||||
break;
|
||||
case 'Escape': // close menu
|
||||
event.preventDefault();
|
||||
|
@ -118,9 +119,9 @@ export default {
|
|||
// set correct tabindex to allow easier navigation
|
||||
this.$nextTick(() => {
|
||||
if (this.menuVisible) {
|
||||
this.focusElem(this.$refs.showAllChanges, this.$refs.expandBtn);
|
||||
this.focusElem(this.$refs.showAllChanges as HTMLElement, this.$refs.expandBtn as HTMLElement);
|
||||
} else {
|
||||
this.focusElem(this.$refs.expandBtn, this.$refs.showAllChanges);
|
||||
this.focusElem(this.$refs.expandBtn as HTMLElement, this.$refs.showAllChanges as HTMLElement);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@ -188,7 +189,7 @@ export default {
|
|||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="ui scrolling dropdown custom diff-commit-selector">
|
||||
|
|
|
@ -17,7 +17,7 @@ function toggleFileList() {
|
|||
store.fileListIsVisible = !store.fileListIsVisible;
|
||||
}
|
||||
|
||||
function diffTypeToString(pType) {
|
||||
function diffTypeToString(pType: number) {
|
||||
const diffTypes = {
|
||||
1: 'add',
|
||||
2: 'modify',
|
||||
|
@ -28,7 +28,7 @@ function diffTypeToString(pType) {
|
|||
return diffTypes[pType];
|
||||
}
|
||||
|
||||
function diffStatsWidth(adds, dels) {
|
||||
function diffStatsWidth(adds: number, dels: number) {
|
||||
return `${adds / (adds + dels) * 100}%`;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ const fileTree = computed(() => {
|
|||
parent = newParent;
|
||||
}
|
||||
}
|
||||
const mergeChildIfOnlyOneDir = (entries) => {
|
||||
const mergeChildIfOnlyOneDir = (entries: Array<Record<string, any>>) => {
|
||||
for (const entry of entries) {
|
||||
if (entry.children) {
|
||||
mergeChildIfOnlyOneDir(entry.children);
|
||||
|
@ -110,13 +110,13 @@ function toggleVisibility() {
|
|||
updateVisibility(!store.fileTreeIsVisible);
|
||||
}
|
||||
|
||||
function updateVisibility(visible) {
|
||||
function updateVisibility(visible: boolean) {
|
||||
store.fileTreeIsVisible = visible;
|
||||
localStorage.setItem(LOCAL_STORAGE_KEY, store.fileTreeIsVisible);
|
||||
updateState(store.fileTreeIsVisible);
|
||||
}
|
||||
|
||||
function updateState(visible) {
|
||||
function updateState(visible: boolean) {
|
||||
const btn = document.querySelector('.diff-toggle-file-tree-button');
|
||||
const [toShow, toHide] = btn.querySelectorAll('.icon');
|
||||
const tree = document.querySelector('#diff-file-tree');
|
||||
|
|
|
@ -25,7 +25,7 @@ defineProps<{
|
|||
const store = diffTreeStore();
|
||||
const collapsed = ref(false);
|
||||
|
||||
function getIconForDiffType(pType) {
|
||||
function getIconForDiffType(pType: number) {
|
||||
const diffTypes = {
|
||||
1: {name: 'octicon-diff-added', classes: ['text', 'green']},
|
||||
2: {name: 'octicon-diff-modified', classes: ['text', 'yellow']},
|
||||
|
@ -36,7 +36,7 @@ function getIconForDiffType(pType) {
|
|||
return diffTypes[pType];
|
||||
}
|
||||
|
||||
function fileIcon(file) {
|
||||
function fileIcon(file: File) {
|
||||
if (file.IsSubmodule) {
|
||||
return 'octicon-file-submodule';
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ function toggleActionForm(show: boolean) {
|
|||
mergeMessageFieldValue.value = mergeStyleDetail.value.mergeMessageFieldText;
|
||||
}
|
||||
|
||||
function switchMergeStyle(name, autoMerge = false) {
|
||||
function switchMergeStyle(name: string, autoMerge = false) {
|
||||
mergeStyle.value = name;
|
||||
autoMergeWhenSucceed.value = autoMerge;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import {SvgIcon} from '../svg.ts';
|
||||
import ActionRunStatus from './ActionRunStatus.vue';
|
||||
import {createApp} from 'vue';
|
||||
import {defineComponent, type PropType} from 'vue';
|
||||
import {createElementFromAttrs, toggleElem} from '../utils/dom.ts';
|
||||
import {formatDatetime} from '../utils/time.ts';
|
||||
import {renderAnsi} from '../render/ansi.ts';
|
||||
|
@ -38,7 +38,7 @@ function parseLineCommand(line: LogLine): LogLineCommand | null {
|
|||
return null;
|
||||
}
|
||||
|
||||
function isLogElementInViewport(el: HTMLElement): boolean {
|
||||
function isLogElementInViewport(el: Element): boolean {
|
||||
const rect = el.getBoundingClientRect();
|
||||
return rect.top >= 0 && rect.bottom <= window.innerHeight; // only check height but not width
|
||||
}
|
||||
|
@ -57,25 +57,28 @@ function getLocaleStorageOptions(): LocaleStorageOptions {
|
|||
return {autoScroll: true, expandRunning: false};
|
||||
}
|
||||
|
||||
const sfc = {
|
||||
export default defineComponent({
|
||||
name: 'RepoActionView',
|
||||
components: {
|
||||
SvgIcon,
|
||||
ActionRunStatus,
|
||||
},
|
||||
props: {
|
||||
runIndex: String,
|
||||
jobIndex: String,
|
||||
actionsURL: String,
|
||||
locale: Object,
|
||||
},
|
||||
|
||||
watch: {
|
||||
optionAlwaysAutoScroll() {
|
||||
this.saveLocaleStorageOptions();
|
||||
runIndex: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
optionAlwaysExpandRunning() {
|
||||
this.saveLocaleStorageOptions();
|
||||
jobIndex: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
actionsURL: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
locale: {
|
||||
type: Object as PropType<Record<string, string>>,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -102,10 +105,11 @@ const sfc = {
|
|||
link: '',
|
||||
title: '',
|
||||
titleHTML: '',
|
||||
status: '',
|
||||
status: 'unknown' as RunStatus,
|
||||
canCancel: false,
|
||||
canApprove: false,
|
||||
canRerun: false,
|
||||
canDeleteArtifact: false,
|
||||
done: false,
|
||||
workflowID: '',
|
||||
workflowLink: '',
|
||||
|
@ -131,6 +135,7 @@ const sfc = {
|
|||
branch: {
|
||||
name: '',
|
||||
link: '',
|
||||
isDeleted: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -148,7 +153,16 @@ const sfc = {
|
|||
};
|
||||
},
|
||||
|
||||
async mounted() {
|
||||
watch: {
|
||||
optionAlwaysAutoScroll() {
|
||||
this.saveLocaleStorageOptions();
|
||||
},
|
||||
optionAlwaysExpandRunning() {
|
||||
this.saveLocaleStorageOptions();
|
||||
},
|
||||
},
|
||||
|
||||
async mounted() { // eslint-disable-line @typescript-eslint/no-misused-promises
|
||||
// load job data and then auto-reload periodically
|
||||
// need to await first loadJob so this.currentJobStepsStates is initialized and can be used in hashChangeListener
|
||||
await this.loadJob();
|
||||
|
@ -186,6 +200,7 @@ const sfc = {
|
|||
// get the active logs container element, either the `job-step-logs` or the `job-log-list` in the `job-log-group`
|
||||
getActiveLogsContainer(stepIndex: number): HTMLElement {
|
||||
const el = this.getJobStepLogsContainer(stepIndex);
|
||||
// @ts-expect-error - _stepLogsActiveContainer is a custom property
|
||||
return el._stepLogsActiveContainer ?? el;
|
||||
},
|
||||
// begin a log group
|
||||
|
@ -263,7 +278,7 @@ const sfc = {
|
|||
const el = this.getJobStepLogsContainer(stepIndex);
|
||||
// if the logs container is empty, then auto-scroll if the step is expanded
|
||||
if (!el.lastChild) return this.currentJobStepsStates[stepIndex].expanded;
|
||||
return isLogElementInViewport(el.lastChild);
|
||||
return isLogElementInViewport(el.lastChild as Element);
|
||||
},
|
||||
|
||||
appendLogs(stepIndex: number, startTime: number, logLines: LogLine[]) {
|
||||
|
@ -380,7 +395,7 @@ const sfc = {
|
|||
|
||||
toggleTimeDisplay(type: string) {
|
||||
this.timeVisible[`log-time-${type}`] = !this.timeVisible[`log-time-${type}`];
|
||||
for (const el of this.$refs.steps.querySelectorAll(`.log-time-${type}`)) {
|
||||
for (const el of (this.$refs.steps as HTMLElement).querySelectorAll(`.log-time-${type}`)) {
|
||||
toggleElem(el, this.timeVisible[`log-time-${type}`]);
|
||||
}
|
||||
},
|
||||
|
@ -414,59 +429,12 @@ const sfc = {
|
|||
// so logline can be selected by querySelector
|
||||
await this.loadJob();
|
||||
}
|
||||
const logLine = this.$refs.steps.querySelector(selectedLogStep);
|
||||
const logLine = (this.$refs.steps as HTMLElement).querySelector(selectedLogStep);
|
||||
if (!logLine) return;
|
||||
logLine.querySelector('.line-num').click();
|
||||
logLine.querySelector<HTMLAnchorElement>('.line-num').click();
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default sfc;
|
||||
|
||||
export function initRepositoryActionView() {
|
||||
const el = document.querySelector('#repo-action-view');
|
||||
if (!el) return;
|
||||
|
||||
// TODO: the parent element's full height doesn't work well now,
|
||||
// but we can not pollute the global style at the moment, only fix the height problem for pages with this component
|
||||
const parentFullHeight = document.querySelector<HTMLElement>('body > div.full.height');
|
||||
if (parentFullHeight) parentFullHeight.style.paddingBottom = '0';
|
||||
|
||||
const view = createApp(sfc, {
|
||||
runIndex: el.getAttribute('data-run-index'),
|
||||
jobIndex: el.getAttribute('data-job-index'),
|
||||
actionsURL: el.getAttribute('data-actions-url'),
|
||||
locale: {
|
||||
approve: el.getAttribute('data-locale-approve'),
|
||||
cancel: el.getAttribute('data-locale-cancel'),
|
||||
rerun: el.getAttribute('data-locale-rerun'),
|
||||
rerun_all: el.getAttribute('data-locale-rerun-all'),
|
||||
scheduled: el.getAttribute('data-locale-runs-scheduled'),
|
||||
commit: el.getAttribute('data-locale-runs-commit'),
|
||||
pushedBy: el.getAttribute('data-locale-runs-pushed-by'),
|
||||
artifactsTitle: el.getAttribute('data-locale-artifacts-title'),
|
||||
areYouSure: el.getAttribute('data-locale-are-you-sure'),
|
||||
confirmDeleteArtifact: el.getAttribute('data-locale-confirm-delete-artifact'),
|
||||
showTimeStamps: el.getAttribute('data-locale-show-timestamps'),
|
||||
showLogSeconds: el.getAttribute('data-locale-show-log-seconds'),
|
||||
showFullScreen: el.getAttribute('data-locale-show-full-screen'),
|
||||
downloadLogs: el.getAttribute('data-locale-download-logs'),
|
||||
status: {
|
||||
unknown: el.getAttribute('data-locale-status-unknown'),
|
||||
waiting: el.getAttribute('data-locale-status-waiting'),
|
||||
running: el.getAttribute('data-locale-status-running'),
|
||||
success: el.getAttribute('data-locale-status-success'),
|
||||
failure: el.getAttribute('data-locale-status-failure'),
|
||||
cancelled: el.getAttribute('data-locale-status-cancelled'),
|
||||
skipped: el.getAttribute('data-locale-status-skipped'),
|
||||
blocked: el.getAttribute('data-locale-status-blocked'),
|
||||
},
|
||||
logsAlwaysAutoScroll: el.getAttribute('data-locale-logs-always-auto-scroll'),
|
||||
logsAlwaysExpandRunning: el.getAttribute('data-locale-logs-always-expand-running'),
|
||||
},
|
||||
});
|
||||
view.mount(el);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="ui container action-view-container">
|
||||
|
|
|
@ -8,13 +8,15 @@ const colors = ref({
|
|||
textAltColor: 'white',
|
||||
});
|
||||
|
||||
// possible keys:
|
||||
// * avatar_link: (...)
|
||||
// * commits: (...)
|
||||
// * home_link: (...)
|
||||
// * login: (...)
|
||||
// * name: (...)
|
||||
const activityTopAuthors = window.config.pageData.repoActivityTopAuthors || [];
|
||||
type ActivityAuthorData = {
|
||||
avatar_link: string;
|
||||
commits: number;
|
||||
home_link: string;
|
||||
login: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
const activityTopAuthors: Array<ActivityAuthorData> = window.config.pageData.repoActivityTopAuthors || [];
|
||||
|
||||
const graphPoints = computed(() => {
|
||||
return activityTopAuthors.map((item) => {
|
||||
|
@ -26,7 +28,7 @@ const graphPoints = computed(() => {
|
|||
});
|
||||
|
||||
const graphAuthors = computed(() => {
|
||||
return activityTopAuthors.map((item, idx) => {
|
||||
return activityTopAuthors.map((item, idx: number) => {
|
||||
return {
|
||||
position: idx + 1,
|
||||
...item,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import {nextTick} from 'vue';
|
||||
import {defineComponent, nextTick} from 'vue';
|
||||
import {SvgIcon} from '../svg.ts';
|
||||
import {showErrorToast} from '../modules/toast.ts';
|
||||
import {GET} from '../modules/fetch.ts';
|
||||
|
@ -17,51 +17,11 @@ type SelectedTab = 'branches' | 'tags';
|
|||
|
||||
type TabLoadingStates = Record<SelectedTab, '' | 'loading' | 'done'>
|
||||
|
||||
const sfc = {
|
||||
export default defineComponent({
|
||||
components: {SvgIcon},
|
||||
props: {
|
||||
elRoot: HTMLElement,
|
||||
},
|
||||
computed: {
|
||||
searchFieldPlaceholder() {
|
||||
return this.selectedTab === 'branches' ? this.textFilterBranch : this.textFilterTag;
|
||||
},
|
||||
filteredItems(): ListItem[] {
|
||||
const searchTermLower = this.searchTerm.toLowerCase();
|
||||
const items = this.allItems.filter((item: ListItem) => {
|
||||
const typeMatched = (this.selectedTab === 'branches' && item.refType === 'branch') || (this.selectedTab === 'tags' && item.refType === 'tag');
|
||||
if (!typeMatched) return false;
|
||||
if (!this.searchTerm) return true; // match all
|
||||
return item.refShortName.toLowerCase().includes(searchTermLower);
|
||||
});
|
||||
|
||||
// TODO: fix this anti-pattern: side-effects-in-computed-properties
|
||||
this.activeItemIndex = !items.length && this.showCreateNewRef ? 0 : -1;
|
||||
return items;
|
||||
},
|
||||
showNoResults() {
|
||||
if (this.tabLoadingStates[this.selectedTab] !== 'done') return false;
|
||||
return !this.filteredItems.length && !this.showCreateNewRef;
|
||||
},
|
||||
showCreateNewRef() {
|
||||
if (!this.allowCreateNewRef || !this.searchTerm) {
|
||||
return false;
|
||||
}
|
||||
return !this.allItems.filter((item: ListItem) => {
|
||||
return item.refShortName === this.searchTerm; // FIXME: not quite right here, it mixes "branch" and "tag" names
|
||||
}).length;
|
||||
},
|
||||
createNewRefFormActionUrl() {
|
||||
return `${this.currentRepoLink}/branches/_new/${this.currentRefType}/${pathEscapeSegments(this.currentRefShortName)}`;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
menuVisible(visible: boolean) {
|
||||
if (!visible) return;
|
||||
this.focusSearchField();
|
||||
this.loadTabItems();
|
||||
},
|
||||
},
|
||||
data() {
|
||||
const shouldShowTabBranches = this.elRoot.getAttribute('data-show-tab-branches') === 'true';
|
||||
return {
|
||||
|
@ -89,7 +49,7 @@ const sfc = {
|
|||
currentRepoDefaultBranch: this.elRoot.getAttribute('data-current-repo-default-branch'),
|
||||
currentRepoLink: this.elRoot.getAttribute('data-current-repo-link'),
|
||||
currentTreePath: this.elRoot.getAttribute('data-current-tree-path'),
|
||||
currentRefType: this.elRoot.getAttribute('data-current-ref-type'),
|
||||
currentRefType: this.elRoot.getAttribute('data-current-ref-type') as GitRefType,
|
||||
currentRefShortName: this.elRoot.getAttribute('data-current-ref-short-name'),
|
||||
|
||||
refLinkTemplate: this.elRoot.getAttribute('data-ref-link-template'),
|
||||
|
@ -102,6 +62,46 @@ const sfc = {
|
|||
enableFeed: this.elRoot.getAttribute('data-enable-feed') === 'true',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
searchFieldPlaceholder() {
|
||||
return this.selectedTab === 'branches' ? this.textFilterBranch : this.textFilterTag;
|
||||
},
|
||||
filteredItems(): ListItem[] {
|
||||
const searchTermLower = this.searchTerm.toLowerCase();
|
||||
const items = this.allItems.filter((item: ListItem) => {
|
||||
const typeMatched = (this.selectedTab === 'branches' && item.refType === 'branch') || (this.selectedTab === 'tags' && item.refType === 'tag');
|
||||
if (!typeMatched) return false;
|
||||
if (!this.searchTerm) return true; // match all
|
||||
return item.refShortName.toLowerCase().includes(searchTermLower);
|
||||
});
|
||||
|
||||
// TODO: fix this anti-pattern: side-effects-in-computed-properties
|
||||
this.activeItemIndex = !items.length && this.showCreateNewRef ? 0 : -1; // eslint-disable-line vue/no-side-effects-in-computed-properties
|
||||
return items;
|
||||
},
|
||||
showNoResults() {
|
||||
if (this.tabLoadingStates[this.selectedTab] !== 'done') return false;
|
||||
return !this.filteredItems.length && !this.showCreateNewRef;
|
||||
},
|
||||
showCreateNewRef() {
|
||||
if (!this.allowCreateNewRef || !this.searchTerm) {
|
||||
return false;
|
||||
}
|
||||
return !this.allItems.filter((item: ListItem) => {
|
||||
return item.refShortName === this.searchTerm; // FIXME: not quite right here, it mixes "branch" and "tag" names
|
||||
}).length;
|
||||
},
|
||||
createNewRefFormActionUrl() {
|
||||
return `${this.currentRepoLink}/branches/_new/${this.currentRefType}/${pathEscapeSegments(this.currentRefShortName)}`;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
menuVisible(visible: boolean) {
|
||||
if (!visible) return;
|
||||
this.focusSearchField();
|
||||
this.loadTabItems();
|
||||
},
|
||||
},
|
||||
beforeMount() {
|
||||
document.body.addEventListener('click', (e) => {
|
||||
if (this.$el.contains(e.target)) return;
|
||||
|
@ -139,11 +139,11 @@ const sfc = {
|
|||
}
|
||||
},
|
||||
createNewRef() {
|
||||
this.$refs.createNewRefForm?.submit();
|
||||
(this.$refs.createNewRefForm as HTMLFormElement)?.submit();
|
||||
},
|
||||
focusSearchField() {
|
||||
nextTick(() => {
|
||||
this.$refs.searchField.focus();
|
||||
(this.$refs.searchField as HTMLInputElement).focus();
|
||||
});
|
||||
},
|
||||
getSelectedIndexInFiltered() {
|
||||
|
@ -154,6 +154,7 @@ const sfc = {
|
|||
},
|
||||
getActiveItem() {
|
||||
const el = this.$refs[`listItem${this.activeItemIndex}`]; // eslint-disable-line no-jquery/variable-pattern
|
||||
// @ts-expect-error - el is unknown type
|
||||
return (el && el.length) ? el[0] : null;
|
||||
},
|
||||
keydown(e) {
|
||||
|
@ -212,9 +213,7 @@ const sfc = {
|
|||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default sfc; // activate IDE's Vue plugin
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="ui dropdown custom branch-selector-dropdown ellipsis-items-nowrap">
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<script lang="ts">
|
||||
import {defineComponent, type PropType} from 'vue';
|
||||
import {SvgIcon} from '../svg.ts';
|
||||
import dayjs from 'dayjs';
|
||||
import {
|
||||
|
@ -56,11 +57,11 @@ Chart.register(
|
|||
customEventListener,
|
||||
);
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
components: {ChartLine, SvgIcon},
|
||||
props: {
|
||||
locale: {
|
||||
type: Object,
|
||||
type: Object as PropType<Record<string, any>>,
|
||||
required: true,
|
||||
},
|
||||
repoLink: {
|
||||
|
@ -88,7 +89,7 @@ export default {
|
|||
this.fetchGraphData();
|
||||
|
||||
fomanticQuery('#repo-contributors').dropdown({
|
||||
onChange: (val) => {
|
||||
onChange: (val: string) => {
|
||||
this.xAxisMin = this.xAxisStart;
|
||||
this.xAxisMax = this.xAxisEnd;
|
||||
this.type = val;
|
||||
|
@ -320,7 +321,7 @@ export default {
|
|||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue