From d1fa32a9fedb61cd999116bc7fe6766b78e04308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C5=A1per=20Grom?= Date: Sun, 27 Sep 2026 21:37:05 +0100 Subject: [PATCH 1/5] fix: type shared filter, identity and saved-view modules (CM-1532) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs linuxfoundation/lfx-cdp-insights-ops#232 Signed-off-by: Gašper Grom --- .../src/shared/modules/filters/components/Filter.vue | 2 +- .../modules/filters/components/FilterDropdown.vue | 2 +- .../shared/modules/filters/components/FilterItem.vue | 7 +++---- .../shared/modules/filters/components/FilterSearch.vue | 2 +- .../filters/components/filterTypes/DateFilter.vue | 4 ++-- .../config/apiFilterRenderer/date.filter.renderer.ts | 8 ++++---- .../config/apiFilterRenderer/number.filter.renderer.ts | 6 +++--- .../modules/filters/config/apiFilterRendererByType.ts | 2 +- .../config/itemLabelRenderer/date.label.renderer.ts | 8 ++++++-- .../components/identities-horizontal-list.vue | 6 ++++-- .../identities/config/useOrganizationIdentities.ts | 2 +- .../modules/merge/config/member/apiErrorMessage.ts | 2 +- .../merge/config/organization/apiErrorMessage.ts | 2 +- .../modules/permissions/router/PermissionGuard.ts | 7 ++++++- .../shared/modules/platform/components/platform.vue | 2 +- .../report-issue/component/report-data-issue-modal.vue | 2 +- .../type/project-affiliation/project-affiliation.ts | 3 ++- .../saved-views/components/forms/SavedViewForm.vue | 10 +++++----- 18 files changed, 44 insertions(+), 33 deletions(-) diff --git a/frontend/src/shared/modules/filters/components/Filter.vue b/frontend/src/shared/modules/filters/components/Filter.vue index 111195bc07..afa3465ba7 100644 --- a/frontend/src/shared/modules/filters/components/Filter.vue +++ b/frontend/src/shared/modules/filters/components/Filter.vue @@ -86,7 +86,7 @@ const props = defineProps<{ lockRelation?: boolean, }>(); -const emit = defineEmits<{(e: 'update:modelValue', value: Filter), (e: 'fetch', value: FilterQuery), }>(); +const emit = defineEmits<{(e: 'update:modelValue', value: Filter): void, (e: 'fetch', value: FilterQuery): void, }>(); const { trackEvent } = useProductTracking(); const router = useRouter(); diff --git a/frontend/src/shared/modules/filters/components/FilterDropdown.vue b/frontend/src/shared/modules/filters/components/FilterDropdown.vue index 75674802ce..b129d41038 100644 --- a/frontend/src/shared/modules/filters/components/FilterDropdown.vue +++ b/frontend/src/shared/modules/filters/components/FilterDropdown.vue @@ -57,7 +57,7 @@ const props = defineProps<{ modelValue: string[] }>(); -const emit = defineEmits<{(e: 'update:modelValue', value: string[]), (e: 'open', value: string)}>(); +const emit = defineEmits<{(e: 'update:modelValue', value: string[]): void, (e: 'open', value: string): void}>(); const open = ref(false); const search = ref(''); diff --git a/frontend/src/shared/modules/filters/components/FilterItem.vue b/frontend/src/shared/modules/filters/components/FilterItem.vue index 3f76f251d0..144b967197 100644 --- a/frontend/src/shared/modules/filters/components/FilterItem.vue +++ b/frontend/src/shared/modules/filters/components/FilterItem.vue @@ -70,7 +70,7 @@ import LfIcon from '@/ui-kit/icon/Icon.vue'; import LfButton from '@/ui-kit/button/Button.vue'; const props = defineProps<{ - modelValue: string, + modelValue: Record, open: string, config: FilterConfig, hideRemove?: boolean, @@ -99,9 +99,8 @@ const isOpen = computed({ }); const getComponent = computed(() => { - const { type, component } = props.config; - if (type === FilterConfigType.CUSTOM) { - return component; + if (props.config.type === FilterConfigType.CUSTOM) { + return props.config.component; } return filterComponentByType[props.config.type]; }); diff --git a/frontend/src/shared/modules/filters/components/FilterSearch.vue b/frontend/src/shared/modules/filters/components/FilterSearch.vue index 7f2bc78b06..861713761c 100644 --- a/frontend/src/shared/modules/filters/components/FilterSearch.vue +++ b/frontend/src/shared/modules/filters/components/FilterSearch.vue @@ -31,7 +31,7 @@ const props = defineProps<{ placeholder?: string, }>(); -const emit = defineEmits<{(e: 'update:modelValue', value: string)}>(); +const emit = defineEmits<{(e: 'update:modelValue', value: string): void}>(); const model = ref(''); diff --git a/frontend/src/shared/modules/filters/components/filterTypes/DateFilter.vue b/frontend/src/shared/modules/filters/components/filterTypes/DateFilter.vue index 1b0ed5e9b8..7141831cd5 100644 --- a/frontend/src/shared/modules/filters/components/filterTypes/DateFilter.vue +++ b/frontend/src/shared/modules/filters/components/filterTypes/DateFilter.vue @@ -137,13 +137,13 @@ const timePicker = computed({ const isCustom = computed(() => !(typeof form.value.value === 'string' && timePickerOptionValues.includes(form.value.value))); -const checkIfBetween = (operator: string) => [FilterDateOperator.BETWEEN, FilterDateOperator.NOT_BETWEEN].includes(operator); +const checkIfBetween = (operator: FilterDateOperator) => [FilterDateOperator.BETWEEN, FilterDateOperator.NOT_BETWEEN].includes(operator); const isBetween = computed(() => checkIfBetween(form.value.operator)); const operators = computed(() => { if (props.datepickerType === 'year') { - return dateFilterOperators.filter((o) => !checkIfBetween(o.value)); + return dateFilterOperators.filter((o) => !checkIfBetween(o.value as FilterDateOperator)); } return dateFilterOperators; }); diff --git a/frontend/src/shared/modules/filters/config/apiFilterRenderer/date.filter.renderer.ts b/frontend/src/shared/modules/filters/config/apiFilterRenderer/date.filter.renderer.ts index f089b4a2a7..5375e85489 100644 --- a/frontend/src/shared/modules/filters/config/apiFilterRenderer/date.filter.renderer.ts +++ b/frontend/src/shared/modules/filters/config/apiFilterRenderer/date.filter.renderer.ts @@ -34,18 +34,18 @@ export const dateApiFilterRenderer = (property: string, { value, operator }: Dat filter = { [property]: { between: [ - dateHelper.utc(mappedValue).startOf('day').toISOString(), - dateHelper.utc(mappedValue).endOf('day').toISOString(), + dateHelper.utc(mappedValue as string).startOf('day').toISOString(), + dateHelper.utc(mappedValue as string).endOf('day').toISOString(), ], }, }; } else { - let parsedValue = dateHelper.utc(mappedValue).startOf('day').toISOString(); + let parsedValue = dateHelper.utc(mappedValue as string).startOf('day').toISOString(); if (['last24h'].includes(value as string)) { parsedValue = mappedValue as string; } else if ([FilterDateOperator.GT, FilterDateOperator.GTE].includes(operator)) { - parsedValue = dateHelper.utc(mappedValue).endOf('day').toISOString(); + parsedValue = dateHelper.utc(mappedValue as string).endOf('day').toISOString(); } filter = { diff --git a/frontend/src/shared/modules/filters/config/apiFilterRenderer/number.filter.renderer.ts b/frontend/src/shared/modules/filters/config/apiFilterRenderer/number.filter.renderer.ts index 920695df3c..17468e4851 100644 --- a/frontend/src/shared/modules/filters/config/apiFilterRenderer/number.filter.renderer.ts +++ b/frontend/src/shared/modules/filters/config/apiFilterRenderer/number.filter.renderer.ts @@ -6,12 +6,12 @@ export const numberApiFilterRenderer = ( { value, valueTo, operator, }: NumberFilterValue, - parse: (value: number) => number, + parse?: (value: number) => number, ): any[] => { const includeFilter = ![FilterNumberOperator.NE, FilterNumberOperator.NOT_BETWEEN].includes(operator); let filterOperator = operator; - const parsedValue = parse ? parse(value) : +value; - const parsedValueTo = parse ? parse(valueTo) : +valueTo; + const parsedValue = parse ? parse(Number(value)) : Number(value); + const parsedValueTo = parse ? parse(Number(valueTo)) : Number(valueTo); const filterValue = [FilterNumberOperator.BETWEEN, FilterNumberOperator.NOT_BETWEEN].includes(operator) ? [parsedValue, parsedValueTo!] diff --git a/frontend/src/shared/modules/filters/config/apiFilterRendererByType.ts b/frontend/src/shared/modules/filters/config/apiFilterRendererByType.ts index c45a670c22..08c6bd334d 100644 --- a/frontend/src/shared/modules/filters/config/apiFilterRendererByType.ts +++ b/frontend/src/shared/modules/filters/config/apiFilterRendererByType.ts @@ -8,7 +8,7 @@ import { multiSelectApiFilterRenderer, } from './apiFilterRenderer/multiselect.filter.renderer'; -export const apiFilterRendererByType: Record any[]> = { +export const apiFilterRendererByType: Record number) => any[]> = { [FilterConfigType.BOOLEAN]: booleanApiFilterRenderer, [FilterConfigType.NUMBER]: numberApiFilterRenderer, [FilterConfigType.DATE]: dateApiFilterRenderer, diff --git a/frontend/src/shared/modules/filters/config/itemLabelRenderer/date.label.renderer.ts b/frontend/src/shared/modules/filters/config/itemLabelRenderer/date.label.renderer.ts index c40c5cb503..6b79af7f6a 100644 --- a/frontend/src/shared/modules/filters/config/itemLabelRenderer/date.label.renderer.ts +++ b/frontend/src/shared/modules/filters/config/itemLabelRenderer/date.label.renderer.ts @@ -4,7 +4,10 @@ import { FilterDateOperator, } from '@/shared/modules/filters/config/constants/date.constants'; -const operatorText: Record = { +type LabelledDateOperator = Exclude; + +// shortcut: gte has no label, so a gte filter throws below (known legacy bug). revisit: when gte is offered in the UI. +const operatorText: Record = { [FilterDateOperator.EQ]: '', [FilterDateOperator.NE]: 'is not', [FilterDateOperator.LT]: 'before', @@ -16,7 +19,8 @@ const operatorText: Record = { export const dateItemLabelRenderer = (property: string, { value, operator }: DateFilterValue): string => { const dateOption = dateFilterTimePickerOptions.find((option) => option.value === value && option.operator === operator); let valueText = `${value}`; - let operatorTextDisplay = operatorText[operator].length > 0 ? `${operatorText[operator]} ` : ''; + let operatorTextDisplay = operatorText[operator as LabelledDateOperator].length > 0 + ? `${operatorText[operator as LabelledDateOperator]} ` : ''; if (dateOption) { valueText = dateOption.label; diff --git a/frontend/src/shared/modules/identities/components/identities-horizontal-list.vue b/frontend/src/shared/modules/identities/components/identities-horizontal-list.vue index a46b938dde..db16870dbd 100644 --- a/frontend/src/shared/modules/identities/components/identities-horizontal-list.vue +++ b/frontend/src/shared/modules/identities/components/identities-horizontal-list.vue @@ -63,7 +63,8 @@ const props = defineProps<{ identities: { [key: string]: { handle: string; - link: string; + link: string | null; + verified: boolean; }[]; }; limit?: number; @@ -82,7 +83,8 @@ const parsedIdentities = computed(() => { acc: { [key: string]: { handle: string; - link: string; + link: string | null; + verified: boolean; }[]; }, k, diff --git a/frontend/src/shared/modules/identities/config/useOrganizationIdentities.ts b/frontend/src/shared/modules/identities/config/useOrganizationIdentities.ts index 2b1e3e0ab8..b41f3acc31 100644 --- a/frontend/src/shared/modules/identities/config/useOrganizationIdentities.ts +++ b/frontend/src/shared/modules/identities/config/useOrganizationIdentities.ts @@ -112,7 +112,7 @@ export default ({ } return acc; - }, {} as Record); + }, {} as Record); const getAffiliatedProfiles = (): { handle: string; diff --git a/frontend/src/shared/modules/merge/config/member/apiErrorMessage.ts b/frontend/src/shared/modules/merge/config/member/apiErrorMessage.ts index b498eef66d..2d6b280936 100644 --- a/frontend/src/shared/modules/merge/config/member/apiErrorMessage.ts +++ b/frontend/src/shared/modules/merge/config/member/apiErrorMessage.ts @@ -3,7 +3,7 @@ import type { ErrorMessage } from '../../types/MemberMessage'; export default ({ error }: ErrorMessage) => { ToastStore.closeAll(); - if (error.response.status === 404) { + if (error.response!.status === 404) { ToastStore.success('Profiles already merged or deleted', { message: `Sorry, the profiles you are trying to merge might have already been merged or deleted. Please refresh to see the updated information.`, diff --git a/frontend/src/shared/modules/merge/config/organization/apiErrorMessage.ts b/frontend/src/shared/modules/merge/config/organization/apiErrorMessage.ts index 3b9c150b4f..54d5341004 100644 --- a/frontend/src/shared/modules/merge/config/organization/apiErrorMessage.ts +++ b/frontend/src/shared/modules/merge/config/organization/apiErrorMessage.ts @@ -4,7 +4,7 @@ import type { ApiErrorMessage } from '../../types/OrganizationMessage'; export default ({ error }: ApiErrorMessage) => { ToastStore.closeAll(); - if (error.response.status === 404) { + if (error.response!.status === 404) { ToastStore.success('Organizations already merged or deleted', { message: `Sorry, the organizations you are trying to merge might have already been merged or deleted. Please refresh to see the updated information.`, diff --git a/frontend/src/shared/modules/permissions/router/PermissionGuard.ts b/frontend/src/shared/modules/permissions/router/PermissionGuard.ts index 42d2ff1270..09600c2e2a 100644 --- a/frontend/src/shared/modules/permissions/router/PermissionGuard.ts +++ b/frontend/src/shared/modules/permissions/router/PermissionGuard.ts @@ -1,9 +1,14 @@ +import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router'; import { ToastStore } from '@/shared/message/notification'; import type { LfPermission } from '@/shared/modules/permissions/types/Permissions'; import usePermissions from '@/shared/modules/permissions/helpers/usePermissions'; import { useAuthStore } from '@/modules/auth/store/auth.store'; -export const PermissionGuard = (permission: LfPermission) => async (to, from, next) => { +export const PermissionGuard = (permission: LfPermission) => async ( + to: RouteLocationNormalized, + from: RouteLocationNormalized, + next: NavigationGuardNext, +) => { // Ensure user is loaded const { ensureLoaded } = useAuthStore(); await ensureLoaded(); diff --git a/frontend/src/shared/modules/platform/components/platform.vue b/frontend/src/shared/modules/platform/components/platform.vue index d48e05509b..884592b65d 100644 --- a/frontend/src/shared/modules/platform/components/platform.vue +++ b/frontend/src/shared/modules/platform/components/platform.vue @@ -46,7 +46,7 @@ const props = withDefaults( size?: string; identities?: { handle: string; - link: string; + link: string | null; }[]; asLink?: boolean; asSvg?: boolean; diff --git a/frontend/src/shared/modules/report-issue/component/report-data-issue-modal.vue b/frontend/src/shared/modules/report-issue/component/report-data-issue-modal.vue index 1ace5b9f23..c41b37f016 100644 --- a/frontend/src/shared/modules/report-issue/component/report-data-issue-modal.vue +++ b/frontend/src/shared/modules/report-issue/component/report-data-issue-modal.vue @@ -204,7 +204,7 @@ const submit = () => { loading.value = true; return authAxios.post( - `${getConfig.value.url(entity.value.id)}`, + `${getConfig.value.url(entity.value!.id)}`, data, ) .then(() => { diff --git a/frontend/src/shared/modules/report-issue/config/type/project-affiliation/project-affiliation.ts b/frontend/src/shared/modules/report-issue/config/type/project-affiliation/project-affiliation.ts index b33d99c60f..b1bcae1128 100644 --- a/frontend/src/shared/modules/report-issue/config/type/project-affiliation/project-affiliation.ts +++ b/frontend/src/shared/modules/report-issue/config/type/project-affiliation/project-affiliation.ts @@ -1,9 +1,10 @@ +import type { ContributorAffiliation } from '@/modules/contributor/types/Contributor'; import type { ReportDataTypeConfig } from '@/shared/modules/report-issue/config'; import ProjectAffiliation from './type-project-affiliation.vue'; export const projectAffiliation: ReportDataTypeConfig = { description: (attribute: any) => { - const affiliations = Object.values(attribute.affiliations).flat(); + const affiliations = Object.values(attribute.affiliations).flat(); const list: string[] = [ `Project: ${attribute.name}`, diff --git a/frontend/src/shared/modules/saved-views/components/forms/SavedViewForm.vue b/frontend/src/shared/modules/saved-views/components/forms/SavedViewForm.vue index 631025979b..09b18399ad 100644 --- a/frontend/src/shared/modules/saved-views/components/forms/SavedViewForm.vue +++ b/frontend/src/shared/modules/saved-views/components/forms/SavedViewForm.vue @@ -227,7 +227,7 @@ const props = defineProps<{ filters: Record, customFilters?: Record, placement: string, - view: SavedView | SavedViewCreate | null, + view: Partial | null, }>(); const emit = defineEmits<{(e: 'update:modelValue', value: boolean): any, @@ -346,15 +346,15 @@ const removeFilter = (key: any) => { const fillForm = () => { if (props.view) { form.shared = hasPermission(LfPermission.customViewsTenantManage) ? props.view.visibility === 'tenant' : false; - form.name = props.view.name; + form.name = props.view.name!; const { relation, order, settings, search, ...restFilters - } = props.view.config; + } = props.view.config!; form.relation = relation; form.sorting.prop = order.prop; form.sorting.order = order.order; - form.filters = { ...restFilters } || {}; - form.settings = { ...settings } || {}; + form.filters = { ...restFilters }; + form.settings = { ...settings }; filterList.value = Object.keys(restFilters); formSnapshot(); } From feafe876ef5ddd50c33975b43443cdd8d2cd5f72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C5=A1per=20Grom?= Date: Sun, 27 Sep 2026 21:41:19 +0100 Subject: [PATCH 2/5] refactor: minimize shared modules typing (CM-1532) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs linuxfoundation/lfx-cdp-insights-ops#232 Signed-off-by: Gašper Grom --- .../config/apiFilterRenderer/number.filter.renderer.ts | 2 +- .../config/itemLabelRenderer/date.label.renderer.ts | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/frontend/src/shared/modules/filters/config/apiFilterRenderer/number.filter.renderer.ts b/frontend/src/shared/modules/filters/config/apiFilterRenderer/number.filter.renderer.ts index 17468e4851..7a208275b8 100644 --- a/frontend/src/shared/modules/filters/config/apiFilterRenderer/number.filter.renderer.ts +++ b/frontend/src/shared/modules/filters/config/apiFilterRenderer/number.filter.renderer.ts @@ -14,7 +14,7 @@ export const numberApiFilterRenderer = ( const parsedValueTo = parse ? parse(Number(valueTo)) : Number(valueTo); const filterValue = [FilterNumberOperator.BETWEEN, FilterNumberOperator.NOT_BETWEEN].includes(operator) - ? [parsedValue, parsedValueTo!] + ? [parsedValue, parsedValueTo] : parsedValue; if (operator === FilterNumberOperator.NE) { diff --git a/frontend/src/shared/modules/filters/config/itemLabelRenderer/date.label.renderer.ts b/frontend/src/shared/modules/filters/config/itemLabelRenderer/date.label.renderer.ts index 6b79af7f6a..2cd6597a72 100644 --- a/frontend/src/shared/modules/filters/config/itemLabelRenderer/date.label.renderer.ts +++ b/frontend/src/shared/modules/filters/config/itemLabelRenderer/date.label.renderer.ts @@ -4,10 +4,8 @@ import { FilterDateOperator, } from '@/shared/modules/filters/config/constants/date.constants'; -type LabelledDateOperator = Exclude; - // shortcut: gte has no label, so a gte filter throws below (known legacy bug). revisit: when gte is offered in the UI. -const operatorText: Record = { +const operatorText: Partial> = { [FilterDateOperator.EQ]: '', [FilterDateOperator.NE]: 'is not', [FilterDateOperator.LT]: 'before', @@ -19,8 +17,7 @@ const operatorText: Record = { export const dateItemLabelRenderer = (property: string, { value, operator }: DateFilterValue): string => { const dateOption = dateFilterTimePickerOptions.find((option) => option.value === value && option.operator === operator); let valueText = `${value}`; - let operatorTextDisplay = operatorText[operator as LabelledDateOperator].length > 0 - ? `${operatorText[operator as LabelledDateOperator]} ` : ''; + let operatorTextDisplay = operatorText[operator]!.length > 0 ? `${operatorText[operator]} ` : ''; if (dateOption) { valueText = dateOption.label; From 5b88e2737d64aff6f7b5298d5f07df5f0030a834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C5=A1per=20Grom?= Date: Sun, 27 Sep 2026 21:56:22 +0100 Subject: [PATCH 3/5] refactor: shorten the gte shortcut note (CM-1532) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs linuxfoundation/lfx-cdp-insights-ops#232 Signed-off-by: Gašper Grom --- .../filters/config/itemLabelRenderer/date.label.renderer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/shared/modules/filters/config/itemLabelRenderer/date.label.renderer.ts b/frontend/src/shared/modules/filters/config/itemLabelRenderer/date.label.renderer.ts index 2cd6597a72..2ea117b8bf 100644 --- a/frontend/src/shared/modules/filters/config/itemLabelRenderer/date.label.renderer.ts +++ b/frontend/src/shared/modules/filters/config/itemLabelRenderer/date.label.renderer.ts @@ -4,7 +4,7 @@ import { FilterDateOperator, } from '@/shared/modules/filters/config/constants/date.constants'; -// shortcut: gte has no label, so a gte filter throws below (known legacy bug). revisit: when gte is offered in the UI. +// shortcut: gte has no label and throws below (legacy). revisit: when gte is offered in the UI. const operatorText: Partial> = { [FilterDateOperator.EQ]: '', [FilterDateOperator.NE]: 'is not', From a378b96cd8765ddd2e9f1d717385bbd8592e9f92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C5=A1per=20Grom?= Date: Wed, 14 Oct 2026 11:04:42 +0100 Subject: [PATCH 4/5] fix: mark null-hiding casts in shared modules (CM-1532) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs linuxfoundation/lfx-cdp-insights-ops#232 Signed-off-by: Gašper Grom --- .../filters/config/apiFilterRenderer/date.filter.renderer.ts | 2 ++ .../src/shared/modules/merge/config/member/apiErrorMessage.ts | 1 + .../shared/modules/merge/config/organization/apiErrorMessage.ts | 1 + .../modules/report-issue/component/report-data-issue-modal.vue | 1 + .../modules/saved-views/components/forms/SavedViewForm.vue | 1 + 5 files changed, 6 insertions(+) diff --git a/frontend/src/shared/modules/filters/config/apiFilterRenderer/date.filter.renderer.ts b/frontend/src/shared/modules/filters/config/apiFilterRenderer/date.filter.renderer.ts index 5375e85489..05c23a331c 100644 --- a/frontend/src/shared/modules/filters/config/apiFilterRenderer/date.filter.renderer.ts +++ b/frontend/src/shared/modules/filters/config/apiFilterRenderer/date.filter.renderer.ts @@ -31,6 +31,7 @@ export const dateApiFilterRenderer = (property: string, { value, operator }: Dat }, }; } else if ([FilterDateOperator.EQ, FilterDateOperator.NE].includes(operator)) { + // shortcut: these casts hide an array mappedValue, as on main. revisit: when filter values are typed per operator. filter = { [property]: { between: [ @@ -40,6 +41,7 @@ export const dateApiFilterRenderer = (property: string, { value, operator }: Dat }, }; } else { + // shortcut: these casts hide an array mappedValue, as on main. revisit: when filter values are typed per operator. let parsedValue = dateHelper.utc(mappedValue as string).startOf('day').toISOString(); if (['last24h'].includes(value as string)) { diff --git a/frontend/src/shared/modules/merge/config/member/apiErrorMessage.ts b/frontend/src/shared/modules/merge/config/member/apiErrorMessage.ts index 2d6b280936..bf1f339903 100644 --- a/frontend/src/shared/modules/merge/config/member/apiErrorMessage.ts +++ b/frontend/src/shared/modules/merge/config/member/apiErrorMessage.ts @@ -3,6 +3,7 @@ import type { ErrorMessage } from '../../types/MemberMessage'; export default ({ error }: ErrorMessage) => { ToastStore.closeAll(); + // shortcut: assumes the merge error carries a response, as on main. revisit: when merge errors are typed. if (error.response!.status === 404) { ToastStore.success('Profiles already merged or deleted', { message: `Sorry, the profiles you are trying to merge might have already been merged or deleted. diff --git a/frontend/src/shared/modules/merge/config/organization/apiErrorMessage.ts b/frontend/src/shared/modules/merge/config/organization/apiErrorMessage.ts index 54d5341004..20d9bcf8d0 100644 --- a/frontend/src/shared/modules/merge/config/organization/apiErrorMessage.ts +++ b/frontend/src/shared/modules/merge/config/organization/apiErrorMessage.ts @@ -4,6 +4,7 @@ import type { ApiErrorMessage } from '../../types/OrganizationMessage'; export default ({ error }: ApiErrorMessage) => { ToastStore.closeAll(); + // shortcut: assumes the merge error carries a response, as on main. revisit: when merge errors are typed. if (error.response!.status === 404) { ToastStore.success('Organizations already merged or deleted', { message: `Sorry, the organizations you are trying to merge might have already been merged or deleted. diff --git a/frontend/src/shared/modules/report-issue/component/report-data-issue-modal.vue b/frontend/src/shared/modules/report-issue/component/report-data-issue-modal.vue index c41b37f016..49fa3ec672 100644 --- a/frontend/src/shared/modules/report-issue/component/report-data-issue-modal.vue +++ b/frontend/src/shared/modules/report-issue/component/report-data-issue-modal.vue @@ -203,6 +203,7 @@ const submit = () => { }; loading.value = true; + // shortcut: the modal only submits with an entity set, as on main. revisit: when the entity prop is required. return authAxios.post( `${getConfig.value.url(entity.value!.id)}`, data, diff --git a/frontend/src/shared/modules/saved-views/components/forms/SavedViewForm.vue b/frontend/src/shared/modules/saved-views/components/forms/SavedViewForm.vue index 09b18399ad..b218ba9101 100644 --- a/frontend/src/shared/modules/saved-views/components/forms/SavedViewForm.vue +++ b/frontend/src/shared/modules/saved-views/components/forms/SavedViewForm.vue @@ -346,6 +346,7 @@ const removeFilter = (key: any) => { const fillForm = () => { if (props.view) { form.shared = hasPermission(LfPermission.customViewsTenantManage) ? props.view.visibility === 'tenant' : false; + // shortcut: an edited view always has a name and config, as on main. revisit: when create and edit views get separate types. form.name = props.view.name!; const { relation, order, settings, search, ...restFilters From 7953072eb47f6538364bf33aebde85fc61773d10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C5=A1per=20Grom?= Date: Fri, 16 Oct 2026 04:52:16 +0100 Subject: [PATCH 5/5] chore: lower the type-check baseline to 154 (CM-1532) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs linuxfoundation/lfx-cdp-insights-ops#232 Signed-off-by: Gašper Grom --- frontend/typecheck-baseline.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/typecheck-baseline.json b/frontend/typecheck-baseline.json index 51e3530aba..e36cdfcf62 100644 --- a/frontend/typecheck-baseline.json +++ b/frontend/typecheck-baseline.json @@ -1 +1 @@ -{ "errors": 187 } +{ "errors": 154 }