This commit is contained in:
Philippe Torrel
2026-10-13 11:49:05 +02:00
parent c41a126ea6
commit 36c0c2c7ea
13 changed files with 343 additions and 81 deletions
@@ -40,3 +40,25 @@ Content-Type: application/json
DELETE http://127.0.0.1:8000/api/products/174a2a19-26eb-475e-af47-4f46d2ab62ec
###
# RESET PRODUCTS
PATCH http://127.0.0.1:8000/api/products/reset
Content-Type: application/json
{
"reset": true
}
###
# SAVE PRODUCTS
PATCH http://127.0.0.1:8000/api/products/save
Content-Type: application/json
{
"save": true
}
@@ -0,0 +1,32 @@
[
{
"_id": "174a2a19-26eb-475e-af47-4f46d2ab62ec",
"position": 1,
"name": "3Doodler 3D Printing Pen",
"price": 29.99
},
{
"_id": "ba337ef0-fead-48c9-a210-16514fce54cd",
"position": 2,
"name": "Powerstation 5- E. Maximus Chargus",
"price": 44.95
},
{
"_id": "61c25758-5d24-4a1d-baf3-bb8e11d8c9a2",
"position": 3,
"name": "8-Bit Legendary Hero Heat-Change Mug",
"price": 6.99
},
{
"_id": "2b8eae22-50ad-43a6-91f5-5ca5d62976fa",
"position": 4,
"name": "16-Bit Legendary Hero Heat-Change Mug",
"price": 12.99
},
{
"_id": "dfee3d18-86b1-424e-a5eb-4a32e50b851c",
"position": 5,
"name": "32-Bit Legendary Hero Heat-Change Mug",
"price": 14.99
}
]
@@ -29,4 +29,4 @@
"name": "32-Bit Legendary Hero Heat-Change Mug",
"price": 14.99
}
]
]
@@ -14,6 +14,23 @@ const ProductModel = () => {
}
};
const reset = () => {
try {
products = JSON.parse(fs.readFileSync('./data/products.backup.json', 'utf-8'));
} catch (error) {
console.log('Something went wrong: ', error);
products = [];
}
};
const save = () => {
try {
fs.writeFileSync('./data/products.json', JSON.stringify(products, null, 2), 'utf-8');
} catch (error) {
console.log('Something went wrong: ', error);
}
};
const getAll = () => {
return products;
};
@@ -83,6 +100,8 @@ const ProductModel = () => {
add,
update,
delete: remove,
reset,
save,
};
};
@@ -101,6 +101,34 @@ app.delete('/api/products/:id', (req, res) => {
return res.send({ msg: 'Product deleted', status: 200, success: true, data: id });
});
// HTTP - Methode - PATCH
// reseten von Produkten
app.patch('/api/products/reset', (req, res) => {
const reset = req.body.reset;
if (!reset) {
return res.status(400).send({ msg: 'Could not reset products', status: 400, success: false });
}
products.reset();
return res.send({ msg: 'Products reseted', status: 200, success: true, data: [] });
});
// HTTP - Methode - PATCH
// speichern von Produkten
app.patch('/api/products/save', (req, res) => {
const save = req.body.save;
if (!save) {
return res.status(400).send({ msg: 'Could not save products', status: 400, success: false });
}
products.save();
return res.send({ msg: 'Products saved', status: 200, success: true, data: [] });
});
app.get('/', (req, res) => {
return res.send('Server is running!');
});
@@ -12398,20 +12398,28 @@ blockquote {
display: block;
}
/* Mobile first */
.product-manager table tfoot .row > * {
margin-bottom: 0.5rem;
.product-manager .nav-products-actions ul {
padding: 0;
margin: 0;
list-style: none;
display: flex;
justify-content: flex-end;
}
@media (min-width: 992px) {
.product-manager table tfoot .row > * {
margin-bottom: 0;
}
.product-manager .nav-products-actions ul li button {
margin: 0.5rem 0 0.5rem 0.5rem;
}
.product-manager table .th-actions {
width: 185px;
}
.product-manager table .th-dragger {
width: 50px;
}
.product-manager table td {
vertical-align: middle;
}
.product-manager table td button {
margin: 0 2px;
}
.product-manager table tbody:empty::after {
content: "loading products...";
width: -moz-max-content;
@@ -12420,15 +12428,11 @@ blockquote {
color: #999;
padding: 1rem;
}
.product-manager table td button {
margin: 0 2px;
.product-manager table tfoot .row > * {
margin-bottom: 0.5rem;
}
.product-manager table .th-actions {
width: 185px;
}
.product-manager table .th-dragger {
width: 50px;
@media (min-width: 992px) {
.product-manager table tfoot .row > * {
margin-bottom: 0;
}
}/*# sourceMappingURL=../map/main.css.map */
@@ -17,14 +17,14 @@
if(typeof ShadowRoot==='undefined'){return false;}var OwnElement=getWindow(node).ShadowRoot;return node instanceof OwnElement||node instanceof ShadowRoot;}
// and applies them to the HTMLElements such as popper and arrow
function applyStyles$1(_ref){var state=_ref.state;Object.keys(state.elements).forEach(function(name){var style=state.styles[name]||{};var attributes=state.attributes[name]||{};var element=state.elements[name];// arrow is optional + virtual elements
function applyStyles(_ref){var state=_ref.state;Object.keys(state.elements).forEach(function(name){var style=state.styles[name]||{};var attributes=state.attributes[name]||{};var element=state.elements[name];// arrow is optional + virtual elements
if(!isHTMLElement(element)||!getNodeName(element)){return;}// Flow doesn't support to extend this property, but it's the most
// effective way to apply styles to an HTMLElement
// $FlowFixMe[cannot-write]
Object.assign(element.style,style);Object.keys(attributes).forEach(function(name){var value=attributes[name];if(value===false){element.removeAttribute(name);}else {element.setAttribute(name,value===true?'':value);}});});}function effect$2(_ref2){var state=_ref2.state;var initialStyles={popper:{position:state.options.strategy,left:'0',top:'0',margin:'0'},arrow:{position:'absolute'},reference:{}};Object.assign(state.elements.popper.style,initialStyles.popper);state.styles=initialStyles;if(state.elements.arrow){Object.assign(state.elements.arrow.style,initialStyles.arrow);}return function(){Object.keys(state.elements).forEach(function(name){var element=state.elements[name];var attributes=state.attributes[name]||{};var styleProperties=Object.keys(state.styles.hasOwnProperty(name)?state.styles[name]:initialStyles[name]);// Set all values to an empty string to unset them
var style=styleProperties.reduce(function(style,property){style[property]='';return style;},{});// arrow is optional + virtual elements
if(!isHTMLElement(element)||!getNodeName(element)){return;}Object.assign(element.style,style);Object.keys(attributes).forEach(function(attribute){element.removeAttribute(attribute);});});};}// eslint-disable-next-line import/no-unused-modules
var applyStyles = {name:'applyStyles',enabled:true,phase:'write',fn:applyStyles$1,effect:effect$2,requires:['computeStyles']};
var applyStyles$1 = {name:'applyStyles',enabled:true,phase:'write',fn:applyStyles,effect:effect$2,requires:['computeStyles']};
function getBasePlacement(placement){return placement.split('-')[0];}
@@ -86,12 +86,12 @@
function expandToHashMap(value,keys){return keys.reduce(function(hashMap,key){hashMap[key]=value;return hashMap;},{});}
var toPaddingObject=function toPaddingObject(padding,state){padding=typeof padding==='function'?padding(Object.assign({},state.rects,{placement:state.placement})):padding;return mergePaddingObject(typeof padding!=='number'?padding:expandToHashMap(padding,basePlacements));};function arrow$1(_ref){var _state$modifiersData$;var state=_ref.state,name=_ref.name,options=_ref.options;var arrowElement=state.elements.arrow;var popperOffsets=state.modifiersData.popperOffsets;var basePlacement=getBasePlacement(state.placement);var axis=getMainAxisFromPlacement(basePlacement);var isVertical=[left,right].indexOf(basePlacement)>=0;var len=isVertical?'height':'width';if(!arrowElement||!popperOffsets){return;}var paddingObject=toPaddingObject(options.padding,state);var arrowRect=getLayoutRect(arrowElement);var minProp=axis==='y'?top:left;var maxProp=axis==='y'?bottom:right;var endDiff=state.rects.reference[len]+state.rects.reference[axis]-popperOffsets[axis]-state.rects.popper[len];var startDiff=popperOffsets[axis]-state.rects.reference[axis];var arrowOffsetParent=getOffsetParent(arrowElement);var clientSize=arrowOffsetParent?axis==='y'?arrowOffsetParent.clientHeight||0:arrowOffsetParent.clientWidth||0:0;var centerToReference=endDiff/2-startDiff/2;// Make sure the arrow doesn't overflow the popper if the center point is
var toPaddingObject=function toPaddingObject(padding,state){padding=typeof padding==='function'?padding(Object.assign({},state.rects,{placement:state.placement})):padding;return mergePaddingObject(typeof padding!=='number'?padding:expandToHashMap(padding,basePlacements));};function arrow(_ref){var _state$modifiersData$;var state=_ref.state,name=_ref.name,options=_ref.options;var arrowElement=state.elements.arrow;var popperOffsets=state.modifiersData.popperOffsets;var basePlacement=getBasePlacement(state.placement);var axis=getMainAxisFromPlacement(basePlacement);var isVertical=[left,right].indexOf(basePlacement)>=0;var len=isVertical?'height':'width';if(!arrowElement||!popperOffsets){return;}var paddingObject=toPaddingObject(options.padding,state);var arrowRect=getLayoutRect(arrowElement);var minProp=axis==='y'?top:left;var maxProp=axis==='y'?bottom:right;var endDiff=state.rects.reference[len]+state.rects.reference[axis]-popperOffsets[axis]-state.rects.popper[len];var startDiff=popperOffsets[axis]-state.rects.reference[axis];var arrowOffsetParent=getOffsetParent(arrowElement);var clientSize=arrowOffsetParent?axis==='y'?arrowOffsetParent.clientHeight||0:arrowOffsetParent.clientWidth||0:0;var centerToReference=endDiff/2-startDiff/2;// Make sure the arrow doesn't overflow the popper if the center point is
// outside of the popper bounds
var min=paddingObject[minProp];var max=clientSize-arrowRect[len]-paddingObject[maxProp];var center=clientSize/2-arrowRect[len]/2+centerToReference;var offset=within(min,center,max);// Prevents breaking syntax highlighting...
var axisProp=axis;state.modifiersData[name]=(_state$modifiersData$={},_state$modifiersData$[axisProp]=offset,_state$modifiersData$.centerOffset=offset-center,_state$modifiersData$);}function effect$1(_ref2){var state=_ref2.state,options=_ref2.options;var _options$element=options.element,arrowElement=_options$element===void 0?'[data-popper-arrow]':_options$element;if(arrowElement==null){return;}// CSS selector
if(typeof arrowElement==='string'){arrowElement=state.elements.popper.querySelector(arrowElement);if(!arrowElement){return;}}if(!contains(state.elements.popper,arrowElement)){return;}state.elements.arrow=arrowElement;}// eslint-disable-next-line import/no-unused-modules
var arrow = {name:'arrow',enabled:true,phase:'main',fn:arrow$1,effect:effect$1,requires:['popperOffsets'],requiresIfExists:['preventOverflow']};
var arrow$1 = {name:'arrow',enabled:true,phase:'main',fn:arrow,effect:effect$1,requires:['popperOffsets'],requiresIfExists:['preventOverflow']};
function getVariation(placement){return placement.split('-')[1];}
@@ -101,8 +101,8 @@
function roundOffsetsByDPR(_ref,win){var x=_ref.x,y=_ref.y;var dpr=win.devicePixelRatio||1;return {x:round(x*dpr)/dpr||0,y:round(y*dpr)/dpr||0};}function mapToStyles(_ref2){var _Object$assign2;var popper=_ref2.popper,popperRect=_ref2.popperRect,placement=_ref2.placement,variation=_ref2.variation,offsets=_ref2.offsets,position=_ref2.position,gpuAcceleration=_ref2.gpuAcceleration,adaptive=_ref2.adaptive,roundOffsets=_ref2.roundOffsets,isFixed=_ref2.isFixed;var _offsets$x=offsets.x,x=_offsets$x===void 0?0:_offsets$x,_offsets$y=offsets.y,y=_offsets$y===void 0?0:_offsets$y;var _ref3=typeof roundOffsets==='function'?roundOffsets({x:x,y:y}):{x:x,y:y};x=_ref3.x;y=_ref3.y;var hasX=offsets.hasOwnProperty('x');var hasY=offsets.hasOwnProperty('y');var sideX=left;var sideY=top;var win=window;if(adaptive){var offsetParent=getOffsetParent(popper);var heightProp='clientHeight';var widthProp='clientWidth';if(offsetParent===getWindow(popper)){offsetParent=getDocumentElement(popper);if(getComputedStyle$1(offsetParent).position!=='static'&&position==='absolute'){heightProp='scrollHeight';widthProp='scrollWidth';}}// $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it
offsetParent=offsetParent;if(placement===top||(placement===left||placement===right)&&variation===end){sideY=bottom;var offsetY=isFixed&&offsetParent===win&&win.visualViewport?win.visualViewport.height:// $FlowFixMe[prop-missing]
offsetParent[heightProp];y-=offsetY-popperRect.height;y*=gpuAcceleration?1:-1;}if(placement===left||(placement===top||placement===bottom)&&variation===end){sideX=right;var offsetX=isFixed&&offsetParent===win&&win.visualViewport?win.visualViewport.width:// $FlowFixMe[prop-missing]
offsetParent[widthProp];x-=offsetX-popperRect.width;x*=gpuAcceleration?1:-1;}}var commonStyles=Object.assign({position:position},adaptive&&unsetSides);var _ref4=roundOffsets===true?roundOffsetsByDPR({x:x,y:y},getWindow(popper)):{x:x,y:y};x=_ref4.x;y=_ref4.y;if(gpuAcceleration){var _Object$assign;return Object.assign({},commonStyles,(_Object$assign={},_Object$assign[sideY]=hasY?'0':'',_Object$assign[sideX]=hasX?'0':'',_Object$assign.transform=(win.devicePixelRatio||1)<=1?"translate("+x+"px, "+y+"px)":"translate3d("+x+"px, "+y+"px, 0)",_Object$assign));}return Object.assign({},commonStyles,(_Object$assign2={},_Object$assign2[sideY]=hasY?y+"px":'',_Object$assign2[sideX]=hasX?x+"px":'',_Object$assign2.transform='',_Object$assign2));}function computeStyles$1(_ref5){var state=_ref5.state,options=_ref5.options;var _options$gpuAccelerat=options.gpuAcceleration,gpuAcceleration=_options$gpuAccelerat===void 0?true:_options$gpuAccelerat,_options$adaptive=options.adaptive,adaptive=_options$adaptive===void 0?true:_options$adaptive,_options$roundOffsets=options.roundOffsets,roundOffsets=_options$roundOffsets===void 0?true:_options$roundOffsets;var commonStyles={placement:getBasePlacement(state.placement),variation:getVariation(state.placement),popper:state.elements.popper,popperRect:state.rects.popper,gpuAcceleration:gpuAcceleration,isFixed:state.options.strategy==='fixed'};if(state.modifiersData.popperOffsets!=null){state.styles.popper=Object.assign({},state.styles.popper,mapToStyles(Object.assign({},commonStyles,{offsets:state.modifiersData.popperOffsets,position:state.options.strategy,adaptive:adaptive,roundOffsets:roundOffsets})));}if(state.modifiersData.arrow!=null){state.styles.arrow=Object.assign({},state.styles.arrow,mapToStyles(Object.assign({},commonStyles,{offsets:state.modifiersData.arrow,position:'absolute',adaptive:false,roundOffsets:roundOffsets})));}state.attributes.popper=Object.assign({},state.attributes.popper,{'data-popper-placement':state.placement});}// eslint-disable-next-line import/no-unused-modules
var computeStyles = {name:'computeStyles',enabled:true,phase:'beforeWrite',fn:computeStyles$1,data:{}};
offsetParent[widthProp];x-=offsetX-popperRect.width;x*=gpuAcceleration?1:-1;}}var commonStyles=Object.assign({position:position},adaptive&&unsetSides);var _ref4=roundOffsets===true?roundOffsetsByDPR({x:x,y:y},getWindow(popper)):{x:x,y:y};x=_ref4.x;y=_ref4.y;if(gpuAcceleration){var _Object$assign;return Object.assign({},commonStyles,(_Object$assign={},_Object$assign[sideY]=hasY?'0':'',_Object$assign[sideX]=hasX?'0':'',_Object$assign.transform=(win.devicePixelRatio||1)<=1?"translate("+x+"px, "+y+"px)":"translate3d("+x+"px, "+y+"px, 0)",_Object$assign));}return Object.assign({},commonStyles,(_Object$assign2={},_Object$assign2[sideY]=hasY?y+"px":'',_Object$assign2[sideX]=hasX?x+"px":'',_Object$assign2.transform='',_Object$assign2));}function computeStyles(_ref5){var state=_ref5.state,options=_ref5.options;var _options$gpuAccelerat=options.gpuAcceleration,gpuAcceleration=_options$gpuAccelerat===void 0?true:_options$gpuAccelerat,_options$adaptive=options.adaptive,adaptive=_options$adaptive===void 0?true:_options$adaptive,_options$roundOffsets=options.roundOffsets,roundOffsets=_options$roundOffsets===void 0?true:_options$roundOffsets;var commonStyles={placement:getBasePlacement(state.placement),variation:getVariation(state.placement),popper:state.elements.popper,popperRect:state.rects.popper,gpuAcceleration:gpuAcceleration,isFixed:state.options.strategy==='fixed'};if(state.modifiersData.popperOffsets!=null){state.styles.popper=Object.assign({},state.styles.popper,mapToStyles(Object.assign({},commonStyles,{offsets:state.modifiersData.popperOffsets,position:state.options.strategy,adaptive:adaptive,roundOffsets:roundOffsets})));}if(state.modifiersData.arrow!=null){state.styles.arrow=Object.assign({},state.styles.arrow,mapToStyles(Object.assign({},commonStyles,{offsets:state.modifiersData.arrow,position:'absolute',adaptive:false,roundOffsets:roundOffsets})));}state.attributes.popper=Object.assign({},state.attributes.popper,{'data-popper-placement':state.placement});}// eslint-disable-next-line import/no-unused-modules
var computeStyles$1 = {name:'computeStyles',enabled:true,phase:'beforeWrite',fn:computeStyles,data:{}};
var passive={passive:true};function effect(_ref){var state=_ref.state,instance=_ref.instance,options=_ref.options;var _options$scroll=options.scroll,scroll=_options$scroll===void 0?true:_options$scroll,_options$resize=options.resize,resize=_options$resize===void 0?true:_options$resize;var window=getWindow(state.elements.popper);var scrollParents=[].concat(state.scrollParents.reference,state.scrollParents.popper);if(scroll){scrollParents.forEach(function(scrollParent){scrollParent.addEventListener('scroll',instance.update,passive);});}if(resize){window.addEventListener('resize',instance.update,passive);}return function(){if(scroll){scrollParents.forEach(function(scrollParent){scrollParent.removeEventListener('scroll',instance.update,passive);});}if(resize){window.removeEventListener('resize',instance.update,passive);}};}// eslint-disable-next-line import/no-unused-modules
var eventListeners = {name:'eventListeners',enabled:true,phase:'write',fn:function fn(){},effect:effect,data:{}};
@@ -161,26 +161,26 @@
function computeAutoPlacement(state,options){if(options===void 0){options={};}var _options=options,placement=_options.placement,boundary=_options.boundary,rootBoundary=_options.rootBoundary,padding=_options.padding,flipVariations=_options.flipVariations,_options$allowedAutoP=_options.allowedAutoPlacements,allowedAutoPlacements=_options$allowedAutoP===void 0?placements:_options$allowedAutoP;var variation=getVariation(placement);var placements$1=variation?flipVariations?variationPlacements:variationPlacements.filter(function(placement){return getVariation(placement)===variation;}):basePlacements;var allowedPlacements=placements$1.filter(function(placement){return allowedAutoPlacements.indexOf(placement)>=0;});if(allowedPlacements.length===0){allowedPlacements=placements$1;}// $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...
var overflows=allowedPlacements.reduce(function(acc,placement){acc[placement]=detectOverflow(state,{placement:placement,boundary:boundary,rootBoundary:rootBoundary,padding:padding})[getBasePlacement(placement)];return acc;},{});return Object.keys(overflows).sort(function(a,b){return overflows[a]-overflows[b];});}
function getExpandedFallbackPlacements(placement){if(getBasePlacement(placement)===auto){return [];}var oppositePlacement=getOppositePlacement(placement);return [getOppositeVariationPlacement(placement),oppositePlacement,getOppositeVariationPlacement(oppositePlacement)];}function flip$1(_ref){var state=_ref.state,options=_ref.options,name=_ref.name;if(state.modifiersData[name]._skip){return;}var _options$mainAxis=options.mainAxis,checkMainAxis=_options$mainAxis===void 0?true:_options$mainAxis,_options$altAxis=options.altAxis,checkAltAxis=_options$altAxis===void 0?true:_options$altAxis,specifiedFallbackPlacements=options.fallbackPlacements,padding=options.padding,boundary=options.boundary,rootBoundary=options.rootBoundary,altBoundary=options.altBoundary,_options$flipVariatio=options.flipVariations,flipVariations=_options$flipVariatio===void 0?true:_options$flipVariatio,allowedAutoPlacements=options.allowedAutoPlacements;var preferredPlacement=state.options.placement;var basePlacement=getBasePlacement(preferredPlacement);var isBasePlacement=basePlacement===preferredPlacement;var fallbackPlacements=specifiedFallbackPlacements||(isBasePlacement||!flipVariations?[getOppositePlacement(preferredPlacement)]:getExpandedFallbackPlacements(preferredPlacement));var placements=[preferredPlacement].concat(fallbackPlacements).reduce(function(acc,placement){return acc.concat(getBasePlacement(placement)===auto?computeAutoPlacement(state,{placement:placement,boundary:boundary,rootBoundary:rootBoundary,padding:padding,flipVariations:flipVariations,allowedAutoPlacements:allowedAutoPlacements}):placement);},[]);var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var checksMap=new Map();var makeFallbackChecks=true;var firstFittingPlacement=placements[0];for(var i=0;i<placements.length;i++){var placement=placements[i];var _basePlacement=getBasePlacement(placement);var isStartVariation=getVariation(placement)===start;var isVertical=[top,bottom].indexOf(_basePlacement)>=0;var len=isVertical?'width':'height';var overflow=detectOverflow(state,{placement:placement,boundary:boundary,rootBoundary:rootBoundary,altBoundary:altBoundary,padding:padding});var mainVariationSide=isVertical?isStartVariation?right:left:isStartVariation?bottom:top;if(referenceRect[len]>popperRect[len]){mainVariationSide=getOppositePlacement(mainVariationSide);}var altVariationSide=getOppositePlacement(mainVariationSide);var checks=[];if(checkMainAxis){checks.push(overflow[_basePlacement]<=0);}if(checkAltAxis){checks.push(overflow[mainVariationSide]<=0,overflow[altVariationSide]<=0);}if(checks.every(function(check){return check;})){firstFittingPlacement=placement;makeFallbackChecks=false;break;}checksMap.set(placement,checks);}if(makeFallbackChecks){// `2` may be desired in some cases – research later
function getExpandedFallbackPlacements(placement){if(getBasePlacement(placement)===auto){return [];}var oppositePlacement=getOppositePlacement(placement);return [getOppositeVariationPlacement(placement),oppositePlacement,getOppositeVariationPlacement(oppositePlacement)];}function flip(_ref){var state=_ref.state,options=_ref.options,name=_ref.name;if(state.modifiersData[name]._skip){return;}var _options$mainAxis=options.mainAxis,checkMainAxis=_options$mainAxis===void 0?true:_options$mainAxis,_options$altAxis=options.altAxis,checkAltAxis=_options$altAxis===void 0?true:_options$altAxis,specifiedFallbackPlacements=options.fallbackPlacements,padding=options.padding,boundary=options.boundary,rootBoundary=options.rootBoundary,altBoundary=options.altBoundary,_options$flipVariatio=options.flipVariations,flipVariations=_options$flipVariatio===void 0?true:_options$flipVariatio,allowedAutoPlacements=options.allowedAutoPlacements;var preferredPlacement=state.options.placement;var basePlacement=getBasePlacement(preferredPlacement);var isBasePlacement=basePlacement===preferredPlacement;var fallbackPlacements=specifiedFallbackPlacements||(isBasePlacement||!flipVariations?[getOppositePlacement(preferredPlacement)]:getExpandedFallbackPlacements(preferredPlacement));var placements=[preferredPlacement].concat(fallbackPlacements).reduce(function(acc,placement){return acc.concat(getBasePlacement(placement)===auto?computeAutoPlacement(state,{placement:placement,boundary:boundary,rootBoundary:rootBoundary,padding:padding,flipVariations:flipVariations,allowedAutoPlacements:allowedAutoPlacements}):placement);},[]);var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var checksMap=new Map();var makeFallbackChecks=true;var firstFittingPlacement=placements[0];for(var i=0;i<placements.length;i++){var placement=placements[i];var _basePlacement=getBasePlacement(placement);var isStartVariation=getVariation(placement)===start;var isVertical=[top,bottom].indexOf(_basePlacement)>=0;var len=isVertical?'width':'height';var overflow=detectOverflow(state,{placement:placement,boundary:boundary,rootBoundary:rootBoundary,altBoundary:altBoundary,padding:padding});var mainVariationSide=isVertical?isStartVariation?right:left:isStartVariation?bottom:top;if(referenceRect[len]>popperRect[len]){mainVariationSide=getOppositePlacement(mainVariationSide);}var altVariationSide=getOppositePlacement(mainVariationSide);var checks=[];if(checkMainAxis){checks.push(overflow[_basePlacement]<=0);}if(checkAltAxis){checks.push(overflow[mainVariationSide]<=0,overflow[altVariationSide]<=0);}if(checks.every(function(check){return check;})){firstFittingPlacement=placement;makeFallbackChecks=false;break;}checksMap.set(placement,checks);}if(makeFallbackChecks){// `2` may be desired in some cases – research later
var numberOfChecks=flipVariations?3:1;var _loop=function _loop(_i){var fittingPlacement=placements.find(function(placement){var checks=checksMap.get(placement);if(checks){return checks.slice(0,_i).every(function(check){return check;});}});if(fittingPlacement){firstFittingPlacement=fittingPlacement;return "break";}};for(var _i=numberOfChecks;_i>0;_i--){var _ret=_loop(_i);if(_ret==="break")break;}}if(state.placement!==firstFittingPlacement){state.modifiersData[name]._skip=true;state.placement=firstFittingPlacement;state.reset=true;}}// eslint-disable-next-line import/no-unused-modules
var flip = {name:'flip',enabled:true,phase:'main',fn:flip$1,requiresIfExists:['offset'],data:{_skip:false}};
var flip$1 = {name:'flip',enabled:true,phase:'main',fn:flip,requiresIfExists:['offset'],data:{_skip:false}};
function getSideOffsets(overflow,rect,preventedOffsets){if(preventedOffsets===void 0){preventedOffsets={x:0,y:0};}return {top:overflow.top-rect.height-preventedOffsets.y,right:overflow.right-rect.width+preventedOffsets.x,bottom:overflow.bottom-rect.height+preventedOffsets.y,left:overflow.left-rect.width-preventedOffsets.x};}function isAnySideFullyClipped(overflow){return [top,right,bottom,left].some(function(side){return overflow[side]>=0;});}function hide$1(_ref){var state=_ref.state,name=_ref.name;var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var preventedOffsets=state.modifiersData.preventOverflow;var referenceOverflow=detectOverflow(state,{elementContext:'reference'});var popperAltOverflow=detectOverflow(state,{altBoundary:true});var referenceClippingOffsets=getSideOffsets(referenceOverflow,referenceRect);var popperEscapeOffsets=getSideOffsets(popperAltOverflow,popperRect,preventedOffsets);var isReferenceHidden=isAnySideFullyClipped(referenceClippingOffsets);var hasPopperEscaped=isAnySideFullyClipped(popperEscapeOffsets);state.modifiersData[name]={referenceClippingOffsets:referenceClippingOffsets,popperEscapeOffsets:popperEscapeOffsets,isReferenceHidden:isReferenceHidden,hasPopperEscaped:hasPopperEscaped};state.attributes.popper=Object.assign({},state.attributes.popper,{'data-popper-reference-hidden':isReferenceHidden,'data-popper-escaped':hasPopperEscaped});}// eslint-disable-next-line import/no-unused-modules
var hide = {name:'hide',enabled:true,phase:'main',requiresIfExists:['preventOverflow'],fn:hide$1};
function getSideOffsets(overflow,rect,preventedOffsets){if(preventedOffsets===void 0){preventedOffsets={x:0,y:0};}return {top:overflow.top-rect.height-preventedOffsets.y,right:overflow.right-rect.width+preventedOffsets.x,bottom:overflow.bottom-rect.height+preventedOffsets.y,left:overflow.left-rect.width-preventedOffsets.x};}function isAnySideFullyClipped(overflow){return [top,right,bottom,left].some(function(side){return overflow[side]>=0;});}function hide(_ref){var state=_ref.state,name=_ref.name;var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var preventedOffsets=state.modifiersData.preventOverflow;var referenceOverflow=detectOverflow(state,{elementContext:'reference'});var popperAltOverflow=detectOverflow(state,{altBoundary:true});var referenceClippingOffsets=getSideOffsets(referenceOverflow,referenceRect);var popperEscapeOffsets=getSideOffsets(popperAltOverflow,popperRect,preventedOffsets);var isReferenceHidden=isAnySideFullyClipped(referenceClippingOffsets);var hasPopperEscaped=isAnySideFullyClipped(popperEscapeOffsets);state.modifiersData[name]={referenceClippingOffsets:referenceClippingOffsets,popperEscapeOffsets:popperEscapeOffsets,isReferenceHidden:isReferenceHidden,hasPopperEscaped:hasPopperEscaped};state.attributes.popper=Object.assign({},state.attributes.popper,{'data-popper-reference-hidden':isReferenceHidden,'data-popper-escaped':hasPopperEscaped});}// eslint-disable-next-line import/no-unused-modules
var hide$1 = {name:'hide',enabled:true,phase:'main',requiresIfExists:['preventOverflow'],fn:hide};
function distanceAndSkiddingToXY(placement,rects,offset){var basePlacement=getBasePlacement(placement);var invertDistance=[left,top].indexOf(basePlacement)>=0?-1:1;var _ref=typeof offset==='function'?offset(Object.assign({},rects,{placement:placement})):offset,skidding=_ref[0],distance=_ref[1];skidding=skidding||0;distance=(distance||0)*invertDistance;return [left,right].indexOf(basePlacement)>=0?{x:distance,y:skidding}:{x:skidding,y:distance};}function offset$1(_ref2){var state=_ref2.state,options=_ref2.options,name=_ref2.name;var _options$offset=options.offset,offset=_options$offset===void 0?[0,0]:_options$offset;var data=placements.reduce(function(acc,placement){acc[placement]=distanceAndSkiddingToXY(placement,state.rects,offset);return acc;},{});var _data$state$placement=data[state.placement],x=_data$state$placement.x,y=_data$state$placement.y;if(state.modifiersData.popperOffsets!=null){state.modifiersData.popperOffsets.x+=x;state.modifiersData.popperOffsets.y+=y;}state.modifiersData[name]=data;}// eslint-disable-next-line import/no-unused-modules
var offset = {name:'offset',enabled:true,phase:'main',requires:['popperOffsets'],fn:offset$1};
function distanceAndSkiddingToXY(placement,rects,offset){var basePlacement=getBasePlacement(placement);var invertDistance=[left,top].indexOf(basePlacement)>=0?-1:1;var _ref=typeof offset==='function'?offset(Object.assign({},rects,{placement:placement})):offset,skidding=_ref[0],distance=_ref[1];skidding=skidding||0;distance=(distance||0)*invertDistance;return [left,right].indexOf(basePlacement)>=0?{x:distance,y:skidding}:{x:skidding,y:distance};}function offset(_ref2){var state=_ref2.state,options=_ref2.options,name=_ref2.name;var _options$offset=options.offset,offset=_options$offset===void 0?[0,0]:_options$offset;var data=placements.reduce(function(acc,placement){acc[placement]=distanceAndSkiddingToXY(placement,state.rects,offset);return acc;},{});var _data$state$placement=data[state.placement],x=_data$state$placement.x,y=_data$state$placement.y;if(state.modifiersData.popperOffsets!=null){state.modifiersData.popperOffsets.x+=x;state.modifiersData.popperOffsets.y+=y;}state.modifiersData[name]=data;}// eslint-disable-next-line import/no-unused-modules
var offset$1 = {name:'offset',enabled:true,phase:'main',requires:['popperOffsets'],fn:offset};
function popperOffsets$1(_ref){var state=_ref.state,name=_ref.name;// Offsets are the actual position the popper needs to have to be
function popperOffsets(_ref){var state=_ref.state,name=_ref.name;// Offsets are the actual position the popper needs to have to be
// properly positioned near its reference element
// This is the most basic placement, and will be adjusted by
// the modifiers in the next step
state.modifiersData[name]=computeOffsets({reference:state.rects.reference,element:state.rects.popper,placement:state.placement});}// eslint-disable-next-line import/no-unused-modules
var popperOffsets = {name:'popperOffsets',enabled:true,phase:'read',fn:popperOffsets$1,data:{}};
var popperOffsets$1 = {name:'popperOffsets',enabled:true,phase:'read',fn:popperOffsets,data:{}};
function getAltAxis(axis){return axis==='x'?'y':'x';}
function preventOverflow$1(_ref){var state=_ref.state,options=_ref.options,name=_ref.name;var _options$mainAxis=options.mainAxis,checkMainAxis=_options$mainAxis===void 0?true:_options$mainAxis,_options$altAxis=options.altAxis,checkAltAxis=_options$altAxis===void 0?false:_options$altAxis,boundary=options.boundary,rootBoundary=options.rootBoundary,altBoundary=options.altBoundary,padding=options.padding,_options$tether=options.tether,tether=_options$tether===void 0?true:_options$tether,_options$tetherOffset=options.tetherOffset,tetherOffset=_options$tetherOffset===void 0?0:_options$tetherOffset;var overflow=detectOverflow(state,{boundary:boundary,rootBoundary:rootBoundary,padding:padding,altBoundary:altBoundary});var basePlacement=getBasePlacement(state.placement);var variation=getVariation(state.placement);var isBasePlacement=!variation;var mainAxis=getMainAxisFromPlacement(basePlacement);var altAxis=getAltAxis(mainAxis);var popperOffsets=state.modifiersData.popperOffsets;var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var tetherOffsetValue=typeof tetherOffset==='function'?tetherOffset(Object.assign({},state.rects,{placement:state.placement})):tetherOffset;var normalizedTetherOffsetValue=typeof tetherOffsetValue==='number'?{mainAxis:tetherOffsetValue,altAxis:tetherOffsetValue}:Object.assign({mainAxis:0,altAxis:0},tetherOffsetValue);var offsetModifierState=state.modifiersData.offset?state.modifiersData.offset[state.placement]:null;var data={x:0,y:0};if(!popperOffsets){return;}if(checkMainAxis){var _offsetModifierState$;var mainSide=mainAxis==='y'?top:left;var altSide=mainAxis==='y'?bottom:right;var len=mainAxis==='y'?'height':'width';var offset=popperOffsets[mainAxis];var min$1=offset+overflow[mainSide];var max$1=offset-overflow[altSide];var additive=tether?-popperRect[len]/2:0;var minLen=variation===start?referenceRect[len]:popperRect[len];var maxLen=variation===start?-popperRect[len]:-referenceRect[len];// We need to include the arrow in the calculation so the arrow doesn't go
function preventOverflow(_ref){var state=_ref.state,options=_ref.options,name=_ref.name;var _options$mainAxis=options.mainAxis,checkMainAxis=_options$mainAxis===void 0?true:_options$mainAxis,_options$altAxis=options.altAxis,checkAltAxis=_options$altAxis===void 0?false:_options$altAxis,boundary=options.boundary,rootBoundary=options.rootBoundary,altBoundary=options.altBoundary,padding=options.padding,_options$tether=options.tether,tether=_options$tether===void 0?true:_options$tether,_options$tetherOffset=options.tetherOffset,tetherOffset=_options$tetherOffset===void 0?0:_options$tetherOffset;var overflow=detectOverflow(state,{boundary:boundary,rootBoundary:rootBoundary,padding:padding,altBoundary:altBoundary});var basePlacement=getBasePlacement(state.placement);var variation=getVariation(state.placement);var isBasePlacement=!variation;var mainAxis=getMainAxisFromPlacement(basePlacement);var altAxis=getAltAxis(mainAxis);var popperOffsets=state.modifiersData.popperOffsets;var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var tetherOffsetValue=typeof tetherOffset==='function'?tetherOffset(Object.assign({},state.rects,{placement:state.placement})):tetherOffset;var normalizedTetherOffsetValue=typeof tetherOffsetValue==='number'?{mainAxis:tetherOffsetValue,altAxis:tetherOffsetValue}:Object.assign({mainAxis:0,altAxis:0},tetherOffsetValue);var offsetModifierState=state.modifiersData.offset?state.modifiersData.offset[state.placement]:null;var data={x:0,y:0};if(!popperOffsets){return;}if(checkMainAxis){var _offsetModifierState$;var mainSide=mainAxis==='y'?top:left;var altSide=mainAxis==='y'?bottom:right;var len=mainAxis==='y'?'height':'width';var offset=popperOffsets[mainAxis];var min$1=offset+overflow[mainSide];var max$1=offset-overflow[altSide];var additive=tether?-popperRect[len]/2:0;var minLen=variation===start?referenceRect[len]:popperRect[len];var maxLen=variation===start?-popperRect[len]:-referenceRect[len];// We need to include the arrow in the calculation so the arrow doesn't go
// outside the reference bounds
var arrowElement=state.elements.arrow;var arrowRect=tether&&arrowElement?getLayoutRect(arrowElement):{width:0,height:0};var arrowPaddingObject=state.modifiersData['arrow#persistent']?state.modifiersData['arrow#persistent'].padding:getFreshSideObject();var arrowPaddingMin=arrowPaddingObject[mainSide];var arrowPaddingMax=arrowPaddingObject[altSide];// If the reference length is smaller than the arrow length, we don't want
// to include its full size in the calculation. If the reference is small
@@ -188,7 +188,7 @@
// reference is not overflowing as well (e.g. virtual elements with no
// width or height)
var arrowLen=within(0,referenceRect[len],arrowRect[len]);var minOffset=isBasePlacement?referenceRect[len]/2-additive-arrowLen-arrowPaddingMin-normalizedTetherOffsetValue.mainAxis:minLen-arrowLen-arrowPaddingMin-normalizedTetherOffsetValue.mainAxis;var maxOffset=isBasePlacement?-referenceRect[len]/2+additive+arrowLen+arrowPaddingMax+normalizedTetherOffsetValue.mainAxis:maxLen+arrowLen+arrowPaddingMax+normalizedTetherOffsetValue.mainAxis;var arrowOffsetParent=state.elements.arrow&&getOffsetParent(state.elements.arrow);var clientOffset=arrowOffsetParent?mainAxis==='y'?arrowOffsetParent.clientTop||0:arrowOffsetParent.clientLeft||0:0;var offsetModifierValue=(_offsetModifierState$=offsetModifierState==null?void 0:offsetModifierState[mainAxis])!=null?_offsetModifierState$:0;var tetherMin=offset+minOffset-offsetModifierValue-clientOffset;var tetherMax=offset+maxOffset-offsetModifierValue;var preventedOffset=within(tether?min(min$1,tetherMin):min$1,offset,tether?max(max$1,tetherMax):max$1);popperOffsets[mainAxis]=preventedOffset;data[mainAxis]=preventedOffset-offset;}if(checkAltAxis){var _offsetModifierState$2;var _mainSide=mainAxis==='x'?top:left;var _altSide=mainAxis==='x'?bottom:right;var _offset=popperOffsets[altAxis];var _len=altAxis==='y'?'height':'width';var _min=_offset+overflow[_mainSide];var _max=_offset-overflow[_altSide];var isOriginSide=[top,left].indexOf(basePlacement)!==-1;var _offsetModifierValue=(_offsetModifierState$2=offsetModifierState==null?void 0:offsetModifierState[altAxis])!=null?_offsetModifierState$2:0;var _tetherMin=isOriginSide?_min:_offset-referenceRect[_len]-popperRect[_len]-_offsetModifierValue+normalizedTetherOffsetValue.altAxis;var _tetherMax=isOriginSide?_offset+referenceRect[_len]+popperRect[_len]-_offsetModifierValue-normalizedTetherOffsetValue.altAxis:_max;var _preventedOffset=tether&&isOriginSide?withinMaxClamp(_tetherMin,_offset,_tetherMax):within(tether?_tetherMin:_min,_offset,tether?_tetherMax:_max);popperOffsets[altAxis]=_preventedOffset;data[altAxis]=_preventedOffset-_offset;}state.modifiersData[name]=data;}// eslint-disable-next-line import/no-unused-modules
var preventOverflow = {name:'preventOverflow',enabled:true,phase:'main',fn:preventOverflow$1,requiresIfExists:['offset']};
var preventOverflow$1 = {name:'preventOverflow',enabled:true,phase:'main',fn:preventOverflow,requiresIfExists:['offset']};
function getHTMLElementScroll(element){return {scrollLeft:element.scrollLeft,scrollTop:element.scrollTop};}
@@ -239,15 +239,15 @@
// one.
function runModifierEffects(){state.orderedModifiers.forEach(function(_ref){var name=_ref.name,_ref$options=_ref.options,options=_ref$options===void 0?{}:_ref$options,effect=_ref.effect;if(typeof effect==='function'){var cleanupFn=effect({state:state,name:name,instance:instance,options:options});var noopFn=function noopFn(){};effectCleanupFns.push(cleanupFn||noopFn);}});}function cleanupModifierEffects(){effectCleanupFns.forEach(function(fn){return fn();});effectCleanupFns=[];}return instance;};}
var defaultModifiers=[eventListeners,popperOffsets,computeStyles,applyStyles,offset,flip,preventOverflow,arrow,hide];var createPopper=/*#__PURE__*/popperGenerator({defaultModifiers:defaultModifiers});// eslint-disable-next-line import/no-unused-modules
var defaultModifiers=[eventListeners,popperOffsets$1,computeStyles$1,applyStyles$1,offset$1,flip$1,preventOverflow$1,arrow$1,hide$1];var createPopper=/*#__PURE__*/popperGenerator({defaultModifiers:defaultModifiers});// eslint-disable-next-line import/no-unused-modules
var Popper = /*#__PURE__*/Object.freeze({
__proto__: null,
afterMain: afterMain,
afterRead: afterRead,
afterWrite: afterWrite,
applyStyles: applyStyles,
arrow: arrow,
applyStyles: applyStyles$1,
arrow: arrow$1,
auto: auto,
basePlacements: basePlacements,
beforeMain: beforeMain,
@@ -255,22 +255,22 @@
beforeWrite: beforeWrite,
bottom: bottom,
clippingParents: clippingParents,
computeStyles: computeStyles,
computeStyles: computeStyles$1,
createPopper: createPopper,
detectOverflow: detectOverflow,
end: end,
eventListeners: eventListeners,
flip: flip,
hide: hide,
flip: flip$1,
hide: hide$1,
left: left,
main: main,
modifierPhases: modifierPhases,
offset: offset,
offset: offset$1,
placements: placements,
popper: popper,
popperGenerator: popperGenerator,
popperOffsets: popperOffsets,
preventOverflow: preventOverflow,
popperOffsets: popperOffsets$1,
preventOverflow: preventOverflow$1,
read: read,
reference: reference,
right: right,
@@ -887,19 +887,22 @@
// import 'bootstrap';
// Factory Function
const ProductManager=(el=null,options={})=>{// === DOM & VARS =======
const module=el||document.querySelector('.product-manager')||console.warn('Product Manager Element not found');if(!module)return;const DOM={module,table:module.querySelector('.table-products'),tbody:module.querySelector('tbody'),inputName:module.querySelector('.input-product-name'),inputPrice:module.querySelector('.input-product-price'),btnAdd:module.querySelector('.button-product-add'),templateRow:module.querySelector('.template-row'),// Modal Edit
const module=el||document.querySelector('.product-manager')||console.warn('Product Manager Element not found');if(!module)return;const DOM={module,table:module.querySelector('.table-products'),tbody:module.querySelector('tbody'),inputName:module.querySelector('.input-product-name'),inputPrice:module.querySelector('.input-product-price'),btnAdd:module.querySelector('.button-product-add'),templateRow:module.querySelector('.template-row'),// Nav Actions
navActions:module.querySelector('.nav-products-actions'),btnReset:module.querySelector('.button-products-reset'),btnSave:module.querySelector('.button-products-save'),// Modal Edit
modalEdit:module.querySelector('.modal-edit'),formEdit:module.querySelector('.form-product-edit'),inputEditName:module.querySelector('.input-edit-name'),inputEditPrice:module.querySelector('.input-edit-price'),inputEditId:module.querySelector('.input-edit-id'),inputEditPosition:module.querySelector('.input-edit-position'),btnUpdate:module.querySelector('.button-product-update'),// Modal Delete
modalDelete:module.querySelector('.modal-delete'),productName:module.querySelector('strong.product-name'),btnConfirmDelete:module.querySelector('.button-confirm-delete')};const SERVER_BASE_URL='http://127.0.0.1:8000';const bsModalEdit=new Modal(DOM.modalEdit,{backdrop:'static',keyboard:true});const bsModalDelete=new Modal(DOM.modalDelete,{backdrop:true,keyboard:true});// console.log(DOM);
// === INIT =============
const init=()=>{// Funktionsaufrufe zu beginn der Anwendung
initProducts();DOM.btnAdd.disabled=true;// Event-Lauscher zu beginn der Anwendung
DOM.btnAdd.addEventListener('click',onClickAdd);DOM.btnConfirmDelete.addEventListener('click',onClickConfirmDelete);DOM.formEdit.addEventListener('submit',onSubmitEdit);window.addEventListener('keyup',onKeyUp);};// === EVENTHANDLER =====
DOM.btnReset.addEventListener('click',onClickReset);DOM.btnSave.addEventListener('click',onClickSave);DOM.btnAdd.addEventListener('click',onClickAdd);DOM.btnConfirmDelete.addEventListener('click',onClickConfirmDelete);DOM.formEdit.addEventListener('submit',onSubmitEdit);window.addEventListener('keyup',onKeyUp);};// === EVENTHANDLER =====
const onKeyUp=e=>{DOM.btnAdd.disabled=!(DOM.inputName.value!==''&&DOM.inputPrice.value!=='');// if (DOM.inputName.value !== '' && DOM.inputPrice.value !== '') {
// DOM.btnAdd.disabled = false;
// } else {
// DOM.btnAdd.disabled = true;
// }
};const onClickAdd=e=>{const product={name:DOM.inputName.value,//
};const onClickReset=e=>{const btnEl=e.currentTarget;const icon=btnEl.querySelector('i');icon.classList.add('fa-jello');// async API request
resetProducts().then(data=>{if(data.success){Toast(data.msg,'success').show();loadProducts();}else {Toast(data.msg,'error').show();}setTimeout(()=>{icon.classList.remove('fa-jello');},500);});};const onClickSave=e=>{const btnEl=e.currentTarget;const icon=btnEl.querySelector('i');icon.classList.add('fa-jello');// async API request
saveProducts().then(data=>{if(data.success){Toast(data.msg,'success').show();}else {Toast(data.msg,'error').show();}setTimeout(()=>{icon.classList.remove('fa-jello');},500);});};const onClickAdd=e=>{const product={name:DOM.inputName.value,//
price:Number(DOM.inputPrice.valueAsNumber)};// async API request
createProduct(product).then(data=>{console.log(data);if(data.success){Toast(data.msg,'success').show();loadProducts();resetInputFields();disableNonFunctionalButtons();}else {Toast(data.msg,'error').show();}});// addProduct(product);
};const onSubmitEdit=e=>{e.preventDefault();// Standardverhalten unterbinden (Modal Form nicht versenden)
@@ -952,7 +955,15 @@
// BREA(D) - Delete - löschen eines Produkts
const deleteProduct=async id=>{try{const response=await fetch(`${SERVER_BASE_URL}/api/products/${id}`,{method:'DELETE'});// HTTP-Request URL
if(!response.ok){throw new Error('Fetch went wrong.');}const data=await response.json();// HTTP-Response-Body in JS-Objekt geparsed -> Promise
return data;}catch(error){Toast(error.message||"Couldn't delete product",'error').show();console.error(error);throw error;}};// === FUNCTIONS ========
return data;}catch(error){Toast(error.message||"Couldn't delete product",'error').show();console.error(error);throw error;}};// HTTP - Methode - PATCH
// Reseten der Produkte
const resetProducts=async id=>{try{const response=await fetch(`${SERVER_BASE_URL}/api/products/reset`,{method:'PATCH',headers:{'Content-Type':'application/json'},body:JSON.stringify({reset:true})});// HTTP-Request URL
if(!response.ok){throw new Error('Fetch went wrong.');}const data=await response.json();// HTTP-Response-Body in JS-Objekt geparsed -> Promise
return data;}catch(error){Toast(error.message||"Couldn't reset products",'error').show();console.error(error);throw error;}};// HTTP - Methode - PATCH
// Speichern der Produkte
const saveProducts=async id=>{try{const response=await fetch(`${SERVER_BASE_URL}/api/products/save`,{method:'PATCH',headers:{'Content-Type':'application/json'},body:JSON.stringify({save:true})});// HTTP-Request URL
if(!response.ok){throw new Error('Fetch went wrong.');}const data=await response.json();// HTTP-Response-Body in JS-Objekt geparsed -> Promise
return data;}catch(error){Toast(error.message||"Couldn't save products",'error').show();console.error(error);throw error;}};// === FUNCTIONS ========
const initProducts=()=>{fetchProducts().then(products=>{products.forEach(addProduct);disableNonFunctionalButtons();});};const loadProducts=()=>{DOM.tbody.innerHTML='';fetchProducts().then(data=>{// TODO: add fade Animation
data.forEach(addProduct);disableNonFunctionalButtons();});};const addProduct=product=>{const{name,price,_id:id}=product;// https://developer.mozilla.org/de/docs/Web/HTML/Reference/Elements/template#anwendungshinweise
const trEl=DOM.templateRow.content.firstElementChild.cloneNode(true);const tdNameEl=trEl.querySelector('.td-name');const tdPriceEl=trEl.querySelector('.td-price');const btnDragEl=trEl.querySelector('.button-product-drag');const btnEditEl=trEl.querySelector('.button-product-edit');const btnRemoveEl=trEl.querySelector('.button-product-remove');const btnMoveUpEl=trEl.querySelector('.button-product-move-up');const btnMoveDownEl=trEl.querySelector('.button-product-move-down');// Drag 'n Drop hinzufügen.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -2,6 +2,24 @@
<div class="product-manager">
<div class="container py-5">
<h1>Productmanager</h1>
<nav class="nav-products-actions">
<ul class="list">
<li>
<button class="btn btn-dark button-products-save">
<i class="fas fa-floppy-disk"></i>
<span>Save Products</span>
</button>
</li>
<li>
<button class="btn btn-danger button-products-reset">
<i class="fas fa-box-archive"></i>
<span>Reset Products</span>
</button>
</li>
</ul>
</nav>
<!-- table.table.table-striped.table-products>thead.table-dark>tr>th*2 -->
<table class="table table-striped table-products">
<thead class="table-dark">
@@ -22,6 +22,11 @@ const ProductManager = (el = null, options = {}) => {
btnAdd: module.querySelector('.button-product-add'),
templateRow: module.querySelector('.template-row'),
// Nav Actions
navActions: module.querySelector('.nav-products-actions'),
btnReset: module.querySelector('.button-products-reset'),
btnSave: module.querySelector('.button-products-save'),
// Modal Edit
modalEdit: module.querySelector('.modal-edit'),
formEdit: module.querySelector('.form-product-edit'),
@@ -57,6 +62,10 @@ const ProductManager = (el = null, options = {}) => {
initProducts();
DOM.btnAdd.disabled = true;
// Event-Lauscher zu beginn der Anwendung
DOM.btnReset.addEventListener('click', onClickReset);
DOM.btnSave.addEventListener('click', onClickSave);
DOM.btnAdd.addEventListener('click', onClickAdd);
DOM.btnConfirmDelete.addEventListener('click', onClickConfirmDelete);
DOM.formEdit.addEventListener('submit', onSubmitEdit);
@@ -73,6 +82,43 @@ const ProductManager = (el = null, options = {}) => {
// }
};
const onClickReset = (e) => {
const btnEl = e.currentTarget;
const icon = btnEl.querySelector('i');
icon.classList.add('fa-jello');
// async API request
resetProducts().then((data) => {
if (data.success) {
Toast(data.msg, 'success').show();
loadProducts();
} else {
Toast(data.msg, 'error').show();
}
setTimeout(() => {
icon.classList.remove('fa-jello');
}, 500);
});
};
const onClickSave = (e) => {
const btnEl = e.currentTarget;
const icon = btnEl.querySelector('i');
icon.classList.add('fa-jello');
// async API request
saveProducts().then((data) => {
if (data.success) {
Toast(data.msg, 'success').show();
} else {
Toast(data.msg, 'error').show();
}
setTimeout(() => {
icon.classList.remove('fa-jello');
}, 500);
});
};
const onClickAdd = (e) => {
const product = {
name: DOM.inputName.value, //
@@ -352,6 +398,56 @@ const ProductManager = (el = null, options = {}) => {
}
};
// HTTP - Methode - PATCH
// Reseten der Produkte
const resetProducts = async (id) => {
try {
const response = await fetch(`${SERVER_BASE_URL}/api/products/reset`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ reset: true }),
}); // HTTP-Request URL
if (!response.ok) {
throw new Error('Fetch went wrong.');
}
const data = await response.json(); // HTTP-Response-Body in JS-Objekt geparsed -> Promise
return data;
} catch (error) {
Toast(error.message || "Couldn't reset products", 'error').show();
console.error(error);
throw error;
}
};
// HTTP - Methode - PATCH
// Speichern der Produkte
const saveProducts = async (id) => {
try {
const response = await fetch(`${SERVER_BASE_URL}/api/products/save`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ save: true }),
}); // HTTP-Request URL
if (!response.ok) {
throw new Error('Fetch went wrong.');
}
const data = await response.json(); // HTTP-Response-Body in JS-Objekt geparsed -> Promise
return data;
} catch (error) {
Toast(error.message || "Couldn't save products", 'error').show();
console.error(error);
throw error;
}
};
// === FUNCTIONS ========
const initProducts = () => {
fetchProducts().then((products) => {
@@ -1,33 +1,47 @@
/* Mobile first */
.product-manager table tfoot .row > * {
margin-bottom: 0.5rem;
}
.product-manager {
.nav-products-actions {
ul {
padding: 0;
margin: 0;
list-style: none;
display: flex;
justify-content: flex-end;
@media (min-width: 992px) {
.product-manager table tfoot .row > * {
margin-bottom: 0;
li {
button {
margin: 0.5rem 0 0.5rem 0.5rem;
}
}
}
}
table {
.th-actions {
width: 185px;
}
.th-dragger {
width: 50px;
}
td {
vertical-align: middle;
button {
margin: 0 2px;
}
}
tbody:empty::after {
content: 'loading products...';
width: max-content;
display: inline-block;
color: #999;
padding: 1rem;
}
tfoot .row > * {
margin-bottom: 0.5rem;
@media (min-width: 992px) {
margin-bottom: 0;
}
}
}
}
.product-manager table td {
vertical-align: middle;
}
.product-manager table tbody:empty::after {
content: 'loading products...';
width: max-content;
display: inline-block;
color: #999;
padding: 1rem;
}
.product-manager table td button {
margin: 0 2px;
}
.product-manager table .th-actions {
width: 185px;
}
.product-manager table .th-dragger {
width: 50px;
}
@@ -40,6 +40,24 @@
<div class="product-manager">
<div class="container py-5">
<h1>Productmanager</h1>
<nav class="nav-products-actions">
<ul class="list">
<li>
<button class="btn btn-dark button-products-save">
<i class="fas fa-floppy-disk"></i>
<span>Save Products</span>
</button>
</li>
<li>
<button class="btn btn-danger button-products-reset">
<i class="fas fa-box-archive"></i>
<span>Reset Products</span>
</button>
</li>
</ul>
</nav>
<!-- table.table.table-striped.table-products>thead.table-dark>tr>th*2 -->
<table class="table table-striped table-products">
<thead class="table-dark">