@mythpe/quasar-ui-qui 0.3.27 → 0.3.29

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mythpe/quasar-ui-qui",
3
- "version": "0.3.27",
3
+ "version": "0.3.29",
4
4
  "description": "MyTh Quasar UI Kit App Extension",
5
5
  "author": {
6
6
  "name": "MyTh Ahmed Faiz",
@@ -60,6 +60,7 @@
60
60
  "core-js": "^3.39.0",
61
61
  "cssnano": "^7.0.6",
62
62
  "eslint": "^8.57.0",
63
+ "@vue/eslint-config-typescript": "^14.4.0",
63
64
  "eslint-config-standard": "^17.0.0",
64
65
  "eslint-plugin-import": "^2.19.1",
65
66
  "eslint-plugin-n": "^15.0.0",
@@ -73,12 +74,12 @@
73
74
  "rollup": "^4.27.4",
74
75
  "rtlcss": "^4.3.0",
75
76
  "sass": "^1.81.0",
76
- "typescript": "~5.5.3",
77
+ "typescript": "^5.9.2",
77
78
  "uglify-js": "^3.19.3",
78
- "vite-plugin-checker": "^0.8.0",
79
+ "vite-plugin-checker": "^0.10.0",
79
80
  "vue": "^3.5.13",
80
81
  "vue-router": "^4.5.0",
81
- "vue-tsc": "^2.1.10",
82
+ "vue-tsc": "^3.0.7",
82
83
  "zlib": "^1.0.5"
83
84
  },
