コミット
f462fe74fd

+ 18
- 18
package-lock.json ファイルの表示

433
       }
433
       }
434
     },
434
     },
435
     "node_modules/@jridgewell/resolve-uri": {
435
     "node_modules/@jridgewell/resolve-uri": {
436
-      "version": "3.0.8",
437
-      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.8.tgz",
438
-      "integrity": "sha512-YK5G9LaddzGbcucK4c8h5tWFmMPBvRZ/uyWmN1/SbBdIvqGUdWGkJ5BAaccgs6XbzVLsqbPJrBSFwKv3kT9i7w==",
436
+      "version": "3.1.0",
437
+      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
438
+      "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
439
       "dev": true,
439
       "dev": true,
440
       "peer": true,
440
       "peer": true,
441
       "engines": {
441
       "engines": {
694
       }
694
       }
695
     },
695
     },
696
     "node_modules/caniuse-lite": {
696
     "node_modules/caniuse-lite": {
697
-      "version": "1.0.30001361",
698
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001361.tgz",
699
-      "integrity": "sha512-ybhCrjNtkFji1/Wto6SSJKkWk6kZgVQsDq5QI83SafsF6FXv2JB4df9eEdH6g8sdGgqTXrFLjAxqBGgYoU3azQ==",
697
+      "version": "1.0.30001363",
698
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001363.tgz",
699
+      "integrity": "sha512-HpQhpzTGGPVMnCjIomjt+jvyUu8vNFo3TaDiZ/RcoTrlOq/5+tC8zHdsbgFB6MxmaY+jCpsH09aD80Bb4Ow3Sg==",
700
       "dev": true,
700
       "dev": true,
701
       "funding": [
701
       "funding": [
702
         {
702
         {
867
       }
867
       }
868
     },
868
     },
869
     "node_modules/electron-to-chromium": {
869
     "node_modules/electron-to-chromium": {
870
-      "version": "1.4.176",
871
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.176.tgz",
872
-      "integrity": "sha512-92JdgyRlcNDwuy75MjuFSb3clt6DGJ2IXSpg0MCjKd3JV9eSmuUAIyWiGAp/EtT0z2D4rqbYqThQLV90maH3Zw==",
870
+      "version": "1.4.180",
871
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.180.tgz",
872
+      "integrity": "sha512-7at5ash3FD9U5gPa3/wPr6OdiZd/zBjvDZaaHBpcqFOFUhZiWnb7stkqk8xUFL9H9nk7Yok5vCCNK8wyC/+f8A==",
873
       "dev": true,
873
       "dev": true,
874
       "peer": true
874
       "peer": true
875
     },
875
     },
2392
       }
2392
       }
2393
     },
2393
     },
2394
     "@jridgewell/resolve-uri": {
2394
     "@jridgewell/resolve-uri": {
2395
-      "version": "3.0.8",
2396
-      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.8.tgz",
2397
-      "integrity": "sha512-YK5G9LaddzGbcucK4c8h5tWFmMPBvRZ/uyWmN1/SbBdIvqGUdWGkJ5BAaccgs6XbzVLsqbPJrBSFwKv3kT9i7w==",
2395
+      "version": "3.1.0",
2396
+      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
2397
+      "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
2398
       "dev": true,
2398
       "dev": true,
2399
       "peer": true
2399
       "peer": true
2400
     },
2400
     },
2607
       }
2607
       }
2608
     },
2608
     },
2609
     "caniuse-lite": {
2609
     "caniuse-lite": {
2610
-      "version": "1.0.30001361",
2611
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001361.tgz",
2612
-      "integrity": "sha512-ybhCrjNtkFji1/Wto6SSJKkWk6kZgVQsDq5QI83SafsF6FXv2JB4df9eEdH6g8sdGgqTXrFLjAxqBGgYoU3azQ==",
2610
+      "version": "1.0.30001363",
2611
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001363.tgz",
2612
+      "integrity": "sha512-HpQhpzTGGPVMnCjIomjt+jvyUu8vNFo3TaDiZ/RcoTrlOq/5+tC8zHdsbgFB6MxmaY+jCpsH09aD80Bb4Ow3Sg==",
2613
       "dev": true,
2613
       "dev": true,
2614
       "peer": true
2614
       "peer": true
2615
     },
2615
     },
