diff --git a/strr-examiner-web/app/components/ApplicationInfoHeader.vue b/strr-examiner-web/app/components/ApplicationInfoHeader.vue index dd9dd2e7a..2d5474fe0 100644 --- a/strr-examiner-web/app/components/ApplicationInfoHeader.vue +++ b/strr-examiner-web/app/components/ApplicationInfoHeader.vue @@ -5,6 +5,7 @@ const exStore = useExaminerStore() const { activeHeader, activeReg, isFilingHistoryOpen } = storeToRefs(exStore) const { toggleFilingHistory, checkAndPerformAction } = useHostExpansion() const localePath = useLocalePath() +const { isSnapshotRoute } = useExaminerRoute() const getBadgeColor = (status: ApplicationStatus): string => { switch (status) { @@ -89,6 +90,7 @@ const registrationCountdown = computed(() => { /> { /> { > {{ t('btn.viewReceipt') }} +
activeReg.value.status === RegistrationStatus.CANCELLED) @@ -31,7 +32,7 @@ const isEditAddressDisabled = computed((): boolean => activeReg.value.status ===
{{ t('strr.label.rentalUnit').toUpperCase() }}
{ switch (status) { @@ -63,7 +64,7 @@ const nocCountdown = computed(() => {
-
+
{{ activeReg.registrationNumber }} @@ -88,6 +89,7 @@ const nocCountdown = computed(() => { /> { />
{ > {{ $t('btn.viewReceipt') }} +
{ > {{ t('strr.label.expiryDate') }} {{ dateToString(activeReg.expiryDate, 'y-MM-dd', true) }} - ({{ dayCountdown(activeReg.expiryDate.toString()) }} days left) + ({{ dayCountdown(activeReg.expiryDate?.toString()) }} days left) | {{ t('strr.label.assignee') }} - {{ activeHeader.assignee?.username || '-' }} - diff --git a/strr-examiner-web/app/pages/registration/[registrationId].vue b/strr-examiner-web/app/pages/registration/[registrationId]/index.vue similarity index 96% rename from strr-examiner-web/app/pages/registration/[registrationId].vue rename to strr-examiner-web/app/pages/registration/[registrationId]/index.vue index cf180c9d7..732e846e4 100644 --- a/strr-examiner-web/app/pages/registration/[registrationId].vue +++ b/strr-examiner-web/app/pages/registration/[registrationId]/index.vue @@ -12,7 +12,7 @@ const { const { isAssignedToUser, emailContent, emailFormRef, activeRecord, isApplication } = storeToRefs(useExaminerStore()) const { openConfirmActionModal, close: closeConfirmActionModal } = useStrrModals() const { showDecisionPanel } = useExaminerDecision() -const { isHistoricalApplicationsTableEnabled } = useExaminerFeatureFlags() +const { isHistoricalApplicationsTableEnabled, isSnapshotVersionsTableEnabled } = useExaminerFeatureFlags() useHead({ title: t('page.dashboardList.title') @@ -227,6 +227,10 @@ watch( v-if="!isApplication && isHistoricalApplicationsTableEnabled" :applications="(activeRecord as HousRegistrationResponse).header.applications ?? []" /> + diff --git a/strr-examiner-web/app/pages/registration/[registrationId]/snapshots/[snapshotId].vue b/strr-examiner-web/app/pages/registration/[registrationId]/snapshots/[snapshotId].vue new file mode 100644 index 000000000..a6d4a6038 --- /dev/null +++ b/strr-examiner-web/app/pages/registration/[registrationId]/snapshots/[snapshotId].vue @@ -0,0 +1,54 @@ + + + diff --git a/strr-examiner-web/app/stores/examiner.ts b/strr-examiner-web/app/stores/examiner.ts index d12f943fa..125d8fb58 100644 --- a/strr-examiner-web/app/stores/examiner.ts +++ b/strr-examiner-web/app/stores/examiner.ts @@ -13,6 +13,7 @@ export const useExaminerStore = defineStore('strr/examiner-store', () => { const isApplication = computed(() => { return !!activeRecord.value && 'registration' in activeRecord.value }) + const activeReg = computed(() => { return isApplication.value ? activeRecord.value?.registration @@ -31,6 +32,9 @@ export const useExaminerStore = defineStore('strr/examiner-store', () => { return currentRecordHeader }) const _isAssignedToUser = ref(false) + + const snapshotInfo = ref({} as ApiSnapshot) + watch( () => [ activeHeader.value?.assignee?.username @@ -529,6 +533,22 @@ export const useExaminerStore = defineStore('strr/examiner-store', () => { } } + /** + * Get a snapshot by registrationId and snapshotId. + * + * @param {string} registrationId - The registrationId for the registration + * @param {string} snapshotId - The snapshotId for the snapshot + */ + const getSnapshotById = async ( + registrationId: string, + snapshotId: string + ): Promise => { + return await $strrApi( + `/registrations/${registrationId}/snapshots/${snapshotId}`, + { method: 'GET' } + ) + } + const openDocInNewTab = async ( appRegNumber: string | number, supportingDocument: ApiDocument, @@ -602,6 +622,7 @@ export const useExaminerStore = defineStore('strr/examiner-store', () => { isAssignedToUser, sendNocSchema, emailContent, + snapshotInfo, // examiner approval conditions conditions, @@ -644,6 +665,7 @@ export const useExaminerStore = defineStore('strr/examiner-store', () => { setAsideApplication, getApplicationFilingHistory, getRegistrationFilingHistory, + getSnapshotById, startEditRentalUnitAddress, resetEditRentalUnitAddress, saveRentalUnitAddress, diff --git a/strr-examiner-web/i18n/locales/en-CA.ts b/strr-examiner-web/i18n/locales/en-CA.ts index 0d3fb6bc4..71cf2544d 100644 --- a/strr-examiner-web/i18n/locales/en-CA.ts +++ b/strr-examiner-web/i18n/locales/en-CA.ts @@ -139,6 +139,8 @@ export default { own: 'Own', coown: 'Co-Own', rent: 'Rent', + version: 'Version:', + date: 'Date:', accessDwelling: 'Accessory Dwelling', bb: 'Bed & Breakfast', condoApt: 'Condo or Apartment', @@ -267,6 +269,7 @@ export default { view: 'View', viewAllPlatforms: 'View all platforms', viewApplication: 'View Application', + viewSnapshot: 'View Snapshot', edit: 'Edit', done: 'Done', showDetails: 'Show Details', @@ -353,6 +356,7 @@ export default { }, label: { applications: 'Applications', + versions: 'Versions', hotelName: 'Hotel Name', expiryDate: 'Expiry Date', application: 'Application', @@ -488,6 +492,13 @@ export default { address: 'Address', localGovernment: 'Local Government', action: 'Action' + }, + registrationSnapshots: { + version: 'Version', + date: 'Date', + decision: 'Decision', + assignee: 'Assignee', + action: 'Action' } }, hint: { @@ -495,6 +506,9 @@ export default { docUpload: 'File must be a PDF. Maximum 10 MB.' }, page: { + snapshot: { + title: 'Snapshot - My Short-Term Rental Registry' + }, dashboardList: { title: 'Dashboard - My Short-Term Rental Registry', h1: 'My CEU STR Registry Dashboard', diff --git a/strr-examiner-web/package.json b/strr-examiner-web/package.json index 3fa6079f4..7cdf3de2e 100644 --- a/strr-examiner-web/package.json +++ b/strr-examiner-web/package.json @@ -2,7 +2,7 @@ "name": "strr-examiner-web", "private": true, "type": "module", - "version": "0.2.6", + "version": "0.2.7", "scripts": { "build-check": "nuxt build", "build": "nuxt generate", diff --git a/strr-examiner-web/tests/mocks/mockedData.ts b/strr-examiner-web/tests/mocks/mockedData.ts index e6ac3c9c5..74c8bbd89 100644 --- a/strr-examiner-web/tests/mocks/mockedData.ts +++ b/strr-examiner-web/tests/mocks/mockedData.ts @@ -563,3 +563,18 @@ export const mockHistoricalApplications: ApiApplicationEntry[] = [ applicationType: 'renewal' } ] + +export const mockSnapshots: ApiSnapshot[] = [ + { + id: 1, + snapshotDateTime: '2025-01-15T10:30:00.000000', + snapshotEndpoint: '/registrations/12345/snapshot/1', + version: 1 + }, + { + id: 2, + snapshotDateTime: '2025-02-20T14:45:00.000000', + snapshotEndpoint: '/registrations/12345/snapshot/2', + version: 2 + } +] diff --git a/strr-examiner-web/tests/unit/registration-details.spec.ts b/strr-examiner-web/tests/unit/registration-details.spec.ts index 402849298..42494f092 100644 --- a/strr-examiner-web/tests/unit/registration-details.spec.ts +++ b/strr-examiner-web/tests/unit/registration-details.spec.ts @@ -7,14 +7,17 @@ import { mockExpiredRegistration, mockSuspendedRegistration, mockCancelledRegistration, - mockHistoricalApplications + mockHistoricalApplications, + mockSnapshots } from '../mocks/mockedData' import { enI18n } from '../mocks/i18n' -import RegistrationDetails from '~/pages/registration/[registrationId].vue' +import RegistrationDetails from '~/pages/registration/[registrationId]/index.vue' import { DecisionPanel, HistoricalApplicationsTable, - RegistrationInfoHeader + RegistrationInfoHeader, + SnapshotVersionsTable, + SnapshotInfo } from '#components' import ApprovalConditions from '~/components/ApprovalConditions.vue' @@ -51,7 +54,8 @@ vi.mock('@/stores/examiner', () => ({ decisionEmailContent: ref({}), decisionEmailFormRef: ref({ clear: vi.fn() - }) + }), + snapshotInfo: ref(mockSnapshots[0]) }) })) @@ -317,4 +321,40 @@ describe('Examiner - Registration Details Page', () => { const viewButtons = wrapper.findAll('[data-testid="view-application-button"]') expect(viewButtons.length).toBe(2) }) + + it('displays Snapshot Versions table', async () => { + const wrapper = await mountSuspended(SnapshotVersionsTable, { + global: { plugins: [enI18n] }, + props: { snapshots: mockSnapshots } + }) + + expect(wrapper.exists()).toBe(true) + expect(wrapper.find('[data-testid="snapshot-versions-table"]').exists()).toBe(true) + + // verify that both snapshots are rendered + const rows = wrapper.find('[data-testid="snapshot-versions-table"]').findAll('tbody tr') + expect(rows.length).toBe(2) + + // verify version numbers are displayed + expect(wrapper.text()).toContain('1') + expect(wrapper.text()).toContain('2') + + // verify view snapshot buttons exist + const viewButtons = wrapper.findAll('[data-testid="view-snapshot-button"]') + expect(viewButtons.length).toBe(2) + }) + + it('displays Snapshot Info', async () => { + const wrapper = await mountSuspended(SnapshotInfo, { + global: { plugins: [enI18n] } + }) + + expect(wrapper.exists()).toBe(true) + expect(wrapper.find('[data-testid="snapshot-info"]').exists()).toBe(true) + + // verify version and date are displayed + expect(wrapper.text()).toContain('Version:') + expect(wrapper.text()).toContain('1') + expect(wrapper.text()).toContain('Date:') + }) })