atom-nuxt 1.1.0 → 1.3.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.
Files changed (33) hide show
  1. package/dist/module.cjs +5 -0
  2. package/dist/module.d.mts +1 -2
  3. package/dist/module.d.ts +22 -0
  4. package/dist/module.json +3 -3
  5. package/dist/runtime/components/AlertDisplay.vue +18 -11
  6. package/dist/runtime/components/CrudAddressSearchField.vue +35 -22
  7. package/dist/runtime/components/CrudApiSelectorField.vue +24 -11
  8. package/dist/runtime/components/CrudConfirmDialog.vue +17 -11
  9. package/dist/runtime/components/CrudErrorDisplay.vue +4 -3
  10. package/dist/runtime/components/CrudFilter.vue +46 -25
  11. package/dist/runtime/components/CrudFilterList.vue +6 -0
  12. package/dist/runtime/components/CrudFormDialog.vue +16 -6
  13. package/dist/runtime/components/CrudFormLoader.vue +121 -98
  14. package/dist/runtime/components/CrudListLoader.vue +28 -17
  15. package/dist/runtime/components/CrudPaginatedLoader.vue +93 -57
  16. package/dist/runtime/components/CrudUploadField.vue +28 -6
  17. package/dist/runtime/components/CrudUploadFieldSelection.vue +27 -19
  18. package/dist/types.d.mts +2 -4
  19. package/dist/types.d.ts +7 -0
  20. package/package.json +1 -1
  21. package/dist/runtime/components/AlertDisplay.vue.d.ts +0 -2
  22. package/dist/runtime/components/CrudAddressSearchField.vue.d.ts +0 -8
  23. package/dist/runtime/components/CrudApiSelectorField.vue.d.ts +0 -30
  24. package/dist/runtime/components/CrudConfirmDialog.vue.d.ts +0 -18
  25. package/dist/runtime/components/CrudErrorDisplay.vue.d.ts +0 -6
  26. package/dist/runtime/components/CrudFilter.vue.d.ts +0 -8
  27. package/dist/runtime/components/CrudFilterList.vue.d.ts +0 -5
  28. package/dist/runtime/components/CrudFormDialog.vue.d.ts +0 -33
  29. package/dist/runtime/components/CrudFormLoader.vue.d.ts +0 -41
  30. package/dist/runtime/components/CrudListLoader.vue.d.ts +0 -37
  31. package/dist/runtime/components/CrudPaginatedLoader.vue.d.ts +0 -75
  32. package/dist/runtime/components/CrudUploadField.vue.d.ts +0 -23
  33. package/dist/runtime/components/CrudUploadFieldSelection.vue.d.ts +0 -18
@@ -0,0 +1,5 @@
1
+ module.exports = function(...args) {
2
+ return import('./module.mjs').then(m => m.default.call(this, ...args))
3
+ }
4
+ const _meta = module.exports.meta = require('./module.json')
5
+ module.exports.getMeta = () => Promise.resolve(_meta)
package/dist/module.d.mts CHANGED
@@ -19,5 +19,4 @@ interface AtomCrudModuleOptions {
19
19
  }
20
20
  declare const _default: _nuxt_schema.NuxtModule<AtomCrudModuleOptions, AtomCrudModuleOptions, false>;
21
21
 
22
- export { _default as default };
23
- export type { AtomCrudModuleOptions, azureAdB2COptions };
22
+ export { type AtomCrudModuleOptions, type azureAdB2COptions, _default as default };
@@ -0,0 +1,22 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface azureAdB2COptions {
4
+ clientId: string;
5
+ authority: string;
6
+ knownAuthorities?: Array<string>;
7
+ redirectUri: string;
8
+ postLogoutRedirectUri?: string;
9
+ navigateToLoginRequestUrl: boolean;
10
+ scopes?: string[];
11
+ }
12
+ interface AtomCrudModuleOptions {
13
+ apiBaseUrl?: string;
14
+ storageBaseUrl?: string;
15
+ additionalHeaders?: Record<string, string>;
16
+ azureAdB2C?: azureAdB2COptions;
17
+ googleMapsApiKey?: string;
18
+ debug?: boolean;
19
+ }
20
+ declare const _default: _nuxt_schema.NuxtModule<AtomCrudModuleOptions, AtomCrudModuleOptions, false>;
21
+
22
+ export { type AtomCrudModuleOptions, type azureAdB2COptions, _default as default };
package/dist/module.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@atomengine/atom-nuxt",
3
3
  "configKey": "atomNuxt",
