diff --git a/addon/components/customer-form-panel.hbs b/addon/components/customer-form-panel.hbs index 8e8f99c7..072c66cb 100644 --- a/addon/components/customer-form-panel.hbs +++ b/addon/components/customer-form-panel.hbs @@ -94,6 +94,63 @@ {{#let (cannot this.savePermission) as |unauthorized|}} + +
+ + +
+
+ {{this.user.name}} +
+
+
{{model.name}}
+
+ + {{n-a model.email}} +
+
+ + {{n-a model.phone}} +
+
+
+
+
+
+ {{#if this.customer.user}} +
+ + + + + + + + + + + +
+ {{/if}} +
+
diff --git a/addon/components/customer-form-panel.js b/addon/components/customer-form-panel.js index 087e7caf..24fc5ef3 100644 --- a/addon/components/customer-form-panel.js +++ b/addon/components/customer-form-panel.js @@ -14,6 +14,8 @@ export default class CustomerFormPanelComponent extends Component { @service notifications; @service hostRouter; @service contextPanel; + @service modalsManager; + @service universe; /** * Overlay context. @@ -28,6 +30,62 @@ export default class CustomerFormPanelComponent extends Component { */ @tracked savePermission; + /** + * Action to create a new user quickly + * + * @memberof DriverFormPanelComponent + */ + userAccountActionButtons = [ + { + text: 'Create new user', + icon: 'user-plus', + size: 'xs', + permission: 'iam create user', + onClick: () => { + const user = this.store.createRecord('user', { + status: 'pending', + type: 'user', + }); + + this.modalsManager.show('modals/user-form', { + title: 'Create a new user', + user, + formPermission: 'iam create user', + uploadNewPhoto: (file) => { + this.fetch.uploadFile.perform( + file, + { + path: `uploads/${this.currentUser.companyId}/users/${user.slug}`, + key_uuid: user.id, + key_type: 'user', + type: 'user_photo', + }, + (uploadedFile) => { + user.setProperties({ + avatar_uuid: uploadedFile.id, + avatar_url: uploadedFile.url, + avatar: uploadedFile, + }); + } + ); + }, + confirm: async (modal) => { + modal.startLoading(); + + try { + await user.save(); + this.notifications.success('New user created successfully!'); + modal.done(); + } catch (error) { + this.notifications.serverError(error); + modal.stopLoading(); + } + }, + }); + }, + }, + ]; + /** * Constructs the component and applies initial state. */ diff --git a/addon/components/customer-panel/details.hbs b/addon/components/customer-panel/details.hbs index 81f58260..578c2ecb 100644 --- a/addon/components/customer-panel/details.hbs +++ b/addon/components/customer-panel/details.hbs @@ -1,40 +1,52 @@
- -
-
-
{{t "fleet-ops.common.name"}}
-
{{n-a @customer.name}}
+
+ +
+
+
{{t "fleet-ops.common.name"}}
+
{{n-a @customer.name}}
+
+
+
{{t "fleet-ops.common.email"}}
+ {{n-a @customer.email}} +
+
+
{{t "fleet-ops.common.phone"}}
+ {{n-a @customer.phone}} +
- -
-
{{t "fleet-ops.common.title"}}
-
{{n-a @customer.title}}
+ + +
+
+
{{t "fleet-ops.common.name"}}
+
{{n-a @customer.name}}
+
+
+
{{t "fleet-ops.common.title"}}
+
{{n-a @customer.title}}
+
+
+
{{t "fleet-ops.common.email"}}
+ {{n-a @customer.email}} +
+
+
{{t "fleet-ops.common.email"}}
+ {{n-a @customer.phone}} +
+
+
{{t "fleet-ops.common.internal-id"}}
+
{{n-a @customer.internal_id}}
+
+
+
{{t "fleet-ops.common.type"}}
+
{{smart-humanize @customer.type}}
+
+
+
{{t "fleet-ops.common.address"}}
+
{{n-a @customer.address}}
+
- -
-
{{t "fleet-ops.common.email"}}
- {{n-a @customer.email}} -
- -
-
{{t "fleet-ops.common.email"}}
- {{n-a @customer.phone}} -
- -
-
{{t "fleet-ops.common.internal-id"}}
-
{{n-a @customer.internal_id}}
-
- -
-
{{t "fleet-ops.common.type"}}
-
{{smart-humanize @customer.type}}
-
- -
-
{{t "fleet-ops.common.address"}}
-
{{n-a @customer.address}}
-
-
-
+ +
\ No newline at end of file diff --git a/addon/components/customer/orders.hbs b/addon/components/customer/orders.hbs index debd6629..a0a90a47 100644 --- a/addon/components/customer/orders.hbs +++ b/addon/components/customer/orders.hbs @@ -1,7 +1,7 @@
{{#let (and this.newOrder this.map) as |isCreatingOrder|}}
-
+
diff --git a/addon/components/driver-form-panel.hbs b/addon/components/driver-form-panel.hbs index 0f9c61de..16a04d95 100644 --- a/addon/components/driver-form-panel.hbs +++ b/addon/components/driver-form-panel.hbs @@ -126,7 +126,14 @@
{{model.name}}
-
{{n-a model.phone}}
+
+ + {{n-a model.email}} +
+
+ + {{n-a model.phone}} +
@@ -134,7 +141,7 @@
{{#if this.driver.user}}
- + diff --git a/addon/styles/fleetops-engine.css b/addon/styles/fleetops-engine.css index 93112a9d..98d6bd65 100644 --- a/addon/styles/fleetops-engine.css +++ b/addon/styles/fleetops-engine.css @@ -748,8 +748,8 @@ body[data-theme='dark'] .order-progress-bar > .order-progress-bar-wrapper > .ord bottom: 0; top: 0; right: 0; - width: 40%; - max-width: 40%; + width: 52%; + max-width: 52%; height: 100%; padding: 1rem; } @@ -981,6 +981,37 @@ body[data-theme='light'] .flb--modal.flb--default-modal.finalize-service-quote-p #fleetops-customer-orders-container #fleetops-customer-orders-sidebar { margin-right: 1rem; + width: 50%; +} + +@media (width >= 992px) { + #fleetops-customer-orders-container #fleetops-customer-orders-sidebar { + width: 50%; + } +} + +@media (width >= 1200px) { + #fleetops-customer-orders-container #fleetops-customer-orders-sidebar { + width: 35%; + } +} + +@media (width >= 1400px) { + #fleetops-customer-orders-container #fleetops-customer-orders-sidebar { + width: 30%; + } +} + +@media (width >= 1700px) { + #fleetops-customer-orders-container #fleetops-customer-orders-sidebar { + width: 25%; + } +} + +@media (width >= 1900px) { + #fleetops-customer-orders-container #fleetops-customer-orders-sidebar { + width: 20%; + } } #fleetops-customer-orders-container.collapse-sidebar #fleetops-customer-orders-sidebar { diff --git a/composer.json b/composer.json index 7c5a0058..9a15a755 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "fleetbase/fleetops-api", - "version": "0.5.24", + "version": "0.5.25", "description": "Fleet & Transport Management Extension for Fleetbase", "keywords": [ "fleetbase-extension", diff --git a/extension.json b/extension.json index 5512080c..64a4af9d 100644 --- a/extension.json +++ b/extension.json @@ -1,6 +1,6 @@ { "name": "Fleet-Ops", - "version": "0.5.24", + "version": "0.5.25", "description": "Fleet & Transport Management Extension for Fleetbase", "repository": "https://github.com/fleetbase/fleetops", "license": "AGPL-3.0-or-later", diff --git a/package.json b/package.json index f933ba0d..bde19365 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@fleetbase/fleetops-engine", - "version": "0.5.24", + "version": "0.5.25", "description": "Fleet & Transport Management Extension for Fleetbase", "fleetbase": { "route": "fleet-ops" @@ -50,9 +50,9 @@ "@fortawesome/fontawesome-svg-core": "6.4.0", "@fortawesome/free-brands-svg-icons": "6.4.0", "@fortawesome/free-solid-svg-icons": "6.4.0", - "@stripe/connect-js": "^3.3.10", "@joint/core": "^4.0.1", "@joint/layout-directed-graph": "^4.0.1", + "@stripe/connect-js": "^3.3.10", "@terraformer/spatial": "^2.1.2", "@zestia/ember-dragula": "^12.0.0", "broccoli-funnel": "^3.0.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f6d9c4ad..88bb3490 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,7 +19,7 @@ importers: version: 0.2.37(@ember/test-helpers@3.3.1(@babel/core@7.25.2)(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0))(webpack@5.94.0))(@glimmer/component@1.1.2(@babel/core@7.25.2))(@glimmer/tracking@1.1.2)(ember-resolver@11.0.1(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0)))(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0))(postcss@8.4.47)(rollup@2.79.1)(tracked-built-ins@3.4.0(@babel/core@7.25.2))(webpack@5.94.0) '@fleetbase/fleetops-data': specifier: latest - version: 0.1.18(@ember/string@3.1.1)(@ember/test-helpers@3.3.1(@babel/core@7.25.2)(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0))(webpack@5.94.0))(ember-resolver@11.0.1(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0)))(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0))(eslint@8.57.0)(webpack@5.94.0) + version: 0.1.19(@ember/string@3.1.1)(@ember/test-helpers@3.3.1(@babel/core@7.25.2)(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0))(webpack@5.94.0))(ember-resolver@11.0.1(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0)))(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0))(eslint@8.57.0)(webpack@5.94.0) '@fleetbase/leaflet-routing-machine': specifier: ^3.2.16 version: 3.2.16 @@ -313,6 +313,10 @@ packages: resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@7.26.5': + resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} + engines: {node: '>=6.9.0'} + '@babel/helper-remap-async-to-generator@7.25.0': resolution: {integrity: sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==} engines: {node: '>=6.9.0'} @@ -461,6 +465,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-decorators@7.25.9': + resolution: {integrity: sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-dynamic-import@7.8.3': resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} peerDependencies: @@ -1313,6 +1323,10 @@ packages: resolution: {integrity: sha512-qyN64T1jMHZ99ihlk7VFHCWHYZHLE1DOdHi0J7lmn5waV1DoW7gD8JLi1i7FregzXtKhbDc7shyEmTmWPTs8MQ==} engines: {node: 12.* || 14.* || >= 16} + '@embroider/addon-shim@1.9.0': + resolution: {integrity: sha512-fMzayl/licUL8VRAy4qXROKcYvHwUbV8aTh4m97L5/MRuVpxbcAy92DGGTqx5OBKCSQN3gMg+sUKeE6AviefpQ==} + engines: {node: 12.* || 14.* || >= 16} + '@embroider/addon@0.30.0': resolution: {integrity: sha512-hBgskhX38RMIyHcnUpRt+KbddLMPLVOFdLp4qhv7Vs881SPDwsbo7pir4KpILmnoqcvBMh1MCVY970tYaAyMcQ==} engines: {node: 10.* || >= 12} @@ -1334,6 +1348,10 @@ packages: resolution: {integrity: sha512-wyFQNSqN+RZWg5ckqsk0Qfun433aEd70L6sc16sY4FFf/AzDnolmc0t3eR7lkdyxltYSrO5eqkFN7hW7l/glaw==} engines: {node: 12.* || 14.* || >= 16} + '@embroider/shared-internals@2.9.0': + resolution: {integrity: sha512-8untWEvGy6av/oYibqZWMz/yB+LHsKxEOoUZiLvcpFwWj2Sipc0DcXeTJQZQZ++otNkLCWyDrDhOLrOkgjOPSg==} + engines: {node: 12.* || 14.* || >= 16} + '@embroider/test-setup@3.0.3': resolution: {integrity: sha512-3K5KSyTdnxAkZQill6+TdC/XTRr6226LNwZMsrhRbBM0FFZXw2D8qmJSHPvZLheQx3A1jnF9t1lyrAzrKlg6Yw==} engines: {node: 12.* || 14.* || >= 16} @@ -1394,8 +1412,8 @@ packages: resolution: {integrity: sha512-3AhwP5jhAiuhl0mAeOGkhIGcIZo1OKPJbnWD+HUG+WNsG/Tdx0o1dGfaPpHahl5TNSd8UDEdFqV2gyficO/xnA==} engines: {node: '>= 18'} - '@fleetbase/fleetops-data@0.1.18': - resolution: {integrity: sha512-SBiL992igloYgEGMbUX65uW95nv8k32u2QSoqVm7HrWfhCwMEeHubEOA916otDkBalkHNSE6QgWigaJDMNnW4A==} + '@fleetbase/fleetops-data@0.1.19': + resolution: {integrity: sha512-f/265ud0+nNERmjv7f1GHS34PduF902GAQgsTL1tkf26j7GthScmFI6UuRs5+2IItK+8ZchfRxYBUhPqyiTfbA==} engines: {node: '>= 18'} '@fleetbase/intl-lint@0.0.1': @@ -2564,6 +2582,10 @@ packages: resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} engines: {node: '>= 0.8'} + better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + big.js@5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} @@ -3541,6 +3563,15 @@ packages: supports-color: optional: true + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} engines: {node: '>=0.10.0'} @@ -3564,6 +3595,9 @@ packages: decorator-transforms@2.0.0: resolution: {integrity: sha512-ETfQccGcotK01YJsoB0AGTdUp7kS9jI93mBzrRY5Oyo+bOJfa2UKTSjCNf+iRNwAWBmBKlbiCcyL4tkY4C4dZQ==} + decorator-transforms@2.3.0: + resolution: {integrity: sha512-jo8c1ss9yFPudHuYYcrJ9jpkDZIoi+lOGvt+Uyp9B+dz32i50icRMx9Bfa8hEt7TnX1FyKWKkjV+cUdT/ep2kA==} + deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} @@ -5417,6 +5451,10 @@ packages: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} + is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + is-symbol@1.0.4: resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} engines: {node: '>= 0.4'} @@ -6464,6 +6502,9 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} + pkg-entry-points@1.1.1: + resolution: {integrity: sha512-BhZa7iaPmB4b3vKIACoppyUoYn8/sFs17VJJtzrzPZvEnN2nqrgg911tdL65lA2m1ml6UI3iPeYbZQ4VXpn1mA==} + pkg-up@2.0.0: resolution: {integrity: sha512-fjAPuiws93rm7mPUu21RdBnkeZNrbfCFCwfAhPWY+rR3zG0ubpe5cEReHOw5fIbfmsxEV/g2kSxGTATY3Bpnwg==} engines: {node: '>=4'} @@ -7296,6 +7337,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + send@0.19.0: resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} engines: {node: '>= 0.8.0'} @@ -8441,6 +8487,8 @@ snapshots: '@babel/helper-plugin-utils@7.24.8': {} + '@babel/helper-plugin-utils@7.26.5': {} + '@babel/helper-remap-async-to-generator@7.25.0(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -8612,6 +8660,11 @@ snapshots: '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-decorators@7.25.9(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -9714,6 +9767,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@embroider/addon-shim@1.9.0': + dependencies: + '@embroider/shared-internals': 2.9.0 + broccoli-funnel: 3.0.8 + common-ancestor-path: 1.0.1 + semver: 7.7.1 + transitivePeerDependencies: + - supports-color + '@embroider/addon@0.30.0': dependencies: ember-cli-babel: 7.26.11 @@ -9759,6 +9821,23 @@ snapshots: transitivePeerDependencies: - supports-color + '@embroider/shared-internals@2.9.0': + dependencies: + babel-import-util: 2.1.1 + debug: 4.4.0 + ember-rfc176-data: 0.3.18 + fs-extra: 9.1.0 + is-subdir: 1.2.0 + js-string-escape: 1.0.1 + lodash: 4.17.21 + minimatch: 3.1.2 + pkg-entry-points: 1.1.1 + resolve-package-path: 4.0.3 + semver: 7.7.1 + typescript-memoize: 1.1.1 + transitivePeerDependencies: + - supports-color + '@embroider/test-setup@3.0.3': dependencies: lodash: 4.17.21 @@ -9941,7 +10020,7 @@ snapshots: - webpack-cli - webpack-command - '@fleetbase/fleetops-data@0.1.18(@ember/string@3.1.1)(@ember/test-helpers@3.3.1(@babel/core@7.25.2)(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0))(webpack@5.94.0))(ember-resolver@11.0.1(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0)))(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0))(eslint@8.57.0)(webpack@5.94.0)': + '@fleetbase/fleetops-data@0.1.19(@ember/string@3.1.1)(@ember/test-helpers@3.3.1(@babel/core@7.25.2)(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0))(webpack@5.94.0))(ember-resolver@11.0.1(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0)))(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0))(eslint@8.57.0)(webpack@5.94.0)': dependencies: '@babel/core': 7.25.2 '@fleetbase/ember-core': 0.2.22(@ember/string@3.1.1)(@ember/test-helpers@3.3.1(@babel/core@7.25.2)(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0))(webpack@5.94.0))(ember-resolver@11.0.1(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0)))(ember-source@5.4.1(@babel/core@7.25.2)(@glimmer/component@1.1.2(@babel/core@7.25.2))(rsvp@4.8.5)(webpack@5.94.0))(eslint@8.57.0)(webpack@5.94.0) @@ -11425,6 +11504,10 @@ snapshots: dependencies: safe-buffer: 5.1.2 + better-path-resolve@1.0.0: + dependencies: + is-windows: 1.0.2 + big.js@5.2.2: {} binary-extensions@1.13.1: @@ -12710,6 +12793,10 @@ snapshots: dependencies: ms: 2.1.3 + debug@4.4.0: + dependencies: + ms: 2.1.3 + decamelize-keys@1.1.1: dependencies: decamelize: 1.2.0 @@ -12732,6 +12819,13 @@ snapshots: transitivePeerDependencies: - '@babel/core' + decorator-transforms@2.3.0(@babel/core@7.25.2): + dependencies: + '@babel/plugin-syntax-decorators': 7.25.9(@babel/core@7.25.2) + babel-import-util: 3.0.0 + transitivePeerDependencies: + - '@babel/core' + deep-extend@0.6.0: {} deep-is@0.1.4: {} @@ -15813,6 +15907,10 @@ snapshots: dependencies: has-tostringtag: 1.0.2 + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 + is-symbol@1.0.4: dependencies: has-symbols: 1.0.3 @@ -16856,6 +16954,8 @@ snapshots: dependencies: find-up: 4.1.0 + pkg-entry-points@1.1.1: {} + pkg-up@2.0.0: dependencies: find-up: 2.1.0 @@ -17798,6 +17898,8 @@ snapshots: semver@7.6.3: {} + semver@7.7.1: {} + send@0.19.0: dependencies: debug: 2.6.9 @@ -18618,8 +18720,8 @@ snapshots: tracked-built-ins@3.4.0(@babel/core@7.25.2): dependencies: - '@embroider/addon-shim': 1.8.9 - decorator-transforms: 2.0.0(@babel/core@7.25.2) + '@embroider/addon-shim': 1.9.0 + decorator-transforms: 2.3.0(@babel/core@7.25.2) ember-tracked-storage-polyfill: 1.0.0 transitivePeerDependencies: - '@babel/core' diff --git a/server/src/Expansions/UserExpansion.php b/server/src/Expansions/UserExpansion.php index 536230e4..22be6492 100644 --- a/server/src/Expansions/UserExpansion.php +++ b/server/src/Expansions/UserExpansion.php @@ -58,7 +58,7 @@ public static function customer() { return function () { /** @var \Illuminate\Database\Eloquent\Model $this */ - return $this->hasOne(Contact::class)->where(['type' => 'customer', 'user_uuid' => $this->uuid])->without('user'); + return $this->hasOne(Contact::class, 'user_uuid', 'uuid')->where('type', 'customer')->without('user'); }; } @@ -69,7 +69,7 @@ public static function contact() { return function () { /** @var \Illuminate\Database\Eloquent\Model $this */ - return $this->hasOne(Contact::class)->where('user_uuid', $this->uuid)->without('user'); + return $this->hasOne(Contact::class, 'user_uuid', 'uuid')->without('user'); }; } } diff --git a/server/src/Expansions/UserFilterExpansion.php b/server/src/Expansions/UserFilterExpansion.php index 92a3a3f9..a5264b50 100644 --- a/server/src/Expansions/UserFilterExpansion.php +++ b/server/src/Expansions/UserFilterExpansion.php @@ -43,4 +43,17 @@ public static function doesntHaveContact() }); }; } + + /** + * @return void + */ + public static function doesntHaveCustomer() + { + return function () { + /** @var \Fleetbase\Http\Filter\UserFilter|\Fleetbase\Http\Filter\Filter $this */ + $this->builder->whereDoesntHave('customer', function ($query) { + $query->where('company_uuid', session('company')); + }); + }; + } } diff --git a/server/src/Http/Controllers/Api/v1/ContactController.php b/server/src/Http/Controllers/Api/v1/ContactController.php index c2f06dbe..0063d7d1 100644 --- a/server/src/Http/Controllers/Api/v1/ContactController.php +++ b/server/src/Http/Controllers/Api/v1/ContactController.php @@ -34,7 +34,6 @@ public function create(CreateContactRequest $request) [ 'company_uuid' => session('company'), 'name' => $input['name'], - 'phone' => $input['phone'], 'email' => $input['email'], ], $input diff --git a/server/src/Http/Controllers/Api/v1/TrackingNumberController.php b/server/src/Http/Controllers/Api/v1/TrackingNumberController.php index 8d419cd9..1f39d27d 100644 --- a/server/src/Http/Controllers/Api/v1/TrackingNumberController.php +++ b/server/src/Http/Controllers/Api/v1/TrackingNumberController.php @@ -35,6 +35,9 @@ public function create(CreateTrackingNumberRequest $request) [ 'public_id' => $request->input('owner'), 'company_uuid' => session('company'), + ], + [ + 'with_table' => true, ] ); diff --git a/server/src/Http/Controllers/Internal/v1/ContactController.php b/server/src/Http/Controllers/Internal/v1/ContactController.php index c23d30e5..9ece19ea 100644 --- a/server/src/Http/Controllers/Internal/v1/ContactController.php +++ b/server/src/Http/Controllers/Internal/v1/ContactController.php @@ -45,7 +45,7 @@ public function getAsFacilitator($id) */ public function getAsCustomer($id) { - $contact = Contact::where('uuid', $id)->withTrashed()->first(); + $contact = Contact::where('uuid', $id)->first(); if (!$contact) { return response()->error('Customer not found.'); diff --git a/server/src/Http/Resources/v1/Contact.php b/server/src/Http/Resources/v1/Contact.php index 9bf6b62d..1c2e81dc 100644 --- a/server/src/Http/Resources/v1/Contact.php +++ b/server/src/Http/Resources/v1/Contact.php @@ -35,7 +35,7 @@ public function toArray($request) 'photo_url' => $this->photo_url ?? null, 'place' => $this->whenLoaded('place', fn () => new Place($this->place)), 'places' => $this->whenLoaded('places', fn () => Place::collection($this->places)), - 'user' => $this->whenLoaded('user', fn () => new User($this->user)), + 'user' => $this->when(Http::isInternalRequest(), fn () => new User($this->user)), 'address' => $this->when(Http::isInternalRequest(), data_get($this, 'place.address')), 'address_street' => $this->when(Http::isInternalRequest(), data_get($this, 'place.street1')), 'type' => $this->type ?? null, diff --git a/server/src/Http/Resources/v1/Place.php b/server/src/Http/Resources/v1/Place.php index 67c288bf..ed1fe537 100644 --- a/server/src/Http/Resources/v1/Place.php +++ b/server/src/Http/Resources/v1/Place.php @@ -47,7 +47,7 @@ public function toArray($request) 'phone' => $this->phone ?? null, 'owner' => Resolve::resourceForMorph($this->owner_type, $this->owner_uuid), 'tracking_number' => $this->whenLoaded('trackingNumber', fn () => $this->trackingNumber), - 'type' => $this->type, + 'type' => $this->type ?? 'place', 'meta' => data_get($this, 'meta', []), 'eta' => $this->when($this->eta, $this->eta), 'updated_at' => $this->updated_at, diff --git a/server/src/Models/Contact.php b/server/src/Models/Contact.php index d3ed3841..1b389489 100644 --- a/server/src/Models/Contact.php +++ b/server/src/Models/Contact.php @@ -292,7 +292,7 @@ public static function createUserFromContact(Contact $contact, bool $sendInvite })->whereNull('deleted_at')->first(); if ($existingUser) { // Check if existing user belongs to another contact - $existingUserContact = Contact::where(['user_uuid' => $existingUser->uuid, 'company_uuid' => $contact->company_uuid])->first(); + $existingUserContact = Contact::where(['user_uuid' => $existingUser->uuid, 'company_uuid' => $contact->company_uuid])->whereHas('user')->first(); if ($existingUserContact) { throw new UserAlreadyExistsException('User already exists, try to assigning the user to this contact.', $existingUser); } else { diff --git a/translations/en-us.yaml b/translations/en-us.yaml index be24c4e7..5e0eec21 100644 --- a/translations/en-us.yaml +++ b/translations/en-us.yaml @@ -773,6 +773,9 @@ fleet-ops: new-address: New Address contact-details: Contact Details customer-form-panel: + user-account: User Account + user-account-help-text: Each customer profile needs to be connected to a specific user account. This association is essential for handling the authentication process, ensuring that each customer can securely access and manage their profile and other services. + select-user: Select User success-message: Customer {customerName} saved successfully. view-customer-button: View customer details save-customer: Save Customer @@ -796,6 +799,7 @@ fleet-ops: edit-button: Edit customer cancel-edit-button: Cancel edit customer cancel-new-button: Cancel new customer + user-account: User Account display-panel: no-address: No {type} address! no-address-message: No address!