84
85
  "browserslist": [
@@ -22,9 +22,11 @@ import MDtUrlColumn from './MDtUrlColumn.vue'
22
22
  import MDtColorColumn from './MDtColorColumn.vue'
23
23
  import MDtSarColumn from './MDtSarColumn.vue'
24
24
  import MDtCopyColumn from './MDtCopyColumn.vue'
25
+ import { useRouter } from 'vue-router'
25
26
 
26
27
  type Props = {
27
28
  controlKey?: MDatatableProps['controlKey'];
29
+ controlStart?: boolean;
28
30
  defaultItem?: MDatatableProps['defaultItem'];
29
31
  contextItems?: MDatatableProps['contextItems'];
30
32
  contextItemsLength?: MDatatableProps['contextItemsLength'];
@@ -92,23 +94,25 @@ type Props = {
92
94
  help?: MDatatableProps['help'];
93
95
  noWrapBtn?: boolean;
94
96
  lockValue?: MDatatableProps['lockValue'];
97
+ align?: MDatatableProps['align'];
95
98
  }
96
99
 
97
100
  const props = withDefaults(defineProps<Props>(), {
98
101
  rows: undefined,
99
- controlKey: () => 'control',
102
+ controlKey: 'control',
103
+ controlStart: undefined,
100
104
  defaultItem: undefined,
101
105
  contextItems: undefined,
102
106
  contextItemsLength: 4,
103
107
  hideAutoMessage: undefined,
104
108
  headers: () => ([]),
105
- serviceName: () => '',
109
+ serviceName: '',
106
110
  requestParams: undefined,
107
111
  pdf: undefined,
108
112
  excel: undefined,
109
113
  exportUrl: undefined,
110
114
  hideSearch: !1,
111
- searchDebounce: () => 600,
115
+ searchDebounce: 600,
112
116
  withIndex: undefined,
113
117
  withStore: undefined,
114
118
  withShow: undefined,
@@ -162,7 +166,8 @@ const props = withDefaults(defineProps<Props>(), {
162
166
  descColumns: undefined,
163
167
  help: undefined,
164
168
  noWrapBtn: undefined,
165
- lockValue: undefined
169
+ lockValue: undefined,
170
+ align: 'left'
166
171
  })
167
172
 
168
173
  interface Emits {
@@ -184,6 +189,7 @@ const {
184
189
  } = useMyth()
185
190
 
186
191
  const $q = useQuasar()
192
+ const $router = useRouter()
187
193
  const { te } = useI18n({ useScope: 'global' })
188
194
  const useFormContext = useForm<any, any>()
189
195
  const { resetForm: resetDialogForm, handleSubmit } = useFormContext
@@ -652,12 +658,14 @@ defineExpose({
652
658
  <template v-else-if="computedColorColumns.indexOf(col.name) !== -1">
653
659
  <MDtColorColumn
654
660
  v-if="col.value !== undefined && col.value !== null"
661
+ :align="col.align as any"
655
662
  :value="col.value"
656
663
  />
657
664
  </template>
658
665
  <template v-else-if="computedSarColumns.indexOf(col.name) !== -1">
659
666
  <MDtSarColumn
660
667
  v-if="col.value !== undefined && col.value !== null"
668
+ :align="col.align as any"
661
669
  :copy="computedCopyColumns.includes(col.name)"
662
670
  :copy-value="col.copyValue && typeof col.copyValue === 'function' ? col.copyValue(iTempProps.row) : iTempProps.row[col.copyValue || col.field]"
663
671
  :value="col.value"
@@ -666,12 +674,16 @@ defineExpose({
666
674
  <template v-else-if="computedCopyColumns.indexOf(col.name) !== -1">
667
675
  <MDtCopyColumn
668
676
  v-if="col.value !== undefined && col.value !== null"
677
+ :align="col.align as any || undefined"
669
678
  :label="col.value"
670
679
  :value="col.copyValue && typeof col.copyValue === 'function' ? col.copyValue(iTempProps.row) : iTempProps.row[col.copyValue || col.field]"
671
680
  />
672
681
  </template>
673
682
  <template v-else-if="computedDescColumns.indexOf(col.name) !== -1">
674
- <MDtDescColumn :value="col.value" />
683
+ <MDtDescColumn
684
+ :align="col.align as any || undefined"
685
+ :value="col.value"
686
+ />
675
687
  </template>
676
688
  <template v-else-if="col.name === controlKey">
677
689
  <MRow
@@ -916,249 +928,264 @@ defineExpose({
916
928
  />
917
929
  </MRow>
918
930
  <!--Buttons-->
919
- <MRow class="q-gutter-x-sm q-gutter-xs-y-sm items-center">
920
- <!-- Export PDF-->
921
- <MDtBtn
922
- v-if="pdf && getRows.length > 0"
923
- :disable="loading"
924
- icon="fa-solid fa-file-pdf"
925
- v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.buttons?.filter as any, textColor: 'red'}"
926
- @click="exportData('pdf')"
927
- >
928
- <q-tooltip class="m-dt-btn-tooltip">
929
- {{ __('myth.titles.exportPdf') }}
930
- </q-tooltip>
931
- </MDtBtn>
932
- <!-- Export Excel-->
933
- <MDtBtn
934
- v-if="excel && getRows.length > 0"
935
- icon="fa-solid fa-file-excel"
936
- :disable="loading"
937
- v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.buttons?.filter as any, textColor: 'green'}"
938
- @click="exportData('excel')"
939
- >
940
- <q-tooltip class="m-dt-btn-tooltip">
941
- {{ __('myth.titles.exportExcel') }}
942
- </q-tooltip>
943
- </MDtBtn>
944
- <!-- Filter dialog -->
945
- <MDtBtn
946
- v-if="hasFilterDialog"
947
- key="filter-selection-btn"
948
- color="brand"
949
- icon="ion-ios-options"
950
- label="myth.datatable.hints.filter"
951
- text-color="on-brand"
952
- :disable="loading"
953
- v-bind="{...pluginOptions.dt?.buttons?.filter as any}"
954
- >
955
- <MModalMenu
956
- v-model="filterDialogModel"
957
- :offset="[10,10]"
958
- no-close-btn
959
- persistent
960
- position="top"
961
- v-bind="pluginOptions.dt?.filterDialogProps as any"
962
- @before-show="beforeCloseFilterDialog"
931
+ <MRow
932
+ class="items-center justify-between"
933
+ gutter="xs"
934
+ >
935
+ <MCol auto>
936
+ <MRow
937
+ class="items-center"
938
+ gutter="xs"
963
939
  >
964
- <q-card
965
- :style="$q.screen.gt.sm?`width: ${Math.ceil($q.screen.width/2)}px` : undefined"
966
- flat
967
- square
940
+ <!-- Export PDF-->
941
+ <MDtBtn
942
+ v-if="pdf && getRows.length > 0"
943
+ :disable="loading"
944
+ icon="fa-solid fa-file-pdf"
945
+ v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.buttons?.filter as any, textColor: 'red'}"
946
+ @click="exportData('pdf')"
968
947
  >
969
- <MContainer class="q-pa-lg">
970
- <q-toolbar :class="{'q-pa-none': isSmall}">
971
- <q-toolbar-title>
972
- {{ __('myth.datatable.filter.title') }}
973
- </q-toolbar-title>
974
- </q-toolbar>
975
- <q-separator />
976
- <MRow class="items-center">
977
- <MCol col="12">
978
- <MContainer>
979
- <slot
980
- :dt="datatableItemsScope"
981
- :filter="tempFilterForm"
982
- :form="useFormContext"
983
- :index="dialogItemIndex"
984
- :item="dialogItem"
985
- name="filter"
986
- />
987
- </MContainer>
988
- </MCol>
989
- <MCol
990
- class="q-pt-lg"
991
- col="12"
992
- >
993
- <MRow class="justify-between">
994
- <MBtn
995
- v-close-popup
996
- :label="__('myth.datatable.filter.save')"
997
- style="min-width: 110px"
998
- v-bind="pluginOptions.dt?.dialogButtonsProps as any"
999
- @click="saveFilterDialog"
1000
- />
1001
- <MBtn
1002
- v-close-popup
1003
- :label="__('myth.datatable.filter.cancel')"
1004
- style="min-width: 100px"
1005
- v-bind="pluginOptions.dt?.dialogButtonsProps as any"
1006
- @click="closeFilterDialog"
1007
- />
948
+ <q-tooltip class="m-dt-btn-tooltip">
949
+ {{ __('myth.titles.exportPdf') }}
950
+ </q-tooltip>
951
+ </MDtBtn>
952
+ <!-- Export Excel-->
953
+ <MDtBtn
954
+ v-if="excel && getRows.length > 0"
955
+ :disable="loading"
956
+ icon="fa-solid fa-file-excel"
957
+ v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.buttons?.filter as any, textColor: 'green'}"
958
+ @click="exportData('excel')"
959
+ >
960
+ <q-tooltip class="m-dt-btn-tooltip">
961
+ {{ __('myth.titles.exportExcel') }}
962
+ </q-tooltip>
963
+ </MDtBtn>
964
+ <!-- Filter dialog -->
965
+ <MDtBtn
966
+ v-if="hasFilterDialog"
967
+ key="filter-selection-btn"
968
+ :disable="loading"
969
+ color="brand"
970
+ icon="ion-ios-options"
971
+ label="myth.datatable.hints.filter"
972
+ text-color="on-brand"
973
+ v-bind="{...pluginOptions.dt?.buttons?.filter as any}"
974
+ >
975
+ <MModalMenu
976
+ v-model="filterDialogModel"
977
+ :offset="[10,10]"
978
+ no-close-btn
979
+ persistent
980
+ position="top"
981
+ v-bind="pluginOptions.dt?.filterDialogProps as any"
982
+ @before-show="beforeCloseFilterDialog"
983
+ >
984
+ <q-card
985
+ :style="$q.screen.gt.sm?`width: ${Math.ceil($q.screen.width/2)}px` : undefined"
986
+ flat
987
+ square
988
+ >
989
+ <MContainer class="q-pa-lg">
990
+ <q-toolbar :class="{'q-pa-none': isSmall}">
991
+ <q-toolbar-title>
992
+ {{ __('myth.datatable.filter.title') }}
993
+ </q-toolbar-title>
994
+ </q-toolbar>
995
+ <q-separator />
996
+ <MRow class="items-center">
997
+ <MCol col="12">
998
+ <MContainer>
999
+ <slot
1000
+ :dt="datatableItemsScope"
1001
+ :filter="tempFilterForm"
1002
+ :form="useFormContext"
1003
+ :index="dialogItemIndex"
1004
+ :item="dialogItem"
1005
+ name="filter"
1006
+ />
1007
+ </MContainer>
1008
+ </MCol>
1009
+ <MCol
1010
+ class="q-pt-lg"
1011
+ col="12"
1012
+ >
1013
+ <MRow class="justify-between">
1014
+ <MBtn
1015
+ v-close-popup
1016
+ :label="__('myth.datatable.filter.save')"
1017
+ style="min-width: 110px"
1018
+ v-bind="pluginOptions.dt?.dialogButtonsProps as any"
1019
+ @click="saveFilterDialog"
1020
+ />
1021
+ <MBtn
1022
+ v-close-popup
1023
+ :label="__('myth.datatable.filter.cancel')"
1024
+ style="min-width: 100px"
1025
+ v-bind="pluginOptions.dt?.dialogButtonsProps as any"
1026
+ @click="closeFilterDialog"
1027
+ />
1028
+ </MRow>
1029
+ </MCol>
1008
1030
  </MRow>
1009
- </MCol>
1010
- </MRow>
1011
- </MContainer>
1012
- </q-card>
1013
- </MModalMenu>
1014
- </MDtBtn>
1015
- <!--Refresh-->
1016
- <MDtBtn
1017
- v-if="!noRefreshBtn"
1018
- key="refresh-selection-btn"
1019
- :disable="loading"
1020
- icon="ion-ios-refresh"
1021
- tooltip="myth.datatable.hints.refresh"
1022
- v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.buttons?.refresh as any}"
1023
- @click="refreshNoUpdate()"
1024
- />
1025
- <!--Fullscreen-->
1026
- <MDtBtn
1027
- v-if="fullscreenBtn === undefined ? ( !!pluginOptions.datatable?.fullscreenBtn) : fullscreenBtn"
1028
- key="fullscreen-selection-btn"
1029
- :disable="loading"
1030
- :icon="fullscreen ? 'ion-ios-contract' : 'ion-ios-desktop'"
1031
- :tooltip="`myth.datatable.${fullscreen ? 'exitFullscreen' : 'fullscreen'}`"
1032
- v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.buttons?.fullscreen as any}"
1033
- @click="fullscreen = !fullscreen"
1034
- />
1035
- <template v-if="hasSelectedItem">
1036
- <MDtBtn
1037
- v-if="hasUpdateBtn && isSingleSelectedItem"
1038
- key="update-dt-selection-btn"
1039
- :disable="loading"
1040
- icon="ion-ios-create"
1041
- update
1042
- v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.topSelection?.btn as any}"
1043
- @click="openUpdateDialogNoIndex(selected[0] as any)"
1044
- />
1045
- <MDtBtn
1046
- v-if="hasCloneBtn && isSingleSelectedItem"
1047
- key="clone-dt-selection-btn"
1048
- :disable="loading"
1049
- clone
1050
- tooltip="labels.clone"
1051
- v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.topSelection?.btn as any}"
1052
- @click="onCloneItem(selected[0] as any)"
1053
- />
1054
- <MDtBtn
1055
- v-if="hasShowBtn && isSingleSelectedItem"
1056
- key="show-dt-selection-btn"
1057
- :disable="loading"
1058
- icon="ion-ios-eye"
1059
- show
1060
- v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.topSelection?.btn as any}"
1061
- @click="openShowDialogNoIndex(selected[0] as any)"
1062
- />
1063
- <MDtBtn
1064
- v-if="selected.length > 1 ? (hasDestroyBtn && multiDestroy) : hasDestroyBtn"
1065
- key="destroy-dt-selection-btn"
1066
- :disable="!hasSelectedItem || loading"
1067
- color="negative"
1068
- destroy
1069
- icon="ion-ios-trash"
1070
- v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.topSelection?.btn as any}"
1071
- @click="deleteSelectionItem()"
1072
- />
1073
- <template
1074
- v-for="(contextBtn,i) in contextItems as GenericMDtBtn[]"
1075
- :key="`top-s-${i}`"
1076
- >
1031
+ </MContainer>
1032
+ </q-card>
1033
+ </MModalMenu>
1034
+ </MDtBtn>
1035
+ <!--Refresh-->
1077
1036
  <MDtBtn
1078
- v-if="(typeof contextBtn.showIf === 'function' ? contextBtn.showIf(selected[0],0) : contextBtn.showIf !==!1) && ( (contextBtn.click && isSingleSelectedItem)
1079
- || (contextBtn.multiClick && !isSingleSelectedItem) )"
1080
- :tooltip="contextBtn.tooltip?__(contextBtn.tooltip):(contextBtn.label?(te(`labels.${contextBtn.label}`) ?
1081
- __(`labels.${contextBtn.label}`) : __(contextBtn.label) ):undefined)"
1082
- v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.topSelection?.btn as any,...contextBtn as any,...contextBtn.attr as any}"
1083
- @click="onClickTopMenu(contextBtn)"
1037
+ v-if="!noRefreshBtn"
1038
+ key="refresh-selection-btn"
1039
+ :disable="loading"
1040
+ icon="ion-ios-refresh"
1041
+ tooltip="myth.datatable.hints.refresh"
1042
+ v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.buttons?.refresh as any}"
1043
+ @click="refreshNoUpdate()"
1084
1044
  />