4
- "version": "1.1.0",
4
+ "version": "1.3.0",
5
5
  "builder": {
6
- "@nuxt/module-builder": "1.0.1",
7
- "unbuild": "3.5.0"
6
+ "@nuxt/module-builder": "0.8.4",
7
+ "unbuild": "2.0.0"
8
8
  }
9
9
  }
@@ -1,43 +1,46 @@
1
- <script setup>
2
- import { useAlertService } from "../composables/useAlertService";
3
- import { computed } from "vue";
4
- const { alertMessage, alertActive } = useAlertService();
1
+ <script setup lang="ts">
2
+ import {useAlertService} from '../composables/useAlertService';
3
+ import {computed} from 'vue';
4
+
5
+ const {alertMessage, alertActive} = useAlertService();
6
+
5
7
  const message = computed(() => {
6
8
  if (!alertMessage.value || !alertActive.value) {
7
9
  return null;
8
10
  }
9
- return typeof alertMessage.value === "string" ? alertMessage.value : alertMessage.value.message;
11
+ return typeof alertMessage.value === 'string' ? alertMessage.value : alertMessage.value.message;
10
12
  });
11
13
  const color = computed(() => {
12
14
  if (!alertMessage.value || !alertActive.value) {
13
15
  return null;
14
16
  }
15
- return typeof alertMessage.value === "string" ? "success" : alertMessage.value.color || "success";
17
+ return typeof alertMessage.value === 'string' ? 'success' : alertMessage.value.color || 'success';
16
18
  });
17
19
  const location = computed(() => {
18
20
  if (!alertMessage.value || !alertActive.value) {
19
21
  return "";
20
22
  }
21
- return typeof alertMessage.value === "string" ? "" : alertMessage.value.location || "";
23
+ return typeof alertMessage.value === 'string' ? "" : alertMessage.value.location || "";
22
24
  });
23
25
  const icon = computed(() => {
24
26
  if (!alertMessage.value || !alertActive.value) {
25
27
  return null;
26
28
  }
27
- return typeof alertMessage.value === "string" ? null : alertMessage.value.icon || null;
29
+ return typeof alertMessage.value === 'string' ? null : alertMessage.value.icon || null;
28
30
  });
31
+
29
32
  const clickable = computed(() => {
30
- if (!alertMessage.value || !alertActive.value || typeof alertMessage.value === "string" || !alertMessage.value.onClick) {
33
+ if (!alertMessage.value || !alertActive.value || typeof alertMessage.value === 'string' || !alertMessage.value.onClick) {
31
34
  return false;
32
35
  }
33
36
  return true;
34
- });
37
+ })
35
38
  const onClick = () => {
36
39
  if (!clickable.value) {
37
40
  return;
38
41
  }
39
42
  alertMessage.value.onClick();
40
- };
43
+ }
41
44
  </script>
42
45
 
43
46
  <template>