2733
       }
2733
       }
2734
     },
2734
     },
2735
     "electron-to-chromium": {
2735
     "electron-to-chromium": {
2736
-      "version": "1.4.176",
2737
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.176.tgz",
2738
-      "integrity": "sha512-92JdgyRlcNDwuy75MjuFSb3clt6DGJ2IXSpg0MCjKd3JV9eSmuUAIyWiGAp/EtT0z2D4rqbYqThQLV90maH3Zw==",
2736
+      "version": "1.4.180",
2737
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.180.tgz",
2738
+      "integrity": "sha512-7at5ash3FD9U5gPa3/wPr6OdiZd/zBjvDZaaHBpcqFOFUhZiWnb7stkqk8xUFL9H9nk7Yok5vCCNK8wyC/+f8A==",
2739
       "dev": true,
2739
       "dev": true,
2740
       "peer": true
2740
       "peer": true
2741
     },
2741
     },

+ 30
- 6
resources/js/pages/Purchases/Components/Cart.vue ファイルの表示

1
 <script setup>
1
 <script setup>
2
+import { ref } from 'vue'
2
 import { IDRCurrencyFormat } from '@/utils/currencyFormat'
3
 import { IDRCurrencyFormat } from '@/utils/currencyFormat'
4
+import AppInputNumber from '@/components/AppInputNumber.vue'
5
+import AppInputText from '@/components/AppInputText.vue'
3
 
6
 
4
 defineProps({
7
 defineProps({
5
   title: String,
8
   title: String,
6
-  ppn: {
7
-    required: true,
8
-    type: Number,
9
-  },
10
   headerTable: {
9
   headerTable: {
11
     required: true,
10
     required: true,
12
     type: Array,
11
     type: Array,
17
   },
16
   },
18
   checkedPpn: Boolean,
17
   checkedPpn: Boolean,
19
 })
18
 })
19
+
20
+const editingRows = ref([])
20
 </script>
21
 </script>
21
 
22
 
22
 <template>
23
 <template>
23
   <DataTable
24
   <DataTable
24
     responsiveLayout="scroll"
25
     responsiveLayout="scroll"
25
     columnResizeMode="expand"
26
     columnResizeMode="expand"
27
+    edit-mode="row"
28
+    data-key="number"
26
     :value="valueTable"
29
     :value="valueTable"
27
     :rowHover="true"
30
     :rowHover="true"
28
     :stripedRows="true"
31
     :stripedRows="true"
32
+    v-model:editing-rows="editingRows"
33
+    @row-edit-save="$emit('edit', $event)"
29
   >
34
   >
30
     <template #header>
35
     <template #header>
31
       <h2 class="text-2xl font-bold">{{ title }}</h2>
36
       <h2 class="text-2xl font-bold">{{ title }}</h2>
32
 
37
 
33
       <div class="field-checkbox flex justify-content-end gap-2">
38
       <div class="field-checkbox flex justify-content-end gap-2">
34
         <label class="text-sm" for="ppn">
39
         <label class="text-sm" for="ppn">
35
-          Semua produk dikenakan PPN {{ ppn }}%
40
+          Semua produk dikenakan PPN {{ $page.props.ppn }}%
36
         </label>
41
         </label>
37
         <input
42
         <input
38
           type="checkbox"
43
           type="checkbox"
45
 
50
 
46
     <Column
51
     <Column
47
       v-for="value in headerTable"
52
       v-for="value in headerTable"
53
+      :key="value.field"
48
       :field="value.field"
54
       :field="value.field"
49
       :header="value.header"
55
       :header="value.header"
50
-      :key="value.field"
51
     >
56
     >
52
       <template #body="{ data, field }">
57
       <template #body="{ data, field }">
53
         <template v-if="field === 'price'">
58
         <template v-if="field === 'price'">
56
 
61
 
57
         <template v-else> {{ data[field] }} </template>
62
         <template v-else> {{ data[field] }} </template>
58
       </template>
63
       </template>