1085
- </template>
1086
- </template>
1087
-
1088
- <q-space />
1089
- <!-- Manage Columns -->
1090
- <MDtBtn
1091
- v-if="manageColumns"
1092
- key="manage-columns-btn"
1093
- :disable="loading"
1094
- color="brand"
1095
- icon="ion-ios-desktop"
1096
- label="myth.datatable.columnsToShow"
1097
- text-color="on-brand"
1098
- tooltip="myth.datatable.columnsToShowCaption"
1099
- v-bind="pluginOptions.dt?.buttons?.filter as any"
1100
- >
1101
- <MModalMenu
1102
- :no-close-btn="$q.screen.gt.xs"
1103
- :offset="[10,10]"
1104
- >
1105
- <q-card style="min-width: 250px; max-width: 900px">
1106
- <q-card-section>
1107
- <div class="text-body1 q-mb-md">
1108
- {{ __('myth.datatable.columnsToShow') }}
1109
- </div>
1110
- <div class="text-body2">
1111
- <q-icon name="ion-ios-information-circle-outline" />
1112
- {{ __('myth.datatable.columnsToShowCaption') }}
1113
- </div>
1114
- </q-card-section>
1115
- <q-card-section>
1116
- <template
1117
- v-for="h in getHeaders"
1118
- :key="h.name"
1119
- >
1120
- <q-checkbox
1121
- v-model="visibleHeaders"
1122
- :disable="visibleHeaders.length < 2 && visibleHeaders.indexOf(h.name) !== -1"
1123
- :label="h.label"
1124
- :val="h.name"
1125
- />
1126
- </template>
1127
- </q-card-section>
1128
- <q-card-section>
1129
- <MBtn
1130
- v-if="$q.screen.gt.xs"
1131
- v-close-popup
1132
- :class="{'q-mr-sm': !$q.screen.xs}"
1133
- color="brand"
1134
- label="labels.close"
1135
- no-caps
1136
- style="min-width: 100px"
1137
- text-color="on-brand"
1138
- unelevated
1139
- />
1140
- <MBtn
1141
- :class="{'full-width': $q.screen.xs}"
1142
- :label="__(`labels.${visibleHeaders.length === getHeaders.length ? 'unselect':'select'}_all`)"
1143
- color="brand"
1144
- no-caps
1145
- style="min-width: 100px"
1146
- text-color="on-brand"
1147
- unelevated
1148
- @click="onManageColumnsClick()"
1045
+ <!--Fullscreen-->
1046
+ <MDtBtn
1047
+ v-if="fullscreenBtn === undefined ? ( !!pluginOptions.datatable?.fullscreenBtn) : fullscreenBtn"
1048
+ key="fullscreen-selection-btn"
1049
+ :disable="loading"
1050
+ :icon="fullscreen ? 'ion-ios-contract' : 'ion-ios-desktop'"
1051
+ :tooltip="`myth.datatable.${fullscreen ? 'exitFullscreen' : 'fullscreen'}`"
1052
+ v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.buttons?.fullscreen as any}"
1053
+ @click="fullscreen = !fullscreen"
1054
+ />
1055
+ <template v-if="hasSelectedItem">
1056
+ <MDtBtn
1057
+ v-if="hasUpdateBtn && isSingleSelectedItem"
1058
+ key="update-dt-selection-btn"
1059
+ :disable="loading"
1060
+ icon="ion-ios-create"
1061
+ update
1062
+ v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.topSelection?.btn as any}"
1063
+ @click="openUpdateDialogNoIndex(selected[0] as any)"
1064
+ />
1065
+ <MDtBtn
1066
+ v-if="hasCloneBtn && isSingleSelectedItem"
1067
+ key="clone-dt-selection-btn"
1068
+ :disable="loading"
1069
+ clone
1070
+ tooltip="labels.clone"
1071
+ v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.topSelection?.btn as any}"
1072
+ @click="onCloneItem(selected[0] as any)"
1073
+ />
1074
+ <MDtBtn
1075
+ v-if="hasShowBtn && isSingleSelectedItem"
1076
+ key="show-dt-selection-btn"
1077
+ :disable="loading"
1078
+ icon="ion-ios-eye"
1079
+ show
1080
+ v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.topSelection?.btn as any}"
1081
+ @click="openShowDialogNoIndex(selected[0] as any)"
1082
+ />
1083
+ <MDtBtn
1084
+ v-if="selected.length > 1 ? (hasDestroyBtn && multiDestroy) : hasDestroyBtn"
1085
+ key="destroy-dt-selection-btn"
1086
+ :disable="!hasSelectedItem || loading"
1087
+ color="negative"
1088
+ destroy
1089
+ icon="ion-ios-trash"
1090
+ v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.topSelection?.btn as any}"
1091
+ @click="deleteSelectionItem()"
1092
+ />
1093
+ <template
1094
+ v-for="(contextBtn,i) in contextItems as GenericMDtBtn[]"
1095
+ :key="`top-s-${i}`"
1096
+ >
1097
+ <MDtBtn
1098
+ v-if="(typeof contextBtn.showIf === 'function' ? contextBtn.showIf(selected[0],0) : contextBtn.showIf !==!1) && ( (contextBtn.click && isSingleSelectedItem)
1099
+ || (contextBtn.multiClick && !isSingleSelectedItem) )"
1100
+ :tooltip="contextBtn.tooltip?__(contextBtn.tooltip):(contextBtn.label?(te(`labels.${contextBtn.label}`) ?
1101
+ __(`labels.${contextBtn.label}`) : __(contextBtn.label) ):undefined)"
1102
+ v-bind="{...defaultTopBtnProps,...pluginOptions.dt?.topSelection?.btn as any,...contextBtn as any,...contextBtn.attr as any}"
1103
+ @click="onClickTopMenu(contextBtn)"
1149
1104
  />
