vue-ready-modular 1.0.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/README.md +0 -0
- package/bin/cli.js +12 -0
- package/docs/INSTALLATION.md +6 -0
- package/lib/generator.js +76 -0
- package/lib/templates/data.template.js +10 -0
- package/lib/templates/index.template.js +6 -0
- package/lib/templates/modal-add.template.js +59 -0
- package/lib/templates/modal-delete.template.js +52 -0
- package/lib/templates/modal-edit.template.js +69 -0
- package/lib/templates/modal-view.template.js +33 -0
- package/lib/templates/mutation.template.js +29 -0
- package/lib/templates/page.template.js +61 -0
- package/lib/templates/query.template.js +19 -0
- package/lib/templates/routes.template.js +21 -0
- package/lib/templates/service.template.js +43 -0
- package/lib/templates/store.template.js +31 -0
- package/lib/utils/file.js +9 -0
- package/lib/utils/string.js +3 -0
- package/package.json +19 -0
package/README.md
ADDED
|
File without changes
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { createModule } from "../lib/generator.js";
|
|
4
|
+
|
|
5
|
+
const args = process.argv.slice(2);
|
|
6
|
+
|
|
7
|
+
if (args[0] !== "make" || !args[1]) {
|
|
8
|
+
console.log("Usage: vue-modular make <module-name>");
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
createModule(args[1]);
|
package/lib/generator.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
|
|
4
|
+
import { createDir, createFile } from "./utils/file.js";
|
|
5
|
+
import { capitalize } from "./utils/string.js";
|
|
6
|
+
|
|
7
|
+
// Templates
|
|
8
|
+
import indexTemplate from "./templates/index.template.js";
|
|
9
|
+
import routesTemplate from "./templates/routes.template.js";
|
|
10
|
+
import storeTemplate from "./templates/store.template.js";
|
|
11
|
+
import dataTemplate from "./templates/data.template.js";
|
|
12
|
+
import serviceTemplate from "./templates/service.template.js";
|
|
13
|
+
import queryTemplate from "./templates/query.template.js";
|
|
14
|
+
import mutationTemplate from "./templates/mutation.template.js";
|
|
15
|
+
import pageTemplate from "./templates/page.template.js";
|
|
16
|
+
import addModalTemplate from "./templates/modal-add.template.js";
|
|
17
|
+
import editModalTemplate from "./templates/modal-edit.template.js";
|
|
18
|
+
import viewModalTemplate from "./templates/modal-view.template.js";
|
|
19
|
+
import deleteModalTemplate from "./templates/modal-delete.template.js";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Generates a modular Vue.js module with a full structure.
|
|
23
|
+
* @param {string} name - Module name (e.g., "country")
|
|
24
|
+
*/
|
|
25
|
+
export function createModule(name) {
|
|
26
|
+
const module = name.toLowerCase();
|
|
27
|
+
const Module = capitalize(module);
|
|
28
|
+
|
|
29
|
+
const basePath = path.join(process.cwd(), "src/modules", module);
|
|
30
|
+
|
|
31
|
+
// Prevent overwriting existing module
|
|
32
|
+
if (fs.existsSync(basePath)) {
|
|
33
|
+
console.error(`❌ Module "${module}" already exists`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// -----------------------------
|
|
38
|
+
// 1. Create folder structure
|
|
39
|
+
// -----------------------------
|
|
40
|
+
const folders = [
|
|
41
|
+
`${basePath}/stores`,
|
|
42
|
+
`${basePath}/pages/components`,
|
|
43
|
+
`${basePath}/data`,
|
|
44
|
+
`${basePath}/services`,
|
|
45
|
+
`${basePath}/queries`,
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
folders.forEach(createDir);
|
|
49
|
+
|
|
50
|
+
// -----------------------------
|
|
51
|
+
// 2. Prepare template context
|
|
52
|
+
// -----------------------------
|
|
53
|
+
const ctx = { name: module, Name: Module };
|
|
54
|
+
|
|
55
|
+
// -----------------------------
|
|
56
|
+
// 3. Create core module files
|
|
57
|
+
// -----------------------------
|
|
58
|
+
createFile(`${basePath}/index.js`, indexTemplate(ctx));
|
|
59
|
+
createFile(`${basePath}/routes.js`, routesTemplate(ctx));
|
|
60
|
+
createFile(`${basePath}/stores/${module}Store.js`, storeTemplate(ctx));
|
|
61
|
+
createFile(`${basePath}/data/${module}Data.js`, dataTemplate(ctx));
|
|
62
|
+
createFile(`${basePath}/services/${module}Service.js`, serviceTemplate(ctx));
|
|
63
|
+
createFile(`${basePath}/queries/use${Module}sQuery.js`, queryTemplate(ctx));
|
|
64
|
+
createFile(`${basePath}/queries/use${Module}Mutations.js`, mutationTemplate(ctx));
|
|
65
|
+
|
|
66
|
+
// -----------------------------
|
|
67
|
+
// 4. Create page & modal components
|
|
68
|
+
// -----------------------------
|
|
69
|
+
createFile(`${basePath}/pages/${Module}Page.vue`, pageTemplate(ctx));
|
|
70
|
+
createFile(`${basePath}/pages/components/AddModal.vue`, addModalTemplate(ctx));
|
|
71
|
+
createFile(`${basePath}/pages/components/EditModal.vue`, editModalTemplate(ctx));
|
|
72
|
+
createFile(`${basePath}/pages/components/ViewModal.vue`, viewModalTemplate(ctx));
|
|
73
|
+
createFile(`${basePath}/pages/components/DeleteModal.vue`, deleteModalTemplate(ctx));
|
|
74
|
+
|
|
75
|
+
console.log(`✅ Module "${module}" created successfully`);
|
|
76
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export default ({ name, Name }) => `<template>
|
|
2
|
+
<BaseModal
|
|
3
|
+
:isVisible="store.isModal"
|
|
4
|
+
:title="\`Add \${store.moduleName}\`"
|
|
5
|
+
:maxWidth="\`\${store.modalWidth}\`"
|
|
6
|
+
@close="store.handleToggleModal"
|
|
7
|
+
>
|
|
8
|
+
<form @submit.prevent="handleSubmit" class="space-y-4">
|
|
9
|
+
<!-- ${Name} Name -->
|
|
10
|
+
<div>
|
|
11
|
+
<BaseLabel for="name">Name</BaseLabel>
|
|
12
|
+
<BaseInput
|
|
13
|
+
id="name"
|
|
14
|
+
v-model="formData.name"
|
|
15
|
+
:required="true"
|
|
16
|
+
placeholder="Eg: Example Name"
|
|
17
|
+
/>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<!-- Actions -->
|
|
21
|
+
<div class="flex justify-end gap-2 pt-4">
|
|
22
|
+
<BaseButton
|
|
23
|
+
class="bg-yellow-600 hover:bg-yellow-700"
|
|
24
|
+
type="button"
|
|
25
|
+
@click="store.handleToggleModal"
|
|
26
|
+
>Cancel</BaseButton>
|
|
27
|
+
<BaseButton type="submit">Save</BaseButton>
|
|
28
|
+
</div>
|
|
29
|
+
</form>
|
|
30
|
+
</BaseModal>
|
|
31
|
+
</template>
|
|
32
|
+
|
|
33
|
+
<script setup>
|
|
34
|
+
import { ref } from 'vue'
|
|
35
|
+
import { use${Name}Mutations } from '@/modules/${name}/queries/use${Name}Mutations'
|
|
36
|
+
import app from '@/shared/config/appConfig'
|
|
37
|
+
import { use${Name}Store } from '@/modules/${name}/stores/${name}Store'
|
|
38
|
+
|
|
39
|
+
const store = use${Name}Store()
|
|
40
|
+
|
|
41
|
+
const formData = ref({
|
|
42
|
+
name: app.moduleLocal ? 'Test Name' : '',
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
const { submit } = use${Name}Mutations(store.moduleName, {
|
|
46
|
+
onSuccess() {
|
|
47
|
+
store.handleToggleModal() // ✅ close modal
|
|
48
|
+
store.handleReset(formData.value) // ✅ reset form
|
|
49
|
+
},
|
|
50
|
+
onError: (error) => {
|
|
51
|
+
console.log('Custom error handling', error)
|
|
52
|
+
},
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
const handleSubmit = async () => {
|
|
56
|
+
await submit.mutateAsync(formData.value)
|
|
57
|
+
}
|
|
58
|
+
</script>
|
|
59
|
+
`;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export default ({ name, Name }) => `<template>
|
|
2
|
+
<BaseModal
|
|
3
|
+
:isVisible="store.isDeleteModal"
|
|
4
|
+
:title="\`Are you sure you want to delete this \${store.moduleName}?\`"
|
|
5
|
+
:maxWidth="\`\${store.modalWidth}\`"
|
|
6
|
+
@close="store.handleToggleModal"
|
|
7
|
+
>
|
|
8
|
+
<form @submit.prevent="handleSubmit" class="space-y-4">
|
|
9
|
+
<div class="space-y-2">
|
|
10
|
+
<p class="text-lg">
|
|
11
|
+
<strong>ID:</strong>
|
|
12
|
+
{{ store.item.id }}
|
|
13
|
+
</p>
|
|
14
|
+
<p class="text-lg">
|
|
15
|
+
<strong>Name:</strong>
|
|
16
|
+
{{ store.item.name }}
|
|
17
|
+
</p>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<!-- Actions -->
|
|
21
|
+
<div class="flex justify-end gap-2 pt-4">
|
|
22
|
+
<BaseButton
|
|
23
|
+
class="bg-yellow-600 hover:bg-yellow-700"
|
|
24
|
+
type="button"
|
|
25
|
+
@click="store.handleToggleModal"
|
|
26
|
+
>Cancel</BaseButton>
|
|
27
|
+
<BaseButton type="submit" class="bg-red-600 hover:bg-red-700">Delete</BaseButton>
|
|
28
|
+
</div>
|
|
29
|
+
</form>
|
|
30
|
+
</BaseModal>
|
|
31
|
+
</template>
|
|
32
|
+
|
|
33
|
+
<script setup>
|
|
34
|
+
import { use${Name}Mutations } from '@/modules/${name}/queries/use${Name}Mutations'
|
|
35
|
+
import { use${Name}Store } from '@/modules/${name}/stores/${name}Store'
|
|
36
|
+
|
|
37
|
+
const store = use${Name}Store()
|
|
38
|
+
|
|
39
|
+
const { remove } = use${Name}Mutations(store.moduleName, {
|
|
40
|
+
onSuccess() {
|
|
41
|
+
store.handleToggleModal() // ✅ close modal
|
|
42
|
+
},
|
|
43
|
+
onError: (error) => {
|
|
44
|
+
console.log('Custom error handling', error)
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
const handleSubmit = async () => {
|
|
49
|
+
await remove.mutateAsync(store.item.id)
|
|
50
|
+
}
|
|
51
|
+
</script>
|
|
52
|
+
`;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export default ({ name, Name }) => `<template>
|
|
2
|
+
<BaseModal
|
|
3
|
+
:isVisible="store.isEditModal"
|
|
4
|
+
:title="\`Edit \${store.moduleName}\`"
|
|
5
|
+
:maxWidth="\`\${store.modalWidth}\`"
|
|
6
|
+
@close="store.handleToggleModal"
|
|
7
|
+
>
|
|
8
|
+
<form @submit.prevent="handleSubmit" class="space-y-4">
|
|
9
|
+
<!-- ${Name} Name -->
|
|
10
|
+
<div>
|
|
11
|
+
<BaseLabel for="name">Name</BaseLabel>
|
|
12
|
+
<BaseInput
|
|
13
|
+
id="name"
|
|
14
|
+
v-model="formData.name"
|
|
15
|
+
placeholder="Eg: Example Name"
|
|
16
|
+
/>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<!-- Actions -->
|
|
20
|
+
<div class="flex justify-end gap-2 pt-4">
|
|
21
|
+
<BaseButton
|
|
22
|
+
class="bg-yellow-600 hover:bg-yellow-700"
|
|
23
|
+
type="button"
|
|
24
|
+
@click="store.handleToggleModal"
|
|
25
|
+
>Cancel</BaseButton>
|
|
26
|
+
<BaseButton type="submit">Save</BaseButton>
|
|
27
|
+
</div>
|
|
28
|
+
</form>
|
|
29
|
+
</BaseModal>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<script setup>
|
|
33
|
+
import { ref, watch } from 'vue'
|
|
34
|
+
import { use${Name}Mutations } from '@/modules/${name}/queries/use${Name}Mutations'
|
|
35
|
+
import { use${Name}Store } from '@/modules/${name}/stores/${name}Store'
|
|
36
|
+
|
|
37
|
+
const store = use${Name}Store()
|
|
38
|
+
|
|
39
|
+
const formData = ref({
|
|
40
|
+
name: '',
|
|
41
|
+
id: '',
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
// Prefill form when selected item changes
|
|
45
|
+
watch(
|
|
46
|
+
() => store.item,
|
|
47
|
+
(newItem) => {
|
|
48
|
+
if (newItem) {
|
|
49
|
+
formData.value.name = newItem.name || ''
|
|
50
|
+
formData.value.id = newItem.id || ''
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{ immediate: true }
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
const { update } = use${Name}Mutations(store.moduleName, {
|
|
57
|
+
onSuccess() {
|
|
58
|
+
store.handleToggleModal() // ✅ close modal
|
|
59
|
+
},
|
|
60
|
+
onError: (error) => {
|
|
61
|
+
console.log('Custom error handling', error)
|
|
62
|
+
},
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
const handleSubmit = async () => {
|
|
66
|
+
await update.mutateAsync(formData.value)
|
|
67
|
+
}
|
|
68
|
+
</script>
|
|
69
|
+
`;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export default ({ name, Name }) => `<template>
|
|
2
|
+
<BaseModal
|
|
3
|
+
:isVisible="store.isViewModal"
|
|
4
|
+
:title="\`View \${store.moduleName} Details\`"
|
|
5
|
+
:maxWidth="\`\${store.modalWidth}\`"
|
|
6
|
+
@close="store.handleToggleModal"
|
|
7
|
+
>
|
|
8
|
+
<div class="space-y-2">
|
|
9
|
+
<p class="text-lg">
|
|
10
|
+
<strong>ID:</strong>
|
|
11
|
+
{{ store.item.id }}
|
|
12
|
+
</p>
|
|
13
|
+
<p class="text-lg">
|
|
14
|
+
<strong>Name:</strong>
|
|
15
|
+
{{ store.item.name }}
|
|
16
|
+
</p>
|
|
17
|
+
<p class="text-lg">
|
|
18
|
+
<strong>Created At:</strong>
|
|
19
|
+
{{ store.item.created_at }}
|
|
20
|
+
</p>
|
|
21
|
+
<p class="text-lg">
|
|
22
|
+
<strong>Updated At:</strong>
|
|
23
|
+
{{ store.item.updated_at }}
|
|
24
|
+
</p>
|
|
25
|
+
</div>
|
|
26
|
+
</BaseModal>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
<script setup>
|
|
30
|
+
import { use${Name}Store } from '@/modules/${name}/stores/${name}Store'
|
|
31
|
+
const store = use${Name}Store()
|
|
32
|
+
</script>
|
|
33
|
+
`;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export default ({
|
|
2
|
+
name,
|
|
3
|
+
Name,
|
|
4
|
+
}) => `import { useMutation, useQueryClient } from '@tanstack/vue-query'
|
|
5
|
+
import { submitData, updateData, deleteItem } from '../services/${name}Service'
|
|
6
|
+
import { toast } from '@/shared/config/toastConfig'
|
|
7
|
+
|
|
8
|
+
export function use${Name}Mutations(moduleName, options = {}) {
|
|
9
|
+
const queryClient = useQueryClient()
|
|
10
|
+
|
|
11
|
+
const handleSuccess = (data, variables) => {
|
|
12
|
+
toast.success(\`\${moduleName} operation successful\`)
|
|
13
|
+
queryClient.invalidateQueries(['${name}s'])
|
|
14
|
+
options.onSuccess?.(data, variables) // ✅ generic callback
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const handleError = (error) => {
|
|
18
|
+
console.error(error)
|
|
19
|
+
toast.error(\`Request Failed: \${error?.message || 'Unknown error'}\`)
|
|
20
|
+
options.onError?.(error)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const submit = useMutation({ mutationFn: submitData, onSuccess: handleSuccess, onError: handleError })
|
|
24
|
+
const update = useMutation({ mutationFn: updateData, onSuccess: handleSuccess, onError: handleError })
|
|
25
|
+
const remove = useMutation({ mutationFn: deleteItem, onSuccess: handleSuccess, onError: handleError })
|
|
26
|
+
|
|
27
|
+
return { submit, update, remove }
|
|
28
|
+
}
|
|
29
|
+
`;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export default ({ name, Name }) => `<template>
|
|
2
|
+
<div class="min-h-screen bg-gray-50">
|
|
3
|
+
<div class="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
|
4
|
+
<PageTitle>{{ store.moduleName }} List</PageTitle>
|
|
5
|
+
<BaseButton @click="store.handleToggleModal('add')">
|
|
6
|
+
Add {{ store.moduleName }}
|
|
7
|
+
</BaseButton>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div class="rounded-lg bg-white shadow-sm">
|
|
11
|
+
<BaseTable
|
|
12
|
+
v-if="!isLoading"
|
|
13
|
+
:columns="columns"
|
|
14
|
+
:rows="rows"
|
|
15
|
+
show-actions
|
|
16
|
+
@view="onView"
|
|
17
|
+
@edit="onEdit"
|
|
18
|
+
@delete="onDelete"
|
|
19
|
+
/>
|
|
20
|
+
|
|
21
|
+
<AddModal />
|
|
22
|
+
<EditModal />
|
|
23
|
+
<ViewModal />
|
|
24
|
+
<DeleteModal />
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
<script setup>
|
|
30
|
+
import { computed, defineAsyncComponent } from 'vue'
|
|
31
|
+
import { use${Name}sQuery } from '../queries/use${Name}sQuery'
|
|
32
|
+
import { use${Name}Store } from '../stores/${name}Store'
|
|
33
|
+
|
|
34
|
+
const ViewModal = defineAsyncComponent(() => import('./components/ViewModal.vue'))
|
|
35
|
+
const AddModal = defineAsyncComponent(() => import('./components/AddModal.vue'))
|
|
36
|
+
const EditModal = defineAsyncComponent(() => import('./components/EditModal.vue'))
|
|
37
|
+
const DeleteModal = defineAsyncComponent(() => import('./components/DeleteModal.vue'))
|
|
38
|
+
|
|
39
|
+
const store = use${Name}Store()
|
|
40
|
+
const { data, isLoading } = use${Name}sQuery()
|
|
41
|
+
|
|
42
|
+
const columns = [
|
|
43
|
+
{ key: 'sl', label: 'SL' },
|
|
44
|
+
{ key: 'name', label: '${Name}' },
|
|
45
|
+
{ key: 'created_at', label: 'Created At' },
|
|
46
|
+
{ key: 'updated_at', label: 'Updated At' }
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
const rows = computed(() => data.value?.data?.data ?? [])
|
|
50
|
+
|
|
51
|
+
function onView(row) {
|
|
52
|
+
store.handleToggleModal('view', row)
|
|
53
|
+
}
|
|
54
|
+
function onEdit(row) {
|
|
55
|
+
store.handleToggleModal('edit', row)
|
|
56
|
+
}
|
|
57
|
+
function onDelete(row) {
|
|
58
|
+
store.handleToggleModal('delete', row)
|
|
59
|
+
}
|
|
60
|
+
</script>
|
|
61
|
+
`;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export default ({
|
|
2
|
+
name,
|
|
3
|
+
Name,
|
|
4
|
+
}) => `import { useQuery } from '@tanstack/vue-query'
|
|
5
|
+
import { fetchAll } from '../services/${name}Service'
|
|
6
|
+
|
|
7
|
+
export function use${Name}sQuery(params = {}) {
|
|
8
|
+
return useQuery({
|
|
9
|
+
queryKey: ['${name}s', params],
|
|
10
|
+
queryFn: () => fetchAll(params),
|
|
11
|
+
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
12
|
+
cacheTime: 1000 * 60 * 60, // 1 hour
|
|
13
|
+
keepPreviousData: true,
|
|
14
|
+
meta: {
|
|
15
|
+
persist: true, // ✅ persisted
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
`;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export default ({
|
|
2
|
+
name,
|
|
3
|
+
Name,
|
|
4
|
+
}) => `import ${Name}Page from './pages/${Name}Page.vue'
|
|
5
|
+
import DashboardLayout from '@/shared/layouts/DashboardLayout.vue'
|
|
6
|
+
|
|
7
|
+
export default [
|
|
8
|
+
{
|
|
9
|
+
path: '/${name}s',
|
|
10
|
+
component: DashboardLayout,
|
|
11
|
+
meta: { requiresAuth: true },
|
|
12
|
+
children: [
|
|
13
|
+
{
|
|
14
|
+
path: '',
|
|
15
|
+
name: '${Name}List',
|
|
16
|
+
component: ${Name}Page,
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
},
|
|
20
|
+
]
|
|
21
|
+
`;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export default ({
|
|
2
|
+
name,
|
|
3
|
+
Name,
|
|
4
|
+
}) => `import { useApi } from '@/shared/composables/useApi'
|
|
5
|
+
|
|
6
|
+
const BASE_URL = '/${name}s'
|
|
7
|
+
|
|
8
|
+
const response = (api) => ({
|
|
9
|
+
data: api.data.value,
|
|
10
|
+
error: api.error.value,
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
export async function fetchAll() {
|
|
14
|
+
const api = useApi()
|
|
15
|
+
await api.sendRequest(BASE_URL)
|
|
16
|
+
return response(api)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function submitData(payload) {
|
|
20
|
+
const api = useApi()
|
|
21
|
+
await api.sendRequest(BASE_URL, 'POST', payload)
|
|
22
|
+
if (api.error.value) {
|
|
23
|
+
throw api.error.value // 🚨 so useMutation.onError triggers
|
|
24
|
+
}
|
|
25
|
+
return api.data.value
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function updateData(payload) {
|
|
29
|
+
const api = useApi()
|
|
30
|
+
await api.sendRequest(\`\${BASE_URL}/\${payload.id}\`, 'POST', payload, {
|
|
31
|
+
headers: { 'X-HTTP-Method-Override': 'PUT' }
|
|
32
|
+
})
|
|
33
|
+
if (api.error.value) throw api.error.value
|
|
34
|
+
return api.data.value
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function deleteItem(id) {
|
|
38
|
+
const api = useApi()
|
|
39
|
+
await api.sendRequest(\`\${BASE_URL}/\${id}\`, 'DELETE')
|
|
40
|
+
if (api.error.value) throw api.error.value
|
|
41
|
+
return api.data.value
|
|
42
|
+
}
|
|
43
|
+
`;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export default ({ name, Name }) => `import { defineStore } from 'pinia'
|
|
2
|
+
import { useModalHelpers } from '@/shared/composables/useModalHelpers'
|
|
3
|
+
|
|
4
|
+
export const use${Name}Store = defineStore('${name}', () => {
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
item,
|
|
8
|
+
isModal,
|
|
9
|
+
isViewModal,
|
|
10
|
+
isEditModal,
|
|
11
|
+
isDeleteModal,
|
|
12
|
+
handleToggleModal,
|
|
13
|
+
handleReset,
|
|
14
|
+
} = useModalHelpers()
|
|
15
|
+
|
|
16
|
+
const moduleName = '${Name}'
|
|
17
|
+
const modalWidth = '30vw'
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
item,
|
|
21
|
+
isModal,
|
|
22
|
+
isViewModal,
|
|
23
|
+
isEditModal,
|
|
24
|
+
isDeleteModal,
|
|
25
|
+
moduleName,
|
|
26
|
+
modalWidth,
|
|
27
|
+
handleToggleModal,
|
|
28
|
+
handleReset,
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
`;
|
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vue-ready-modular",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Vue.js module generator",
|
|
5
|
+
"main": "lib/generator.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"vue-modular": "./bin/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "echo \"No tests yet\""
|
|
12
|
+
},
|
|
13
|
+
"keywords": ["vue", "generator", "module", "cli"],
|
|
14
|
+
"author": "Your Name",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"path": "^0.12.7"
|
|
18
|
+
}
|
|
19
|
+
}
|