Replace CRA SW with Vite SW and resolve PWA installation.
@@ -1,6 +1,6 @@
|
||||
GENERATE_SOURCEMAP=true
|
||||
VITE_APP_GRAPHQL_ENDPOINT=https://db.imex.online/v1/graphql
|
||||
VITE_APP_GRAPHQL_ENDPOINT_WS=wss://db.imex.online/v1/graphql
|
||||
VITE_APP_GRAPHQL_ENDPOINT=https://db.romeonline.io/v1/graphql
|
||||
VITE_APP_GRAPHQL_ENDPOINT_WS=wss://db.romeonline.io/v1/graphql
|
||||
VITE_APP_GA_CODE=231103507
|
||||
VITE_APP_FIREBASE_CONFIG={ "apiKey": "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE", "authDomain": "rome-prod-1.firebaseapp.com", "projectId": "rome-prod-1", "storageBucket": "rome-prod-1.appspot.com", "messagingSenderId": "147786367145", "appId": "1:147786367145:web:9d4cba68071c3f29a8a9b8", "measurementId": "G-G8Z9DRHTZS"}
|
||||
VITE_APP_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/bodyshop
|
||||
@@ -9,7 +9,7 @@ VITE_APP_CLOUDINARY_API_KEY=473322739956866
|
||||
VITE_APP_CLOUDINARY_THUMB_TRANSFORMATIONS=c_fill,h_250,w_250
|
||||
VITE_APP_FIREBASE_PUBLIC_VAPID_KEY='BMgZT1NZztW2DsJl8Mg2L04hgY9FzAg6b8fbzgNAfww2VDzH3VE63Ot9EaP_U7KWS2JT-7HPHaw0T_Tw_5vkZc8'
|
||||
VITE_APP_STRIPE_PUBLIC_KEY=pk_test_51GqB4TJl3nQjrZ0wCQWAxAhlNF8jKe0tipIa6ExBaxwJGitwvFsIZUEua4dUzaMIAuXp4qwYHXx7lgjyQSwP0Pe900vzm38C7g
|
||||
VITE_APP_AXIOS_BASE_API_URL=https://api.imex.online/
|
||||
VITE_APP_REPORTS_SERVER_URL=https://reports.imex.online
|
||||
VITE_APP_AXIOS_BASE_API_URL=https://api.romeonline.io/
|
||||
VITE_APP_REPORTS_SERVER_URL=https://reports.romeonline.io
|
||||
VITE_APP_SPLIT_API=et9pjkik6bn67he5evpmpr1agoo7gactphgk
|
||||
VITE_APP_INSTANCE=PROMANAGER
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
VITE_APP_GRAPHQL_ENDPOINT=https://db.test.bodyshop.app/v1/graphql
|
||||
VITE_APP_GRAPHQL_ENDPOINT_WS=wss://db.test.bodyshop.app/v1/graphql
|
||||
VITE_APP_GRAPHQL_ENDPOINT=https://db.test.romeonline.io/v1/graphql
|
||||
VITE_APP_GRAPHQL_ENDPOINT_WS=wss://db.test.romeonline.io/v1/graphql
|
||||
VITE_APP_GA_CODE=231099835
|
||||
VITE_APP_FIREBASE_CONFIG={ "apiKey": "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE", "authDomain": "rome-prod-1.firebaseapp.com", "projectId": "rome-prod-1", "storageBucket": "rome-prod-1.appspot.com", "messagingSenderId": "147786367145", "appId": "1:147786367145:web:9d4cba68071c3f29a8a9b8", "measurementId": "G-G8Z9DRHTZS"}
|
||||
VITE_APP_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/bodyshop
|
||||
@@ -8,8 +8,8 @@ VITE_APP_CLOUDINARY_API_KEY=473322739956866
|
||||
VITE_APP_CLOUDINARY_THUMB_TRANSFORMATIONS=c_fill,h_250,w_250
|
||||
VITE_APP_FIREBASE_PUBLIC_VAPID_KEY='BN2GcDPjipR5MTEosO5dT4CfQ3cmrdBIsI4juoOQrRijn_5aRiHlwj1mlq0W145mOusx6xynEKl_tvYJhpCc9lo'
|
||||
VITE_APP_STRIPE_PUBLIC_KEY=pk_test_51GqB4TJl3nQjrZ0wCQWAxAhlNF8jKe0tipIa6ExBaxwJGitwvFsIZUEua4dUzaMIAuXp4qwYHXx7lgjyQSwP0Pe900vzm38C7g
|
||||
VITE_APP_AXIOS_BASE_API_URL=https://api.test.imex.online/
|
||||
VITE_APP_REPORTS_SERVER_URL=https://reports3.test.imex.online
|
||||
VITE_APP_AXIOS_BASE_API_URL=https://api.test.romeonline.io/
|
||||
VITE_APP_REPORTS_SERVER_URL=https://reports.test.romeonline.io
|
||||
VITE_APP_IS_TEST=true
|
||||
VITE_APP_SPLIT_API=ts615lqgnmk84thn72uk18uu5pgce6e0l4rc
|
||||
VITE_APP_INSTANCE=PROMANAGER
|
||||
|
||||
1
client/dev-dist/registerSW.js
Normal file
@@ -0,0 +1 @@
|
||||
if('serviceWorker' in navigator) navigator.serviceWorker.register('/dev-sw.js?dev-sw', { scope: '/', type: 'classic' })
|
||||
92
client/dev-dist/sw.js
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Copyright 2018 Google Inc. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// If the loader is already loaded, just stop.
|
||||
if (!self.define) {
|
||||
let registry = {};
|
||||
|
||||
// Used for `eval` and `importScripts` where we can't get script URL by other means.
|
||||
// In both cases, it's safe to use a global var because those functions are synchronous.
|
||||
let nextDefineUri;
|
||||
|
||||
const singleRequire = (uri, parentUri) => {
|
||||
uri = new URL(uri + ".js", parentUri).href;
|
||||
return registry[uri] || (
|
||||
|
||||
new Promise(resolve => {
|
||||
if ("document" in self) {
|
||||
const script = document.createElement("script");
|
||||
script.src = uri;
|
||||
script.onload = resolve;
|
||||
document.head.appendChild(script);
|
||||
} else {
|
||||
nextDefineUri = uri;
|
||||
importScripts(uri);
|
||||
resolve();
|
||||
}
|
||||
})
|
||||
|
||||
.then(() => {
|
||||
let promise = registry[uri];
|
||||
if (!promise) {
|
||||
throw new Error(`Module ${uri} didn’t register its module`);
|
||||
}
|
||||
return promise;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
self.define = (depsNames, factory) => {
|
||||
const uri = nextDefineUri || ("document" in self ? document.currentScript.src : "") || location.href;
|
||||
if (registry[uri]) {
|
||||
// Module is already loading or loaded.
|
||||
return;
|
||||
}
|
||||
let exports = {};
|
||||
const require = depUri => singleRequire(depUri, uri);
|
||||
const specialDeps = {
|
||||
module: { uri },
|
||||
exports,
|
||||
require
|
||||
};
|
||||
registry[uri] = Promise.all(depsNames.map(
|
||||
depName => specialDeps[depName] || require(depName)
|
||||
)).then(deps => {
|
||||
factory(...deps);
|
||||
return exports;
|
||||
});
|
||||
};
|
||||
}
|
||||
define(['./workbox-b5f7729d'], (function (workbox) { 'use strict';
|
||||
|
||||
self.skipWaiting();
|
||||
workbox.clientsClaim();
|
||||
|
||||
/**
|
||||
* The precacheAndRoute() method efficiently caches and responds to
|
||||
* requests for URLs in the manifest.
|
||||
* See https://goo.gl/S9QRab
|
||||
*/
|
||||
workbox.precacheAndRoute([{
|
||||
"url": "registerSW.js",
|
||||
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
||||
}, {
|
||||
"url": "index.html",
|
||||
"revision": "0.sa702m4aq68"
|
||||
}], {});
|
||||
workbox.cleanupOutdatedCaches();
|
||||
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
||||
allowlist: [/^\/$/]
|
||||
}));
|
||||
|
||||
}));
|
||||
3391
client/dev-dist/workbox-b5f7729d.js
Normal file
@@ -7,18 +7,19 @@
|
||||
<% } %> <% if (env.VITE_APP_INSTANCE === 'ROME') { %>
|
||||
<link rel="icon" href="/ro-favicon.png" />
|
||||
<% } %> <% if (env.VITE_APP_INSTANCE === 'PROMANAGER') { %>
|
||||
<link rel="icon" href="/favicon.png" />
|
||||
<link rel="icon" href="/pm/pm-favicon.ico" />
|
||||
<% } %>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#002366" />
|
||||
<meta name="theme-color" content="#1690ff" />
|
||||
<!-- <link rel="apple-touch-icon" href="logo192.png" /> -->
|
||||
<!-- TODO:AIo Update the individual logos for each.-->
|
||||
<link rel="apple-touch-icon" href="public/logo192.png" />
|
||||
<link rel="mask-icon" href="/mask-icon.svg" color="#FFFFFF">
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
|
||||
301
client/package-lock.json
generated
@@ -123,6 +123,7 @@
|
||||
"vite-plugin-babel": "^1.2.0",
|
||||
"vite-plugin-legacy": "^2.1.0",
|
||||
"vite-plugin-node-polyfills": "^0.19.0",
|
||||
"vite-plugin-pwa": "^0.19.0",
|
||||
"vite-plugin-style-import": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -13707,6 +13708,19 @@
|
||||
"version": "1.0.0",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"license": "MIT",
|
||||
@@ -27057,6 +27071,293 @@
|
||||
"vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa": {
|
||||
"version": "0.19.0",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.19.0.tgz",
|
||||
"integrity": "sha512-Unfb4Jk/ka4HELtpMLIPCmGcW4LFT+CL7Ri1/Of1544CVKXS2ftP91kUkNzkzeI1sGpOdVGuxprVLB9NjMoCAA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4",
|
||||
"fast-glob": "^3.3.2",
|
||||
"pretty-bytes": "^6.1.1",
|
||||
"workbox-build": "^7.0.0",
|
||||
"workbox-window": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vite-pwa/assets-generator": "^0.2.4",
|
||||
"vite": "^3.1.0 || ^4.0.0 || ^5.0.0",
|
||||
"workbox-build": "^7.0.0",
|
||||
"workbox-window": "^7.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vite-pwa/assets-generator": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/pretty-bytes": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz",
|
||||
"integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/rollup": {
|
||||
"version": "2.79.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
|
||||
"integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/source-map": {
|
||||
"version": "0.8.0-beta.0",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz",
|
||||
"integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"whatwg-url": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/tr46": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
|
||||
"integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/webidl-conversions": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
|
||||
"integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/whatwg-url": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
|
||||
"integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lodash.sortby": "^4.7.0",
|
||||
"tr46": "^1.0.1",
|
||||
"webidl-conversions": "^4.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/workbox-background-sync": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.0.0.tgz",
|
||||
"integrity": "sha512-S+m1+84gjdueM+jIKZ+I0Lx0BDHkk5Nu6a3kTVxP4fdj3gKouRNmhO8H290ybnJTOPfBDtTMXSQA/QLTvr7PeA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"idb": "^7.0.1",
|
||||
"workbox-core": "7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/workbox-broadcast-update": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.0.0.tgz",
|
||||
"integrity": "sha512-oUuh4jzZrLySOo0tC0WoKiSg90bVAcnE98uW7F8GFiSOXnhogfNDGZelPJa+6KpGBO5+Qelv04Hqx2UD+BJqNQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"workbox-core": "7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/workbox-build": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.0.0.tgz",
|
||||
"integrity": "sha512-CttE7WCYW9sZC+nUYhQg3WzzGPr4IHmrPnjKiu3AMXsiNQKx+l4hHl63WTrnicLmKEKHScWDH8xsGBdrYgtBzg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@apideck/better-ajv-errors": "^0.3.1",
|
||||
"@babel/core": "^7.11.1",
|
||||
"@babel/preset-env": "^7.11.0",
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@rollup/plugin-babel": "^5.2.0",
|
||||
"@rollup/plugin-node-resolve": "^11.2.1",
|
||||
"@rollup/plugin-replace": "^2.4.1",
|
||||
"@surma/rollup-plugin-off-main-thread": "^2.2.3",
|
||||
"ajv": "^8.6.0",
|
||||
"common-tags": "^1.8.0",
|
||||
"fast-json-stable-stringify": "^2.1.0",
|
||||
"fs-extra": "^9.0.1",
|
||||
"glob": "^7.1.6",
|
||||
"lodash": "^4.17.20",
|
||||
"pretty-bytes": "^5.3.0",
|
||||
"rollup": "^2.43.1",
|
||||
"rollup-plugin-terser": "^7.0.0",
|
||||
"source-map": "^0.8.0-beta.0",
|
||||
"stringify-object": "^3.3.0",
|
||||
"strip-comments": "^2.0.1",
|
||||
"tempy": "^0.6.0",
|
||||
"upath": "^1.2.0",
|
||||
"workbox-background-sync": "7.0.0",
|
||||
"workbox-broadcast-update": "7.0.0",
|
||||
"workbox-cacheable-response": "7.0.0",
|
||||
"workbox-core": "7.0.0",
|
||||
"workbox-expiration": "7.0.0",
|
||||
"workbox-google-analytics": "7.0.0",
|
||||
"workbox-navigation-preload": "7.0.0",
|
||||
"workbox-precaching": "7.0.0",
|
||||
"workbox-range-requests": "7.0.0",
|
||||
"workbox-recipes": "7.0.0",
|
||||
"workbox-routing": "7.0.0",
|
||||
"workbox-strategies": "7.0.0",
|
||||
"workbox-streams": "7.0.0",
|
||||
"workbox-sw": "7.0.0",
|
||||
"workbox-window": "7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/workbox-build/node_modules/pretty-bytes": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
|
||||
"integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/workbox-cacheable-response": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.0.0.tgz",
|
||||
"integrity": "sha512-0lrtyGHn/LH8kKAJVOQfSu3/80WDc9Ma8ng0p2i/5HuUndGttH+mGMSvOskjOdFImLs2XZIimErp7tSOPmu/6g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"workbox-core": "7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/workbox-google-analytics": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.0.0.tgz",
|
||||
"integrity": "sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==",
|
||||
"deprecated": "It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"workbox-background-sync": "7.0.0",
|
||||
"workbox-core": "7.0.0",
|
||||
"workbox-routing": "7.0.0",
|
||||
"workbox-strategies": "7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/workbox-range-requests": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.0.0.tgz",
|
||||
"integrity": "sha512-SxAzoVl9j/zRU9OT5+IQs7pbJBOUOlriB8Gn9YMvi38BNZRbM+RvkujHMo8FOe9IWrqqwYgDFBfv6sk76I1yaQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"workbox-core": "7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/workbox-recipes": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.0.0.tgz",
|
||||
"integrity": "sha512-DntcK9wuG3rYQOONWC0PejxYYIDHyWWZB/ueTbOUDQgefaeIj1kJ7pdP3LZV2lfrj8XXXBWt+JDRSw1lLLOnww==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"workbox-cacheable-response": "7.0.0",
|
||||
"workbox-core": "7.0.0",
|
||||
"workbox-expiration": "7.0.0",
|
||||
"workbox-precaching": "7.0.0",
|
||||
"workbox-routing": "7.0.0",
|
||||
"workbox-strategies": "7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/workbox-streams": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.0.0.tgz",
|
||||
"integrity": "sha512-moVsh+5to//l6IERWceYKGiftc+prNnqOp2sgALJJFbnNVpTXzKISlTIsrWY+ogMqt+x1oMazIdHj25kBSq/HQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"workbox-core": "7.0.0",
|
||||
"workbox-routing": "7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/workbox-sw": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.0.0.tgz",
|
||||
"integrity": "sha512-SWfEouQfjRiZ7GNABzHUKUyj8pCoe+RwjfOIajcx6J5mtgKkN+t8UToHnpaJL5UVVOf5YhJh+OHhbVNIHe+LVA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/vite-plugin-pwa/node_modules/workbox-window": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.0.0.tgz",
|
||||
"integrity": "sha512-j7P/bsAWE/a7sxqTzXo3P2ALb1reTfZdvVp6OJ/uLr/C2kZAMvjeWGm8V4htQhor7DOvYg0sSbFN2+flT5U0qA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/trusted-types": "^2.0.2",
|
||||
"workbox-core": "7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-style-import": {
|
||||
"version": "2.0.0",
|
||||
"dev": true,
|
||||
|
||||
@@ -164,6 +164,7 @@
|
||||
"vite-plugin-babel": "^1.2.0",
|
||||
"vite-plugin-legacy": "^2.1.0",
|
||||
"vite-plugin-node-polyfills": "^0.19.0",
|
||||
"vite-plugin-pwa": "^0.19.0",
|
||||
"vite-plugin-style-import": "^2.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
// unlayer.registerPropertyEditor({
|
||||
// name: "field_name",
|
||||
// layout: "bottom",
|
||||
// Widget: unlayer.createWidget({
|
||||
// render(value) {
|
||||
// return `
|
||||
// <input class="field" value=${value} />
|
||||
// `;
|
||||
// },
|
||||
// mount(node, value, updateValue) {
|
||||
// var input = node.getElementsByClassName("field")[0];
|
||||
// input.onchange = function (event) {
|
||||
// updateValue(event.target.value);
|
||||
// };
|
||||
// },
|
||||
// }),
|
||||
// });
|
||||
|
||||
// unlayer.registerTool({
|
||||
// type: "whatever",
|
||||
// category: "contents",
|
||||
// label: "Begin Repeat",
|
||||
// icon: "fa-smile",
|
||||
// values: {},
|
||||
// options: {
|
||||
// default: {
|
||||
// title: null,
|
||||
// },
|
||||
// text: {
|
||||
// title: "Field",
|
||||
// position: 1,
|
||||
// options: {
|
||||
// field: {
|
||||
// label: "Field",
|
||||
// defaultValue: "",
|
||||
// widget: "field_name",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// renderer: {
|
||||
// Viewer: unlayer.createViewer({
|
||||
// render(values) {
|
||||
// console.log(values);
|
||||
// return `
|
||||
// <div style="display: none;">{{#each ${values.field}}}</div>
|
||||
// `;
|
||||
// },
|
||||
// }),
|
||||
// exporters: {
|
||||
// web: function () {},
|
||||
// email: function () {},
|
||||
// },
|
||||
// },
|
||||
// });
|
||||
|
||||
// unlayer.registerTool({
|
||||
// type: "whatever",
|
||||
// category: "contents",
|
||||
// label: "End Repeat",
|
||||
// icon: "fa-smile",
|
||||
// values: {},
|
||||
// options: {
|
||||
// default: {
|
||||
// title: null,
|
||||
// },
|
||||
// text: {
|
||||
// title: "Field",
|
||||
// position: 1,
|
||||
// options: {
|
||||
// field: {
|
||||
// label: "Field",
|
||||
// defaultValue: "",
|
||||
// widget: "field_name",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// renderer: {
|
||||
// Viewer: unlayer.createViewer({
|
||||
// render(values) {
|
||||
// return `
|
||||
// <div style="display: none;">{{ /each }}</div>
|
||||
// `;
|
||||
// },
|
||||
// }),
|
||||
// exporters: {
|
||||
// web: function () {},
|
||||
// email: function () {},
|
||||
// },
|
||||
// },
|
||||
// });
|
||||
|
||||
unlayer.registerColumns([2, 2, 2, 2, 2, 2]);
|
||||
unlayer.registerColumns([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]);
|
||||
@@ -1,71 +0,0 @@
|
||||
// Scripts for firebase and firebase messaging
|
||||
importScripts("https://www.gstatic.com/firebasejs/8.2.0/firebase-app.js");
|
||||
importScripts("https://www.gstatic.com/firebasejs/8.2.0/firebase-messaging.js");
|
||||
|
||||
// Initialize the Firebase app in the service worker by passing the generated config
|
||||
let firebaseConfig;
|
||||
switch (this.location.hostname) {
|
||||
case "localhost":
|
||||
firebaseConfig = {
|
||||
apiKey: "AIzaSyDPLT8GiDHDR1R4nI66Qi0BY1aYviDPioc",
|
||||
authDomain: "imex-dev.firebaseapp.com",
|
||||
databaseURL: "https://imex-dev.firebaseio.com",
|
||||
projectId: "imex-dev",
|
||||
storageBucket: "imex-dev.appspot.com",
|
||||
messagingSenderId: "759548147434",
|
||||
appId: "1:759548147434:web:e8239868a48ceb36700993",
|
||||
measurementId: "G-K5XRBVVB4S",
|
||||
};
|
||||
break;
|
||||
case "test.imex.online":
|
||||
firebaseConfig = {
|
||||
apiKey: "AIzaSyBw7_GTy7GtQyfkIRPVrWHEGKfcqeyXw0c",
|
||||
authDomain: "imex-test.firebaseapp.com",
|
||||
projectId: "imex-test",
|
||||
storageBucket: "imex-test.appspot.com",
|
||||
messagingSenderId: "991923618608",
|
||||
appId: "1:991923618608:web:633437569cdad78299bef5",
|
||||
// measurementId: "${config.measurementId}",
|
||||
};
|
||||
break;
|
||||
case "romeonline.io":
|
||||
case "test.romeonline.io":
|
||||
case "test.promanager.web-est.com":
|
||||
case "promanager.web-est.com":
|
||||
firebaseConfig = {
|
||||
apiKey: "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE",
|
||||
authDomain: "rome-prod-1.firebaseapp.com",
|
||||
projectId: "rome-prod-1",
|
||||
storageBucket: "rome-prod-1.appspot.com",
|
||||
messagingSenderId: "147786367145",
|
||||
appId: "1:147786367145:web:9d4cba68071c3f29a8a9b8",
|
||||
measurementId: "G-G8Z9DRHTZS",
|
||||
};
|
||||
break;
|
||||
|
||||
case "imex.online":
|
||||
default:
|
||||
firebaseConfig = {
|
||||
apiKey: "AIzaSyDSezy-jGJreo7ulgpLdlpOwAOrgcaEkhU",
|
||||
authDomain: "imex-prod.firebaseapp.com",
|
||||
databaseURL: "https://imex-prod.firebaseio.com",
|
||||
projectId: "imex-prod",
|
||||
storageBucket: "imex-prod.appspot.com",
|
||||
messagingSenderId: "253497221485",
|
||||
appId: "1:253497221485:web:3c81c483b94db84b227a64",
|
||||
measurementId: "G-NTWBKG2L0M",
|
||||
};
|
||||
}
|
||||
|
||||
firebase.initializeApp(firebaseConfig);
|
||||
|
||||
// Retrieve firebase messaging
|
||||
const messaging = firebase.messaging();
|
||||
|
||||
messaging.onBackgroundMessage(function (payload) {
|
||||
// Customize notification here
|
||||
const channel = new BroadcastChannel("imex-sw-messages");
|
||||
channel.postMessage(payload);
|
||||
|
||||
//self.registration.showNotification(notificationTitle, notificationOptions);
|
||||
});
|
||||
@@ -1,27 +0,0 @@
|
||||
{
|
||||
"short_name": "Rome Online",
|
||||
"name": "Rome Online",
|
||||
"description": "The ultimate bodyshop management system.",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo1024.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#fff",
|
||||
"background_color": "#fff",
|
||||
"gcm_sender_id": "103953800507"
|
||||
}
|
||||
BIN
client/public/pm/pm-apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
client/public/pm/pm-favicon.ico
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
client/public/pm/pm-icon-192-maskable.png
Normal file
|
After Width: | Height: | Size: 6.0 KiB |
BIN
client/public/pm/pm-icon-192.png
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
client/public/pm/pm-icon-512-maskable.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
client/public/pm/pm-icon-512.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
client/src/assets/promanager/android/play_store_512.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
<monochrome android:drawable="@mipmap/ic_launcher_monochrome"/>
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 857 B |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 463 B |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 8.2 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.8 KiB |
BIN
client/src/assets/promanager/ios/AppIcon-20@2x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
client/src/assets/promanager/ios/AppIcon-20@2x~ipad.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
client/src/assets/promanager/ios/AppIcon-20@3x.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
client/src/assets/promanager/ios/AppIcon-20~ipad.png
Normal file
|
After Width: | Height: | Size: 527 B |
BIN
client/src/assets/promanager/ios/AppIcon-29.png
Normal file
|
After Width: | Height: | Size: 948 B |
BIN
client/src/assets/promanager/ios/AppIcon-29@2x.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
client/src/assets/promanager/ios/AppIcon-29@2x~ipad.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
client/src/assets/promanager/ios/AppIcon-29@3x.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
client/src/assets/promanager/ios/AppIcon-29~ipad.png
Normal file
|
After Width: | Height: | Size: 948 B |
BIN
client/src/assets/promanager/ios/AppIcon-40@2x.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
client/src/assets/promanager/ios/AppIcon-40@2x~ipad.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
client/src/assets/promanager/ios/AppIcon-40@3x.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
client/src/assets/promanager/ios/AppIcon-40~ipad.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
client/src/assets/promanager/ios/AppIcon-60@2x~car.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
client/src/assets/promanager/ios/AppIcon-60@3x~car.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
client/src/assets/promanager/ios/AppIcon-83.5@2x~ipad.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
client/src/assets/promanager/ios/AppIcon@2x.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
client/src/assets/promanager/ios/AppIcon@2x~ipad.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
client/src/assets/promanager/ios/AppIcon@3x.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
client/src/assets/promanager/ios/AppIcon~ios-marketing.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
client/src/assets/promanager/ios/AppIcon~ipad.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
134
client/src/assets/promanager/ios/Contents.json
Normal file
@@ -0,0 +1,134 @@
|
||||
{
|
||||
"images": [
|
||||
{
|
||||
"filename": "AppIcon@2x.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "2x",
|
||||
"size": "60x60"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon@3x.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "3x",
|
||||
"size": "60x60"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon~ipad.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "1x",
|
||||
"size": "76x76"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon@2x~ipad.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "2x",
|
||||
"size": "76x76"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon-83.5@2x~ipad.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "2x",
|
||||
"size": "83.5x83.5"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon-40@2x.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "2x",
|
||||
"size": "40x40"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon-40@3x.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "3x",
|
||||
"size": "40x40"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon-40~ipad.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "1x",
|
||||
"size": "40x40"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon-40@2x~ipad.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "2x",
|
||||
"size": "40x40"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon-20@2x.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "2x",
|
||||
"size": "20x20"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon-20@3x.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "3x",
|
||||
"size": "20x20"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon-20~ipad.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "1x",
|
||||
"size": "20x20"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon-20@2x~ipad.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "2x",
|
||||
"size": "20x20"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon-29.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "1x",
|
||||
"size": "29x29"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon-29@2x.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "2x",
|
||||
"size": "29x29"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon-29@3x.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "3x",
|
||||
"size": "29x29"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon-29~ipad.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "1x",
|
||||
"size": "29x29"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon-29@2x~ipad.png",
|
||||
"idiom": "ipad",
|
||||
"scale": "2x",
|
||||
"size": "29x29"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon-60@2x~car.png",
|
||||
"idiom": "car",
|
||||
"scale": "2x",
|
||||
"size": "60x60"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon-60@3x~car.png",
|
||||
"idiom": "car",
|
||||
"scale": "3x",
|
||||
"size": "60x60"
|
||||
},
|
||||
{
|
||||
"filename": "AppIcon~ios-marketing.png",
|
||||
"idiom": "ios-marketing",
|
||||
"scale": "1x",
|
||||
"size": "1024x1024"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "iconkitchen",
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
18
client/src/assets/promanager/web/README.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
Add this to your HTML <head>:
|
||||
|
||||
<link rel="icon" href="/favicon.ico" sizes="any">
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
||||
|
||||
Add this to your app's manifest.json:
|
||||
|
||||
...
|
||||
{
|
||||
"icons": [
|
||||
{ "src": "/favicon.ico", "type": "image/x-icon", "sizes": "16x16 32x32" },
|
||||
{ "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" },
|
||||
{ "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" },
|
||||
{ "src": "/icon-192-maskable.png", "type": "image/png", "sizes": "192x192", "purpose": "maskable" },
|
||||
{ "src": "/icon-512-maskable.png", "type": "image/png", "sizes": "512x512", "purpose": "maskable" }
|
||||
]
|
||||
}
|
||||
...
|
||||
BIN
client/src/assets/promanager/web/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
client/src/assets/promanager/web/favicon.ico
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
client/src/assets/promanager/web/icon-192-maskable.png
Normal file
|
After Width: | Height: | Size: 6.0 KiB |
BIN
client/src/assets/promanager/web/icon-192.png
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
client/src/assets/promanager/web/icon-512-maskable.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
client/src/assets/promanager/web/icon-512.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
@@ -1,60 +0,0 @@
|
||||
import {withApollo} from "@apollo/client/react/hoc";
|
||||
import React, {Component} from "react";
|
||||
import {connect} from "react-redux";
|
||||
import {createStructuredSelector} from "reselect";
|
||||
//import { logImEXEvent, messaging } from "../../firebase/firebase.utils";
|
||||
import {selectCurrentUser} from "../../redux/user/user.selectors";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
currentUser: selectCurrentUser,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
});
|
||||
|
||||
class FcmNotificationComponent extends Component {
|
||||
async componentDidMount() {
|
||||
//const { client, currentUser } = this.props;
|
||||
// if (!!!messaging) return; //Skip all of the notification functionality if the firebase SDK could not start.
|
||||
// messaging
|
||||
// .requestPermission()
|
||||
// .then(async function () {
|
||||
// // const token = await messaging.getToken();
|
||||
// // client.mutate({
|
||||
// // mutation: UPDATE_FCM_TOKEN,
|
||||
// // variables: { authEmail: currentUser.email, token: { [token]: true } },
|
||||
// // });
|
||||
// })
|
||||
// .catch(function (err) {
|
||||
// console.log("Unable to get permission to notify.", err);
|
||||
// logImEXEvent("fcm_permission_denied", { message: err });
|
||||
// });
|
||||
}
|
||||
|
||||
render() {
|
||||
return <span/>;
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(withApollo(FcmNotificationComponent));
|
||||
|
||||
//Firebase Service Worker Register
|
||||
// if ("serviceWorker" in navigator) {
|
||||
// navigator.serviceWorker
|
||||
// .register("/firebase-messaging-sw.js")
|
||||
// .then(function (registration) {
|
||||
// console.log(
|
||||
// "[FCM] Registration successful, scope is:",
|
||||
// registration.scope
|
||||
// );
|
||||
// navigator.serviceWorker.addEventListener("message", (event) => {
|
||||
// console.log("Handler for Navigator Service Worker.", event);
|
||||
// });
|
||||
// })
|
||||
// .catch(function (err) {
|
||||
// console.log("[FCM] Service worker registration failed, error:", err);
|
||||
// });
|
||||
// }
|
||||
@@ -1,79 +1,99 @@
|
||||
import {Alert, Button, Col, Row, Space} from "antd";
|
||||
import i18n from "i18next";
|
||||
import React from "react";
|
||||
import {connect} from "react-redux";
|
||||
import {createStructuredSelector} from "reselect";
|
||||
import {selectUpdateAvailable} from "../../redux/application/application.selectors";
|
||||
import {AlertOutlined} from "@ant-design/icons";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {setUpdateAvailable} from "../../redux/application/application.actions";
|
||||
import {store} from "../../redux/store";
|
||||
import * as serviceWorkerRegistration from "../../serviceWorkerRegistration";
|
||||
import { Alert, Button, Col, Row, Space } from 'antd';
|
||||
import i18n from 'i18next';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createStructuredSelector } from 'reselect';
|
||||
import { selectUpdateAvailable } from '../../redux/application/application.selectors';
|
||||
import { AlertOutlined } from '@ant-design/icons';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { setUpdateAvailable } from '../../redux/application/application.actions';
|
||||
import { store } from '../../redux/store';
|
||||
//import * as serviceWorkerRegistration from '../../serviceWorkerRegistration';
|
||||
import InstanceRenderManager from '../../utils/instanceRenderMgr';
|
||||
import { useRegisterSW } from 'virtual:pwa-register/react';
|
||||
|
||||
let globalRegistration;
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
updateAvailable: selectUpdateAvailable,
|
||||
updateAvailable: selectUpdateAvailable,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
});
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(UpdateAlert);
|
||||
const intervalMS = 10 * 60 * 1000;
|
||||
export function UpdateAlert({ updateAvailable }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
export function UpdateAlert({updateAvailable}) {
|
||||
const {t} = useTranslation();
|
||||
if (!updateAvailable) return null;
|
||||
return (
|
||||
<Alert
|
||||
message={t("general.messages.newversiontitle",{app: InstanceRenderManager({imex:'$t(titles.imexonline)', rome: '$t(titles.romeonline)', promanager: '$t(titles.promanager)'})})}
|
||||
showIcon
|
||||
icon={<AlertOutlined/>}
|
||||
description={
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col sm={24} md={16} lg={18}>
|
||||
{t("general.messages.newversionmessage",{app: InstanceRenderManager({imex:'$t(titles.imexonline)', rome: '$t(titles.romeonline)', promanager: '$t(titles.promanager)'})})}
|
||||
</Col>
|
||||
<Col sm={24} md={8} lg={6}>
|
||||
<Space wrap>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
window.open("https://imex-online.noticeable.news/", "_blank");
|
||||
}}
|
||||
>
|
||||
{i18n.t("general.actions.viewreleasenotes")}
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={async () => {
|
||||
if (globalRegistration && globalRegistration.waiting) {
|
||||
await globalRegistration.unregister();
|
||||
// Makes Workbox call skipWaiting()
|
||||
globalRegistration.waiting.postMessage({
|
||||
type: "SKIP_WAITING",
|
||||
});
|
||||
// Once the service worker is unregistered, we can reload the page to let
|
||||
// the browser download a fresh copy of our app (invalidating the cache)
|
||||
window.location.reload();
|
||||
}
|
||||
}}
|
||||
>
|
||||
{i18n.t("general.actions.refresh")}
|
||||
</Button>
|
||||
</Space>
|
||||
</Col>
|
||||
</Row>
|
||||
}
|
||||
closable={false}
|
||||
type="warning"
|
||||
/>
|
||||
);
|
||||
const {
|
||||
offlineReady: [
|
||||
offlineReady, //setOfflineReady
|
||||
],
|
||||
needRefresh: [
|
||||
needRefresh, //setNeedRefresh
|
||||
],
|
||||
updateServiceWorker,
|
||||
} = useRegisterSW({
|
||||
onRegistered(r) {
|
||||
// eslint-disable-next-line prefer-template
|
||||
console.log('SW Registered: ' + r);
|
||||
r &&
|
||||
setInterval(() => {
|
||||
r.update();
|
||||
}, intervalMS);
|
||||
},
|
||||
onRegisterError(error) {
|
||||
console.log('SW registration error', error);
|
||||
},
|
||||
});
|
||||
console.log(`SW Status => Refresh? ${needRefresh} - offlineReady? ${offlineReady}`);
|
||||
|
||||
if (!needRefresh) return null;
|
||||
return (
|
||||
<Alert
|
||||
message={t('general.messages.newversiontitle', {
|
||||
app: InstanceRenderManager({
|
||||
imex: '$t(titles.imexonline)',
|
||||
rome: '$t(titles.romeonline)',
|
||||
promanager: '$t(titles.promanager)',
|
||||
}),
|
||||
})}
|
||||
showIcon
|
||||
icon={<AlertOutlined />}
|
||||
description={
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col sm={24} md={16} lg={18}>
|
||||
{t('general.messages.newversionmessage', {
|
||||
app: InstanceRenderManager({
|
||||
imex: '$t(titles.imexonline)',
|
||||
rome: '$t(titles.romeonline)',
|
||||
promanager: '$t(titles.promanager)',
|
||||
}),
|
||||
})}
|
||||
</Col>
|
||||
<Col sm={24} md={8} lg={6}>
|
||||
<Space wrap>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
window.open('https://imex-online.noticeable.news/', '_blank');
|
||||
}}
|
||||
>
|
||||
{i18n.t('general.actions.viewreleasenotes')}
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={async () => {
|
||||
updateServiceWorker(true);
|
||||
}}
|
||||
>
|
||||
{i18n.t('general.actions.refresh')}
|
||||
</Button>
|
||||
</Space>
|
||||
</Col>
|
||||
</Row>
|
||||
}
|
||||
closable={false}
|
||||
type="warning"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const onServiceWorkerUpdate = (registration) => {
|
||||
console.log("onServiceWorkerUpdate", registration);
|
||||
globalRegistration = registration;
|
||||
store.dispatch(setUpdateAvailable(true));
|
||||
};
|
||||
|
||||
serviceWorkerRegistration.register({onUpdate: onServiceWorkerUpdate});
|
||||
|
||||
@@ -94,57 +94,3 @@ export const logImEXEvent = (eventName, additionalParams, stateProp = null) => {
|
||||
// );
|
||||
logEvent(analytics, eventName, eventParams);
|
||||
};
|
||||
|
||||
// if (messaging) {
|
||||
// onMessage(async (payload) => {
|
||||
// console.log("[FCM] UTILS Message received. ", payload);
|
||||
// navigator.serviceWorker.getRegistration().then((registration) => {
|
||||
// return registration.showNotification(
|
||||
// "[UTIL]" + payload.notification.title,
|
||||
// payload.notification
|
||||
// );
|
||||
// });
|
||||
|
||||
// // if (!payload.clientId) return;
|
||||
|
||||
// // // Get the client.
|
||||
// // const client = await clients.get(payload.clientId);
|
||||
// // // Exit early if we don't get the client.
|
||||
// // // Eg, if it closed.
|
||||
// // if (!client) return;
|
||||
|
||||
// // // Send a message to the client.
|
||||
// // console.log("Posting to client.");
|
||||
// // client.postMessage({
|
||||
// // msg: "Hey I just got a fetch from you!",
|
||||
// // url: payload.request.url,
|
||||
// // });
|
||||
|
||||
// // [START_EXCLUDE]
|
||||
// // Update the UI to include the received message.
|
||||
// //appendMessage(payload);
|
||||
|
||||
// // [END_EXCLUDE]
|
||||
// });
|
||||
|
||||
// messaging.onTokenRefresh(() => {
|
||||
// messaging
|
||||
// .getToken()
|
||||
// .then((refreshedToken) => {
|
||||
// console.log("[FCM] Token refreshed.");
|
||||
// // Indicate that the new Instance ID token has not yet been sent to the
|
||||
// // app server.
|
||||
// // setTokenSentToServer(false);
|
||||
// // // Send Instance ID token to app server.
|
||||
// // sendTokenToServer(refreshedToken);
|
||||
// // // [START_EXCLUDE]
|
||||
// // // Display new Instance ID token and clear UI of all previous messages.
|
||||
// // resetUI();
|
||||
// // [END_EXCLUDE]
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// console.log("[FCM] Unable to retrieve refreshed token ", err);
|
||||
// // showToken("Unable to retrieve refreshed token ", err);
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
|
||||
@@ -19,7 +19,9 @@ import "./translations/i18n";
|
||||
import "./utils/CleanAxios";
|
||||
import { ConfigProvider } from "antd";
|
||||
import InstanceRenderManager from "./utils/instanceRenderMgr";
|
||||
import { registerSW } from 'virtual:pwa-register'
|
||||
|
||||
registerSW({ immediate: true })
|
||||
//import { BrowserTracing } from "@sentry/tracing";
|
||||
//import "antd/dist/antd.css";
|
||||
// import "antd/dist/antd.less";
|
||||
@@ -93,44 +95,4 @@ ReactDOM.createRoot(document.getElementById("root")).render(
|
||||
</ConfigProvider>
|
||||
);
|
||||
|
||||
// const onServiceWorkerUpdate = (registration) => {
|
||||
// console.log("onServiceWorkerUpdate", registration);
|
||||
|
||||
// const btn = (
|
||||
// <Space flex>
|
||||
// <Button
|
||||
// onClick={async () => {
|
||||
// window.open("https://imex-online.noticeable.news/", "_blank");
|
||||
// }}
|
||||
// >
|
||||
// {i18n.t("general.actions.viewreleasenotes")}
|
||||
// </Button>
|
||||
// <Button
|
||||
// type="primary"
|
||||
// onClick={async () => {
|
||||
// if (registration && registration.waiting) {
|
||||
// await registration.unregister();
|
||||
// // Makes Workbox call skipWaiting()
|
||||
// registration.waiting.postMessage({ type: "SKIP_WAITING" });
|
||||
// // Once the service worker is unregistered, we can reload the page to let
|
||||
// // the browser download a fresh copy of our app (invalidating the cache)
|
||||
// window.location.reload();
|
||||
// }
|
||||
// }}
|
||||
// >
|
||||
// {i18n.t("general.actions.refresh")}
|
||||
// </Button>
|
||||
// </Space>
|
||||
// );
|
||||
// notification.open({
|
||||
// icon: <AlertOutlined />,
|
||||
// message: i18n.t("general.messages.newversiontitle"),
|
||||
// description: i18n.t("general.messages.newversionmessage"),
|
||||
// duration: 0,
|
||||
// btn,
|
||||
// key: "updateavailable",
|
||||
// });
|
||||
// };
|
||||
|
||||
// serviceWorkerRegistration.register({ onUpdate: onServiceWorkerUpdate });
|
||||
reportWebVitals();
|
||||
|
||||
@@ -6,7 +6,6 @@ import AlertComponent from "../../components/alert/alert.component";
|
||||
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
|
||||
import {QUERY_BODYSHOP} from "../../graphql/bodyshop.queries";
|
||||
import {setBodyshop} from "../../redux/user/user.actions";
|
||||
//import "../../utils/RegisterSw";
|
||||
import ManagePage from "./manage.page.component";
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
|
||||
@@ -9,7 +9,6 @@ import LoadingSpinner from "../../components/loading-spinner/loading-spinner.com
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {selectBodyshop} from "../../redux/user/user.selectors";
|
||||
import {createStructuredSelector} from "reselect";
|
||||
//import "../../utils/RegisterSw";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/* eslint-disable no-restricted-globals */
|
||||
|
||||
// This service worker can be customized!
|
||||
// See https://developers.google.com/web/tools/workbox/modules
|
||||
// for the list of available Workbox modules, or add any other
|
||||
// code you'd like.
|
||||
// You can also remove this file if you'd prefer not to use a
|
||||
// service worker, and the Workbox build step will be skipped.
|
||||
|
||||
import {clientsClaim} from 'workbox-core';
|
||||
import {ExpirationPlugin} from 'workbox-expiration';
|
||||
import { createHandlerBoundToURL, precacheAndRoute} from 'workbox-precaching';
|
||||
import {registerRoute} from 'workbox-routing';
|
||||
import {StaleWhileRevalidate} from 'workbox-strategies';
|
||||
|
||||
clientsClaim();
|
||||
|
||||
// Precache all of the assets generated by your build process.
|
||||
// Their URLs are injected into the manifest variable below.
|
||||
// This variable must be present somewhere in your service worker file,
|
||||
// even if you decide not to use precaching. See https://cra.link/PWA
|
||||
precacheAndRoute(self.__WB_MANIFEST);
|
||||
|
||||
// Set up App Shell-style routing, so that all navigation requests
|
||||
// are fulfilled with your index.html shell. Learn more at
|
||||
// https://developers.google.com/web/fundamentals/architecture/app-shell
|
||||
const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$');
|
||||
registerRoute(
|
||||
// Return false to exempt requests from being fulfilled by index.html.
|
||||
({request, url}) => {
|
||||
// If this isn't a navigation, skip.
|
||||
if (request.mode !== 'navigate') {
|
||||
return false;
|
||||
} // If this is a URL that starts with /_, skip.
|
||||
|
||||
if (url.pathname.startsWith('/_')) {
|
||||
return false;
|
||||
} // If this looks like a URL for a resource, because it contains // a file extension, skip.
|
||||
|
||||
if (url.pathname.match(fileExtensionRegexp)) {
|
||||
return false;
|
||||
} // Return true to signal that we want to use the handler.
|
||||
|
||||
return true;
|
||||
},
|
||||
createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html')
|
||||
);
|
||||
|
||||
// An example runtime caching route for requests that aren't handled by the
|
||||
// precache, in this case same-origin .png requests like those from in public/
|
||||
registerRoute(
|
||||
// Add in any other file extensions or routing criteria as needed.
|
||||
({url}) => url.origin === self.location.origin && url.pathname.endsWith('.png'), // Customize this strategy as needed, e.g., by changing to CacheFirst.
|
||||
new StaleWhileRevalidate({
|
||||
cacheName: 'images',
|
||||
plugins: [
|
||||
// Ensure that once this runtime cache reaches a maximum size the
|
||||
// least-recently used images are removed.
|
||||
new ExpirationPlugin({maxEntries: 50}),
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
// This allows the web app to trigger skipWaiting via
|
||||
// registration.waiting.postMessage({type: 'SKIP_WAITING'})
|
||||
self.addEventListener('message', (event) => {
|
||||
if (event.data && event.data.type === 'SKIP_WAITING') {
|
||||
self.skipWaiting();
|
||||
}
|
||||
});
|
||||
|
||||
// Any other custom service worker logic can go here.
|
||||
@@ -1,149 +0,0 @@
|
||||
// This optional code is used to register a service worker.
|
||||
// register() is not called by default.
|
||||
|
||||
// This lets the app load faster on subsequent visits in production, and gives
|
||||
// it offline capabilities. However, it also means that developers (and users)
|
||||
// will only see deployed updates on subsequent visits to a page, after all the
|
||||
// existing tabs open on the page have been closed, since previously cached
|
||||
// resources are updated in the background.
|
||||
|
||||
// To learn more about the benefits of this model and instructions on how to
|
||||
// opt-in, read https://bit.ly/CRA-PWA
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === "localhost" ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === "[::1]" ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
|
||||
export function register(config) {
|
||||
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||
return;
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl, config);
|
||||
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
"This web app is being served cache-first by a service " +
|
||||
"worker. To learn more, visit https://bit.ly/CRA-PWA"
|
||||
);
|
||||
});
|
||||
} else {
|
||||
// Is not localhost. Just register service worker
|
||||
registerValidSW(swUrl, config);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function registerValidSW(swUrl, config) {
|
||||
navigator.serviceWorker
|
||||
.register(swUrl)
|
||||
.then((registration) => {
|
||||
// Start addition---
|
||||
// https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#manual_updates
|
||||
// Added code, as our application will be open for a long time and we are a SPA, we need
|
||||
// to trigger checks for updates frequently
|
||||
setInterval(() => {
|
||||
console.log("Checking if service worker was updated in server");
|
||||
registration.update();
|
||||
}, 15 * 60 * 1000); // Every 15 mins check
|
||||
// End addition---
|
||||
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
if (installingWorker == null) {
|
||||
return;
|
||||
}
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === "installed") {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the updated precached content has been fetched,
|
||||
// but the previous service worker will still serve the older
|
||||
// content until all client tabs are closed.
|
||||
console.log(
|
||||
"New content is available and will be used when all " +
|
||||
"tabs for this page are closed. See https://bit.ly/CRA-PWA."
|
||||
);
|
||||
|
||||
// Execute callback
|
||||
if (config && config.onUpdate) {
|
||||
config.onUpdate(registration);
|
||||
}
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log("Content is cached for offline use.");
|
||||
|
||||
// Execute callback
|
||||
if (config && config.onSuccess) {
|
||||
config.onSuccess(registration);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error during service worker registration:", error);
|
||||
});
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl, config) {
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
console.log("Seeing if service worker cna be found.");
|
||||
fetch(swUrl)
|
||||
.then((response) => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
const contentType = response.headers.get("content-type");
|
||||
if (
|
||||
response.status === 404 ||
|
||||
(contentType != null && contentType.indexOf("javascript") === -1)
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
console.log("No service worker found. Unregistering.");
|
||||
navigator.serviceWorker.ready.then((registration) => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
console.log("Service worker found. Registering.");
|
||||
|
||||
registerValidSW(swUrl, config);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
"No internet connection found. App is running in offline mode."
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ("serviceWorker" in navigator) {
|
||||
navigator.serviceWorker.ready.then((registration) => {
|
||||
registration.unregister();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
// This optional code is used to register a service worker.
|
||||
// register() is not called by default.
|
||||
|
||||
// This lets the app load faster on subsequent visits in production, and gives
|
||||
// it offline capabilities. However, it also means that developers (and users)
|
||||
// will only see deployed updates on subsequent visits to a page, after all the
|
||||
// existing tabs open on the page have been closed, since previously cached
|
||||
// resources are updated in the background.
|
||||
|
||||
// To learn more about the benefits of this model and instructions on how to
|
||||
// opt-in, read https://cra.link/PWA
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.0/8 are considered localhost for IPv4.
|
||||
window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
|
||||
);
|
||||
|
||||
export function register(config) {
|
||||
if (import.meta.env.PROD && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL('process.env.PUBLIC_URL', window.location.href);
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||
return;
|
||||
}
|
||||
//TODO:AIO Resolve this for all 3 host names.
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `service-worker.js`;
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl, config);
|
||||
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://cra.link/PWA'
|
||||
);
|
||||
});
|
||||
} else {
|
||||
// Is not localhost. Just register service worker
|
||||
registerValidSW(swUrl, config);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function registerValidSW(swUrl, config) {
|
||||
navigator.serviceWorker
|
||||
.register(swUrl)
|
||||
.then((registration) => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
if (installingWorker == null) {
|
||||
return;
|
||||
}
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the updated precached content has been fetched,
|
||||
// but the previous service worker will still serve the older
|
||||
// content until all client tabs are closed.
|
||||
console.log(
|
||||
'New content is available and will be used when all ' +
|
||||
'tabs for this page are closed. See https://cra.link/PWA.'
|
||||
);
|
||||
|
||||
// Execute callback
|
||||
if (config && config.onUpdate) {
|
||||
config.onUpdate(registration);
|
||||
}
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log('Content is cached for offline use.');
|
||||
|
||||
// Execute callback
|
||||
if (config && config.onSuccess) {
|
||||
config.onSuccess(registration);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error during service worker registration:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl, config) {
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl, {
|
||||
headers: { 'Service-Worker': 'script' },
|
||||
})
|
||||
.then((response) => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
const contentType = response.headers.get('content-type');
|
||||
if (
|
||||
response.status === 404 ||
|
||||
(contentType != null && contentType.indexOf('javascript') === -1)
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then((registration) => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl, config);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log('No internet connection found. App is running in offline mode.');
|
||||
});
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready
|
||||
.then((registration) => {
|
||||
registration.unregister();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -9,15 +9,22 @@
|
||||
* @property { string | object | function } imex Return this prop if Rome.
|
||||
*/
|
||||
|
||||
export default function InstanceRenderManager({ executeFunction, rome, promanager, imex, debug }) {
|
||||
export default function InstanceRenderManager({
|
||||
executeFunction,
|
||||
rome,
|
||||
promanager,
|
||||
imex,
|
||||
debug,
|
||||
instance,
|
||||
}) {
|
||||
let propToReturn = null;
|
||||
|
||||
switch (import.meta.env.VITE_APP_INSTANCE) {
|
||||
switch (instance || import.meta.env.VITE_APP_INSTANCE) {
|
||||
case 'IMEX':
|
||||
propToReturn = imex;
|
||||
break;
|
||||
case 'ROME':
|
||||
propToReturn = rome; //TODO:AIO Implement USE_IMEX
|
||||
propToReturn = rome; //TODO:AIO Implement USE_IMEX
|
||||
break;
|
||||
case 'PROMANAGER':
|
||||
//Return the rome prop if USE_ROME.
|
||||
|
||||
@@ -6,6 +6,8 @@ import * as url from 'url';
|
||||
import { defineConfig } from 'vite';
|
||||
import { ViteEjsPlugin } from 'vite-plugin-ejs';
|
||||
import CompressionPlugin from 'vite-plugin-compression';
|
||||
import { VitePWA } from 'vite-plugin-pwa';
|
||||
import InstanceRenderManager from './src/utils/instanceRenderMgr';
|
||||
|
||||
process.env.VITE_APP_GIT_SHA_DATE = new Date().toLocaleString('en-US', {
|
||||
timeZone: 'America/Los_Angeles',
|
||||
@@ -40,7 +42,65 @@ export default defineConfig({
|
||||
// viteConfig is the current Vite resolved config
|
||||
return { env: viteConfig.env };
|
||||
}),
|
||||
|
||||
VitePWA({
|
||||
injectRegister: 'auto',
|
||||
registerType: 'prompt',
|
||||
manifest: {
|
||||
short_name: InstanceRenderManager({
|
||||
instance: process.env.VITE_APP_INSTANCE,
|
||||
imex: 'ImEX Online',
|
||||
rome: 'Rome Online',
|
||||
promanager: 'ProManager',
|
||||
}),
|
||||
name: InstanceRenderManager({
|
||||
instance: process.env.VITE_APP_INSTANCE,
|
||||
imex: 'ImEX Online',
|
||||
rome: 'Rome Online',
|
||||
promanager: 'ProManager',
|
||||
}),
|
||||
description: 'The ultimate bodyshop management system.',
|
||||
icons: [
|
||||
{ //TODO:AIO Ensure that these are correct for Rome and IO.
|
||||
src: InstanceRenderManager({
|
||||
instance: process.env.VITE_APP_INSTANCE,
|
||||
imex: 'favicon.png',
|
||||
rome: 'ro-favicon.png',
|
||||
promanager: '/pm/pm-favicon.ico',
|
||||
}),
|
||||
sizes: '64x64 32x32 24x24 16x16',
|
||||
type: 'image/x-icon',
|
||||
},
|
||||
{
|
||||
src: InstanceRenderManager({
|
||||
instance: process.env.VITE_APP_INSTANCE,
|
||||
imex: 'logo192.png',
|
||||
rome: 'logo192.png',
|
||||
promanager: '/pm/pm-icon-192.png',
|
||||
}),
|
||||
type: 'image/png',
|
||||
sizes: '192x192',
|
||||
},
|
||||
{
|
||||
src: InstanceRenderManager({
|
||||
instance: process.env.VITE_APP_INSTANCE,
|
||||
imex: 'logo512.png',
|
||||
rome: 'ro-favicon.png',
|
||||
promanager: '/pm/pm-icon-512.png',
|
||||
}),
|
||||
type: 'image/png',
|
||||
sizes: '512x512',
|
||||
},
|
||||
],
|
||||
theme_color: InstanceRenderManager({
|
||||
instance: process.env.VITE_APP_INSTANCE,
|
||||
imex: '#1890ff',
|
||||
rome: '#fff',
|
||||
promanager: '#1d69a6',
|
||||
}),
|
||||
background_color: '#fff',
|
||||
gcm_sender_id: '103953800507',
|
||||
},
|
||||
}),
|
||||
reactVirtualized(),
|
||||
react(),
|
||||
CompressionPlugin(),
|
||||
|
||||