1150
- </q-card-section>
1151
- </q-card>
1152
- </MModalMenu>
1153
- </MDtBtn>
1154
- <!-- Wrap Btn -->
1155
- <MDtBtn
1156
- v-if="!computedNoWrapBtn"
1157
- :icon="`ion-ios-${!wrapCellsRef ? 'grid' : 'list'}`"
1158
- flat
1159
- tooltip="myth.datatable.wrapBtn"
1160
- @click="wrapCellsRef = !wrapCellsRef"
1161
- />
1105
+ </template>
1106
+ </template>
1107
+ </MRow>
1108
+ </MCol>
1109
+ <MCol auto>
1110
+ <MRow
1111
+ class="items-center"
1112
+ gutter="xs"
1113
+ >
1114
+ <!-- Manage Columns -->
1115
+ <MDtBtn
1116
+ v-if="manageColumns"
1117
+ key="manage-columns-btn"
1118
+ :disable="loading"
1119
+ color="brand"
1120
+ icon="ion-ios-desktop"
1121
+ label="myth.datatable.columnsToShow"
1122
+ text-color="on-brand"
1123
+ tooltip="myth.datatable.columnsToShowCaption"
1124
+ v-bind="pluginOptions.dt?.buttons?.filter as any"
1125
+ >
1126
+ <MModalMenu
1127
+ :no-close-btn="$q.screen.gt.xs"
1128
+ :offset="[10,10]"
1129
+ >
1130
+ <q-card style="min-width: 250px; max-width: 900px">
1131
+ <q-card-section>
1132
+ <div class="text-body1 q-mb-md">
1133
+ {{ __('myth.datatable.columnsToShow') }}
1134
+ </div>
1135
+ <div class="text-body2">
1136
+ <q-icon name="ion-ios-information-circle-outline" />
1137
+ {{ __('myth.datatable.columnsToShowCaption') }}
1138
+ </div>
1139
+ </q-card-section>
1140
+ <q-card-section>
1141
+ <template
1142
+ v-for="h in getHeaders"
1143
+ :key="h.name"
1144
+ >
1145
+ <q-checkbox
1146
+ v-model="visibleHeaders"
1147
+ :disable="visibleHeaders.length < 2 && visibleHeaders.indexOf(h.name) !== -1"
1148
+ :label="h.label"
1149
+ :val="h.name"
1150
+ />
1151
+ </template>
1152
+ </q-card-section>
1153
+ <q-card-section>
1154
+ <MBtn
1155
+ v-if="$q.screen.gt.xs"
1156
+ v-close-popup
1157
+ :class="{'q-mr-sm': !$q.screen.xs}"
1158
+ color="brand"
1159
+ label="labels.close"
1160
+ no-caps
1161
+ style="min-width: 100px"
1162
+ text-color="on-brand"
1163
+ unelevated
1164
+ />
1165
+ <MBtn
1166
+ :class="{'full-width': $q.screen.xs}"
1167
+ :label="__(`labels.${visibleHeaders.length === getHeaders.length ? 'unselect':'select'}_all`)"
1168
+ color="brand"
1169
+ no-caps
1170
+ style="min-width: 100px"
1171
+ text-color="on-brand"
1172
+ unelevated
1173
+ @click="onManageColumnsClick()"
1174
+ />
1175
+ </q-card-section>
1176
+ </q-card>
1177
+ </MModalMenu>
1178
+ </MDtBtn>
1179
+ <!-- Wrap Btn -->
1180
+ <MDtBtn
1181
+ v-if="!computedNoWrapBtn"
1182
+ :icon="`ion-ios-${!wrapCellsRef ? 'grid' : 'list'}`"
1183
+ flat
1184
+ tooltip="myth.datatable.wrapBtn"
1185
+ @click="wrapCellsRef = !wrapCellsRef"
1186
+ />
1187
+ </MRow>
1188
+ </MCol>
1162
1189
  </MRow>