64
+
65
+      <template #editor="{ data, field }">
66
+        <AppInputNumber
67
+          v-if="field === 'price'"
68
+          label="Harga"
69
+          placeholder="harga"
70
+          v-model="data[field]"
71
+        />
72
+
73
+        <AppInputText
74
+          v-if="field === 'qty'"
75
+          label="Kuantitas"
76
+          placeholder="kuantitas"
77
+          type="number"
78
+          v-model="data[field]"
79
+        />
80
+      </template>
59
     </Column>
81
     </Column>
60
 
82
 
83
+    <Column :row-editor="true" />
84
+
61
     <Column>
85
     <Column>
62
       <template #body="{ index }">
86
       <template #body="{ index }">
63
         <Button
87
         <Button

+ 1
- 1
resources/js/pages/Purchases/Components/Details.vue ファイルの表示

64
         <div class="col-12">
64
         <div class="col-12">
65
           <div class="grid">
65
           <div class="grid">
66
             <div v-if="price" class="col">
66
             <div v-if="price" class="col">
67
-              <h3 class="text-base">Harga</h3>
67
+              <h3 class="text-base">Total Harga</h3>
68
               <span>{{ IDRCurrencyFormat(price) }}</span>
68
               <span>{{ IDRCurrencyFormat(price) }}</span>
69
             </div>
69
             </div>
70
           </div>
70
           </div>

+ 8
- 1
resources/js/pages/Purchases/Composables/useProductCart.js ファイルの表示

1
 import FormValidationError from '@/utils/FormValidationError'
1
 import FormValidationError from '@/utils/FormValidationError'
2
 import { reactive } from 'vue'
2
 import { reactive } from 'vue'
3
 
3
 
4
-export function useProductCart(form) {
4
+export function useProductCart(form, initialProducts) {
5
   const productCart = reactive([])
5
   const productCart = reactive([])
6
 
6
 
7
   const productValidation = () => {
7
   const productValidation = () => {
54
     return productPrices.reduce((prev, current) => prev + current, 0)
54
     return productPrices.reduce((prev, current) => prev + current, 0)
55
   }
55
   }
56
 
56
 
57
+  const onEditProduct = (event) => {
58
+    const { newData, index } = event
59
+
60
+    productCart[index] = newData
61
+  }
62
+
57
   return {
63
   return {
58
     productCart,
64
     productCart,
59
     onAddProduct,
65
     onAddProduct,
60
     onDeleteProduct,
66
     onDeleteProduct,
67
+    onEditProduct,
61
     onClearProduct,
68
     onClearProduct,
62
     totalProductPrice,
69
     totalProductPrice,
63
   }
70
   }

+ 2
- 1
resources/js/pages/Purchases/Create.vue ファイルの表示

57
   productCart,
57
   productCart,
58
   onAddProduct,
58
   onAddProduct,
59
   onDeleteProduct,
59
   onDeleteProduct,
60
+  onEditProduct,
60
   onClearProduct,
61
   onClearProduct,
61
   totalProductPrice,
62
   totalProductPrice,
62
 } = useProductCart(form)
63
 } = useProductCart(form)
208
           <div class="col-12">
209
           <div class="col-12">
209
             <Cart
210
             <Cart
210
               title="Keranjang Produk"
211
               title="Keranjang Produk"
211
-              :ppn="ppn"
212
               :value-table="productCart"
212
               :value-table="productCart"
213
               :header-table="cartTable"
213
               :header-table="cartTable"
214
               v-model:checked-ppn="form.checkedPpn"
214
               v-model:checked-ppn="form.checkedPpn"
215
               @delete="onDeleteProduct"
215
               @delete="onDeleteProduct"
216
+              @edit="onEditProduct"
216
             />
217
             />
217
           </div>
218
           </div>
218
         </div>
219
         </div>

+ 7
- 3
resources/js/vue.js ファイルの表示

1
 import './bootstrap'
1
 import './bootstrap'
2
-import '../css/app.scss'
3
 import { createApp, h } from 'vue'
2
 import { createApp, h } from 'vue'
4
 import { createInertiaApp } from '@inertiajs/inertia-vue3'
3
 import { createInertiaApp } from '@inertiajs/inertia-vue3'
5
 import { InertiaProgress } from '@inertiajs/progress'
4
 import { InertiaProgress } from '@inertiajs/progress'