@@ -53,3 +56,7 @@ const onClick = () => {
53
56
  </div>
54
57
  </v-snackbar>
55
58
  </template>
59
+
60
+ <style scoped>
61
+
62
+ </style>
@@ -1,33 +1,36 @@
1
1
  <script setup>
2
- import { ref, watch } from "vue";
3
- import { useRuntimeConfig } from "nuxt/app";
4
- import { useDebounceFn } from "@vueuse/core";
2
+ import {ref, watch} from 'vue';
3
+ import {useRuntimeConfig} from "nuxt/app";
4
+ import {useDebounceFn} from '@vueuse/core'; // Ensure @vueuse/core is installed
5
+
5
6
  const atomNuxtConfig = useRuntimeConfig().public.atomNuxt;
6
7
  const props = defineProps({
7
8
  hint: {
8
9
  type: String,
9
- default: "Search by postcode, city or country. You must select an option from the list."
10
+ default: 'Search by postcode, city or country. You must select an option from the list.'
10
11
  },
11
12
  label: {
12
13
  type: String,
13
- default: "Address search"
14
+ default: 'Address search'
14
15
  },
15
16
  placeholder: {
16
17
  type: String,
17
- default: "Start typing address"
18
+ default: 'Start typing address'
18
19
  },
19
20
  countries: {
20
21
  type: Array,
21
- default: () => []
22
- // Example: ['gb', 'fr', 'us']
22
+ default: () => [] // Example: ['gb', 'fr', 'us']
23
23
  }
24
24
  });
25
- const searchText = ref("");
25
+ // Data
26
+ const searchText = ref('');
26
27
  const addressSearchResults = ref([]);
27
28
  const loading = ref(false);
28
29
  const selectedPlaceId = ref(null);
29
30
  const model = defineModel();
30
- const placeModel = defineModel("place");
31
+ const placeModel = defineModel("place")
32
+
33
+ // Function to get autocomplete suggestions using fetch
31
34
  const fetchAutocompleteSuggestions = async (query) => {
32
35
  if (!query || loading.value) return;
33
36
  loading.value = true;
@@ -38,21 +41,23 @@ const fetchAutocompleteSuggestions = async (query) => {
38
41
  params: {
39
42
  input: query,
40
43
  key: atomNuxtConfig.googleMapsApiKey,
41
- components: props.countries.length ? props.countries.map((c) => `country:${c}`).join("|") : void 0
44
+ components: props.countries.length
45
+ ? props.countries.map(c => `country:${c}`).join('|')
46
+ : undefined
42
47
  },
43
- method: "GET"
48
+ method: 'GET'
44
49
  }
45
50
  );
46
- if (result.status === "OK") {
47
- addressSearchResults.value = result.predictions.map((prediction) => ({
51
+ if (result.status === 'OK') {
52
+ addressSearchResults.value = result.predictions.map(prediction => ({
48
53
  text: prediction.description,
49
54
  place_id: prediction.place_id
50
55
  }));
51
56
  } else {
52
- console.error("Error fetching autocomplete suggestions:", result.status);
57
+ console.error('Error fetching autocomplete suggestions:', result.status);
53
58
  }
54
59
  } catch (error) {
55
- console.error("Error fetching autocomplete suggestions:", error);
60
+ console.error('Error fetching autocomplete suggestions:', error);
56
61
  } finally {
57
62
  loading.value = false;
58
63
  }
@@ -68,29 +73,37 @@ const fetchPlaceId = async (placeId) => {
68
73
  `/api/maps/places`,
69
74
  {
70
75
  params: {
71
- placeId,
72
- key: atomNuxtConfig.googleMapsApiKey
76
+ placeId: placeId,
77
+ key: atomNuxtConfig.googleMapsApiKey,
73
78
  },
74
- method: "GET"
79
+ method: 'GET'
75
80
  }
76
81
  );
77
- if (result.status === "OK") {
82
+ // Check if the API call was successful
83
+ if (result.status === 'OK') {
78
84
  placeModel.value = result.result;
79
85
  model.value = `${result.result.geometry.location.lat},${result.result.geometry.location.lng}`;
80
86
  } else {
81
- console.error("Error fetching place details:", result.status);
87
+ console.error('Error fetching place details:', result.status);
82
88
  }
83
89
  } catch (error) {
84
- console.error("Error fetching place details:", error);
90
+ console.error('Error fetching place details:', error);
85
91
  }
86
92
  };
93
+
94
+
95
+ // Debounce the search text updates to avoid excessive API calls
87
96
  const debouncedFetchAutocompleteSuggestions = useDebounceFn(fetchAutocompleteSuggestions, 500);
97
+
98
+ // Watch for changes to searchText and trigger debounced API calls
88
99
  watch(searchText, (newQuery) => {
89
100
  debouncedFetchAutocompleteSuggestions(newQuery);
90
101
  });
102
+
91
103
  watch(selectedPlaceId, (newPlaceId) => {
92
104
  fetchPlaceId(newPlaceId);
93
105
  });
106
+
94
107
  </script>
95
108
 
96
109
  <template>
@@ -1,31 +1,44 @@
1
1
  <script setup>
2
2
  import CrudListLoader from "./CrudListLoader.vue";
3
- import { defineModel, ref, computed } from "vue";
3
+ import {defineModel, ref, computed} from "vue";
4
+
4
5
  const props = defineProps({
5
- path: { type: String, required: true },
6
- multiple: { type: Boolean, default: false },
7
- endpointDisplayKey: { type: String, default: "name" },
8
- endpointFilterKey: { type: String, default: "keywords" },
9
- endpointResponseKey: { type: String, default: "id" },
10
- additionalFilters: { type: Object, default: () => ({}) },
11
- disableUpdate: { type: Boolean, default: false },
12
- createBtnText: { type: String, default: "Select" },
13
- updateBtnText: { type: String, default: "Update" }
6
+ path: {type: String, required: true},
7
+ multiple: {type: Boolean, default: false},
8
+ endpointDisplayKey: {type: String, default: "name"},
9
+ endpointFilterKey: {type: String, default: "keywords"},
10
+ endpointResponseKey: {type: String, default: "id"},
11
+ additionalFilters: {type: Object, default: () => ({})},
12
+ disableUpdate: {type: Boolean, default: false},
13
+ createBtnText: {type: String, default: "Select"},
14
+ updateBtnText: {type: String, default: "Update"}
14
15
  });
16
+
15
17
  const selectionModel = defineModel();
16
18
  const search = ref("");
17
19
  const searchDialog = ref(false);
18
20
  const searchDialogSelectedValue = ref(null);
21
+
19
22
  const hasSelection = computed(() => props.multiple ? selectionModel.value !== null && Array.isArray(selectionModel.value) && selectionModel.value.length > 0 : selectionModel.value !== null);
23
+
20
24
  const onAction = () => {
21
- searchDialogSelectedValue.value = selectionModel.value ? Array.isArray(selectionModel.value) ? [...selectionModel.value] : selectionModel.value : null;
25
+ // Clone selectionModel into searchDialogSelectedValue (to modify freely inside the dialog)
26
+ searchDialogSelectedValue.value = selectionModel.value
27
+ ? Array.isArray(selectionModel.value)
28
+ ? [...selectionModel.value]
29
+ : selectionModel.value
30
+ : null;
22
31
  searchDialog.value = true;
23
32
  };
33
+
24
34
  const onDone = () => {
35
+ // Update selectionModel only when clicking "Done"
25
36
  selectionModel.value = searchDialogSelectedValue.value;
26
37
  searchDialog.value = false;
27
38
  };
39
+
28
40
  const onCancel = () => {
41
+ // Close the dialog without saving changes
29
42
  searchDialog.value = false;
30
43
  };
31
44
  </script>
@@ -1,40 +1,41 @@
1
1
  <script setup>
2
- import { ref, defineProps, defineEmits } from "vue";
2
+ import { ref, defineProps, defineEmits } from 'vue';
3
3
  defineProps({
4
4
  title: {
5
5
  type: String,
6
6
  default() {
7
- return "Delete item";
7
+ return "Delete item"
8
8
  }
9
9
  },
10
10
  message: {
11
11
  type: String,
12
12
  default() {
13
- return "Are you sure you want to delete this item?";
13
+ return "Are you sure you want to delete this item?"
14
14
  }
15
15
  },
16
16
  cancelText: {
17
17
  type: String,
18
18
  default() {
19
- return "Cancel";
19
+ return "Cancel"
20
20
  }
21
21
  },
22
22
  confirmText: {
23
23
  type: String,
24
24
  default() {
25
- return "OK";
25
+ return "OK"
26
26
  }
27
27
  }
28
- });
29
- const emit = defineEmits(["confirm"]);
30
- const dialog = ref(false);
28
+ })
29
+ const emit = defineEmits(['confirm']); // Declare the 'confirm' event
30
+ const dialog = ref(false)
31
31
  const open = () => {
32
- dialog.value = true;
33
- };
32
+ dialog.value = true
33
+ }
34
34
  const handleConfirm = () => {
35
- emit("confirm");
35
+ emit('confirm'); // Emit the 'confirm' event
36
36
  dialog.value = false;
37
37
  };
