11<template >
2- <div >
3-
2+ <div >
3+ <div class =" data-table" >
4+ <data-loading
5+ v-show =" shouldShowLoader"
6+ :for =" /cases-retention-logs/"
7+ :empty =" $t('No Data Available')"
8+ :empty-desc =" $t('')"
9+ empty-icon =" noData"
10+ />
11+ <div
12+ v-show =" !shouldShowLoader"
13+ class =" card card-body table-card"
14+ >
15+ <vuetable
16+ :data-manager =" dataManager"
17+ :css =" css"
18+ :api-mode =" false"
19+ :fields =" fields"
20+ :data =" data"
21+ data-path =" data"
22+ :no-data-template =" $t('No Data Available')"
23+ pagination-path =" meta"
24+ @vuetable:pagination-data =" onPaginationData"
25+ >
26+ <template
27+ slot="process_name"
28+ slot-scope="props"
29+ >
30+ <span v-uni-id =" props.rowData.id.toString()" >{{ props.rowData.name }}</span >
31+ </template >
32+ <template
33+ slot="case_id"
34+ slot-scope="props"
35+ >
36+ <span v-uni-id =" `case-id-${props.rowData.id}`" >{{ props.rowData.case_id }}</span >
37+ </template >
38+ <template
39+ slot="deleted_at"
40+ slot-scope="props"
41+ >
42+ {{ formatDate(props.rowData.deleted_at) }}
43+ </template >
44+ </vuetable >
45+ <pagination
46+ ref =" pagination"
47+ :single =" $t('Case')"
48+ :plural =" $t('Cases')"
49+ :per-page-select-enabled =" true"
50+ @changePerPage =" changePerPage"
51+ @vuetable-pagination:change-page =" onPageChange"
52+ />
53+ </div >
454 </div >
5- </template >
55+ </div >
56+ </template >
57+
58+ <script >
59+ import datatableMixin from " ../../../components/common/mixins/datatable" ;
60+ import dataLoadingMixin from " ../../../components/common/mixins/apiDataLoading" ;
61+
62+ /**
63+ * Fake data matching retention_policy_logs schema until the table/API exists.
64+ * - id, process_id, case_id (single or serialized list), deleted_at, created_at
65+ */
66+ const FAKE_RETENTION_LOGS = [
67+ {
68+ id: 1 ,
69+ process_id: 101 ,
70+ case_id: 5001 ,
71+ deleted_at: " 2025-03-01T14:30:00.000000Z" ,
72+ created_at: " 2025-03-01T14:30:05.000000Z" ,
73+ },
74+ {
75+ id: 2 ,
76+ process_id: 101 ,
77+ case_id: 5002 ,
78+ deleted_at: " 2025-03-02T09:15:00.000000Z" ,
79+ created_at: " 2025-03-02T09:15:02.000000Z" ,
80+ },
81+ {
82+ id: 3 ,
83+ process_id: 204 ,
84+ case_id: " [7001, 7002, 7003]" ,
85+ deleted_at: " 2025-03-03T16:45:00.000000Z" ,
86+ created_at: " 2025-03-03T16:45:10.000000Z" ,
87+ },
88+ {
89+ id: 4 ,
90+ process_id: 305 ,
91+ case_id: 8010 ,
92+ deleted_at: " 2025-03-04T11:00:00.000000Z" ,
93+ created_at: " 2025-03-04T11:00:01.000000Z" ,
94+ },
95+ {
96+ id: 5 ,
97+ process_id: 204 ,
98+ case_id: 7005 ,
99+ deleted_at: " 2025-03-05T08:22:00.000000Z" ,
100+ created_at: " 2025-03-05T08:22:03.000000Z" ,
101+ },
102+ ];
103+
104+ export default {
105+ name: " CasesRetentionLogs" ,
106+ mixins: [datatableMixin, dataLoadingMixin],
107+ props: {
108+ filter: {
109+ type: String ,
110+ default: " " ,
111+ },
112+ },
113+ data () {
114+ return {
115+ orderBy: " name" ,
116+ data: [],
117+ fields: [
118+ {
119+ title : () => this .$t (" Process" ),
120+ name: " __slot:process_name" ,
121+ width: " 33%" ,
122+ },
123+ {
124+ title : () => this .$t (" Case ID" ),
125+ name: " __slot:case_id" ,
126+ width: " 33%" ,
127+ },
128+ {
129+ title : () => this .$t (" Deleted At" ),
130+ name: " __slot:deleted_at" ,
131+ callback: " formatDate" ,
132+ width: " 33%" ,
133+ },
134+ ],
135+ };
136+ },
137+ watch: {
138+ filter () {
139+ this .page = 1 ;
140+ this .fetch ();
141+ },
142+ },
143+ methods: {
144+ fetch () {
145+ // TODO: replace with API call when retention_policy_logs table and endpoint exist
146+ // e.g. ProcessMaker.apiClient.get('/retention-policy-logs').then(r => {
147+ // this.data = r.data; // expect { data: [...], meta: { total, per_page, current_page, ... } }
148+ // }).finally(() => { this.apiDataLoading = false; });
149+ const total = FAKE_RETENTION_LOGS .length ;
150+ this .data = {
151+ data: FAKE_RETENTION_LOGS ,
152+ meta: {
153+ total,
154+ per_page: 15 ,
155+ current_page: 1 ,
156+ last_page: 1 ,
157+ from: 1 ,
158+ to: total,
159+ total_pages: 1 ,
160+ count: total,
161+ },
162+ };
163+ this .apiDataLoading = false ;
164+ },
165+ reload () {
166+ this .fetch ();
167+ },
168+ },
169+ };
170+ </script >
171+
172+ <style lang="scss" scoped>
173+ .data-table {
174+ .table-card {
175+ border-radius : 8px ;
176+ border : 1px solid #D7DDE5 ;
177+ }
178+
179+ .vuetable {
180+ border-radius : 8px ;
181+ overflow : hidden ;
182+
183+ thead {
184+ th {
185+ background-color : #FBFBFC !important ;
186+ border-bottom : 1px solid #D7DDE5 !important ;
187+ border-right : 1px solid #D7DDE5 !important ;
188+ font-weight : 600 !important ;
189+ color : #596372 !important ;
190+ padding : 12px 16px !important ;
191+ font-family : ' Inter' , sans-serif !important ;
192+ font-weight : 600 !important ;
193+ line-height : 20px !important ;
194+ letter-spacing : -0.01em !important ;
195+ font-size : 14px !important ;
196+
197+ & :last-child {
198+ border-right : none !important ;
199+ }
200+ }
201+ }
202+ }
203+ }
204+
205+ // Global override for Vuetable styles
206+ :deep(.vuetable ) {
207+ thead th {
208+ background-color : #FBFBFC !important ;
209+ border-bottom : 1px solid #D7DDE5 !important ;
210+ border-right : 1px solid #D7DDE5 !important ;
211+ font-weight : 600 !important ;
212+ color : #596372 !important ;
213+ padding : 12px 16px !important ;
214+ font-family : ' Inter' , sans-serif !important ;
215+ line-height : 20px !important ;
216+ font-size : 14px !important ;
217+ }
218+
219+ thead th :last-child {
220+ border-right : none !important ;
221+ }
222+
223+ tbody {
224+ tr {
225+ color : #4E5663 !important ;
226+ border-bottom : 1px solid #E9ECEF !important ;
227+ font-family : ' Inter' , sans-serif !important ;
228+ font-weight : 400 !important ;
229+ font-size : 14px !important ;
230+ line-height : 20px !important ;
231+
232+ td {
233+ padding : 12px 16px !important ;
234+ vertical-align : middle !important ;
235+ border-bottom : 1px solid #E9ECEF !important ;
236+ }
237+ }
238+ }
239+ }
240+ </style >
0 commit comments