6
 import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'
5
 import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'
7
 
6
 
7
+import 'primeflex/primeflex.css'
8
 import 'primevue/resources/themes/mdc-light-indigo/theme.css'
8
 import 'primevue/resources/themes/mdc-light-indigo/theme.css'
9
 import 'primevue/resources/primevue.min.css'
9
 import 'primevue/resources/primevue.min.css'
10
-import 'primeflex/primeflex.css'
11
 import 'primeicons/primeicons.css'
10
 import 'primeicons/primeicons.css'
11
+import '../css/app.scss'
12
 import PrimeVue from 'primevue/config'
12
 import PrimeVue from 'primevue/config'
13
 import StyleClass from 'primevue/styleclass'
13
 import StyleClass from 'primevue/styleclass'
14
 import AutoComplete from 'primevue/autocomplete'
14
 import AutoComplete from 'primevue/autocomplete'
18
 import Card from 'primevue/card'
18
 import Card from 'primevue/card'
19
 import Chart from 'primevue/chart'
19
 import Chart from 'primevue/chart'
20
 import Column from 'primevue/column'
20
 import Column from 'primevue/column'
21
+import ColumnGroup from 'primevue/columngroup'
21
 import ConfirmationService from 'primevue/confirmationservice'
22
 import ConfirmationService from 'primevue/confirmationservice'
22
 import ConfirmDialog from 'primevue/confirmdialog'
23
 import ConfirmDialog from 'primevue/confirmdialog'
23
 import DataTable from 'primevue/datatable'
24
 import DataTable from 'primevue/datatable'
30
 import InputText from 'primevue/inputtext'
31
 import InputText from 'primevue/inputtext'
31
 import Message from 'primevue/message'
32
 import Message from 'primevue/message'
32
 import Password from 'primevue/password'
33
 import Password from 'primevue/password'
34
+import Row from 'primevue/row'
33
 import TabView from 'primevue/tabview'
35
 import TabView from 'primevue/tabview'
34
 import TabPanel from 'primevue/tabpanel'
36
 import TabPanel from 'primevue/tabpanel'
35
 import Tooltip from 'primevue/tooltip'
37
 import Tooltip from 'primevue/tooltip'
43
     ),
45
     ),
44
   setup({ el, App, props, plugin }) {
46
   setup({ el, App, props, plugin }) {
45
     createApp({ render: () => h(App, props) })
47
     createApp({ render: () => h(App, props) })
48
+      .mixin({ methods: { route } })
46
       .use(plugin)
49
       .use(plugin)
47
       .use(PrimeVue, {
50
       .use(PrimeVue, {
48
         ripple: true,
51
         ripple: true,
49
       })
52
       })
50
       .use(ConfirmationService)
53
       .use(ConfirmationService)
51
       .use(DialogService)
54
       .use(DialogService)
52
-      .mixin({ methods: { route } })
53
       .directive('styleclass', StyleClass)
55
       .directive('styleclass', StyleClass)
54
       .directive('tooltip', Tooltip)
56
       .directive('tooltip', Tooltip)
55
       .component('AutoComplete', AutoComplete)
57
       .component('AutoComplete', AutoComplete)
59
       .component('Calendar', Calendar)
61
       .component('Calendar', Calendar)
60
       .component('Chart', Chart)
62
       .component('Chart', Chart)
61
       .component('Column', Column)
63
       .component('Column', Column)
64
+      .component('ColumnGroup', ColumnGroup)
62
       .component('ConfirmDialog', ConfirmDialog)
65
       .component('ConfirmDialog', ConfirmDialog)
63
       .component('DataTable', DataTable)
66
       .component('DataTable', DataTable)
64
       .component('Divider', Divider)
67
       .component('Divider', Divider)
69
       .component('InputText', InputText)
72
       .component('InputText', InputText)
70
       .component('Message', Message)
73
       .component('Message', Message)
71
       .component('Password', Password)
74
       .component('Password', Password)
75
+      .component('Row', Row)
72
       .component('TabView', TabView)
76
       .component('TabView', TabView)
73
       .component('TabPanel', TabPanel)
77
       .component('TabPanel', TabPanel)
74
       .mount(el)
78
       .mount(el)