From 00474edffed5bdd8971e8e2c6d1dfadc05dc1b3f Mon Sep 17 00:00:00 2001 From: "Dzmitry_Tamashevich@epam.com" Date: Sun, 29 Nov 2020 21:13:18 +0300 Subject: [PATCH] add app to gitignore --- media-store/.gitignore | 5 +- media-store/app/.gitignore | 23 -- media-store/app/.vscode/launch.json | 13 -- media-store/app/favicon.ico | Bin 3150 -> 0 bytes media-store/app/index.html | 44 ---- media-store/app/logo192.png | Bin 5347 -> 0 bytes media-store/app/logo512.png | Bin 9664 -> 0 bytes media-store/app/manifest.json | 31 --- media-store/app/package.json | 42 ---- media-store/app/public/favicon.ico | Bin 3150 -> 0 bytes media-store/app/public/index.html | 43 ---- media-store/app/public/logo192.png | Bin 5347 -> 0 bytes media-store/app/public/logo512.png | Bin 9664 -> 0 bytes media-store/app/public/manifest.json | 31 --- media-store/app/public/robots.txt | 3 - media-store/app/public/xs-app.json | 10 - media-store/app/robots.txt | 3 - media-store/app/src/App.css | 57 ----- media-store/app/src/App.js | 18 -- media-store/app/src/api/axiosInstance.js | 21 -- media-store/app/src/api/calls.js | 188 --------------- .../app/src/api/changeAxiosDefaults.js | 27 --- .../app/src/api/responseErrorInterceptor.js | 62 ----- media-store/app/src/components/Header.css | 3 - media-store/app/src/components/Header.js | 158 ------------- media-store/app/src/components/Router.js | 58 ----- .../app/src/contexts/AppStateContext.js | 71 ------ media-store/app/src/hocs/withRestrictions.js | 16 -- .../app/src/hooks/useAbortableEffect.js | 22 -- media-store/app/src/hooks/useAppState.js | 6 - media-store/app/src/hooks/useErrors.js | 34 --- media-store/app/src/index.js | 11 - media-store/app/src/logo.svg | 7 - media-store/app/src/pages/ErrorPage.js | 50 ---- media-store/app/src/pages/InvoicePage.js | 107 --------- media-store/app/src/pages/Login.js | 107 --------- media-store/app/src/pages/ManageStore.js | 115 --------- media-store/app/src/pages/MyInvoicesPage.js | 185 --------------- media-store/app/src/pages/PersonPage.js | 108 --------- media-store/app/src/pages/TracksPage.css | 4 - media-store/app/src/pages/TracksPage.js | 219 ------------------ .../src/pages/manage-store/AddAlbumForm.js | 62 ----- .../src/pages/manage-store/AddArtistForm.js | 22 -- .../app/src/pages/manage-store/TrackForm.js | 93 -------- .../app/src/pages/tracks/DeleteAction.js | 43 ---- .../app/src/pages/tracks/EditAction.js | 119 ---------- .../app/src/pages/tracks/ManagedTrack.css | 7 - .../app/src/pages/tracks/ManagedTrack.js | 42 ---- media-store/app/src/pages/tracks/Track.js | 56 ----- .../app/src/pages/tracks/TrackCardBody.js | 33 --- media-store/app/src/serviceWorker.js | 141 ----------- media-store/app/src/setupTests.js | 5 - media-store/app/src/util/EventEmitter.js | 5 - media-store/app/src/util/constants.js | 14 -- .../app/src/util/localStorageService.js | 35 --- media-store/app/src/util/validateUser.js | 20 -- media-store/app/xs-app.json | 10 - media-store/approuter/package.json | 11 - media-store/approuter/xs-app.json | 17 -- media-store/html5Deployer/package.json | 12 - 60 files changed, 4 insertions(+), 2645 deletions(-) delete mode 100644 media-store/app/.gitignore delete mode 100644 media-store/app/.vscode/launch.json delete mode 100644 media-store/app/favicon.ico delete mode 100644 media-store/app/index.html delete mode 100644 media-store/app/logo192.png delete mode 100644 media-store/app/logo512.png delete mode 100644 media-store/app/manifest.json delete mode 100644 media-store/app/package.json delete mode 100644 media-store/app/public/favicon.ico delete mode 100644 media-store/app/public/index.html delete mode 100644 media-store/app/public/logo192.png delete mode 100644 media-store/app/public/logo512.png delete mode 100644 media-store/app/public/manifest.json delete mode 100644 media-store/app/public/robots.txt delete mode 100644 media-store/app/public/xs-app.json delete mode 100644 media-store/app/robots.txt delete mode 100644 media-store/app/src/App.css delete mode 100644 media-store/app/src/App.js delete mode 100644 media-store/app/src/api/axiosInstance.js delete mode 100644 media-store/app/src/api/calls.js delete mode 100644 media-store/app/src/api/changeAxiosDefaults.js delete mode 100644 media-store/app/src/api/responseErrorInterceptor.js delete mode 100644 media-store/app/src/components/Header.css delete mode 100644 media-store/app/src/components/Header.js delete mode 100644 media-store/app/src/components/Router.js delete mode 100644 media-store/app/src/contexts/AppStateContext.js delete mode 100644 media-store/app/src/hocs/withRestrictions.js delete mode 100644 media-store/app/src/hooks/useAbortableEffect.js delete mode 100644 media-store/app/src/hooks/useAppState.js delete mode 100644 media-store/app/src/hooks/useErrors.js delete mode 100644 media-store/app/src/index.js delete mode 100644 media-store/app/src/logo.svg delete mode 100644 media-store/app/src/pages/ErrorPage.js delete mode 100644 media-store/app/src/pages/InvoicePage.js delete mode 100644 media-store/app/src/pages/Login.js delete mode 100644 media-store/app/src/pages/ManageStore.js delete mode 100644 media-store/app/src/pages/MyInvoicesPage.js delete mode 100644 media-store/app/src/pages/PersonPage.js delete mode 100644 media-store/app/src/pages/TracksPage.css delete mode 100644 media-store/app/src/pages/TracksPage.js delete mode 100644 media-store/app/src/pages/manage-store/AddAlbumForm.js delete mode 100644 media-store/app/src/pages/manage-store/AddArtistForm.js delete mode 100644 media-store/app/src/pages/manage-store/TrackForm.js delete mode 100644 media-store/app/src/pages/tracks/DeleteAction.js delete mode 100644 media-store/app/src/pages/tracks/EditAction.js delete mode 100644 media-store/app/src/pages/tracks/ManagedTrack.css delete mode 100644 media-store/app/src/pages/tracks/ManagedTrack.js delete mode 100644 media-store/app/src/pages/tracks/Track.js delete mode 100644 media-store/app/src/pages/tracks/TrackCardBody.js delete mode 100644 media-store/app/src/serviceWorker.js delete mode 100644 media-store/app/src/setupTests.js delete mode 100644 media-store/app/src/util/EventEmitter.js delete mode 100644 media-store/app/src/util/constants.js delete mode 100644 media-store/app/src/util/localStorageService.js delete mode 100644 media-store/app/src/util/validateUser.js delete mode 100644 media-store/app/xs-app.json delete mode 100644 media-store/approuter/package.json delete mode 100644 media-store/approuter/xs-app.json delete mode 100644 media-store/html5Deployer/package.json diff --git a/media-store/.gitignore b/media-store/.gitignore index 73962f43..1b6ca866 100644 --- a/media-store/.gitignore +++ b/media-store/.gitignore @@ -9,7 +9,10 @@ target/ package-lock.json # html5Deployer -html5Deployer/resources/app/ +deployers/html5Deployer/resources/app/ + +# app +app/ # Web IDE, App Studio .che/ diff --git a/media-store/app/.gitignore b/media-store/app/.gitignore deleted file mode 100644 index 4d29575d..00000000 --- a/media-store/app/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* diff --git a/media-store/app/.vscode/launch.json b/media-store/app/.vscode/launch.json deleted file mode 100644 index d4e0b5d5..00000000 --- a/media-store/app/.vscode/launch.json +++ /dev/null @@ -1,13 +0,0 @@ - -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Chrome", - "type": "chrome", - "request": "launch", - "url": "http://localhost:3000", - "webRoot": "${workspaceRoot}/src" - } - ] -} \ No newline at end of file diff --git a/media-store/app/favicon.ico b/media-store/app/favicon.ico deleted file mode 100644 index bcd5dfd67cd0361b78123e95c2dd96031f27f743..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3150 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 MDeX2GIKR{Qf5okjU;qFB diff --git a/media-store/app/index.html b/media-store/app/index.html deleted file mode 100644 index 28e725c5..00000000 --- a/media-store/app/index.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - React App - - - - -
- - - - \ No newline at end of file diff --git a/media-store/app/logo192.png b/media-store/app/logo192.png deleted file mode 100644 index fc44b0a3796c0e0a64c3d858ca038bd4570465d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5347 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 b{|{}U^kRn2wo}j7|0ATu<;8xA7zX}7|B6mN diff --git a/media-store/app/manifest.json b/media-store/app/manifest.json deleted file mode 100644 index 45979ace..00000000 --- a/media-store/app/manifest.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff", - "sap.app": { - "id": "mediastore", - "applicationVersion": { - "version": "1.0.0" - } - } -} diff --git a/media-store/app/package.json b/media-store/app/package.json deleted file mode 100644 index 6da78597..00000000 --- a/media-store/app/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "mediastore", - "version": "0.1.0", - "private": true, - "dependencies": { - "@testing-library/jest-dom": "^4.2.4", - "@testing-library/react": "^9.3.2", - "@testing-library/user-event": "^7.1.2", - "@umijs/hooks": "^1.9.3", - "antd": "^4.8.2", - "axios": "^0.20.0", - "events": "^3.2.0", - "lodash": "^4.17.20", - "moment": "^2.29.1", - "react": "^16.14.0", - "react-dom": "^16.14.0", - "react-inline-editing": "^1.0.10", - "react-router-dom": "^5.2.0", - "react-scripts": "^4.0.0" - }, - "scripts": { - "start": "react-scripts start --no-cache", - "build": "react-scripts build", - "test": "react-scripts test --no-cache", - "eject": "react-scripts eject" - }, - "eslintConfig": { - "extends": "react-app" - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - } -} diff --git a/media-store/app/public/favicon.ico b/media-store/app/public/favicon.ico deleted file mode 100644 index bcd5dfd67cd0361b78123e95c2dd96031f27f743..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3150 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 MDeX2GIKR{Qf5okjU;qFB diff --git a/media-store/app/public/index.html b/media-store/app/public/index.html deleted file mode 100644 index aa069f27..00000000 --- a/media-store/app/public/index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - React App - - - -
- - - diff --git a/media-store/app/public/logo192.png b/media-store/app/public/logo192.png deleted file mode 100644 index fc44b0a3796c0e0a64c3d858ca038bd4570465d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5347 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 b{|{}U^kRn2wo}j7|0ATu<;8xA7zX}7|B6mN diff --git a/media-store/app/public/manifest.json b/media-store/app/public/manifest.json deleted file mode 100644 index 45979ace..00000000 --- a/media-store/app/public/manifest.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff", - "sap.app": { - "id": "mediastore", - "applicationVersion": { - "version": "1.0.0" - } - } -} diff --git a/media-store/app/public/robots.txt b/media-store/app/public/robots.txt deleted file mode 100644 index e9e57dc4..00000000 --- a/media-store/app/public/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/media-store/app/public/xs-app.json b/media-store/app/public/xs-app.json deleted file mode 100644 index 930c40ee..00000000 --- a/media-store/app/public/xs-app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "welcomeFile": "/index.html", - "routes": [ - { - "source": "^(.*)", - "target": "$1", - "service": "html5-apps-repo-rt" - } - ] -} \ No newline at end of file diff --git a/media-store/app/robots.txt b/media-store/app/robots.txt deleted file mode 100644 index e9e57dc4..00000000 --- a/media-store/app/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/media-store/app/src/App.css b/media-store/app/src/App.css deleted file mode 100644 index 1ec8f2fe..00000000 --- a/media-store/app/src/App.css +++ /dev/null @@ -1,57 +0,0 @@ -@import "~antd/dist/antd.css"; - -html { - overflow: hidden; -} -#root { - height: 100%; -} -section.ant-layout { - height: 100vh; - overflow: auto; -} - -/* Layout -*/ -.site-layout .site-layout-background { - background: #fff; -} - -.App { - text-align: center; -} - -.App-logo { - height: 40vmin; - pointer-events: none; -} - -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/media-store/app/src/App.js b/media-store/app/src/App.js deleted file mode 100644 index c1794718..00000000 --- a/media-store/app/src/App.js +++ /dev/null @@ -1,18 +0,0 @@ -import React from "react"; -import "antd/dist/antd.css"; -import "./App.css"; -import { Layout } from "antd"; -import { MyRouter } from "./components/Router"; -import { AppStateContextProvider } from "./contexts/AppStateContext"; - -const App = () => { - return ( - - - - - - ); -}; - -export default App; diff --git a/media-store/app/src/api/axiosInstance.js b/media-store/app/src/api/axiosInstance.js deleted file mode 100644 index 49fd0fa6..00000000 --- a/media-store/app/src/api/axiosInstance.js +++ /dev/null @@ -1,21 +0,0 @@ -import axios from "axios"; -import { getUserFromLS, getLocaleFromLS } from "../util/localStorageService"; -import { - changeUserDefaults, - changeLocaleDefaults, -} from "./changeAxiosDefaults"; -import { API } from "../util/constants"; -import { responseErrorInterceptor } from "./responseErrorInterceptor"; - -const axiosInstance = axios.create({ - baseURL: API, - timeout: 2000, -}); -const user = getUserFromLS(); -const locale = getLocaleFromLS(); -changeUserDefaults(user); -changeLocaleDefaults(locale); - -axiosInstance.interceptors.response.use(null, responseErrorInterceptor); - -export { axiosInstance, changeLocaleDefaults, changeUserDefaults }; diff --git a/media-store/app/src/api/calls.js b/media-store/app/src/api/calls.js deleted file mode 100644 index fb35f412..00000000 --- a/media-store/app/src/api/calls.js +++ /dev/null @@ -1,188 +0,0 @@ -import { isEmpty } from "lodash"; -import { axiosInstance } from "./axiosInstance"; - -const BROWSE_TRACKS_SERVICE = "browse-tracks"; -const INVOICES_SERVICE = "browse-invoices"; -const USER_SERVICE = "users"; -const MANAGE_STORE = "manage-store"; - -const constructGenresQuery = (genreIds) => { - return !isEmpty(genreIds) - ? " and " + genreIds.map((value) => `genre_ID eq ${value}`).join(" or ") - : ""; -}; - -const fetchTacks = ({ - $top = 20, - $skip = 0, - genreIds = [], - substr = "", -} = {}) => { - const serializeTracksUrl = () => { - return `$expand=genre,album($expand=artist)&$top=${$top}&$skip=${$skip}&$filter=${ - `contains(name,'${substr}')` + constructGenresQuery(genreIds) - }`; - }; - - return axiosInstance.get( - `${BROWSE_TRACKS_SERVICE}/${axiosInstance.defaults.tracksEntity}`, - { - params: {}, - paramsSerializer: () => serializeTracksUrl(), - } - ); -}; - -const countTracks = ({ genreIds = [], substr = "" } = {}) => { - const tracksEntity = axiosInstance.defaults.tracksEntity; - - return axiosInstance.get( - `${BROWSE_TRACKS_SERVICE}/${tracksEntity}/$count?$filter=${ - `contains(name,'${substr}')` + constructGenresQuery(genreIds) - }` - ); -}; - -const fetchGenres = () => { - return axiosInstance.get(`${BROWSE_TRACKS_SERVICE}/Genres`); -}; - -const invoice = (tracks) => { - return axiosInstance.post( - `${INVOICES_SERVICE}/invoice`, - { - tracks: tracks.map(({ unitPrice, ID }) => ({ - unitPrice: `${unitPrice}`, - ID, - })), - }, - { - headers: { "content-type": "application/json;IEEE754Compatible=true" }, - } - ); -}; - -const fetchPerson = () => { - return axiosInstance.get( - `${USER_SERVICE}/${axiosInstance.defaults.userEntity}` - ); -}; - -const confirmPerson = (person) => { - return axiosInstance.put( - `${USER_SERVICE}/${axiosInstance.defaults.userEntity}`, - { - ...person, - }, - { - headers: { "content-type": "application/json" }, - } - ); -}; - -const fetchInvoices = () => { - return axiosInstance.get( - `${INVOICES_SERVICE}/Invoices?$expand=invoiceItems($expand=track($expand=album($expand=artist)))` - ); -}; - -const cancelInvoice = (ID) => { - return axiosInstance.post( - `${INVOICES_SERVICE}/cancelInvoice`, - { - ID, - }, - { - headers: { "content-type": "application/json" }, - } - ); -}; - -const fetchAlbumsByName = (substr = "", top) => { - return axiosInstance.get( - `${BROWSE_TRACKS_SERVICE}/Albums?$filter=${`contains(title,'${substr}')&$top=${top}`}` - ); -}; - -const addTrack = (data) => { - return axiosInstance.post(`${MANAGE_STORE}/Tracks`, data, { - headers: { "content-type": "application/json;IEEE754Compatible=true" }, - }); -}; - -const addArtist = (data) => { - return axiosInstance.post(`${MANAGE_STORE}/Artists`, data, { - headers: { "content-type": "application/json" }, - }); -}; - -const addAlbum = (data) => { - return axiosInstance.post(`${MANAGE_STORE}/Albums`, data, { - headers: { "content-type": "application/json" }, - }); -}; - -const fetchArtistsByName = (substr = "", top) => { - return axiosInstance.get( - `${MANAGE_STORE}/Artists?$filter=${`contains(name,'${substr}')&$top=${top}`}` - ); -}; - -const login = (data) => { - return axiosInstance.post(`${USER_SERVICE}/login`, data, { - headers: { "content-type": "application/json" }, - }); -}; - -const updateTrack = (track) => { - return axiosInstance.put( - `${MANAGE_STORE}/Tracks/${track.ID}`, - { - ...track, - }, - { - headers: { "content-type": "application/json;IEEE754Compatible=true" }, - } - ); -}; - -const getTrack = (ID) => { - return axiosInstance.get( - `${BROWSE_TRACKS_SERVICE}/${axiosInstance.defaults.tracksEntity}/${ID}?$expand=genre,album($expand=artist)` - ); -}; - -const deleteTrack = (ID) => { - return axiosInstance.delete(`${MANAGE_STORE}/Tracks(${ID})`); -}; - -const refreshTokens = (refreshToken) => { - return axiosInstance.post( - `${USER_SERVICE}/refreshTokens`, - { refreshToken }, - { - headers: { "content-type": "application/json" }, - } - ); -}; - -export { - fetchTacks, - countTracks, - fetchGenres, - invoice, - fetchPerson, - confirmPerson, - fetchInvoices, - cancelInvoice, - fetchAlbumsByName, - addTrack, - addArtist, - addAlbum, - fetchArtistsByName, - login, - updateTrack, - getTrack, - deleteTrack, - refreshTokens, -}; diff --git a/media-store/app/src/api/changeAxiosDefaults.js b/media-store/app/src/api/changeAxiosDefaults.js deleted file mode 100644 index be816790..00000000 --- a/media-store/app/src/api/changeAxiosDefaults.js +++ /dev/null @@ -1,27 +0,0 @@ -import { axiosInstance } from "./axiosInstance"; - -function changeUserDefaults(currentUser) { - if (currentUser) { - axiosInstance.defaults.headers.common[ - "Authorization" - ] = `Basic ${currentUser.accessToken}`; - axiosInstance.defaults.userID = currentUser.ID; - if (currentUser.roles.includes("customer")) { - axiosInstance.defaults.userEntity = `Customers/${currentUser.ID}`; - axiosInstance.defaults.tracksEntity = "MarkedTracks"; - } else { - axiosInstance.defaults.userEntity = `Employees/${currentUser.ID}`; - axiosInstance.defaults.tracksEntity = "Tracks"; - } - } else { - axiosInstance.defaults.tracksEntity = "Tracks"; - } -} - -function changeLocaleDefaults(locale) { - if (locale) { - axiosInstance.defaults.headers.common["Accept-language"] = locale; - } -} - -export { changeLocaleDefaults, changeUserDefaults }; diff --git a/media-store/app/src/api/responseErrorInterceptor.js b/media-store/app/src/api/responseErrorInterceptor.js deleted file mode 100644 index 40824e4d..00000000 --- a/media-store/app/src/api/responseErrorInterceptor.js +++ /dev/null @@ -1,62 +0,0 @@ -import { emitter } from "../util/EventEmitter"; -import { axiosInstance } from "./axiosInstance"; -import { refreshTokens } from "./calls"; -import { getUserFromLS } from "../util/localStorageService"; - -let isRefreshing = false; -let subscribers = []; - -function responseErrorInterceptor(error) { - const originalRequest = error.config; - const user = getUserFromLS(); - - if (error.response && error.response.status === 401 && !!user) { - if (originalRequest.url === "users/login") { - return Promise.reject(error); - } - - // if users/refreshTokens request failed - if (isRefreshing && originalRequest.url === "users/refreshTokens") { - subscribers.forEach((request) => request.reject(error)); - subscribers = []; - isRefreshing = false; - return Promise.reject(error); - } - - // if got a 401 error we sending users/refreshTokens request - if (!isRefreshing) { - isRefreshing = true; - - refreshTokens(user.refreshToken) - .then((response) => { - emitter.emit("UPDATE_USER", response.data); - subscribers.forEach((request) => - request.resolve(response.data.accessToken) - ); - subscribers = []; - isRefreshing = false; - }) - .catch(() => { - emitter.emit("UPDATE_USER", undefined); - }); - } - - // holding requests which should be sended after users/refreshTokens complete - // otherwise if users/refreshTokens failed an error will be thrown - return new Promise((resolve, reject) => { - subscribers.push({ - resolve: (newAccessToken) => { - originalRequest.headers.Authorization = "Basic " + newAccessToken; - resolve(axiosInstance(originalRequest)); - }, - reject: (err) => { - reject(err); - }, - }); - }); - } - - return Promise.reject(error); -} - -export { responseErrorInterceptor }; diff --git a/media-store/app/src/components/Header.css b/media-store/app/src/components/Header.css deleted file mode 100644 index 3d78184d..00000000 --- a/media-store/app/src/components/Header.css +++ /dev/null @@ -1,3 +0,0 @@ -.ant-menu-item .anticon { - margin: 0; -} diff --git a/media-store/app/src/components/Header.js b/media-store/app/src/components/Header.js deleted file mode 100644 index 495ef11b..00000000 --- a/media-store/app/src/components/Header.js +++ /dev/null @@ -1,158 +0,0 @@ -import React from "react"; -import { Menu, Badge, Spin } from "antd"; -import { isEmpty } from "lodash"; -import { - CreditCardOutlined, - LogoutOutlined, - LoginOutlined, - LoadingOutlined, -} from "@ant-design/icons"; -import { useHistory, useLocation } from "react-router-dom"; -import { useAppState } from "../hooks/useAppState"; -import { setLocaleToLS } from "../util/localStorageService"; -import { changeLocaleDefaults } from "../api/axiosInstance"; -import { emitter } from "../util/EventEmitter"; -import "./Header.css"; -import { requireEmployee, requireCustomer } from "../util/constants"; - -const { SubMenu } = Menu; - -const keys = ["/", "/person", "/login", "/manage", "/invoice", "/invoices"]; -const AVAILABLE_LOCALES = ["en", "fr", "de"]; -const RELOAD_LOCATION_NUMBER = 0; - -const Header = () => { - const history = useHistory(); - const location = useLocation(); - const { - user, - invoicedItems, - setInvoicedItems, - locale, - setLocale, - loading, - } = useAppState(); - const currentKey = [keys.find((key) => key === location.pathname)]; - const haveInvoicedItems = !isEmpty(invoicedItems); - const invoicedItemsLength = invoicedItems.length; - - const onChangeLocale = (value) => { - setLocaleToLS(value); - changeLocaleDefaults(value); - setLocale(value); - history.go(RELOAD_LOCATION_NUMBER); - }; - const localeElements = AVAILABLE_LOCALES.filter( - (localeName) => localeName !== locale - ).map((curLocale, index) => ( - onChangeLocale(curLocale)} - > - {curLocale} - - )); - - const onUserLogout = () => { - emitter.emit("UPDATE_USER", undefined); - history.go(0); - }; - - return ( -
- - history.push("/")}> - Browse - - - {!!user && ( - history.push("/person")}> - Profile - - )} - {requireCustomer(user) && ( - history.push("/invoices")}> - Invoices - - )} - {requireEmployee(user) && ( - history.push("/manage")}> - Manage - - )} - - {loading && ( - } - /> - )} - - - - - {haveInvoicedItems && ( - history.push("/invoice")} - key="/invoice" - > -
- - - -
-
- )} - - {localeElements} - - {!!user ? ( - } - > - ) : ( - history.push("/login")} - icon={} - > - )} -
-
- ); -}; - -export { Header }; diff --git a/media-store/app/src/components/Router.js b/media-store/app/src/components/Router.js deleted file mode 100644 index caa69a6e..00000000 --- a/media-store/app/src/components/Router.js +++ /dev/null @@ -1,58 +0,0 @@ -import React from "react"; -import { BrowserRouter as Router, Switch, Route } from "react-router-dom"; -import { isEmpty } from "lodash"; -import { TracksContainer } from "../pages/TracksPage"; -import { Header } from "../components/Header"; -import { PersonPage } from "../pages/PersonPage"; -import { ErrorPage } from "../pages/ErrorPage"; -import { Login } from "../pages/Login"; -import { withRestrictions } from "../hocs/withRestrictions"; -import { InvoicePage } from "../pages/InvoicePage"; -import { ManageStore } from "../pages/ManageStore"; -import { MyInvoicesPage } from "../pages/MyInvoicesPage"; -import { requireEmployee } from "../util/constants"; - -const RestrictedLogin = withRestrictions(Login, ({ user }) => !user); -const RestrictedInvoicePage = withRestrictions( - InvoicePage, - ({ user, invoicedItems }) => !requireEmployee(user) && !isEmpty(invoicedItems) -); -const RestrictedPersonPage = withRestrictions(PersonPage, ({ user }) => !!user); -const RestrictedManageStore = withRestrictions(ManageStore, ({ user }) => - requireEmployee(user) -); - -const MyRouter = () => { - return ( - -
-
- - - - - - - - - - - - - - - - - - - - - - - -
- - ); -}; - -export { MyRouter }; diff --git a/media-store/app/src/contexts/AppStateContext.js b/media-store/app/src/contexts/AppStateContext.js deleted file mode 100644 index e0029d6e..00000000 --- a/media-store/app/src/contexts/AppStateContext.js +++ /dev/null @@ -1,71 +0,0 @@ -import React, { useMemo, createContext, useState, useEffect } from "react"; -import { - getUserFromLS, - getLocaleFromLS, - setUserToLS, -} from "../util/localStorageService"; -import { changeUserDefaults } from "../api/axiosInstance"; -import { emitter } from "../util/EventEmitter"; - -let counter = 0; - -const globalContext = { - error: {}, - loading: true, - user: { - ID: undefined, - roles: [], - email: undefined, - accessToken: undefined, - refreshToken: undefined, - }, - locale: undefined, - invoicedItems: [], - notifications: [], -}; -const AppStateContext = createContext(globalContext); - -const AppStateContextProvider = ({ children }) => { - const [invoicedItems, setInvoicedItems] = useState([]); - const [loading, setLoading] = useState(false); - const [error, setError] = useState({}); - const [user, setUser] = useState(getUserFromLS()); - const [locale, setLocale] = useState(getLocaleFromLS()); - - useEffect(() => { - const updateUser = (newUser) => { - console.log("USER_UPDATE WAS TRIGGERED", counter++); - changeUserDefaults(newUser); - setUserToLS(newUser); - setUser(newUser); - }; - emitter.on("UPDATE_USER", updateUser); - return () => { - emitter.removeListener("UPDATE_USER", updateUser); - }; - }, []); - - const value = useMemo( - () => ({ - error: error, - loading: loading, - invoicedItems: invoicedItems, - user: user, - locale: locale, - setLoading, - setError, - setInvoicedItems, - setUser: setUser, - setLocale: setLocale, - }), - [locale, user, loading, error, invoicedItems] - ); - - return ( - - {children} - - ); -}; - -export { AppStateContextProvider, AppStateContext }; diff --git a/media-store/app/src/hocs/withRestrictions.js b/media-store/app/src/hocs/withRestrictions.js deleted file mode 100644 index 525cbae7..00000000 --- a/media-store/app/src/hocs/withRestrictions.js +++ /dev/null @@ -1,16 +0,0 @@ -import React from "react"; -import { Redirect } from "react-router-dom"; -import { useAppState } from "../hooks/useAppState"; - -const withRestrictions = (Component, isUserMeetRestrictions) => { - return (props) => { - const { user, invoicedItems } = useAppState(); - return isUserMeetRestrictions({ user, invoicedItems }) ? ( - - ) : ( - - ); - }; -}; - -export { withRestrictions }; diff --git a/media-store/app/src/hooks/useAbortableEffect.js b/media-store/app/src/hooks/useAbortableEffect.js deleted file mode 100644 index 6fa18e87..00000000 --- a/media-store/app/src/hooks/useAbortableEffect.js +++ /dev/null @@ -1,22 +0,0 @@ -import { useEffect } from "react"; - -function useAbortableEffect(effect, dependencies) { - const status = {}; // mutable status object - useEffect(() => { - status.aborted = false; - // pass the mutable object to the effect callback - // store the returned value for cleanup - const cleanUpFn = effect(status); - return () => { - // mutate the object to signal the consumer - // this effect is cleaning up - status.aborted = true; - if (typeof cleanUpFn === "function") { - // run the cleanup function - cleanUpFn(); - } - }; - }, [...dependencies]); -} - -export { useAbortableEffect }; diff --git a/media-store/app/src/hooks/useAppState.js b/media-store/app/src/hooks/useAppState.js deleted file mode 100644 index 6ea35f5f..00000000 --- a/media-store/app/src/hooks/useAppState.js +++ /dev/null @@ -1,6 +0,0 @@ -import { useContext } from "react"; -import { AppStateContext } from "../contexts/AppStateContext"; - -const useAppState = () => useContext(AppStateContext); - -export { useAppState }; diff --git a/media-store/app/src/hooks/useErrors.js b/media-store/app/src/hooks/useErrors.js deleted file mode 100644 index 086a5a04..00000000 --- a/media-store/app/src/hooks/useErrors.js +++ /dev/null @@ -1,34 +0,0 @@ -import { useHistory } from "react-router-dom"; -import { useAppState } from "./useAppState"; - -const useErrors = () => { - const history = useHistory(); - const { setError } = useAppState(); - - const handleError = (error) => { - console.error("Error", error); - - if (error.response) { - const { status, statusText, data } = error.response; - setError({ - status, - statusText, - message: data.error ? data.error.message : data, - }); - } else { - setError({ - status: "", - statusText: "Error", - message: "Something went wrong. Seems like request is too long", - }); - } - - history.push("/error"); - }; - - return { - handleError, - }; -}; - -export { useErrors }; diff --git a/media-store/app/src/index.js b/media-store/app/src/index.js deleted file mode 100644 index c1684e83..00000000 --- a/media-store/app/src/index.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from "react"; -import ReactDOM from "react-dom"; -import App from "./App"; -import * as serviceWorker from "./serviceWorker"; - -ReactDOM.render(, document.getElementById("root")); - -// If you want your app to work offline and load faster, you can change -// unregister() to register() below. Note this comes with some pitfalls. -// Learn more about service workers: https://bit.ly/CRA-PWA -serviceWorker.unregister(); diff --git a/media-store/app/src/logo.svg b/media-store/app/src/logo.svg deleted file mode 100644 index 6b60c104..00000000 --- a/media-store/app/src/logo.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/media-store/app/src/pages/ErrorPage.js b/media-store/app/src/pages/ErrorPage.js deleted file mode 100644 index 77a68af8..00000000 --- a/media-store/app/src/pages/ErrorPage.js +++ /dev/null @@ -1,50 +0,0 @@ -import React from "react"; -import { useHistory } from "react-router-dom"; -import { isEmpty } from "lodash"; -import { Result, Button } from "antd"; -import { useAppState } from "../hooks/useAppState"; - -const ErrorPage = () => { - const { error, setError } = useAppState(); - const history = useHistory(); - - const onGoHome = () => { - setError({}); - history.push("/"); - }; - - const goLoginPage = () => { - setError({}); - history.push("/login"); - }; - - const goHomeButton = ( - - ); - const goLoginButton = ( - - ); - - const errorResultProps = isEmpty(error) - ? { - status: 404, - title: "Not found", - subTitle: "Sorry, the page you visited does not exist.", - extra: goHomeButton, - } - : { - status: [404, 403, 500].includes(error.status) ? error.status : "error", - title: error.statusText, - subTitle: error.message, - extra: - error.status === 401 ? [goHomeButton, goLoginButton] : goHomeButton, - }; - - return ; -}; - -export { ErrorPage }; diff --git a/media-store/app/src/pages/InvoicePage.js b/media-store/app/src/pages/InvoicePage.js deleted file mode 100644 index a4644e97..00000000 --- a/media-store/app/src/pages/InvoicePage.js +++ /dev/null @@ -1,107 +0,0 @@ -import React from "react"; -import { Table, Button, message } from "antd"; -import { useAppState } from "../hooks/useAppState"; -import { useHistory } from "react-router-dom"; -import { invoice } from "../api/calls"; -import { useErrors } from "../hooks/useErrors"; -import { MESSAGE_TIMEOUT } from "../util/constants"; - -const columns = [ - { - title: "Name", - dataIndex: "name", - }, - { - title: "Artist", - dataIndex: "artist", - }, - { - title: "Album", - dataIndex: "albumTitle", - }, - { - title: "Price", - dataIndex: "unitPrice", - }, -]; - -const InvoicePage = () => { - const history = useHistory(); - const { handleError } = useErrors(); - const { user, invoicedItems, setInvoicedItems, setLoading } = useAppState(); - - const data = invoicedItems.map(({ ID, ...otherProps }) => ({ - key: `invoiceItem${ID}`, - ...otherProps, - })); - - const onBuy = () => { - setLoading(true); - invoice( - invoicedItems.map(({ ID, unitPrice }) => ({ - ID, - unitPrice, - })) - ) - .then(() => { - setInvoicedItems([]); - message.success("Invoice successfully completed", MESSAGE_TIMEOUT); - history.push("/invoices"); - }) - .catch(handleError) - .finally(() => setLoading(false)); - }; - const onCancel = () => { - setInvoicedItems([]); - history.push("/"); - }; - const goLogin = () => { - history.push("/login"); - }; - - return ( -
- ( -
- {user ? ( - <> - - - - ) : ( -
- - to buy selected -
- )} -
- )} - /> - - ); -}; - -export { InvoicePage }; diff --git a/media-store/app/src/pages/Login.js b/media-store/app/src/pages/Login.js deleted file mode 100644 index 3efd5a6d..00000000 --- a/media-store/app/src/pages/Login.js +++ /dev/null @@ -1,107 +0,0 @@ -import React from "react"; -import { Form, Input, Button, Checkbox, message } from "antd"; -import { login } from "../api/calls"; -import { useHistory } from "react-router-dom"; -import { useAppState } from "../hooks/useAppState"; -import { useErrors } from "../hooks/useErrors"; -import { MESSAGE_TIMEOUT } from "../util/constants"; -import { emitter } from "../util/EventEmitter"; - -const layout = { - labelCol: { - span: 8, - }, - wrapperCol: { - span: 8, - }, -}; -const tailLayout = { - wrapperCol: { - offset: 8, - span: 8, - }, -}; - -const Login = () => { - const [form] = Form.useForm(); - const history = useHistory(); - const { setLoading, setInvoicedItems } = useAppState(); - const { handleError } = useErrors(); - - const onFinish = (values) => { - setLoading(true); - login({ email: values.email, password: values.password }) - .then(({ data: user }) => { - emitter.emit("UPDATE_USER", user); - if (user.roles.includes("employee")) { - setInvoicedItems([]); - } - history.push("/"); - }) - .catch((error) => { - console.log(error); - if (error.response && error.response.status === 401) { - form.resetFields(); - message.error("Invalid credentials!", MESSAGE_TIMEOUT); - } else { - handleError(error); - } - }) - .finally(() => setLoading(false)); - }; - - const onFinishFailed = (errorInfo) => { - console.log("Validation Failed:", errorInfo); - }; - - return ( - - - - - - - - - - - Remember me - - - - - - - ); -}; - -export { Login }; diff --git a/media-store/app/src/pages/ManageStore.js b/media-store/app/src/pages/ManageStore.js deleted file mode 100644 index c23c2e33..00000000 --- a/media-store/app/src/pages/ManageStore.js +++ /dev/null @@ -1,115 +0,0 @@ -import React, { useState, useMemo, useEffect } from "react"; -import { Form, Radio, Button, message } from "antd"; -import { TrackForm } from "./manage-store/TrackForm"; -import { AddArtistForm } from "./manage-store/AddArtistForm"; -import { AddAlbumForm } from "./manage-store/AddAlbumForm"; -import { useErrors } from "../hooks/useErrors"; -import { useAppState } from "../hooks/useAppState"; -import { addTrack, addArtist, addAlbum } from "../api/calls"; -import { MESSAGE_TIMEOUT } from "../util/constants"; - -const FORM_TYPES = { - track: "track", - artist: "artist", - album: "album", - playlist: "", -}; - -const chooseForm = (type) => { - return ( - (type === "track" && ) || - (type === "artist" && ) || - (type === "album" && ) - ); -}; - -const ManageStore = () => { - const [form] = Form.useForm(); - const { handleError } = useErrors(); - const { setLoading } = useAppState(); - const [formType, setFormType] = useState("track"); - - useEffect(() => { - form.resetFields(); - }, [formType]); - - const formElement = useMemo(() => { - return chooseForm(formType); - }, [formType]); - - const onChangeForm = (event) => { - setFormType(event.target.value); - }; - - const sendCreateRequest = ({ type, ...data }) => { - setLoading(true); - - let promise; - switch (type) { - case FORM_TYPES.track: - promise = addTrack({ - name: data.name, - composer: data.composer, - album: { ID: data.albumID }, - genre: { ID: data.genreID }, - unitPrice: data.unitPrice.toString(), - }); - break; - case FORM_TYPES.artist: - promise = addArtist(data); - break; - case FORM_TYPES.album: - promise = addAlbum({ title: data.name, artist: { ID: data.artistID } }); - break; - default: - } - - promise - .then(() => { - message.success("Entity successfully created", MESSAGE_TIMEOUT); - form.resetFields(); - }) - .catch(handleError) - .finally(() => setLoading(false)); - }; - - return ( -
console.log("Not valid params provided")} - > - - - Track - Album - Artist - - - {formElement} - - - - - ); -}; - -export { ManageStore }; diff --git a/media-store/app/src/pages/MyInvoicesPage.js b/media-store/app/src/pages/MyInvoicesPage.js deleted file mode 100644 index fb7053e8..00000000 --- a/media-store/app/src/pages/MyInvoicesPage.js +++ /dev/null @@ -1,185 +0,0 @@ -import React, { useState, useEffect, useMemo, useCallback } from "react"; -import { Button, message, Tag, Collapse, Table, Spin } from "antd"; -import moment from "moment"; -import { useErrors } from "../hooks/useErrors"; -import { useAppState } from "../hooks/useAppState"; -import { cancelInvoice, fetchInvoices } from "../api/calls"; -import { MESSAGE_TIMEOUT } from "../util/constants"; - -const { Panel } = Collapse; -const INVOICE_STATUS = { - 2: { - tagTitle: "Shipped", - color: "green", - }, - 1: { - tagTitle: "Submitted", - color: "processing", - canCancel: true, - }, - ["-1"]: { - tagTitle: "Cancelled", - color: "default", - }, -}; -const CANCELLED_STATUS = -1; -const DATE_TIME_FORMAT_PATTERN = "LLLL"; -const UTC_DATE_TIME_FORMAT = "YYYY-MM-DDThh:mm:ss"; -const INVOICE_ITEMS_COLUMNS = [ - { - title: "Track name", - dataIndex: "name", - }, - { - title: "Artist", - dataIndex: "artistName", - }, - { - title: "Album", - dataIndex: "albumTitle", - }, - { - title: "Price", - dataIndex: "unitPrice", - }, -]; -const LEVERAGE_DURATION = 1; // in hours -const STATUSES = { submitted: 1, shipped: 2, canceled: -1 }; - -const isLeverageTimeExpired = (utcNowTimestamp, invoiceDate) => { - const duration = moment.duration( - moment(utcNowTimestamp).diff(moment(invoiceDate).valueOf()) - ); - return duration.asHours() > LEVERAGE_DURATION; -}; - -const chooseStatus = (utcNowTimestamp, invoiceDate, statusFromDb) => { - if ( - isLeverageTimeExpired(utcNowTimestamp, invoiceDate) && - statusFromDb !== STATUSES.canceled - ) { - return INVOICE_STATUS[STATUSES.shipped]; - } - return INVOICE_STATUS[statusFromDb]; -}; - -const ExtraHeader = ({ ID, invoiceDate, status: initialStatus }) => { - const { loading, setLoading } = useAppState(); - const { handleError } = useErrors(); - const [loadingHeaderId, setLoadingHeaderId] = useState(); - const [status, setStatus] = useState(initialStatus); - - const statusConfig = useMemo(() => { - const utcNowTimestamp = moment( - moment().utc().format(UTC_DATE_TIME_FORMAT) - ).valueOf(); - return chooseStatus(utcNowTimestamp, invoiceDate, status); - }, [status]); - - const onCancelInvoice = (event, ID) => { - event.stopPropagation(); - setLoading(true); - setLoadingHeaderId(ID); - cancelInvoice(ID) - .then(() => { - message.success("Invoice successfully cancelled", MESSAGE_TIMEOUT); - setLoadingHeaderId(undefined); - setStatus(CANCELLED_STATUS); - }) - .catch(handleError) - .finally(() => setLoading(false)); - }; - - return ( - - {statusConfig.tagTitle} - {statusConfig.canCancel && ( - - )} - - ); -}; - -const MyInvoicesPage = () => { - const { handleError } = useErrors(); - const { setLoading } = useAppState(); - const [invoices, setInvoices] = useState([]); - - useEffect(() => { - setLoading(true); - fetchInvoices() - .then(({ data: { value } }) => setInvoices(value)) - .catch(handleError) - .finally(() => setLoading(false)); - }, []); - - const genExtra = useCallback( - (ID, status, invoiceDate) => ( - - ), - [] - ); - const invoiceElements = useMemo(() => { - return invoices.map(({ ID, status, invoiceDate, total, invoiceItems }) => { - const invoiceItemsData = invoiceItems.map( - ({ - ID, - track: { - name, - unitPrice, - album: { - title: albumTitle, - artist: { name: artistName }, - }, - }, - }) => ({ - key: ID, - ID, - name, - unitPrice, - albumTitle, - artistName, - }) - ); - - return ( - -
-
( - {`Total price: ${total}`} - )} - /> - - - ); - }); - }, [invoices]); - - return ( -
- {invoiceElements && ( - {invoiceElements} - )} -
- ); -}; - -export { MyInvoicesPage }; diff --git a/media-store/app/src/pages/PersonPage.js b/media-store/app/src/pages/PersonPage.js deleted file mode 100644 index e941c4a6..00000000 --- a/media-store/app/src/pages/PersonPage.js +++ /dev/null @@ -1,108 +0,0 @@ -import React, { useState } from "react"; -import { Form, Button, message, Input } from "antd"; -import { omit, map } from "lodash"; -import { fetchPerson, confirmPerson } from "../api/calls"; -import { useErrors } from "../hooks/useErrors"; -import { useAppState } from "../hooks/useAppState"; -import { MESSAGE_TIMEOUT } from "../util/constants"; -import { useAbortableEffect } from "../hooks/useAbortableEffect"; - -const PERSON_PROP = { - address: "Address ", - city: "City ", - country: "Country ", - fax: "Fax: ", - firstName: "First name: ", - lastName: "Last name: ", - phone: "Phone: ", - postalCode: "Postal code: ", - state: "State", - email: "email", - company: "Company: ", -}; - -const PersonPage = () => { - const { setLoading } = useAppState(); - const { handleError } = useErrors(); - const [form] = Form.useForm(); - const [person, setPerson] = useState({ - lastName: "", - firstName: "", - city: "", - state: "", - address: "", - country: "", - phone: "", - postalCode: "", - fax: "", - email: "", - company: "", - }); - - useAbortableEffect((status) => { - setLoading(true); - - fetchPerson() - .then(({ data: personData }) => { - personData = omit(personData, "@odata.context", "ID"); - if (!status.aborted) { - setPerson(personData); - } - }) - .catch(handleError) - .finally(() => setLoading(false)); - }, []); - - const onConfirmChanges = (newPerson) => { - setLoading(true); - confirmPerson(newPerson) - .then(() => { - message.success("Person successfully updated", MESSAGE_TIMEOUT); - }) - .catch(handleError) - .finally(() => setLoading(false)); - }; - - const personProperties = map(Object.keys(person), (currentKey) => ( -
- - - -
- )); - - return ( - <> - {person.lastName !== "" && ( - console.log("Not valid params provided")} - initialValues={{ - ...person, - }} - > - {personProperties} - - - - - )} - - ); -}; - -export { PersonPage }; diff --git a/media-store/app/src/pages/TracksPage.css b/media-store/app/src/pages/TracksPage.css deleted file mode 100644 index c3855497..00000000 --- a/media-store/app/src/pages/TracksPage.css +++ /dev/null @@ -1,4 +0,0 @@ -.ant-select > div.ant-select-selector { - padding: 5px; - min-width: 300px; -} diff --git a/media-store/app/src/pages/TracksPage.js b/media-store/app/src/pages/TracksPage.js deleted file mode 100644 index f3842535..00000000 --- a/media-store/app/src/pages/TracksPage.js +++ /dev/null @@ -1,219 +0,0 @@ -import React, { useState } from "react"; -import { debounce } from "lodash"; -import { Input, Col, Row, Select, Pagination } from "antd"; -import { Track } from "./tracks/Track"; -import { ManagedTrack } from "./tracks/ManagedTrack"; -import { useAppState } from "../hooks/useAppState"; -import { useErrors } from "../hooks/useErrors"; -import { fetchTacks, countTracks, fetchGenres } from "../api/calls"; -import { useAbortableEffect } from "../hooks/useAbortableEffect"; -import { requireEmployee } from "../util/constants"; -import "./TracksPage.css"; - -const { Search } = Input; -const { Option } = Select; - -const DEBOUNCE_TIMER = 500; -const DEBOUNCE_OPTIONS = { - leading: true, - trailing: false, -}; - -const renderGenres = (genres) => - genres.map(({ ID, name }) => ( - - )); - -const TracksContainer = () => { - const { setLoading, user } = useAppState(); - const { handleError } = useErrors(); - const [state, setState] = useState({ - tracks: [], - genres: [], - pagination: { - currentPage: 1, - totalItems: 0, - pageSize: 20, - }, - searchOptions: { - substr: "", - genreIds: [], - }, - }); - - useAbortableEffect((status) => { - setLoading(true); - - const countTracksReq = countTracks(); - const getTracksRequest = fetchTacks(); - const getGenresReq = fetchGenres(); - - Promise.all([countTracksReq, getTracksRequest, getGenresReq]) - .then( - ([ - { data: totalItems }, - { - data: { value: tracks }, - }, - { - data: { value: genres }, - }, - ]) => { - if (!status.aborted) { - setState({ - ...state, - tracks, - genres, - pagination: { ...state.pagination, totalItems }, - }); - } - } - ) - .catch(handleError) - .finally(() => setLoading(false)); - }, []); - - const onSearch = debounce( - () => { - setLoading(true); - const options = { - $top: state.pagination.pageSize, - substr: state.searchOptions.substr, - genreIds: state.searchOptions.genreIds, - }; - - Promise.all([ - fetchTacks(options), - countTracks({ - substr: options.substr, - genreIds: options.genreIds, - }), - ]) - .then(([{ data: { value: tracks } }, { data: totalItems }]) => - setState({ - ...state, - tracks, - pagination: { ...state.pagination, totalItems }, - }) - ) - .catch(handleError) - .finally(() => setLoading(false)); - }, - DEBOUNCE_TIMER, - DEBOUNCE_OPTIONS - ); - const onSelectChange = (genres) => { - setState({ - ...state, - searchOptions: { - ...state.searchOptions, - genreIds: genres.map((value) => parseInt(value, 10)), - }, - }); - }; - const onSearchChange = (event) => { - setState({ - ...state, - searchOptions: { ...state.searchOptions, substr: event.target.value }, - }); - }; - const onChangePage = (pageNumber) => { - document - .querySelector("section.ant-layout") - .scrollTo({ top: 0, left: 0, behavior: "smooth" }); - setLoading(true); - - const options = { - $top: state.pagination.pageSize, - substr: state.searchOptions.substr, - genreIds: state.searchOptions.genreIds, - $skip: (pageNumber - 1) * state.pagination.pageSize, - }; - fetchTacks(options) - .then((response) => - setState({ - ...state, - tracks: response.data.value, - pagination: { ...state.pagination, currentPage: pageNumber }, - }) - ) - .catch(handleError) - .finally(() => setLoading(false)); - }; - const deleteTrack = (ID) => { - setState({ - ...state, - tracks: state.tracks.filter(({ ID: curID }) => curID !== ID), - }); - }; - const renderTracks = (tracks) => { - const isEmployee = requireEmployee(user); - const TrackComponent = isEmployee ? ManagedTrack : Track; - return tracks.map((track) => { - const isAlreadyOrdered = !isEmployee && track.alreadyOrdered; - const onDeleteTrack = isEmployee && ((ID) => deleteTrack(ID)); - return ( - - - - ); - }); - }; - - const trackElements = renderTracks(state.tracks); - const genreElements = renderGenres(state.genres); - - return ( - <> -
- - -
-
- - {trackElements} - -
-
- -
- - ); -}; - -export { TracksContainer }; diff --git a/media-store/app/src/pages/manage-store/AddAlbumForm.js b/media-store/app/src/pages/manage-store/AddAlbumForm.js deleted file mode 100644 index 2aa219ac..00000000 --- a/media-store/app/src/pages/manage-store/AddAlbumForm.js +++ /dev/null @@ -1,62 +0,0 @@ -import React, { useEffect } from "react"; -import { Form, Input, Select } from "antd"; -import { useSearch } from "@umijs/hooks"; -import { useErrors } from "../../hooks/useErrors"; -import { fetchArtistsByName } from "../../api/calls"; - -const REQUIRED = [ - { - required: true, - message: "This filed is required!", - }, -]; -const ARTISTS_LIMIT = 10; - -const getArtists = function (value) { - return fetchArtistsByName(value, ARTISTS_LIMIT) - .then((response) => response.data.value) - .catch(this.handleError); -}; - -const AddAlbumForm = () => { - const { handleError } = useErrors(); - const { - data: artists, - loading: isArtistsLoading, - onChange: onChangeArtistInput, - cancel: onArtistCancel, - } = useSearch(getArtists.bind({ handleError })); - - useEffect(() => { - onChangeArtistInput(); - }, []); - - return ( - <> -

Add album

- - - - - - - - ); -}; - -export { AddAlbumForm }; diff --git a/media-store/app/src/pages/manage-store/AddArtistForm.js b/media-store/app/src/pages/manage-store/AddArtistForm.js deleted file mode 100644 index ed31f9d6..00000000 --- a/media-store/app/src/pages/manage-store/AddArtistForm.js +++ /dev/null @@ -1,22 +0,0 @@ -import React from "react"; -import { Form, Input } from "antd"; - -const REQUIRED = [ - { - required: true, - message: "This filed is required!", - }, -]; - -const AddArtistForm = () => { - return ( - <> -

Add artist

- - - - - ); -}; - -export { AddArtistForm }; diff --git a/media-store/app/src/pages/manage-store/TrackForm.js b/media-store/app/src/pages/manage-store/TrackForm.js deleted file mode 100644 index 3724dc85..00000000 --- a/media-store/app/src/pages/manage-store/TrackForm.js +++ /dev/null @@ -1,93 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { Form, Input, Select, InputNumber } from "antd"; -import { head } from "lodash"; -import { useSearch } from "@umijs/hooks"; -import { useAppState } from "../../hooks/useAppState"; -import { fetchAlbumsByName, fetchGenres } from "../../api/calls"; -import { useErrors } from "../../hooks/useErrors"; - -const ALBUMS_LIMIT = 10; -const REQUIRED = [ - { - required: true, - message: "This filed is required!", - }, -]; - -const getAlbums = function (value) { - return fetchAlbumsByName(value, ALBUMS_LIMIT) - .then((response) => response.data.value) - .catch(this.handleError); -}; - -const TrackForm = ({ initialAlbumTitle }) => { - const { handleError } = useErrors(); - const { - data: albums, - loading: isAlbumsLoading, - onChange: onChangeAlbumInput, - cancel: onAlbumCancel, - } = useSearch(getAlbums.bind({ handleError })); - const { setLoading } = useAppState(); - const [genres, setGenres] = useState([]); - - useEffect(() => { - setLoading(true); - Promise.all([fetchGenres(), onChangeAlbumInput(initialAlbumTitle)]) - .then((responses) => setGenres(head(responses).data.value)) - .catch(handleError) - .finally(() => setLoading(false)); - }, []); - - return ( -
- - - - - - - - - - - - - - value.replace(/\$\s?|(,*)/g, "")} - /> - -
- ); -}; - -export { TrackForm }; diff --git a/media-store/app/src/pages/tracks/DeleteAction.js b/media-store/app/src/pages/tracks/DeleteAction.js deleted file mode 100644 index 34e8cd33..00000000 --- a/media-store/app/src/pages/tracks/DeleteAction.js +++ /dev/null @@ -1,43 +0,0 @@ -import React, { useState } from "react"; -import { Modal, message } from "antd"; -import { DeleteOutlined } from "@ant-design/icons"; -import { deleteTrack } from "../../api/calls"; -import { useErrors } from "../../hooks/useErrors"; -import { MESSAGE_TIMEOUT } from "../../util/constants"; - -const DeleteAction = ({ ID, onDeleteTrack }) => { - const [modalVisible, setModalVisible] = useState(false); - const { handleError } = useErrors(); - - const onOk = () => { - setModalVisible(false); - deleteTrack(ID) - .then(() => { - onDeleteTrack(); - setModalVisible(false); - message.success("Track successfully deleted!", MESSAGE_TIMEOUT); - }) - .catch(handleError); - }; - - const onCancel = () => setModalVisible(false); - const onOpenModal = () => { - setModalVisible(true); - }; - - return ( - <> - Delete - -

Are You really want to delete this track?

-
- - ); -}; - -export { DeleteAction }; diff --git a/media-store/app/src/pages/tracks/EditAction.js b/media-store/app/src/pages/tracks/EditAction.js deleted file mode 100644 index a469c018..00000000 --- a/media-store/app/src/pages/tracks/EditAction.js +++ /dev/null @@ -1,119 +0,0 @@ -import React from "react"; -import { Button, Modal, Form, message } from "antd"; -import { EditOutlined, LoadingOutlined } from "@ant-design/icons"; -import { useErrors } from "../../hooks/useErrors"; -import { TrackForm } from "../manage-store/TrackForm"; -import { updateTrack, getTrack } from "../../api/calls"; -import { MESSAGE_TIMEOUT } from "../../util/constants"; - -const EditAction = ({ - ID, - name, - composer, - genre, - unitPrice, - album, - afterTrackUpdate, -}) => { - const [visible, setVisible] = React.useState(false); - const [confirmLoading, setConfirmLoading] = React.useState(false); - const [updateLoading, setUpdateLoading] = React.useState(false); - const [form] = Form.useForm(); - const { handleError } = useErrors(); - - const onShowModal = () => { - setVisible(true); - }; - - const onFinish = (value) => { - setConfirmLoading(true); - updateTrack({ - ID, - name: value.name, - composer: value.composer, - album: { ID: value.albumID }, - genre: { ID: value.genreID }, - unitPrice: value.unitPrice.toString(), - }) - .then(() => { - message.success("Track successfully updated!", MESSAGE_TIMEOUT); - setConfirmLoading(false); - setVisible(false); - afterCloseModal(); - }) - .catch(handleError); - }; - - const handleOk = () => { - form.submit(); - }; - - const handleCancel = () => { - setVisible(false); - }; - - const afterCloseModal = () => { - setUpdateLoading(true); - getTrack(ID) - .then((response) => { - afterTrackUpdate(response.data); - setUpdateLoading(false); - }) - .catch(handleError); - }; - - return ( - <> - {updateLoading ? ( - - ) : ( - - )} - - Cancel - , - , - ]} - > -
console.log("Not valid params provided")} - initialValues={{ - name: name, - composer: composer, - genreID: genre.ID, - albumID: album.ID, - unitPrice: unitPrice, - }} - > - - -
- - ); -}; - -export { EditAction }; diff --git a/media-store/app/src/pages/tracks/ManagedTrack.css b/media-store/app/src/pages/tracks/ManagedTrack.css deleted file mode 100644 index e2107b16..00000000 --- a/media-store/app/src/pages/tracks/ManagedTrack.css +++ /dev/null @@ -1,7 +0,0 @@ -span > span.anticon.anticon-delete:hover { - color: #ff4d4f; -} - -.card-element { - transition: opacity 0.5s ease-in-out; -} diff --git a/media-store/app/src/pages/tracks/ManagedTrack.js b/media-store/app/src/pages/tracks/ManagedTrack.js deleted file mode 100644 index 8beaa37c..00000000 --- a/media-store/app/src/pages/tracks/ManagedTrack.js +++ /dev/null @@ -1,42 +0,0 @@ -import React, { useState, useRef } from "react"; -import { Card } from "antd"; -import { EditAction } from "./EditAction"; -import { DeleteAction } from "./DeleteAction"; -import { TrackCardBody } from "./TrackCardBody"; -import "./ManagedTrack.css"; - -const ManagedTrack = ({ initialTrack, onDeleteTrack }) => { - const trackElement = useRef(); - const [track, setTrack] = useState(initialTrack); - - return ( -
- { - trackElement.current.style.opacity = 0; - setTimeout(() => onDeleteTrack(track.ID), 500); - }} - />, - setTrack(value)} - />, - ]} - title={track.name} - bordered={false} - > - - -
- ); -}; - -export { ManagedTrack }; diff --git a/media-store/app/src/pages/tracks/Track.js b/media-store/app/src/pages/tracks/Track.js deleted file mode 100644 index ff88e565..00000000 --- a/media-store/app/src/pages/tracks/Track.js +++ /dev/null @@ -1,56 +0,0 @@ -import React, { useState, useRef } from "react"; -import { Card, Button } from "antd"; -import { PlusOutlined, MinusOutlined } from "@ant-design/icons"; -import { useAppState } from "../../hooks/useAppState"; -import { TrackCardBody } from "./TrackCardBody"; - -const Track = ({ initialTrack, isAlreadyOrdered }) => { - const trackElement = useRef(); - const { setInvoicedItems, invoicedItems } = useAppState(); - const [isJustInvoiced, setIsJustInvoiced] = useState( - invoicedItems.find((curTrack) => curTrack.ID === initialTrack.ID) - ); - - const onChangedStatus = () => { - const newIsJustInvoiced = !isJustInvoiced; - if (newIsJustInvoiced) { - setInvoicedItems([ - ...invoicedItems, - { - ID: initialTrack.ID, - name: initialTrack.name, - artist: initialTrack.album.artist.name, - albumTitle: initialTrack.album.title, - unitPrice: initialTrack.unitPrice, - }, - ]); - } else { - setInvoicedItems( - invoicedItems.filter(({ ID: curID }) => curID !== initialTrack.ID) - ); - } - setIsJustInvoiced(newIsJustInvoiced); - }; - - return ( -
- - {!isAlreadyOrdered && ( - - )} - , - ]} - title={initialTrack.name} - bordered={false} - > - - -
- ); -}; - -export { Track }; diff --git a/media-store/app/src/pages/tracks/TrackCardBody.js b/media-store/app/src/pages/tracks/TrackCardBody.js deleted file mode 100644 index d3174e2f..00000000 --- a/media-store/app/src/pages/tracks/TrackCardBody.js +++ /dev/null @@ -1,33 +0,0 @@ -import React from "react"; - -const TrackCardBody = ({ track }) => { - return ( - <> -
- Artist:{" "} - {track.album.artist.name} -
-
- Album: {track.album.title} -
-
- Genre: {track.genre.name} -
-
- {track.composer && ( - - Compositor:{" "} - {track.composer} - - )} -
-
- - Price: {track.unitPrice} - -
- - ); -}; - -export { TrackCardBody }; diff --git a/media-store/app/src/serviceWorker.js b/media-store/app/src/serviceWorker.js deleted file mode 100644 index b04b771a..00000000 --- a/media-store/app/src/serviceWorker.js +++ /dev/null @@ -1,141 +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.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 (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 => { - 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. - 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); - }); - } -} diff --git a/media-store/app/src/setupTests.js b/media-store/app/src/setupTests.js deleted file mode 100644 index 74b1a275..00000000 --- a/media-store/app/src/setupTests.js +++ /dev/null @@ -1,5 +0,0 @@ -// jest-dom adds custom jest matchers for asserting on DOM nodes. -// allows you to do things like: -// expect(element).toHaveTextContent(/react/i) -// learn more: https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom/extend-expect'; diff --git a/media-store/app/src/util/EventEmitter.js b/media-store/app/src/util/EventEmitter.js deleted file mode 100644 index 370e9777..00000000 --- a/media-store/app/src/util/EventEmitter.js +++ /dev/null @@ -1,5 +0,0 @@ -import EventEmitter from "events"; - -const emitter = new EventEmitter(); - -export { emitter }; diff --git a/media-store/app/src/util/constants.js b/media-store/app/src/util/constants.js deleted file mode 100644 index c844c903..00000000 --- a/media-store/app/src/util/constants.js +++ /dev/null @@ -1,14 +0,0 @@ -export const AVAILABLE_LOCALES = ["en", "fr", "de"]; - -export const MESSAGE_TIMEOUT = 2; - -// in dev mode using provided api -// in prod mode using proxy -export const API = - process.env.NODE_ENV === "development" ? "http://localhost:4004/" : "api/"; - -export const requireEmployee = (user) => - !!user && user.roles.includes("employee"); - -export const requireCustomer = (user) => - !!user && user.roles.includes("customer"); diff --git a/media-store/app/src/util/localStorageService.js b/media-store/app/src/util/localStorageService.js deleted file mode 100644 index 2f0fca17..00000000 --- a/media-store/app/src/util/localStorageService.js +++ /dev/null @@ -1,35 +0,0 @@ -import { isValidUser } from "./validateUser"; -import { AVAILABLE_LOCALES } from "./constants"; - -const setUserToLS = (user) => { - if (user) { - localStorage.setItem("user", JSON.stringify(user)); - } else { - localStorage.removeItem("user"); - } -}; - -const getUserFromLS = () => { - let userFromLS; - try { - userFromLS = JSON.parse(localStorage.getItem("user")); - if (isValidUser(userFromLS)) { - return userFromLS; - } - } catch (e) {} -}; - -const getLocaleFromLS = () => { - const localeFromLS = localStorage.getItem("locale"); - return localeFromLS && - localeFromLS !== "undefined" && - AVAILABLE_LOCALES.includes(localeFromLS) - ? localeFromLS - : "en"; -}; - -const setLocaleToLS = (locale) => { - localStorage.setItem("locale", locale); -}; - -export { setLocaleToLS, getLocaleFromLS, getUserFromLS, setUserToLS }; diff --git a/media-store/app/src/util/validateUser.js b/media-store/app/src/util/validateUser.js deleted file mode 100644 index 160740b8..00000000 --- a/media-store/app/src/util/validateUser.js +++ /dev/null @@ -1,20 +0,0 @@ -import { isArray, isEmpty, isString, isNumber } from "lodash"; - -const CUSTOMER_ROLE = "customer"; -const EMPLOYEE_ROLE = "employee"; - -const isValidUser = (user) => { - return ( - !isEmpty(user) && - isNumber(user.ID) && - isArray(user.roles) && - !!user.roles.some( - (role) => role === CUSTOMER_ROLE || role === EMPLOYEE_ROLE - ) && - isString(user.email) && - isString(user.accessToken) && - isString(user.refreshToken) - ); -}; - -export { isValidUser }; diff --git a/media-store/app/xs-app.json b/media-store/app/xs-app.json deleted file mode 100644 index 930c40ee..00000000 --- a/media-store/app/xs-app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "welcomeFile": "/index.html", - "routes": [ - { - "source": "^(.*)", - "target": "$1", - "service": "html5-apps-repo-rt" - } - ] -} \ No newline at end of file diff --git a/media-store/approuter/package.json b/media-store/approuter/package.json deleted file mode 100644 index d9a4cd89..00000000 --- a/media-store/approuter/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "media-store-approuter", - "description": "Approuter", - "version": "1.0.0", - "dependencies": { - "@sap/approuter": "^6.8.2" - }, - "scripts": { - "start": "node node_modules/@sap/approuter/approuter.js" - } -} diff --git a/media-store/approuter/xs-app.json b/media-store/approuter/xs-app.json deleted file mode 100644 index 4270e0cb..00000000 --- a/media-store/approuter/xs-app.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "welcomeFile": "/index.html", - "authenticationMethod": "none", - "routes": [ - { - "source": "/api/(.*)", - "target": "$1", - "destination": "srv-binding", - "authenticationType": "none" - }, - { - "source": "^(.*)", - "target": "mediastore/$1", - "service": "html5-apps-repo-rt" - } - ] -} diff --git a/media-store/html5Deployer/package.json b/media-store/html5Deployer/package.json deleted file mode 100644 index 09f597b2..00000000 --- a/media-store/html5Deployer/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "media-store-html5deployer", - "engines": { - "node": ">=6.0.0" - }, - "dependencies": { - "@sap/html5-app-deployer": "^2.0.0" - }, - "scripts": { - "start": "node node_modules/@sap/html5-app-deployer/index.js" - } -}