1163
1190
 
1164
1191
  <!-- Manage Columns -->
@@ -1302,19 +1329,19 @@ defineExpose({
1302
1329
  />
1303
1330
  </q-list>
1304
1331
  </q-btn-dropdown>
1305
- <MRow
1306
- v-else
1307
- class="m-dt-context_menu_items justify-end"
1308
- gutter
1309
- space="xs"
1310
- >
1311
- <!--Control-->
1312
- <MDtContextmenuItems
1313
- :index="noBodyProps.rowIndex"
1314
- :item="noBodyProps.row"
1315
- :items="contextmenuItems"
1316
- />
1317
- </MRow>
1332
+ <div v-else>
1333
+ <MRow
1334
+ :class="['m-dt-context_menu_items ',{'justify-end': !controlStart}]"
1335
+ gutter="xs"
1336
+ >
1337
+ <!--Control-->
1338
+ <MDtContextmenuItems
1339
+ :index="noBodyProps.rowIndex"
1340
+ :item="noBodyProps.row"
1341
+ :items="contextmenuItems"
1342
+ />
1343
+ </MRow>
1344
+ </div>
1318
1345
  </q-td>
1319
1346
  </slot>
1320
1347
  </template>
@@ -1354,6 +1381,7 @@ defineExpose({
1354
1381
  <q-td :props="ccProps">
1355
1382
  <MDtColorColumn
1356
1383
  v-if="ccProps.row[ccProps.col.field] !== undefined && ccProps.row[ccProps.col.field] !== null"
1384
+ :align="ccProps.col.align as any"
1357
1385
  :value="ccProps.row[ccProps.col.field]"
1358
1386
  />
1359
1387
  </q-td>
@@ -1366,6 +1394,7 @@ defineExpose({
1366
1394
  <q-td :props="sarCellProps">
1367
1395
  <MDtSarColumn
1368
1396
  v-if="sarCellProps.row[sarCellProps.col.field] !== undefined && sarCellProps.row[sarCellProps.col.field] !== null"
1397
+ :align="sarCellProps.col.align as any"
1369
1398
  :copy="computedCopyColumns.includes(sarCellProps.col.name)"
1370
1399
  :copy-value="sarCellProps.col.copyValue && typeof sarCellProps.col.copyValue === 'function' ? sarCellProps.col.copyValue(sarCellProps.row) : sarCellProps.row[sarCellProps.col.copyValue || sarCellProps.col.field]"
1371
1400
  :value="sarCellProps.row[sarCellProps.col.field]"
@@ -1379,6 +1408,7 @@ defineExpose({
1379
1408
  >
1380
1409
  <q-td :props="copyCellProps">
1381
1410
  <MDtCopyColumn
1411
+ :align="copyCellProps.col.align as any || undefined"
1382
1412
  :label="copyCellProps.col.copyLabel && typeof copyCellProps.col.copyLabel === 'function' ? copyCellProps.col.copyLabel(copyCellProps.row) : copyCellProps.row[copyCellProps.col.copyLabel || copyCellProps.col.field]"
1383
1413
  :value="copyCellProps.col.copyValue && typeof copyCellProps.col.copyValue === 'function' ? copyCellProps.col.copyValue(copyCellProps.row) : copyCellProps.row[copyCellProps.col.copyValue || copyCellProps.col.field]"
1384
1414
  />
@@ -1392,6 +1422,7 @@ defineExpose({
1392
1422
  <q-td :props="descColumnProps">
1393
1423
  <MDtDescColumn
1394
1424
  v-if="descColumnProps.row[descColumnProps.col.field] !== undefined && descColumnProps.row[descColumnProps.col.field] !== null"
1425
+ :align="descColumnProps.col.align as any || undefined"
1395
1426
  :value="descColumnProps.row[descColumnProps.col.field]"
1396
1427
  />
1397
1428
  </q-td>
@@ -10,14 +10,22 @@
10
10
 
11
11
  import { useMyth } from '../../composable'
12
12
  import type { MDtColorColumnProps } from '../../types'
13
+ import { computed } from 'vue'
13
14
 
14
15
  interface Props {
15
16
  value?: MDtColorColumnProps['value'];
16
17
  size?: MDtColorColumnProps['size'];
18
+ align?: MDtColorColumnProps['align'];
17
19
  }
18
20
 
19
- defineProps<Props>()
21
+ const props = defineProps<Props>()
20
22
  const { __, copyText } = useMyth()
23
+ const map = {
24
+ left: 'start',
25
+ center: 'center',
26
+ right: 'end'
27
+ }
28
+ const getAlign = computed(() => props.align ? map[props.align] || undefined : undefined)
21
29
  defineOptions({
22
30
  name: 'MDtColorColumn',
23
31
  inheritAttrs: !1
@@ -25,8 +33,9 @@ defineOptions({
25
33
  </script>
26
34
 
27
35
  <template>
28
- <div
29
- class="row q-gutter-lg justify-center items-center"
36
+ <MRow
37
+ :class="`items-center justify-${getAlign}`"
38
+ gutter="xs"
30
39
  v-bind="$attrs"
31
40
  >
32
41
  <div>
@@ -42,5 +51,5 @@ defineOptions({
42
51
  </q-tooltip>
43
52
  </div>
44
53
  <slot />
45
- </div>
54
+ </MRow>
46
55
  </template>
@@ -11,16 +11,24 @@
11
11
  import { useMyth } from '../../composable'
12
12
  import type { MDtCopyColumnProps } from '../../types'
13
13
  import MDtSarColumn from './MDtSarColumn.vue'
14
+ import { computed } from 'vue'
14
15
 
15
16
  interface Props {
16
17
  label?: MDtCopyColumnProps['label'];
17
18
  value?: MDtCopyColumnProps['value'];
18
19
  width?: MDtCopyColumnProps['width'];
19
20
  sar?: MDtCopyColumnProps['sar'];
21
+ align?: MDtCopyColumnProps['align'];
20
22
  }
21
23
 
22
- defineProps<Props>()
24
+ const props = defineProps<Props>()
23
25
  const { copyText } = useMyth()
26
+ const map = {
27
+ left: 'start',
28
+ center: 'center',
29
+ right: 'end'
30
+ }
31
+ const getAlign = computed(() => props.align ? map[props.align] || undefined : undefined)
24
32
  defineOptions({
25
33
  name: 'MDtCopyColumn',
26
34
  inheritAttrs: !1
@@ -30,7 +38,7 @@ defineOptions({
30
38
  <template>
31
39
  <MRow
32
40
  v-if="!!value"
33
- class="items-center justify-center"
41
+ :class="`items-center justify-${getAlign}`"
34
42
  v-bind="$attrs"
35
43
  >
36
44
  <div
@@ -10,15 +10,21 @@
10
10
 
11
11
  import type { MDtDescColumnProps } from '../../types'
12
12
  import { useMyth } from '../../composable'
13
+ import { computed } from 'vue'
13
14
 
14
15
  interface Props {
15
16
  value?: MDtDescColumnProps['value'];
17
+ align?: MDtDescColumnProps['align'];
16
18
  }
17
19
 
18
- defineProps<Props>()
19
-
20
- const { __, copyText } = useMyth()
21
-
20
+ const props = defineProps<Props>()
21
+ const { copyText } = useMyth()
22
+ const map = {
23
+ left: 'start',
24
+ center: 'center',
25
+ right: 'end'
26
+ }
27
+ const getAlign = computed(() => props.align ? map[props.align] || undefined : undefined)
22
28
  defineOptions({
23
29
  name: 'MDtDescColumn',
24
30
  inheritAttrs: !1
@@ -26,8 +32,9 @@ defineOptions({
26
32
  </script>
27
33
 
28
34
  <template>
29
- <div
30
- class="row q-gutter-md items-center justify-center"
35
+ <MRow
36
+ :class="`items-center justify-${getAlign}`"
37
+ gutter="xs"
31
38
  v-bind="$attrs"
32
39
  >
33
40
  <div class="m-dt__max_desc">
@@ -49,5 +56,5 @@ defineOptions({
49
56
  </q-tooltip>
50
57
  </div>
51
58
  <slot />
52
- </div>
59
+ </MRow>
53
60
  </template>
@@ -73,7 +73,3 @@ defineOptions({
73
73
  </q-avatar>
74
74
  </template>
75
75
  </template>
76
-
77
- <style lang="sass" scoped>
78
-
79
- </style>
@@ -17,12 +17,19 @@ interface Props {
17
17
  value?: MDtSarColumnProps['value'];
18
18
  copyValue?: MDtSarColumnProps['copyValue'];
19
19
  copy?: boolean;
20
+ align?: MDtSarColumnProps['align'];
20
21
  }
21
22
 
22
23
  const props = defineProps<Props>()
23
24
  const { __, copyText } = useMyth()
24
25
  const val = computed(() => props.value || '0.00')
25
26
  const inputValue = computed(() => (props.copyValue || props.value) || '0.00')
27
+ const map = {
28
+ left: 'start',
29
+ center: 'center',
30
+ right: 'end'
31
+ }
32
+ const getAlign = computed(() => props.align ? map[props.align] || undefined : undefined)
26
33
  defineOptions({
27
34
  name: 'MDtSarColumn',
28
35
  inheritAttrs: !1
@@ -30,17 +37,17 @@ defineOptions({
30
37
  </script>
31
38
 
32
39
  <template>
33
- <div
34
- class="row justify-center items-center"
40
+ <MRow
41
+ :class="`items-center justify-${getAlign}`"
35
42
  v-bind="$attrs"
36
43
  >
37
44
  <q-btn
38
45
  v-if="!!copy && !!inputValue"
46
+ class="q-mr-xs"
39
47
  dense
40
48
  flat
41
49
  icon="ion-copy"
42
50
  round
43
- class="q-mr-xs"
44
51
  size="sm"
45
52
  @click="() => copyText(inputValue)"
46
53
  >
@@ -50,5 +57,5 @@ defineOptions({
50
57
  </q-btn>
51
58
  <MSarString :text="val" />
52
59
  <slot />
53
- </div>
60
+ </MRow>
54
61
  </template>
@@ -23,7 +23,7 @@ type ModelValue = MUploaderMediaItem & File & {
23
23
  __progressLabel?: string;
24
24
  __status?: string;
25
25
  __img?: any;
26
- };
26
+ }
27
27
 
28
28
  interface P {
29
29
  name: Props['name'];
@@ -288,7 +288,7 @@ defineOptions({
288
288
  dense
289
289
  flat
290
290
  target="_blank"
291
- v-bind="pluginOptions.uploaderOptions?.downloadBtnProps"
291
+ v-bind="pluginOptions.uploaderOptions?.downloadBtnProps as any"
292
292
  >
293
293
  <q-tooltip class="m-dt-btn-tooltip">
294
294
  {{ __('myth.titles.download') }}
@@ -299,7 +299,7 @@ defineOptions({
299
299
  flat
300
300
  icon="ion-ios-eye"
301
301
  v-bind="pluginOptions.uploaderOptions?.downloadBtnProps"
302
- @click="emit('showMedia', mediaProp, $event)"
302
+ @click="emit('showMedia', mediaProp as MUploaderMediaItem, $event)"
303
303
  >
304
304
  <q-tooltip class="m-dt-btn-tooltip">
305
305
  {{ __('labels.show') }}
@@ -307,7 +307,7 @@ defineOptions({
307
307
  </q-btn>
308
308
  </template>
309
309
  <q-btn
310
- v-if="(!hideDeleteMedia || (hideDeleteMedia && !mediaProp.id))"
310
+ v-if="(!hideDeleteMedia || (hideDeleteMedia && !mediaProp.id as any))"
311
311
  :disable="deleting || scope.isBusy || scope.isUploading"
312
312
  :icon="deleteMediaIcon"
313
313
  dense
@@ -324,7 +324,7 @@ defineOptions({
324
324
  <audio controls>
325
325
  <source
326
326
  v-if="!!modelValue.url"
327
- :src="modelValue.url"
327
+ :src="modelValue.url as any"
328
328
  :type="modelValue.mime_type"
329
329
  v-bind="audioProps"
330
330
  >
@@ -339,7 +339,7 @@ defineOptions({
339
339
  <q-video
340
340
  v-if="!!modelValue.url"
341
341
  :ratio="ratio"
342
- :src="modelValue.url"
342
+ :src="modelValue.url as any"
343
343
  v-bind="videoProps"
344
344
  />
345
345
  </div>
@@ -112,7 +112,11 @@ export const useDtHelpers = (options: MaybeRefOrGetter<MDatatableProps>) => {
112
112
  }
113
113
 
114
114
  const getHeaders = computed<any[]>(() => {
115
- const h = parseHeaders(props.headers as MDtHeadersParameter, { noSort: props.imageColumns }) || []
115
+ const h = parseHeaders(props.headers as MDtHeadersParameter, {
116
+ noSort: props.imageColumns,
117
+ controlAlign: props.controlStart ? 'left' : 'right',
118
+ align: getProp.value('align')
119
+ }) || []
116
120
  if (!activeContextItems.value.length) {
117
121
  return h.filter(e => e.name !== props.controlKey)
118
122
  }
@@ -120,22 +120,24 @@ export const useMyth = () => {
120
120
  */
121
121
  const parseHeaders = (headers: MDtHeadersParameter, options: ParseHeaderOptions = {}): MDtColumn[] => {
122
122
  const defaultOptions: Partial<ParseHeaderOptions> = {
123
- controlKey: 'control',
123
+ controlKey: 'control'
124
124
  // controlStyle: 'max-width: 150 px',
125
- align: 'center'
125
+ // align: 'center'
126
126
  // sortable: !0
127
127
  }
128
128
  const opts = extend<ParseHeaderOptions>(!0, {}, defaultOptions, options)
129
- let control: string | undefined = defaultOptions.controlKey
130
- let controlStyle: string | undefined = defaultOptions.controlStyle
131
- if (opts.controlKey) {
132
- control = opts.controlKey
133
- delete opts.controlKey
134
- }
135
- if (opts.controlStyle) {
136
- controlStyle = opts.controlStyle
137
- delete opts.controlStyle
138
- }
129
+ const control: string | undefined = opts.controlKey || defaultOptions.controlKey
130
+ const controlStyle: string | undefined = opts.controlStyle || defaultOptions.controlStyle
131
+ const noSort = options.noSort || []
132
+ // delete opts.noSort
133
+ // if (opts.controlKey) {
134
+ // control = opts.controlKey
135
+ // delete opts.controlKey
136
+ // }
137
+ // if (opts.controlStyle) {
138
+ // controlStyle = opts.controlStyle
139
+ // delete opts.controlStyle
140
+ // }
139
141
  const result: MDtColumn[] = []
140
142
 
141
143
  headers.forEach((elm: string | MDtColumn | undefined) => {
@@ -191,7 +193,10 @@ export const useMyth = () => {
191
193
  item.headerClasses = (item.headerClasses ? item.headerClasses : '') + ' m-control-header'
192
194
  item.headerClasses = item.headerClasses.trim()
193
195
  item.sortable = !1
194
- if (!item.align) {
196
+ if (opts.controlAlign) {
197
+ item.align = opts.controlAlign
198
+ } else if (!item.align) {
199
+ // console.log(item)
195
200
  item.align = 'right'
196
201
  }
197
202
  // opts.classes = opts.classes || ''
@@ -203,14 +208,17 @@ export const useMyth = () => {
203
208
  opts.classes = opts.classes.trim()
204
209
  }
205
210
  }
206
-
211
+ if (!item.align) {
212
+ item.align = 'left'
213
+ }
207
214
  item = { ...opts, ...item }
208
215
 
209
- if (item.sortable === undefined && (options.noSort ?? []).length > 0 && options.noSort?.includes(item.name)) {
216
+ if (item.sortable === undefined && noSort.length > 0 && noSort.includes(item.name)) {
210
217
  item.sortable = !1
211
218
  } else if (item.sortable === undefined) {
212
219
  item.sortable = !0
213
220
  }
221
+ // console.log(item)
214
222
  result.push(item)
215
223
  })
216
224
  return Helpers.uniqBy(result, 'name')
@@ -214,6 +214,7 @@ export type MDtRequestParamsObjectProp = Partial<GenericFormValues>
214
214
  export type MDatatableProps<I extends GenericFormValues = GenericFormValues> = Omit<QTableProps, 'rows' | 'rowsPerPageOptions' | 'visibleColumns'> & {
215
215
  rows?: any[];
216
216
  controlKey?: string;
217
+ controlStart?: boolean;
217
218
  defaultItem?: Partial<MDtItem<I>>
218
219
  contextItems?: MaybeRefOrGetter<GenericMDtBtn[]>;
219
220
  contextItemsLength?: number;
@@ -336,6 +337,10 @@ export type MDatatableProps<I extends GenericFormValues = GenericFormValues> = O
336
337
  * Column name to lock the value.
337
338
  */
338
339
  lockValue?: string;
340
+ /**
341
+ * Align all table columns to the left, center, or right.
342
+ */
343
+ align?: 'left' | 'right' | 'center';
339
344
  }
340
345
 
341
346
  export interface MDtAvatarProps extends QAvatarProps {
@@ -368,6 +373,7 @@ export interface MDtContextmenuItemsSlots {
368
373
  export interface MDtColorColumnProps {
369
374
  value?: any;
370
375
  size?: string | number;
376
+ align?: 'left' | 'right' | 'center';
371
377
  }
372
378
 
373
379
  export interface MDtColorColumnSlots {
@@ -382,6 +388,7 @@ export interface MDtCopyColumnProps {
382
388
  value?: any;
383
389
  width?: string | number;
384
390
  sar?: boolean;
391
+ align?: 'left' | 'right' | 'center';
385
392
  }
386
393
 
387
394
  export interface MDtCopyColumnSlots {
@@ -393,6 +400,7 @@ export interface MDtCopyColumnSlots {
393
400
 
394
401
  export interface MDtDescColumnProps {
395
402
  value?: any;
403
+ align?: 'left' | 'right' | 'center';
396
404
  }
397
405
 
398
406
  export interface MDtDescColumnSlots {
@@ -419,6 +427,7 @@ export interface MDtSarColumnProps {
419
427
  value?: any;
420
428
  copy?: boolean;
421
429
  copyValue?: any;
430
+ align?: 'left' | 'right' | 'center';
422
431
  }
423
432
 
424
433
  export interface MDtSarColumnSlots {
@@ -11,12 +11,13 @@ import type { DialogChainObject, QNotifyCreateOptions, QNotifyUpdateOptions, QTa
11
11
  import type { MDatatableProps } from './m-datatable'
12
12
 
13
13
  export type ParseHeaderOptions = {
14
- controlKey?: 'control' | string
15
- controlStyle?: 'max-width: 150px' | string
16
- align?: 'left' | 'right' | 'center' | undefined
14
+ controlKey?: 'control' | string;
15
+ controlStyle?: 'max-width: 150px' | string;
16
+ controlAlign?: 'left' | 'right' | 'center' | undefined;
17
+ align?: 'left' | 'right' | 'center' | undefined;
17
18
  sortable?: boolean | undefined;
18
- classes?: string | (() => string) | (<T>(item: T) => string),
19
- noSort?: string[]
19
+ classes?: string | (() => string) | (<T>(item: T) => string);
20
+ noSort?: string[];
20
21
  }
21
22
 
22
23
  export type MDtColumn = QTableProps['columns'][number]