38
+
38
39
  </script>
39
40
 
40
41
  <template>
@@ -78,6 +79,11 @@ const handleConfirm = () => {
78
79
  </v-btn>
79
80
  </v-card-actions>
80
81
 
82
+
81
83
  </v-card>
82
84
  </v-dialog>
83
85
  </template>
86
+
87
+ <style scoped>
88
+
89
+ </style>
@@ -1,6 +1,6 @@
1
1
  <script setup>
2
- import { computed } from "vue";
3
- import { defineProps } from "vue";
2
+ import {computed} from 'vue';
3
+ import {defineProps} from 'vue';
4
4
  const props = defineProps({
5
5
  errors: Object,
6
6
  errorKey: {
@@ -8,9 +8,9 @@ const props = defineProps({
8
8
  default: null
9
9
  }
10
10
  });
11
+
11
12
  const random = computed(() => Math.random());
12
13
  </script>
13
-
14
14
  <template>
15
15
  <v-alert
16
16
  v-if="errors != null && errors[errorKey ?? 'global'] != null"
@@ -26,3 +26,4 @@ const random = computed(() => Math.random());
26
26
  </div>
27
27
  </v-alert>
28
28
  </template>
29
+
@@ -1,103 +1,121 @@
1
1
  <script setup>
2
2
  import CrudListLoader from "./CrudListLoader.vue";
3
- import { ref, computed, watch, onMounted, onBeforeUnmount } from "vue";
4
- import { useDebounceFn } from "@vueuse/core";
3
+ import {ref, computed, watch, onMounted, onBeforeUnmount} from "vue";
4
+ import {useDebounceFn} from "@vueuse/core";
5
5
  import CrudAddressSearchField from "./CrudAddressSearchField.vue";
6
- import { useCrudConverters } from "../composables/useCrudConverters";
7
- import { useCrudApi } from "../composables/useCrudApi";
6
+ import {useCrudConverters} from "../composables/useCrudConverters";
7
+ import {useCrudApi} from "../composables/useCrudApi";
8
+
8
9
  const props = defineProps({
9
10
  filter: {
10
11
  type: Object,
11
- required: true
12
+ required: true,
12
13
  },
13
14
  modelValue: null,
14
- disabled: Boolean
15
+ disabled: Boolean,
15
16
  });
16
17
  const model = ref();
17
- const emit = defineEmits(["update:modelValue"]);
18
+ const emit = defineEmits(['update:modelValue']);
19
+ // Watch for changes in the prop and update the internal model
18
20
  watch(() => props.modelValue, (newValue) => {
19
- model.value = newValue;
21
+ model.value = newValue; // Sync internal model when the prop changes
20
22
  });
23
+ // Debounced emit function
24
+
21
25
  const filter = ref(props.filter);
26
+
27
+ // Watch for changes in the filter prop and update the internal filter
22
28
  watch(() => props.filter, (newValue) => {
23
- filter.value = newValue;
29
+ filter.value = newValue; // Sync internal filter when the prop changes
24
30
  });
31
+
25
32
  const searchDialogSelectedValue = ref(null);
26
33
  const search = ref(null);
27
34
  const searchDialog = ref(false);
28
35
  const datePickerValue = ref(null);
29
36
  const datePicker = ref(false);
37
+
30
38
  const emitUpdate = () => {
31
- emit("update:modelValue", model.value);
32
- };
39
+ emit('update:modelValue', model.value);
40
+ }
33
41
  const debouncedUpdate = useDebounceFn(emitUpdate, 700);
34
- const { inputDateForDb, outputDateFromDb, cloneDeep, localDateForDb } = useCrudConverters();
42
+
43
+
44
+ const {inputDateForDb, outputDateFromDb, cloneDeep, localDateForDb} = useCrudConverters();
45
+
35
46
  const datePickerDisplayValue = computed(() => {
36
47
  if (!selectedValue.value || selectedValue.value.length !== 2) {
37
48
  return null;
38
49
  }
39
- const startDate = outputDateFromDb(selectedValue.value[0], "dd LLL");
40
- const endDate = outputDateFromDb(selectedValue.value[1], "dd LLL");
50
+ const startDate = outputDateFromDb(selectedValue.value[0], 'dd LLL');
51
+ const endDate = outputDateFromDb(selectedValue.value[1], 'dd LLL');
41
52
  return `${startDate} - ${endDate}`;
42
53
  });
54
+
43
55
  const selectedValue = computed({
44
56
  get() {
45
57
  if (model.value != null) {
46
- if (props.filter.optionType === "DateTimeRange") {
58
+ if (props.filter.optionType === 'DateTimeRange') {
47
59
  if (!model.value || model.value.length !== 2) {
48
60
  return null;
49
61
  }
50
62
  return model.value;
51
63
  }
52
64
  return model.value;
53
- } else if (props.filter.type === "multiOption" || props.filter.type === "multiSearch") {
65
+ } else if (props.filter.type === 'multiOption' || props.filter.type === 'multiSearch') {
54
66
  return [];
55
67
  } else {
56
68
  return null;
57
69
  }
58
70
  },
59
71
  set(val) {
60
- if (props.filter.optionType === "DateTimeRange" && val && val[0]) {
72
+ if (props.filter.optionType === 'DateTimeRange' && val && val[0]) {
61
73
  let start = val[0];
62
74
  let end = val[1];
63
75
  model.value = [start, end];
64
76
  } else {
65
77
  model.value = val;
66
78
  }
67
- if (props.filter.type === "search" || props.filter.type === "multiSearch" || props.filter.type === "option" || props.filter.type === "multiOption" || props.filter.type === "multiOptionTree") {
79
+ if (props.filter.type === 'search' || props.filter.type === 'multiSearch' || props.filter.type === 'option' || props.filter.type === 'multiOption' || props.filter.type === 'multiOptionTree') {
68
80
  emitUpdate();
69
81
  } else {
70
82
  debouncedUpdate();
71
83
  }
72
- }
84
+ },
73
85
  });
86
+
74
87
  const {
75
88
  getItems: searchGetItems,
76
89
  items: searchListItems,
77
90
  listPending: searchLoading
78
91
  } = useCrudApi(props.filter.endpoint);
92
+
93
+
79
94
  async function getSearchListValue() {
80
95
  if (!selectedValue.value || selectedValue.value.length === 0) {
81
96
  return;
82
97
  }
83
- const filters = { ids: selectedValue.value };
98
+ const filters = {ids: selectedValue.value};
84
99
  await searchGetItems(1, selectedValue.value.length, filters);
85
100
  }
101
+
86
102
  const validateDateRange = () => {
87
103
  datePicker.value = false;
104
+
88
105
  if (!datePickerValue.value || datePickerValue.value.length < 2) {
89
106
  return;
90
107
  }
91
108
  let startDate = localDateForDb(datePickerValue.value[0]);
92
109
  let endDate = localDateForDb(datePickerValue.value[datePickerValue.value.length - 1]);
93
110
  selectedValue.value = [startDate, endDate];
94
- };
111
+ }
112
+
95
113
  const closeDatePicker = (clear = false) => {
96
114
  if (clear) {
97
115
  selectedValue.value = null;
98
116
  }
99
117
  datePicker.value = false;
100
- };
118
+ }
101
119
  watch(searchDialog, (newValue, oldValue) => {
102
120
  if (!newValue && searchDialogSelectedValue.value != null) {
103
121
  selectedValue.value = cloneDeep(searchDialogSelectedValue.value);
@@ -108,19 +126,22 @@ watch(searchDialog, (newValue, oldValue) => {
108
126
  searchDialogSelectedValue.value = cloneDeep(model.value);
109
127
  }
110
128
  });
129
+
111
130
  onMounted(() => {
112
131
  model.value = props.modelValue;
113
- if (props.filter.type === "search" || props.filter.type === "multiSearch") {
132
+ if (props.filter.type === 'search' || props.filter.type === 'multiSearch') {
114
133
  getSearchListValue();
115
134
  }
116
135
  });
136
+
117
137
  const displayForChip = (item) => {
118
- var searchItem = searchListItems.value.find((inlineItem) => inlineItem[props.filter.endpointResponseKey] === item.raw);
138
+ var searchItem = searchListItems.value.find(inlineItem => inlineItem[props.filter.endpointResponseKey] === item.raw);
119
139
  if (!searchItem) {
120
140
  return "Loading";
121
141
  }
122
142
  return searchItem[props.filter.endpointDisplayKey] ?? "Loading";
123
- };
143
+ }
144
+
124
145
  </script>
125
146
 
126
147
  <template>
@@ -1,5 +1,6 @@
1
1
  <script setup>
2
2
  import CrudFilter from "../components/CrudFilter.vue";
3
+
3
4
  const model = defineModel();
4
5
  const props = defineProps({
5
6
  filters: {
@@ -9,6 +10,7 @@ const props = defineProps({
9
10
  }
10
11
  }
11
12
  });
13
+
12
14
  </script>
13
15
 
14
16
  <template>
@@ -18,3 +20,7 @@ const props = defineProps({
18
20
  </div>
19
21
  </div>
20
22
  </template>
23
+
24
+ <style scoped>
25
+
26
+ </style>
@@ -1,7 +1,8 @@
1
1
  <script setup>
2
2
  import CrudErrorDisplay from "../components/CrudErrorDisplay.vue";
3
- import { computed } from "vue";
4
- import { useDisplay } from "vuetify";
3
+ import {computed} from "vue";
4
+ import {useDisplay} from "vuetify";
5
+
5
6
  const props = defineProps({
6
7
  action: {
7
8
  type: String,
@@ -96,17 +97,22 @@ const props = defineProps({
96
97
  }
97
98
  });
98
99
  const item = defineModel();
99
- const dialogOpen = defineModel("dialog");
100
+ const dialogOpen = defineModel('dialog');
100
101
  const hasItem = computed(() => item.value && Object.keys(item.value).length > 0);
102
+
101
103
  const buttonTitle = computed(() => {
102
- return props.btnText ? props.btnText : props.action === "create" ? props.createTitle : props.action === "update" ? props.updateTitle : props.action === "delete" ? props.deleteTitle : props.action === "view" ? props.viewTitle : "";
104
+ return props.btnText ? props.btnText : (props.action === 'create' ? props.createTitle : (props.action === 'update' ? props.updateTitle : (props.action === 'delete' ? props.deleteTitle : (props.action === 'view' ? props.viewTitle : ''))));
103
105
  });
106
+
104
107
  const buttonIcon = computed(() => {
105
- return props.btnIcon ? props.btnIcon : props.action === "create" ? "mdi-plus" : props.action === "update" ? "mdi-pencil" : props.action === "delete" ? "mdi-delete" : props.action === "view" ? "mdi-eye" : "mdi-timer-sand";
108
+ return props.btnIcon ? props.btnIcon : (props.action === 'create' ? 'mdi-plus' : (props.action === 'update' ? 'mdi-pencil' : (props.action === 'delete' ? 'mdi-delete' : (props.action === 'view' ? 'mdi-eye' : 'mdi-timer-sand'))));
106
109
  });
110
+
107
111
  const display = useDisplay();
108
112
  const isLarge = computed(() => display.lgAndUp.value);
109
- const readonly = computed(() => props.action === "view");
113
+
114
+ const readonly = computed(() => props.action === 'view');
115
+
110
116
  </script>
111
117
 
112
118
  <template>
@@ -185,3 +191,7 @@ const readonly = computed(() => props.action === "view");
185
191
  </v-card>
186
192
  </v-dialog>
187
193
  </template>
194
+
195
+ <style scoped>
196
+
197
+ </style>