@citizenplane/pimp 8.26.0 → 8.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{IconAccompaniedMinorEach-DDeSlaA_.js → IconAccompaniedMinorEach-BJYaPpW3.js} +1 -1
- package/dist/{IconAccompaniedMinorNone-BKs1gk1K.js → IconAccompaniedMinorNone-D1JR2Qpd.js} +1 -1
- package/dist/{IconAccompaniedMinorOne-CpL8FNve.js → IconAccompaniedMinorOne-BJ3jzEDZ.js} +1 -1
- package/dist/{IconAddReceipt-DLH3pqjA.js → IconAddReceipt-BX_va94f.js} +1 -1
- package/dist/{IconAirportTerminal-Cc4CU6MC.js → IconAirportTerminal-Dzr98nfc.js} +1 -1
- package/dist/{IconArrival-CdtUsRVo.js → IconArrival-Ced9HrJH.js} +1 -1
- package/dist/{IconBroadcast-QjMZtFA9.js → IconBroadcast-BYX44Wak.js} +1 -1
- package/dist/{IconCabinBag-xVC6mOQF.js → IconCabinBag-D1Qs952U.js} +1 -1
- package/dist/{IconCheckedBaggage-I_1h49TJ.js → IconCheckedBaggage-Q4_SQL9l.js} +1 -1
- package/dist/{IconCheckedBaggage20-CyPcsqrn.js → IconCheckedBaggage20-DVH1-A0V.js} +1 -1
- package/dist/{IconCheckedBaggage30-s5htbUIA.js → IconCheckedBaggage30-DYOAf-7Z.js} +1 -1
- package/dist/{IconChild-DL43kbm1.js → IconChild-BeCLAr8Y.js} +1 -1
- package/dist/{IconContact-FdhTr03q.js → IconContact-B3r39fyI.js} +1 -1
- package/dist/{IconDeparture-DNR3OGPD.js → IconDeparture-BflKZUiE.js} +1 -1
- package/dist/{IconDistribution-Cl8L6177.js → IconDistribution-CBxQ7UWb.js} +1 -1
- package/dist/{IconDistributionClosed-DBT6wR78.js → IconDistributionClosed-BWp_k24K.js} +1 -1
- package/dist/{IconDistributionExclusivePair-CkRG6yNV.js → IconDistributionExclusivePair-erLbcLps.js} +1 -1
- package/dist/{IconDistributionSided-D_wdvDNf.js → IconDistributionSided-y000n4qB.js} +1 -1
- package/dist/{IconDistributionSupplySided-C3VcE8Dw.js → IconDistributionSupplySided-7kCvGwnz.js} +1 -1
- package/dist/{IconDynamicContent-Ct1HRd3s.js → IconDynamicContent-SwBxkPMB.js} +1 -1
- package/dist/{IconFares-dIGVrtE4.js → IconFares-DTm0Q_RI.js} +1 -1
- package/dist/{IconFaresOutlined-bd8kT44f.js → IconFaresOutlined-BFMo_x9Q.js} +1 -1
- package/dist/{IconFemale-CMeYHrDy.js → IconFemale-Ma0KeaEM.js} +1 -1
- package/dist/{IconFindConversation-BdN2Yd3R.js → IconFindConversation-CpsDYPgD.js} +1 -1
- package/dist/{IconFire-obwuluyJ.js → IconFire-DECrDnLM.js} +1 -1
- package/dist/{IconFlight-B_6tJxB3.js → IconFlight-D5M0A0CM.js} +1 -1
- package/dist/{IconFlightReturn-BEO97PwR.js → IconFlightReturn-CTvqEFME.js} +1 -1
- package/dist/{IconHandHeart-hs0yFSEL.js → IconHandHeart-ChgdfXQa.js} +1 -1
- package/dist/{IconHistory-CT-jOMRt.js → IconHistory-DpIXDYI5.js} +1 -1
- package/dist/{IconHourGlass-CF940vmy.js → IconHourGlass-CIRkFUSM.js} +1 -1
- package/dist/{IconIdCard-DKkU58Ix.js → IconIdCard-UD5VZsUi.js} +1 -1
- package/dist/{IconInfant-DIUT-6_4.js → IconInfant-CmLUvWpO.js} +1 -1
- package/dist/{IconItinerary-D7mOGUmj.js → IconItinerary-CY8irele.js} +1 -1
- package/dist/{IconLeave-BExl4uyV.js → IconLeave-C3bpPz6L.js} +1 -1
- package/dist/{IconMale-eHGH5XBz.js → IconMale-x4xdulWB.js} +1 -1
- package/dist/{IconMultiSegments-KkrKiZrK.js → IconMultiSegments-BhTMfvhQ.js} +1 -1
- package/dist/{IconNoPassport-PJ2QqqoI.js → IconNoPassport-_Xm76k6b.js} +1 -1
- package/dist/{IconNoRefund-W47AQisu.js → IconNoRefund-B78s0oyF.js} +1 -1
- package/dist/{IconNotion-CCnhatKK.js → IconNotion-C22PTLTU.js} +1 -1
- package/dist/{IconOffline-3wunTEJG.js → IconOffline-BDzikWE9.js} +1 -1
- package/dist/{IconOneWay-BQ5K41Bu.js → IconOneWay-DlTVxokv.js} +2 -2
- package/dist/{IconPaid-zwDwWzF8.js → IconPaid-DmGERe85.js} +1 -1
- package/dist/{IconPassport-IxhNLS8P.js → IconPassport-6VOlXjxJ.js} +1 -1
- package/dist/{IconPayout-BNSON3dj.js → IconPayout-abr6BXCd.js} +1 -1
- package/dist/{IconReceipt-DOosYtgi.js → IconReceipt-BnTaihcq.js} +1 -1
- package/dist/{IconRecurrence-B8i5kO2Q.js → IconRecurrence-C5TPG2ht.js} +1 -1
- package/dist/{IconRefund-DkjF9lEI.js → IconRefund-Ysv8pyMJ.js} +1 -1
- package/dist/{IconRoundTrip-BZvhS65z.js → IconRoundTrip-CIVDw8LK.js} +1 -1
- package/dist/{IconRouteNoStop-CeSlfnpx.js → IconRouteNoStop-DQrq4gW5.js} +1 -1
- package/dist/{IconRouteOneStop-aP1Mj-Bv.js → IconRouteOneStop-pzisj4i4.js} +1 -1
- package/dist/{IconScheduleChange-QQ4AMAMI.js → IconScheduleChange-BONs1AAT.js} +1 -1
- package/dist/{IconSeatEmpty-DgVBD165.js → IconSeatEmpty-CHij3aGA.js} +1 -1
- package/dist/{IconSeatSold-BGBwNZUa.js → IconSeatSold-QspS_zCh.js} +1 -1
- package/dist/{IconSeatTotal-Dq9uXccZ.js → IconSeatTotal-DTZ1TcAX.js} +1 -1
- package/dist/{IconTemplate-BgruEhjI.js → IconTemplate-BDmmr-9L.js} +1 -1
- package/dist/{IconTicket-BTaYnuPt.js → IconTicket--vVn61Ey.js} +1 -1
- package/dist/{IconTimer-CyJzne5T.js → IconTimer-CspKpwqZ.js} +1 -1
- package/dist/{IconTrafficControl-BeQtpwhK.js → IconTrafficControl-DBamcJNe.js} +1 -1
- package/dist/{index-B8RNa4cx.js → index-C3oHnZQk.js} +9152 -10064
- package/dist/pimp.es.js +1 -1
- package/dist/pimp.umd.js +17 -17
- package/dist/style.css +1 -1
- package/package.json +2 -1
- package/src/components/atomic-elements/CpAirlineLogo.vue +9 -10
- package/src/components/atomic-elements/CpBadge.vue +33 -41
- package/src/components/atomic-elements/CpDialog.vue +14 -9
- package/src/components/atomic-elements/CpPartnerBadge.vue +12 -20
- package/src/components/atomic-elements/CpTooltip.vue +12 -11
- package/src/components/buttons/CpButton.vue +63 -104
- package/src/components/core/BaseInputLabel.vue +9 -15
- package/src/components/core/BaseSelectClearButton.vue +1 -1
- package/src/components/date-pickers/CpCalendar.vue +154 -153
- package/src/components/date-pickers/CpDate.vue +202 -212
- package/src/components/date-pickers/CpDatepicker.vue +112 -138
- package/src/components/feedback-indicators/CpAlert.vue +16 -27
- package/src/components/feedback-indicators/CpLoader.vue +7 -8
- package/src/components/feedback-indicators/CpToaster.vue +197 -192
- package/src/components/helpers-utilities/TransitionExpand.vue +31 -33
- package/src/components/icons/IconOneWay.vue +1 -1
- package/src/components/index.ts +28 -40
- package/src/components/inputs/CpInput.vue +40 -57
- package/src/components/inputs/CpTextarea.vue +30 -50
- package/src/components/lists-and-table/CpTable.vue +165 -114
- package/src/components/lists-and-table/CpTableEmptyState.vue +5 -8
- package/src/components/selects/CpMultiselect.vue +58 -89
- package/src/components/selects/CpSelect.vue +70 -90
- package/src/components/selects/CpSelectMenu.vue +94 -96
- package/src/components/toggles/CpCheckbox.vue +45 -54
- package/src/components/toggles/CpRadio.vue +47 -58
- package/src/components/toggles/CpSwitch.vue +51 -67
- package/src/components/typography/CpHeading.vue +11 -31
- package/src/components/visual/CpIcon.vue +2 -1
- package/src/constants/{src/CpCustomIcons.ts → CpCustomIcons.ts} +1 -1
- package/src/constants/CpTableConfig.ts +12 -0
- package/src/constants/Heading.ts +8 -0
- package/src/{utils/constants/src/Intent.js → constants/Intent.ts} +1 -1
- package/src/constants/PartnerTypes.ts +6 -0
- package/src/constants/Position.ts +10 -0
- package/src/constants/Sizes.ts +5 -0
- package/src/constants/colors/Colors.ts +10 -0
- package/src/constants/colors/ToggleColors.ts +6 -0
- package/src/constants/index.ts +10 -5
- package/src/directives/ClickOutside.ts +17 -0
- package/src/directives/{ResizeSelect.js → ResizeSelect.ts} +3 -3
- package/src/helpers/{dom.js → dom.ts} +13 -9
- package/src/helpers/{index.js → index.ts} +13 -3
- package/src/helpers/object.ts +9 -0
- package/src/helpers/string/src/camelize.ts +6 -0
- package/src/helpers/string/src/{decamelize.js → decamelize.ts} +1 -1
- package/src/libs/CoreDatepicker.vue +4 -4
- package/src/plugins/toaster.ts +71 -0
- package/src/stories/BaseInputLabel.stories.ts +1 -0
- package/src/stories/CpAlert.stories.ts +1 -0
- package/src/stories/CpBadge.stories.ts +18 -0
- package/src/stories/CpCheckbox.stories.ts +3 -1
- package/src/stories/CpDate.stories.ts +3 -1
- package/src/stories/CpDatepicker.stories.ts +3 -1
- package/src/stories/CpDialog.stories.ts +2 -1
- package/src/stories/CpHeading.stories.ts +1 -0
- package/src/stories/CpIcon.stories.ts +2 -0
- package/src/stories/CpInput.stories.ts +3 -1
- package/src/stories/CpLoader.stories.ts +1 -0
- package/src/stories/CpMultiselect.stories.ts +2 -1
- package/src/stories/CpPartnerBadge.stories.ts +1 -1
- package/src/stories/CpRadio.stories.ts +3 -1
- package/src/stories/CpSelect.stories.ts +3 -1
- package/src/stories/CpSelectMenu.stories.ts +3 -1
- package/src/stories/CpSwitch.stories.ts +3 -1
- package/src/stories/CpTable.stories.ts +8 -1
- package/src/stories/CpTableEmptyState.stories.ts +1 -0
- package/src/stories/CpTextarea.stories.ts +3 -1
- package/src/stories/CpToaster.stories.ts +1 -0
- package/src/stories/CpTooltip.stories.ts +1 -0
- package/src/stories/TransitionExpand.stories.ts +3 -1
- package/src/types/luxon.d.ts +1 -0
- package/src/vendors/ff-polyfill.ts +38 -0
- package/vitest.workspace.js +1 -3
- package/src/constants/src/CpTableConfig.ts +0 -14
- package/src/constants/src/Position.ts +0 -10
- package/src/constants/src/colors/Colors.ts +0 -10
- package/src/constants/src/colors/ToggleColors.ts +0 -6
- package/src/directives/ClickOutside.js +0 -13
- package/src/helpers/object.js +0 -9
- package/src/helpers/string/src/camelize.js +0 -6
- package/src/plugins/toaster.js +0 -61
- package/src/utils/constants/index.js +0 -3
- package/src/utils/constants/src/PartnerTypes.js +0 -6
- package/src/utils/constants/src/Sizes.js +0 -5
- package/src/vendors/ff-polyfill.js +0 -36
- /package/src/helpers/string/{index.js → index.ts} +0 -0
|
@@ -111,98 +111,109 @@
|
|
|
111
111
|
</div>
|
|
112
112
|
</template>
|
|
113
113
|
|
|
114
|
-
<script setup>
|
|
114
|
+
<script setup lang="ts">
|
|
115
115
|
import { ref, computed } from 'vue'
|
|
116
116
|
|
|
117
|
+
import CpTableEmptyState from '@/components/lists-and-table/CpTableEmptyState.vue'
|
|
118
|
+
|
|
117
119
|
import { camelize, decamelize } from '@/helpers/string'
|
|
120
|
+
|
|
121
|
+
import { PAGINATION_FORMATS, RESERVED_KEYS, VISIBLE_ROWS_MAX } from '@/constants'
|
|
118
122
|
import { randomString } from '@/helpers'
|
|
119
123
|
|
|
120
|
-
|
|
124
|
+
const LoaderColor = '#5341F9'
|
|
121
125
|
|
|
122
|
-
|
|
126
|
+
interface ColumnDefinition {
|
|
127
|
+
id: string
|
|
128
|
+
name: string
|
|
129
|
+
textAlign?: 'left' | 'center' | 'right'
|
|
130
|
+
width?: number
|
|
131
|
+
}
|
|
123
132
|
|
|
124
|
-
|
|
133
|
+
interface PaginationServer {
|
|
134
|
+
activePage: number
|
|
135
|
+
total: number
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
interface Pagination {
|
|
139
|
+
enabled?: boolean
|
|
140
|
+
format?: (typeof PAGINATION_FORMATS)[keyof typeof PAGINATION_FORMATS]
|
|
141
|
+
limit?: number
|
|
142
|
+
server?: PaginationServer
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
interface RowOptions {
|
|
146
|
+
action: (payload: { rowData: Record<string, unknown>; rowIndex: number }, event: Event) => void
|
|
147
|
+
disabled?: boolean
|
|
148
|
+
icon: string
|
|
149
|
+
id: string
|
|
150
|
+
isCritical?: boolean
|
|
151
|
+
label: string
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
interface GroupByData {
|
|
155
|
+
groupBy: string
|
|
156
|
+
rows: Record<string, unknown>[]
|
|
157
|
+
}
|
|
125
158
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
return isLimitValid && isFooterDetailsFormatValid
|
|
152
|
-
},
|
|
153
|
-
},
|
|
154
|
-
areRowsClickable: {
|
|
155
|
-
type: Boolean,
|
|
156
|
-
default: false,
|
|
157
|
-
required: false,
|
|
158
|
-
},
|
|
159
|
-
emptyCellPlaceholder: {
|
|
160
|
-
type: String,
|
|
161
|
-
default: 'n/a',
|
|
162
|
-
required: false,
|
|
163
|
-
},
|
|
164
|
-
noResultPlaceholder: {
|
|
165
|
-
type: String,
|
|
166
|
-
default: 'No results found',
|
|
167
|
-
required: false,
|
|
168
|
-
},
|
|
169
|
-
isLoading: {
|
|
170
|
-
type: Boolean,
|
|
171
|
-
default: false,
|
|
172
|
-
required: false,
|
|
173
|
-
},
|
|
174
|
-
enableRowOptions: {
|
|
175
|
-
type: Boolean,
|
|
176
|
-
default: false,
|
|
177
|
-
required: false,
|
|
178
|
-
},
|
|
179
|
-
quickOptionsLimit: {
|
|
180
|
-
type: Number,
|
|
181
|
-
default: 3,
|
|
182
|
-
required: false,
|
|
183
|
-
},
|
|
184
|
-
rowOptions: {
|
|
185
|
-
type: Array,
|
|
186
|
-
default: () => [],
|
|
187
|
-
required: false,
|
|
188
|
-
},
|
|
159
|
+
interface Props {
|
|
160
|
+
areRowsClickable?: boolean
|
|
161
|
+
caption?: string
|
|
162
|
+
columns?: string[] | ColumnDefinition[]
|
|
163
|
+
data: (Record<string, unknown> | GroupByData)[]
|
|
164
|
+
emptyCellPlaceholder?: string
|
|
165
|
+
enableRowOptions?: boolean
|
|
166
|
+
isLoading?: boolean
|
|
167
|
+
noResultPlaceholder?: string
|
|
168
|
+
pagination?: Pagination
|
|
169
|
+
quickOptionsLimit?: number
|
|
170
|
+
rowOptions?: RowOptions[]
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
174
|
+
caption: '',
|
|
175
|
+
columns: () => [],
|
|
176
|
+
pagination: undefined,
|
|
177
|
+
areRowsClickable: false,
|
|
178
|
+
emptyCellPlaceholder: 'n/a',
|
|
179
|
+
noResultPlaceholder: 'No results found',
|
|
180
|
+
isLoading: false,
|
|
181
|
+
enableRowOptions: false,
|
|
182
|
+
quickOptionsLimit: 3,
|
|
183
|
+
rowOptions: () => [],
|
|
189
184
|
})
|
|
190
185
|
|
|
191
|
-
|
|
186
|
+
interface Emits {
|
|
187
|
+
(e: 'onRowClick', data: Record<string, unknown>): void
|
|
188
|
+
(e: 'onRowRightClick', payload: { data: Record<string, unknown>; event: Event }): void
|
|
189
|
+
(e: 'onNextClick'): void
|
|
190
|
+
(e: 'onPreviousClick'): void
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const emit = defineEmits<Emits>()
|
|
192
194
|
|
|
193
195
|
const uniqueId = ref(randomString())
|
|
194
196
|
const pageNumber = ref(0)
|
|
195
|
-
const cpTableContainer = ref(null)
|
|
197
|
+
const cpTableContainer = ref<HTMLElement | null>(null)
|
|
196
198
|
|
|
197
199
|
const hasQuickOptions = computed(() => !!quickOptions.value.length)
|
|
198
200
|
const hasMoreQuickActionsThanLimit = computed(() => props.rowOptions.length >= props.quickOptionsLimit)
|
|
199
201
|
|
|
200
|
-
const defaultRowOptions = computed(() => {
|
|
201
|
-
if (!props.enableRowOptions || !props.rowOptions.length)
|
|
202
|
+
const defaultRowOptions = computed<RowOptions>(() => {
|
|
203
|
+
if (!props.enableRowOptions || !props.rowOptions.length) {
|
|
204
|
+
return {
|
|
205
|
+
id: 'default',
|
|
206
|
+
label: 'More',
|
|
207
|
+
icon: 'more-vertical',
|
|
208
|
+
action: () => {},
|
|
209
|
+
}
|
|
210
|
+
}
|
|
202
211
|
return {
|
|
212
|
+
id: 'more',
|
|
203
213
|
label: 'More',
|
|
204
214
|
icon: 'more-vertical',
|
|
205
|
-
action: ({ rowData, rowIndex }
|
|
215
|
+
action: ({ rowData, rowIndex }: { rowData: Record<string, unknown>; rowIndex: number }, $event: Event) =>
|
|
216
|
+
handleRowRightClick({ rowData, rowIndex }, $event),
|
|
206
217
|
}
|
|
207
218
|
})
|
|
208
219
|
|
|
@@ -222,7 +233,7 @@ const containerDOMElement = computed(() => cpTableContainer.value)
|
|
|
222
233
|
const mainClasses = computed(() => ({ 'cpTable--isLoading': props.isLoading }))
|
|
223
234
|
const containerClasses = computed(() => ({ 'cpTable__container--hasPagination': hasPagination.value }))
|
|
224
235
|
|
|
225
|
-
const normalizedColumns = computed(() => {
|
|
236
|
+
const normalizedColumns = computed<ColumnDefinition[]>(() => {
|
|
226
237
|
if (!props.columns) return []
|
|
227
238
|
const columns = props.columns.length ? [...props.columns] : [...columnsFromRows.value]
|
|
228
239
|
|
|
@@ -235,8 +246,8 @@ const normalizedColumns = computed(() => {
|
|
|
235
246
|
}
|
|
236
247
|
|
|
237
248
|
return {
|
|
238
|
-
id: column.id || camelize(column.name),
|
|
239
249
|
...column,
|
|
250
|
+
id: column.id || camelize(column.name),
|
|
240
251
|
}
|
|
241
252
|
})
|
|
242
253
|
})
|
|
@@ -245,30 +256,39 @@ const numberOfColumns = computed(() => normalizedColumns.value.length)
|
|
|
245
256
|
|
|
246
257
|
const hasGroupBy = computed(() => {
|
|
247
258
|
if (!props.data.length) return false
|
|
248
|
-
return props.data.some((item) =>
|
|
259
|
+
return props.data.some((item) => RESERVED_KEYS.GROUP_BY in item)
|
|
249
260
|
})
|
|
250
261
|
|
|
251
262
|
const columnsFromRows = computed(() => {
|
|
252
263
|
if (!props.data.length) return []
|
|
253
|
-
const
|
|
254
|
-
|
|
264
|
+
const firstItem = props.data[0]
|
|
265
|
+
const firstRow = hasGroupBy.value && 'rows' in firstItem ? (firstItem as GroupByData).rows[0] : firstItem
|
|
266
|
+
return Object.keys(firstRow as Record<string, unknown>)
|
|
255
267
|
})
|
|
256
268
|
|
|
257
269
|
const numberOfResults = computed(() => {
|
|
258
|
-
return isServerSidePagination.value ? props.pagination
|
|
270
|
+
return isServerSidePagination.value ? props.pagination?.server?.total || 0 : flattenedRows.value.length
|
|
259
271
|
})
|
|
260
272
|
|
|
261
273
|
const hasNoResult = computed(() => numberOfResults.value === 0)
|
|
262
|
-
const rowsPerPageLimit = computed(() =>
|
|
274
|
+
const rowsPerPageLimit = computed(() => {
|
|
275
|
+
if (typeof props.pagination === 'object' && props.pagination.limit) {
|
|
276
|
+
return props.pagination.limit
|
|
277
|
+
}
|
|
278
|
+
return VISIBLE_ROWS_MAX
|
|
279
|
+
})
|
|
263
280
|
|
|
264
281
|
const flattenedRows = computed(() => {
|
|
265
282
|
if (!props.data) return []
|
|
266
|
-
if (!hasGroupBy.value) return props.data
|
|
283
|
+
if (!hasGroupBy.value) return props.data as Record<string, unknown>[]
|
|
267
284
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
285
|
+
return props.data.reduce((flattenedRows: Record<string, unknown>[], item) => {
|
|
286
|
+
if ('groupBy' in item) {
|
|
287
|
+
const groupByItem = item as GroupByData
|
|
288
|
+
const fullWidthRow = { [RESERVED_KEYS.GROUP_BY]: groupByItem.groupBy }
|
|
289
|
+
return [...flattenedRows, fullWidthRow, ...groupByItem.rows]
|
|
290
|
+
}
|
|
291
|
+
return [...flattenedRows, item as Record<string, unknown>]
|
|
272
292
|
}, [])
|
|
273
293
|
})
|
|
274
294
|
|
|
@@ -286,11 +306,16 @@ const visibleRows = computed(() =>
|
|
|
286
306
|
)
|
|
287
307
|
|
|
288
308
|
const paginationState = computed(() => {
|
|
289
|
-
return typeof props.pagination === 'boolean' ? props.pagination : props.pagination
|
|
309
|
+
return typeof props.pagination === 'boolean' ? props.pagination : props.pagination?.enabled
|
|
290
310
|
})
|
|
291
311
|
|
|
292
|
-
const hasPagination = computed(() => paginationState.value || numberOfResults.value >
|
|
293
|
-
const paginationFormat = computed(() =>
|
|
312
|
+
const hasPagination = computed(() => paginationState.value || numberOfResults.value > VISIBLE_ROWS_MAX)
|
|
313
|
+
const paginationFormat = computed(() => {
|
|
314
|
+
if (typeof props.pagination === 'object' && props.pagination.format) {
|
|
315
|
+
return props.pagination.format
|
|
316
|
+
}
|
|
317
|
+
return PAGINATION_FORMATS.PAGES
|
|
318
|
+
})
|
|
294
319
|
const hasRemainingPages = computed(() => numberOfPages.value > activePage.value)
|
|
295
320
|
const isNextEnabled = computed(() => hasRemainingPages.value && !props.isLoading)
|
|
296
321
|
|
|
@@ -307,11 +332,11 @@ const activePage = computed(() => {
|
|
|
307
332
|
})
|
|
308
333
|
|
|
309
334
|
const isServerSidePagination = computed(() => {
|
|
310
|
-
if (
|
|
335
|
+
if (!props.pagination) return false
|
|
311
336
|
return 'server' in props.pagination
|
|
312
337
|
})
|
|
313
338
|
|
|
314
|
-
const serverActivePage = computed(() => props.pagination
|
|
339
|
+
const serverActivePage = computed(() => props.pagination?.server?.activePage || 0)
|
|
315
340
|
const serverPagesStartIndex = computed(() => serverActivePage.value * rowsPerPageLimit.value + 1)
|
|
316
341
|
const serverPagesEndIndex = computed(() => rowsPerPageLimit.value * (1 + serverActivePage.value))
|
|
317
342
|
|
|
@@ -325,7 +350,7 @@ const pageLastResultIndex = computed(() => {
|
|
|
325
350
|
})
|
|
326
351
|
|
|
327
352
|
const paginationLabel = computed(() => {
|
|
328
|
-
if (paginationFormat.value ===
|
|
353
|
+
if (paginationFormat.value === PAGINATION_FORMATS.PAGES) {
|
|
329
354
|
const pluralizedCount = numberOfPages.value > 1 ? 'pages' : 'page'
|
|
330
355
|
return `${activePage.value}/${numberOfPages.value} ${pluralizedCount}`
|
|
331
356
|
}
|
|
@@ -338,22 +363,25 @@ const paginationResultsDetails = computed(() => {
|
|
|
338
363
|
return `${formattedNumberOfResults} ${pluralizedCount}`
|
|
339
364
|
})
|
|
340
365
|
|
|
341
|
-
const getQuickOptionTooltip = (option) => (!option.disabled ? option.label : '')
|
|
366
|
+
const getQuickOptionTooltip = (option: RowOptions) => (!option.disabled ? option.label : '')
|
|
342
367
|
|
|
343
|
-
const getQuickOptionClasses = (option) => {
|
|
368
|
+
const getQuickOptionClasses = (option: RowOptions) => {
|
|
344
369
|
return { 'cpTable__action--isCritical': option.isCritical }
|
|
345
370
|
}
|
|
346
371
|
|
|
347
|
-
const getRowPayload = (rowIndex) => rawVisibleRows.value[rowIndex]
|
|
372
|
+
const getRowPayload = (rowIndex: number) => rawVisibleRows.value[rowIndex]
|
|
348
373
|
|
|
349
|
-
const handleRowClick = (rowData, rowIndex) => {
|
|
374
|
+
const handleRowClick = (rowData: Record<string, unknown>, rowIndex: number) => {
|
|
350
375
|
if (isFullWidthRow(rowData)) return
|
|
351
376
|
|
|
352
377
|
const data = getRowPayload(rowIndex)
|
|
353
378
|
emit('onRowClick', data)
|
|
354
379
|
}
|
|
355
380
|
|
|
356
|
-
const handleRowRightClick = (
|
|
381
|
+
const handleRowRightClick = (
|
|
382
|
+
{ rowData, rowIndex }: { rowData: Record<string, unknown>; rowIndex: number },
|
|
383
|
+
event: Event,
|
|
384
|
+
) => {
|
|
357
385
|
if (isFullWidthRow(rowData)) return
|
|
358
386
|
|
|
359
387
|
const data = getRowPayload(rowIndex)
|
|
@@ -375,7 +403,13 @@ const handleNavigationClick = (isNext = true) => {
|
|
|
375
403
|
emit('onPreviousClick')
|
|
376
404
|
}
|
|
377
405
|
|
|
378
|
-
const normalizeRowData = ({
|
|
406
|
+
const normalizeRowData = ({
|
|
407
|
+
columns = normalizedColumns.value,
|
|
408
|
+
rowPayload,
|
|
409
|
+
}: {
|
|
410
|
+
columns?: ColumnDefinition[]
|
|
411
|
+
rowPayload: Record<string, unknown>
|
|
412
|
+
}) => {
|
|
379
413
|
if (!Array.isArray(rowPayload)) {
|
|
380
414
|
return { ...rowPayload }
|
|
381
415
|
}
|
|
@@ -390,12 +424,18 @@ const normalizeRowData = ({ columns = normalizedColumns.value, rowPayload }) =>
|
|
|
390
424
|
}, {})
|
|
391
425
|
}
|
|
392
426
|
|
|
393
|
-
const mapCellToColumn = ({
|
|
427
|
+
const mapCellToColumn = ({
|
|
428
|
+
columns = normalizedColumns.value,
|
|
429
|
+
rowPayload,
|
|
430
|
+
}: {
|
|
431
|
+
columns?: ColumnDefinition[]
|
|
432
|
+
rowPayload: Record<string, unknown>
|
|
433
|
+
}) => {
|
|
394
434
|
if (isFullWidthRow(rowPayload)) return rowPayload
|
|
395
435
|
// Bind column id with each row key
|
|
396
436
|
// and replace row missing keys with the emptyCellPlaceholder value
|
|
397
437
|
return columns.reduce((finalRow, currentColumn) => {
|
|
398
|
-
const correspondingColumn = currentColumn
|
|
438
|
+
const correspondingColumn = currentColumn.id
|
|
399
439
|
const correspondingValue = rowPayload[correspondingColumn] || props.emptyCellPlaceholder
|
|
400
440
|
const cellValue = { [correspondingColumn]: correspondingValue }
|
|
401
441
|
|
|
@@ -411,9 +451,13 @@ const decreaseOffset = () => {
|
|
|
411
451
|
if (isPreviousEnabled.value) pageNumber.value--
|
|
412
452
|
}
|
|
413
453
|
|
|
414
|
-
const resetScrollPosition = () =>
|
|
454
|
+
const resetScrollPosition = () => {
|
|
455
|
+
if (containerDOMElement.value) {
|
|
456
|
+
containerDOMElement.value.scrollTop = 0
|
|
457
|
+
}
|
|
458
|
+
}
|
|
415
459
|
|
|
416
|
-
const getColumnStyle = (columnPayload) => {
|
|
460
|
+
const getColumnStyle = (columnPayload: ColumnDefinition) => {
|
|
417
461
|
const formattedWidth = columnPayload?.width && `${columnPayload.width}px`
|
|
418
462
|
|
|
419
463
|
return {
|
|
@@ -422,14 +466,14 @@ const getColumnStyle = (columnPayload) => {
|
|
|
422
466
|
}
|
|
423
467
|
}
|
|
424
468
|
|
|
425
|
-
const getCellStyle = (cellKey,
|
|
469
|
+
const getCellStyle = (cellKey: RESERVED_KEYS, cellIndex: number) => {
|
|
426
470
|
if (isFullWidthCell(cellKey)) return null
|
|
427
471
|
return {
|
|
428
|
-
textAlign: normalizedColumns.value[
|
|
472
|
+
textAlign: normalizedColumns.value[cellIndex]?.textAlign,
|
|
429
473
|
}
|
|
430
474
|
}
|
|
431
475
|
|
|
432
|
-
const getRowClasses = (rowData, rowIndex) => {
|
|
476
|
+
const getRowClasses = (rowData: Record<string, unknown>, rowIndex: number) => {
|
|
433
477
|
return {
|
|
434
478
|
'cpTable__row--isFullWidth': isFullWidthRow(rowData),
|
|
435
479
|
'cpTable__row--isClickable': !isFullWidthRow(rowData) && props.areRowsClickable,
|
|
@@ -437,24 +481,26 @@ const getRowClasses = (rowData, rowIndex) => {
|
|
|
437
481
|
}
|
|
438
482
|
}
|
|
439
483
|
|
|
440
|
-
const getCellClasses = (cellKey) => {
|
|
484
|
+
const getCellClasses = (cellKey: RESERVED_KEYS) => {
|
|
441
485
|
return { 'cpTable__cell--isFullWidth': isFullWidthCell(cellKey) }
|
|
442
486
|
}
|
|
443
487
|
|
|
444
|
-
const getColspan = (cellKey) => {
|
|
488
|
+
const getColspan = (cellKey: RESERVED_KEYS) => {
|
|
445
489
|
const numberOfColumnsValue = props.enableRowOptions ? numberOfColumns.value + 1 : numberOfColumns.value
|
|
446
|
-
return isFullWidthCell(cellKey) ? numberOfColumnsValue :
|
|
490
|
+
return isFullWidthCell(cellKey) ? numberOfColumnsValue : undefined
|
|
447
491
|
}
|
|
448
492
|
|
|
449
|
-
const getTabindex = (rowData) => (isFullWidthRow(rowData) ? -1 : 0)
|
|
450
|
-
|
|
451
|
-
const fullWidthCellKeys = [CpTableConfig.RESERVED_KEYS.FULL_WIDTH, CpTableConfig.RESERVED_KEYS.GROUP_BY]
|
|
493
|
+
const getTabindex = (rowData: Record<string, unknown>) => (isFullWidthRow(rowData) ? -1 : 0)
|
|
452
494
|
|
|
453
|
-
const
|
|
454
|
-
const
|
|
495
|
+
const fullWidthCellKeys = [RESERVED_KEYS.FULL_WIDTH, RESERVED_KEYS.GROUP_BY]
|
|
496
|
+
const isFullWidthCell = (cellKey: RESERVED_KEYS) => fullWidthCellKeys.includes(cellKey)
|
|
497
|
+
const isFullWidthRow = (rowData: Record<string, unknown>) => fullWidthCellKeys.some((key) => rowData[key])
|
|
455
498
|
|
|
456
|
-
const isRowSelected = (rowIndex) =>
|
|
457
|
-
const
|
|
499
|
+
const isRowSelected = (rowIndex: number) => {
|
|
500
|
+
const row = rawVisibleRows.value[rowIndex] as Record<string, unknown>
|
|
501
|
+
return row?.[RESERVED_KEYS.IS_SELECTED] || false
|
|
502
|
+
}
|
|
503
|
+
const areRowOptionsEnabled = (rowData: Record<string, unknown>) => props.enableRowOptions && !isFullWidthRow(rowData)
|
|
458
504
|
|
|
459
505
|
const resetPagination = () => (pageNumber.value = 0)
|
|
460
506
|
|
|
@@ -679,12 +725,17 @@ defineExpose({ resetPagination })
|
|
|
679
725
|
@media (hover: hover) and (pointer: fine) {
|
|
680
726
|
&__cell--isOptions {
|
|
681
727
|
opacity: 0;
|
|
728
|
+
min-width: fn.px-to-rem(50);
|
|
682
729
|
transition: opacity 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.175);
|
|
683
730
|
}
|
|
684
731
|
|
|
685
732
|
// Actions wrapper on desktop : displayed only if there are quick actions inside
|
|
686
733
|
&__cell--isOptions:has(.cpTable__action) .cpTable__actions {
|
|
687
|
-
|
|
734
|
+
position: absolute;
|
|
735
|
+
top: 50%;
|
|
736
|
+
transform: translateY(-50%);
|
|
737
|
+
right: fn.px-to-rem(12);
|
|
738
|
+
display: inline-flex;
|
|
688
739
|
overflow: hidden;
|
|
689
740
|
border: 1px solid colors.$border-color;
|
|
690
741
|
border-radius: fn.px-to-rem(8);
|
|
@@ -10,15 +10,12 @@
|
|
|
10
10
|
</div>
|
|
11
11
|
</template>
|
|
12
12
|
|
|
13
|
-
<script>
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
placeholder: {
|
|
17
|
-
type: String,
|
|
18
|
-
required: true,
|
|
19
|
-
},
|
|
20
|
-
},
|
|
13
|
+
<script setup lang="ts">
|
|
14
|
+
interface Props {
|
|
15
|
+
placeholder: string
|
|
21
16
|
}
|
|
17
|
+
|
|
18
|
+
defineProps<Props>()
|
|
22
19
|
</script>
|
|
23
20
|
|
|
24
21
|
<style lang="scss">
|
|
@@ -67,96 +67,61 @@
|
|
|
67
67
|
</div>
|
|
68
68
|
</template>
|
|
69
69
|
|
|
70
|
-
<script setup>
|
|
71
|
-
import { ref, computed, onMounted } from 'vue'
|
|
72
|
-
import AutoComplete from 'primevue/autocomplete'
|
|
73
|
-
|
|
70
|
+
<script setup lang="ts">
|
|
74
71
|
import { absolutePosition, getOuterWidth } from '@primeuix/utils/dom'
|
|
72
|
+
import AutoComplete from 'primevue/autocomplete'
|
|
73
|
+
import { ref, computed, onMounted } from 'vue'
|
|
75
74
|
|
|
76
75
|
import BaseInputLabel from '@/components/core/BaseInputLabel.vue'
|
|
77
|
-
import TransitionExpand from '@/components/helpers-utilities/TransitionExpand.vue'
|
|
78
76
|
import BaseSelectClearButton from '@/components/core/BaseSelectClearButton.vue'
|
|
77
|
+
import TransitionExpand from '@/components/helpers-utilities/TransitionExpand.vue'
|
|
79
78
|
|
|
80
79
|
import { isEmpty } from '@/helpers/object'
|
|
81
80
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
default: false,
|
|
117
|
-
},
|
|
118
|
-
disabled: {
|
|
119
|
-
type: Boolean,
|
|
120
|
-
required: false,
|
|
121
|
-
default: false,
|
|
122
|
-
},
|
|
123
|
-
multiple: {
|
|
124
|
-
type: Boolean,
|
|
125
|
-
required: false,
|
|
126
|
-
default: false,
|
|
127
|
-
},
|
|
128
|
-
options: {
|
|
129
|
-
type: Array,
|
|
130
|
-
required: false,
|
|
131
|
-
default: () => [],
|
|
132
|
-
},
|
|
133
|
-
optionLabel: {
|
|
134
|
-
type: String,
|
|
135
|
-
required: false,
|
|
136
|
-
default: 'name',
|
|
137
|
-
},
|
|
138
|
-
trackBy: {
|
|
139
|
-
type: String,
|
|
140
|
-
required: false,
|
|
141
|
-
default: 'id',
|
|
142
|
-
},
|
|
143
|
-
emptyMessage: {
|
|
144
|
-
type: String,
|
|
145
|
-
required: false,
|
|
146
|
-
default: 'No results found',
|
|
147
|
-
},
|
|
148
|
-
errorMessage: {
|
|
149
|
-
type: String,
|
|
150
|
-
required: false,
|
|
151
|
-
default: '',
|
|
152
|
-
},
|
|
153
|
-
modelValue: {
|
|
154
|
-
type: [Array, Object],
|
|
155
|
-
required: false,
|
|
156
|
-
},
|
|
81
|
+
interface Props {
|
|
82
|
+
disabled?: boolean
|
|
83
|
+
emptyMessage?: string
|
|
84
|
+
errorMessage?: string
|
|
85
|
+
isClearable?: boolean
|
|
86
|
+
isInvalid?: boolean
|
|
87
|
+
isLoading?: boolean
|
|
88
|
+
label?: string
|
|
89
|
+
modelValue?: Record<string, unknown>[] | Record<string, unknown> | null
|
|
90
|
+
multiple?: boolean
|
|
91
|
+
name?: string
|
|
92
|
+
optionLabel?: string
|
|
93
|
+
options?: unknown[]
|
|
94
|
+
placeholder?: string
|
|
95
|
+
required?: boolean
|
|
96
|
+
trackBy?: string
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
100
|
+
label: '',
|
|
101
|
+
required: false,
|
|
102
|
+
name: '',
|
|
103
|
+
placeholder: '',
|
|
104
|
+
isInvalid: false,
|
|
105
|
+
isClearable: false,
|
|
106
|
+
isLoading: false,
|
|
107
|
+
disabled: false,
|
|
108
|
+
multiple: false,
|
|
109
|
+
options: () => [],
|
|
110
|
+
optionLabel: 'name',
|
|
111
|
+
trackBy: 'id',
|
|
112
|
+
emptyMessage: 'No results found',
|
|
113
|
+
errorMessage: '',
|
|
114
|
+
modelValue: null,
|
|
157
115
|
})
|
|
158
116
|
|
|
159
|
-
|
|
117
|
+
interface Emits {
|
|
118
|
+
(e: 'search', query: string): void
|
|
119
|
+
(e: 'select', option: Record<string, unknown>): void
|
|
120
|
+
(e: 'clear'): void
|
|
121
|
+
(e: 'update:modelValue', value: Record<string, unknown> | Record<string, unknown>[] | null): void
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const emit = defineEmits<Emits>()
|
|
160
125
|
|
|
161
126
|
const selectModel = computed({
|
|
162
127
|
get() {
|
|
@@ -183,7 +148,7 @@ const passThroughConfig = {
|
|
|
183
148
|
loader: { class: 'cpMultiselect__hidden' },
|
|
184
149
|
}
|
|
185
150
|
|
|
186
|
-
const multiselect = ref(null)
|
|
151
|
+
const multiselect = ref<InstanceType<typeof AutoComplete> | null>(null)
|
|
187
152
|
|
|
188
153
|
const isDropdownOpen = computed(() => multiselect.value?.overlayVisible)
|
|
189
154
|
|
|
@@ -203,29 +168,33 @@ const displayClearButton = computed(() => {
|
|
|
203
168
|
return props.isClearable && !isEmpty(selectModel.value)
|
|
204
169
|
})
|
|
205
170
|
|
|
206
|
-
const handleSearch = (event) => emit('search', event.query)
|
|
171
|
+
const handleSearch = (event: { query: string }) => emit('search', event.query)
|
|
207
172
|
const handleClear = () => (selectModel.value = null)
|
|
208
173
|
|
|
209
174
|
const toggleDropdown = () => {
|
|
210
175
|
if (isDropdownOpen.value) {
|
|
211
|
-
multiselect.value
|
|
176
|
+
multiselect.value?.hide()
|
|
212
177
|
} else {
|
|
213
|
-
multiselect.value
|
|
178
|
+
multiselect.value?.show()
|
|
214
179
|
}
|
|
215
180
|
}
|
|
216
181
|
|
|
217
|
-
const handleUpdateModelValue = (value) => {
|
|
182
|
+
const handleUpdateModelValue = (value: Record<string, unknown> | null) => {
|
|
218
183
|
// Autocomplete will set the model value to the query string if not blocked
|
|
219
184
|
if (!value || typeof value === 'string') {
|
|
220
185
|
return
|
|
221
186
|
}
|
|
222
187
|
}
|
|
223
188
|
|
|
224
|
-
const overrideAlignOverlay = () =>
|
|
189
|
+
const overrideAlignOverlay = () => {
|
|
190
|
+
if (multiselect.value) {
|
|
191
|
+
multiselect.value.alignOverlay = alignOverlay
|
|
192
|
+
}
|
|
193
|
+
}
|
|
225
194
|
|
|
226
195
|
const alignOverlay = () => {
|
|
227
|
-
const target = multiselect.value
|
|
228
|
-
if (!multiselect.value
|
|
196
|
+
const target = multiselect.value?.$el
|
|
197
|
+
if (!multiselect.value?.overlay || !target) return
|
|
229
198
|
|
|
230
199
|
multiselect.value.overlay.style.width = `${getOuterWidth(target)}px`
|
|
231
200
|
|