Skip to content

Use shallowRef instead of ref in .vue files where possible #34813

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions web_src/js/components/ActivityHeatmap.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts" setup>
// TODO: Switch to upstream after https://github.com/razorness/vue3-calendar-heatmap/pull/34 is merged
import {CalendarHeatmap} from '@silverwind/vue3-calendar-heatmap';
import {onMounted, ref} from 'vue';
import {onMounted, shallowRef} from 'vue';
import type {Value as HeatmapValue, Locale as HeatmapLocale} from '@silverwind/vue3-calendar-heatmap';
defineProps<{
Expand All @@ -24,7 +24,7 @@ const colorRange = [
'var(--color-primary-dark-4)',
];
const endDate = ref(new Date());
const endDate = shallowRef(new Date());
onMounted(() => {
// work around issue with first legend color being rendered twice and legend cut off
Expand Down
12 changes: 6 additions & 6 deletions web_src/js/components/ContextPopup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
import {SvgIcon} from '../svg.ts';
import {GET} from '../modules/fetch.ts';
import {getIssueColor, getIssueIcon} from '../features/issue.ts';
import {computed, onMounted, ref} from 'vue';
import {computed, onMounted, shallowRef, useTemplateRef} from 'vue';
import type {IssuePathInfo} from '../types.ts';

const {appSubUrl, i18n} = window.config;

const loading = ref(false);
const issue = ref(null);
const renderedLabels = ref('');
const loading = shallowRef(false);
const issue = shallowRef(null);
const renderedLabels = shallowRef('');
const i18nErrorOccurred = i18n.error_occurred;
const i18nErrorMessage = ref(null);
const i18nErrorMessage = shallowRef(null);

const createdAt = computed(() => new Date(issue.value.created_at).toLocaleDateString(undefined, {year: 'numeric', month: 'short', day: 'numeric'}));
const body = computed(() => {
Expand All @@ -22,7 +22,7 @@ const body = computed(() => {
return body;
});

const root = ref<HTMLElement | null>(null);
const root = useTemplateRef('root');

onMounted(() => {
root.value.addEventListener('ce-load-context-popup', (e: CustomEventInit<IssuePathInfo>) => {
Expand Down
4 changes: 2 additions & 2 deletions web_src/js/components/DiffFileTreeItem.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<script lang="ts" setup>
import {SvgIcon, type SvgName} from '../svg.ts';
import {ref} from 'vue';
import {shallowRef} from 'vue';
import {type DiffStatus, type DiffTreeEntry, diffTreeStore} from '../modules/diff-file.ts';

const props = defineProps<{
item: DiffTreeEntry,
}>();

const store = diffTreeStore();
const collapsed = ref(props.item.IsViewed);
const collapsed = shallowRef(props.item.IsViewed);

function getIconForDiffStatus(pType: DiffStatus) {
const diffTypes: Record<DiffStatus, { name: SvgName, classes: Array<string> }> = {
Expand Down
40 changes: 20 additions & 20 deletions web_src/js/components/PullRequestMergeForm.vue
Original file line number Diff line number Diff line change
@@ -1,53 +1,53 @@
<script lang="ts" setup>
import {computed, onMounted, onUnmounted, ref, watch} from 'vue';
import {computed, onMounted, onUnmounted, shallowRef, watch} from 'vue';
import {SvgIcon} from '../svg.ts';
import {toggleElem} from '../utils/dom.ts';

const {csrfToken, pageData} = window.config;

const mergeForm = ref(pageData.pullRequestMergeForm);
const mergeForm = pageData.pullRequestMergeForm;

const mergeTitleFieldValue = ref('');
const mergeMessageFieldValue = ref('');
const deleteBranchAfterMerge = ref(false);
const autoMergeWhenSucceed = ref(false);
const mergeTitleFieldValue = shallowRef('');
const mergeMessageFieldValue = shallowRef('');
const deleteBranchAfterMerge = shallowRef(false);
const autoMergeWhenSucceed = shallowRef(false);

const mergeStyle = ref('');
const mergeStyleDetail = ref({
const mergeStyle = shallowRef('');
const mergeStyleDetail = shallowRef({
hideMergeMessageTexts: false,
textDoMerge: '',
mergeTitleFieldText: '',
mergeMessageFieldText: '',
hideAutoMerge: false,
});

const mergeStyleAllowedCount = ref(0);
const mergeStyleAllowedCount = shallowRef(0);

const showMergeStyleMenu = ref(false);
const showActionForm = ref(false);
const showMergeStyleMenu = shallowRef(false);
const showActionForm = shallowRef(false);

const mergeButtonStyleClass = computed(() => {
if (mergeForm.value.allOverridableChecksOk) return 'primary';
if (mergeForm.allOverridableChecksOk) return 'primary';
return autoMergeWhenSucceed.value ? 'primary' : 'red';
});

const forceMerge = computed(() => {
return mergeForm.value.canMergeNow && !mergeForm.value.allOverridableChecksOk;
return mergeForm.canMergeNow && !mergeForm.allOverridableChecksOk;
});

watch(mergeStyle, (val) => {
mergeStyleDetail.value = mergeForm.value.mergeStyles.find((e: any) => e.name === val);
mergeStyleDetail.value = mergeForm.mergeStyles.find((e: any) => e.name === val);
for (const elem of document.querySelectorAll('[data-pull-merge-style]')) {
toggleElem(elem, elem.getAttribute('data-pull-merge-style') === val);
}
});

onMounted(() => {
mergeStyleAllowedCount.value = mergeForm.value.mergeStyles.reduce((v: any, msd: any) => v + (msd.allowed ? 1 : 0), 0);
mergeStyleAllowedCount.value = mergeForm.mergeStyles.reduce((v: any, msd: any) => v + (msd.allowed ? 1 : 0), 0);

let mergeStyle = mergeForm.value.mergeStyles.find((e: any) => e.allowed && e.name === mergeForm.value.defaultMergeStyle)?.name;
if (!mergeStyle) mergeStyle = mergeForm.value.mergeStyles.find((e: any) => e.allowed)?.name;
switchMergeStyle(mergeStyle, !mergeForm.value.canMergeNow);
let mergeStyle = mergeForm.mergeStyles.find((e: any) => e.allowed && e.name === mergeForm.defaultMergeStyle)?.name;
if (!mergeStyle) mergeStyle = mergeForm.mergeStyles.find((e: any) => e.allowed)?.name;
switchMergeStyle(mergeStyle, !mergeForm.canMergeNow);

document.addEventListener('mouseup', hideMergeStyleMenu);
});
Expand All @@ -63,7 +63,7 @@ function hideMergeStyleMenu() {
function toggleActionForm(show: boolean) {
showActionForm.value = show;
if (!show) return;
deleteBranchAfterMerge.value = mergeForm.value.defaultDeleteBranchAfterMerge;
deleteBranchAfterMerge.value = mergeForm.defaultDeleteBranchAfterMerge;
mergeTitleFieldValue.value = mergeStyleDetail.value.mergeTitleFieldText;
mergeMessageFieldValue.value = mergeStyleDetail.value.mergeMessageFieldText;
}
Expand All @@ -74,7 +74,7 @@ function switchMergeStyle(name: string, autoMerge = false) {
}

function clearMergeMessage() {
mergeMessageFieldValue.value = mergeForm.value.defaultMergeMessage;
mergeMessageFieldValue.value = mergeForm.defaultMergeMessage;
}
</script>

Expand Down
8 changes: 4 additions & 4 deletions web_src/js/components/RepoActivityTopAuthors.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<script lang="ts" setup>
// @ts-expect-error - module exports no types
import {VueBarGraph} from 'vue-bar-graph';
import {computed, onMounted, ref} from 'vue';
import {computed, onMounted, shallowRef, useTemplateRef} from 'vue';

const colors = ref({
const colors = shallowRef({
barColor: 'green',
textColor: 'black',
textAltColor: 'white',
Expand Down Expand Up @@ -41,8 +41,8 @@ const graphWidth = computed(() => {
return activityTopAuthors.length * 40;
});

const styleElement = ref<HTMLElement | null>(null);
const altStyleElement = ref<HTMLElement | null>(null);
const styleElement = useTemplateRef('styleElement');
const altStyleElement = useTemplateRef('altStyleElement');

onMounted(() => {
const refStyle = window.getComputedStyle(styleElement.value);
Expand Down
12 changes: 6 additions & 6 deletions web_src/js/components/RepoCodeFrequency.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
import {chartJsColors} from '../utils/color.ts';
import {sleep} from '../utils.ts';
import 'chartjs-adapter-dayjs-4/dist/chartjs-adapter-dayjs-4.esm';
import {onMounted, ref} from 'vue';
import {onMounted, shallowRef} from 'vue';

const {pageData} = window.config;

Expand All @@ -47,10 +47,10 @@ defineProps<{
};
}>();

const isLoading = ref(false);
const errorText = ref('');
const repoLink = ref(pageData.repoLink || []);
const data = ref<DayData[]>([]);
const isLoading = shallowRef(false);
const errorText = shallowRef('');
const repoLink = pageData.repoLink;
const data = shallowRef<DayData[]>([]);

onMounted(() => {
fetchGraphData();
Expand All @@ -61,7 +61,7 @@ async function fetchGraphData() {
try {
let response: Response;
do {
response = await GET(`${repoLink.value}/activity/code-frequency/data`);
response = await GET(`${repoLink}/activity/code-frequency/data`);
if (response.status === 202) {
await sleep(1000); // wait for 1 second before retrying
}
Expand Down
10 changes: 5 additions & 5 deletions web_src/js/components/RepoRecentCommits.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
import {chartJsColors} from '../utils/color.ts';
import {sleep} from '../utils.ts';
import 'chartjs-adapter-dayjs-4/dist/chartjs-adapter-dayjs-4.esm';
import {onMounted, ref} from 'vue';
import {onMounted, ref, shallowRef} from 'vue';

const {pageData} = window.config;

Expand All @@ -43,9 +43,9 @@ defineProps<{
};
}>();

const isLoading = ref(false);
const errorText = ref('');
const repoLink = ref(pageData.repoLink || []);
const isLoading = shallowRef(false);
const errorText = shallowRef('');
const repoLink = pageData.repoLink;
const data = ref<DayData[]>([]);

onMounted(() => {
Expand All @@ -57,7 +57,7 @@ async function fetchGraphData() {
try {
let response: Response;
do {
response = await GET(`${repoLink.value}/activity/recent-commits/data`);
response = await GET(`${repoLink}/activity/recent-commits/data`);
if (response.status === 202) {
await sleep(1000); // wait for 1 second before retrying
}
Expand Down
4 changes: 2 additions & 2 deletions web_src/js/components/ViewFileTree.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<script lang="ts" setup>
import ViewFileTreeItem from './ViewFileTreeItem.vue';
import {onMounted, ref} from 'vue';
import {onMounted, useTemplateRef} from 'vue';
import {createViewFileTreeStore} from './ViewFileTreeStore.ts';

const elRoot = ref<HTMLElement | null>(null);
const elRoot = useTemplateRef('elRoot');

const props = defineProps({
repoLink: {type: String, required: true},
Expand Down
8 changes: 4 additions & 4 deletions web_src/js/components/ViewFileTreeItem.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts" setup>
import {SvgIcon} from '../svg.ts';
import {isPlainClick} from '../utils/dom.ts';
import {ref} from 'vue';
import {shallowRef} from 'vue';
import {type createViewFileTreeStore} from './ViewFileTreeStore.ts';

type Item = {
Expand All @@ -20,9 +20,9 @@ const props = defineProps<{
}>();

const store = props.store;
const isLoading = ref(false);
const children = ref(props.item.children);
const collapsed = ref(!props.item.children);
const isLoading = shallowRef(false);
const children = shallowRef(props.item.children);
const collapsed = shallowRef(!props.item.children);

const doLoadChildren = async () => {
collapsed.value = !collapsed.value;
Expand Down