shared-ritm 1.2.37 → 1.2.38
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/index.css +1 -1
- package/dist/shared-ritm.es.js +7601 -5176
- package/dist/shared-ritm.umd.js +7 -7
- package/dist/types/api/services/ControlsService.d.ts +5 -5
- package/dist/types/api/services/MetricsService.d.ts +2 -0
- package/dist/types/common/app-table/controllers/useTableModel.d.ts +31 -0
- package/dist/types/index.d.ts +8 -1
- package/package.json +1 -1
- package/src/api/services/ControlsService.ts +10 -10
- package/src/api/services/MetricsService.ts +8 -0
- package/src/api/services/RepairsService.ts +100 -100
- package/src/common/app-table/AppTable.vue +188 -0
- package/src/common/app-table/components/TableModal.vue +368 -0
- package/src/common/app-table/components/TablePagination.vue +151 -0
- package/src/common/app-table/components/TableSearch.vue +78 -0
- package/src/common/app-table/controllers/useTableModel.ts +104 -0
- package/src/icons/components/table-filter-icon.vue +30 -0
- package/src/index.ts +11 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import ApiService, { ResponseApi } from '@/api/settings/ApiService';
|
|
2
2
|
import { Api_ControlZones_Dto } from '@/api/types/Api_Controls';
|
|
3
3
|
declare class ControlsService extends ApiService {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
fetchControlZones(params: Record<string, any>): Promise<ResponseApi<Api_ControlZones_Dto[]>>;
|
|
5
|
+
fetchControlZone(id: string): Promise<ResponseApi<Api_ControlZones_Dto>>;
|
|
6
|
+
createControlZone(params: any): Promise<ResponseApi<any>>;
|
|
7
|
+
editControlZone(id: string, params: any): Promise<ResponseApi<any>>;
|
|
8
|
+
deleteControlZone(id: string): Promise<any>;
|
|
9
9
|
}
|
|
10
10
|
export default function useControlsService(): ControlsService;
|
|
11
11
|
export {};
|
|
@@ -23,6 +23,8 @@ declare class MetricsService extends ApiService {
|
|
|
23
23
|
fetchQualityInfo(params: string): Promise<any>;
|
|
24
24
|
fetchPieWorkZone(queryString: string): Promise<ResponseApi<any>>;
|
|
25
25
|
fetchWorkZoneInfo(queryString: string): Promise<ResponseApi<any>>;
|
|
26
|
+
fetchPieAllTasks(queryString: string): Promise<ResponseApi<any>>;
|
|
27
|
+
fetchPieAllTasksInfo(queryString: string): Promise<ResponseApi<any>>;
|
|
26
28
|
}
|
|
27
29
|
export default function useMetricsService(): MetricsService;
|
|
28
30
|
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
export interface TableColumn {
|
|
3
|
+
name: string;
|
|
4
|
+
label: string;
|
|
5
|
+
style?: string;
|
|
6
|
+
headerStyle?: string;
|
|
7
|
+
field: string | ((row: any) => any);
|
|
8
|
+
sortable?: boolean;
|
|
9
|
+
filterType: 'single' | 'multi' | null;
|
|
10
|
+
align?: 'left' | 'center' | 'right';
|
|
11
|
+
}
|
|
12
|
+
export interface FilterOption {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
}
|
|
16
|
+
export interface TableModel<T = any> {
|
|
17
|
+
columns: TableColumn[];
|
|
18
|
+
rows: T[] | Ref<T[]>;
|
|
19
|
+
filtersOptions?: Ref<Record<string, FilterOption[]>>;
|
|
20
|
+
}
|
|
21
|
+
export declare const useTableModel: <T = any>(model: TableModel<T>) => {
|
|
22
|
+
rows: import("vue").ComputedRef<T[]>;
|
|
23
|
+
columns: import("vue").ComputedRef<TableColumn[]>;
|
|
24
|
+
columnFilters: Ref<Record<string, string | string[] | undefined>, Record<string, string | string[] | undefined>>;
|
|
25
|
+
filterMenus: Ref<Record<string, boolean>, Record<string, boolean>>;
|
|
26
|
+
filteredRows: import("vue").ComputedRef<T[]>;
|
|
27
|
+
toggleFilterValue: (colName: string, value: string) => void;
|
|
28
|
+
clearFilter: (colName: string) => void;
|
|
29
|
+
openFilterMenu: (colName: string, isOpen: boolean) => void;
|
|
30
|
+
selectedFilters: import("vue").ComputedRef<Record<string, string[]>>;
|
|
31
|
+
};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -15,6 +15,10 @@ import AppToggle from '@/common/app-toggle/AppToggle.vue';
|
|
|
15
15
|
import AppWrapper from '@/common/app-wrapper/AppWrapper.vue';
|
|
16
16
|
import AppConfirmDialog from '@/common/app-dialogs/AppConfirmDialog.vue';
|
|
17
17
|
import AppDropdown from '@/common/app-dropdown/AppDropdown.vue';
|
|
18
|
+
import AppTablePagination from '@/common/app-table/components/TablePagination.vue';
|
|
19
|
+
import AppTableSearch from '@/common/app-table/components/TableSearch.vue';
|
|
20
|
+
import AppTableModal from '@/common/app-table/components/TableModal.vue';
|
|
21
|
+
import AppTable from '@/common/app-table/AppTable.vue';
|
|
18
22
|
import useGanttService from '@/api/services/GanttService';
|
|
19
23
|
import useMetricsService from '@/api/services/MetricsService';
|
|
20
24
|
import useProjectsService from '@/api/services/ProjectsService';
|
|
@@ -24,10 +28,13 @@ import useAuthService from '@/api/services/AuthService';
|
|
|
24
28
|
import useFileService from '@/api/services/FileService';
|
|
25
29
|
import ApiService from '@/api/settings/ApiService';
|
|
26
30
|
import useControlsService from '@/api/services/ControlsService';
|
|
27
|
-
export { AppButton, AppCheckbox, AppDatePicker, AppInput, AppInputSearch, AppLayout, AppLayoutHeader, AppLayoutPage, AppLoader, AppSelect, AppSheet, AppSidebar, AppToggle, AppWrapper, AppConfirmDialog, AppDropdown, };
|
|
31
|
+
export { AppButton, AppCheckbox, AppDatePicker, AppInput, AppInputSearch, AppLayout, AppLayoutHeader, AppLayoutPage, AppLoader, AppSelect, AppSheet, AppSidebar, AppToggle, AppWrapper, AppConfirmDialog, AppDropdown, AppTablePagination, AppTableSearch, AppTableModal, AppTable, };
|
|
28
32
|
export { ApiService, useAuthService, useGanttService, useMetricsService, useProjectsService, useRepairsService, useTasksService, useFileService, useControlsService, };
|
|
33
|
+
export { useTableModel } from './common/app-table/controllers/useTableModel';
|
|
34
|
+
export type { FilterOption, TableModel, TableColumn } from './common/app-table/controllers/useTableModel';
|
|
29
35
|
export type { NotificationType } from './utils/notification';
|
|
30
36
|
export { notificationSettings } from './utils/notification';
|
|
31
37
|
export * from './api/types/Api_Tasks';
|
|
32
38
|
export * from './api/types/Api_Repairs';
|
|
33
39
|
export * from './api/types/Api_Projects';
|
|
40
|
+
export * from './api/types/Api_Controls';
|
package/package.json
CHANGED
|
@@ -3,24 +3,24 @@ import ApiService, { ResponseApi } from '@/api/settings/ApiService'
|
|
|
3
3
|
import { Api_ControlZones_Dto } from '@/api/types/Api_Controls'
|
|
4
4
|
|
|
5
5
|
class ControlsService extends ApiService {
|
|
6
|
-
public
|
|
7
|
-
return this.get(
|
|
6
|
+
public fetchControlZones(params: Record<string, any>): Promise<ResponseApi<Api_ControlZones_Dto[]>> {
|
|
7
|
+
return this.get('/frame/list', { params })
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
public
|
|
11
|
-
return this.
|
|
10
|
+
public async fetchControlZone(id: string): Promise<ResponseApi<Api_ControlZones_Dto>> {
|
|
11
|
+
return this.get(`/frame/${id}`)
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
public
|
|
15
|
-
return this.
|
|
14
|
+
public createControlZone(params: any): Promise<ResponseApi<any>> {
|
|
15
|
+
return this.post<any, ResponseApi<any>>('/frame', params)
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
public
|
|
19
|
-
return this.
|
|
18
|
+
public editControlZone(id: string, params: any): Promise<ResponseApi<any>> {
|
|
19
|
+
return this.put<any, ResponseApi<any>>(`/frame/${id}`, params)
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
public
|
|
23
|
-
return this.delete<ResponseApi<any>>(`/
|
|
22
|
+
public deleteControlZone(id: string): Promise<any> {
|
|
23
|
+
return this.delete<ResponseApi<any>>(`/frame/${id}`)
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -91,6 +91,14 @@ class MetricsService extends ApiService {
|
|
|
91
91
|
public async fetchWorkZoneInfo(queryString: string): Promise<ResponseApi<any>> {
|
|
92
92
|
return await this.get('repairs/metrics/get_list_work_zone_instrument_by_status' + '?' + queryString)
|
|
93
93
|
}
|
|
94
|
+
|
|
95
|
+
public async fetchPieAllTasks(queryString: string): Promise<ResponseApi<any>> {
|
|
96
|
+
return await this.get('repairs/metrics/get_list_task_group_by_status' + '?' + queryString)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
public async fetchPieAllTasksInfo(queryString: string): Promise<ResponseApi<any>> {
|
|
100
|
+
return await this.get('repairs/metrics/get_list_task_by_status' + '?' + queryString)
|
|
101
|
+
}
|
|
94
102
|
}
|
|
95
103
|
|
|
96
104
|
let api: MetricsService
|
|
@@ -1,100 +1,100 @@
|
|
|
1
|
-
import ApiService, { ResponseApi } from '@/api/settings/ApiService'
|
|
2
|
-
import {
|
|
3
|
-
Api_Create_Repair_With_Equipments,
|
|
4
|
-
Api_Equipment_Full_Dto,
|
|
5
|
-
Api_Repair_Dto,
|
|
6
|
-
Api_Update_Repair,
|
|
7
|
-
OptionFilters,
|
|
8
|
-
} from '@/api/types/Api_Repairs'
|
|
9
|
-
|
|
10
|
-
class RepairsService extends ApiService {
|
|
11
|
-
public fetchFilters(fullParams: string): Promise<OptionFilters> {
|
|
12
|
-
return this.get(`get_list_repair?smart=1&${fullParams}`)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
public fetchRepairs(
|
|
16
|
-
isQuery: boolean,
|
|
17
|
-
queries?: string,
|
|
18
|
-
hasTeams?: boolean | string,
|
|
19
|
-
teamsFilter?: string,
|
|
20
|
-
typeFilter?: string,
|
|
21
|
-
): Promise<ResponseApi<Api_Repair_Dto[]>> {
|
|
22
|
-
return this.get(
|
|
23
|
-
'get_list_repair' +
|
|
24
|
-
(isQuery
|
|
25
|
-
? `${queries}&per_page=100000${typeFilter ? '&' + typeFilter : ''}&${!hasTeams ? teamsFilter : ''}`
|
|
26
|
-
: `?per_page=100000${typeFilter ? '&' + typeFilter : ''}&${teamsFilter}`),
|
|
27
|
-
)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
public fetchEquipment(): Promise<ResponseApi<Api_Equipment_Full_Dto[]>> {
|
|
31
|
-
return this.get('repairs/equipment/list?per_page=100000')
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
public createRepair(payload: Api_Create_Repair_With_Equipments) {
|
|
35
|
-
return this.post<Api_Create_Repair_With_Equipments, any>('/repairs/equipments', payload)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
public startRepair(id: string): Promise<void> {
|
|
39
|
-
return this.post<null, void>(`/repairs/${id}/start`, null)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
public finishRepair(id: string) {
|
|
43
|
-
return this.post<any, void>(`/repairs/complete_repair_list`, {
|
|
44
|
-
repairIdList: [id],
|
|
45
|
-
})
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
public finishPreparationProject(id: string) {
|
|
49
|
-
return this.post<null, void>(`/repairs/${id}/finish_preparation`, null)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
public moveRepairToCurrent(id: string) {
|
|
53
|
-
return this.post<any, void>(`/repairs/transfer_repair_plan_to_current`, {
|
|
54
|
-
repairs: [id],
|
|
55
|
-
})
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
public moveArchiveToCurrent(id: string) {
|
|
59
|
-
return this.post<any, void>(`/repairs/transfer_repair_archive_to_current`, {
|
|
60
|
-
repairs_ids: [id],
|
|
61
|
-
})
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
public moveRepairToApr(id: string) {
|
|
65
|
-
return this.post<any, void>(`/repairs/transfer_repair_current_to_plan`, {
|
|
66
|
-
repairs: [id],
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
public moveRepairToArchive(id: string) {
|
|
71
|
-
return this.post<any, void>(`/repairs/transfer_repair_current_to_archive`, {
|
|
72
|
-
repairs_ids: [id],
|
|
73
|
-
})
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
public restoreRepair(id: string) {
|
|
77
|
-
return this.post<any, void>(`/restore_repair`, {
|
|
78
|
-
repairs_ids: [id],
|
|
79
|
-
})
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
public updateRepair(payload: Api_Update_Repair, id: string) {
|
|
83
|
-
return this.put<Api_Update_Repair, void>(`/repairs/${id}`, payload)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
public copyRepair(id: string) {
|
|
87
|
-
return this.post<null, any>(`/repairs/${id}/clone`, null)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
public deleteRepair(id: string) {
|
|
91
|
-
return this.delete<any>(`/repairs/${id}`)
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
let api: RepairsService
|
|
96
|
-
|
|
97
|
-
export default function useRepairsService() {
|
|
98
|
-
if (!api) api = new RepairsService()
|
|
99
|
-
return api
|
|
100
|
-
}
|
|
1
|
+
import ApiService, { ResponseApi } from '@/api/settings/ApiService'
|
|
2
|
+
import {
|
|
3
|
+
Api_Create_Repair_With_Equipments,
|
|
4
|
+
Api_Equipment_Full_Dto,
|
|
5
|
+
Api_Repair_Dto,
|
|
6
|
+
Api_Update_Repair,
|
|
7
|
+
OptionFilters,
|
|
8
|
+
} from '@/api/types/Api_Repairs'
|
|
9
|
+
|
|
10
|
+
class RepairsService extends ApiService {
|
|
11
|
+
public fetchFilters(fullParams: string): Promise<OptionFilters> {
|
|
12
|
+
return this.get(`get_list_repair?smart=1&${fullParams}`)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public fetchRepairs(
|
|
16
|
+
isQuery: boolean,
|
|
17
|
+
queries?: string,
|
|
18
|
+
hasTeams?: boolean | string,
|
|
19
|
+
teamsFilter?: string,
|
|
20
|
+
typeFilter?: string,
|
|
21
|
+
): Promise<ResponseApi<Api_Repair_Dto[]>> {
|
|
22
|
+
return this.get(
|
|
23
|
+
'get_list_repair' +
|
|
24
|
+
(isQuery
|
|
25
|
+
? `${queries}&per_page=100000${typeFilter ? '&' + typeFilter : ''}&${!hasTeams ? teamsFilter : ''}`
|
|
26
|
+
: `?per_page=100000${typeFilter ? '&' + typeFilter : ''}&${teamsFilter}`),
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public fetchEquipment(): Promise<ResponseApi<Api_Equipment_Full_Dto[]>> {
|
|
31
|
+
return this.get('repairs/equipment/list?per_page=100000')
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public createRepair(payload: Api_Create_Repair_With_Equipments) {
|
|
35
|
+
return this.post<Api_Create_Repair_With_Equipments, any>('/repairs/equipments', payload)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public startRepair(id: string): Promise<void> {
|
|
39
|
+
return this.post<null, void>(`/repairs/${id}/start`, null)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public finishRepair(id: string) {
|
|
43
|
+
return this.post<any, void>(`/repairs/complete_repair_list`, {
|
|
44
|
+
repairIdList: [id],
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public finishPreparationProject(id: string) {
|
|
49
|
+
return this.post<null, void>(`/repairs/${id}/finish_preparation`, null)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public moveRepairToCurrent(id: string) {
|
|
53
|
+
return this.post<any, void>(`/repairs/transfer_repair_plan_to_current`, {
|
|
54
|
+
repairs: [id],
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public moveArchiveToCurrent(id: string) {
|
|
59
|
+
return this.post<any, void>(`/repairs/transfer_repair_archive_to_current`, {
|
|
60
|
+
repairs_ids: [id],
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public moveRepairToApr(id: string) {
|
|
65
|
+
return this.post<any, void>(`/repairs/transfer_repair_current_to_plan`, {
|
|
66
|
+
repairs: [id],
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public moveRepairToArchive(id: string) {
|
|
71
|
+
return this.post<any, void>(`/repairs/transfer_repair_current_to_archive`, {
|
|
72
|
+
repairs_ids: [id],
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public restoreRepair(id: string) {
|
|
77
|
+
return this.post<any, void>(`/restore_repair`, {
|
|
78
|
+
repairs_ids: [id],
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public updateRepair(payload: Api_Update_Repair, id: string) {
|
|
83
|
+
return this.put<Api_Update_Repair, void>(`/repairs/${id}`, payload)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public copyRepair(id: string) {
|
|
87
|
+
return this.post<null, any>(`/repairs/${id}/clone`, null)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public deleteRepair(id: string) {
|
|
91
|
+
return this.delete<any>(`/repairs/${id}`)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
let api: RepairsService
|
|
96
|
+
|
|
97
|
+
export default function useRepairsService() {
|
|
98
|
+
if (!api) api = new RepairsService()
|
|
99
|
+
return api
|
|
100
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { defineProps, defineEmits, ref, computed } from 'vue'
|
|
3
|
+
import type { Ref } from 'vue'
|
|
4
|
+
import FilterIcon from '@/icons/components/table-filter-icon.vue'
|
|
5
|
+
|
|
6
|
+
interface FilterOption {
|
|
7
|
+
id: string
|
|
8
|
+
name: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface TableEmits {
|
|
12
|
+
'toggle-filter-value': [colName: string, value: string]
|
|
13
|
+
'clear-filter': [colName: string]
|
|
14
|
+
'open-filter-menu': [colName: string, isOpen: boolean]
|
|
15
|
+
'row-click': [row: Record<string, any>]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const emit = defineEmits<TableEmits>()
|
|
19
|
+
|
|
20
|
+
const props = defineProps<{
|
|
21
|
+
rows: Ref<any[]>
|
|
22
|
+
columns: any[]
|
|
23
|
+
columnFilters: Ref<Record<string, string | string[] | undefined>>
|
|
24
|
+
filterMenus: Ref<Record<string, boolean>>
|
|
25
|
+
filtersOptions: Record<string, FilterOption[]>
|
|
26
|
+
meta: Ref<{ currentPage: number; perPage: number }>
|
|
27
|
+
}>()
|
|
28
|
+
|
|
29
|
+
const localSearches = ref<Record<string, string>>({})
|
|
30
|
+
|
|
31
|
+
const filteredOptions = computed(() => {
|
|
32
|
+
const result: Record<string, FilterOption[]> = {}
|
|
33
|
+
for (const col of props.columns) {
|
|
34
|
+
const search = localSearches.value[col.name]?.toLowerCase() || ''
|
|
35
|
+
const options = props.filtersOptions[col.name] || []
|
|
36
|
+
result[col.name] = options.filter(opt => opt.name.toLowerCase().includes(search))
|
|
37
|
+
}
|
|
38
|
+
return result
|
|
39
|
+
})
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<template>
|
|
43
|
+
<q-page class="flex flex-col" style="min-height: 100%">
|
|
44
|
+
<q-table
|
|
45
|
+
:rows="rows.value"
|
|
46
|
+
:columns="columns"
|
|
47
|
+
row-key="id"
|
|
48
|
+
flat
|
|
49
|
+
bordered
|
|
50
|
+
hide-bottom
|
|
51
|
+
class="full-width"
|
|
52
|
+
:rows-per-page-options="[0]"
|
|
53
|
+
@row-click="(_, row) => emit('row-click', row)"
|
|
54
|
+
>
|
|
55
|
+
<template #body-cell-index="props">
|
|
56
|
+
<q-td :props="props" class="text-center">
|
|
57
|
+
{{ props.rowIndex + 1 + (meta.value.currentPage - 1) * meta.value.perPage }}
|
|
58
|
+
</q-td>
|
|
59
|
+
</template>
|
|
60
|
+
|
|
61
|
+
<template v-for="col in columns" :key="col.name" #[`header-cell-${col.name}`]="propsSlot">
|
|
62
|
+
<q-th :props="propsSlot" :class="{ 'cursor-pointer': col.filterType }">
|
|
63
|
+
<div
|
|
64
|
+
v-if="col.filterType"
|
|
65
|
+
class="row items-center no-wrap"
|
|
66
|
+
@click.stop="emit('open-filter-menu', col.name, !filterMenus.value[col.name])"
|
|
67
|
+
>
|
|
68
|
+
<filter-icon class="q-mr-xs" />
|
|
69
|
+
<span>{{ col.label }}</span>
|
|
70
|
+
<template v-if="col.filterType === 'multi' && columnFilters.value[col.name]?.length">
|
|
71
|
+
<div class="label-length">- {{ columnFilters.value[col.name]?.length }}</div>
|
|
72
|
+
</template>
|
|
73
|
+
</div>
|
|
74
|
+
<div v-else>{{ col.label }}</div>
|
|
75
|
+
|
|
76
|
+
<q-menu
|
|
77
|
+
v-if="col.filterType"
|
|
78
|
+
:model-value="filterMenus.value[col.name]"
|
|
79
|
+
fit
|
|
80
|
+
max-height="300px"
|
|
81
|
+
class="filter-menu"
|
|
82
|
+
@update:model-value="isOpen => emit('open-filter-menu', col.name, isOpen)"
|
|
83
|
+
>
|
|
84
|
+
<div class="filter-content">
|
|
85
|
+
<q-input v-model="localSearches[col.name]" dense outlined placeholder="Поиск" class="q-mb-sm" clearable />
|
|
86
|
+
<q-scroll-area style="height: 200px">
|
|
87
|
+
<q-list style="min-width: 200px">
|
|
88
|
+
<q-item v-for="option in filteredOptions[col.name]" :key="`${col.name}-${option.id}`" tag="label">
|
|
89
|
+
<q-item-section avatar>
|
|
90
|
+
<q-checkbox
|
|
91
|
+
v-if="col.filterType === 'multi'"
|
|
92
|
+
dense
|
|
93
|
+
:model-value="
|
|
94
|
+
Array.isArray(columnFilters.value[col.name]) &&
|
|
95
|
+
columnFilters.value[col.name]?.includes(option.name)
|
|
96
|
+
"
|
|
97
|
+
@update:model-value="() => emit('toggle-filter-value', col.name, option.name)"
|
|
98
|
+
/>
|
|
99
|
+
<q-radio
|
|
100
|
+
v-else
|
|
101
|
+
dense
|
|
102
|
+
:model-value="columnFilters.value[col.name]"
|
|
103
|
+
:val="option.name"
|
|
104
|
+
@update:model-value="emit('toggle-filter-value', col.name, $event)"
|
|
105
|
+
/>
|
|
106
|
+
</q-item-section>
|
|
107
|
+
<q-item-section>{{ option.name }}</q-item-section>
|
|
108
|
+
</q-item>
|
|
109
|
+
</q-list>
|
|
110
|
+
</q-scroll-area>
|
|
111
|
+
|
|
112
|
+
<div class="filter-footer">
|
|
113
|
+
<q-btn color="negative" flat dense label="Сбросить фильтр" @click="emit('clear-filter', col.name)" />
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
</q-menu>
|
|
117
|
+
</q-th>
|
|
118
|
+
</template>
|
|
119
|
+
</q-table>
|
|
120
|
+
</q-page>
|
|
121
|
+
</template>
|
|
122
|
+
|
|
123
|
+
<style scoped lang="scss">
|
|
124
|
+
.cursor-pointer {
|
|
125
|
+
cursor: pointer;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.filter-menu {
|
|
129
|
+
padding: 10px;
|
|
130
|
+
}
|
|
131
|
+
.label-length {
|
|
132
|
+
margin-left: 5px;
|
|
133
|
+
}
|
|
134
|
+
.filter-content {
|
|
135
|
+
display: flex;
|
|
136
|
+
flex-direction: column;
|
|
137
|
+
color: #1d425d;
|
|
138
|
+
.q-item {
|
|
139
|
+
padding: 0 5px;
|
|
140
|
+
min-height: 40px;
|
|
141
|
+
}
|
|
142
|
+
.q-item__section {
|
|
143
|
+
min-width: 30px;
|
|
144
|
+
padding: 0px;
|
|
145
|
+
}
|
|
146
|
+
::v-deep(.q-radio__inner),
|
|
147
|
+
::v-deep(.q-checkbox__inner) {
|
|
148
|
+
color: #a4b4cf;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.filter-footer {
|
|
153
|
+
border-top: 1px solid #eee;
|
|
154
|
+
display: flex;
|
|
155
|
+
justify-content: center;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
::v-deep(.q-table thead) {
|
|
159
|
+
background: #f2f7fb;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
::v-deep(.q-table th) {
|
|
163
|
+
font-family: NunitoSansFont, sans-serif;
|
|
164
|
+
color: #a4b4cf;
|
|
165
|
+
font-size: 15px;
|
|
166
|
+
font-style: normal;
|
|
167
|
+
font-weight: 700;
|
|
168
|
+
line-height: 20px;
|
|
169
|
+
height: 61px;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
::v-deep(.q-table tbody td) {
|
|
173
|
+
height: 61px;
|
|
174
|
+
font-size: 14px;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
::v-deep(.q-table tbody) {
|
|
178
|
+
font-family: NunitoSansFont, sans-serif;
|
|
179
|
+
border-color: #d7e0ef;
|
|
180
|
+
color: #1d425d;
|
|
181
|
+
line-height: 20px;
|
|
182
|
+
font-size: 14px;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
::v-deep(.q-table tbody tr:last-child td) {
|
|
186
|
+
border-bottom: 1px solid #d7e0ef;
|
|
187
|
+
}
|
|
188
|
+
</style>
|