{"version":3,"sources":["webpack:///src/environments/environment.ts","webpack:///src/app/shared/form-component.ts","webpack:///src/app/shared/base.component.ts","webpack:///src/app/shared/file-format-validator.ts","webpack:///src/app/neuten/neut/neut-position.ts","webpack:///src/app/core/services/backend.service.ts","webpack:///src/app/shared/models/model-factory.ts","webpack:///src/app/shared/models/neut.model.ts","webpack:///src/app/core/services/data-state.service.ts","webpack:///src/app/shared/models/dorpel-decorator.ts","webpack:///src/app/shared/api-models/bewerkingDto.ts","webpack:///src/app/dealers/custom-dealer-resource-map.ts","webpack:///src/app/core/services/ui-state-service.ts","webpack:///src/app/shared/models/dorpel-type.model.ts","webpack:///src/app/sluitpot/sluitpot-position.ts","webpack:///src/app/shared/models/sluitpot.model.ts","webpack:///src/app/core/services/graphics.service.ts","webpack:///src/app/shared/validation-error/validation-error.component.ts","webpack:///src/app/footer/footer.component.ts","webpack:///src/app/footer/footer.component.html","webpack:///src/app/shared/file-value-accessor.directive.ts","webpack:///src/app/shared/integer-only.directive.ts","webpack:///src/app/welkom/welkom.component.html","webpack:///src/app/welkom/welkom.component.ts","webpack:///src/app/welkom/constants.ts","webpack:///src/app/shared/resize-listener.ts","webpack:///src/app/dorpel/dorpel-horiz.component.html","webpack:///src/app/dorpel/dorpel.component.ts","webpack:///src/app/shared/tooltip-configuration.ts","webpack:///src/app/core/services/tooltip.service.ts","webpack:///src/app/neuten/daagmaat/daagmaat.component.html","webpack:///src/app/neuten/daagmaat/daagmaat.component.ts","webpack:///src/app/neuten/neut/neut-horiz.component.html","webpack:///src/app/neuten/neut/neut.component.ts","webpack:///src/app/neuten/neuten-horiz.component.html","webpack:///src/app/neuten/neuten.component.ts","webpack:///src/app/sluitpot/sluitpot-horiz.component.html","webpack:///src/app/sluitpot/sluitpot.component.ts","webpack:///src/app/bewerkingen-horiz/bewerkingen-pill/bewerkingen-pill.component.ts","webpack:///src/app/bewerkingen-horiz/bewerkingen-horiz.component.html","webpack:///src/app/bewerkingen-horiz/bewerkingen-pill/bewerkingen-pill.component.html","webpack:///src/app/bewerkingen-horiz/bewerkingen-horiz.component.ts","webpack:///src/app/dorpel-page/dorpel-page-horiz.component.html","webpack:///src/app/dorpel-page/dorpel-page.component.ts","webpack:///src/app/core/services/cleanup.service.ts","webpack:///src/app/overzicht/overzicht.component.html","webpack:///src/app/overzicht/overzicht.component.ts","webpack:///src/app/redirect/redirect.component.ts","webpack:///src/app/redirect/redirect.component.html","webpack:///src/app/dealers/dealers.component.ts","webpack:///src/app/dealers/dealers.component.html","webpack:///src/app/landing-pages/luvema-landing.component.ts","webpack:///src/app/landing-pages/luvema-landing.template.html","webpack:///src/app/app-routing.module.ts","webpack:///src/app/header/header.component.ts","webpack:///src/app/header/header.component.html","webpack:///src/app/tooltip/tooltip.component.html","webpack:///src/app/tooltip/tooltip.component.ts","webpack:///src/app/app.component.ts","webpack:///src/app/app.component.html","webpack:///src/app/core/services/api-key-interceptor.ts","webpack:///src/app/core/core.module.ts","webpack:///src/app/shared/shared.module.ts","webpack:///src/app/app.module.ts","webpack:///src/main.ts","webpack:///$_lazy_route_resource lazy namespace object"],"names":["environment","FormComponent","formGroup","key","formControl","this","get","valid","firstError","Object","keys","errors","ValidationMessages","index","formArray","at","touched","console","log","required","email","min","max","unsubscribe$","Subject","next","complete","FileFormatValidator","control","fileName","value","name","segments","split","extension","length","includes","acceptedFile","c","validate","provide","useExisting","multi","NeutPosition","httpClient","dealersApiUrl","neutenApiUrl","glaslattenApiUrl","sluitpottenApiUrl","bewerkingenApiUrl","dorpelsApiUrl","postMaakDocumentUrl","getOrderNoUrl","postPrefilledOrderformUrl","addAttachmentUrl","removeAttachmentUrl","_dealers","of","pipe","tap","dealers","_neuten","neuten","_glaslatten","glaslatten","dorpelCode","productType","map","items","filter","dorpel","productsoort","toLowerCase","formData","orderNo","post","file","orderId","fileFormData","FormData","append","delete","model","id","Guid","create","toString","afleverdatum","Date","aantal","aantalNeuten","aantalSluitpotten","guid","maatA","maatZ","bewerkingen","createNeut","zaagmaat","sluitpotten","Left","Center","Right","VOORSPONNING_SIZE_MAP","freeze","width","height","pos","position","count","neutDescription","description","toLocaleLowerCase","isWissel","isDraaikiep","isSpecial","isRegular","indexOf","isSlidingDoor","isLeftVakConversion","isRightVakConversion","isSpecialCaseException","isBinnenDorpel","isBuitenDorpel","leftOptions","rightOptions","push","vorsponning","i","crtVorsponning","tekeningString","rtlOffset","xOffset","yOffset","pointsList","result","isDrawingRTL","parseInt","isDrawingHalves","forEach","point","coordinates","x","y","landingPagePath","dorpelModel","sm","getModel","dorpels","findIndex","dorpelDto","JSON","stringify","parse","dorpelType","dorpelOrder","getCurrentDorpel","merk","schema","firstMaatA","deurmaatA","deurmaatB","deurmaatC","maatB","maatC","isInHouseDorpel","neutenModels","nm","daagmaat","neutCode","neut","omschrijving","positie","getPositionString","sponningmaat","sponningsoort","glaslat","beglazingsprofiel","aanslagprofiel","damverbreeding","gemonteerd","linksVoorsponning","rechtsVoorsponning","isInHouseNeut","customWidth","models","maat","maat2","sluitpotCode","opmerking","trim","drawingData","drawing","submitModel","createBestelling","files","path","homePath","dorpelId","find","target","splice","sluitpottenCount","createSluitpot","extra","diff","DEFAULT_VALUES","offset","depth","delta","orientatie","cutNeut","BewerkingUtils","bewerkingDescription","isRenovatiesponning","isKloostersponning","isVersteksponning","CUSTOM_DEALERS_RESOURCE_MAP","resourcesFolderName","customLink","dealerName","customClass","fromPrefilledOrder","_redrawCount","dorpelChoices","neutenChoices","_sluitpottenCount$","BehaviorSubject","_redraw$","_neutenCount$","_schema$","_productType$","_neutCustomWidthUpdateSubject","neutCustomWidthUpdate$","asObservable","_dorpelCode$","_zaagmaat$","_maatA$","_maatZ$","_deurmaatA$","_deurmaatB$","_maatB$","_firstMaatA$","_deurmaatC$","_maatC$","_neuten$","choices","_isDrawingInExampleMode","_currentProductType","_currentDorpel","_currentDealersGroup","_customDealerResources","_railType","currentDorpel","d","dorpelsoort","p","code","preventDataReset","Error","setSluitpottenCount","setDorpelCode","setNeutenCount","setSchema","setZaagmaat","setMaatA","setFirstMaatA","setDeurmaatA","setMaatB","setDeurmaatB","setMaatC","setDeurmaatC","setMaatZ","setNumberOfNeuten","isActive","isLeftSide","isRightSide","leftCustomDepth","leftCustomLength","leftCustomOffset","rightCustomDepth","rightCustomLength","rightCustomOffset","leftOrientatie","rightOrientatie","selectedBwCodes","leftKloostersponningActive","leftRenovatiesponningActive","rightKloostersponningActive","rightRenovatiesponningActive","leftVersteksponningActive","rightVersteksponningActive","leftKloostersponningCustomDepth","leftRenovatiesponningCustomDepth","rightKloostersponningCustomDepth","rightRenovatiesponningCustomDepth","leftKloostersponningCustomOffset","leftRenovatiesponningCustomOffset","rightKloostersponningCustomOffset","rightRenovatiesponningCustomOffset","leftKloostersponningCustomLength","leftRenovatiesponningCustomLength","rightKloostersponningCustomLength","rightRenovatiesponningCustomLength","leftVerstekSponningOrientatie","rightVerstekSponningOrientatie","bw","isKloostersponningLeft","customDepth","customLength","customOffset","isKloostersponningRight","isKloostersponningLeftAndRight","isRenovatiesponningLeft","isRenovatiesponningRight","isRenovatiesponningLeftAndRight","isVersteksponningLeft","isVersteksponningRight","renovatieSponningOptions","kloosterSponningOptions","verstekSponningOptions","getResetSponningOptions","type","railType","setNumberOfSluitpotten","neutData","neutIndex","voorsponningSize","sluitpodData","url","logoUrl","dealerGuid","DORPEL_CODES","DorpelUtils","size","heightAboveDam","slice","heightBelowDam","dorpelSplitDimensions","substr","SluitpotPosition","Dam","Sponning","Sponning2","VOORSPONNING_TYPES","SCALE_TIP_ARROW","DORPEL_START","WISSELNEUT_SPONNINGMAAT_COORDINATES","W1","right","left","W2","W3","W4","W5","uiService","canvasContext","canvasId","canvasSize","canvasSelector","canvas","document","getElementById","setCanvasSize","clearCanvas","context","getContext","save","ctx","clearRect","targetDorpelModel","canvasElement","turnOffDrawingExample","dorpelData","damLevel","getDamLevelFromDorpelCode","setCanvasContext","drawFrame","drawSlidingNeut","drawNeuten","cutVerstekSurplus","drawSluitpotten","drawDamLine","restore","startPoint","dorpelHeight","getThicknessFromDorpelCode","beginPath","lineWidth","rect","stroke","drawScaleMeasurements","leftVerstek","calculateVerstekLengthByAngle","rightVerstek","leftVerstekOrientation","rightVerstekOrientation","upperLeft","bottomLeft","bottomRight","upperRight","globalCompositeOperation","moveTo","lineTo","closePath","fill","setLineDash","thickness","neutDto","getNeutDtoByCodeAndPositie","neutWidth","neutbreedte","neutLength","neutlengte","deviationOptions","klooster","active","data","getKloosterSponningData","isLeft","isRight","renovatie","getRenovatieSponningData","drawALSchema","drawARSchema","drawCGSchema","drawDSchema","trueScaleMeasurements","scaledMeasurements","ratio","parseFloat","toFixed","a1","a2","b","baseline","getSlidingNeutValues","hasLeftRenovatieSponning","hasRightRenovatieSponning","hasLeftKloosterSponning","hasRightKloosterSponning","renovatieSponningData","kloosterSponningData","maxDeurmaatWidth","minDeurmaatWidth","scalableElementRatio","getScalableElementRatioForALARSchemas","scaledMA","Math","scaledMZ","deurmaatRatio","deurmaatValue","p2","p3","p4","p6","p7","renovatieDepthLeft","renovatieLengthLeft","kloosterOffsetLeft","kloosterDepthLeft","kloosterLengthLeft","renovatieDepthRight","renovatieLengthRight","kloosterOffsetRight","kloosterDepthRight","kloosterLengthRight","topLineY","HS_RAIL_WIDTH","bottomLineY","p5","minDeurmaat","getScalableElementRatioForCGSchemas","deurmaatAVal","deurmaatCVal","maxMaatB","maatBVal","p8","p9","totalVariableElementsLength","totalFixedElementsLength","getScalableElementRatioForDSchemas","firstMaatAVal","maatCVal","maxDeurmaatB","minDeurmaatB","deurmaatBVal","initialNextNeutPosition","nextNeut","nextNeutWidth","abs","options","daagmaatVirtualRatio","calculateDaagmatVirtualRatio","drawTextLabel","currentNeutPosition","prevNeut","leftCustomSponningmaat","neutRightLimit","drawNeut","nextDaagmaat","nextNeutPosition","compensateForRightEndAccuracy","glaslatMarkVerticalPosition","nextNeutDiff","nextNeutDto","getNeutTopVsBaseWidthDifference","isConversionNeut","label","markSpooningsoort","isLeftSideDiffrence","startCoord","endCoord","neutCoords","tekening","start","startX","startY","neutHeight","leftEdge","rightEdge","isLeftNeut","isRightNeut","isMiddleNeut","drawStartY","drawStartX","shouldAlterTekeningString","isDrawingFlipped","hasTekeningStringException","flipDraw","updateTekeningStringWithCustomWidth","changeTekeningStringSponningmaatValue","isW2Neut","isW3Neut","insertVoorsponningDeviation","isTopPointingNeut","isDK","isCutDirectionRight","insertBewerkingenDeviation","isKloosterSponning","isRenovatieSponning","neutCoordinatePoints","getDrawingCoorodatesList","drawByCoordinates","resetFlip","tekeningCoordinates","convertTekeningStringToCoordinatesList","convertCoordinatesListToTekeningString","rightSponningmaat","leftSponningmaat","wisselTypeToken","targetPoints","getSponningmaatUpdateTargetPoints","tp","wisselType","fillColor","coordinate","fillShape","fromX","toX","dorpelTopY","extractedLetter","charAt","fillText","color","fillStyle","sluitpot","drawSluitpott","SCALE_HEIGHT","markerLevels","sluitpotValue","isInDeDam","isInDeSponning","sluitpotMarkerSize","verticalPosition","excludeSideDelimiters","midY","drawArrowHeadLeft","drawArrowHeadRight","cachedFont","font","text","textSize","measureText","tipPoint","doorThickness","splitTekening","response","tekeningPoint","coordinatesList","stringifiedCooridinatesList","join","tekeningCoordinatesList","insertionPointDeterminingOptions","indices","voorsponningType","isVoorsponningOnTop","neutTopPositionIndices","getNeutTopEdgePointsIndices","topSideYValue","insertionPointIndex","determineVoorsponningInsertionPoint","targetPoint","deviation","getLinksVoorsponningDeviation","getRechtsVoorsponningDeviation","firstPointIndex","secondPointIndex","voorsponning","vorsponningHeight","determineBewerkingInsertionPoint","getKloosterDeviation","deviationCoordinates","reverse","unshift","getRenovatieDeviation","foundIndex","kloosterTopBottomOffset","angle","verstekAngle","tangentValueOfAngle","tan","PI","round","window","devicePixelRatio","style","referenceHeight","translate","scale","ValidationErrorComponent","show","FooterComponent","FileValueAccessorDirective","onChange","_","onTouched","fn","IntegerOnlyDirective","event","preventDefault","replace","PRESERVED_FORM_FIELDS","formBuilder","backend","router","dataStateService","uiState","spinner","cdRef","activatedRoute","graphics","super","prefilledOrderErrorMessage","originalList","sortedList","sort","d1","d2","naam","localeCompare","snapshot","paramMap","setProductType","populatePreservedWelkomFormValues","updateFormData","guidAssociatedDealers","currentDealersGroup","getSortedDealersList","currentlySelectedDealerCode","dealer","dealerCode","setFirtDealerFormGuidAssociatedList","getDealers","takeUntil","subscribe","setTimeout","detectChanges","customDealerResources","setValue","preserveWelkomFormValues","buildForm","_formComponent","bijlage","removeAt","showError","errorMessage","saveChangesToPostModel","navigate","relativeTo","controls","field","markAsTouched","validateForm","queryParams","dorpelGuid","posted","cartItems","addOffscreenDrawing","logoImageData","offscreenCanvas","createElement","initializeDrawing","drawDorpel","imageData","toDataURL","$event","acc","prefilledOrderformFile","getPrefilledOrderform","catchError","err","hide","error","throwError","order","overrideWelkomFormValues","setModel","setNeutenChoices","fieldNameList","fieldName","fieldValue","lsKey","localStorage","setItem","previouslySavedValue","getItem","fileProcessingResultOrder","opdrachtgever","contactpersoon","telefoonnummer","emailadres","uwReferentie","postPrefilledOrderform","postModel","form","opmerkingen","group","maxLength","minLength","buildBijlageFormArray","fileNames","array","onDorpelBestellenButtonClicked","maxlength","minlength","elementRef","resizeEvent","emit","ResizeObserver","observe","nativeElement","uiStateService","ngZone","_zaagmaatMismatchSignFactor","zaagmaatTargetValue","_sumOfMatenCustomError","_slidingDoorsCustomErrors","neutValue","dorpelDependentFields","schemaDependentFields","zaagmaatDependentFieldsEnabled","dorpelAutodrawn","isDrawingInfoMessageVisible","visibleCanvasWidth","exampleDrawingPath","isDrawingInExampleMode","setHomePath","viewMode","turnOnDrawingExample","getDorpels","take","enableDorpelDependentFields","enableDorpelTypeDependentFields","enableZaagmaatDependentFields","draw","redraw$","dorpelDrawing","isCanvasEmpty","parentElement","getBoundingClientRect","dorpelDtos","neutenCount","setExampleDrawingPath","toggleSchemaDependentFields","isBinnenDoor","isBuitenDoor","runOutsideAngular","rafId","cancelAnimationFrame","requestAnimationFrame","isSlidingDorpel","hasError","scrollTo","top","zaagmatAmountMismatchTooLow","zaagmatAmountMismatchTooHigh","disabled","isValid","getImageData","some","channel","total","resetSlidingDoorsCustomErrors","getNeutDimension","availableMechanismSpace","validateALARSchemaDistances","validateCGSchemaDistances","validateDSchema","reduce","accumulator","currentValue","sumOfMatenNull","values","deurmaatMinWidth","deurmaatMaxWdith","deurmaatAMaxWdith","deurmaatCMaxWdith","firstMaatAMinWidth","firstMaatAMaxWidth","maatCMinWidth","maatCMaxWidth","deurmaatBMinWidth","deurmaatBMaxWidth","pattern","fieldToEnable","enable","isEditMode","isCurrentDoorSliding","neutenValue","disable","targetField","bind","maxLimit","getZaagmaatMaxLimit","validateZaagmaat","checkOtherFormsValidity","measureSurfaceAndTriggerDebouncedDraw","drawTimer","clearTimeout","imagePath","textDescription","TOOLTIP_POSITIONS","TOOLTIP_OFFSET","assetsPath","component","tooltipComponent","targetElement","tooltipTypeKey","getAttribute","setOptions","tooltipOptions","getOptions","customImageName","customTextDescription","imageOnly","descriptionOnly","showTooltip","computeTooltipPoisitionString","setCustomStyle","hideTooltip","elementRect","getPositioningStyleString","targetRect","targetTop","scrollY","targetRight","scrollX","targetBottom","targetLeft","positions","getPreferedPositioningOrder","tooltipBox","tooltipbox","tooltipWidth","offsetWidth","tooltipHeight","offsetHeight","shift","fitsRight","innerHeight","fitsBottom","innerWidth","fitsTop","GLASLATTEN_CONFLICT_ERR_MESSAGE","graphicsService","tooltipService","isUitvoeringAvailable","neutenDependentFields","sponningmaatOptions","beglazingConflictError","aanslagConflictError","glaslatConflictError","neutModel","input","neutMatchesDorpelAndPosition","determineUitvoeringAvailability","setSponningmaatOptionsAndSetDefault","dorpelCode$","filterGlaslattenChoicesByDorpelsoort","glaslattenChoices","subscribeToNeutenCountChanges","currentProductType","glaslattenOptionsList","currentDorpelType","neutenCount$","enableNeutenDependentFields","param","cachedDaagmaatValue","updateDaagmaat","resetGlaslattenConflictErrors","isConversionDaagmaat","populateNeut","defaultSponningmaatValue","getLabel","selectedNeutCode","n","shouldEnable","fieldToUpdateValidity","aanslagprofielField","updateAanslagprofiel","beglazingsField","updateBeglazingsprofiel","glaslatField","updateGlaslat","resetAanslagprofiel","triggerRedraw","resetGlaslat","resetBeglazingsprofiel","updateDamverbreeding","updateSpooningsoort","isNeutRegularOrW2","isNeutDraaiKiep","defaultOption","isDefault","extraOption","exceptionOption","updateSponningmaat","tooltip","leftVoorsponningOptions","rightVoorsponningOptions","customNeutRemovalErrorMessage","isTooltipResourceCheckInProgress","shouldAbortTooltipDisplay","voorsponningChanged","currentNeutChanged","selectedNeut","neutenCathegories","activeNeutCathegory","isCathegoryListOpen","boundClickOutsideListener","voorsponningEnabled","shouldHideLeftVoorsponning","shouldHideRightVoorsponning","isSpecialNeut","specialNeutWidth","alreadySubscribedToNeutenCount","clickOutsideListener","setCurrentDorpelType","packNeutenIntoCathegories","neuten$","currentNeut","filterOutIncompatibleNeuten","isConversionVakFollowingNeut","setVoorsponningOptions","isFirstNeut","isLastNeut","currentNeutDto","setVoorsponningDefaultValueIfNecessary","computeVoorsponningVisibility","schema$","toggleNeutDisablingBySchema","populateLeftVoorsponning","populateRightVoorsponning","vorsponningSize","getVorsponningValue","prevNeutDescription","isRegularTussen","isRegularRight","isW3","isW1","isW5","isW2","isW4","isDKMidRight","isDKLeft","isDKRight","isDKMidBoth","isDKMidLeft","currentNeutCode","updateNeutenChoices","cleanNeutOrder","resetNeutCodeSelection","body","addEventListener","removeEventListener","e","closest","neutSelectorSpecialClassName","cathegoriesListSpecialClassName","closeCathegoryList","onNeutSelected","resetActiveNeutCathegory","neutCathegory","regulier","wissel","draai","special","getVoorsponningOptions","neutControl","fieldToUpdate","isVoorsponningDisabledCase","previousValue","currentlySelectedNeut","updateVoorsponningVisibility","getSelectedNeut","targetProperty","targetNeutIndex","updateSpecialNeutCustomWidth","neutOrder","undefined","sponningmaatValue","neutImageName","getCustomNeutTooltipImageName","loadImageTooltip","loadMissingImageTooltip","attemptResourceLoad","resourcePath","loadCallback","failCallback","img","Image","onload","onerror","src","backendService","neutInputModels","filteredGlaslatten","canShowRailOptions","isNeutenSectionInvalid","showDealerContactMessage","currentSchema","showSponningmaat","handleInitialValues","updateNeutInputModels","currentDorpelCode","toggleRailTypeEnabledState","resetRailType","addOrRemoveNeut","isEnabled","setRailType","isPrefilledOrder","neutDtos","getNeuten","chosenDorpel","neutComponents","toArray","comp","modelDaagmaatA","daagmatAComponent","daagmatCompList","daagmatComponents","daagmatNeutModel","foundInvalidComponents","invalid","nc","targetNeutComponent","setLinksVoorsponningValue","setRechtsVoorsponningValue","updateSpecificNeutInputModel","dif","getPositionFromIndex","Promise","resolve","reject","forkJoin","getGlaslatten","filterGlaslattenChoicesByProductsoort","_aantalSluitpotten","sluitpottenModels","combineLatest","getSluitpotten","sluitpottenCount$","dorpelCodeValue","dto","sluitpotOrder","isNonBlinde","isNonBlindeSluitpott","item","validation","dirty","s","updateSluitpot","sp","bewerkingRemoved","removePill","selectedBwErrors","selectorDisabled","neutLengte","switchMap","getAllBewerkingen","bws","setBewerkingenOptions","setDisabledStateBySchema","updateNeutHeight","bewerking","getDataForCode","duplicateBewerkingError","preventDuplicateValues","cleanupBewerkingConflicts","revalidateBwerkingenOptions","DUPLICATE_ERROR_MESSAGE","addingKloostersponnigLeft","addingKloostersponnigRight","addingRenovatiesponnigLeft","addingRenovatiesponnigRight","isLosEindstuk","newBewerkingDecription","addingKloostersponnigBoth","addingRenovatiesponnigBoth","addingVersteksponnigLeft","addingVersteksponnigRight","cleansedList","hasSchema","errorObject","overflow","bewerkingCode","defaults","getDefaults","bewerkingData","onBewerkingSelected","dataState","addToCartButtonLabel","addToCartAndClearButtonLabel","invalidComponentsMessage","showBewerkingen","queryParamMap","getDorpelById","createBestellingDorpel","setCurrentDorpel","enableDorpelOpmerkingField","createTempDorpel","addDorpelData","dorpelForm","addNeutenData","neutenForm","getNeutenFormData","addSluitpottenData","sluitpotForm","getSluitpotModels","addBewerkingen","getData","preventNavigation","formsValidity","dataIsValid","v","checkFormValidity","validateNeutenComponents","state","editDorpel","createDorpel","addDorpelOpmerking","addDrawing","getDorpelDrawingData","dorpelOpmerking","currentRoute","segment","navigateByUrl","skipLocationChange","then","addToCart","clearData","CleanupService","stateService","dataService","_location","cleanupService","back","postRequest","r","cleanup","parent","alert","regularPosition","hasCustomDimensions","hasCustomOrientation","hasNeutCutOption","lengteLabel","orientatieLabel","dimensions","prefilledOrderFlowCleanup","getOrderNo","uploadAttachments","postForm","orderno","from","mergeMap","uploadAttachmentFile","uploadAttachment","onGoBackButtonClicked","onDorpelConfirmButtonClicked","RedirectComponent","onButtonClicked","seeLuvema","seeIsowel","seeCentor","seeHenderson","currentDealerGuid","sessionStorage","removeItem","setLandingPagePath","setCustomDealerResources","sleutel","setCurrentDealersGroup","randomDealer","luvema","isowel","centor","LuvemaLandingComponent","routes","redirectTo","pathMatch","children","canActivate","AppRoutingModule","useValue","route","forRoot","HeaderComponent","onHeaderClicked","TooltipComponent","isVisible","registerTooltipComponent","optionsObject","customStyle","title","cachedDealerGUID","request","clone","setHeaders","getApiKey","handle","CoreModule","ngModule","useClass","SharedModule","AppModule","bootstrapModule","catch","webpackEmptyAsyncContext","req","module","exports"],"mappings":"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","file":"x","sourcesContent":["export interface EnvConfig {\r\n baseUrl?: string;\r\n production?: boolean;\r\n disableFieldValidation?: boolean,\r\n luvemaApiKey: string\r\n}\r\n\r\nexport const environment: EnvConfig = {\r\n production: false,\r\n // baseUrl: 'https://localhost:44381/api', // LOCAL\r\n //baseUrl: 'https://luvemaapi.azurewebsites.net/api', // old\r\n //baseUrl: 'https://luvemaapidev.azurewebsites.net/api', // DEV\r\n // baseUrl: 'https://luvemaapitest.azurewebsites.net/api', // TEST\r\n baseUrl: 'https://luvemaapiprod.azurewebsites.net/api', // PROD\r\n disableFieldValidation: false,\r\n luvemaApiKey: 'Kasdu3IDAus38kJC'\r\n};\r\n\r\n","import { FormGroup, FormArray } from \"@angular/forms\";\r\n\r\nexport class FormComponent {\r\n constructor(public formGroup: FormGroup) {}\r\n\r\n public errorMessage(key: string): string {\r\n const formControl = this.formGroup.get(key);\r\n if (formControl.valid) {\r\n return \"\";\r\n }\r\n const [firstError] = Object.keys(formControl.errors);\r\n return ValidationMessages[firstError];\r\n }\r\n\r\n public showError(key: string, index?: number): boolean {\r\n if (!this.formGroup.get(key)) {\r\n console.log('No control for key=' + key);\r\n return;\r\n }\r\n\r\n if (index !== null && typeof index !== \"undefined\") {\r\n let formArray = this.formGroup.get(key) as FormArray;\r\n return !formArray.at(index).valid && formArray.at(index).touched;\r\n }\r\n\r\n return !this.formGroup.get(key).valid && this.formGroup.get(key).touched;\r\n }\r\n}\r\n\r\nconst ValidationMessages = {\r\n required: \"Dit veld is verplicht\",\r\n email: \"Dit is geen geldig e-mail adres\",\r\n min: \"Voer een hoger aantal in\",\r\n max: \"Voer een kleiner aantal in\",\r\n};\r\n","import { OnDestroy } from '@angular/core';\r\nimport { Subject } from 'rxjs';\r\n\r\nexport class BaseComponent implements OnDestroy {\r\n protected unsubscribe$: Subject<void> = new Subject<void>();\r\n\r\n public ngOnDestroy() {\r\n this.unsubscribe$.next();\r\n this.unsubscribe$.complete();\r\n }\r\n}\r\n","import {Directive} from \"@angular/core\";\r\nimport {NG_VALIDATORS, Validator, FormControl} from \"@angular/forms\";\r\n\r\n@Directive({\r\n selector: \"[acceptedFormats]\",\r\n providers: [\r\n { provide: NG_VALIDATORS, useExisting: FileFormatValidator, multi: true },\r\n ]\r\n})\r\nexport class FileFormatValidator implements Validator {\r\n static validate(control: FormControl): {[key: string]: boolean} | null {\r\n let fileName = control.value[0].name;\r\n let validationFailedResponse = {\r\n acceptedFile: true\r\n };\r\n \r\n if (!fileName) {\r\n return null;\r\n }\r\n \r\n let acceptedFileFormats = [\"pdf\", \"txt\", \"doc\", \"docx\"];\r\n let segments = fileName.split(\".\");\r\n let extension = segments[segments.length - 1];\r\n \r\n if(acceptedFileFormats.includes(extension)) {\r\n return null;\r\n }\r\n \r\n return validationFailedResponse;\r\n }\r\n\r\n validate(c: FormControl): {[key: string]: boolean} | null {\r\n return FileFormatValidator.validate(c);\r\n }\r\n}","export enum NeutPosition {\r\n Left,\r\n Center,\r\n Right\r\n}","import { Injectable } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { Observable, of } from 'rxjs';\r\nimport { environment } from 'src/environments/environment';\r\nimport { DealerDto, NeutDto, SluitpotDto, BewerkingDto, DorpelDto, GlaslatDto } from 'src/app/shared/api-models/models';\r\nimport {map, tap} from 'rxjs/internal/operators';\r\n\r\n@Injectable()\r\nexport class BackendService {\r\n private readonly dealersApiUrl = 'dealers';\r\n private readonly neutenApiUrl = 'neuten';\r\n private readonly glaslattenApiUrl = 'glaslatten';\r\n private readonly sluitpottenApiUrl = 'sluitpotten';\r\n private readonly bewerkingenApiUrl = 'bewerkingen';\r\n private readonly dorpelsApiUrl = 'dorpels';\r\n private readonly postMaakDocumentUrl = 'bestelling/PostMaakDocument';\r\n private readonly getOrderNoUrl = 'bestelling/OrderNumber';\r\n private readonly postPrefilledOrderformUrl = 'prefilled/PostPrefilledOrderform';\r\n private readonly addAttachmentUrl = 'bestelling/AddAttachment';\r\n private readonly removeAttachmentUrl = 'bestelling/RemoveAttachment';\r\n\r\n private _neuten: NeutDto[];\r\n private _glaslatten: GlaslatDto[];\r\n private _dealers: DealerDto[];\r\n\r\n public constructor(private httpClient: HttpClient) { }\r\n\r\n public getDealers(): Observable<DealerDto[]> {\r\n if (!this._dealers) {\r\n return this.httpClient.get<DealerDto[]>(`${environment.baseUrl}/${this.dealersApiUrl}`)\r\n .pipe(tap(dealers => this._dealers = dealers));\r\n }\r\n return of(this._dealers);\r\n }\r\n\r\n public getNeuten(): Observable<NeutDto[]> {\r\n if (!this._neuten) {\r\n return this.httpClient.get<NeutDto[]>(`${environment.baseUrl}/${this.neutenApiUrl}`)\r\n .pipe(tap(neuten => this._neuten = neuten));\r\n }\r\n return of(this._neuten);\r\n }\r\n\r\n public getGlaslatten(): Observable<GlaslatDto[]> {\r\n if (!this._glaslatten) {\r\n return this.httpClient.get<GlaslatDto[]>(`${environment.baseUrl}/${this.glaslattenApiUrl}`)\r\n .pipe(tap(glaslatten => this._glaslatten = glaslatten));\r\n }\r\n return of(this._glaslatten);\r\n }\r\n\r\n public getSluitpotten(): Observable<SluitpotDto[]> {\r\n return this.httpClient.get<SluitpotDto[]>(`${environment.baseUrl}/${this.sluitpottenApiUrl}`);\r\n }\r\n\r\n public getBewerkingen(dorpelCode: string): Observable<BewerkingDto[]> {\r\n return this.httpClient.get<BewerkingDto[]>(`${environment.baseUrl}/${this.bewerkingenApiUrl}/${dorpelCode}`);\r\n }\r\n\r\n public getAllBewerkingen(): Observable<BewerkingDto[]> {\r\n return this.httpClient.get<BewerkingDto[]>(`${environment.baseUrl}/${this.bewerkingenApiUrl}`);\r\n }\r\n\r\n public getDorpels(productType: string): Observable<DorpelDto[]> {\r\n return this.httpClient.get<DorpelDto[]>(`${environment.baseUrl}/${this.dorpelsApiUrl}`)\r\n .pipe(map(items => items.filter(dorpel => dorpel.productsoort.toLowerCase() === productType.toLowerCase())));\r\n }\r\n\r\n public postForm(formData: FormData, orderNo: string): Observable<any> {\r\n return this.httpClient.post(`${environment.baseUrl}/${this.postMaakDocumentUrl}/${orderNo}`, formData);\r\n }\r\n\r\n public getOrderNo(): Observable<any> {\r\n return this.httpClient.get(`${environment.baseUrl}/${this.getOrderNoUrl}`);\r\n }\r\n\r\n public postPrefilledOrderform(formData: FormData): Observable<any> {\r\n return this.httpClient.post(`${environment.baseUrl}/${this.postPrefilledOrderformUrl}`, formData);\r\n }\r\n\r\n public uploadAttachment(file: any, orderId: string): Observable<any> {\r\n const fileFormData = new FormData();\r\n fileFormData.append('file', file);\r\n return this.httpClient.post(`${environment.baseUrl}/${this.addAttachmentUrl}?orderId=${orderId}`, fileFormData);\r\n }\r\n\r\n public removeAttachment(fileName: string, orderId: string): Observable<any> {\r\n return this.httpClient.delete(`${environment.baseUrl}/${this.removeAttachmentUrl}?orderId=${orderId}&fileName=${fileName}`);\r\n }\r\n}\r\n","import { BestellingDto } from 'src/app/shared/api-models/models';\r\nimport {BestellingDorpelDto, BestellingNeutDto, BestellingSluitpotDto} from '../api-models/models';\r\nimport {Guid} from 'guid-typescript';\r\n\r\nexport class ModelFactory {\r\n\r\n public static createBestelling(): BestellingDto {\r\n const model = <BestellingDto> {};\r\n model.id = Guid.create().toString();\r\n model.afleverdatum = new Date();\r\n return model;\r\n }\r\n\r\n public static createBestellingDorpel(productType: string): BestellingDorpelDto {\r\n const model = <BestellingDorpelDto> {\r\n productType: productType,\r\n aantal: 1,\r\n aantalNeuten: 2,\r\n aantalSluitpotten: 0,\r\n guid: Guid.create().toString(),\r\n maatA: 0,\r\n maatZ: 0,\r\n bewerkingen: [],\r\n neuten: [\r\n this.createNeut(),\r\n this.createNeut()\r\n ],\r\n zaagmaat: 0,\r\n sluitpotten: []\r\n };\r\n \r\n return model;\r\n }\r\n\r\n public static createNeut(): BestellingNeutDto {\r\n const model = <BestellingNeutDto> {\r\n //daagmaat: 0\r\n };\r\n return model;\r\n }\r\n\r\n public static createSluitpot(): BestellingSluitpotDto {\r\n const model = <BestellingSluitpotDto> {\r\n //maat: 0\r\n };\r\n return model;\r\n }\r\n}\r\n","import { NeutPosition } from \"../../neuten/neut/neut-position\";\r\nimport { NeutDto } from \"../api-models/neutDto\";\r\n\r\nexport interface NeutModel {\r\n neut: string;\r\n omschrijving: string;\r\n sponningmaat: number;\r\n\r\n maatA: number;\r\n maatZ: number;\r\n daagmaat: number;\r\n sponningsoort: string;\r\n //positie: 'Links' | 'Rechts' | 'Tussen';\r\n position: NeutPosition;\r\n glaslat: string;\r\n beglazingsprofiel: string,\r\n aanslagprofiel: string,\r\n gemonteerd: boolean,\r\n damverbreeding: number,\r\n linksVoorsponning: VorsponningSize;\r\n rechtsVoorsponning: VorsponningSize;\r\n customWidth?: number\r\n}\r\n\r\nexport interface VorsponningSize {\r\n width: number;\r\n height: number;\r\n}\r\n\r\nexport const VOORSPONNING_SIZE_MAP = Object.freeze({\r\n \"6x6\": {\r\n width: 6,\r\n height: 6\r\n },\r\n \"8x8\": {\r\n width: 8,\r\n height: 8\r\n },\r\n \"6x19\": {\r\n width: 6,\r\n height: 19\r\n },\r\n \"8x19\": {\r\n width: 8,\r\n height: 19\r\n },\r\n \"6\": {\r\n width: 6,\r\n height: null\r\n },\r\n \"8\": {\r\n width: 8,\r\n height: null\r\n }\r\n});\r\n\r\nexport class NeutUtils {\r\n public static getNeutPositionFromString(pos: string): NeutPosition {\r\n let position = NeutPosition.Left;\r\n switch (pos) {\r\n case \"Tussen\":\r\n position = NeutPosition.Center;\r\n break;\r\n case \"Rechts\":\r\n position = NeutPosition.Right;\r\n break;\r\n default:\r\n position = NeutPosition.Left;\r\n }\r\n return position;\r\n }\r\n\r\n public static getPositionString(position: NeutPosition): string {\r\n switch (position) {\r\n case NeutPosition.Center:\r\n return \"Tussen\";\r\n case NeutPosition.Right:\r\n return \"Rechts\";\r\n }\r\n return \"Links\";\r\n }\r\n\r\n public static getPositionFromIndex(\r\n index: number,\r\n count: number\r\n ): NeutPosition {\r\n if (index === 0) {\r\n return NeutPosition.Left;\r\n }\r\n if (index === count - 1) {\r\n return NeutPosition.Right;\r\n }\r\n return NeutPosition.Center;\r\n }\r\n\r\n public static isRegular(neutDescription: string): boolean {\r\n let description = neutDescription.toLocaleLowerCase();\r\n return !this.isWissel(description) && !this.isDraaikiep(description) && !this.isSpecial(description);\r\n }\r\n\r\n public static isRegularTussen(neutDescription: string): boolean {\r\n let description = neutDescription.toLocaleLowerCase();\r\n return this.isRegular(description) && description.indexOf(\"tussen\") !== -1;\r\n }\r\n\r\n public static isRegularRight(neutDescription: string): boolean {\r\n let description = neutDescription.toLocaleLowerCase();\r\n return this.isRegular(description) && description.indexOf(\"rechts\") !== -1;\r\n }\r\n\r\n public static isWissel(neutDescription: string): boolean {\r\n let description = neutDescription.toLocaleLowerCase();\r\n return description.indexOf(\"w\") === 0;\r\n }\r\n\r\n public static isDraaikiep(neutDescription: string): boolean {\r\n let description = neutDescription.toLocaleLowerCase();\r\n return description.indexOf(\"dk\") !== -1;\r\n }\r\n\r\n public static isSpecial(neutDescription: string): boolean {\r\n let description = neutDescription.toLocaleLowerCase();\r\n return description.indexOf(\"x\") !== -1;\r\n }\r\n\r\n public static isDK(neutDescription: string): boolean {\r\n let description = neutDescription.toLocaleLowerCase();\r\n return description.indexOf(\"dk\") !== -1;\r\n }\r\n\r\n public static isDKLeft(neutDescription: string): boolean {\r\n let description = neutDescription.toLocaleLowerCase();\r\n return description.indexOf(\"dk\") !== -1 && description.indexOf(\"eindneut\") !== -1 && description.indexOf(\"links\") !== -1;\r\n }\r\n\r\n public static isDKRight(neutDescription: string): boolean {\r\n let description = neutDescription.toLocaleLowerCase();\r\n return description.indexOf(\"dk\") !== -1 && description.indexOf(\"eindneut\") !== -1 && description.indexOf(\"rechts\") !== -1;\r\n }\r\n\r\n public static isDKMidRight(neutDescription: string): boolean {\r\n let description = neutDescription.toLocaleLowerCase();\r\n return description.indexOf(\"dk\") !== -1 && description.indexOf(\"tussen\") !== -1 && description.indexOf(\"rechts\") !== -1;\r\n }\r\n\r\n public static isDKMidLeft(neutDescription: string): boolean {\r\n let description = neutDescription.toLocaleLowerCase();\r\n return description.indexOf(\"dk\") !== -1 && description.indexOf(\"tussen\") !== -1 && description.indexOf(\"links\") !== -1;\r\n }\r\n\r\n public static isDKMidBoth(neutDescription: string): boolean {\r\n let description = neutDescription.toLocaleLowerCase();\r\n return description.indexOf(\"dk\") !== -1 && description.indexOf(\"tussen\") !== -1 && (description.indexOf(\"ls+rs\") !== -1 || description.indexOf(\"ls + rs\") !== -1);\r\n }\r\n\r\n public static isW5(neutDescription: string): boolean {\r\n let description = neutDescription.toLocaleLowerCase();\r\n return description.indexOf(\"w5\") !== -1;\r\n }\r\n\r\n public static isW3(neutDescription: string): boolean {\r\n let description = neutDescription.toLocaleLowerCase();\r\n return description.indexOf(\"w3\") !== -1;\r\n }\r\n\r\n public static isW2(neutDescription: string): boolean {\r\n let description = neutDescription.toLocaleLowerCase();\r\n return description.indexOf(\"w2\") !== -1;\r\n }\r\n\r\n public static isW1(neutDescription: string): boolean {\r\n let description = neutDescription.toLocaleLowerCase();\r\n return description.indexOf(\"w1\") !== -1;\r\n }\r\n\r\n public static isW4(neutDescription: string): boolean {\r\n let description = neutDescription.toLocaleLowerCase();\r\n return description.indexOf(\"w4\") !== -1;\r\n }\r\n\r\n //NOT IN USE ANYMORE\r\n\r\n // public static getDimensionFromCode(neutenCode: string): number { \r\n // //\"N6351.L90.B\" code example for left 90mm\r\n // let splitCodeValues = neutenCode.split(\".\");\r\n // let positionAndSize = splitCodeValues[1];\r\n // let size = parseInt(positionAndSize.slice(-2));\r\n // return size;\r\n // }\r\n\r\n // private getNumericValueFromNeutCode(code: string): number {\r\n // const split = code.split('.');\r\n // if (split.length !== 3) return 0;\r\n // let codePart = split[1];\r\n // let nr = parseInt(codePart);\r\n // let index = 0;\r\n // while (Number.isNaN(nr)) {\r\n // codePart = codePart.substr(++index);\r\n // nr = parseInt(codePart);\r\n // }\r\n // return nr;\r\n // }\r\n\r\n public static getLabel(index: number, count: number, isSlidingDoor?: boolean): string {\r\n if (index === 0) {\r\n return isSlidingDoor ? \"Neut\" : \"Linkerneut\";\r\n }\r\n if (index === count - 1) {\r\n return \"Rechterneut\";\r\n }\r\n return \"Middenneut \" + index;\r\n }\r\n\r\n public static getVoorsponningOptions(\r\n isLeftVakConversion: boolean,\r\n isRightVakConversion: boolean,\r\n isSpecialCaseException: boolean,\r\n isBinnenDorpel: boolean,\r\n isBuitenDorpel: boolean) {\r\n let leftOptions: string[] = [];\r\n let rightOptions: string[] = [];\r\n if (isBinnenDorpel || isLeftVakConversion) {\r\n leftOptions = [\"6x6\", \"8x8\"];\r\n if (isSpecialCaseException) {\r\n leftOptions.push(...[\"6x19\", \"8x19\"])\r\n }\r\n } else if (isBuitenDorpel) {\r\n leftOptions = [\"6x19\", \"8x19\"];\r\n } else {\r\n leftOptions = [\"6\", \"8\"];\r\n }\r\n\r\n if (isBinnenDorpel || isRightVakConversion) {\r\n rightOptions = [\"6x6\", \"8x8\"];\r\n if (isSpecialCaseException) {\r\n rightOptions.push(...[\"6x19\", \"8x19\"])\r\n }\r\n } else if (isBuitenDorpel) {\r\n rightOptions = [\"6x19\", \"8x19\"];\r\n } else {\r\n rightOptions = [\"6\", \"8\"];\r\n }\r\n\r\n return {\r\n leftOptions,\r\n rightOptions\r\n }\r\n }\r\n\r\n public static getVorsponningValue(vorsponning?: VorsponningSize): string {\r\n if (!vorsponning) {\r\n return;\r\n }\r\n let keys = Object.keys(VOORSPONNING_SIZE_MAP);\r\n for (let i = 0; i < keys.length; i++) {\r\n const crtVorsponning = VOORSPONNING_SIZE_MAP[keys[i]];\r\n\r\n if (crtVorsponning.width === vorsponning.width && crtVorsponning.height === vorsponning.height) {\r\n return keys[i];\r\n }\r\n }\r\n }\r\n\r\n public static getDrawingCoorodatesList(tekeningString: string, rtlOffset: number, xOffset?: number, yOffset?: number): Array<{ x: number, y: number }> {\r\n let pointsList = tekeningString.split(\"/\");\r\n let result = [];\r\n /**\r\n * if second coordinate has a negative x value, this means that the neut is drawn from Right to Left\r\n * in this scenario, we add the neut width to each x coordinate to shift it back into place as it was LTR\r\n */\r\n let isDrawingRTL = parseInt(pointsList[1].split(\",\")[0]) < 0;\r\n let isDrawingHalves = pointsList[pointsList.length - 1] !== \"0,0\";\r\n\r\n pointsList.forEach(point => {\r\n let coordinates = point.split(\",\");\r\n result.push({\r\n x: parseInt(coordinates[0]) + (xOffset || 0) + (isDrawingRTL ? (isDrawingHalves ? rtlOffset / 2 : rtlOffset) : 0),\r\n y: parseInt(coordinates[1]) + (yOffset || 0)\r\n });\r\n });\r\n\r\n return result;\r\n }\r\n}\r\n","import { ModelFactory } from \"./../../shared/models/model-factory\";\r\nimport { Injectable } from \"@angular/core\";\r\nimport {\r\n BestellingBewerkingDto,\r\n BestellingDorpelDto,\r\n BestellingDto,\r\n BestellingNeutDto,\r\n BestellingSluitpotDto,\r\n} from \"src/app/shared/api-models/models\";\r\nimport { DorpelType } from \"src/app/shared/models/dorpel-type.model\";\r\nimport { NeutModel, NeutUtils } from \"src/app/shared/models/neut.model\";\r\nimport { SluitpotModel } from \"src/app/shared/models/sluitpot.model\";\r\n\r\nconst HOME_PATH_STORAGE_KEY = \"hp\";\r\n\r\n@Injectable({\r\n providedIn: \"root\",\r\n})\r\nexport class DataStateService {\r\n public homePath: string;\r\n public landingPagePath: string = \"/\";\r\n private submitModel: BestellingDto;\r\n private index: number = 0;\r\n\r\n constructor() {}\r\n\r\n public createDorpel(model: BestellingDorpelDto): DataStateService {\r\n const dorpelModel = model;\r\n const sm = this.getModel();\r\n sm.dorpels.push(dorpelModel);\r\n this.index = sm.dorpels.length - 1;\r\n\r\n return this;\r\n }\r\n\r\n public editDorpel(guid: string): DataStateService {\r\n this.index = this.getModel().dorpels.findIndex(\r\n (dorpel) => dorpel.guid === guid\r\n );\r\n return this;\r\n }\r\n\r\n public createTempDorpel(dorpelDto: BestellingDorpelDto): BestellingDorpelDto {\r\n const dorpel = JSON.stringify(dorpelDto);\r\n const temp = JSON.parse(dorpel) as BestellingDorpelDto;\r\n return temp;\r\n }\r\n\r\n public addDorpelData(\r\n dorpelType: DorpelType,\r\n dorpelOrder?: BestellingDorpelDto\r\n ): DataStateService {\r\n const dorpel = dorpelOrder || this.getCurrentDorpel();\r\n dorpel.aantalNeuten = dorpelType.aantalNeuten;\r\n dorpel.aantalSluitpotten = dorpelType.aantalSluitpotten;\r\n dorpel.dorpelCode = dorpelType.dorpel;\r\n dorpel.merk = dorpelType.merk;\r\n dorpel.zaagmaat = dorpelType.zaagmaat;\r\n dorpel.schema = dorpelType.schema;\r\n dorpel.firstMaatA = dorpelType.firstMaatA;\r\n\r\n dorpel.deurmaatA = dorpelType.deurmaatA;\r\n dorpel.deurmaatB = dorpelType.deurmaatB;\r\n dorpel.deurmaatC = dorpelType.deurmaatC;\r\n dorpel.maatA = dorpelType.maatA;\r\n dorpel.maatB = dorpelType.maatB;\r\n dorpel.maatC = dorpelType.maatC;\r\n dorpel.maatZ = dorpelType.maatZ;\r\n //opmerking detached to separate form handled in the dorpel page component\r\n //due to its position in the view - see addDorpelOpmerking method\r\n dorpel.aantal = dorpelType.aantal;\r\n dorpel.isInHouseDorpel = true;\r\n\r\n return this;\r\n }\r\n\r\n public addNeutenData(\r\n neutenModels: NeutModel[],\r\n dorpelOrder?: BestellingDorpelDto\r\n ): DataStateService {\r\n const dorpel = dorpelOrder || this.getCurrentDorpel();\r\n dorpel.neuten = neutenModels.map(\r\n (nm) =>\r\n <BestellingNeutDto>{\r\n daagmaat: nm.daagmaat,\r\n neutCode: nm.neut,\r\n neutDescription: nm.omschrijving,\r\n positie: NeutUtils.getPositionString(nm.position),\r\n sponningmaat: nm.sponningmaat,\r\n sponningsoort: nm.sponningsoort,\r\n glaslat: nm.glaslat,\r\n beglazingsprofiel: nm.beglazingsprofiel,\r\n aanslagprofiel: nm.aanslagprofiel,\r\n damverbreeding: nm.damverbreeding,\r\n gemonteerd: nm.gemonteerd,\r\n linksVoorsponning: nm.linksVoorsponning,\r\n rechtsVoorsponning: nm.rechtsVoorsponning,\r\n isInHouseNeut: true,\r\n customWidth: nm.customWidth\r\n }\r\n );\r\n\r\n /**\r\n * for sliding doors, the maatA and maatZ values are already set by addDorpelData() function,\r\n * as they reside on the dorpel component / form (we use a special different layout);\r\n **/\r\n dorpel.maatA = dorpel.maatA || neutenModels[0].maatA;\r\n dorpel.maatZ = dorpel.maatZ || neutenModels[neutenModels.length - 1].maatZ;\r\n\r\n return this;\r\n }\r\n\r\n public addSluitpottenData(\r\n models: SluitpotModel[],\r\n dorpelOrder?: BestellingDorpelDto\r\n ): DataStateService {\r\n const dorpel = dorpelOrder || this.getCurrentDorpel();\r\n dorpel.sluitpotten = models.map(\r\n (model) =>\r\n <BestellingSluitpotDto>{\r\n maat: model.maat,\r\n maat2: model.maat2,\r\n sluitpotCode: model.sluitpotCode,\r\n omschrijving: model.omschrijving,\r\n }\r\n );\r\n\r\n return this;\r\n }\r\n\r\n public addBewerkingen(\r\n models: BestellingBewerkingDto[],\r\n dorpelOrder?: BestellingDorpelDto\r\n ): DataStateService {\r\n const dorpel = dorpelOrder || this.getCurrentDorpel();\r\n dorpel.bewerkingen = models;\r\n return this;\r\n }\r\n\r\n public addDorpelOpmerking(\r\n opmerking: string,\r\n dorpelOrder?: BestellingDorpelDto\r\n ): DataStateService {\r\n const dorpel = dorpelOrder || this.getCurrentDorpel();\r\n dorpel.opmerking = opmerking.trim();\r\n return this;\r\n }\r\n\r\n public addDrawing(\r\n drawingData?: string,\r\n dorpelOrder?: BestellingDorpelDto\r\n ): DataStateService {\r\n if (!drawingData) {\r\n return this;\r\n }\r\n\r\n const dorpel = dorpelOrder || this.getCurrentDorpel();\r\n dorpel.drawing = drawingData;\r\n return this;\r\n }\r\n\r\n public getModel(): BestellingDto {\r\n if (!this.submitModel) {\r\n this.submitModel = ModelFactory.createBestelling();\r\n this.submitModel.dorpels = [];\r\n this.submitModel.files = [];\r\n }\r\n\r\n if (!this.submitModel.files) {\r\n //prefilled order models come from BE without the files key\r\n this.submitModel.files = [];\r\n }\r\n\r\n return this.submitModel;\r\n }\r\n\r\n public setModel(model: BestellingDto): void {\r\n this.submitModel = model;\r\n this.index = 0;\r\n }\r\n\r\n public setHomePath(path: string): void {\r\n this.homePath = path;\r\n }\r\n\r\n public setLandingPagePath(path: string): void {\r\n this.landingPagePath = path;\r\n }\r\n\r\n public getCurrentDorpel(): BestellingDorpelDto {\r\n return this.getModel().dorpels[this.index];\r\n }\r\n\r\n public getDorpelById(dorpelId: string): BestellingDorpelDto {\r\n return this.getModel().dorpels.find((dorpel) => dorpel.guid === dorpelId);\r\n }\r\n}\r\n","import { BestellingDorpelDto, BestellingNeutDto } from \"../api-models/models\";\r\nimport { ModelFactory } from \"./model-factory\";\r\n\r\nexport class DorpelDecorator {\r\n public static setNumberOfSluitpotten(\r\n target: BestellingDorpelDto,\r\n count: number\r\n ): BestellingDorpelDto {\r\n target.aantalSluitpotten = count;\r\n if (target.sluitpotten?.length > count) {\r\n target.sluitpotten.splice(count);\r\n } else {\r\n const sluitpottenCount = target.sluitpotten?.length;\r\n for (let i = 0; i < count - sluitpottenCount; i++) {\r\n target.sluitpotten.push(ModelFactory.createSluitpot());\r\n }\r\n }\r\n return target;\r\n }\r\n\r\n public static setNumberOfNeuten(\r\n target: BestellingDorpelDto,\r\n count: number\r\n ): BestellingDorpelDto {\r\n target.aantalNeuten = count;\r\n if (target.neuten.length > count) {\r\n if(count > 1) {\r\n let length = target.neuten.length;\r\n let extra = length - count;\r\n target.neuten.splice(length - extra - 1, extra);\r\n } else if (count === 1) {\r\n target.neuten.splice(1);\r\n }\r\n } else {\r\n const neutenCount = target.neuten.length;\r\n const diff = count - neutenCount;\r\n for (let i = 0; i < diff; i++) {\r\n target.neuten.splice(target.neuten.length - 1, 0, ModelFactory.createNeut())\r\n }\r\n }\r\n return target;\r\n }\r\n}\r\n","/**\r\n * Bestelformulier API\r\n * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)\r\n *\r\n * OpenAPI spec version: v1\r\n * \r\n *\r\n * NOTE: This class is auto generated by the swagger code generator program.\r\n * https://github.com/swagger-api/swagger-codegen.git\r\n * Do not edit the class manually.\r\n */\r\nconst KLOOSTERSPONNING_KEYWORD = \"kloostersp\";\r\nconst RENOVATIESPONNING_KEYWORD = \"renovatiesp\";\r\nconst VERSTEKSPONNING_KEYWORD = \"verstek\";\r\nexport interface BewerkingDto {\r\n bewerkingCode?: string;\r\n omschrijving?: string;\r\n dorpelCode?: string;\r\n}\r\n\r\nexport type VerstekOrientatie = \"naarBuiten\" | \"naarBinnen\"\r\n\r\nexport type BewerkingDefaultValues = {\r\n offset: number,\r\n depth: number,\r\n length: number,\r\n delta: number,\r\n orientatie: VerstekOrientatie;\r\n cutNeut: boolean\r\n}\r\n\r\nconst DEFAULT_VALUES = {\r\n kloostersponning: {\r\n offset: 22,\r\n depth: 10,\r\n length: 70,\r\n delta: 22\r\n },\r\n renovatiesponning: {\r\n offset: 0,\r\n depth: 10,\r\n length: 94,\r\n delta: 20\r\n },\r\n verstekSponning: {\r\n orientatie: \"naarBuiten\" as VerstekOrientatie,\r\n cutNeut: false\r\n }\r\n}\r\n\r\nexport class BewerkingUtils {\r\n public static isRenovatiesponning(bewerkingDescription: string): boolean {\r\n let description = bewerkingDescription.toLowerCase();\r\n\r\n return description.indexOf(RENOVATIESPONNING_KEYWORD) !== -1;\r\n }\r\n\r\n public static isRenovatiesponningLeft(bewerkingDescription: string): boolean {\r\n let description = bewerkingDescription.toLowerCase();\r\n\r\n return this.isRenovatiesponning(bewerkingDescription) && description.indexOf(\"link\") !== -1 &&\r\n description.indexOf(\"l&r\") === -1 && description.indexOf(\"l&r\") === -1 && description.indexOf(\"links & rechts\") === -1;\r\n }\r\n\r\n public static isRenovatiesponningRight(bewerkingDescription: string): boolean {\r\n let description = bewerkingDescription.toLowerCase();\r\n\r\n return this.isRenovatiesponning(bewerkingDescription) && description.indexOf(\"recht\") !== -1 &&\r\n description.indexOf(\"l&r\") === -1 && description.indexOf(\"l&r\") === -1 && description.indexOf(\"links & rechts\") === -1;\r\n }\r\n public static isRenovatiesponningLeftAndRight(bewerkingDescription: string): boolean {\r\n let description = bewerkingDescription.toLowerCase();\r\n\r\n return this.isRenovatiesponning(bewerkingDescription) &&\r\n (description.indexOf(\"l&r\") !== -1 || description.indexOf(\"l&r\") !== -1 || description.indexOf(\"links & rechts\") !== -1);\r\n }\r\n\r\n public static isKloostersponning(bewerkingDescription: string): boolean {\r\n let description = bewerkingDescription.toLowerCase();\r\n\r\n return description.indexOf(KLOOSTERSPONNING_KEYWORD) !== -1;\r\n }\r\n\r\n public static isKloostersponningLeft(bewerkingDescription: string): boolean {\r\n let description = bewerkingDescription.toLowerCase();\r\n\r\n return this.isKloostersponning(bewerkingDescription) && description.indexOf(\"link\") !== -1 &&\r\n description.indexOf(\"l&r\") === -1 && description.indexOf(\"l&r\") === -1 && description.indexOf(\"links & rechts\") === -1;\r\n }\r\n\r\n public static isKloostersponningRight(bewerkingDescription: string): boolean {\r\n let description = bewerkingDescription.toLowerCase();\r\n\r\n return this.isKloostersponning(bewerkingDescription) && description.indexOf(\"recht\") !== -1 &&\r\n description.indexOf(\"l&r\") === -1 && description.indexOf(\"l&r\") === -1 && description.indexOf(\"links & rechts\") === -1;\r\n }\r\n\r\n public static isKloostersponningLeftAndRight(bewerkingDescription: string): boolean {\r\n let description = bewerkingDescription.toLowerCase();\r\n\r\n return this.isKloostersponning(bewerkingDescription) &&\r\n (description.indexOf(\"l&r\") !== -1 || description.indexOf(\"l&r\") !== -1 || description.indexOf(\"links & rechts\") !== -1);\r\n }\r\n\r\n public static isVersteksponning(bewerkingDescription: string): boolean {\r\n let description = bewerkingDescription.toLowerCase();\r\n\r\n return description.indexOf(VERSTEKSPONNING_KEYWORD) !== -1;\r\n }\r\n\r\n public static isVersteksponningLeft(bewerkingDescription: string): boolean {\r\n let description = bewerkingDescription.toLowerCase();\r\n\r\n return this.isVersteksponning(bewerkingDescription) && description.indexOf(\"link\") !== -1;\r\n }\r\n\r\n public static isVersteksponningRight(bewerkingDescription: string): boolean {\r\n let description = bewerkingDescription.toLowerCase();\r\n\r\n return this.isVersteksponning(bewerkingDescription) && description.indexOf(\"recht\") !== -1;\r\n }\r\n\r\n public static isLosEindstuk(bewerkingDescription: string): boolean {\r\n let description = bewerkingDescription.toLowerCase();\r\n\r\n return description.indexOf(\"eindstuk\") !== -1;\r\n }\r\n\r\n public static getDefaults(bewerkingDescription: string): Partial<BewerkingDefaultValues> {\r\n if (BewerkingUtils.isKloostersponning(bewerkingDescription)) {\r\n return DEFAULT_VALUES.kloostersponning;\r\n }\r\n\r\n if (BewerkingUtils.isRenovatiesponning(bewerkingDescription)) {\r\n return DEFAULT_VALUES.renovatiesponning;\r\n }\r\n\r\n if (BewerkingUtils.isVersteksponning(bewerkingDescription)) {\r\n return DEFAULT_VALUES.verstekSponning;\r\n }\r\n }\r\n\r\n}","const CUSTOM_DEALERS_RESOURCE_MAP = Object.freeze({\r\n \"EB8BF0F7-5281-4EFA-B08D-D9DC09BE27F7\": {\r\n resourcesFolderName: \"burghouwt\",\r\n customLink: \"https://www.burghouwt.nl/\",\r\n dealerName: \"Burghouwt\",\r\n customClass: \"burghouwt\"\r\n }\r\n});\r\nexport type DealerCustomResources = {\r\n resourcesFolderName: string,\r\n customLink: string,\r\n customClass: string,\r\n dealerName: string\r\n}\r\nexport const DEALER_GUID_STORAGE_KEY = \"dealerGUID\";\r\nexport default CUSTOM_DEALERS_RESOURCE_MAP;","import { Injectable } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\nimport { BestellingDorpelDto, DorpelDto } from 'src/app/shared/api-models/models';\r\nimport { DorpelDecorator } from 'src/app/shared/models/dorpel-decorator';\r\nimport { filter } from 'rxjs/operators';\r\nimport { BestellingNeutDto, NeutDto, BestellingBewerkingDto, DealerDto } from '../../shared/api-models/models';\r\nimport { BewerkingUtils, VerstekOrientatie } from '../../shared/api-models/bewerkingDto';\r\nimport { ModelFactory } from '../../shared/models/model-factory';\r\nimport CUSTOM_DEALERS_RESOURCE_MAP, { DealerCustomResources } from '../../dealers/custom-dealer-resource-map';\r\nimport { VorsponningSize } from 'src/app/shared/models/neut.model';\r\n\r\nexport interface FormState {\r\n aantalNeuten?: number;\r\n aantalSluitpotten?: number;\r\n dorpel?: DorpelDto;\r\n}\r\ninterface SponningOptions {\r\n isActive: boolean;\r\n isLeftSide: boolean;\r\n isRightSide: boolean;\r\n leftCustomDepth: number;\r\n leftCustomLength: number;\r\n leftCustomOffset: number;\r\n rightCustomDepth: number;\r\n rightCustomLength: number;\r\n rightCustomOffset: number;\r\n leftOrientatie?: VerstekOrientatie;\r\n rightOrientatie?: VerstekOrientatie;\r\n}\r\n\r\n@Injectable()\r\nexport class UiStateService {\r\n\r\n public viewMode: 'Edit' | 'Add';\r\n\r\n public logoUrl: string;\r\n\r\n public fromPrefilledOrder: boolean = false;\r\n\r\n private _currentDorpel: BestellingDorpelDto;\r\n\r\n private _isDrawingInExampleMode: boolean;\r\n\r\n private _currentProductType: string;\r\n\r\n private _railType: string | null;\r\n\r\n private _currentDealersGroup: DealerDto[] | null;\r\n\r\n private _customDealerResources: DealerCustomResources | null;\r\n\r\n private _redrawCount = 0;\r\n\r\n public dorpelChoices: DorpelDto[] = [];\r\n\r\n public neutenChoices: NeutDto[] = [];\r\n\r\n public kloosterSponningOptions: SponningOptions;\r\n\r\n public renovatieSponningOptions: SponningOptions;\r\n\r\n public verstekSponningOptions: SponningOptions;\r\n\r\n public setNeutenChoices(choices: NeutDto[]): void {\r\n this.neutenChoices = choices;\r\n }\r\n\r\n public turnOnDrawingExample() {\r\n this._isDrawingInExampleMode = true;\r\n }\r\n\r\n public turnOffDrawingExample() {\r\n this._isDrawingInExampleMode = false;\r\n }\r\n\r\n public isDrawingInExampleMode(): boolean {\r\n return this._isDrawingInExampleMode;\r\n }\r\n\r\n public getNeutDtoByCodeAndPositie(neutCode: string, positie: string): NeutDto {\r\n return this.neutenChoices.find(neut => neut.neutCode === neutCode && neut.positie === positie);\r\n }\r\n\r\n public get currentProductType(): string {\r\n return this._currentProductType;\r\n }\r\n\r\n public get currentDorpel(): BestellingDorpelDto {\r\n return this._currentDorpel;\r\n }\r\n\r\n public get currentDealersGroup(): DealerDto[] | null {\r\n return this._currentDealersGroup;\r\n }\r\n\r\n public get customDealerResources(): DealerCustomResources | null {\r\n return this._customDealerResources;\r\n }\r\n public get railType(): string | null {\r\n return this._railType;\r\n }\r\n\r\n public get isCurrentDorpelSliding(): boolean {\r\n const dorpelCode = this.currentDorpel.dorpelCode;\r\n const chosenDorpel = this.dorpelChoices.find(d => d.dorpelCode === dorpelCode);\r\n let isCurrentDoorSliding = chosenDorpel.dorpelsoort === \"Hefschuifdorpel\";\r\n\r\n return isCurrentDoorSliding;\r\n }\r\n\r\n private _sluitpottenCount$: BehaviorSubject<number> = new BehaviorSubject<number>(null);\r\n\r\n public get sluitpottenCount$(): Observable<number> {\r\n //we need to notify empty field values or 0s to disable fields as part of the field dependency work\r\n return this._sluitpottenCount$.asObservable()/*.pipe(filter(count => !!count))*/;\r\n }\r\n\r\n private _redraw$: BehaviorSubject<number> = new BehaviorSubject<number>(null);\r\n\r\n public get redraw$(): Observable<number> {\r\n return this._redraw$.asObservable();\r\n }\r\n\r\n public triggerRedraw(): void {\r\n this._redrawCount += 1;\r\n this._redraw$.next(this._redrawCount);\r\n }\r\n\r\n private _neutenCount$: BehaviorSubject<number> = new BehaviorSubject<number>(null);\r\n\r\n public get neutenCount$(): Observable<number> {\r\n //we need to notify empty field values or 0s to disable fields as part of the field dependency work\r\n return this._neutenCount$.asObservable()/*.pipe(filter(count => !!count))*/;\r\n }\r\n\r\n private _schema$: BehaviorSubject<string> = new BehaviorSubject<string>(null);\r\n\r\n public get schema$(): Observable<string> {\r\n return this._schema$.asObservable().pipe(filter(schema => !!schema));\r\n }\r\n\r\n private _productType$: BehaviorSubject<string> = new BehaviorSubject<string>(null);\r\n\r\n public get productType$(): Observable<string> {\r\n return this._productType$.asObservable().pipe(filter(p => !!p));\r\n }\r\n\r\n //CUSTOM WIDTH FOR SPECIAL NEUTEN\r\n private _neutCustomWidthUpdateSubject = new BehaviorSubject<any>(null);\r\n public neutCustomWidthUpdate$ = this._neutCustomWidthUpdateSubject.asObservable();\r\n public updateSpecialNeutCustomWidth(width: number): void {\r\n this._neutCustomWidthUpdateSubject.next(width);\r\n }\r\n\r\n public setProductType(productType: string): void {\r\n this._currentProductType = productType\r\n this._productType$.next(productType);\r\n }\r\n\r\n private _dorpelCode$: BehaviorSubject<string> = new BehaviorSubject<string>(null);\r\n\r\n public get dorpelCode$(): Observable<string> {\r\n return this._dorpelCode$.asObservable().pipe(filter(code => !!code));\r\n }\r\n\r\n private _zaagmaat$: BehaviorSubject<number> = new BehaviorSubject<number>(null);\r\n\r\n public get zaagmaat$(): Observable<number> {\r\n return this._zaagmaat$.asObservable().pipe(filter(value => !!value));\r\n }\r\n\r\n private _maatA$: BehaviorSubject<number> = new BehaviorSubject<number>(null);\r\n\r\n public get maatA$(): Observable<number> {\r\n return this._maatA$.asObservable().pipe(filter(value => !!value));\r\n }\r\n\r\n private _maatZ$: BehaviorSubject<number> = new BehaviorSubject<number>(null);\r\n\r\n public get maatZ$(): Observable<number> {\r\n return this._maatZ$.asObservable().pipe(filter(value => !!value));\r\n }\r\n\r\n private _deurmaatA$: BehaviorSubject<number> = new BehaviorSubject<number>(null);\r\n\r\n public get deurmaatA$(): Observable<number> {\r\n return this._deurmaatA$.asObservable().pipe(filter(value => !!value));\r\n }\r\n\r\n private _deurmaatB$: BehaviorSubject<number> = new BehaviorSubject<number>(null);\r\n\r\n public get deurmaatB$(): Observable<number> {\r\n return this._deurmaatB$.asObservable().pipe(filter(value => !!value));\r\n }\r\n\r\n private _maatB$: BehaviorSubject<number> = new BehaviorSubject<number>(null);\r\n\r\n public get maatB$(): Observable<number> {\r\n return this._maatB$.asObservable().pipe(filter(value => !!value));\r\n }\r\n\r\n private _firstMaatA$: BehaviorSubject<number> = new BehaviorSubject<number>(null);\r\n\r\n public get firstMaatA$(): Observable<number> {\r\n return this._firstMaatA$.asObservable().pipe(filter(value => !!value));\r\n }\r\n\r\n private _deurmaatC$: BehaviorSubject<number> = new BehaviorSubject<number>(null);\r\n\r\n public get deurmaatC$(): Observable<number> {\r\n return this._deurmaatC$.asObservable().pipe(filter(value => !!value));\r\n }\r\n\r\n private _maatC$: BehaviorSubject<number> = new BehaviorSubject<number>(null);\r\n\r\n public get maatC$(): Observable<number> {\r\n return this._maatC$.asObservable().pipe(filter(value => !!value));\r\n }\r\n\r\n private _neuten$: BehaviorSubject<BestellingNeutDto[]> = new BehaviorSubject<BestellingNeutDto[]>([]);\r\n\r\n public get neuten$(): Observable<BestellingNeutDto[]> {\r\n return this._neuten$.asObservable().pipe(filter(value => !!value));\r\n }\r\n\r\n public setCurrentDorpel(dorpelOrder: BestellingDorpelDto, preventDataReset: boolean = true): void {\r\n if (!dorpelOrder) {\r\n throw new Error('dorpelOrder should not be null!');\r\n }\r\n this._currentDorpel = dorpelOrder;\r\n this.setSluitpottenCount(this.currentDorpel.aantalSluitpotten);\r\n this.setDorpelCode(this.currentDorpel.dorpelCode, preventDataReset); //call with prevent dorpel data reset\r\n this.setNeutenCount(this.currentDorpel.aantalNeuten);\r\n this.setSchema(this.currentDorpel.schema);\r\n this.setZaagmaat(this.currentDorpel.zaagmaat);\r\n this.setMaatA(this.currentDorpel.maatA);\r\n this.setFirstMaatA(this.currentDorpel.firstMaatA);\r\n this.setDeurmaatA(this.currentDorpel.deurmaatA);\r\n this.setMaatB(this.currentDorpel.maatB);\r\n this.setDeurmaatB(this.currentDorpel.deurmaatB);\r\n this.setMaatC(this.currentDorpel.maatC);\r\n this.setDeurmaatC(this.currentDorpel.deurmaatC);\r\n this.setMaatZ(this.currentDorpel.maatZ);\r\n }\r\n\r\n public setNeutenCount(count: number): void {\r\n DorpelDecorator.setNumberOfNeuten(this.currentDorpel, count);\r\n this._neutenCount$.next(count);\r\n }\r\n\r\n private getResetSponningOptions(): SponningOptions {\r\n return {\r\n isActive: false,\r\n isLeftSide: false,\r\n isRightSide: false,\r\n leftCustomDepth: null,\r\n leftCustomLength: null,\r\n leftCustomOffset: null,\r\n rightCustomDepth: null,\r\n rightCustomLength: null,\r\n rightCustomOffset: null,\r\n leftOrientatie: \"naarBuiten\",\r\n rightOrientatie: \"naarBuiten\"\r\n }\r\n }\r\n\r\n public setBewerkingenOptions(selectedBwCodes: BestellingBewerkingDto[]): void {\r\n let leftKloostersponningActive = false;\r\n let leftRenovatiesponningActive = false;\r\n let rightKloostersponningActive = false;\r\n let rightRenovatiesponningActive = false;\r\n let leftVersteksponningActive = false;\r\n let rightVersteksponningActive = false;\r\n\r\n let leftKloostersponningCustomDepth = null;\r\n let leftRenovatiesponningCustomDepth = null;\r\n let rightKloostersponningCustomDepth = null;\r\n let rightRenovatiesponningCustomDepth = null;\r\n let leftVersteksponningCustomDepth = null;\r\n let rightVersteksponningCustomDepth = null;\r\n\r\n let leftKloostersponningCustomOffset = null;\r\n let leftRenovatiesponningCustomOffset = null;\r\n let rightKloostersponningCustomOffset = null;\r\n let rightRenovatiesponningCustomOffset = null;\r\n let leftVersteksponningCustomOffset = null;\r\n let rightVersteksponningCustomOffset = null;\r\n\r\n let leftKloostersponningCustomLength = null;\r\n let leftRenovatiesponningCustomLength = null;\r\n let rightKloostersponningCustomLength = null;\r\n let rightRenovatiesponningCustomLength = null;\r\n let leftVersteksponningCustomLength = null;\r\n let rightVersteksponningCustomLength = null;\r\n\r\n let leftVerstekSponningOrientatie = \"naarBuiten\" as VerstekOrientatie;\r\n let rightVerstekSponningOrientatie = \"naarBuiten\" as VerstekOrientatie;\r\n\r\n if (!selectedBwCodes.length) {\r\n this.kloosterSponningOptions = this.getResetSponningOptions();\r\n this.renovatieSponningOptions = this.getResetSponningOptions();\r\n this.verstekSponningOptions = this.getResetSponningOptions();\r\n } else {\r\n selectedBwCodes.forEach((bw, index) => {\r\n if (BewerkingUtils.isKloostersponningLeft(bw.description)) {\r\n leftKloostersponningActive = true;\r\n leftKloostersponningCustomDepth = bw.customDepth;\r\n leftKloostersponningCustomLength = bw.customLength;\r\n leftKloostersponningCustomOffset = bw.customOffset;\r\n }\r\n\r\n if (BewerkingUtils.isKloostersponningRight(bw.description)) {\r\n rightKloostersponningActive = true;\r\n rightKloostersponningCustomDepth = bw.customDepth;\r\n rightKloostersponningCustomLength = bw.customLength;\r\n rightKloostersponningCustomOffset = bw.customOffset;\r\n }\r\n\r\n if (BewerkingUtils.isKloostersponningLeftAndRight(bw.description)) {\r\n leftKloostersponningActive = true;\r\n rightKloostersponningActive = true;\r\n leftKloostersponningCustomDepth = bw.customDepth;\r\n leftKloostersponningCustomLength = bw.customLength;\r\n leftKloostersponningCustomOffset = bw.customOffset;\r\n rightKloostersponningCustomDepth = bw.customDepth;\r\n rightKloostersponningCustomLength = bw.customLength;\r\n rightKloostersponningCustomOffset = bw.customOffset;\r\n }\r\n\r\n if (BewerkingUtils.isRenovatiesponningLeft(bw.description)) {\r\n leftRenovatiesponningActive = true;\r\n leftRenovatiesponningCustomDepth = bw.customDepth;\r\n leftRenovatiesponningCustomLength = bw.customLength;\r\n leftRenovatiesponningCustomOffset = bw.customOffset;\r\n }\r\n\r\n if (BewerkingUtils.isRenovatiesponningRight(bw.description)) {\r\n rightRenovatiesponningActive = true;\r\n rightRenovatiesponningCustomDepth = bw.customDepth;\r\n rightRenovatiesponningCustomLength = bw.customLength;\r\n rightRenovatiesponningCustomOffset = bw.customOffset;\r\n }\r\n\r\n if (BewerkingUtils.isRenovatiesponningLeftAndRight(bw.description)) {\r\n leftRenovatiesponningActive = true;\r\n rightRenovatiesponningActive = true;\r\n leftRenovatiesponningCustomDepth = bw.customDepth;\r\n leftRenovatiesponningCustomLength = bw.customLength;\r\n leftRenovatiesponningCustomOffset = bw.customOffset;\r\n rightRenovatiesponningCustomDepth = bw.customDepth;\r\n rightRenovatiesponningCustomLength = bw.customLength;\r\n rightRenovatiesponningCustomOffset = bw.customOffset;\r\n }\r\n\r\n if (BewerkingUtils.isVersteksponningLeft(bw.description)) {\r\n leftVersteksponningActive = true;\r\n leftVerstekSponningOrientatie = bw.orientatie;\r\n }\r\n\r\n if (BewerkingUtils.isVersteksponningRight(bw.description)) {\r\n rightVersteksponningActive = true;\r\n rightVerstekSponningOrientatie = bw.orientatie;\r\n }\r\n });\r\n\r\n this.renovatieSponningOptions = {\r\n isLeftSide: leftRenovatiesponningActive,\r\n isRightSide: rightRenovatiesponningActive,\r\n isActive: leftRenovatiesponningActive || rightRenovatiesponningActive,\r\n leftCustomDepth: leftRenovatiesponningCustomDepth,\r\n leftCustomLength: leftRenovatiesponningCustomLength,\r\n leftCustomOffset: leftRenovatiesponningCustomOffset,\r\n rightCustomDepth: rightRenovatiesponningCustomDepth,\r\n rightCustomLength: rightRenovatiesponningCustomLength,\r\n rightCustomOffset: rightRenovatiesponningCustomOffset\r\n }\r\n\r\n this.kloosterSponningOptions = {\r\n isLeftSide: leftKloostersponningActive,\r\n isRightSide: rightKloostersponningActive,\r\n isActive: leftKloostersponningActive || rightKloostersponningActive,\r\n leftCustomDepth: leftKloostersponningCustomDepth,\r\n leftCustomLength: leftKloostersponningCustomLength,\r\n leftCustomOffset: leftKloostersponningCustomOffset,\r\n rightCustomDepth: rightKloostersponningCustomDepth,\r\n rightCustomLength: rightKloostersponningCustomLength,\r\n rightCustomOffset: rightKloostersponningCustomOffset\r\n }\r\n\r\n //verstek custom depths are always null\r\n this.verstekSponningOptions = {\r\n isLeftSide: leftVersteksponningActive,\r\n isRightSide: rightVersteksponningActive,\r\n isActive: leftVersteksponningActive || rightVersteksponningActive,\r\n leftCustomDepth: leftVersteksponningCustomDepth,\r\n leftCustomLength: leftVersteksponningCustomLength,\r\n leftCustomOffset: leftVersteksponningCustomOffset,\r\n rightCustomDepth: rightVersteksponningCustomDepth,\r\n rightCustomLength: rightVersteksponningCustomLength,\r\n rightCustomOffset: rightVersteksponningCustomOffset,\r\n leftOrientatie: leftVerstekSponningOrientatie,\r\n rightOrientatie: rightVerstekSponningOrientatie\r\n }\r\n }\r\n }\r\n\r\n public setDorpelCode(dorpelCode: string, preventDataReset?: boolean): void {\r\n this.currentDorpel.dorpelCode = dorpelCode;\r\n this.kloosterSponningOptions = this.getResetSponningOptions();\r\n this.renovatieSponningOptions = this.getResetSponningOptions();\r\n this.verstekSponningOptions = this.getResetSponningOptions();\r\n\r\n if (!preventDataReset && !this.fromPrefilledOrder) {\r\n //reset neuten data\r\n for (let i = 0; i < this.currentDorpel.neuten.length; i++) {\r\n this.currentDorpel.neuten[i] = ModelFactory.createNeut();\r\n }\r\n\r\n //reset sluitpotten data\r\n for (let i = 0; i < this.currentDorpel.sluitpotten.length; i++) {\r\n this.currentDorpel.sluitpotten[i] = ModelFactory.createSluitpot();\r\n }\r\n\r\n //RESET VALUES\r\n this.currentDorpel.bewerkingen = [];\r\n this.currentDorpel.firstMaatA = 0;\r\n this.currentDorpel.deurmaatA = 0;\r\n this.currentDorpel.deurmaatB = 0;\r\n this.currentDorpel.deurmaatC = 0;\r\n this.currentDorpel.maatA = 0;\r\n this.currentDorpel.maatB = 0;\r\n this.currentDorpel.maatC = 0;\r\n this.currentDorpel.maatZ = 0;\r\n this.currentDorpel.zaagmaat = 0;\r\n }\r\n\r\n this._dorpelCode$.next(dorpelCode);\r\n this._neuten$.next(this.currentDorpel.neuten);\r\n }\r\n\r\n public setRailType(type: string | null) {\r\n this.currentDorpel.railType = type;\r\n this._railType = type;\r\n }\r\n\r\n public setZaagmaat(zaagmaat: number): void {\r\n this.currentDorpel.zaagmaat = zaagmaat;\r\n this._zaagmaat$.next(zaagmaat);\r\n }\r\n\r\n public setMaatA(maatA: number): void {\r\n this.currentDorpel.maatA = maatA;\r\n this._maatA$.next(maatA);\r\n }\r\n\r\n public setMaatZ(maatZ: number): void {\r\n this.currentDorpel.maatZ = maatZ;\r\n this._maatZ$.next(maatZ);\r\n }\r\n\r\n public setDeurmaatA(deurmaatA: number): void {\r\n this.currentDorpel.deurmaatA = deurmaatA;\r\n this._deurmaatA$.next(deurmaatA);\r\n }\r\n\r\n public setDeurmaatB(deurmaatB: number): void {\r\n this.currentDorpel.deurmaatB = deurmaatB;\r\n this._deurmaatB$.next(deurmaatB);\r\n }\r\n\r\n public setMaatB(maatB: number): void {\r\n this.currentDorpel.maatB = maatB;\r\n this._maatB$.next(maatB);\r\n }\r\n\r\n public setFirstMaatA(firstMaatA: number): void {\r\n this.currentDorpel.firstMaatA = firstMaatA;\r\n this._firstMaatA$.next(firstMaatA);\r\n }\r\n\r\n public setDeurmaatC(deurmaatC: number): void {\r\n this.currentDorpel.deurmaatC = deurmaatC;\r\n this._deurmaatC$.next(deurmaatC);\r\n }\r\n\r\n public setMaatC(maatC: number): void {\r\n this.currentDorpel.maatC = maatC;\r\n this._maatC$.next(maatC);\r\n }\r\n\r\n public updateDaagmaat(daagmaat: number, index: number): void {\r\n this.currentDorpel.neuten[index].daagmaat = daagmaat;\r\n }\r\n\r\n public updateGlaslat(glaslat: string, index: number): void {\r\n this.currentDorpel.neuten[index].glaslat = glaslat;\r\n }\r\n\r\n public updateBeglazingsprofiel(beglazingsprofiel: string, index: number): void {\r\n this.currentDorpel.neuten[index].beglazingsprofiel = beglazingsprofiel;\r\n }\r\n\r\n public updateAanslagprofiel(aanslagprofiel: string, index: number): void {\r\n this.currentDorpel.neuten[index].aanslagprofiel = aanslagprofiel;\r\n }\r\n\r\n public updateDamverbreeding(damverbreeding: number, index: number): void {\r\n this.currentDorpel.neuten[index].damverbreeding = damverbreeding;\r\n }\r\n\r\n public updateSpooningsoort(sponningsoort: string, index: number): void {\r\n this.currentDorpel.neuten[index].sponningsoort = sponningsoort;\r\n }\r\n\r\n public updateSponningmaat(sponningmaat: number, index: number): void {\r\n this.currentDorpel.neuten[index].sponningmaat = sponningmaat;\r\n }\r\n\r\n public setSluitpottenCount(count: number): void {\r\n DorpelDecorator.setNumberOfSluitpotten(this.currentDorpel, count);\r\n this._sluitpottenCount$.next(count);\r\n }\r\n\r\n public setSchema(schema: string): void {\r\n this.currentDorpel.schema = schema;\r\n this._schema$.next(schema);\r\n }\r\n\r\n public populateNeut(neutData: Partial<BestellingNeutDto>, index: number): void {\r\n let target = this.currentDorpel.neuten[index];\r\n let keys = Object.keys(neutData);\r\n keys.forEach(key => {\r\n target[key] = neutData[key];\r\n });\r\n this._neuten$.next(this.currentDorpel.neuten);\r\n }\r\n\r\n public populateLeftVoorsponning(neutIndex: number, voorsponningSize: VorsponningSize) {\r\n this.currentDorpel.neuten[neutIndex].linksVoorsponning = voorsponningSize;\r\n }\r\n\r\n public populateRightVoorsponning(neutIndex: number, voorsponningSize: VorsponningSize) {\r\n this.currentDorpel.neuten[neutIndex].rechtsVoorsponning = voorsponningSize;\r\n }\r\n\r\n public updateSluitpot(sluitpodData, index): void {\r\n this.currentDorpel.sluitpotten[index] = sluitpodData;\r\n }\r\n\r\n public setLogoUrl(url: string) {\r\n this.logoUrl = url;\r\n }\r\n\r\n public setCurrentDealersGroup(dealers: DealerDto[] | null) {\r\n this._currentDealersGroup = dealers;\r\n }\r\n\r\n public setCustomDealerResources(dealerGuid?: string) {\r\n if (dealerGuid && CUSTOM_DEALERS_RESOURCE_MAP[dealerGuid]) {\r\n this._customDealerResources = CUSTOM_DEALERS_RESOURCE_MAP[dealerGuid];\r\n } else {\r\n this._customDealerResources = null;\r\n }\r\n }\r\n}\r\n","export interface DorpelType {\r\n dorpel: string;\r\n merk: string;\r\n zaagmaat: number;\r\n aantalNeuten: number;\r\n aantalSluitpotten: number;\r\n schema: string;\r\n deurmaatA?: number;\r\n deurmaatB?: number;\r\n deurmaatC?: number;\r\n firstMaatA?: number;\r\n maatA?: number;\r\n maatB?: number;\r\n maatC?: number;\r\n maatZ?: number;\r\n opmerking?: string;\r\n aantal?: number;\r\n}\r\n\r\nconst DORPEL_CODES = {\r\n BINNEN_DORPEL: \"BI\",\r\n BUITEN_DORPEL: \"BU\",\r\n HEFSCHUIF_DORPEL: \"HS\"\r\n};\r\n\r\nexport class DorpelUtils {\r\n public static getThicknessFromDorpelCode(dorpelCode: string): number {\r\n let size = dorpelCode.split(\".\")[1];\r\n if (DorpelUtils.isSlidingDoor(dorpelCode)) {\r\n return parseInt(size);\r\n }\r\n\r\n let heightAboveDam = size.slice(0,2);\r\n let heightBelowDam = size.slice(2);\r\n return parseInt(heightAboveDam) + parseInt(heightBelowDam);\r\n }\r\n\r\n public static getDamLevelFromDorpelCode(dorpelCode: string): number {\r\n let dorpelSplitDimensions = dorpelCode.split(\".\")[1];\r\n let damLevel = dorpelSplitDimensions ? parseInt(dorpelSplitDimensions.substr(0,2)) : 0;\r\n return damLevel;\r\n }\r\n\r\n public static isSlidingDoor(dorpelCode: string): boolean {\r\n return dorpelCode.indexOf(DORPEL_CODES.HEFSCHUIF_DORPEL) !== -1\r\n }\r\n\r\n public static isBinnenDoor(dorpelCode: string): boolean {\r\n return dorpelCode.indexOf(DORPEL_CODES.BINNEN_DORPEL) !== -1\r\n }\r\n\r\n public static isBuitenDoor(dorpelCode: string): boolean {\r\n return dorpelCode.indexOf(DORPEL_CODES.BUITEN_DORPEL) !== -1\r\n }\r\n}","export enum SluitpotPosition {\r\n Dam = \"dam\",\r\n Sponning = \"sponning\",\r\n Sponning2 = \"sponningzijde\"\r\n}","import { NeutPosition } from \"../../neuten/neut/neut-position\";\r\nimport { SluitpotPosition } from \"../../sluitpot/sluitpot-position\";\r\n\r\nexport interface SluitpotModel {\r\n sluitpotCode?: string;\r\n omschrijving?: string;\r\n maat?: number;\r\n maat2?: number;\r\n isNonBlinde?: boolean;\r\n}\r\n\r\nexport class SluitpotUtils {\r\n public static isInDeDam(omschrijving: string): boolean {\r\n return omschrijving.toLowerCase().indexOf(SluitpotPosition.Dam) !== -1;\r\n }\r\n\r\n public static isInDeSponning(omschrijving: string): boolean {\r\n return omschrijving.toLowerCase().indexOf(SluitpotPosition.Sponning) !== -1\r\n || omschrijving.toLowerCase().indexOf(SluitpotPosition.Sponning2) !== -1;\r\n }\r\n\r\n public static isNonBlindeSluitpott(omschrijving: string): boolean {\r\n return omschrijving?.toLowerCase().indexOf(\"blind\") === -1;\r\n }\r\n}","import { Injectable } from \"@angular/core\";\r\nimport { UiStateService } from \"./ui-state-service\";\r\nimport { NeutUtils, VorsponningSize } from \"src/app/shared/models/neut.model\";\r\nimport { DorpelUtils } from \"src/app/shared/models/dorpel-type.model\";\r\nimport {\r\n SluitpotUtils,\r\n SluitpotModel,\r\n} from \"src/app/shared/models/sluitpot.model\";\r\nimport {\r\n NeutDto,\r\n BestellingDorpelDto,\r\n BestellingNeutDto,\r\n} from \"../../shared/api-models/models\";\r\ninterface Coordinate {\r\n x: number;\r\n y: number;\r\n}\r\n\r\ntype NeutDrawingOptions = {\r\n isBuitenDorpel: boolean,\r\n isBinnenDorpel: boolean,\r\n isSlidingDoor: boolean,\r\n leftCustomSponningmaat?: number\r\n};\r\n\r\ntype SponningmaatUpdateTargetPoints = {\r\n left: number[],\r\n right: number[]\r\n}\r\n\r\nconst DORPEL_CODES = {\r\n BINNEN_DORPEL: \"BI\",\r\n BUITEN_DORPEL: \"BU\",\r\n HEFSCHUIF_DORPEL: \"HS\",\r\n};\r\nconst VOORSPONNING_TYPES = {\r\n LEFT: \"links\",\r\n RIGHT: \"rechts\",\r\n};\r\nconst SCALE_TIP_ARROW = {\r\n WIDTH: 7,\r\n HEIGHT: 10,\r\n};\r\nconst SCALE_HEIGHT = 20;\r\nconst DORPEL_START: Coordinate = {\r\n x: 0,\r\n y: 60,\r\n};\r\nconst DEFAULT_CANVAS_HEIGHT = 260;\r\nconst HS_RAIL_WIDTH = 4;\r\nconst NEUT_COLOR = \"#f3f3f3\";\r\nconst INVALID_NEUT_COLOR = \"#eb5463\";\r\nconst SCALE_TEXT_FONT = \"13px Arial\";\r\nconst DOOR_FRAME_WIDTH = 2;\r\nconst CONTENT_OFFSET = 1;\r\nconst DOOR_ELEMENT_WIDTH = 2;\r\nconst TEXT_STROKE_WIDTH = 1;\r\nconst VOORSPONNING_HEIGHT = 17;\r\nconst WISSELNEUT_SPONNINGMAAT_COORDINATES = {\r\n W1: {right: [2, 3], left: []},\r\n W2: {right: [], left: [0, 1, 8]},\r\n W3: {right: [2, 3], left: []},\r\n W4: {right: [], left: [0, 1, 6]},\r\n W5: {right: [4, 5], left: [0, 1, 8]},\r\n};\r\n@Injectable({\r\n providedIn: \"root\",\r\n})\r\nexport class GraphicsService {\r\n constructor(private uiService: UiStateService) { }\r\n\r\n private canvasContext: CanvasRenderingContext2D = null;\r\n private canvasSize: number;\r\n private canvasSelector: string;\r\n private dorpelData: BestellingDorpelDto;\r\n\r\n public initializeDrawing(canvasId: string, size: number): void {\r\n this.canvasSize = size;\r\n this.canvasSelector = canvasId;\r\n let canvas: HTMLCanvasElement = document.getElementById(this.canvasSelector) as HTMLCanvasElement;\r\n\r\n if (canvas) {\r\n this.setCanvasSize(canvas, this.canvasSize, DEFAULT_CANVAS_HEIGHT);\r\n this.clearCanvas();\r\n }\r\n }\r\n\r\n public setCanvasContext(canvas: HTMLCanvasElement): void {\r\n let context = canvas.getContext(\"2d\");\r\n context.save();\r\n this.canvasContext = context;\r\n }\r\n\r\n private clearCanvas(): void {\r\n let ctx: CanvasRenderingContext2D = this.canvasContext;\r\n\r\n if (ctx) {\r\n ctx.clearRect(0, 0, ctx.canvas.width, 350);\r\n }\r\n }\r\n\r\n /**\r\n * DORPEL DRAWING FUNCTIONS\r\n */\r\n\r\n public drawDorpel(\r\n targetDorpelModel: BestellingDorpelDto,\r\n canvasElement?: HTMLCanvasElement\r\n ) {\r\n this.uiService.turnOffDrawingExample();\r\n this.dorpelData = targetDorpelModel;\r\n let dorpelCode = this.dorpelData.dorpelCode;\r\n let damLevel = DorpelUtils.getDamLevelFromDorpelCode(dorpelCode);\r\n let canvas: HTMLCanvasElement =\r\n canvasElement ||\r\n (document.getElementById(this.canvasSelector) as HTMLCanvasElement);\r\n\r\n if (!canvas) {\r\n return;\r\n }\r\n this.setCanvasSize(canvas, this.canvasSize, DEFAULT_CANVAS_HEIGHT);\r\n this.clearCanvas();\r\n this.setCanvasContext(canvas);\r\n\r\n this.drawFrame(dorpelCode, DORPEL_START);\r\n\r\n if (DorpelUtils.isSlidingDoor(dorpelCode)) {\r\n //is sliding door case\r\n this.drawSlidingNeut();\r\n } else {\r\n this.drawNeuten();\r\n }\r\n\r\n this.cutVerstekSurplus(DORPEL_START, this.canvasSize, dorpelCode);\r\n\r\n this.drawSluitpotten();\r\n\r\n if (!DorpelUtils.isSlidingDoor(dorpelCode)) {\r\n //no dam lines for sliding doors\r\n this.drawDamLine(DORPEL_START, damLevel + CONTENT_OFFSET);\r\n }\r\n\r\n this.canvasContext.restore();\r\n }\r\n\r\n private drawFrame(dorpelCode: string, startPoint) {\r\n let ctx: CanvasRenderingContext2D = this.canvasContext;\r\n let zaagmaat = this.dorpelData.zaagmaat;\r\n let dorpelHeight = DorpelUtils.getThicknessFromDorpelCode(dorpelCode);\r\n\r\n if (dorpelCode.indexOf(DORPEL_CODES.BINNEN_DORPEL) !== -1) {\r\n ctx.beginPath();\r\n ctx.lineWidth = DOOR_FRAME_WIDTH;\r\n ctx.rect(\r\n startPoint.x,\r\n startPoint.y /**dorpel height */,\r\n this.canvasSize,\r\n dorpelHeight + 2 * CONTENT_OFFSET\r\n );\r\n ctx.stroke();\r\n } else if (dorpelCode.indexOf(DORPEL_CODES.BUITEN_DORPEL) !== -1) {\r\n ctx.beginPath();\r\n ctx.lineWidth = DOOR_FRAME_WIDTH;\r\n ctx.rect(\r\n startPoint.x,\r\n startPoint.y,\r\n this.canvasSize,\r\n dorpelHeight + 2 * CONTENT_OFFSET\r\n );\r\n ctx.stroke();\r\n } else if (DorpelUtils.isSlidingDoor(dorpelCode)) {\r\n ctx.beginPath();\r\n ctx.lineWidth = DOOR_FRAME_WIDTH;\r\n ctx.rect(\r\n startPoint.x,\r\n startPoint.y,\r\n this.canvasSize,\r\n dorpelHeight\r\n );\r\n ctx.stroke();\r\n }\r\n\r\n ctx.lineWidth = DOOR_ELEMENT_WIDTH;\r\n this.drawScaleMeasurements(ctx, 0, this.canvasSize, 5, SCALE_HEIGHT, zaagmaat);\r\n }\r\n\r\n private cutVerstekSurplus(startPoint: any, zaagmaat: number, dorpelCode: string) {\r\n if (!this.uiService.verstekSponningOptions?.isActive) {\r\n return;\r\n }\r\n\r\n let dorpelHeight = DorpelUtils.getThicknessFromDorpelCode(dorpelCode);\r\n\r\n let leftVerstek = this.uiService.verstekSponningOptions.isLeftSide\r\n ? this.calculateVerstekLengthByAngle(dorpelHeight)\r\n : 0;\r\n let rightVerstek = this.uiService.verstekSponningOptions.isRightSide\r\n ? this.calculateVerstekLengthByAngle(dorpelHeight)\r\n : 0;\r\n let leftVerstekOrientation = this.uiService.verstekSponningOptions.leftOrientatie;\r\n let rightVerstekOrientation = this.uiService.verstekSponningOptions.rightOrientatie;\r\n\r\n let upperLeft = {\r\n x: leftVerstekOrientation === \"naarBuiten\" ? startPoint.x + leftVerstek : startPoint.x,\r\n y: startPoint.y,\r\n };\r\n let bottomLeft = {\r\n x: leftVerstekOrientation === \"naarBuiten\" ? startPoint.x : startPoint.x + leftVerstek,\r\n y: startPoint.y + dorpelHeight + 2 * CONTENT_OFFSET,\r\n };\r\n let bottomRight = {\r\n x: rightVerstekOrientation === \"naarBuiten\" ? startPoint.x + zaagmaat : startPoint.x + zaagmaat - rightVerstek,\r\n y: startPoint.y + dorpelHeight + 2 * CONTENT_OFFSET,\r\n };\r\n let upperRight = {\r\n x: rightVerstekOrientation === \"naarBuiten\" ? startPoint.x + zaagmaat - rightVerstek : startPoint.x + zaagmaat,\r\n y: startPoint.y,\r\n };\r\n\r\n let ctx: CanvasRenderingContext2D = this.canvasContext;\r\n\r\n if (leftVerstek) {\r\n ctx.globalCompositeOperation = 'destination-out';\r\n ctx.beginPath();\r\n if (leftVerstekOrientation === \"naarBuiten\") {\r\n ctx.moveTo(startPoint.x, startPoint.y - DOOR_FRAME_WIDTH);\r\n ctx.lineTo(upperLeft.x, upperLeft.y - DOOR_FRAME_WIDTH);\r\n ctx.lineTo(bottomLeft.x, bottomLeft.y + DOOR_FRAME_WIDTH);\r\n ctx.lineTo(startPoint.x, startPoint.y - DOOR_FRAME_WIDTH);\r\n } else if (leftVerstekOrientation === \"naarBinnen\") {\r\n ctx.moveTo(startPoint.x, startPoint.y - DOOR_FRAME_WIDTH);\r\n ctx.lineTo(bottomLeft.x, bottomLeft.y + DOOR_FRAME_WIDTH);\r\n ctx.lineTo(startPoint.x, bottomLeft.y + DOOR_FRAME_WIDTH);\r\n ctx.lineTo(startPoint.x, startPoint.y - DOOR_FRAME_WIDTH);\r\n }\r\n ctx.closePath();\r\n ctx.fill();\r\n\r\n ctx.globalCompositeOperation = 'source-over';\r\n ctx.beginPath();\r\n ctx.moveTo(upperLeft.x, upperLeft.y);\r\n ctx.lineTo(bottomLeft.x, bottomLeft.y);\r\n ctx.stroke();\r\n }\r\n\r\n if (rightVerstek) {\r\n ctx.globalCompositeOperation = 'destination-out';\r\n ctx.beginPath();\r\n if (rightVerstekOrientation === \"naarBuiten\") {\r\n ctx.moveTo(upperRight.x, upperRight.y - DOOR_FRAME_WIDTH);\r\n ctx.lineTo(zaagmaat, startPoint.y - DOOR_FRAME_WIDTH);\r\n ctx.lineTo(zaagmaat, bottomRight.y + DOOR_FRAME_WIDTH);\r\n ctx.lineTo(upperRight.x, upperRight.y - DOOR_FRAME_WIDTH);\r\n } else if (rightVerstekOrientation === \"naarBinnen\") {\r\n ctx.moveTo(upperRight.x, upperRight.y - DOOR_FRAME_WIDTH);\r\n ctx.lineTo(bottomRight.x, bottomRight.y + DOOR_FRAME_WIDTH);\r\n ctx.lineTo(upperRight.x, bottomRight.y + DOOR_FRAME_WIDTH);\r\n ctx.lineTo(upperRight.x, upperRight.y - DOOR_FRAME_WIDTH);\r\n }\r\n ctx.closePath();\r\n ctx.fill();\r\n\r\n ctx.globalCompositeOperation = 'source-over';\r\n ctx.beginPath();\r\n ctx.moveTo(upperRight.x, upperRight.y);\r\n ctx.lineTo(bottomRight.x, bottomRight.y);\r\n ctx.stroke();\r\n }\r\n\r\n }\r\n\r\n private drawDamLine(startPoint, damLevel) {\r\n let ctx: CanvasRenderingContext2D = this.canvasContext;\r\n\r\n ctx.beginPath();\r\n ctx.save();\r\n ctx.setLineDash([5]);\r\n ctx.lineWidth = DOOR_ELEMENT_WIDTH;\r\n ctx.moveTo(startPoint.x, startPoint.y + damLevel);\r\n ctx.lineTo(this.canvasSize, startPoint.y + damLevel);\r\n ctx.stroke();\r\n ctx.restore();\r\n }\r\n\r\n /**\r\n * NEUTEN DRAWING FUNCTIONS\r\n */\r\n\r\n private drawSlidingNeut() {\r\n let currentDorpel = this.dorpelData;\r\n let neut = currentDorpel.neuten[0];\r\n let thickness = DorpelUtils.getThicknessFromDorpelCode(\r\n currentDorpel.dorpelCode\r\n );\r\n\r\n if (!currentDorpel.schema || !neut.neutCode) {\r\n return;\r\n }\r\n\r\n let neutDto = this.uiService.getNeutDtoByCodeAndPositie(\r\n neut.neutCode,\r\n neut.positie\r\n );\r\n\r\n let neutWidth = parseInt(neutDto.neutbreedte);\r\n let neutLength = parseInt(neutDto.neutlengte);\r\n let zaagmaat = currentDorpel.zaagmaat;\r\n let deviationOptions = {\r\n klooster: {\r\n active: this.uiService.kloosterSponningOptions?.isActive,\r\n data: this.getKloosterSponningData(),\r\n isLeft: this.uiService.kloosterSponningOptions.isLeftSide,\r\n isRight: this.uiService.kloosterSponningOptions.isRightSide,\r\n },\r\n renovatie: {\r\n active: this.uiService.renovatieSponningOptions?.isActive,\r\n data: this.getRenovatieSponningData(),\r\n isLeft: this.uiService.renovatieSponningOptions.isLeftSide,\r\n isRight: this.uiService.renovatieSponningOptions.isRightSide,\r\n },\r\n };\r\n\r\n switch (currentDorpel.schema) {\r\n case \"AL\":\r\n this.drawALSchema(\r\n neutWidth,\r\n neutLength,\r\n zaagmaat,\r\n thickness,\r\n deviationOptions\r\n );\r\n break;\r\n case \"AR\":\r\n this.drawARSchema(\r\n neutWidth,\r\n neutLength,\r\n zaagmaat,\r\n thickness,\r\n deviationOptions\r\n );\r\n break;\r\n case \"C+G\":\r\n this.drawCGSchema(\r\n neutWidth,\r\n neutLength,\r\n thickness,\r\n deviationOptions\r\n );\r\n break;\r\n case \"D\":\r\n this.drawDSchema(\r\n neutWidth,\r\n neutLength,\r\n thickness,\r\n deviationOptions\r\n );\r\n break;\r\n }\r\n }\r\n\r\n private getScalableElementRatioForALARSchemas(deurmaatA: number, neutWidth: number, maatA: number, maatZ: number, dorpelHeight: number): number {\r\n let trueScaleMeasurements = neutWidth;\r\n let scaledMeasurements = deurmaatA;\r\n\r\n if (maatA) {\r\n if (maatA >= dorpelHeight) {\r\n trueScaleMeasurements += dorpelHeight;\r\n scaledMeasurements += maatA - dorpelHeight\r\n } else {\r\n trueScaleMeasurements += maatA;\r\n }\r\n }\r\n\r\n if (maatZ) {\r\n if (maatZ >= dorpelHeight) {\r\n trueScaleMeasurements += dorpelHeight;\r\n scaledMeasurements += maatZ - dorpelHeight\r\n } else {\r\n trueScaleMeasurements += maatZ;\r\n }\r\n }\r\n\r\n let ratio = (this.canvasSize - trueScaleMeasurements) / scaledMeasurements;\r\n return parseFloat(ratio.toFixed(3));\r\n }\r\n\r\n private drawALSchema(\r\n neutWidth: number,\r\n neutLength: number,\r\n zaagmaat: number,\r\n thickness: number,\r\n deviationOptions: any\r\n ) {\r\n let ctx = this.canvasContext;\r\n let { maatA, deurmaatA, maatZ, dorpelCode } = this.dorpelData;\r\n let { a1, a2, b, c, baseline } = this.getSlidingNeutValues(\r\n thickness,\r\n neutLength,\r\n dorpelCode\r\n );\r\n let dorpelHeight = DorpelUtils.getThicknessFromDorpelCode(dorpelCode);\r\n\r\n let hasLeftRenovatieSponning =\r\n deviationOptions.renovatie.active && deviationOptions.renovatie.isLeft;\r\n let hasRightRenovatieSponning =\r\n deviationOptions.renovatie.active && deviationOptions.renovatie.isRight;\r\n let hasLeftKloosterSponning =\r\n deviationOptions.klooster.active && deviationOptions.klooster.isLeft;\r\n let hasRightKloosterSponning =\r\n deviationOptions.klooster.active && deviationOptions.klooster.isRight;\r\n let renovatieSponningData = deviationOptions.renovatie.data;\r\n let kloosterSponningData = deviationOptions.klooster.data;\r\n\r\n maatA = maatA || 0;\r\n maatZ = maatZ || 0;\r\n\r\n //SCALING LOGIC\r\n let maxDeurmaatWidth = zaagmaat - maatA - maatZ - neutWidth;\r\n let minDeurmaatWidth = 2 * neutWidth;\r\n let scalableElementRatio = this.getScalableElementRatioForALARSchemas(maxDeurmaatWidth, neutWidth, maatA, maatZ, dorpelHeight);\r\n let scaledMA = Math.min(maatA, dorpelHeight) + Math.max(maatA - dorpelHeight, 0) * scalableElementRatio;\r\n let scaledMZ = Math.min(maatZ, dorpelHeight) + Math.max(maatZ - dorpelHeight, 0) * scalableElementRatio;\r\n let maxSpaceForDeurmaat = this.canvasSize - scaledMA - scaledMZ - neutWidth;\r\n let deurmaatRatio = maxSpaceForDeurmaat / maxDeurmaatWidth;\r\n let deurmaatValue = Math.max(minDeurmaatWidth, deurmaatA * deurmaatRatio);\r\n //END: SCALING LOGIC\r\n\r\n let p2 = scaledMA;\r\n let p3 = scaledMA + neutWidth;\r\n\r\n let p4 = this.canvasSize - scaledMZ - deurmaatValue;\r\n // let p5 = this.canvasSize - scaledMZ - deurmaatValue + neutWidth;\r\n\r\n let p6 = this.canvasSize - scaledMZ - neutWidth;\r\n let p7 = this.canvasSize - scaledMZ;\r\n\r\n ctx.beginPath();\r\n\r\n //Linkerneut tekenen\r\n ctx.moveTo(\r\n p2 +\r\n (hasLeftRenovatieSponning ? renovatieSponningData.renovatieDepthLeft : 0),\r\n baseline\r\n );\r\n ctx.lineTo(p3, baseline);\r\n ctx.lineTo(p3, baseline + a1);\r\n ctx.lineTo(p3 - b, baseline + a1);\r\n ctx.lineTo(p3 - b, baseline + a1 + c);\r\n ctx.lineTo(p3, baseline + a1 + c);\r\n ctx.lineTo(p3, baseline + neutLength);\r\n ctx.lineTo(p2, baseline + neutLength);\r\n\r\n if (hasLeftRenovatieSponning) {\r\n ctx.lineTo(p2, baseline + renovatieSponningData.renovatieLengthLeft);\r\n ctx.lineTo(\r\n p2 +\r\n (hasLeftRenovatieSponning ? renovatieSponningData.renovatieDepthLeft : 0),\r\n baseline + renovatieSponningData.renovatieLengthLeft\r\n );\r\n } else if (hasLeftKloosterSponning) {\r\n ctx.lineTo(\r\n p2,\r\n baseline + kloosterSponningData.kloosterOffsetLeft\r\n );\r\n ctx.lineTo(\r\n p2 + kloosterSponningData.kloosterDepthLeft,\r\n baseline + kloosterSponningData.kloosterOffsetLeft\r\n );\r\n ctx.lineTo(\r\n p2 + kloosterSponningData.kloosterDepthLeft,\r\n baseline + kloosterSponningData.kloosterOffsetLeft + kloosterSponningData.kloosterLengthLeft\r\n );\r\n ctx.lineTo(\r\n p2,\r\n baseline + kloosterSponningData.kloosterOffsetLeft + kloosterSponningData.kloosterLengthLeft\r\n );\r\n }\r\n ctx.lineTo(\r\n p2 +\r\n (hasLeftRenovatieSponning ? renovatieSponningData.renovatieDepthLeft : 0),\r\n baseline\r\n );\r\n\r\n //Middenneut tekenen\r\n // ctx.moveTo(p4, baseline + a1 + c);\r\n // // ctx.lineTo(p5, baseline + a1 + c);\r\n // ctx.lineTo(p5, baseline + neutLength);\r\n // ctx.lineTo(p4, baseline + neutLength);\r\n // ctx.lineTo(p4, baseline + a1 + c);\r\n\r\n //Rechterneut tekenen\r\n ctx.moveTo(p6, baseline);\r\n\r\n if (hasRightRenovatieSponning) {\r\n //with renovatie\r\n ctx.lineTo(p7 - renovatieSponningData.renovatieDepthRight, baseline);\r\n ctx.lineTo(\r\n p7 - renovatieSponningData.renovatieDepthRight,\r\n baseline + renovatieSponningData.renovatieLengthRight\r\n );\r\n ctx.lineTo(p7, baseline + renovatieSponningData.renovatieLengthRight);\r\n } else if (hasRightKloosterSponning) {\r\n //with klooster\r\n ctx.lineTo(p7, baseline);\r\n ctx.lineTo(\r\n p7,\r\n baseline + kloosterSponningData.kloosterOffsetRight\r\n );\r\n ctx.lineTo(\r\n p7 - kloosterSponningData.kloosterDepthRight,\r\n baseline + kloosterSponningData.kloosterOffsetRight\r\n );\r\n ctx.lineTo(\r\n p7 - kloosterSponningData.kloosterDepthRight,\r\n baseline + kloosterSponningData.kloosterOffsetRight +\r\n kloosterSponningData.kloosterLengthRight\r\n );\r\n ctx.lineTo(\r\n p7,\r\n baseline + kloosterSponningData.kloosterOffsetRight +\r\n kloosterSponningData.kloosterLengthRight\r\n );\r\n } else {\r\n //regular\r\n ctx.lineTo(p7, baseline);\r\n }\r\n\r\n ctx.lineTo(p7, baseline + neutLength);\r\n ctx.lineTo(p6, baseline + neutLength);\r\n ctx.lineTo(p6, baseline + neutLength - a2);\r\n ctx.lineTo(p6 + b, baseline + neutLength - a2);\r\n ctx.lineTo(p6 + b, baseline + neutLength - a2 - c);\r\n ctx.lineTo(p6, baseline + neutLength - a2 - c);\r\n ctx.lineTo(p6, baseline);\r\n\r\n //schuifdeur tekenen\r\n ctx.moveTo(p3 - b, baseline + a1);\r\n ctx.lineTo(p6, baseline + a1);\r\n ctx.lineTo(p6, baseline + a1 + c);\r\n ctx.lineTo(p3 - b, baseline + a1 + c);\r\n ctx.lineTo(p3 - b, baseline + a1);\r\n\r\n //rail\r\n let topLineY = baseline + a1 + c / 2 - HS_RAIL_WIDTH / 2;\r\n let bottomLineY = topLineY + HS_RAIL_WIDTH;\r\n ctx.moveTo(p3 - b, topLineY);\r\n ctx.lineTo(p6, topLineY);\r\n ctx.moveTo(p3 - b, bottomLineY);\r\n ctx.lineTo(p6, bottomLineY);\r\n\r\n //vaste deur tekenen\r\n ctx.moveTo(p4, baseline + neutLength - a2);\r\n ctx.lineTo(p6 + b, baseline + neutLength - a2);\r\n ctx.lineTo(p6 + b, baseline + neutLength - a2 - c);\r\n ctx.lineTo(p4, baseline + neutLength - a2 - c);\r\n ctx.lineTo(p4, baseline + neutLength - a2);\r\n ctx.stroke();\r\n\r\n if (maatA) {\r\n this.drawScaleMeasurements(\r\n ctx,\r\n 0,\r\n scaledMA,\r\n 30,\r\n SCALE_HEIGHT,\r\n maatA\r\n );\r\n }\r\n\r\n this.drawScaleMeasurements(\r\n ctx,\r\n scaledMA,\r\n scaledMA + neutWidth,\r\n 30,\r\n SCALE_HEIGHT,\r\n neutWidth\r\n );\r\n\r\n this.drawScaleMeasurements(\r\n ctx,\r\n this.canvasSize - scaledMZ - deurmaatValue,\r\n this.canvasSize - scaledMZ,\r\n 30,\r\n SCALE_HEIGHT,\r\n deurmaatA\r\n );\r\n\r\n if (maatZ) {\r\n this.drawScaleMeasurements(\r\n ctx,\r\n this.canvasSize - scaledMZ,\r\n this.canvasSize,\r\n 30,\r\n SCALE_HEIGHT,\r\n maatZ\r\n );\r\n }\r\n }\r\n\r\n private drawARSchema(\r\n neutWidth: number,\r\n neutLength: number,\r\n zaagmaat: number,\r\n thickness: number,\r\n deviationOptions: any\r\n ) {\r\n let ctx = this.canvasContext;\r\n let { maatA, deurmaatA, maatZ, dorpelCode } = this.dorpelData;\r\n let { a1, a2, b, c, baseline } = this.getSlidingNeutValues(\r\n thickness,\r\n neutLength,\r\n dorpelCode\r\n );\r\n let dorpelHeight = DorpelUtils.getThicknessFromDorpelCode(dorpelCode)\r\n\r\n let hasLeftRenovatieSponning =\r\n deviationOptions.renovatie.active && deviationOptions.renovatie.isLeft;\r\n let hasRightRenovatieSponning =\r\n deviationOptions.renovatie.active && deviationOptions.renovatie.isRight;\r\n let hasLeftKloosterSponning =\r\n deviationOptions.klooster.active && deviationOptions.klooster.isLeft;\r\n let hasRightKloosterSponning =\r\n deviationOptions.klooster.active && deviationOptions.klooster.isRight;\r\n let renovatieSponningData = deviationOptions.renovatie.data;\r\n let kloosterSponningData = deviationOptions.klooster.data;\r\n\r\n maatA = maatA || 0;\r\n maatZ = maatZ || 0;\r\n\r\n //SCALING LOGIC\r\n let maxDeurmaatWidth = zaagmaat - maatA - maatZ - neutWidth;\r\n let minDeurmaatWidth = 2 * neutWidth;\r\n let scalableElementRatio = this.getScalableElementRatioForALARSchemas(maxDeurmaatWidth, neutWidth, maatA, maatZ, dorpelHeight);\r\n let scaledMA = Math.min(maatA, dorpelHeight) + Math.max(maatA - dorpelHeight, 0) * scalableElementRatio;\r\n let scaledMZ = Math.min(maatZ, dorpelHeight) + Math.max(maatZ - dorpelHeight, 0) * scalableElementRatio;\r\n let maxSpaceForDeurmaat = this.canvasSize - scaledMA - scaledMZ - neutWidth;\r\n let deurmaatRatio = maxSpaceForDeurmaat / maxDeurmaatWidth;\r\n let deurmaatValue = Math.max(minDeurmaatWidth, deurmaatA * deurmaatRatio);\r\n //END: SCALING LOGIC\r\n\r\n let p2 = scaledMA;\r\n let p3 = scaledMA + neutWidth;\r\n // let p4 = scaledMA + deurmaatValue - neutWidth;\r\n let p5 = scaledMA + deurmaatValue;\r\n let p6 = this.canvasSize - scaledMZ - neutWidth;\r\n let p7 = this.canvasSize - scaledMZ;\r\n\r\n ctx.beginPath();\r\n\r\n //Linkerneut tekenen\r\n ctx.moveTo(\r\n p2 +\r\n (hasLeftRenovatieSponning ? renovatieSponningData.renovatieDepthLeft : 0),\r\n baseline\r\n );\r\n ctx.lineTo(p3, baseline);\r\n ctx.lineTo(p3, baseline + neutLength - a2 - c);\r\n ctx.lineTo(p3 - b, baseline + neutLength - a2 - c);\r\n ctx.lineTo(p3 - b, baseline + neutLength - a2);\r\n ctx.lineTo(p3, baseline + neutLength - a2);\r\n ctx.lineTo(p3, baseline + neutLength);\r\n ctx.lineTo(p2, baseline + neutLength);\r\n\r\n if (hasLeftRenovatieSponning) {\r\n ctx.lineTo(p2, baseline + renovatieSponningData.renovatieLengthLeft);\r\n ctx.lineTo(\r\n p2 +\r\n (hasLeftRenovatieSponning ? renovatieSponningData.renovatieDepthLeft : 0),\r\n baseline + renovatieSponningData.renovatieLengthLeft\r\n );\r\n } else if (hasLeftKloosterSponning) {\r\n ctx.lineTo(\r\n p2,\r\n baseline + kloosterSponningData.kloosterOffsetLeft\r\n );\r\n ctx.lineTo(\r\n p2 + kloosterSponningData.kloosterDepthLeft,\r\n baseline + kloosterSponningData.kloosterOffsetLeft\r\n );\r\n ctx.lineTo(\r\n p2 + kloosterSponningData.kloosterDepthLeft,\r\n baseline + kloosterSponningData.kloosterOffsetLeft + kloosterSponningData.kloosterLengthLeft\r\n );\r\n ctx.lineTo(\r\n p2,\r\n baseline + kloosterSponningData.kloosterOffsetLeft + kloosterSponningData.kloosterLengthLeft\r\n );\r\n }\r\n\r\n ctx.lineTo(\r\n p2 +\r\n (hasLeftRenovatieSponning ? renovatieSponningData.renovatieDepthLeft : 0),\r\n baseline\r\n );\r\n\r\n // //Middenneut tekenen\r\n // ctx.moveTo(p4, baseline + a1 + c); // ask jacob what value should be inserted in place of 66\r\n // ctx.lineTo(p5, baseline + a1 + c);\r\n // ctx.lineTo(p5, baseline + neutLength);\r\n // ctx.lineTo(p4, baseline + neutLength);\r\n // ctx.lineTo(p4, baseline + a1 + c);\r\n\r\n //Rechterneut tekenen\r\n ctx.moveTo(p6, baseline);\r\n ctx.lineTo(p6, baseline + a1);\r\n ctx.lineTo(p6 + b, baseline + a1);\r\n ctx.lineTo(p6 + b, baseline + a1 + c);\r\n ctx.lineTo(p6, baseline + a1 + c);\r\n ctx.lineTo(p6, baseline + neutLength);\r\n ctx.lineTo(p7, baseline + neutLength);\r\n\r\n if (hasRightRenovatieSponning) {\r\n //with renovatie\r\n ctx.lineTo(p7, baseline + renovatieSponningData.renovatieLengthRight);\r\n ctx.lineTo(\r\n p7 - renovatieSponningData.renovatieDepthRight,\r\n baseline + renovatieSponningData.renovatieLengthRight\r\n );\r\n ctx.lineTo(p7 - renovatieSponningData.renovatieDepthRight, baseline);\r\n } else if (hasRightKloosterSponning) {\r\n //with klooster\r\n ctx.lineTo(\r\n p7,\r\n baseline + kloosterSponningData.kloosterOffsetRight +\r\n kloosterSponningData.kloosterLengthRight\r\n );\r\n ctx.lineTo(\r\n p7 - kloosterSponningData.kloosterDepthRight,\r\n baseline + kloosterSponningData.kloosterOffsetRight +\r\n kloosterSponningData.kloosterLengthRight\r\n );\r\n ctx.lineTo(\r\n p7 - kloosterSponningData.kloosterDepthRight,\r\n baseline + kloosterSponningData.kloosterOffsetRight\r\n );\r\n ctx.lineTo(\r\n p7,\r\n baseline + kloosterSponningData.kloosterOffsetRight\r\n );\r\n ctx.lineTo(p7, baseline);\r\n } else {\r\n //regular\r\n ctx.lineTo(p7, baseline);\r\n }\r\n ctx.lineTo(p6, baseline);\r\n\r\n // hefschuifdeur\r\n ctx.moveTo(p3, baseline + a1);\r\n ctx.lineTo(p6 + b, baseline + a1);\r\n ctx.lineTo(p6 + b, baseline + a1 + c);\r\n ctx.lineTo(p3, baseline + a1 + c);\r\n ctx.lineTo(p3, baseline + a1);\r\n\r\n //rail\r\n let topLineY = baseline + a1 + c / 2 - HS_RAIL_WIDTH / 2;\r\n let bottomLineY = topLineY + HS_RAIL_WIDTH;\r\n ctx.moveTo(p3, topLineY);\r\n ctx.lineTo(p6 + b, topLineY);\r\n ctx.moveTo(p3, bottomLineY);\r\n ctx.lineTo(p6 + b, bottomLineY);\r\n\r\n // vaste deurmaat\r\n ctx.moveTo(p3 - b, baseline + neutLength - a2);\r\n ctx.lineTo(p5, baseline + neutLength - a2);\r\n ctx.lineTo(p5, baseline + neutLength - a2 - c);\r\n ctx.lineTo(p3 - b, baseline + neutLength - a2 - c);\r\n ctx.lineTo(p3 - b, baseline + neutLength - a2);\r\n ctx.stroke();\r\n\r\n if (maatA) {\r\n this.drawScaleMeasurements(ctx, 0, scaledMA, 30, SCALE_HEIGHT, maatA);\r\n }\r\n\r\n this.drawScaleMeasurements(ctx, scaledMA, scaledMA + deurmaatValue, 30, SCALE_HEIGHT, deurmaatA);\r\n this.drawScaleMeasurements(ctx, this.canvasSize - scaledMZ - neutWidth, this.canvasSize - scaledMZ, 30, SCALE_HEIGHT, neutWidth);\r\n\r\n if (maatZ) {\r\n this.drawScaleMeasurements(ctx, this.canvasSize - scaledMZ, this.canvasSize, 30, SCALE_HEIGHT, maatZ);\r\n }\r\n }\r\n\r\n private getScalableElementRatioForCGSchemas(maatA: number, deurmaatA: number, maatB: number, deurmaatC: number, maatZ: number, dorpelHeight: number): number {\r\n let trueScaleMeasurements = 0;\r\n let scaledMeasurements = deurmaatA + maatB + deurmaatC;\r\n\r\n if (maatA) {\r\n if (maatA >= dorpelHeight) {\r\n trueScaleMeasurements += dorpelHeight;\r\n scaledMeasurements += maatA - dorpelHeight\r\n } else {\r\n trueScaleMeasurements += maatA;\r\n }\r\n }\r\n\r\n if (maatZ) {\r\n if (maatZ >= dorpelHeight) {\r\n trueScaleMeasurements += dorpelHeight;\r\n scaledMeasurements += maatZ - dorpelHeight\r\n } else {\r\n trueScaleMeasurements += maatZ;\r\n }\r\n }\r\n\r\n let ratio = (this.canvasSize - trueScaleMeasurements) / scaledMeasurements;\r\n return parseFloat(ratio.toFixed(3));\r\n }\r\n\r\n private drawCGSchema(\r\n neutWidth: number,\r\n neutLength: number,\r\n thickness: number,\r\n deviationOptions: any\r\n ) {\r\n let ctx = this.canvasContext;\r\n let { maatA, deurmaatA, maatB, deurmaatC, maatZ, dorpelCode } = this.dorpelData;\r\n let { a2, b, c, baseline } = this.getSlidingNeutValues(\r\n thickness,\r\n neutLength,\r\n dorpelCode\r\n );\r\n let dorpelHeight = DorpelUtils.getThicknessFromDorpelCode(dorpelCode);\r\n\r\n let hasLeftRenovatieSponning =\r\n deviationOptions.renovatie.active && deviationOptions.renovatie.isLeft;\r\n let hasRightRenovatieSponning =\r\n deviationOptions.renovatie.active && deviationOptions.renovatie.isRight;\r\n let hasLeftKloosterSponning =\r\n deviationOptions.klooster.active && deviationOptions.klooster.isLeft;\r\n let hasRightKloosterSponning =\r\n deviationOptions.klooster.active && deviationOptions.klooster.isRight;\r\n let renovatieSponningData = deviationOptions.renovatie.data;\r\n let kloosterSponningData = deviationOptions.klooster.data;\r\n\r\n maatA = maatA || 0;\r\n maatZ = maatZ || 0;\r\n maatB = maatB || 0;\r\n\r\n let minDeurmaat = 2 * neutWidth;\r\n let ratio = this.getScalableElementRatioForCGSchemas(maatA, deurmaatA, maatB, deurmaatC, maatZ, dorpelHeight);\r\n let scaledMA = Math.min(maatA, dorpelHeight) + Math.max(maatA - dorpelHeight, 0) * ratio;\r\n let scaledMZ = Math.min(maatZ, dorpelHeight) + Math.max(maatZ - dorpelHeight, 0) * ratio;\r\n\r\n let deurmaatAVal = Math.max(minDeurmaat, deurmaatA * ratio);\r\n let deurmaatCVal = Math.max(minDeurmaat, deurmaatC * ratio);\r\n let maxMaatB = this.canvasSize - scaledMA - scaledMZ - (4 * neutWidth);\r\n let maatBVal = Math.min(maatB * ratio, maxMaatB);\r\n\r\n let p2 = scaledMA;\r\n let p3 = scaledMA + neutWidth;\r\n // let p4 = scaledMA + deurmaatAVal - neutWidth;\r\n let p5 = scaledMA + deurmaatAVal;\r\n let p6 = scaledMA + deurmaatAVal + maatBVal;\r\n // let p7 = scaledMA + deurmaatAVal + maatBVal + neutWidth;\r\n let p8 = scaledMA + deurmaatAVal + maatBVal + deurmaatCVal - neutWidth;\r\n let p9 = scaledMA + deurmaatAVal + maatBVal + deurmaatCVal;\r\n\r\n ctx.beginPath();\r\n\r\n //Linkerneut tekenen\r\n ctx.moveTo(\r\n p2 +\r\n (hasLeftRenovatieSponning ? renovatieSponningData.renovatieDepthLeft : 0),\r\n baseline\r\n );\r\n ctx.lineTo(p3, baseline);\r\n ctx.lineTo(p3, baseline + neutLength - a2 - c);\r\n ctx.lineTo(p3 - b, baseline + neutLength - a2 - c);\r\n ctx.lineTo(p3 - b, baseline + neutLength - a2);\r\n ctx.lineTo(p3, baseline + neutLength - a2);\r\n ctx.lineTo(p3, baseline + neutLength);\r\n ctx.lineTo(p2, baseline + neutLength);\r\n\r\n if (hasLeftRenovatieSponning) {\r\n ctx.lineTo(p2, baseline + renovatieSponningData.renovatieLengthLeft);\r\n ctx.lineTo(\r\n p2 +\r\n (hasLeftRenovatieSponning ? renovatieSponningData.renovatieDepthLeft : 0),\r\n baseline + renovatieSponningData.renovatieLengthLeft\r\n );\r\n } else if (hasLeftKloosterSponning) {\r\n ctx.lineTo(\r\n p2,\r\n baseline + kloosterSponningData.kloosterOffsetLeft\r\n );\r\n ctx.lineTo(\r\n p2 + kloosterSponningData.kloosterDepthLeft,\r\n baseline + kloosterSponningData.kloosterOffsetLeft\r\n );\r\n ctx.lineTo(\r\n p2 + kloosterSponningData.kloosterDepthLeft,\r\n baseline + kloosterSponningData.kloosterOffsetLeft + kloosterSponningData.kloosterLengthLeft\r\n );\r\n ctx.lineTo(\r\n p2,\r\n baseline + kloosterSponningData.kloosterOffsetLeft + kloosterSponningData.kloosterLengthLeft\r\n );\r\n }\r\n\r\n ctx.lineTo(\r\n p2 +\r\n (hasLeftRenovatieSponning ? renovatieSponningData.renovatieDepthLeft : 0),\r\n baseline\r\n );\r\n\r\n //Middenneut 1 tekenen\r\n // ctx.moveTo(p4, baseline + a2 + c);\r\n // ctx.lineTo(p5, baseline + a2 + c);\r\n // ctx.lineTo(p5, baseline + neutLength);\r\n // ctx.lineTo(p4, baseline + neutLength);\r\n // ctx.lineTo(p4, baseline + a2 + c);\r\n\r\n // //Middenneut 2 tekenen\r\n // ctx.moveTo(p6, baseline + a2 + c);\r\n // ctx.lineTo(p7, baseline + a2 + c);\r\n // ctx.lineTo(p7, baseline + neutLength);\r\n // ctx.lineTo(p6, baseline + neutLength);\r\n // ctx.lineTo(p6, baseline + a2 + c);\r\n\r\n //Rechterneut tekenen\r\n ctx.moveTo(p8, baseline);\r\n\r\n if (hasRightRenovatieSponning) {\r\n //with renovatie\r\n ctx.lineTo(p9 - renovatieSponningData.renovatieDepthRight, baseline);\r\n ctx.lineTo(\r\n p9 - renovatieSponningData.renovatieDepthRight,\r\n baseline + renovatieSponningData.renovatieLengthRight\r\n );\r\n ctx.lineTo(p9, baseline + renovatieSponningData.renovatieLengthRight);\r\n } else if (hasRightKloosterSponning) {\r\n //with klooster\r\n ctx.lineTo(p9, baseline);\r\n ctx.lineTo(\r\n p9,\r\n baseline + kloosterSponningData.kloosterOffsetRight\r\n );\r\n ctx.lineTo(\r\n p9 - kloosterSponningData.kloosterDepthRight,\r\n baseline + kloosterSponningData.kloosterOffsetRight\r\n );\r\n ctx.lineTo(\r\n p9 - kloosterSponningData.kloosterDepthRight,\r\n baseline + kloosterSponningData.kloosterOffsetRight +\r\n kloosterSponningData.kloosterLengthRight\r\n );\r\n ctx.lineTo(\r\n p9,\r\n baseline + kloosterSponningData.kloosterOffsetRight +\r\n kloosterSponningData.kloosterLengthRight\r\n );\r\n } else {\r\n //regular\r\n ctx.lineTo(p9, baseline);\r\n }\r\n\r\n ctx.lineTo(p9, baseline + neutLength);\r\n ctx.lineTo(p8, baseline + neutLength);\r\n ctx.lineTo(p8, baseline + neutLength - a2);\r\n ctx.lineTo(p8 + b, baseline + neutLength - a2);\r\n ctx.lineTo(p8 + b, baseline + neutLength - a2 - c);\r\n ctx.lineTo(p8, baseline + neutLength - a2 - c);\r\n ctx.lineTo(p8, baseline);\r\n\r\n // hefschuifdeur\r\n ctx.moveTo(p3, baseline + a2);\r\n ctx.lineTo(p8, baseline + a2);\r\n ctx.lineTo(p8, baseline + a2 + c);\r\n ctx.lineTo(p3, baseline + a2 + c);\r\n ctx.lineTo(p3, baseline + a2);\r\n\r\n //rail\r\n let topLineY = baseline + a2 + c / 2 - HS_RAIL_WIDTH / 2;\r\n let bottomLineY = topLineY + HS_RAIL_WIDTH;\r\n ctx.moveTo(p3, topLineY);\r\n ctx.lineTo(p8, topLineY);\r\n ctx.moveTo(p3, bottomLineY);\r\n ctx.lineTo(p8, bottomLineY);\r\n\r\n // vaste deurmaat a\r\n ctx.moveTo(p3 - b, baseline + neutLength - a2);\r\n ctx.lineTo(p5, baseline + neutLength - a2);\r\n ctx.lineTo(p5, baseline + neutLength - a2 - c);\r\n ctx.lineTo(p3 - b, baseline + neutLength - a2 - c);\r\n ctx.lineTo(p3 - b, baseline + neutLength - a2);\r\n ctx.stroke();\r\n\r\n // vaste deurmaat c\r\n ctx.moveTo(p6, baseline + neutLength - a2 - c);\r\n ctx.lineTo(p8 + b, baseline + neutLength - a2 - c);\r\n ctx.lineTo(p8 + b, baseline + neutLength - a2);\r\n ctx.lineTo(p6, baseline + neutLength - a2);\r\n ctx.lineTo(p6, baseline + neutLength - a2 - c);\r\n ctx.stroke();\r\n\r\n if (maatA) {\r\n this.drawScaleMeasurements(ctx, 0, scaledMA, 30, SCALE_HEIGHT, maatA);\r\n }\r\n this.drawScaleMeasurements(ctx, scaledMA, scaledMA + deurmaatAVal, 30, SCALE_HEIGHT, deurmaatA);\r\n this.drawScaleMeasurements(\r\n ctx,\r\n scaledMA + deurmaatAVal,\r\n scaledMA + deurmaatAVal + maatBVal,\r\n 30,\r\n SCALE_HEIGHT,\r\n maatB,\r\n true\r\n );\r\n this.drawScaleMeasurements(\r\n ctx,\r\n scaledMA + deurmaatAVal + maatBVal,\r\n scaledMA + deurmaatAVal + maatBVal + deurmaatCVal,\r\n 30,\r\n SCALE_HEIGHT,\r\n deurmaatC\r\n );\r\n\r\n if (maatZ) {\r\n this.drawScaleMeasurements(ctx, this.canvasSize - scaledMZ, this.canvasSize, 30, SCALE_HEIGHT, maatZ);\r\n }\r\n }\r\n\r\n private getScalableElementRatioForDSchemas(maatA: number, firstMaatA: number, deurmaatB: number, maatC: number, maatZ: number, neutWidth: number, dorpelHeight: number): number {\r\n let totalVariableElementsLength = deurmaatB;\r\n let totalFixedElementsLength = 0;\r\n if (firstMaatA === neutWidth) {\r\n totalFixedElementsLength += firstMaatA\r\n } else {\r\n totalVariableElementsLength += firstMaatA\r\n }\r\n\r\n if (maatC === neutWidth) {\r\n totalFixedElementsLength += maatC\r\n } else {\r\n totalVariableElementsLength += maatC;\r\n }\r\n\r\n if (maatA) {\r\n if (maatA >= dorpelHeight) {\r\n totalFixedElementsLength += dorpelHeight;\r\n totalVariableElementsLength += maatA - dorpelHeight\r\n } else {\r\n totalFixedElementsLength += maatA;\r\n }\r\n }\r\n\r\n if (maatZ) {\r\n if (maatZ >= dorpelHeight) {\r\n totalFixedElementsLength += dorpelHeight;\r\n totalVariableElementsLength += maatZ - dorpelHeight\r\n } else {\r\n totalFixedElementsLength += maatZ;\r\n }\r\n }\r\n\r\n let ratio = (this.canvasSize - totalFixedElementsLength) / totalVariableElementsLength;\r\n return parseFloat(ratio.toFixed(3));\r\n }\r\n\r\n private drawDSchema(\r\n neutWidth: number,\r\n neutLength: number,\r\n thickness: number,\r\n deviationOptions: any\r\n ) {\r\n let ctx = this.canvasContext;\r\n let { maatA, firstMaatA, deurmaatB, maatC, maatZ, dorpelCode } = this.dorpelData;\r\n let { a1, a2, b, c, baseline } = this.getSlidingNeutValues(\r\n thickness,\r\n neutLength,\r\n dorpelCode\r\n );\r\n let dorpelHeight = DorpelUtils.getThicknessFromDorpelCode(dorpelCode);\r\n\r\n let hasLeftRenovatieSponning =\r\n deviationOptions.renovatie.active && deviationOptions.renovatie.isLeft;\r\n let hasRightRenovatieSponning =\r\n deviationOptions.renovatie.active && deviationOptions.renovatie.isRight;\r\n let hasLeftKloosterSponning =\r\n deviationOptions.klooster.active && deviationOptions.klooster.isLeft;\r\n let hasRightKloosterSponning =\r\n deviationOptions.klooster.active && deviationOptions.klooster.isRight;\r\n let renovatieSponningData = deviationOptions.renovatie.data;\r\n let kloosterSponningData = deviationOptions.klooster.data;\r\n\r\n maatA = maatA || 0;\r\n maatZ = maatZ || 0;\r\n\r\n let ratio = this.getScalableElementRatioForDSchemas(maatA, firstMaatA, deurmaatB, maatC, maatZ, neutWidth, dorpelHeight);\r\n let scaledMA = Math.min(maatA, dorpelHeight) + Math.max(maatA - dorpelHeight, 0) * ratio;\r\n let scaledMZ = Math.min(maatZ, dorpelHeight) + Math.max(maatZ - dorpelHeight, 0) * ratio;\r\n\r\n //if maat equals the neut witdth (which we draw real scale), we also skip applying the ratio and draw the maat real scale too\r\n let firstMaatAVal = Math.max(firstMaatA === neutWidth ? firstMaatA : firstMaatA * ratio, neutWidth);\r\n let maatCVal = Math.max(maatC === neutWidth ? maatC : maatC * ratio, neutWidth);\r\n\r\n let maxDeurmaatB = this.canvasSize - scaledMA - scaledMZ - firstMaatAVal - maatCVal;\r\n let minDeurmaatB = 2 * neutWidth;\r\n\r\n let deurmaatBVal = Math.min(maxDeurmaatB, Math.max(minDeurmaatB, deurmaatB * ratio))\r\n\r\n\r\n var p2 = scaledMA;\r\n var p3 = scaledMA + neutWidth;\r\n var p4 = scaledMA + firstMaatAVal;\r\n // var p5 = scaledMA + firstMaatAVal + neutWidth;\r\n // var p6 = scaledMA + firstMaatAVal + deurmaatBVal - neutWidth;\r\n var p7 = scaledMA + firstMaatAVal + deurmaatBVal;\r\n var p8 = scaledMA + firstMaatAVal + deurmaatBVal + maatCVal - neutWidth;\r\n var p9 = scaledMA + firstMaatAVal + deurmaatBVal + maatCVal;\r\n\r\n ctx.beginPath();\r\n\r\n // Linkerneut tekenen\r\n ctx.moveTo(\r\n p2 +\r\n (hasLeftRenovatieSponning ? renovatieSponningData.renovatieDepthLeft : 0),\r\n baseline\r\n );\r\n ctx.lineTo(p3, baseline);\r\n ctx.lineTo(p3, baseline + a1);\r\n ctx.lineTo(p3 - b, baseline + a1);\r\n ctx.lineTo(p3 - b, baseline + a1 + c);\r\n ctx.lineTo(p3, baseline + a1 + c);\r\n ctx.lineTo(p3, baseline + neutLength);\r\n ctx.lineTo(p2, baseline + neutLength);\r\n\r\n if (hasLeftRenovatieSponning) {\r\n ctx.lineTo(p2, baseline + renovatieSponningData.renovatieLengthLeft);\r\n ctx.lineTo(\r\n p2 +\r\n (hasLeftRenovatieSponning ? renovatieSponningData.renovatieDepthLeft : 0),\r\n baseline + renovatieSponningData.renovatieLengthLeft\r\n );\r\n } else if (hasLeftKloosterSponning) {\r\n ctx.lineTo(\r\n p2,\r\n baseline + kloosterSponningData.kloosterOffsetLeft\r\n );\r\n ctx.lineTo(\r\n p2 + kloosterSponningData.kloosterDepthLeft,\r\n baseline + kloosterSponningData.kloosterOffsetLeft\r\n );\r\n ctx.lineTo(\r\n p2 + kloosterSponningData.kloosterDepthLeft,\r\n baseline + kloosterSponningData.kloosterOffsetLeft + kloosterSponningData.kloosterLengthLeft\r\n );\r\n ctx.lineTo(\r\n p2,\r\n baseline + kloosterSponningData.kloosterOffsetLeft + kloosterSponningData.kloosterLengthLeft\r\n );\r\n }\r\n\r\n ctx.lineTo(\r\n p2 +\r\n (hasLeftRenovatieSponning ? renovatieSponningData.renovatieDepthLeft : 0),\r\n baseline\r\n );\r\n\r\n // //Middenneut 1 tekenen\r\n // ctx.moveTo(p4, baseline + a2 + c);\r\n // ctx.lineTo(p5, baseline + a2 + c);\r\n // ctx.lineTo(p5, baseline + neutLength);\r\n // ctx.lineTo(p4, baseline + neutLength);\r\n // ctx.lineTo(p4, baseline + a2 + c);\r\n\r\n // //Middenneut 2 tekenen\r\n // ctx.moveTo(p6, baseline + a2 + c);\r\n // ctx.lineTo(p7, baseline + a2 + c);\r\n // ctx.lineTo(p7, baseline + neutLength);\r\n // ctx.lineTo(p6, baseline + neutLength);\r\n // ctx.lineTo(p6, baseline + a2 + c);\r\n\r\n //Rechterneut tekenen\r\n ctx.moveTo(p8, baseline);\r\n ctx.lineTo(p8, baseline + a1);\r\n ctx.lineTo(p8 + b, baseline + a1);\r\n ctx.lineTo(p8 + b, baseline + a1 + c);\r\n ctx.lineTo(p8, baseline + a1 + c);\r\n ctx.lineTo(p8, baseline + neutLength);\r\n ctx.lineTo(p9, baseline + neutLength);\r\n\r\n if (hasRightRenovatieSponning) {\r\n //with renovatie\r\n ctx.lineTo(p9, baseline + renovatieSponningData.renovatieLengthRight);\r\n ctx.lineTo(\r\n p9 - renovatieSponningData.renovatieDepthRight,\r\n baseline + renovatieSponningData.renovatieLengthRight\r\n );\r\n ctx.lineTo(p9 - renovatieSponningData.renovatieDepthRight, baseline);\r\n } else if (hasRightKloosterSponning) {\r\n //with klooster\r\n ctx.lineTo(\r\n p9,\r\n baseline + kloosterSponningData.kloosterOffsetRight +\r\n kloosterSponningData.kloosterLengthRight\r\n );\r\n ctx.lineTo(\r\n p9 - kloosterSponningData.kloosterDepthRight,\r\n baseline + kloosterSponningData.kloosterOffsetRight +\r\n kloosterSponningData.kloosterLengthRight\r\n );\r\n ctx.lineTo(\r\n p9 - kloosterSponningData.kloosterDepthRight,\r\n baseline + kloosterSponningData.kloosterOffsetRight\r\n );\r\n ctx.lineTo(\r\n p9,\r\n baseline + kloosterSponningData.kloosterOffsetRight\r\n );\r\n ctx.lineTo(p9, baseline);\r\n } else {\r\n //regular\r\n ctx.lineTo(p9, baseline);\r\n }\r\n ctx.lineTo(p8, baseline);\r\n\r\n // hefschuifdeur\r\n ctx.moveTo(p3 - b, baseline + a2);\r\n ctx.lineTo(p8 + b, baseline + a2);\r\n ctx.lineTo(p8 + b, baseline + a2 + c);\r\n ctx.lineTo(p3 - b, baseline + a2 + c);\r\n ctx.lineTo(p3 - b, baseline + a2);\r\n\r\n //rail\r\n let topLineY = baseline + a2 + c / 2 - HS_RAIL_WIDTH / 2;\r\n let bottomLineY = topLineY + HS_RAIL_WIDTH;\r\n ctx.moveTo(p3 - b, topLineY);\r\n ctx.lineTo(p8 + b, topLineY);\r\n ctx.moveTo(p3 - b, bottomLineY);\r\n ctx.lineTo(p8 + b, bottomLineY);\r\n\r\n // vaste deurmaat B\r\n ctx.moveTo(p4, baseline + neutLength);\r\n ctx.lineTo(p7, baseline + neutLength);\r\n ctx.lineTo(p7, baseline + neutLength - c);\r\n ctx.lineTo(p4, baseline + neutLength - c);\r\n ctx.lineTo(p4, baseline + neutLength);\r\n ctx.stroke();\r\n\r\n if (maatA) {\r\n this.drawScaleMeasurements(\r\n ctx,\r\n 0,\r\n scaledMA,\r\n 30,\r\n SCALE_HEIGHT,\r\n maatA\r\n );\r\n }\r\n\r\n this.drawScaleMeasurements(\r\n ctx,\r\n scaledMA,\r\n scaledMA + firstMaatAVal,\r\n 30,\r\n SCALE_HEIGHT,\r\n firstMaatA\r\n );\r\n this.drawScaleMeasurements(\r\n ctx,\r\n scaledMA + firstMaatAVal,\r\n scaledMA + firstMaatAVal + deurmaatBVal,\r\n 30,\r\n SCALE_HEIGHT,\r\n deurmaatB\r\n );\r\n this.drawScaleMeasurements(\r\n ctx,\r\n scaledMA + firstMaatAVal + deurmaatBVal,\r\n this.canvasSize - scaledMZ,\r\n 30,\r\n SCALE_HEIGHT,\r\n maatC\r\n );\r\n\r\n if (maatZ) {\r\n this.drawScaleMeasurements(\r\n ctx,\r\n this.canvasSize - scaledMZ,\r\n this.canvasSize,\r\n 30,\r\n SCALE_HEIGHT,\r\n maatZ\r\n );\r\n }\r\n }\r\n\r\n private calculateDaagmatVirtualRatio(neuten: BestellingNeutDto[], maatA: number, maatZ: number, dorpelHeight: number): number {\r\n let trueScaleMeasurements = 0;\r\n let scaledMeasurements = 0;\r\n\r\n if (maatA) {\r\n if (maatA >= dorpelHeight) {\r\n trueScaleMeasurements += dorpelHeight;\r\n scaledMeasurements += maatA - dorpelHeight\r\n } else {\r\n trueScaleMeasurements += maatA;\r\n }\r\n }\r\n\r\n if (maatZ) {\r\n if (maatZ >= dorpelHeight) {\r\n trueScaleMeasurements += dorpelHeight;\r\n scaledMeasurements += maatZ - dorpelHeight\r\n } else {\r\n trueScaleMeasurements += maatZ;\r\n }\r\n }\r\n\r\n neuten.forEach(neut => {\r\n let neutDto: NeutDto = this.uiService.getNeutDtoByCodeAndPositie(\r\n neut.neutCode,\r\n neut.positie\r\n );\r\n let neutWidth = neut.customWidth || parseInt(neutDto.neutbreedte);\r\n trueScaleMeasurements += neutWidth;\r\n scaledMeasurements += neut.daagmaat || 0\r\n });\r\n\r\n let ratio = (this.canvasSize - trueScaleMeasurements) / scaledMeasurements;\r\n return parseFloat(ratio.toFixed(3));\r\n }\r\n\r\n private compensateForRightEndAccuracy(initialNextNeutPosition, nextNeut) {\r\n const TRESHOLD = 3;\r\n let neutDto: NeutDto = this.uiService.getNeutDtoByCodeAndPositie(\r\n nextNeut.neutCode,\r\n nextNeut.positie\r\n );\r\n let nextNeutWidth = nextNeut.customWidth || parseInt(neutDto.neutbreedte);\r\n let shouldCompensate = Math.abs((initialNextNeutPosition + nextNeutWidth) - this.canvasSize) < TRESHOLD;\r\n\r\n if (shouldCompensate) {\r\n return this.canvasSize - nextNeutWidth;\r\n }\r\n\r\n return initialNextNeutPosition;\r\n }\r\n\r\n public drawNeuten() {\r\n let currentDorpel: BestellingDorpelDto = this.dorpelData;\r\n let neuten: BestellingNeutDto[] = currentDorpel.neuten;\r\n let maatA = currentDorpel.maatA || 0;\r\n let maatZ = currentDorpel.maatZ || 0;\r\n let ctx: CanvasRenderingContext2D = this.canvasContext;\r\n let dorpelCode = this.dorpelData.dorpelCode;\r\n let options: NeutDrawingOptions = {\r\n isBuitenDorpel: dorpelCode.indexOf(DORPEL_CODES.BUITEN_DORPEL) !== -1,\r\n isBinnenDorpel: dorpelCode.indexOf(DORPEL_CODES.BINNEN_DORPEL) !== -1,\r\n isSlidingDoor: DorpelUtils.isSlidingDoor(dorpelCode),\r\n };\r\n let dorpelHeight = DorpelUtils.getThicknessFromDorpelCode(dorpelCode)\r\n\r\n let daagmaatVirtualRatio = this.calculateDaagmatVirtualRatio(neuten, maatA, maatZ, dorpelHeight);\r\n let scaledMA = Math.min(maatA, dorpelHeight) + Math.max(maatA - dorpelHeight, 0) * daagmaatVirtualRatio;\r\n let scaledMZ = Math.min(maatZ, dorpelHeight) + Math.max(maatZ - dorpelHeight, 0) * daagmaatVirtualRatio;\r\n\r\n if (maatA) {\r\n this.drawScaleMeasurements(ctx, 0, scaledMA, 30, SCALE_HEIGHT, maatA);\r\n this.drawTextLabel(\r\n ctx,\r\n 0,\r\n scaledMA,\r\n DORPEL_START.y + dorpelHeight - 1,\r\n 1,\r\n \"Vak 1\"\r\n );\r\n }\r\n\r\n let currentNeutPosition = scaledMA;\r\n\r\n neuten.forEach((neut, index) => {\r\n if (neut.neutCode) {\r\n const prevNeut: BestellingNeutDto = neuten[index - 1];\r\n if (prevNeut && prevNeut.sponningmaat) {\r\n options.leftCustomSponningmaat = prevNeut.sponningmaat\r\n } else {\r\n options.leftCustomSponningmaat = null\r\n }\r\n\r\n let neutRightLimit = this.drawNeut(\r\n neut,\r\n currentNeutPosition,\r\n DORPEL_START.y,\r\n ctx,\r\n options\r\n );\r\n let nextDaagmaat = neut.daagmaat;\r\n let nextNeutPosition =\r\n neutRightLimit + (nextDaagmaat ? nextDaagmaat * daagmaatVirtualRatio : 0);\r\n\r\n let willNextNeutTouchingRightEdge = index === neuten.length - 2 && !maatZ;\r\n\r\n if (willNextNeutTouchingRightEdge) {\r\n nextNeutPosition = this.compensateForRightEndAccuracy(nextNeutPosition, neuten[index + 1]);\r\n }\r\n\r\n if (nextDaagmaat) {\r\n this.drawScaleMeasurements(\r\n ctx,\r\n neutRightLimit,\r\n nextNeutPosition,\r\n 30,\r\n SCALE_HEIGHT,\r\n nextDaagmaat\r\n );\r\n\r\n this.drawTextLabel(\r\n ctx,\r\n neutRightLimit,\r\n nextNeutPosition,\r\n DORPEL_START.y + dorpelHeight - 1,\r\n 1,\r\n `Vak ${index + 2} Dagmaat`\r\n );\r\n\r\n if (neut.glaslat || neut.beglazingsprofiel || neut.aanslagprofiel) {\r\n let neutDto: NeutDto = this.uiService.getNeutDtoByCodeAndPositie(\r\n neut.neutCode,\r\n neut.positie\r\n );\r\n\r\n let nextNeut: NeutDto = (neuten[index + 1] as unknown) as NeutDto;\r\n let nextNeutDiff = 0;\r\n if (nextNeut) {\r\n let nextNeutDto: NeutDto = this.uiService.getNeutDtoByCodeAndPositie(nextNeut.neutCode!, nextNeut.positie!);\r\n nextNeutDiff = this.getNeutTopVsBaseWidthDifference(nextNeutDto, options, true);\r\n }\r\n let glaslatMarkVerticalPosition: number;\r\n\r\n if (options.isBuitenDorpel || (options.isBinnenDorpel && this.isConversionNeut(neutDto))) {\r\n glaslatMarkVerticalPosition =\r\n DORPEL_START.y +\r\n parseInt(neutDto.neutlengte) -\r\n SCALE_HEIGHT -\r\n 10;\r\n }\r\n\r\n if (options.isBinnenDorpel || (options.isBuitenDorpel && this.isConversionNeut(neutDto))) {\r\n //TODO: if special neut we need to check if this.isConversionNeut() condition is respected for the nextNeutDto\r\n glaslatMarkVerticalPosition = DORPEL_START.y + SCALE_HEIGHT - 5;\r\n }\r\n\r\n let label = \"\";\r\n if (neut.glaslat && neut.beglazingsprofiel) {\r\n label = \"Glaslat + Beglazingsprofiel\"\r\n } else if (neut.glaslat) {\r\n label = \"Glaslat\"\r\n } else if (neut.beglazingsprofiel) {\r\n label = \"Beglazingsprofiel\"\r\n } else if (neut.aanslagprofiel) {\r\n label = \"Aanslagprofiel\"\r\n }\r\n\r\n this.drawScaleMeasurements(\r\n ctx,\r\n neutRightLimit - this.getNeutTopVsBaseWidthDifference(neutDto, options),\r\n nextNeutPosition + nextNeutDiff,\r\n glaslatMarkVerticalPosition,\r\n SCALE_HEIGHT,\r\n label,\r\n true\r\n );\r\n }\r\n }\r\n\r\n if (neut.sponningsoort) {\r\n this.markSpooningsoort(\r\n ctx,\r\n neut.sponningsoort,\r\n neutRightLimit,\r\n neutRightLimit + nextDaagmaat,\r\n DORPEL_START.y,\r\n dorpelHeight\r\n );\r\n }\r\n\r\n currentNeutPosition = nextNeutPosition;\r\n }\r\n });\r\n\r\n if (maatZ) {\r\n this.drawScaleMeasurements(\r\n ctx,\r\n currentNeutPosition,\r\n this.canvasSize,\r\n 30,\r\n SCALE_HEIGHT,\r\n maatZ\r\n );\r\n this.drawTextLabel(\r\n ctx,\r\n currentNeutPosition,\r\n this.canvasSize,\r\n DORPEL_START.y + dorpelHeight - 1,\r\n 1,\r\n `Vak ${neuten.length + 1}`\r\n );\r\n }\r\n }\r\n\r\n private getNeutTopVsBaseWidthDifference(neutDto: NeutDto, options: NeutDrawingOptions, isLeftSideDiffrence?: boolean): number {\r\n let startCoord, endCoord;\r\n\r\n if (neutDto.omschrijving?.indexOf(\"XL\") !== -1 || neutDto.omschrijving?.indexOf(\"XT\") !== -1) {\r\n startCoord = 1;\r\n endCoord = 2;\r\n } else if (neutDto.omschrijving?.indexOf(\"XR\") !== -1) {\r\n startCoord = 0;\r\n endCoord = 3;\r\n } else if (options.isBinnenDorpel || (options.isBuitenDorpel && (neutDto.omschrijving?.indexOf(\"W2\") !== -1 || this.isConversionNeut(neutDto)))) {\r\n //W2 is not a conversion neut for buitendorpels on the right side w2 swithces from w1 e.g. which is a conversion neut back to regular\r\n if (neutDto.positie == \"Links\") {\r\n startCoord = 2;\r\n endCoord = 3;\r\n }\r\n\r\n if (neutDto.positie == \"Rechts\") {\r\n startCoord = 0;\r\n endCoord = 1;\r\n }\r\n\r\n if (neutDto.positie == \"Tussen\") {\r\n startCoord = isLeftSideDiffrence ? 0 : 4;\r\n endCoord = isLeftSideDiffrence ? 1 : 5;\r\n\r\n if (neutDto.omschrijving?.toLocaleLowerCase().indexOf(\"w3\") !== -1) {\r\n startCoord = isLeftSideDiffrence ? 7 : 2;\r\n endCoord = isLeftSideDiffrence ? 6 : 3;\r\n } else if (neutDto.omschrijving?.toLocaleLowerCase().indexOf(\"w2\") !== -1) {\r\n startCoord = isLeftSideDiffrence ? 0 : 5;\r\n endCoord = isLeftSideDiffrence ? 1 : 4;\r\n }\r\n }\r\n } else if (options.isBuitenDorpel || (options.isBinnenDorpel && this.isConversionNeut(neutDto))) {\r\n if (neutDto.positie == \"Links\") {\r\n startCoord = 3;\r\n endCoord = 2;\r\n }\r\n\r\n if (neutDto.positie == \"Rechts\") {\r\n startCoord = 5;\r\n endCoord = 4;\r\n }\r\n\r\n if (neutDto.positie == \"Tussen\") {\r\n startCoord = isLeftSideDiffrence ? 7 : 3;\r\n endCoord = isLeftSideDiffrence ? 6 : 2;\r\n }\r\n }\r\n\r\n let neutCoords = neutDto.tekening?.split(\"/\");\r\n let start = parseInt(neutCoords![startCoord].split(\",\")[0]);\r\n let end = parseInt(neutCoords![endCoord].split(\",\")[0]);\r\n\r\n return end - start;\r\n }\r\n\r\n private isConversionNeut(neutDto: NeutDto): boolean {\r\n let isConversionNeut: boolean =\r\n neutDto.omschrijving?.indexOf(\"W1\") !== -1 ||\r\n neutDto.omschrijving?.indexOf(\"W3\") !== -1 ||\r\n neutDto.omschrijving?.indexOf(\"W4\") !== -1 ||\r\n neutDto.omschrijving?.indexOf(\"W5\") !== -1;\r\n\r\n return isConversionNeut;\r\n }\r\n\r\n private drawNeut(\r\n neut: BestellingNeutDto,\r\n startX: number,\r\n startY: number,\r\n ctx: CanvasRenderingContext2D,\r\n options: NeutDrawingOptions\r\n ): number {\r\n let neutDto: NeutDto = this.uiService.getNeutDtoByCodeAndPositie(\r\n neut.neutCode,\r\n neut.positie\r\n );\r\n let neutWidth = neut.customWidth || parseInt(neutDto.neutbreedte);\r\n let neutHeight = parseInt(neutDto.neutlengte);\r\n let leftEdge = startX;\r\n let rightEdge = startX + neutWidth;\r\n let isLeftNeut: boolean = neut.positie === \"Links\";\r\n let isRightNeut: boolean = neut.positie === \"Rechts\";\r\n let isMiddleNeut: boolean = neut.positie === \"Tussen\";\r\n let drawStartY: number = startY + CONTENT_OFFSET;\r\n let drawStartX: number = leftEdge;\r\n let shouldAlterTekeningString: boolean = false;\r\n let isDrawingFlipped = false;\r\n\r\n //wissel neuts convert a buiten dorpel into a binnen dorpel so they need to have the default orientation;\r\n let isConversionNeut: boolean =\r\n neutDto.omschrijving?.indexOf(\"W1\") !== -1 ||\r\n neutDto.omschrijving?.indexOf(\"W4\") !== -1 ||\r\n neutDto.omschrijving?.indexOf(\"W5\") !== -1;\r\n let tekeningString: string = neutDto.tekening;\r\n\r\n if (neutDto.hasTekeningStringException) {\r\n this.flipDraw(neutHeight);\r\n isDrawingFlipped = true;\r\n }\r\n\r\n if (neut.customWidth && NeutUtils.isSpecial(neutDto.omschrijving)) {\r\n tekeningString = this.updateTekeningStringWithCustomWidth(tekeningString, neut.customWidth);\r\n }\r\n\r\n if (neutDto.isInHouseNeut) {\r\n // condition used to be !this.uiService.fromPrefilledOrder\r\n if (isLeftNeut) {\r\n drawStartX = leftEdge + CONTENT_OFFSET;\r\n shouldAlterTekeningString =\r\n this.uiService.kloosterSponningOptions.isLeftSide ||\r\n this.uiService.renovatieSponningOptions.isLeftSide;\r\n } else if (isRightNeut) {\r\n drawStartX = leftEdge - CONTENT_OFFSET;\r\n shouldAlterTekeningString =\r\n this.uiService.kloosterSponningOptions.isRightSide ||\r\n this.uiService.renovatieSponningOptions.isRightSide;\r\n }\r\n\r\n if (options.isBuitenDorpel && (neut.sponningmaat || options.leftCustomSponningmaat)) {\r\n //only wissels have sponningmaat\r\n //sponningmaat is only populated on the model if different from default (default is already included in tekening)\r\n tekeningString = this.changeTekeningStringSponningmaatValue(\r\n tekeningString,\r\n neut.neutCode,\r\n neut.sponningmaat,\r\n options.leftCustomSponningmaat\r\n );\r\n }\r\n\r\n let isW2Neut = neutDto.omschrijving.indexOf(\"W2\") !== -1;\r\n let isW3Neut = neutDto.omschrijving.indexOf(\"W3\") !== -1;\r\n tekeningString = this.insertVoorsponningDeviation({\r\n linksVoorsponning: neut.linksVoorsponning,\r\n rechtsVoorsponning: neut.rechtsVoorsponning,\r\n tekeningString: tekeningString,\r\n isTopPointingNeut:\r\n options.isBinnenDorpel ||\r\n (options.isBuitenDorpel && isConversionNeut) ||\r\n NeutUtils.isDK(neutDto.omschrijving),\r\n isW2Neut: isW2Neut, //voorsponning exception (bidirectional neut)\r\n isW3Neut: isW3Neut, //voorsponning exception (bidirectional neut)\r\n isLeftNeut: isLeftNeut,\r\n isRightNeut: isRightNeut,\r\n isMiddleNeut: isMiddleNeut,\r\n neutHeight: neutHeight,\r\n });\r\n }\r\n\r\n if (shouldAlterTekeningString) {\r\n let isCutDirectionRight = isLeftNeut;\r\n tekeningString = this.insertBewerkingenDeviation({\r\n isCutDirectionRight: isCutDirectionRight,\r\n isLeftNeut: isLeftNeut,\r\n neutWidth: neutWidth,\r\n neutHeight: neutHeight,\r\n tekeningString: tekeningString,\r\n isKloosterSponning: this.uiService.kloosterSponningOptions?.isActive && ((isLeftNeut && this.uiService.kloosterSponningOptions?.isLeftSide) || (isRightNeut && this.uiService.kloosterSponningOptions?.isRightSide)),\r\n isRenovatieSponning: this.uiService.renovatieSponningOptions?.isActive && ((isLeftNeut && this.uiService.renovatieSponningOptions?.isLeftSide) || (isRightNeut && this.uiService.renovatieSponningOptions?.isRightSide)),\r\n isDrawingFlipped: isDrawingFlipped,\r\n });\r\n }\r\n\r\n let neutCoordinatePoints = NeutUtils.getDrawingCoorodatesList(\r\n tekeningString,\r\n neutWidth,\r\n drawStartX,\r\n drawStartY\r\n );\r\n this.drawByCoordinates(\r\n ctx,\r\n neutCoordinatePoints,\r\n neut.isInHouseNeut ? NEUT_COLOR : INVALID_NEUT_COLOR\r\n );\r\n\r\n if (neutDto.hasTekeningStringException) {\r\n this.resetFlip();\r\n isDrawingFlipped = false;\r\n }\r\n\r\n this.drawScaleMeasurements(\r\n ctx,\r\n leftEdge,\r\n rightEdge,\r\n 30,\r\n SCALE_HEIGHT,\r\n neutWidth\r\n );\r\n return rightEdge;\r\n }\r\n\r\n private updateTekeningStringWithCustomWidth(tekeningString: string, customWidth: number): string {\r\n let tekeningCoordinates: Coordinate[] =\r\n this.convertTekeningStringToCoordinatesList(tekeningString);\r\n tekeningCoordinates[1].x = customWidth;\r\n tekeningCoordinates[2].x = customWidth;\r\n return this.convertCoordinatesListToTekeningString(tekeningCoordinates);\r\n }\r\n\r\n private changeTekeningStringSponningmaatValue(\r\n tekeningString: string,\r\n neutCode: string,\r\n rightSponningmaat: number,\r\n leftSponningmaat: number\r\n ): string {\r\n let wisselTypeToken: string = neutCode.split(\".\")[1].substr(0, 2);\r\n let targetPoints: SponningmaatUpdateTargetPoints =\r\n this.getSponningmaatUpdateTargetPoints(wisselTypeToken);\r\n let tekeningCoordinates: Coordinate[] =\r\n this.convertTekeningStringToCoordinatesList(tekeningString);\r\n\r\n targetPoints?.right.forEach((tp) => {\r\n if (rightSponningmaat) {\r\n tekeningCoordinates[tp].y = rightSponningmaat;\r\n }\r\n });\r\n\r\n targetPoints?.left.forEach((tp) => {\r\n if (leftSponningmaat) {\r\n tekeningCoordinates[tp].y = leftSponningmaat;\r\n }\r\n });\r\n\r\n return this.convertCoordinatesListToTekeningString(tekeningCoordinates);\r\n }\r\n\r\n private getSponningmaatUpdateTargetPoints(wisselType: string): SponningmaatUpdateTargetPoints {\r\n return WISSELNEUT_SPONNINGMAAT_COORDINATES[wisselType];\r\n }\r\n\r\n private drawByCoordinates(\r\n ctx: CanvasRenderingContext2D,\r\n coordinates: any[],\r\n fillColor?: string\r\n ): void {\r\n let startPoint = coordinates[0];\r\n\r\n ctx.beginPath();\r\n ctx.moveTo(startPoint.x, startPoint.y);\r\n coordinates.forEach((coordinate, index) => {\r\n if (index) {\r\n ctx.lineTo(coordinate.x, coordinate.y);\r\n ctx.stroke();\r\n }\r\n });\r\n\r\n if (fillColor) {\r\n this.fillShape(ctx, fillColor);\r\n }\r\n }\r\n\r\n public markSpooningsoort(\r\n ctx: CanvasRenderingContext2D,\r\n sponningsoort: string,\r\n fromX: number,\r\n toX: number,\r\n dorpelTopY: number,\r\n dorpelHeight: number\r\n ) {\r\n let extractedLetter = sponningsoort.charAt(0);\r\n ctx.fillText(\r\n extractedLetter,\r\n fromX + (toX - fromX) / 2,\r\n dorpelTopY + dorpelHeight - 5\r\n );\r\n }\r\n\r\n public fillShape(ctx: CanvasRenderingContext2D, color: string) {\r\n ctx.save();\r\n ctx.fillStyle = color;\r\n ctx.fill();\r\n ctx.restore();\r\n }\r\n\r\n /**\r\n * SLUITPOT DRAWING FUNCTIONS\r\n */\r\n\r\n public drawSluitpotten(damLevel?: number) {\r\n let sluitpotten: SluitpotModel[] = this.dorpelData.sluitpotten;\r\n let ctx: CanvasRenderingContext2D = this.canvasContext;\r\n let minimumScaleY = 185;\r\n let scaleSpacing = SCALE_HEIGHT + 10;\r\n\r\n sluitpotten.forEach((sluitpot, index) => {\r\n if (!sluitpot.maat /*|| (sluitpot.isNonBlinde && !sluitpot.maat2 && sluitpot.maat2 !== 0)*/) {\r\n //if no distance is mentioned (or is 0), avoid drawing the sluitpot\r\n //we can draw sluitpotten with height 0 (maat2 == 0), though\r\n return;\r\n }\r\n\r\n let ratio = this.canvasSize / this.dorpelData.zaagmaat;\r\n this.drawSluitpott(ctx, ratio, sluitpot, damLevel);\r\n this.drawScaleMeasurements(\r\n ctx,\r\n 0,\r\n sluitpot.maat * ratio,\r\n minimumScaleY + index * scaleSpacing,\r\n SCALE_HEIGHT,\r\n sluitpot.maat\r\n );\r\n });\r\n }\r\n\r\n private drawSluitpott(\r\n ctx: CanvasRenderingContext2D,\r\n ratio: number,\r\n sluitpot: SluitpotModel,\r\n damLevel?: number\r\n ): void {\r\n let sluitpotMarkerSize = 10;\r\n let markerLevels = {\r\n dam: 90,\r\n sponning: 140,\r\n };\r\n let sluitpotValue = sluitpot.maat * ratio;\r\n\r\n if (!sluitpotValue) {\r\n return;\r\n }\r\n\r\n let yOffset = 0;\r\n\r\n if (/*sluitpot.isNonBlinde*/ false) {\r\n yOffset += DORPEL_START.y + (damLevel || 0) + (sluitpot.maat2 || 0);\r\n } else {\r\n if (SluitpotUtils.isInDeDam(sluitpot.omschrijving)) {\r\n yOffset = markerLevels.dam;\r\n } else if (SluitpotUtils.isInDeSponning(sluitpot.omschrijving)) {\r\n yOffset = markerLevels.sponning;\r\n }\r\n }\r\n\r\n ctx.beginPath();\r\n ctx.moveTo(sluitpotValue - sluitpotMarkerSize / 2, yOffset - sluitpotMarkerSize / 2);\r\n ctx.lineTo(\r\n sluitpotValue + sluitpotMarkerSize / 2,\r\n yOffset + sluitpotMarkerSize / 2\r\n );\r\n ctx.moveTo(sluitpotValue + sluitpotMarkerSize / 2, yOffset - sluitpotMarkerSize / 2);\r\n ctx.lineTo(\r\n sluitpotValue - sluitpotMarkerSize / 2,\r\n yOffset + sluitpotMarkerSize / 2\r\n );\r\n ctx.stroke();\r\n }\r\n\r\n /**\r\n * SCALE related functions\r\n */\r\n\r\n private drawScaleMeasurements(\r\n ctx: CanvasRenderingContext2D,\r\n fromX: number,\r\n toX: number,\r\n verticalPosition: number,\r\n height: number,\r\n value?: number | string,\r\n excludeSideDelimiters: boolean = false\r\n ) {\r\n let midY = (2 * verticalPosition + height) / 2;\r\n\r\n if (!excludeSideDelimiters) {\r\n ctx.beginPath();\r\n ctx.moveTo(fromX, verticalPosition);\r\n ctx.lineTo(fromX, verticalPosition + height);\r\n ctx.stroke();\r\n\r\n ctx.beginPath();\r\n ctx.moveTo(toX, verticalPosition);\r\n ctx.lineTo(toX, verticalPosition + height);\r\n ctx.stroke();\r\n }\r\n\r\n this.drawArrowHeadLeft(\r\n ctx,\r\n { x: fromX, y: midY },\r\n SCALE_TIP_ARROW.HEIGHT,\r\n SCALE_TIP_ARROW.WIDTH\r\n );\r\n this.drawArrowHeadRight(\r\n ctx,\r\n { x: toX, y: midY },\r\n SCALE_TIP_ARROW.HEIGHT,\r\n SCALE_TIP_ARROW.WIDTH\r\n );\r\n\r\n ctx.beginPath();\r\n ctx.moveTo(fromX, midY);\r\n ctx.lineTo(toX, midY);\r\n ctx.stroke();\r\n ctx.lineWidth = TEXT_STROKE_WIDTH;\r\n\r\n if (value) {\r\n this.drawTextLabel(ctx, fromX, toX, verticalPosition, height, value);\r\n }\r\n\r\n ctx.lineWidth = DOOR_ELEMENT_WIDTH;\r\n }\r\n\r\n public drawTextLabel(ctx: CanvasRenderingContext2D,\r\n fromX: number,\r\n toX: number,\r\n verticalPosition: number,\r\n height: number,\r\n value: number | string) {\r\n let midY = (2 * verticalPosition + height) / 2;\r\n let cachedFont = ctx.font;\r\n let text = value.toString();\r\n ctx.font = SCALE_TEXT_FONT;\r\n let textSize = ctx.measureText(text);\r\n ctx.fillText(text, fromX + (toX - fromX) / 2 - textSize.width / 2, midY - 5);\r\n ctx.font = cachedFont;\r\n }\r\n\r\n private drawArrowHeadLeft(\r\n ctx: CanvasRenderingContext2D,\r\n tipPoint: any,\r\n height: number,\r\n width: number\r\n ) {\r\n ctx.beginPath();\r\n ctx.moveTo(tipPoint.x, tipPoint.y);\r\n ctx.lineTo(tipPoint.x + height, tipPoint.y + width / 2);\r\n ctx.lineTo(tipPoint.x + height, tipPoint.y - width / 2);\r\n ctx.fill();\r\n }\r\n\r\n private drawArrowHeadRight(\r\n ctx: CanvasRenderingContext2D,\r\n tipPoint: any,\r\n height: number,\r\n width: number\r\n ) {\r\n ctx.beginPath();\r\n ctx.moveTo(tipPoint.x, tipPoint.y);\r\n ctx.lineTo(tipPoint.x - height, tipPoint.y + width / 2);\r\n ctx.lineTo(tipPoint.x - height, tipPoint.y - width / 2);\r\n ctx.fill();\r\n }\r\n\r\n /**\r\n * SLIDING DOOR UTILS\r\n */\r\n\r\n private getSlidingNeutValues(doorThickness: number, neutLength: number, dorpelCode): any {\r\n let result = {\r\n a1: null,\r\n a2: null,\r\n b: 6,\r\n c: 42,\r\n baseline: 60,\r\n };\r\n\r\n if (doorThickness == 140) {\r\n if (neutLength == 114 || neutLength == 122) {\r\n result.a1 = 6;\r\n result.a2 = 6;\r\n } else if (neutLength == 139) {\r\n result.a1 = 6;\r\n result.a2 = 12;\r\n } else {\r\n result.a1 = 6;\r\n result.a2 = 6;\r\n }\r\n } else if (doorThickness == 146) {\r\n if (neutLength == 146) {\r\n result.a1 = 12;\r\n result.a2 = 12;\r\n } else if (neutLength == 139) {\r\n result.a1 = 12;\r\n result.a2 = 6;\r\n } else {\r\n result.a1 = 6;\r\n result.a2 = 6;\r\n }\r\n }\r\n\r\n let hasSpecialNeutException = dorpelCode.toLocaleLowerCase().indexOf(\"hs.190\") !== -1;\r\n if(hasSpecialNeutException) {\r\n result.b = 0;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * GENERAL UTILS\r\n */\r\n\r\n private convertTekeningStringToCoordinatesList(\r\n tekeningString: string\r\n ): Coordinate[] {\r\n let splitTekening = tekeningString.split(\"/\");\r\n let response: Coordinate[] = [];\r\n\r\n splitTekening.forEach((tekeningPoint) => {\r\n response.push({\r\n x: parseInt(tekeningPoint.split(\",\")[0]),\r\n y: parseInt(tekeningPoint.split(\",\")[1]),\r\n });\r\n });\r\n\r\n return response;\r\n }\r\n\r\n private convertCoordinatesListToTekeningString(\r\n coordinatesList: Coordinate[]\r\n ): string {\r\n let stringifiedCooridinatesList: string[] = [];\r\n coordinatesList.forEach((coordinate) => {\r\n stringifiedCooridinatesList.push(`${coordinate.x},${coordinate.y}`);\r\n });\r\n return stringifiedCooridinatesList.join(\"/\");\r\n }\r\n\r\n /**\r\n * VOORSPONNING DEVIATION\r\n *\r\n */\r\n\r\n private insertVoorsponningDeviation(options: any): string {\r\n let tekeningCoordinatesList: Coordinate[] =\r\n this.convertTekeningStringToCoordinatesList(options.tekeningString);\r\n let linksVoorsponning = options.linksVoorsponning;\r\n let rechtsVoorsponning = options.rechtsVoorsponning;\r\n let insertionPointDeterminingOptions = {\r\n isLeftNeut: options.isLeftNeut,\r\n isRightNeut: options.isRightNeut,\r\n isMiddleNeut: options.isMiddleNeut,\r\n isTopPointingNeut: options.isTopPointingNeut,\r\n indices: null,\r\n voorsponningType: null,\r\n };\r\n\r\n if (linksVoorsponning && linksVoorsponning.width) {\r\n let isVoorsponningOnTop = options.isTopPointingNeut || options.isW2Neut; //w2 neut types have left voorsponning on the top side (right on the bottom)\r\n let neutTopPositionIndices = this.getNeutTopEdgePointsIndices(\r\n tekeningCoordinatesList,\r\n {\r\n topSideYValue: isVoorsponningOnTop ? 0 : options.neutHeight, //the discriminant for the top edge of the neut\r\n }\r\n );\r\n insertionPointDeterminingOptions.indices = neutTopPositionIndices;\r\n insertionPointDeterminingOptions.isTopPointingNeut = isVoorsponningOnTop; //override initial value with additional check;\r\n insertionPointDeterminingOptions.voorsponningType =\r\n VOORSPONNING_TYPES.LEFT;\r\n\r\n let insertionPointIndex: number =\r\n this.determineVoorsponningInsertionPoint(\r\n insertionPointDeterminingOptions\r\n );\r\n let targetPoint: Coordinate =\r\n tekeningCoordinatesList[insertionPointIndex];\r\n let deviation: Coordinate[] = this.getLinksVoorsponningDeviation(\r\n isVoorsponningOnTop,\r\n targetPoint,\r\n linksVoorsponning\r\n );\r\n tekeningCoordinatesList.splice(insertionPointIndex, 1, ...deviation);\r\n\r\n if (insertionPointIndex === 0) {\r\n //exception for when tekening string starts exactly at the insertion point for left deviation (we also need to update last coordinate)\r\n //this case was encountered for DK neuten where the starting point of the coordinate list is an exception (not the leftmost + topmost but topmost + leftmost)\r\n tekeningCoordinatesList[tekeningCoordinatesList.length - 1] = tekeningCoordinatesList[0];\r\n }\r\n }\r\n\r\n if (rechtsVoorsponning && rechtsVoorsponning.width) {\r\n let isVoorsponningOnTop = options.isTopPointingNeut || options.isW3Neut; //w3 neut types have right voorsponning on the top side (left on the bottom)\r\n let neutTopPositionIndices = this.getNeutTopEdgePointsIndices(\r\n tekeningCoordinatesList,\r\n {\r\n topSideYValue: isVoorsponningOnTop ? 0 : options.neutHeight, //the discriminant for the top edge of the neut\r\n }\r\n );\r\n insertionPointDeterminingOptions.indices = neutTopPositionIndices;\r\n insertionPointDeterminingOptions.isTopPointingNeut = isVoorsponningOnTop; //override initial value with additional check;\r\n insertionPointDeterminingOptions.voorsponningType =\r\n VOORSPONNING_TYPES.RIGHT;\r\n\r\n let insertionPointIndex: number =\r\n this.determineVoorsponningInsertionPoint(\r\n insertionPointDeterminingOptions\r\n );\r\n let targetPoint: Coordinate =\r\n tekeningCoordinatesList[insertionPointIndex];\r\n let deviation: Coordinate[] = this.getRechtsVoorsponningDeviation(\r\n options.isTopPointingNeut || options.isW3Neut,\r\n targetPoint,\r\n rechtsVoorsponning\r\n );\r\n tekeningCoordinatesList.splice(insertionPointIndex, 1, ...deviation);\r\n }\r\n\r\n return this.convertCoordinatesListToTekeningString(tekeningCoordinatesList);\r\n }\r\n\r\n private getNeutTopEdgePointsIndices(\r\n tekeningCoordinatesList: Coordinate[],\r\n options: any\r\n ): any {\r\n // the point indices order reflects the tekening string traversal order (drawing order)\r\n let firstPointIndex;\r\n let secondPointIndex;\r\n\r\n for (let i = 0; i < tekeningCoordinatesList.length; i++) {\r\n if (tekeningCoordinatesList[i].y === options.topSideYValue) {\r\n if (typeof firstPointIndex === \"undefined\") {\r\n firstPointIndex = i;\r\n } else if (typeof secondPointIndex === \"undefined\") {\r\n secondPointIndex = i;\r\n }\r\n }\r\n }\r\n\r\n return {\r\n firstPointIndex: firstPointIndex,\r\n secondPointIndex: secondPointIndex,\r\n };\r\n }\r\n\r\n private determineVoorsponningInsertionPoint(options: any): number {\r\n if (options.isLeftNeut) {\r\n return options.isTopPointingNeut\r\n ? options.indices.secondPointIndex\r\n : options.indices.firstPointIndex;\r\n } else if (options.isRightNeut) {\r\n return options.isTopPointingNeut\r\n ? options.indices.firstPointIndex\r\n : options.indices.secondPointIndex;\r\n } else if (options.isMiddleNeut) {\r\n if (options.voorsponningType === VOORSPONNING_TYPES.LEFT) {\r\n return options.isTopPointingNeut\r\n ? options.indices.firstPointIndex\r\n : options.indices.secondPointIndex;\r\n } else if (options.voorsponningType === VOORSPONNING_TYPES.RIGHT) {\r\n return options.isTopPointingNeut\r\n ? options.indices.secondPointIndex\r\n : options.indices.firstPointIndex;\r\n }\r\n }\r\n }\r\n\r\n private getLinksVoorsponningDeviation(\r\n isTopPointingNeut: boolean,\r\n targetPoint: Coordinate,\r\n voorsponning: VorsponningSize\r\n ): Coordinate[] {\r\n let vorsponningHeight = voorsponning.height || voorsponning.width;\r\n return isTopPointingNeut\r\n ? this.convertTekeningStringToCoordinatesList(\r\n `${targetPoint.x},${targetPoint.y + vorsponningHeight}/${targetPoint.x + voorsponning.width\r\n },${targetPoint.y + vorsponningHeight}/${targetPoint.x + voorsponning.width\r\n },${targetPoint.y}`\r\n )\r\n : this.convertTekeningStringToCoordinatesList(\r\n `${targetPoint.x + voorsponning.width},${targetPoint.y}/${targetPoint.x + voorsponning.width\r\n },${targetPoint.y - vorsponningHeight}/${targetPoint.x},${targetPoint.y - vorsponningHeight\r\n }`\r\n );\r\n }\r\n\r\n private getRechtsVoorsponningDeviation(\r\n isTopPointingNeut: boolean,\r\n targetPoint: Coordinate,\r\n voorsponning: VorsponningSize\r\n ): Coordinate[] {\r\n let vorsponningHeight = voorsponning.height || voorsponning.width;\r\n return isTopPointingNeut\r\n ? this.convertTekeningStringToCoordinatesList(\r\n `${targetPoint.x - voorsponning.width},${targetPoint.y}/${targetPoint.x - voorsponning.width\r\n },${targetPoint.y + vorsponningHeight}/${targetPoint.x},${targetPoint.y + vorsponningHeight\r\n }`\r\n )\r\n : this.convertTekeningStringToCoordinatesList(\r\n `${targetPoint.x},${targetPoint.y - vorsponningHeight}/${targetPoint.x - voorsponning.width\r\n },${targetPoint.y - vorsponningHeight}/${targetPoint.x - voorsponning.width\r\n },${targetPoint.y}`\r\n );\r\n }\r\n\r\n /**\r\n * BEWERKINGEN UTILS\r\n */\r\n\r\n private insertBewerkingenDeviation(options: any): string {\r\n let tekeningCoordinatesList: Coordinate[] =\r\n this.convertTekeningStringToCoordinatesList(options.tekeningString);\r\n let targetPoint: Coordinate = {\r\n x: options.isLeftNeut ? 0 : options.neutWidth,\r\n y: 0,\r\n };\r\n\r\n if (options.isDrawingFlipped) {\r\n //change target point to bottom omologue\r\n targetPoint.y = options.neutHeight;\r\n }\r\n\r\n let insertionPointIndex: number = this.determineBewerkingInsertionPoint(\r\n tekeningCoordinatesList,\r\n targetPoint\r\n );\r\n\r\n if (options.isKloosterSponning) {\r\n let deviation: string = this.getKloosterDeviation({\r\n targetPoint: targetPoint,\r\n isLeftNeut: options.isLeftNeut,\r\n neutHeight: options.neutHeight,\r\n });\r\n let deviationCoordinates: Coordinate[] =\r\n this.convertTekeningStringToCoordinatesList(deviation);\r\n\r\n if (options.isLeftNeut) {\r\n deviationCoordinates.reverse().push(targetPoint);\r\n } else {\r\n deviationCoordinates.unshift(targetPoint);\r\n }\r\n\r\n tekeningCoordinatesList.splice(\r\n insertionPointIndex,\r\n 1,\r\n ...deviationCoordinates\r\n );\r\n }\r\n\r\n if (options.isRenovatieSponning) {\r\n let deviation: string = this.getRenovatieDeviation({\r\n targetPoint: targetPoint,\r\n isLeftNeut: options.isLeftNeut,\r\n isDrawingFlipped: options.isDrawingFlipped,\r\n });\r\n let deviationCoordinates: Coordinate[] =\r\n this.convertTekeningStringToCoordinatesList(deviation);\r\n tekeningCoordinatesList.splice(\r\n insertionPointIndex,\r\n 1,\r\n ...deviationCoordinates\r\n );\r\n }\r\n\r\n if (options.isLeftNeut) {\r\n tekeningCoordinatesList[tekeningCoordinatesList.length - 1] =\r\n tekeningCoordinatesList[0];\r\n }\r\n\r\n return this.convertCoordinatesListToTekeningString(tekeningCoordinatesList);\r\n }\r\n\r\n private determineBewerkingInsertionPoint(\r\n coordinatesList: Coordinate[],\r\n targetPoint: Coordinate\r\n ): number | null {\r\n let foundIndex = null;\r\n\r\n for (let i = 0; i < coordinatesList.length; i++) {\r\n if (\r\n coordinatesList[i].x === targetPoint.x &&\r\n coordinatesList[i].y === targetPoint.y\r\n ) {\r\n foundIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n return foundIndex;\r\n }\r\n\r\n private getRenovatieDeviation(options: any): string {\r\n let renovatieSponningData = this.getRenovatieSponningData();\r\n let targetPoint = options.targetPoint;\r\n\r\n if (options.isDrawingFlipped) {\r\n //we calculate different deviation for neut flipping (only for asymetric deviations - renovatie)\r\n if (options.isLeftNeut) {\r\n return `${targetPoint.x + renovatieSponningData.renovatieDepthLeft},${targetPoint.y\r\n }/\r\n ${targetPoint.x + renovatieSponningData.renovatieDepthLeft},${targetPoint.y - renovatieSponningData.renovatieLengthLeft\r\n }/\r\n ${targetPoint.x},${targetPoint.y - renovatieSponningData.renovatieLengthLeft\r\n }`;\r\n } else {\r\n return `${targetPoint.x},${targetPoint.y - renovatieSponningData.renovatieLengthRight\r\n }/\r\n ${targetPoint.x - renovatieSponningData.renovatieDepthRight},${targetPoint.y - renovatieSponningData.renovatieLengthRight\r\n }/\r\n ${targetPoint.x - renovatieSponningData.renovatieDepthRight},${targetPoint.y\r\n }`;\r\n }\r\n }\r\n\r\n if (options.isLeftNeut) {\r\n return `${targetPoint.x},${targetPoint.y + renovatieSponningData.renovatieLengthLeft\r\n }/\r\n ${targetPoint.x + renovatieSponningData.renovatieDepthLeft},${targetPoint.y + renovatieSponningData.renovatieLengthLeft\r\n }/\r\n ${targetPoint.x + renovatieSponningData.renovatieDepthLeft},${targetPoint.y\r\n }`;\r\n } else {\r\n return `${targetPoint.x - renovatieSponningData.renovatieDepthRight},${targetPoint.y\r\n }/\r\n ${targetPoint.x - renovatieSponningData.renovatieDepthRight},${targetPoint.y + renovatieSponningData.renovatieLengthRight\r\n }/\r\n ${targetPoint.x},${targetPoint.y + renovatieSponningData.renovatieLengthRight\r\n }`;\r\n }\r\n }\r\n\r\n private getKloosterDeviation(options: any): string {\r\n let kloosterSponningData = this.getKloosterSponningData();\r\n let targetPoint = options.targetPoint;\r\n // let totalHeight = options.neutHeight;\r\n let kloosterTopBottomOffset = options.isLeftNeut ? kloosterSponningData.kloosterOffsetLeft : kloosterSponningData.kloosterOffsetRight;\r\n\r\n if (options.isLeftNeut) {\r\n return `${targetPoint.x},${targetPoint.y + kloosterTopBottomOffset}/\r\n ${targetPoint.x + kloosterSponningData.kloosterDepthLeft},${targetPoint.y + kloosterTopBottomOffset\r\n }/\r\n ${targetPoint.x + kloosterSponningData.kloosterDepthLeft},${targetPoint.y +\r\n kloosterTopBottomOffset +\r\n kloosterSponningData.kloosterLengthLeft\r\n }/\r\n ${targetPoint.x},${targetPoint.y +\r\n kloosterTopBottomOffset +\r\n kloosterSponningData.kloosterLengthLeft\r\n }`;\r\n } else {\r\n return `${targetPoint.x},${targetPoint.y + kloosterTopBottomOffset}/\r\n ${targetPoint.x - kloosterSponningData.kloosterDepthRight},${targetPoint.y + kloosterTopBottomOffset\r\n }/\r\n ${targetPoint.x - kloosterSponningData.kloosterDepthRight},${targetPoint.y +\r\n kloosterTopBottomOffset +\r\n kloosterSponningData.kloosterLengthRight\r\n }/\r\n ${targetPoint.x},${targetPoint.y +\r\n kloosterTopBottomOffset +\r\n kloosterSponningData.kloosterLengthRight\r\n }`;\r\n }\r\n }\r\n\r\n private getKloosterSponningData() {\r\n //TODO: move in bewerkingen comp\r\n return {\r\n kloosterDepthLeft: this.uiService.kloosterSponningOptions.leftCustomDepth,\r\n kloosterDepthRight: this.uiService.kloosterSponningOptions.rightCustomDepth,\r\n kloosterLengthLeft: this.uiService.kloosterSponningOptions.leftCustomLength,\r\n kloosterLengthRight: this.uiService.kloosterSponningOptions.rightCustomLength,\r\n kloosterOffsetLeft: this.uiService.kloosterSponningOptions.leftCustomOffset,\r\n kloosterOffsetRight: this.uiService.kloosterSponningOptions.rightCustomOffset,\r\n };\r\n }\r\n\r\n private getRenovatieSponningData() {\r\n //TODO: move in bewerkingen comp\r\n return {\r\n renovatieDepthLeft: this.uiService.renovatieSponningOptions.leftCustomDepth,\r\n renovatieDepthRight: this.uiService.renovatieSponningOptions.rightCustomDepth,\r\n renovatieLengthLeft: this.uiService.renovatieSponningOptions.leftCustomLength,\r\n renovatieLengthRight: this.uiService.renovatieSponningOptions.rightCustomLength,\r\n };\r\n }\r\n\r\n public calculateVerstekLengthByAngle(dorpelHeight: number, angle?: number): number {\r\n //maybe extract dorpelwidth of model (now width is static)\r\n let verstekAngle = angle || 45; //TODO: extract off the uistate when we have fields and pass it in on callsite\r\n let tangentValueOfAngle = Math.tan((verstekAngle * Math.PI) / 180);\r\n\r\n return Math.round(dorpelHeight * tangentValueOfAngle);\r\n }\r\n\r\n private setCanvasSize(\r\n canvas: HTMLCanvasElement,\r\n width: number,\r\n height: number\r\n ) {\r\n let ratio = window.devicePixelRatio;\r\n let style = canvas.style;\r\n\r\n style.width = \"\" + width + \"px\";\r\n style.height = \"\" + height + \"px\";\r\n\r\n canvas.width = width;\r\n canvas.height = height;\r\n }\r\n\r\n\r\n private flipDraw(referenceHeight: number): void {\r\n let ctx = this.canvasContext;\r\n ctx.save();\r\n ctx.translate(0, 2 * (DORPEL_START.y + CONTENT_OFFSET) + referenceHeight);\r\n ctx.scale(1, -1);\r\n }\r\n\r\n private resetFlip(): void {\r\n let ctx = this.canvasContext;\r\n ctx.restore();\r\n }\r\n}\r\n","import { Component, Input } from \"@angular/core\";\r\n\r\n@Component({\r\n selector: \"luv-validationError\",\r\n template: `\r\n <span *ngIf=\"show\" class=\"field-error-wrapper\">{{errorMessage}}<br/><ng-content></ng-content></span>\r\n `,\r\n styleUrls: ['validation-error.component.scss']\r\n})\r\nexport class ValidationErrorComponent {\r\n @Input(\"errorMessage\") public errorMessage: string;\r\n @Input() public show: boolean = true;\r\n}\r\n","import { Component } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'app-footer',\r\n templateUrl: './footer.component.html'\r\n})\r\nexport class FooterComponent {\r\n\r\n}\r\n","<footer class=\"text-body-secondary text-center text-small\">\r\n <p class=\"mb-1\">© 2025 Luvema - Dorpelbestellen.nl <a class=\"luvemafooterlink\" href=\"#\">versie 1.7.2</a> gepubliceerd op 28-01-2025 </p>\r\n</footer>","import { Directive, HostListener } from \"@angular/core\";\r\nimport { NG_VALUE_ACCESSOR, ControlValueAccessor } from \"@angular/forms\";\r\n\r\n@Directive({\r\n selector: \"input[type='file']\",\r\n providers: [\r\n {provide: NG_VALUE_ACCESSOR, useExisting: FileValueAccessorDirective, multi: true}\r\n ]\r\n})\r\nexport class FileValueAccessorDirective implements ControlValueAccessor {\r\n @HostListener('change', ['$event.target.files']) onChange = (_) => {};\r\n @HostListener('blur') onTouched = () => {};\r\n\r\n writeValue(value) {}\r\n registerOnChange(fn: any) { this.onChange = fn; }\r\n registerOnTouched(fn: any) { this.onTouched = fn; }\r\n}","import { Directive, HostListener } from '@angular/core';\r\n\r\n@Directive({\r\n selector: '[integerOnly]'\r\n})\r\nexport class IntegerOnlyDirective {\r\n @HostListener('keydown', ['$event'])\r\n onKeyDown(event: KeyboardEvent): void {\r\n const invalidKeys = ['.', ',', 'e', 'E', '+', '-'];\r\n if (invalidKeys.includes(event.key)) {\r\n event.preventDefault();\r\n }\r\n }\r\n\r\n @HostListener('input', ['$event'])\r\n onInput(event: any): void {\r\n // Remove any floating-point characters if pasted or entered via other means\r\n event.target.value = event.target.value.replace(/[^0-9]/g, '');\r\n }\r\n}","<div class=\"container px-4 py-5 my-5 text-center bg-white rounded-4\">\r\n <h1 class=\"display-5 fw-bold text-body-emphasis\">Dorpelbestellen.nl</h1>\r\n <div class=\"col-lg-6 text-center mx-auto\">\r\n <p class=\"mb-4\"> Dit portaal is ingericht voor bestaande klanten van <a\r\n href=\"https://www.luvema.nl\" target=\"_blank\"><b>Luvema</b></a>.<br><br>Bent u nog geen klant of heeft u vragen neem dan <a\r\n href=\"https://www.luvema.nl/contact/\" target=\"_blank\"><b>contact</b></a> met ons op.<br><br>\r\n <!--Wilt u alleen profielen bestellen? Dat kan op <a href=\"https://www.profielbestellen.nl\"\r\n target=\"_blank\"><b>profielbestellen.nl</b></a>-->\r\n </p>\r\n </div>\r\n</div>\r\n\r\n<div class=\"container px-4 py-5 my-5 bg-white rounded-4\">\r\n <h4 class=\"mb-3\">Accountgegevens</h4>\r\n <div class=\"row g-3\" [formGroup]=\"formGroup\" *ngIf=\"formGroup\" id=\"panel1\">\r\n <div class=\"col-md-6\">\r\n <label for=\"dealerCode\" class=\"form-label\">Dealer</label>\r\n <select class=\"form-select\" id=\"dealerCode\" formControlName=\"dealerCode\" (change)=\"onDealerChanged()\">\r\n <option value=\"\" disabled selected hidden>Selecteer een waarde a.u.b.</option>\r\n <ng-container *ngFor=\"let dealer of dealers\">\r\n <option value=\"{{dealer.dealerCode}}\">{{dealer.naam}}</option>\r\n </ng-container>\r\n </select>\r\n <luv-validationError [show]=\"showError('dealerCode')\" [errorMessage]=\"errorMessage('dealerCode')\">\r\n </luv-validationError>\r\n </div>\r\n\r\n <div class=\"col-sm-6\">\r\n <label for=\"contactpersoon\" class=\"form-label\">Contactpersoon</label>\r\n <input type=\"text\" class=\"form-control\" id=\"contactpersoon\" formControlName=\"contactpersoon\">\r\n <luv-validationError [show]=\"showError('contactpersoon')\" [errorMessage]=\"errorMessage('contactpersoon')\">\r\n </luv-validationError>\r\n </div>\r\n\r\n <div class=\"col-sm-6\">\r\n <label for=\"emailadres\" class=\"form-label\">Email</label>\r\n <input type=\"email\" class=\"form-control\" id=\"emailadres\" formControlName=\"emailadres\">\r\n <luv-validationError [show]=\"showError('emailadres')\" [errorMessage]=\"errorMessage('emailadres')\">\r\n </luv-validationError>\r\n </div>\r\n\r\n <div class=\"col-sm-6\">\r\n <label for=\"telefoonnummer\" class=\"form-label\">Telefoonnummer <span\r\n class=\"text-body-secondary\">(Optioneel)</span></label>\r\n <input type=\"Text\" class=\"form-control\" id=\"telefoonnummer\" formControlName=\"telefoonnummer\">\r\n <luv-validationError [show]=\"showError('telefoonnummer')\" [errorMessage]=\"errorMessage('telefoonnummer')\">\r\n </luv-validationError>\r\n </div>\r\n\r\n <hr class=\"my-4\">\r\n\r\n <div class=\"col-sm-4\">\r\n <label for=\"opdrachtgever\" class=\"form-label\">Opdrachtgever <span\r\n class=\"text-body-secondary\">(Optioneel)</span></label>\r\n <input type=\"text\" class=\"form-control\" id=\"opdrachtgever\" formControlName=\"opdrachtgever\">\r\n <luv-validationError [show]=\"showError('opdrachtgever')\" [errorMessage]=\"errorMessage('opdrachtgever')\">\r\n </luv-validationError>\r\n </div>\r\n\r\n\r\n <div class=\"col-sm-4\">\r\n <label for=\"referentie\" class=\"form-label\">Uw referentie <span\r\n class=\"text-body-secondary\">(Optioneel)</span></label>\r\n <input type=\"text\" class=\"form-control\" id=\"referentie\" formControlName=\"uwReferentie\" />\r\n </div>\r\n\r\n <div class=\"col-sm-4\">\r\n <label for=\"afleverdatum\" class=\"form-label\">Gewenste afleveratum <span\r\n class=\"text-body-secondary\">(Optioneel)</span></label>\r\n <input class=\"form-control\" type=\"date\" id=\"afleverdatum\" formControlName=\"afleverdatum\"\r\n min=\"{{minDeliveryDate}}\" />\r\n </div>\r\n\r\n <hr class=\"my-4\">\r\n\r\n <div class=\"col-sm-12\" formArrayName=\"bijlage\">\r\n <label for=\"formFile\" class=\"form-label\">Bijlagen</label>\r\n\r\n <div class=\"row file-row\" *ngFor=\"let fileControl of bijlage.controls; index as idx\">\r\n <div class=\"col-sm-10\">\r\n <div class=\"input-group\">\r\n <input acceptedFormats type=\"file\" class=\"custom-file-input form-control\" id=\"file{{idx}}\"\r\n (change)=\"onFileSelect($event, idx)\" [formControlName]=\"idx\" accept=\".pdf,.doc,.docx,.txt\">\r\n <!-- <label for=\"file{{idx}}\" class=\"custom-file-label\">{{model.files[idx]?.name || 'er\r\n is nog geen bijlage geselecteerd'}}</label> -->\r\n <span class=\"input-group-text\">bijlage <span *ngIf=\"bijlage.controls.length > 1\"> {{idx +\r\n 1}}</span></span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-sm-2\">\r\n <button type=\"button\" class=\"btn btn-danger btn-lg remove-file\" (click)=\"deleteFile(idx)\">\r\n <i class=\"far fa-trash-alt\"></i>\r\n </button>\r\n </div>\r\n <div class=\"col-sm-12\">\r\n <luv-validationError [show]=\"showError('bijlage', idx)\"\r\n [errorMessage]=\"errorMessage('bijlage', idx)\"></luv-validationError>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-sm-12\">\r\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"addFileUploadControl()\">+ bijlage</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-sm-12\">\r\n <label for=\"opmerkingen\" class=\"form-label\">Opmerkingen</label>\r\n <textarea class=\"form-control\" id=\"opmerkingen\" rows=\"3\" formControlName=\"opmerkingen\"></textarea>\r\n </div>\r\n\r\n <div class=\"d-grid gap-2 d-sm-flex justify-content-sm-center\">\r\n <button type=\"button\" class=\"action-button btn btn-primary btn-lg px-4 gap-3 border-0 rounded-0\"\r\n (click)=\"onDorpelAddButtonClicked()\" [disabled]=\"isFromPrefilledOrder\"><b>Dorpel toevoegen</b></button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"container px-4 py-5 my-5 bg-white rounded-4\">\r\n <h4 class=\"mb-3\">Dorpeloverzicht</h4>\r\n\r\n <table class=\"table table-striped\">\r\n <ng-container *ngFor=\"let dorpel of cartItems\">\r\n <tr>\r\n <td>\r\n <div><span *ngIf=\"dorpel.merk\">{{dorpel.merk}} - </span>{{dorpel.dorpelCode}} - {{dorpel.zaagmaat}}mm</div>\r\n <div *ngIf=\"!dorpel.isInHouseDorpel\">This dorpel is not an inhouse dorpel - it will not be processed</div>\r\n </td>\r\n <td>\r\n <div class=\"no-margin input-group mb-3\">\r\n <input type=\"number\" class=\"form-control\" aria-describedby=\"aantal\" [(ngModel)]=\"dorpel.aantal\" integerOnly />\r\n <span class=\"input-group-text\" id=\"aantal\">Stuks</span>\r\n </div>\r\n </td>\r\n <td>\r\n <span class=\"action-area\" (click)=\"onEditDorpel(dorpel)\"><i class=\"fas fa-pencil-alt\"></i></span>\r\n <span class=\"action-area\" (click)=\"onDeleteDorpel(dorpel)\"><i class=\"far fa-trash-alt\"></i></span>\r\n </td>\r\n </tr>\r\n </ng-container>\r\n </table>\r\n\r\n <div class=\"text-center no-content-error\">\r\n <luv-validationError [show]=\"cartItems.length < 1 && !!posted\"\r\n errorMessage=\"Voeg s.v.p. eerst een dorpel toe aan de dorpeloverzicht.\">\r\n </luv-validationError>\r\n </div>\r\n\r\n <div class=\"row\">\r\n <div class=\"d-grid gap-2 d-sm-flex justify-content-sm-center\">\r\n <button type=\"button\" class=\"action-button btn btn-primary btn-lg px-4 gap-3 border-0 rounded-0\"\r\n (click)=\"onDorpelBestellenButtonClicked()\"><b>Dorpelbestellen</b>\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<app-footer></app-footer>","import { ChangeDetectorRef, Component, OnInit } from \"@angular/core\";\r\nimport {\r\n FormBuilder,\r\n FormGroup,\r\n Validators,\r\n FormArray,\r\n FormControl,\r\n} from \"@angular/forms\";\r\nimport {\r\n BestellingDorpelDto,\r\n BestellingDto,\r\n DealerDto,\r\n} from \"../shared/api-models/models\";\r\nimport { BackendService } from \"../core/services/backend.service\";\r\nimport { FormComponent } from \"../shared/form-component\";\r\nimport { ActivatedRoute, Route, Router } from \"@angular/router\";\r\nimport { DataStateService } from \"../core/services/data-state.service\";\r\nimport { GraphicsService } from \"../core/services/graphics.service\";\r\nimport { NgbPanelChangeEvent } from \"@ng-bootstrap/ng-bootstrap\";\r\nimport { BaseComponent } from \"../shared/base.component\";\r\nimport { takeUntil, catchError } from \"rxjs/internal/operators\";\r\nimport { UiStateService } from \"../core/services/ui-state-service\";\r\nimport { NgxSpinnerService } from \"ngx-spinner\";\r\nimport { environment } from \"../../environments/environment\";\r\nimport { FileFormatValidator } from \"../shared/file-format-validator\";\r\nimport { Observable, throwError } from \"rxjs\";\r\nimport { ProcessingResponse } from \"../shared/api-models/processing-response\";\r\nimport { Guid } from \"guid-typescript\";\r\nimport { formatDate } from \"@angular/common\";\r\nimport { logoBase64 } from \"./constants\";\r\n\r\nconst WRONG_FILE_STRUCTURE_ERROR =\r\n \"Dit is geen geldig Matrix/Groenveld bestand. Voer een geldig bestand in\";\r\nconst PRESERVED_FORM_FIELDS = [\r\n \"opdrachtgever\",\r\n \"contactpersoon\",\r\n \"telefoonnummer\",\r\n \"emailadres\",\r\n \"uwReferentie\",\r\n \"dealerCode\",\r\n];\r\n@Component({\r\n selector: \"app-welkom\",\r\n templateUrl: \"./welkom.component.html\",\r\n styleUrls: [\"./welkom.component.scss\"],\r\n})\r\nexport class WelkomComponent extends BaseComponent implements OnInit {\r\n public formGroup: FormGroup;\r\n public dealers: DealerDto[] = [];\r\n public productType: string;\r\n public prefilledOrderErrorMessage: string | null = null;\r\n public posted: boolean;\r\n\r\n public get model(): BestellingDto {\r\n return this.dataStateService.getModel();\r\n }\r\n\r\n public get minDeliveryDate(): string {\r\n return formatDate(new Date(), \"yyyy-MM-dd\", \"en\");\r\n }\r\n\r\n private _formComponent: FormComponent;\r\n\r\n constructor(\r\n private formBuilder: FormBuilder,\r\n private backend: BackendService,\r\n private router: Router,\r\n private dataStateService: DataStateService,\r\n private uiState: UiStateService,\r\n private spinner: NgxSpinnerService,\r\n private cdRef: ChangeDetectorRef,\r\n private activatedRoute: ActivatedRoute,\r\n private graphics: GraphicsService\r\n ) {\r\n super();\r\n }\r\n\r\n getSortedDealersList(originalList) {\r\n let sortedList = [...originalList];\r\n sortedList.sort((d1, d2) => d1.naam.localeCompare(d2.naam));\r\n\r\n return sortedList;\r\n }\r\n\r\n ngOnInit(): void {\r\n this.dataStateService.homePath = this.router.url;\r\n this.productType = this.activatedRoute.snapshot.paramMap.get(\"productType\");\r\n this.uiState.setProductType(this.productType);\r\n this.populatePreservedWelkomFormValues(PRESERVED_FORM_FIELDS);\r\n\r\n this.updateFormData();\r\n let guidAssociatedDealers = this.uiState.currentDealersGroup;\r\n\r\n if (guidAssociatedDealers) {\r\n this.dealers = this.getSortedDealersList(guidAssociatedDealers);\r\n let currentlySelectedDealerCode = this.formGroup.get(\"dealerCode\").value;\r\n\r\n if (!currentlySelectedDealerCode) {\r\n this.setFirtDealerFormGuidAssociatedList(guidAssociatedDealers);\r\n } else {\r\n let dealerFromGuidAssociatedList = guidAssociatedDealers.filter(\r\n (dealer) => {\r\n return dealer.dealerCode === currentlySelectedDealerCode;\r\n }\r\n );\r\n\r\n if (!dealerFromGuidAssociatedList.length) {\r\n this.setFirtDealerFormGuidAssociatedList(guidAssociatedDealers);\r\n }\r\n }\r\n } else {\r\n this.backend\r\n .getDealers()\r\n .pipe(takeUntil(this.unsubscribe$))\r\n .subscribe((result) => {\r\n this.dealers = this.getSortedDealersList(result);\r\n });\r\n }\r\n\r\n setTimeout(() => {\r\n this.cdRef.detectChanges();\r\n }, 100);\r\n }\r\n\r\n get themeSpecialClass() {\r\n let dealerClass = this.uiState.customDealerResources?.customClass;\r\n return dealerClass || this.productType.toLowerCase();\r\n }\r\n\r\n private setFirtDealerFormGuidAssociatedList(guidAssociatedDealers) {\r\n this.formGroup\r\n .get(\"dealerCode\")\r\n .setValue(guidAssociatedDealers[0].dealerCode);\r\n this.preserveWelkomFormValues([\"dealerCode\"]);\r\n }\r\n\r\n private updateFormData() {\r\n this.formGroup = this.buildForm();\r\n this._formComponent = new FormComponent(this.formGroup);\r\n }\r\n\r\n get bijlage(): FormArray {\r\n return this.formGroup.get(\"bijlage\") as FormArray;\r\n }\r\n\r\n get isFromPrefilledOrder(): boolean {\r\n return !!this.uiState?.fromPrefilledOrder;\r\n }\r\n\r\n deleteFile(index: number): void {\r\n this.bijlage.removeAt(index);\r\n if (this.model.files[index]) {\r\n this.model.files.splice(index, 1);\r\n }\r\n this.cdRef.detectChanges();\r\n }\r\n\r\n async onFileSelect(event, index) {\r\n if (event.target.files.length > 0) {\r\n const file = event.target.files[0];\r\n this.model.files[index] = file;\r\n }\r\n }\r\n\r\n addFileUploadControl(): void {\r\n this.bijlage.push(\r\n this.formBuilder.control([\"\", [FileFormatValidator.validate]])\r\n );\r\n this.cdRef.detectChanges();\r\n }\r\n\r\n public showError(key: string, index?: number): boolean {\r\n let shouldShowError = this._formComponent.showError(key, index);\r\n return shouldShowError;\r\n }\r\n\r\n public errorMessage(key: string, index?: number): string {\r\n let formControl;\r\n\r\n if (index !== null && typeof index !== \"undefined\") {\r\n let formArray = this.formGroup.get(key) as FormArray;\r\n formControl = formArray.at(index);\r\n } else {\r\n formControl = this.formGroup.get(key);\r\n }\r\n\r\n if (formControl.valid) {\r\n return \"\";\r\n }\r\n\r\n const [firstError] = Object.keys(formControl.errors);\r\n const error = ValidationMessages[key]\r\n ? ValidationMessages[key][firstError]\r\n : null;\r\n return error || this._formComponent.errorMessage(key);\r\n }\r\n\r\n public onDorpelAddButtonClicked() {\r\n if (!this.formGroup.valid && !environment.disableFieldValidation) {\r\n Object.keys(this.formGroup.controls).forEach((field) => {\r\n const control = this.formGroup.get(field);\r\n control.markAsTouched();\r\n });\r\n return;\r\n }\r\n this.saveChangesToPostModel();\r\n this.router.navigate([\"dorpel\"], { relativeTo: this.activatedRoute });\r\n }\r\n\r\n public onEditDorpel(dorpel: BestellingDorpelDto): void {\r\n if (!this.validateForm()) {\r\n return;\r\n }\r\n\r\n this.saveChangesToPostModel();\r\n this.router.navigate([\"dorpel\"], {\r\n queryParams: { dorpelGuid: dorpel.guid },\r\n relativeTo: this.activatedRoute,\r\n });\r\n }\r\n\r\n public onDorpelBestellenButtonClicked() {\r\n if (!this.validateForm()) {\r\n return;\r\n }\r\n\r\n this.posted = true;\r\n if (this.cartItems.length < 1) {\r\n return;\r\n }\r\n\r\n this.model.dorpels.forEach((dorpel) => {\r\n if (!dorpel.drawing) {\r\n this.addOffscreenDrawing(dorpel);\r\n }\r\n });\r\n this.model.logoImageData = logoBase64;\r\n\r\n this.saveChangesToPostModel();\r\n this.router.navigate([\"overzicht\"], { relativeTo: this.activatedRoute });\r\n }\r\n\r\n public onDealerChanged(): void {\r\n this.model.dealerCode = this.formGroup.get(\"dealerCode\").value;\r\n this.preserveWelkomFormValues([\"dealerCode\"]);\r\n }\r\n\r\n private addOffscreenDrawing(dorpel: BestellingDorpelDto): void {\r\n let offscreenCanvas = document.createElement(\"canvas\");\r\n offscreenCanvas.width = dorpel.zaagmaat;\r\n offscreenCanvas.height = 260;\r\n offscreenCanvas.id = \"offscreenCanvas\";\r\n this.graphics.initializeDrawing(\"offscreenCanvas\", dorpel.zaagmaat);\r\n this.graphics.drawDorpel(dorpel, offscreenCanvas); //draw at scale 1 for correct fit\r\n\r\n let imageData = offscreenCanvas.toDataURL(\"image/png\");\r\n dorpel.drawing = imageData;\r\n }\r\n\r\n private getDummyJsonModel(): BestellingDto {\r\n const json =\r\n '{\"dorpels\":[{\"guid\":\"b2bdcf82-7d97-5113-acbc-cdef3248eced\",\"aantal\":2,\"aantalNeuten\":2,\"aantalSluitpotten\":2,\"dorpelCode\":\"BI.5757.B\",\"merk\":\"rega\",\"zaagmaat\":500,\"neuten\":[{\"daagmaat\":0,\"neutCode\":\"N5757.L67.B\",\"positie\":\"Links\",\"sponningmaat\":\"53mm\",\"sponningsoort\":\"Sponning\"},{\"daagmaat\":0,\"neutCode\":\"N5757.R67.B\",\"positie\":\"Rechts\",\"sponningmaat\":\"53mm\",\"sponningsoort\":\"Sponning\"}],\"maatA\":0,\"maatZ\":0,\"sluitpotten\":[{\"maat\":0,\"sluitpotCode\":\"SPB.BI\"},{\"maat\":333,\"sluitpotCode\":\"SPB.BI.HMB\"}],\"bewerkingen\":[{\"bewerkingCode\":\"9200\"},{\"bewerkingCode\":\"9201\"}]},{\"guid\":\"b2bdcf82-7d97-5113-acbc-cdef3248e999\",\"aantal\":2,\"aantalNeuten\":2,\"aantalSluitpotten\":2,\"dorpelCode\":\"BI.5757.B\",\"merk\":\"SSAA\",\"zaagmaat\":500,\"neuten\":[{\"daagmaat\":0,\"neutCode\":\"N5757.L67.B\",\"positie\":\"Links\",\"sponningmaat\":\"53mm\",\"sponningsoort\":\"Sponning\"},{\"daagmaat\":0,\"neutCode\":\"N5757.R67.B\",\"positie\":\"Rechts\",\"sponningmaat\":\"53mm\",\"sponningsoort\":\"Sponning\"}],\"maatA\":0,\"maatZ\":0,\"sluitpotten\":[{\"maat\":0,\"sluitpotCode\":\"SPB.BI\"},{\"maat\":333,\"sluitpotCode\":\"SPB.BI.HMB\"}],\"bewerkingen\":[{\"bewerkingCode\":\"9200\"},{\"bewerkingCode\":\"9201\"}]}],\"opdrachtgever\":\"Andrei Ciobanu\",\"contactpersoon\":\"Andrei Ciobanu\",\"telefoonnummer\":\"0755638595\",\"emailadres\":\"bliulinx@gmail.com\",\"uwReferentie\":\"asdasd\",\"dealerCode\":\"CODE\",\"opmerkingen\":\"asdasd\",\"bijlage\":\"file.jpg\"}';\r\n return <BestellingDto>JSON.parse(json);\r\n }\r\n\r\n public get cartItems(): BestellingDorpelDto[] {\r\n return this.dataStateService.getModel().dorpels;\r\n }\r\n\r\n public onDeleteDorpel(dorpel: BestellingDorpelDto): void {\r\n const index = this.model.dorpels.findIndex((d) => d.guid === dorpel.guid);\r\n this.model.dorpels.splice(index, 1);\r\n }\r\n\r\n onPanelChanged($event: NgbPanelChangeEvent, acc) {}\r\n\r\n async onPrefilledOrderformFileSelected(event) {\r\n if (event.target.files.length > 0) {\r\n this.prefilledOrderErrorMessage = null;\r\n\r\n this.spinner.show();\r\n const file = event.target.files[0];\r\n this.model.prefilledOrderformFile = file;\r\n this.getPrefilledOrderform(file)\r\n .pipe(\r\n catchError((err: any) => {\r\n this.spinner.hide();\r\n if (err.error.indexOf(\"WrongFileStructureException\") >= 0) {\r\n this.prefilledOrderErrorMessage = WRONG_FILE_STRUCTURE_ERROR;\r\n }\r\n return throwError(err);\r\n })\r\n )\r\n .subscribe((result: ProcessingResponse) => {\r\n this.uiState.fromPrefilledOrder = true;\r\n result.order.id = Guid.create().toString();\r\n result.order.dorpels.forEach(\r\n (d) => (d.guid = Guid.create().toString())\r\n );\r\n result.order.prefilledOrderformFile = file;\r\n // this.populatePreservedWelkomFormValues(PRESERVED_FORM_FIELDS); TODO: check if import overrides\r\n this.overrideWelkomFormValues(result.order);\r\n this.dataStateService.setModel(result.order);\r\n this.updateFormData();\r\n this.uiState.setNeutenChoices(result.neuten);\r\n this.spinner.hide();\r\n });\r\n }\r\n }\r\n\r\n private preserveWelkomFormValues(fieldNameList: string[]): void {\r\n fieldNameList.map((fieldName: string) => {\r\n let fieldValue: string = this.formGroup.get(fieldName).value;\r\n let lsKey: string = `welkomformvalue_${fieldName}`;\r\n\r\n if (fieldValue) {\r\n localStorage.setItem(lsKey, fieldValue);\r\n }\r\n });\r\n }\r\n\r\n private populatePreservedWelkomFormValues(fieldNameList: string[]): void {\r\n fieldNameList.map((fieldName: string) => {\r\n let lsKey: string = `welkomformvalue_${fieldName}`;\r\n let previouslySavedValue = localStorage.getItem(lsKey);\r\n\r\n if (previouslySavedValue) {\r\n this.model[fieldName] = previouslySavedValue;\r\n }\r\n });\r\n }\r\n\r\n private overrideWelkomFormValues(fileProcessingResultOrder): void {\r\n fileProcessingResultOrder.opdrachtgever =\r\n this.formGroup.get(\"opdrachtgever\").value ||\r\n fileProcessingResultOrder.opdrachtgever;\r\n fileProcessingResultOrder.contactpersoon =\r\n this.formGroup.get(\"contactpersoon\").value ||\r\n fileProcessingResultOrder.contactpersoon;\r\n fileProcessingResultOrder.telefoonnummer =\r\n this.formGroup.get(\"telefoonnummer\").value ||\r\n fileProcessingResultOrder.telefoonnummer;\r\n fileProcessingResultOrder.emailadres =\r\n this.formGroup.get(\"emailadres\").value ||\r\n fileProcessingResultOrder.emailadres;\r\n fileProcessingResultOrder.uwReferentie =\r\n this.formGroup.get(\"uwReferentie\").value ||\r\n fileProcessingResultOrder.uwReferentie;\r\n fileProcessingResultOrder.dealerCode =\r\n this.formGroup.get(\"dealerCode\").value ||\r\n fileProcessingResultOrder.dealerCode;\r\n }\r\n\r\n private getPrefilledOrderform(file: any): Observable<any> {\r\n const formData = new FormData();\r\n formData.append(\"file\", file);\r\n return this.backend.postPrefilledOrderform(formData);\r\n }\r\n\r\n private saveChangesToPostModel() {\r\n const postModel = this.model;\r\n const form = this.formGroup.value;\r\n\r\n postModel.opdrachtgever = form.opdrachtgever;\r\n postModel.contactpersoon = form.contactpersoon;\r\n postModel.telefoonnummer = form.telefoonnummer;\r\n postModel.emailadres = form.emailadres;\r\n postModel.uwReferentie = form.uwReferentie;\r\n postModel.dealerCode = form.dealerCode;\r\n postModel.afleverdatum = form.afleverdatum;\r\n postModel.opmerkingen = form.opmerkingen;\r\n postModel.bijlage = form.bijlage.map((value) => {\r\n return value[0].name || \"\";\r\n });\r\n\r\n this.preserveWelkomFormValues(PRESERVED_FORM_FIELDS);\r\n }\r\n\r\n private buildForm(): FormGroup {\r\n const postModel = this.model;\r\n const formGroup = this.formBuilder.group({\r\n opdrachtgever: [postModel.opdrachtgever || \"\", []],\r\n contactpersoon: [postModel.contactpersoon || \"\", [Validators.required]],\r\n telefoonnummer: [\r\n postModel.telefoonnummer || \"\",\r\n [Validators.maxLength(10), Validators.minLength(10)],\r\n ],\r\n emailadres: [\r\n postModel.emailadres || \"\",\r\n [Validators.required, Validators.email],\r\n ],\r\n uwReferentie: [postModel.uwReferentie || \"\"],\r\n dealerCode: [postModel.dealerCode || \"\", [Validators.required]],\r\n afleverdatum: [\r\n formatDate(postModel.afleverdatum || new Date(), \"yyyy-MM-dd\", \"en\"),\r\n [],\r\n ],\r\n opmerkingen: [postModel.opmerkingen || \"\"],\r\n bijlage: this.buildBijlageFormArray(postModel.bijlage),\r\n prefilledOrderformFile: [postModel.prefilledOrderformFile],\r\n });\r\n\r\n return formGroup;\r\n }\r\n\r\n public buildBijlageFormArray(fileNames?: string[]): FormArray {\r\n if (!fileNames || !fileNames.length) {\r\n return this.formBuilder.array([\r\n // this.formBuilder.control([\"\", [FileFormatValidator.validate]])\r\n ]);\r\n }\r\n\r\n let controls: FormControl[] = [];\r\n\r\n fileNames.forEach((name) => {\r\n controls.push(\r\n this.formBuilder.control([name || \"\", [FileFormatValidator.validate]])\r\n );\r\n });\r\n\r\n return this.formBuilder.array(controls);\r\n }\r\n\r\n private validateForm() {\r\n if (!this.formGroup.valid && !environment.disableFieldValidation) {\r\n Object.keys(this.formGroup.controls).forEach((field) => {\r\n const control = this.formGroup.get(field);\r\n control.markAsTouched();\r\n });\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n}\r\n\r\nconst ValidationMessages = {\r\n opdrachtgever: {\r\n required: \"Opdrachtgever is een verplicht veld\",\r\n },\r\n contactpersoon: {\r\n required: \"Contactpersoon is een verplicht veld\",\r\n },\r\n emailadres: {\r\n required: \"E-mailadres is een verplicht veld.\",\r\n emailadres: \"Dit is geen geldig email adres.\",\r\n },\r\n telefoonnummer: {\r\n required: \"Telefoonnummer is een verplicht veld\",\r\n maxlength: \"Het telefoonnummer moet uit 10 getallen bestaan.\",\r\n minlength: \"Het telefoonnummer moet uit 10 getallen bestaan.\",\r\n },\r\n dealerCode: {\r\n required: \"Dealer is een verplicht veld.\",\r\n },\r\n bijlage: {\r\n acceptedFile:\r\n \"Dit is geen ondersteund bestandstype. Geaccepteerde bestandstypen: *.pdf, *.txt, *.doc, *.docx\",\r\n },\r\n};\r\n","export const logoBase64 = \"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/4SjaRXhpZgAASUkqAAgAAAAHABIBAwABAAAAAQAAABoBBQABAAAAYgAAABsBBQABAAAAagAAACgBAwABAAAAAgAAADEBAgANAAAAcgAAADIBAgAUAAAAgAAAAGmHBAABAAAAlAAAAKYAAABgAAAAAQAAAGAAAAABAAAAR0lNUCAyLjEwLjMyAAAyMDI0OjExOjA3IDE1OjA1OjMxAAEAAaADAAEAAAABAAAAAAAAAAkA/gAEAAEAAAABAAAAAAEEAAEAAAAAAQAAAQEEAAEAAAAAAQAAAgEDAAMAAAAYAQAAAwEDAAEAAAAGAAAABgEDAAEAAAAGAAAAFQEDAAEAAAADAAAAAQIEAAEAAAAeAQAAAgIEAAEAAAC0JwAAAAAAAAgACAAIAP/Y/+AAEEpGSUYAAQEAAAEAAQAA/9sAQwAIBgYHBgUIBwcHCQkICgwUDQwLCwwZEhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQy/9sAQwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgBAAEAAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A65yd34U3JqR1G6sbxDqEmmWSSxsVJlC8AHsT3+lOEHOXKgqTVOLlLY1cmjJrhf8AhLLr/ntJ/wB+0o/4Sy6/57Sf9+0rr+oVTj/tKh3O6yaMmuHj8VXTyBfOfn/pmtdbpM7XmmQ3Ehyz7skjHRiO30rGrhp0leRtRxVOs7QLWTS5NVtUma106WZDhlxggZ6kCuSm8UXUUrJ5z8f9M1oo4adVXiFbFU6LtM7bJoya4X/hLLr/AJ7Sf9+0o/4Sy6/57Sf9+0rb6hVMP7SodzusmjJrhf8AhLLr/ntJ/wB+0o/4Sy6/57Sf9+0o+oVQ/tKh3O6yaMmuF/4Sy6/57Sf9+0o/4Sy6/wCe0n/ftKPqFUP7SodzusmjJrhf+Esuv+e0n/ftKP8AhLLr/ntJ/wB+0o+oVQ/tKh3O6yaMmuF/4Sy6/wCe0n/ftKP+Esuv+e0n/ftKPqFUP7SodzusmjJrhf8AhLLr/ntJ/wB+0o/4Sy6/57Sf9+0o+oVQ/tKh3O6yaMmuF/4Sy6/57Sf9+0o/4Sy6/wCe0n/ftKPqFUP7SodzusmjJrhf+Esuv+e0n/ftKP8AhLLr/ntJ/wB+0o+oVQ/tKh3O6yaMmuF/4Sy6/wCe0n/ftKP+Esuv+e0n/ftKPqFUP7SodzusmjJrhf8AhLLr/ntJ/wB+0o/4Sy6/57Sf9+0o+oVQ/tKh3O6yaMmuF/4Sy6/57Sf9+0o/4Sy6/wCe0n/ftKPqFUP7SodzusmgE5rn9C1ebUZlWR2YFiOVA6LntXRhOa5atOVOXLI66VWNWPNHYndfmrlvHAxpEX/Xwv8A6C1dc681ynjoY0eL/r4X/wBBatcL/FiY43+BI8+ooor6I+VJIP8AXL+P8q9N8Nrnw/a/8D/9DNeZQf65fx/lXqPhlc+HrX/gf/oZrzcx+Bf13PYyr4n/AF2G6+v/ABJLg/7v/oQrzO8/4+3/AA/lXqPiFcaFc/8AAf8A0IV5fe/8fb/h/Kllvwv+uxWbbr+u5p2XhLXNQhMtrY+YgbaT5qDnr3b3FUtR0e+0qVo72DynUgEb1bkjI6E9q9x8C2kD6JMWTJ+0t3P91a4L4nwxxarcbFx+9j7/APTOrpYuU6vI0Y18DCnR9omzkNM0DU9YTfY23mjcU/1iryBnuR2NO1Pw5qujwia/tfJjLhAfMVuSCccE9ga9C+FNvFLYsXXJ+1OOp/55rVr4t20UOgQNGuD9sQdT/wA83pvFS9v7O2hKwcPq/tbu557B4L8QXCF4tP3KDgnzoxz/AN9Vl6hpt3pdy9veQ+VKhAZdwbGRkdCe1e3eALq31jRJpWjckXLJ83HRVPY+9cf8UdJitbqS9jRR5k8afeJP+r/+tSpYubq+zmh1sFCNH2kH/X3HAWGm3ep3SW1nF5sz52ruC5wMnkn0Falx4M1+1jEk1htUnAPnRnn8GrqfhfpEV1eRX0iKxjmkT7xB/wBX6dO9db8RLq30nRIXRHVjdKhK89UY9z7U6mKmqvs4oKWChKj7WbseQaZ4c1bWIDNYWvnRhyhPmKvIAOOSOxFX/wDhA/Ev/QN/8jx//FV3nwlt4ptBnaRcn7Y46n/nmldR4g13SfDsQku7a4cGQR/ucHkgnuw9KirjKkarhFL+vmaUcDSlSVSTa/r0PGJPA/iOKMu+nYUdT58f/wAVWRNp11b3j2ksW2dACy7gcZAPXOO4r1i8+I3hya1eNLHUAxxglF9f9+uAury31PxPd3VujrDIi7VfgjAUdie4rWlWqyvzxsY1sPRjZQle/wDXYX/hA/Ev/QN/8jx//FVQ1Pw5q2jwCa/tPJjZwgPmI3JBOOCewNfSLWVqoyYuP94/41yPj7QoNQ0OARRqrfaVbLuw42sK56eYSckpJW/rzOmrlkFBuLd/68jwy3t5bqdYIV3SNnAyBnAz3rag8FeIbmFZYdP3I3Q+dGPbu1TeBdPF/wCK7KNwpjJkBBJHSNj2r3ey0y1tbRIfK+7noxPU59a2xWLdKXLE58Hgo1oc0rnzxqPhvVtJjL3tp5SgAk+YjcE4HQnvWVXsXxQtootOnKJg+TH3P/PSvHa3w1V1YczOfF0I0anLE09M8P6prEZksLXzlDFM+Yq8gZ7kdjV2bwV4hgQNLp+1ScZ86M8/99V6l8P9Ch07Q5nuER3FyxBR26FVHtXVy2FleRBTCcA55Yj+RriqY+UZtRWh308tg4Jybv8A15HzFRV7VNPfTblYZChLIH+QkjqR3+lUa9RNSV0eRKLi7M6zwcMzp/10b/0Cu6C1w/gsZnT/AK6N/wCgV3oWvCx38Zn0uX/wETuvNcj49GNFh/6+V/8AQWrs2TmuP+IK40WH/r5X/wBAas8L/FiXjf4Ejziiiivoj5Ult/8AXr+P8q9U8LjPhy0/4H/6G1eV23+vX8f5V6x4WXPhu0/4H/6G1ebmPwL+u57GVfE/67CeIl/4kNz/AMB/9CFeV33/AB+Sfh/IV6x4kXGgXP8AwD/0IV5Pff8AH5J+H8hSy74X/XYrNt1/Xc998Bf8gOf/AK+W/wDQVrz/AOKn/IWuP+u0f/oqu2+Gt6t3oE7KG/4+2HIH9xKwviVoE95K9zE8IDzp95jniMj09q56L5cR7x01054b3Rvwk/48G/6+pP8A0WtWfjB/yL0H/X6n/ot6t/DTRLjTNMk894mb7S7ZQk8FFHcCs/4uzq2kRw4O5bxD7f6tv8apNSxd13MnFxwVpdjF+Furpb6lBprMoMs0j42nP+r9en8Ndp8RtL/tbQIFjDsftSt8pA6I4715D4RvTYeKLO4yfk3/AHQCeUYd/rXu1qBrvh+2lYZDOW+fjoWHani17OspoWCkqtB02Yvw60z+yfD9wJN6n7UzfMQeqIO1cP8AE/V1uNZudPUoRFLG/CnP+rHfp/FXpt+V8P8Ahi7lUEbXVvk+bqyjvXhXii+/tHxFdXXzfvNn3gAeEUdvpTwcfaVnUYsdL2VBU4/1uem/CD/kXp/+v1//AEWldV4g0PTdXj23088Y8wN+6I6gEd1PY1yvwg/5F6f/AK/X/wDRaVpeOp9WigH9mXUcD+cuS6g/LsORyD3xWNVN4hpOxvQklhU2rmXq3gzw/b6bNLFe3pdduAxGOo/2K88a3itPEV1BAzNGsYwW68hTWzc3HiyaBkm1S3ZDjI8tR3/3KwoRcLrU4unV5vLG5l6H7uOw7V20YyineVzirTjKUbRtqe/eI7g2mhXM4xldvUccsBVfQ5V1PQrYucMSzEKMdGI707xfz4XvP+Af+hrWF4H1LzLg6d837qFn6DH3x36/xV5ajem2es5WqWfYo/Dnw/Jp8BnmR0ZLh+C6kYKAdq6GDVUm8Z32mhlLQwhyNpz0Tv0/irQuUh0TSZpIUKKrBsKdxySB3rhvDN6198VtXlydrWQIBAB48odq01quU32MXaiowXcm+Kf/ACDZ/wDrjH/6MryrRtLfV7x7eNWYrGXwrAdwO/1r1X4p/wDINn/64x/+jK574XaKbjVJLqXy2ie1cAbiDkOo/oa7cPU9nhnI4cTS9pi1HyPS/ETHT/Dd2YfmcFCA/u6isnwbqM13eNHMqKRCzfKD/eHv71vazc2Gw2l9BJKjqGIXjjPHOQeorP02XQ7GdpLOznikKFSSxPGR6sfQV5yfuNNHqNe8nc4H4p6K6X636K5iitUUsWGATIw6de4rzSvoH4haUL/wxeMgQShY1VmYjH7xT2rwW8tXs7p7dypZMZKnjkZ/rXrYGpzU+V9DxMxo8lTmWzOq8EDM6f8AXR//AECvQAvNcD4GGbhP+ur/APoFehhK8/Hfxmetl38BEzrzXG/ENcaHD/19L/6A1dwy81xfxGXGhQf9fS/+gNUYT+NEvGfwJHmNFFFfQnypLbf8fC/j/KvXPCi58M2f/A//AENq8ktf+PhPx/lXsHhJc+GLM/7/AP6G1ebmPwL+u57GVbv+uwniVceHrr/gH/oYryO//wCP2T8P5CvYPE6/8U7df8A/9DWvH9Q/4/pPw/kKWXfC/wCuw816f13Nfwz4nufD11GYkgKB2cmRWPJXHYivRrD4p2bQKbye3jkwchYJcDnj17V4zRXVVwtOq7yOGjjatKPLHY9e1X4pQi1cWEttLJgYDwyDJzz6dq8213XLjXNQlup0iVpCpPlqQOFA7k+lZVFOlhqdLWIq2Lq1laQoODmvSfCXj2DRdDtrGaWFPKD/AHonY8uT1HHevNaKurRjVVpEUK86MuaJ6L4w8dQa3pE9lDJC4lVB8sTqchw3f6V51RRRSpRpR5YirV5Vpc0jvfA3jC38O6ZJbzSxIWuGkw8btwVUdvpXWf8AC07D/n5t/wDvxLXi1FZVMHSnLmdzenj6tOKjG1key3HxPsZYGQXEBzj/AJYSetedavrUd74mu9QVlKSqoBCkDhVHQ89qwKSnTwtOm24iq42rUtzdD1nW/iNZ6ho89qk8BZ9uAIZB0YHv9K5HQfEqaV4lutR3RhZYPLBZGI6r2HP8NcrzRRDCU4JxXUJ42rOSk+h6Z4p+IUGraFc2UEsDtKEwBFIDw4PU8dq5vwZ4ij0LXZ76d40EluYssjMM7lPQc/w1y2KWnHDQjBwWzFLF1JTU30O98ZeMbbXrSSKKWJt0aL8sbr0fPerXhDxtZaFoltbSTxrIiuCrRO2MuT2rzelpfVafJ7PoP67U9p7Trsb3i7XBr+qxXQMZ2QCP5FKjhmPf61iRStC5ZQCSMc1HRitowUY8q2OedSUp873PYX+JllPavFJcQDcf4YZPavNPEt/Fqev3N3C4eOTZggEZwgHQ89qyuaSsqWGhSd4m1bF1K0eWR2vgMZuE/wCur/8AoFejBa888ADNxH/11f8A9Ar0kLXk47+Mz3Mv/gImZOa4n4kjGgwf9fa/+gPXeMvNcP8AExceH4P+vtf/AEB6zwv8aJpjP4Mjyqiiivoj5Umtf+PlPx/lXsnhBc+FrP8A4H/6G1eN2v8Ax8p+P8q9p8HL/wAUpZf8D/8AQ2rzcx+Ff13PYyrd/wBdhPFK48OXf/AP/Q1rxrUP+P6T8P5CvafFa/8AFNXf/AP/AENa8X1H/j/k/D+QpZd8L/rsPNen9dyrRRRXpnjBRRRQAUUUUAFFFFAHQeC4Vn8UWaMSAd/T/cavWRpcOPvSfmP8K8q8CDPi2x+sn/otq9mVeK8bMJNVFb+tz6DLEnSfr/kZ/wDZcP8Aek/Mf4Uf2XD/AHpPzH+FXZZViOGBPGeKi+1xf3W/KuG8j0bRK/8AZcP96T8x/hR/ZcP96T8x/hVj7XF/db8qPtcX91vyo98PcK/9lw/3pPzH+FH9lw/3pPzH+FWPtcX91vyo+1xf3W/Kj3w9wr/2XD/ek/Mf4Uf2XD/ek/Mf4VY+1xf3W/Kj7XF/db8qPfD3Cv8A2XD/AHpPzH+FH9lw/wB6T8x/hVj7XF/db8qPtcX91vyo98PcK/8AZcP96T8x/hR/ZcP96T8x/hVj7XF/db8qPtcX91vyo98PdI4bFIWBUscepFWAnNJHOkrBVDZPrU4Xmpd+pSt0JmXmuF+J4x4eg/6+1/8AQHrvmXmuD+KIx4dt/wDr8T/0B66ML/Gic2M/gyPJaKKK+hPlSa0/4+U/H+Ve2eDB/wAUnZf9tP8A0Y1eJ2n/AB9J+P8AKvcPBa/8UjYn/rp/6MavNzH4V/Xc9jK93/XYXxYP+KZvP+Af+hrXiWpf8f8AL+H8hXuPi1f+KYvP+Af+hrXh+pf8hCX8P5Cpy7Z/12HmvT+u5Uooor1DxgooooAKKKKACiiigDpvAX/I32A95P8A0W1e1Kvy14t4A58Y2H1k/wDRbV7Yq/LXi5j/ABF6f5n0OV/wn6/5HK+KOH/7Zr/6Ea5fdXUeLflf/tkv/oRrk91VQXuBiH+8JN1G6o91G6trGHMSbqN1R7qN1Fg5iTdRuqPdRuosHMSbqN1R7qN1Fg5iTdRuqPdRuosHMdF4aOb2P/eb/wBBrsgtcZ4W5vov95v/AEGu3C815+IXvnpYb4CZl5rgfioMeHLf/r8T/wBAevQmXmuA+K4/4pu3/wCvxP8A0B6eF/ixIxn8GR4/RRRX0J8sT2f/AB9J+P8AKvdPBIz4PsP+2n/oxq8Ls/8Aj6T8f5V7v4HGfB1h/wBtP/RjV5uY/Cv67nsZXu/67B4vXHhe8/4B/wChrXhmp/8AIQl/D+Qr3fxguPCt7/wD/wBDWvCNU/5CMv4fyFLLtn/XYea9P67lSiiivTPGCiiigAooooAKKKKAOo+Hwz4z0/6yf+i2r3FV+WvD/h4M+NNP+sv/AKLavdFXivFzD+IvT/M+hyv+C/X/ACOM8ZcN/wBsl/8AQjXG7q7Lxt8rH/riv/oZriN1a4ZfuzPFP94yXdRuqLfRvrexzXJd1G6ot9G+iwXJd1G6ot9G+iwXJd1G6ot9G+iwXJd1G6ot9G6iwXOq8I/Nfxf77f8AoFd8F5rgPBnN/F/vv/6BXoYXmvMxK/eHrYX+GSlea8++LIx4bt/+v1P/AEB69EI5rzz4tjHhq3/6/U/9FvRhf4sRYz+DI8booor6E+WJ7P8A4+0/H+Ve9+Bh/wAUbYf9tP8A0Y1eCWf/AB9p+P8AKvffAgz4MsP+2n/oxq8zMdl/Xc9jK93/AF2HeMRjwpe/8A/9DWvBdU/5CMv4fyFe++Mx/wAUne/9s/8A0Na8C1X/AJCUv4fyFLLtn/XYrNen9dynRRRXqHihRRRQAUUUUAFFFFAHV/Dr/kdtP+sv/opq93Vflrwj4c/8jvp31l/9FNXvSj5RXi5h/FXp/mfQ5Z/B+f8AkcJ484Y/9cU/9DNcDvrvfiD8pP8A1xT/ANDNed7zXRhFemcmNlaqT76N9QbzRvNdNjk5yffRvqDeaN5osHOT76N9QbzRvNFg5yffRvqDeaN5osHOT76N9QbzRvNFg5ztfA5zqEP/AF0f/wBAr0oLzXmfgI7tQh/66P8A+gV6eBzXkYv+Ie5gnekiSvO/i6P+KZt/+v1P/Rb16NivOvi8MeGbf/r9T/0W9LC/xYlYz+DI8Xooor6E+WJ7P/j7T8f5V9AeAh/xRen/APbT/wBGNXz/AGX/AB9p+P8AKvoLwEP+KK0//tp/6MavMzHZf13PYyvd/wBdh/jT/kUr7/tn/wCjFr5/1X/kJS/h/IV9BeNR/wAUjff9s/8A0YtfPuq/8hKX8P5Cll2z/rsVmvT+u5Tooor1DxQooooAKKKKACiiigDrfhv/AMjvp31l/wDRTV74o+UV4H8N/wDkeNO+sv8A6KavfkHyivFzD+KvQ+hyz+D8/wDI88+I5xu/64J/6Ga818yvSfiXxu/64J/6MNeYbq68F/CPOzF2rEvmUeZUO6jdXXY4eYm8yjzKh3UbqLBzE3mUeZUO6jdRYOYm8yjzKh3UbqLBzE3mUeZUO6jdRYOY774eNu1KH/rq/wD6Lr1YCvJ/hwc6lB/11k/9F160BXi43+Kz6PL/AOAh9ecfGD/kWbf/AK/k/wDRb16NmvOfi/8A8izbf9fqf+i3qML/ABYmmM/gyPFqKKK+hPliez/4+0/H+VfQfgD/AJErT/8Atp/6Mavnyy/4+0/H+VfQfgE48Faf/wBtP/RjV5mY7L+u57GV7v8ArsS+Nh/xSF9/2z/9GLXz5qv/ACEpfw/kK+jvEWny6roVzZQMiySbcFyQOGB7A+leYXfwp1m5unlFzp+Gx1kfPTH9yssFWhTT5mb5hQnVtyr+tTzSivRP+FRa1/z86d/39k/+Io/4VFrX/Pzp3/f2T/4iu/63R7nmfUa3Y87or0T/AIVFrX/Pzp3/AH9k/wDiKP8AhUWtf8/Onf8Af2T/AOIo+t0e4fUa3Y87or0T/hUWtf8APzp3/f2T/wCIoPwj1r/n507/AL+yf/EUfW6PcX1Gt2PO6K09c0WfQ71LW4eJnaMSAxkkYJI7gelZldEZKSujmlFxfK9zrfht/wAjxp31l/8ARTV9AoPkFfP3w2/5HjTvrL/6KavoBD8grxsw/ir0Pfyz+D8/8jzj4oHAb/r3j/8ARhryndXqnxSPyt/17x/+jDXk+6u7A/wjy8zf7/5Em+jfUW6jdXYedcl30b6i3UbqAuS76N9RbqN1AXJd9G+ot1G6gLku+jfUW6l3UWC56J8MznUoP+usn/ouvYK8c+GJ/wCJlB/12k/9F17FmvBxv8Zn1GXf7uiLIrzv4unPhq3/AOv1P/Rb135avPfi0c+G7f8A6/U/9Aeowv8AFia4z+DI8cooor6E+WJ7L/j7T8f5V9AeA2/4ovT/APtp/wCjGr57icxyBx1FdlpHxAvNK0uGyjnmVIt2AsUZHLE9Tz3rixlGVVLlPSwGIhSb5/62Pddwo3CvF/8AhaF//wA/M/8A34io/wCFoX//AD8z/wDfiKvP+o1ex6f9oUO57RuFG4V4v/wtC/8A+fmf/vxFR/wtC/8A+fmf/vxFR9Rq9h/2hQ7ntG4UbhXi/wDwtC//AOfmf/vxFR/wtC//AOfmf/vxFR9Rq9g/tCh3PaNwo3CvF/8AhaF//wA/M/8A34io/wCFoX//AD8z/wDfiKl9Rq9hf2hQ7mb8RznxDb/9ei/+hvXH1pa3q0us3qXErszLGEyygcAk9vrWbXs0YuNNRZ4FeSnUckdZ8OP+R3076y/+imr3xWG0V4F8Ojjxtp31l/8ARTV7wrcV5WYfxV6f5nt5Z/B+f+R538UT8j/9cI//AEYa8ozXqnxPb92//XCP/wBGGvKMmu7A/wAI8vM1+/H5ozTMmjJrsPPsPzRmmZNGTQFh+aM0zJoyaAsPzRmmZNGTQFh+aM0zJoyaAsei/DE/8TGH/rtJ/wCi69gDV438MmxqEP8A12k/9F16+G5rwcd/GZ9Pl38BELNzXE/EqxutS0GCG1i8xxdKxG4DjY47n3rsGfmoLiCG7QJOm5Qc4yRz+FYUp8k1LsddWn7SDg+p4L/wi2s/8+f/AJFT/Gj/AIRbWf8Anz/8ip/jXuP9k6f/AM+//j7f40f2Rp//AD7/APj7f413f2jLt/X3nmf2VDv/AF9x4d/wi2s/8+f/AJFT/Gj/AIRbWf8Anz/8ip/jXuP9kaf/AM+//j7f40f2Rp//AD7/APj7f40f2jLt/X3h/ZUO/wDX3Hh3/CLaz/z5/wDkVP8AGj/hFtZ/58//ACKn+Ne4/wBkaf8A8+//AI+3+NH9k6f/AM+//j7f40f2jLt/X3h/ZUO/9fceHf8ACLaz/wA+f/kVP8aP+EW1n/nz/wDIqf417j/ZGn/8+/8A4+3+NH9kaf8A8+//AI+3+NP+0Zdv6+8P7Kh3/r7jw7/hFtZ/58//ACKn+NH/AAi2s/8APn/5FT/Gvcf7I0//AJ9//H2/xo/sjT/+ff8A8fb/ABpf2jLt/X3h/ZUO/wDX3Hh3/CLaz/z5/wDkVP8AGj/hFtZ/58//ACKn+Ne4/wBk6f8A8+//AI+3+NH9kaf/AM+//j7f40/7Rl2/r7w/sqHf+vuPDv8AhFtZ/wCfP/yKn+NH/CLaz/z5/wDkVP8AGvcf7I0//n3/APH2/wAaP7I0/wD59/8Ax9v8aX9oy7f194f2VDv/AF9x5j4G0LUrHxbYz3FtsjXzMtvU4zGw7GvYlbis6HT7O3mWWKHa69DuJ/rVzfXJXrOtLmZ34bDqhDlRxHxCsLq/DLbRbyYUH3gOQ5Pc15z/AMIxrH/Pn/5FT/Gvdbi1t7o5mj3HGOpH8qg/smw/54f+Pt/jW1HGOlHlSObEYCNafO3/AF9x4h/wi+sf8+f/AJFT/Gj/AIRjWP8Anz/8ip/jXt/9k2H/ADw/8fb/ABo/sjT/APnh/wCPt/jW39oy7f195h/ZMO7/AK+R4h/wi+s/8+f/AJFT/Gj/AIRfWP8Anz/8ip/jXt/9k2H/ADw/8fb/ABo/smw/54f+Pt/jR/aMu39feH9kw7v+vkeIf8IvrP8Az5/+RU/xo/4RfWf+fP8A8ip/jXt/9k2H/PD/AMfb/Gj+ybD/AJ4f+Pt/jR/aMu39feH9kw7v+vkeIf8ACMax/wA+f/kVP8aP+EX1n/nz/wDIqf417f8A2Rp//Pv/AOPt/jR/ZNh/zw/8fb/Gj+0Zdv6+8P7Jh3f9fI8Q/wCEX1j/AJ8//Iqf40f8IvrH/Pn/AORU/wAa9v8A7JsP+eH/AI+3+NH9k6f/AM+//j7f40f2jLt/X3h/ZMO/9fccN4A0q+sL+I3MGwCRz99TwUx2NenhuazoLK1tnDRRbWHQ7if61bD81xVqvtZ8x6OHoqjDkRAz81mavrlpotss95MIkZwgJRm5IJ7D2NXGfmuG+JbZ0KH/AK+1/wDQHpUIKdRRY8RUdOm5Loan/CwtC/5/1/78Sf4Uf8LC0L/n/X/vxJ/hXjPFHFet/Z9Lu/6+R4n9qVuy/H/M9m/4WFoX/P8Ar/34k/wo/wCFhaF/z/r/AN+JP8K8Z4o4o/s+l3f9fIP7Urdl+P8Amezf8LC0L/n/AF/78Sf4Uf8ACwtC/wCf9f8AvxJ/hXjPFHFH9n0u7/r5B/albsvx/wAz2b/hYWhf8/6/9+JP8KP+FhaF/wA/6/8AfiT/AArxnijij+z6Xd/18g/tSt2X4/5ns3/CwtC/5/1/78Sf4Uf8LC0L/n/X/vxJ/hXjPFHFH9n0u7/r5B/albsvx/zPZv8AhYWhf8/6/wDfiT/Cj/hYWhf8/wCv/fiT/CvGeKOKP7Ppd3/XyD+1K3Zfj/mezf8ACwtC/wCf9f8AvxJ/hR/wsLQv+f8AX/vxJ/hXjPFHFH9n0u7/AK+Qf2pW7L8f8z2b/hYWhf8AP+v/AH4k/wAKP+FhaF/z/r/34k/wrxnijil/Z9Lu/wCvkH9qVuy/H/M9m/4WFoX/AD/r/wB+JP8ACj/hYWhf8/6/9+JP8K8Z4o4p/wBn0u7/AK+Qf2pW7L8f8z2b/hYWhf8AP+v/AH4k/wAKP+FhaF/z/r/34k/wrxnijij+z6Xd/wBfIP7Urdl+P+Z7N/wsLQv+f9f+/En+FH/CwtC/5/1/78Sf4V4zxRxR/Z9Lu/6+Qf2pW7L8f8z2b/hYWhf8/wCv/fiT/Cj/AIWFoX/P+v8A34k/wrxnijij+z6Xd/18g/tSt2X4/wCZ7N/wsLQv+f8AX/vxJ/hR/wALC0L/AJ/1/wC/En+FeM8UcUf2fS7v+vkH9qVuy/H/ADPZv+FhaF/z/r/34k/wo/4WFoX/AD/r/wB+JP8ACvGeKOKX9n0u7/r5B/albsvx/wAz3nSvEthq7AWlwsmWK8RsvIGe4rYD15b8OziRP+uz/wDoAr0wPXmYinGnUcYns4WrKrTU5Fdn5rifiO2dEh/6+l/9Aauvd+a4z4htnRYf+vlf/QGown8aIsb/AAJHm1FFFfRHyoUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAd38PziRf+uz/+gCvRw/NeaeAmxIv/AF1f/wBAr0QPzXgY3+Mz6fAfwEQO/Nch4+bOjxf9fK/+gtXUu5zXJeO2zpEX/Xwv/oLVGE/jRLxv8CR59RRRX0R8qFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAHaeBziRf8Arq//AKBXfh6898EnEi/9dW/9ArvA/NeDjv4zPp8v/gIgd/mrnfFdlc6hp8cVtH5jiYMRuA42kd/rW47c0w4brXNTqOnJSR01aSqQcH1POP8AhGtX/wCfT/yIn+NH/CNav/z6f+RE/wAa9G2r6UbV9K7f7Sqdl/XzPP8A7Jpd3/XyPOf+Ea1f/n0/8iJ/jR/wjWr/APPp/wCRE/xr0bavpRtX0o/tKp2X9fMP7Jpd3/XyPOf+Ea1f/n0/8iJ/jR/wjWr/APPp/wCRE/xr0bavpRtX0o/tKp2X9fMP7Jpd3/XyPOf+Ea1f/n0/8iJ/jR/wjWr/APPp/wCRE/xr0bavpRtX0o/tKp2X9fMP7Jpd3/XyPOf+Ea1f/n0/8iJ/jR/wjWr/APPp/wCRE/xr0bavpRtX0o/tKp2X9fMP7Jpd3/XyPOf+Ea1f/n0/8iJ/jR/wjWr/APPp/wCRE/xr0bavpRtX0o/tKp2X9fMP7Jpd3/XyPOf+Ea1f/n0/8iJ/jR/wjWr/APPp/wCRE/xr0bavpRtX0o/tKp2X9fMP7Jpd3/XyPOf+Ea1f/n0/8iJ/jR/wjWr/APPp/wCRE/xr0bavpRtX0o/tKp2X9fMP7Jpd3/XyPOf+Ea1f/n0/8iJ/jR/wjWr/APPp/wCRE/xr0bavpRtX0o/tKp2X9fMP7Jpd3/XyPOf+Ea1f/n0/8iJ/jR/wjWr/APPp/wCRE/xr0bavpRtX0o/tKp2X9fMP7Jpd3/XyPOf+Ea1f/n0/8iJ/jR/wjWr/APPp/wCRE/xr0bavpRtX0o/tKp2X9fMP7Jpd3/XyPOf+Ea1f/n0/8iJ/jR/wjWr/APPp/wCRE/xr0bavpRtX0o/tKp2X9fMP7Jpd3/XyPOf+Ea1f/n0/8iJ/jR/wjWr/APPp/wCRE/xr0bavpRtX0o/tKp2X9fMP7Jpd3/XyPOf+Ea1f/n0/8iJ/jR/wjWr/APPp/wCRE/xr0bavpRtX0o/tKp2X9fMP7Jpd3/XyOc8M6ZeWDqbmHZ87H7wPG3HY11gfmq4AXpTg1cdaq6suZnoUKKpQ5Ef/2f/hDM1odHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDQuNC4wLUV4aXYyIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6R0lNUD0iaHR0cDovL3d3dy5naW1wLm9yZy94bXAvIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9ImdpbXA6ZG9jaWQ6Z2ltcDo4NjNmNDczMy1lOTNmLTQ1MzMtYThjNC1hYzRjMjg4ZDdlZGQiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6N2VkNGY2YmUtZTUyZS00MWEzLTkzM2YtMDk1MTFhY2ExYmQ1IiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6OGIzMWI2YzEtZjI2Zi00YTVmLTgyNTYtM2ZjNTMyMmQyOGVlIiBkYzpGb3JtYXQ9ImltYWdlL2pwZWciIEdJTVA6QVBJPSIyLjAiIEdJTVA6UGxhdGZvcm09IldpbmRvd3MiIEdJTVA6VGltZVN0YW1wPSIxNzMwOTg0NzMyODI4MzczIiBHSU1QOlZlcnNpb249IjIuMTAuMzIiIHhtcDpDcmVhdG9yVG9vbD0iR0lNUCAyLjEwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDI0OjExOjA3VDE1OjA1OjMxKzAyOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAyNDoxMTowN1QxNTowNTozMSswMjowMCI+IDx4bXBNTTpIaXN0b3J5PiA8cmRmOlNlcT4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDpjaGFuZ2VkPSIvIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmY5ZTIzYThiLWRhNmUtNGM3Mi1iMWQzLWE3MzUyY2I5ZTg5NSIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iR2ltcCAyLjEwIChXaW5kb3dzKSIgc3RFdnQ6d2hlbj0iMjAyNC0xMS0wN1QxNTowNTozMiIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPD94cGFja2V0IGVuZD0idyI/Pv/iArBJQ0NfUFJPRklMRQABAQAAAqBsY21zBDAAAG1udHJSR0IgWFlaIAfoAAsABwANAAAAOGFjc3BNU0ZUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD21gABAAAAANMtbGNtcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADWRlc2MAAAEgAAAAQGNwcnQAAAFgAAAANnd0cHQAAAGYAAAAFGNoYWQAAAGsAAAALHJYWVoAAAHYAAAAFGJYWVoAAAHsAAAAFGdYWVoAAAIAAAAAFHJUUkMAAAIUAAAAIGdUUkMAAAIUAAAAIGJUUkMAAAIUAAAAIGNocm0AAAI0AAAAJGRtbmQAAAJYAAAAJGRtZGQAAAJ8AAAAJG1sdWMAAAAAAAAAAQAAAAxlblVTAAAAJAAAABwARwBJAE0AUAAgAGIAdQBpAGwAdAAtAGkAbgAgAHMAUgBHAEJtbHVjAAAAAAAAAAEAAAAMZW5VUwAAABoAAAAcAFAAdQBiAGwAaQBjACAARABvAG0AYQBpAG4AAFhZWiAAAAAAAAD21gABAAAAANMtc2YzMgAAAAAAAQxCAAAF3v//8yUAAAeTAAD9kP//+6H///2iAAAD3AAAwG5YWVogAAAAAAAAb6AAADj1AAADkFhZWiAAAAAAAAAknwAAD4QAALbEWFlaIAAAAAAAAGKXAAC3hwAAGNlwYXJhAAAAAAADAAAAAmZmAADypwAADVkAABPQAAAKW2Nocm0AAAAAAAMAAAAAo9cAAFR8AABMzQAAmZoAACZnAAAPXG1sdWMAAAAAAAAAAQAAAAxlblVTAAAA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\"\r\n","import { Directive, ElementRef, HostListener, Output, EventEmitter } from '@angular/core';\r\n\r\n@Directive({\r\n selector: '[resizeListener]'\r\n})\r\nexport class ResizeListener {\r\n @Output() resizeEvent = new EventEmitter<void>();\r\n\r\n constructor(private elementRef: ElementRef) {}\r\n\r\n @HostListener('window:resize', ['$event'])\r\n onResize(event: Event): void {\r\n // Emit the resize event when the window is resized\r\n this.resizeEvent.emit();\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n // Use ResizeObserver to detect changes in the size of the element\r\n const resizeObserver = new (window as any).ResizeObserver(() => {\r\n this.resizeEvent.emit();\r\n });\r\n\r\n // Start observing the element for resize changes\r\n resizeObserver.observe(this.elementRef.nativeElement);\r\n }\r\n}","<div class=\"dorpel-wrapper container-fluid\" [formGroup]=\"formGroup\" *ngIf=\"formGroup\">\r\n <div class=\"container bg-white py-4 my-4 rounded-4\">\r\n <div class=\"row align-items-start\">\r\n <div class=\"col\">\r\n <label for=\"dorpeltype\" class=\"form-label\"><b>Dorpeltype:</b></label>\r\n <div>\r\n <select class=\"form-select\" id=\"dorpeltype\" formControlName=\"dorpel\" (change)=\"setupNewConfiguration()\">\r\n <option value=\"\" disabled selected hidden>Selecteer een waarde a.u.b.</option>\r\n <option *ngFor=\"let dorpel of dorpels\" value=\"{{ dorpel.dorpelCode }}\">{{ dorpel.omschrijving }}</option>\r\n </select>\r\n <luv-validationError [show]=\"showError('dorpel')\" [errorMessage]=\"errorMessage('dorpel')\">\r\n </luv-validationError>\r\n </div>\r\n </div>\r\n <div class=\"col\" *ngIf=\"isSlidingDorpel()\" [ngStyle]=\"isDorpelConfigurationDisabled ? {'display': 'none'} : {}\">\r\n <label for=\"schema\" class=\"form-label\">Schema:</label>\r\n <div>\r\n <select class=\"form-select\" id=\"schema\" formControlName=\"schema\" (change)=\"setupNewConfiguration()\">\r\n <option value=\"\" disabled selected hidden>Selecteer een waarde a.u.b.</option>\r\n <option value=\"AL\">Schema AL</option>\r\n <option value=\"AR\">Schema AR</option>\r\n <option value=\"C+G\">Schema C+G</option>\r\n <option value=\"D\">Schema D</option>\r\n </select>\r\n <luv-validationError [show]=\"showError('schema')\" [errorMessage]=\"errorMessage('schema')\">\r\n </luv-validationError>\r\n </div>\r\n </div>\r\n <div class=\"col\">\r\n <label class=\"form-label\"><b>Aantal:</b></label>\r\n <div>\r\n <input type=\"number\" class=\"form-control\" aria-describedby=\"Aantal\" formControlName=\"aantal\" required integerOnly/>\r\n <luv-validationError [show]=\"showError('aantal')\" [errorMessage]=\"errorMessage('aantal')\">\r\n </luv-validationError>\r\n </div>\r\n </div>\r\n <div class=\"col\">\r\n <label for=\"merk\" class=\"form-label\"><b>Merk:</b></label>\r\n <input type=\"text\" class=\"form-control\" id=\"merk\" formControlName=\"merk\" />\r\n </div>\r\n <div class=\"col\">\r\n <label class=\"form-label\"><b>Zaagmaat:</b></label>\r\n <div>\r\n <div class=\"input-group\">\r\n <input type=\"number\" class=\"form-control\" aria-describedby=\"Zaagmaat\" formControlName=\"zaagmaat\"\r\n (change)=\"onZaagmaatValueChanged()\" integerOnly/>\r\n <span class=\"input-group-text\">mm</span>\r\n </div>\r\n <luv-validationError [show]=\"showError('zaagmaat')\" [errorMessage]=\"errorMessage('zaagmaat')\">\r\n <span *ngIf=\"zaagmaatTargetValue\">Moet de zaagmaat <span class=\"link-aspect\"\r\n (click)=\"fillZaagmaatTargetedValue()\">{{this.zaagmaatTargetValue}}</span> zijn?</span>\r\n </luv-validationError>\r\n </div>\r\n\r\n </div>\r\n <div class=\"col\" *ngIf=\"showAantalNeuten()\"\r\n [ngStyle]=\"isDorpelConfigurationDisabled ? {'visibility': 'hidden'} : {}\">\r\n <label for=\"aantalneuten\" class=\"form-label\"><b>Aantal Neuten:</b></label>\r\n <div>\r\n <select class=\"form-select\" id=\"aantalneuten\" formControlName=\"aantalNeuten\"\r\n (change)=\"onNeutenCountChanged()\">\r\n <option value=\"0\">0</option>\r\n <option value=\"1\">1</option>\r\n <option value=\"2\">2</option>\r\n <option value=\"3\">3</option>\r\n <option value=\"4\">4</option>\r\n <option value=\"5\">5</option>\r\n <option value=\"6\">6</option>\r\n <option value=\"7\">7</option>\r\n </select>\r\n <luv-validationError [show]=\"showError('aantalNeuten')\" [errorMessage]=\"errorMessage('aantalNeuten')\">\r\n </luv-validationError>\r\n </div>\r\n </div>\r\n <div class=\"col\" *ngIf=\"showAantalSluitpotten()\"\r\n [ngStyle]=\"isDorpelConfigurationDisabled ? {'visibility': 'hidden'} : {}\">\r\n <label for=\"aantalsluitpotten\" class=\"form-label\"><b>Aantal Sluitpotten:</b></label>\r\n <div>\r\n <input type=\"number\" min=\"0\" max=\"10\" class=\"form-control form-control-sm\" id=\"aantalsluitpotten\"\r\n formControlName=\"aantalSluitpotten\" (change)=\"onSluitpottenCountChanged()\" integerOnly/>\r\n <luv-validationError [show]=\"showError('aantalSluitpotten')\"\r\n [errorMessage]=\"errorMessage('aantalSluitpotten')\">\r\n </luv-validationError>\r\n </div>\r\n </div>\r\n <!-- <div class=\"col\">\r\n <label class=\"form-check-label\" for=\"flexCheckDefault\">\r\n <b>Einddoppen</b>\r\n </label><br>\r\n <input class=\"form-check-input\" type=\"checkbox\" value=\"\" id=\"flexCheckDefault\">\r\n </div> -->\r\n </div>\r\n </div>\r\n <div class=\"container-fluid bg-white py-4 my-4 rounded-4 text-center\" *ngIf=\"!isDorpelConfigurationDisabled\">\r\n <div class=\"drawing-wrapper\" resizeListener (resizeEvent)=\"onDrawingWrapperResize()\">\r\n <img *ngIf=\"isDrawingInExampleMode && exampleDrawingPath\" [src]=\"exampleDrawingPath\" alt=\"Example Drawing\"\r\n class=\"example-drawing\" />\r\n <canvas *ngIf=\"zaagmaatDependentFieldsEnabled\" #dorpel_drawing id=\"dorpelDrawing\" height=\"260\"></canvas>\r\n </div>\r\n\r\n <div class=\"col-auto text-center drawing-controls\" *ngIf=\"zaagmaatDependentFieldsEnabled\">\r\n <button type=\"button\" class=\"action-button btn btn-primary btn-lg px-4 gap-3 border-0 rounded-0\"\r\n (click)=\"draw()\"><b><i class=\"fas fa-paint-brush\"></i> Opnieuw tekenen</b></button>\r\n </div>\r\n\r\n <div class=\"col-sm-auto text-center\">\r\n <luv-validationError [show]=\"_sumOfMatenCustomError\"\r\n [errorMessage]=\"_sumOfMatenCustomError\"></luv-validationError>\r\n </div>\r\n <div class=\"col-sm-auto text-center\" *ngIf=\"_slidingDoorsCustomErrors.neutValue\">\r\n <span class=\"error-text\">{{_slidingDoorsCustomErrors.neutValue}}</span>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div [formGroup]=\"formGroup\" *ngIf=\"formGroup\">\r\n <div class=\"row mb-1 d-flex justify-content-center\" *ngIf=\"isSlidingDorpel()\"\r\n [ngStyle]=\"isDorpelConfigurationDisabled ? {'visibility': 'hidden'} : {}\">\r\n\r\n <div class=\"col bg-white py-4 mx-2 rounded-4 restricted-size-panel\">\r\n <label class=\"form-label\"><b>Vak 1:</b></label>\r\n <div class=\"input-group\">\r\n <input type=\"number\" class=\"form-control\" aria-describedby=\"maatA\" formControlName=\"maatA\"\r\n (change)=\"onMaatAChanged()\" integerOnly/>\r\n <span class=\"input-group-text\">mm</span>\r\n </div>\r\n <luv-validationError [show]=\"showError('maatA')\" [errorMessage]=\"errorMessage('maatA')\">\r\n </luv-validationError>\r\n </div>\r\n\r\n <div class=\"col bg-white py-4 mx-2 rounded-4 restricted-size-panel\" *ngIf=\"showDeurmaatA()\">\r\n <label class=\"form-label\"><b>Deurmaat:</b></label>\r\n <div class=\"input-group\">\r\n <input type=\"number\" class=\"form-control\" aria-describedby=\"deurmaatA\" formControlName=\"deurmaatA\"\r\n (change)=\"onDeurmaatAChanged()\" integerOnly/>\r\n <span class=\"input-group-text\">mm</span>\r\n </div>\r\n <luv-validationError [show]=\"showError('deurmaatA')\" [errorMessage]=\"errorMessage('deurmaatA')\">\r\n </luv-validationError>\r\n <luv-validationError [show]=\"_slidingDoorsCustomErrors.deurmaatA\"\r\n [errorMessage]=\"_slidingDoorsCustomErrors.deurmaatA\"></luv-validationError>\r\n </div>\r\n\r\n <div class=\"col bg-white py-4 mx-2 rounded-4 restricted-size-panel\" *ngIf=\"showMaatA()\">\r\n <label class=\"form-label\"><b>Vak 2:</b></label>\r\n <div class=\"input-group\">\r\n <input type=\"number\" class=\"form-control\" aria-describedby=\"maatA1\" formControlName=\"firstMaatA\"\r\n (change)=\"onFirstMaatAChanged()\" integerOnly/>\r\n <span class=\"input-group-text\">mm</span>\r\n </div>\r\n <luv-validationError [show]=\"showError('firstMaatA')\" [errorMessage]=\"errorMessage('firstMaatA')\">\r\n </luv-validationError>\r\n <luv-validationError [show]=\"_slidingDoorsCustomErrors.firstMaatA\"\r\n [errorMessage]=\"_slidingDoorsCustomErrors.firstMaatA\"></luv-validationError>\r\n </div>\r\n\r\n <div class=\"col bg-white py-4 mx-2 rounded-4 restricted-size-panel\" *ngIf=\"showDeurmaatB()\">\r\n <label class=\"form-label\"><b>Deurmaat:</b></label>\r\n <div class=\"input-group\">\r\n <input type=\"number\" class=\"form-control\" aria-describedby=\"deurmaatB\" formControlName=\"deurmaatB\"\r\n (change)=\"onDeurmaatBChanged()\" integerOnly/>\r\n <span class=\"input-group-text\">mm</span>\r\n </div>\r\n <luv-validationError [show]=\"showError('deurmaatB')\" [errorMessage]=\"errorMessage('deurmaatB')\">\r\n </luv-validationError>\r\n <luv-validationError [show]=\"_slidingDoorsCustomErrors.deurmaatB\"\r\n [errorMessage]=\"_slidingDoorsCustomErrors.deurmaatB\"></luv-validationError>\r\n </div>\r\n\r\n <div class=\"col bg-white py-4 mx-2 rounded-4 restricted-size-panel\" *ngIf=\"showMaatB()\">\r\n <label class=\"form-label\"><b>Vak 2:</b></label>\r\n <div class=\"input-group\">\r\n <input type=\"number\" class=\"form-control\" aria-describedby=\"maatB\" formControlName=\"maatB\"\r\n (change)=\"onMaatBChanged()\" integerOnly/>\r\n <span class=\"input-group-text\">mm</span>\r\n </div>\r\n <luv-validationError [show]=\"showError('maatB')\" [errorMessage]=\"errorMessage('maatB')\">\r\n </luv-validationError>\r\n </div>\r\n\r\n <div class=\"col bg-white py-4 mx-2 rounded-4 restricted-size-panel\" *ngIf=\"showDeurmaatC()\">\r\n <label class=\"form-label\"><b>Deurmaat:</b></label>\r\n <div class=\"input-group\">\r\n <input type=\"number\" class=\"form-control\" aria-describedby=\"deurmaatC\" formControlName=\"deurmaatC\"\r\n (change)=\"onDeurmaatCChanged()\" integerOnly/>\r\n <span class=\"input-group-text\">mm</span>\r\n </div>\r\n <luv-validationError [show]=\"showError('deurmaatC')\" [errorMessage]=\"errorMessage('deurmaatC')\">\r\n </luv-validationError>\r\n <luv-validationError [show]=\"_slidingDoorsCustomErrors.deurmaatC\"\r\n [errorMessage]=\"_slidingDoorsCustomErrors.deurmaatC\"></luv-validationError>\r\n </div>\r\n\r\n <div class=\"col bg-white py-4 mx-2 rounded-4 restricted-size-panel\" *ngIf=\"showMaatC()\">\r\n <label class=\"form-label\"><b>Vak 3:</b></label>\r\n <div class=\"input-group\">\r\n <input type=\"number\" class=\"form-control\" aria-describedby=\"maatC\" formControlName=\"maatC\"\r\n (change)=\"onMaatCChanged()\" integerOnly/>\r\n <span class=\"input-group-text\">mm</span>\r\n </div>\r\n <luv-validationError [show]=\"showError('maatC')\" [errorMessage]=\"errorMessage('maatC')\">\r\n </luv-validationError>\r\n <luv-validationError [show]=\"_slidingDoorsCustomErrors.maatC\"\r\n [errorMessage]=\"_slidingDoorsCustomErrors.maatC\"></luv-validationError>\r\n </div>\r\n\r\n <div class=\"col bg-white py-4 mx-2 rounded-4 restricted-size-panel\">\r\n <label class=\"form-label\"><b>{{getMaatZLabel()}}:</b></label>\r\n <div class=\"input-group\">\r\n <input type=\"number\" class=\"form-control\" aria-describedby=\"maatZ\" formControlName=\"maatZ\"\r\n (change)=\"onMaatZChanged()\" integerOnly/>\r\n <span class=\"input-group-text\">mm</span>\r\n </div>\r\n <luv-validationError [show]=\"showError('maatZ')\" [errorMessage]=\"errorMessage('maatZ')\">\r\n </luv-validationError>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- PRODUCTION-PATCH: remove all [ngStyle]=\"isDorpelConfigurationDisabled ? {'visibility': 'hidden'} : {}\" once HS up to par -->","import { Observable, of } from 'rxjs';\r\nimport { Component, OnInit, ViewChild, ElementRef, ChangeDetectorRef, AfterViewChecked, NgZone, Input } from '@angular/core';\r\nimport { FormGroup, FormBuilder, Validators } from '@angular/forms';\r\nimport { FormComponent } from '../shared/form-component';\r\nimport { BackendService } from '../core/services/backend.service';\r\nimport { UiStateService } from '../core/services/ui-state-service';\r\nimport { GraphicsService } from '../core/services/graphics.service';\r\nimport { take, takeUntil, tap } from 'rxjs/internal/operators';\r\nimport { DorpelDto, BestellingDorpelDto } from '../shared/api-models/models';\r\nimport { BaseComponent } from '../shared/base.component';\r\nimport { ActivatedRoute } from '@angular/router';\r\nimport { DataStateService } from '../core/services/data-state.service';\r\nimport { DorpelUtils } from '../shared/models/dorpel-type.model';\r\n\r\nconst MIN_CANVAS_SIZE = 1000;\r\n\r\n@Component({\r\n selector: 'luv-dorpel',\r\n templateUrl: './dorpel-horiz.component.html',\r\n styleUrls: ['./dorpel.component.scss']\r\n})\r\nexport class DorpelComponent extends BaseComponent implements OnInit, AfterViewChecked {\r\n\r\n @ViewChild('dorpel_drawing') private dorpelDrawing: ElementRef<HTMLCanvasElement>;\r\n @Input() checkOtherFormsValidity: () => boolean;\r\n\r\n public formGroup: FormGroup;\r\n public dorpels: DorpelDto[] = [];\r\n private _formComponent: FormComponent;\r\n private _zaagmaatMismatchSignFactor: number = 0;\r\n public zaagmaatTargetValue: number = 0;\r\n public _sumOfMatenCustomError: string | null = null\r\n public _slidingDoorsCustomErrors: any = {\r\n deurmaatA: null,\r\n deurmaatB: null,\r\n deurmaatC: null,\r\n firstMaatA: null,\r\n maatC: null,\r\n neutValue: null\r\n };\r\n private dorpelDependentFields: string[] = [\"merk\", \"zaagmaat\", \"aantal\"];\r\n private schemaDependentFields: string[] = [\"merk\", \"zaagmaat\", \"aantal\", \"maatA\", \"maatZ\"];\r\n // private dorpelTypeDependentFields: string[] = [\"aantalNeuten\", \"aantalSluitpotten\"];\r\n public zaagmaatDependentFieldsEnabled: boolean = false;\r\n private dorpelAutodrawn: boolean = false;\r\n public isDrawingInfoMessageVisible: boolean = false;\r\n private visibleCanvasWidth: number = MIN_CANVAS_SIZE;\r\n private rafId: number;\r\n private drawTimer: ReturnType<typeof setTimeout>;\r\n public exampleDrawingPath: string = \"\";\r\n public get isDrawingInExampleMode(): boolean {\r\n return this.uiStateService.isDrawingInExampleMode();\r\n }\r\n\r\n constructor(\r\n private formBuilder: FormBuilder,\r\n private uiStateService: UiStateService,\r\n private dataStateService: DataStateService,\r\n private backend: BackendService,\r\n private activatedRoute: ActivatedRoute,\r\n private graphics: GraphicsService,\r\n private cdRef: ChangeDetectorRef,\r\n private ngZone: NgZone) {\r\n super();\r\n }\r\n\r\n ngOnInit(): void {\r\n const productType = this.activatedRoute.snapshot.paramMap.get('productType');\r\n this.dataStateService.setHomePath(`/order-form/${productType}`);\r\n this.uiStateService.viewMode === \"Edit\" ? this.uiStateService.turnOffDrawingExample() : this.uiStateService.turnOnDrawingExample(); //in edit mode real dorpel gets autodrawn\r\n this.getDorpels(productType)\r\n .pipe(take(1))\r\n .pipe(tap(result => this.uiStateService.dorpelChoices = result))\r\n .subscribe(result => {\r\n this.dorpels = result;\r\n const currentDorpel = this.uiStateService.currentDorpel;\r\n this.formGroup = this.buildForm(currentDorpel);\r\n this._formComponent = new FormComponent(this.formGroup);\r\n\r\n if (this.formGroup.get('dorpel').value) {\r\n this.enableDorpelDependentFields();\r\n this.enableDorpelTypeDependentFields();\r\n this.enableZaagmaatDependentFields();\r\n }\r\n });\r\n\r\n this.uiStateService.neutCustomWidthUpdate$\r\n .pipe(takeUntil(this.unsubscribe$))\r\n .subscribe((width) => {\r\n if (width) {\r\n this.draw();\r\n }\r\n });\r\n\r\n this.uiStateService.redraw$\r\n .pipe(takeUntil(this.unsubscribe$))\r\n .subscribe((draw) => {\r\n if(!!draw) {\r\n this.draw();\r\n }\r\n });\r\n }\r\n\r\n ngAfterViewChecked() {\r\n if (this.dorpelAutodrawn || !this.dorpelDrawing || !this.isCanvasEmpty(this.dorpelDrawing.nativeElement)) {\r\n return;\r\n }\r\n\r\n this.visibleCanvasWidth = this.dorpelDrawing.nativeElement.parentElement.getBoundingClientRect().width;\r\n\r\n if (this.uiStateService.viewMode === 'Edit') { //when in edit mode (prefilled scenario or not), we want to autodraw the dorpel\r\n this.draw();\r\n this.cdRef.detectChanges(); //must be called after draw because drawing function triggers validation which might update the view (err message)\r\n this.dorpelAutodrawn = true;\r\n }\r\n }\r\n\r\n get isDorpelConfigurationDisabled(): boolean {\r\n // return this.isSlidingDorpel();\r\n return false;\r\n }\r\n\r\n private getDorpels(productType): Observable<DorpelDto[]> {\r\n const dorpelDtos: DorpelDto[] = [];\r\n dorpelDtos.push(<DorpelDto>{\r\n dorpelCode: this.uiStateService.currentDorpel.dorpelCode,\r\n omschrijving: this.uiStateService.currentDorpel.dorpelCode\r\n });\r\n return this.uiStateService.fromPrefilledOrder ? of(dorpelDtos) : this.backend.getDorpels(productType);\r\n }\r\n\r\n public onNeutenCountChanged(): void {\r\n const neutenCount = this.formGroup.get('aantalNeuten').value;\r\n this.uiStateService.setNeutenCount(parseInt(neutenCount));\r\n }\r\n\r\n public onSluitpottenCountChanged(): void {\r\n const sluitpottenCount = this.formGroup.get('aantalSluitpotten').value;\r\n this.uiStateService.setSluitpottenCount(sluitpottenCount);\r\n }\r\n\r\n public setupNewConfiguration(): void {\r\n const dorpelCode = this.formGroup.get('dorpel').value;\r\n const isSlidingDoor = DorpelUtils.isSlidingDoor(dorpelCode);\r\n const schema = isSlidingDoor ? this.formGroup.get('schema').value : \"\";\r\n this.setExampleDrawingPath(dorpelCode, schema?.toLocaleLowerCase());\r\n\r\n this.uiStateService.setDorpelCode(dorpelCode);\r\n this.uiStateService.setSchema(schema);\r\n this.formGroup = this.buildForm(this.uiStateService.currentDorpel);\r\n this.initializeDrawing();\r\n\r\n setTimeout(() => {\r\n this.enableDorpelDependentFields();\r\n this.enableDorpelTypeDependentFields();\r\n this.toggleSchemaDependentFields();\r\n }, 0);\r\n }\r\n\r\n private setExampleDrawingPath(dorpelCode: string, schema?: string): void {\r\n if (!dorpelCode) {\r\n this.exampleDrawingPath = \"\";\r\n return;\r\n }\r\n\r\n if (DorpelUtils.isBinnenDoor(dorpelCode)) {\r\n this.exampleDrawingPath = \"/assets/example-drawing-bi.png\";\r\n return;\r\n }\r\n\r\n if (DorpelUtils.isBuitenDoor(dorpelCode)) {\r\n this.exampleDrawingPath = \"/assets/example-drawing-bu.png\";\r\n return;\r\n }\r\n\r\n if (DorpelUtils.isSlidingDoor(dorpelCode) && schema) {\r\n this.exampleDrawingPath = `/assets/example-drawing-${schema}.png`;\r\n return;\r\n }\r\n\r\n this.exampleDrawingPath = \"\";\r\n }\r\n\r\n public fillZaagmaatTargetedValue(): void {\r\n this.formGroup.get('zaagmaat').setValue(this.zaagmaatTargetValue);\r\n this.uiStateService.setZaagmaat(this.zaagmaatTargetValue);\r\n this.draw();\r\n }\r\n\r\n //TODO: optimize redraw\r\n onDrawingWrapperResize() {\r\n this.ngZone.runOutsideAngular(() => {\r\n if (this.rafId) {\r\n cancelAnimationFrame(this.rafId);\r\n }\r\n this.rafId = requestAnimationFrame(() => {\r\n this.visibleCanvasWidth = Math.max(this.dorpelDrawing?.nativeElement.parentElement.getBoundingClientRect().width, MIN_CANVAS_SIZE);\r\n this.initializeDrawing();\r\n\r\n if (!this.isDrawingInExampleMode) {\r\n this.graphics.drawDorpel(this.uiStateService.currentDorpel);\r\n }\r\n })\r\n });\r\n }\r\n\r\n public isSlidingDorpel(): boolean {\r\n const dorpelDto = this.dorpels.find(d => d.dorpelCode === this.formGroup.get('dorpel').value);\r\n return dorpelDto && dorpelDto.dorpelsoort === 'Hefschuifdorpel';\r\n }\r\n\r\n public showAantalNeuten(): boolean {\r\n return !this.isSlidingDorpel();\r\n }\r\n\r\n public showAantalSluitpotten(): boolean {\r\n return !this.isSlidingDorpel();\r\n }\r\n\r\n public getMaatZLabel(): string {\r\n const schema = this.formGroup.get('schema')?.value;\r\n if (!schema || schema === 'AL' || schema === 'AR') {\r\n return \"Vak 2\";\r\n }\r\n\r\n if (schema === 'C+G') {\r\n return \"Vak 3\";\r\n }\r\n\r\n return \"Vak 4\";\r\n }\r\n\r\n showDeurmaatA(): boolean {\r\n const schema = this.formGroup.get('schema')?.value;\r\n return schema === 'AL' || schema === 'AR' || schema === 'C+G';\r\n }\r\n\r\n showMaatA() {\r\n const schema = this.formGroup.get('schema')?.value;\r\n return schema === 'D';\r\n }\r\n\r\n showDeurmaatB() {\r\n const schema = this.formGroup.get('schema')?.value;\r\n return schema === 'D';\r\n }\r\n\r\n showMaatB() {\r\n const schema = this.formGroup.get('schema')?.value;\r\n return schema === 'C+G';\r\n }\r\n\r\n showDeurmaatC() {\r\n const schema = this.formGroup.get('schema')?.value;\r\n return schema === 'C+G';\r\n }\r\n\r\n showMaatC() {\r\n const schema = this.formGroup.get('schema')?.value;\r\n return schema === 'D';\r\n }\r\n\r\n public showError(key: string): boolean {\r\n if (key === 'zaagmaat') {\r\n let hasError = this._zaagmaatMismatchSignFactor !== 0 && !this._sumOfMatenCustomError;\r\n if (hasError) {\r\n window.scrollTo({ top: 0 });\r\n }\r\n return hasError;\r\n }\r\n return this._formComponent.showError(key);\r\n }\r\n\r\n // check if hefboom is active to hide sluitpot\r\n showHefdeur(): boolean {\r\n const schema = this.formGroup.get('schema')?.value;\r\n return schema === 'AL' || schema === 'AR' || schema === 'C+G' || schema === 'D';\r\n }\r\n\r\n\r\n public errorMessage(key: string): string {\r\n if (key === 'zaagmaat') {\r\n if (this._zaagmaatMismatchSignFactor === 0) return '';\r\n return (this._zaagmaatMismatchSignFactor < 0 ?\r\n ValidationMessages.zaagmaat.zaagmatAmountMismatchTooLow :\r\n ValidationMessages.zaagmaat.zaagmatAmountMismatchTooHigh);\r\n }\r\n\r\n const formControl = this.formGroup.get(key);\r\n if (formControl.valid || formControl.disabled) {\r\n return '';\r\n }\r\n const [firstError] = Object.keys(formControl.errors);\r\n const error = ValidationMessages[key] ? ValidationMessages[key][firstError] : null;\r\n return error || this._formComponent.errorMessage(key);\r\n }\r\n\r\n public dataIsValid(): boolean {\r\n const isValid = this.formGroup.valid;\r\n\r\n if (!isValid) {\r\n Object.keys(this.formGroup.controls).forEach(field => {\r\n const control = this.formGroup.get(field);\r\n control.markAsTouched();\r\n });\r\n }\r\n\r\n return isValid;\r\n }\r\n\r\n public getDorpelDrawingData(): string | null {\r\n let canvas: HTMLCanvasElement = this.dorpelDrawing.nativeElement;\r\n if (this.isCanvasEmpty(canvas)) {\r\n return null;\r\n }\r\n\r\n let imageData = canvas.toDataURL(\"image/png\");\r\n return imageData;\r\n }\r\n\r\n private isCanvasEmpty(canvas: HTMLCanvasElement): boolean {\r\n return !canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height)\r\n .data.some(channel => channel !== 0);\r\n }\r\n\r\n private getNeutDimension(neutCode: string, positie: string): number {\r\n let neutDto = this.uiStateService.getNeutDtoByCodeAndPositie(neutCode, positie);\r\n if (neutDto) {\r\n return neutDto.neutbreedte ? parseInt(neutDto.neutbreedte) : 0;\r\n }\r\n\r\n return 0;\r\n }\r\n\r\n public validateZaagmaat(dorpel: BestellingDorpelDto): boolean {\r\n let total: number;\r\n this._zaagmaatMismatchSignFactor = 0;\r\n this.zaagmaatTargetValue = 0;\r\n\r\n if (!this.isSlidingDorpel()) {\r\n let maatA = dorpel.maatA || 0;\r\n let maatZ = dorpel.maatZ || 0;\r\n total = maatA + maatZ;\r\n total += dorpel.neuten.map(neut => {\r\n return (neut.customWidth || this.getNeutDimension(neut.neutCode, neut.positie)) + (neut.daagmaat || 0);\r\n }).reduce((accumulator, currentValue) => accumulator + currentValue);\r\n this.zaagmaatTargetValue = total;\r\n } else {\r\n this.resetSlidingDoorsCustomErrors();\r\n\r\n let neut = dorpel.neuten[0]; //single neut type for sliding doors\r\n let neutValue = neut && neut.neutCode ? this.getNeutDimension(neut.neutCode, neut.positie) : 0;\r\n\r\n if (!neutValue) { //TODO: needs refactoring (custom validation for sliding door neut missing value)\r\n this._slidingDoorsCustomErrors.neutValue = \"Kies een neut om de tekening compleet te maken.\";\r\n return;\r\n }\r\n\r\n let maatA = dorpel.maatA || 0;\r\n let maatB = dorpel.maatB || 0;\r\n let maatC = dorpel.maatC || 0;\r\n let firstMaatA = dorpel.firstMaatA || 0;\r\n let deurmaatA = dorpel.deurmaatA || 0;\r\n let deurmaatB = dorpel.deurmaatB || 0;\r\n let deurmaatC = dorpel.deurmaatC || 0;\r\n let maatZ = dorpel.maatZ || 0;\r\n let availableMechanismSpace = dorpel.zaagmaat - maatA - maatZ;\r\n\r\n switch (dorpel.schema) {\r\n case \"AL\":\r\n case \"AR\": {\r\n let distancesValid = this.validateALARSchemaDistances({\r\n availableMechanismSpace: availableMechanismSpace,\r\n neutValue: neutValue,\r\n deurmaatA: deurmaatA\r\n });\r\n\r\n if (!distancesValid) {\r\n return false;\r\n }\r\n\r\n total = dorpel.zaagmaat; //manually validate total\r\n break;\r\n }\r\n case \"C+G\": {\r\n let distancesValid = this.validateCGSchemaDistances({\r\n availableMechanismSpace: availableMechanismSpace,\r\n neutValue: neutValue,\r\n deurmaatA: deurmaatA,\r\n deurmaatC: deurmaatC,\r\n maatB: maatB\r\n });\r\n\r\n if (!distancesValid) {\r\n return false;\r\n }\r\n\r\n total = maatA + deurmaatA + maatB + deurmaatC + maatZ;\r\n this.zaagmaatTargetValue = total;\r\n break;\r\n }\r\n case \"D\": {\r\n let distancesValid = this.validateDSchema({\r\n availableMechanismSpace: availableMechanismSpace,\r\n neutValue: neutValue,\r\n maatA: maatA,\r\n maatC: maatC,\r\n deurmaatB: deurmaatB,\r\n firstMaatA: firstMaatA\r\n });\r\n\r\n if (!distancesValid) {\r\n return false;\r\n }\r\n\r\n total = maatA + firstMaatA + deurmaatB + maatC + maatZ;\r\n this.zaagmaatTargetValue = total;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (total === 0) {\r\n this._sumOfMatenCustomError = ValidationMessages.sumOfMatenNull\r\n } else {\r\n this._sumOfMatenCustomError = null;\r\n }\r\n\r\n if (total !== dorpel.zaagmaat) {\r\n this._zaagmaatMismatchSignFactor = total > dorpel.zaagmaat ? -1 : 1;\r\n }\r\n\r\n return this._zaagmaatMismatchSignFactor === 0;\r\n }\r\n\r\n private resetSlidingDoorsCustomErrors(): void {\r\n this._slidingDoorsCustomErrors.deurmaatA = null;\r\n this._slidingDoorsCustomErrors.deurmaatC = null;\r\n this._slidingDoorsCustomErrors.firstMaatA = null;\r\n this._slidingDoorsCustomErrors.maatC = null;\r\n this._slidingDoorsCustomErrors.deurmaatB = null;\r\n this._slidingDoorsCustomErrors.neutValue = null;\r\n }\r\n\r\n private validateALARSchemaDistances(values: any): boolean {\r\n let deurmaatMinWidth = 2 * values.neutValue + 10; //10 is minimum slider length;\r\n let deurmaatMaxWdith = values.availableMechanismSpace - 1 * values.neutValue;\r\n\r\n if (values.deurmaatA < deurmaatMinWidth) {\r\n this._slidingDoorsCustomErrors.deurmaatA = `Minimum Deurmaat A should be ${deurmaatMinWidth}`;\r\n return false;\r\n } else if (values.deurmaatA > deurmaatMaxWdith) {\r\n this._slidingDoorsCustomErrors.deurmaatA = `Maximum Deurmaat A should be ${deurmaatMaxWdith}`;\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private validateCGSchemaDistances(values: any): boolean {\r\n let deurmaatMinWidth = 2 * values.neutValue + 10; //10 is minimum slider length;\r\n let deurmaatAMaxWdith = values.availableMechanismSpace - values.deurmaatC - values.maatB;\r\n let deurmaatCMaxWdith = values.availableMechanismSpace - values.deurmaatA - values.maatB;\r\n\r\n if (deurmaatAMaxWdith > deurmaatMinWidth) {\r\n if (values.deurmaatA < deurmaatMinWidth) {\r\n this._slidingDoorsCustomErrors.deurmaatA = `Minimum Deurmaat A should be ${deurmaatMinWidth}`;\r\n return false;\r\n } else if (values.deurmaatA > deurmaatAMaxWdith) {\r\n this._slidingDoorsCustomErrors.deurmaatA = `Maximum Deurmaat A should be ${deurmaatAMaxWdith}`;\r\n return false;\r\n }\r\n }\r\n\r\n if (deurmaatCMaxWdith > deurmaatMinWidth) {\r\n if (values.deurmaatC < deurmaatMinWidth) {\r\n this._slidingDoorsCustomErrors.deurmaatC = `Minimum Deurmaat C should be ${deurmaatMinWidth}`;\r\n return false;\r\n } else if (values.deurmaatC > deurmaatCMaxWdith) {\r\n this._slidingDoorsCustomErrors.deurmaatC = `Maximum Deurmaat C should be ${deurmaatCMaxWdith}`;\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private validateDSchema(values: any): boolean {\r\n let firstMaatAMinWidth = values.neutValue //10 is minimum slider length;\r\n let firstMaatAMaxWidth = values.availableMechanismSpace - values.deurmaatB - values.maatC;\r\n let maatCMinWidth = values.neutValue //10 is minimum slider length;\r\n let maatCMaxWidth = values.availableMechanismSpace - values.deurmaatB - values.maatA;\r\n let deurmaatBMinWidth = 2 * values.neutValue;\r\n let deurmaatBMaxWidth = values.availableMechanismSpace - values.maatA - values.maatC;\r\n\r\n if (values.firstMaatA < firstMaatAMinWidth) {\r\n this._slidingDoorsCustomErrors.firstMaatA = `Minimum Maat A should be ${firstMaatAMinWidth}`;\r\n return false;\r\n } else if (values.firstMaatA > firstMaatAMaxWidth) {\r\n this._slidingDoorsCustomErrors.firstMaatA = `Maximum Maat A should be ${firstMaatAMaxWidth}`;\r\n return false;\r\n }\r\n\r\n if (values.maatC < maatCMinWidth) {\r\n this._slidingDoorsCustomErrors.maatC = `Minimum Maat C should be ${maatCMinWidth}`;\r\n return false;\r\n } else if (values.maatC > maatCMaxWidth) {\r\n this._slidingDoorsCustomErrors.maatC = `Maximum Maat C should be ${maatCMaxWidth}`;\r\n return false;\r\n }\r\n\r\n if (values.deurmaatB < deurmaatBMinWidth) {\r\n this._slidingDoorsCustomErrors.deurmaatB = `Minimum Deurmaat B should be ${deurmaatBMinWidth}`;\r\n return false;\r\n } else if (values.deurmaatB > deurmaatBMaxWidth) {\r\n this._slidingDoorsCustomErrors.deurmaatB = `Maximum Deurmaat B should be ${deurmaatBMaxWidth}`;\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private buildForm(dorpel: BestellingDorpelDto): FormGroup {\r\n const formGroup = this.formBuilder.group({\r\n dorpel: [dorpel.dorpelCode || '', [Validators.required]],\r\n merk: [{ value: dorpel.merk || '', disabled: true }],\r\n zaagmaat: [{ value: dorpel.zaagmaat || '', disabled: true }, [Validators.pattern('[0-9]+'), Validators.required]],\r\n aantalNeuten: [{ value: dorpel.aantalNeuten || 2, disabled: true }, [Validators.pattern('[0-9]+'), Validators.required]],\r\n aantalSluitpotten: [{ value: dorpel.aantalSluitpotten || 0, disabled: true }, [Validators.pattern('[0-9]+'), Validators.required]],\r\n schema: [dorpel.schema || ''], //TODO: field validation handling\r\n deurmaatA: [dorpel.deurmaatA], //TODO field validation\r\n deurmaatB: [dorpel.deurmaatB], //TODO field validation\r\n deurmaatC: [dorpel.deurmaatC],\r\n aantal: [{ value: dorpel.aantal || 1, disabled: true }, [Validators.min(1), Validators.required]],\r\n maatA: [dorpel.maatA || 0], //only for sliding doors (otherwise value is on daagmaat component/form)\r\n firstMaatA: [dorpel.firstMaatA],\r\n maatB: [dorpel.maatB],\r\n maatC: [dorpel.maatC],\r\n maatZ: [dorpel.maatZ || 0], //only for sliding doors (otherwise value is on daagmaat component/form)\r\n //opmerking detached to separate form handled in the dorpel page component\r\n //due to its position in the view\r\n });\r\n\r\n return formGroup;\r\n }\r\n\r\n public onMaatAChanged(): void {\r\n const maatA = this.formGroup.get('maatA').value;\r\n this.uiStateService.setMaatA(maatA);\r\n }\r\n\r\n public onMaatZChanged(): void {\r\n const maatZ = this.formGroup.get('maatZ').value;\r\n this.uiStateService.setMaatZ(maatZ);\r\n }\r\n\r\n public onDeurmaatAChanged(): void {\r\n const deurmaatA = this.formGroup.get(\"deurmaatA\").value;\r\n this.uiStateService.setDeurmaatA(deurmaatA);\r\n }\r\n\r\n public onDeurmaatBChanged(): void {\r\n const deurmaatB = this.formGroup.get(\"deurmaatB\").value;\r\n this.uiStateService.setDeurmaatB(deurmaatB);\r\n }\r\n\r\n public onFirstMaatAChanged(): void {\r\n const firstMaatA = this.formGroup.get(\"firstMaatA\").value;\r\n this.uiStateService.setFirstMaatA(firstMaatA);\r\n }\r\n public onMaatBChanged(): void {\r\n const maatB = this.formGroup.get(\"maatB\").value;\r\n this.uiStateService.setMaatB(maatB);\r\n }\r\n public onDeurmaatCChanged(): void {\r\n const deurmaatC = this.formGroup.get(\"deurmaatC\").value;\r\n this.uiStateService.setDeurmaatC(deurmaatC);\r\n }\r\n public onMaatCChanged(): void {\r\n const maatC = this.formGroup.get(\"maatC\").value;\r\n this.uiStateService.setMaatC(maatC);\r\n }\r\n\r\n private enableDorpelDependentFields(): void {\r\n this.dorpelDependentFields.forEach(field => {\r\n let fieldToEnable = this.formGroup.controls[field];\r\n\r\n if (fieldToEnable) {\r\n fieldToEnable.enable();\r\n }\r\n });\r\n }\r\n\r\n enableDorpelTypeDependentFields(): void {\r\n let isEditMode = this.uiStateService.viewMode === 'Edit'\r\n let isCurrentDoorSliding = this.isSlidingDorpel();\r\n let neutenValue: number = isCurrentDoorSliding ? 1 : 2;\r\n\r\n if (!isEditMode) {\r\n this.formGroup.get('aantalNeuten').setValue(neutenValue);\r\n this.uiStateService.setNeutenCount(neutenValue);\r\n }\r\n\r\n if (isCurrentDoorSliding) {\r\n if (!isEditMode) {\r\n this.formGroup.get('aantalSluitpotten').setValue(0);\r\n this.uiStateService.setSluitpottenCount(0);\r\n }\r\n\r\n this.formGroup.controls['aantalNeuten'].disable();\r\n this.formGroup.controls['aantalSluitpotten'].disable();\r\n } else {\r\n this.formGroup.controls['aantalNeuten'].enable();\r\n this.formGroup.controls['aantalSluitpotten'].enable();\r\n }\r\n }\r\n\r\n toggleSchemaDependentFields(): void {\r\n const schema = this.formGroup.get(\"schema\").value;\r\n const isSlidingDorpel = this.isSlidingDorpel();\r\n\r\n if (!isSlidingDorpel) {\r\n return;\r\n }\r\n\r\n this.schemaDependentFields.forEach(field => {\r\n let targetField = this.formGroup.controls[field];\r\n\r\n if (targetField) {\r\n if (!schema) {\r\n targetField.disable();\r\n } else if (schema) {\r\n targetField.enable();\r\n }\r\n }\r\n })\r\n }\r\n\r\n public enableZaagmaatDependentFields(): void {\r\n this.zaagmaatDependentFieldsEnabled = this.formGroup.controls.zaagmaat.value > 0;\r\n setTimeout(this.initializeDrawing.bind(this), 100);\r\n }\r\n\r\n private getZaagmaatMaxLimit(): number {\r\n return 6000;\r\n }\r\n\r\n public onZaagmaatValueChanged(): void {\r\n const zaagmaat = this.formGroup.get('zaagmaat').value;\r\n const maxLimit = this.getZaagmaatMaxLimit();\r\n\r\n if (!this.isSlidingDorpel() && zaagmaat > maxLimit) {\r\n this.formGroup.get('zaagmaat').setValue(maxLimit);\r\n this.uiStateService.setZaagmaat(maxLimit);\r\n } else {\r\n this.uiStateService.setZaagmaat(zaagmaat);\r\n }\r\n\r\n this.enableZaagmaatDependentFields();\r\n }\r\n\r\n public initializeDrawing(): void {\r\n this.graphics.initializeDrawing(\"dorpelDrawing\", this.visibleCanvasWidth);\r\n }\r\n\r\n public draw(): void {\r\n if (!this.validateZaagmaat(this.uiStateService.currentDorpel) || !this.checkOtherFormsValidity()) {\r\n return;\r\n }\r\n\r\n this.measureSurfaceAndTriggerDebouncedDraw();\r\n }\r\n\r\n private measureSurfaceAndTriggerDebouncedDraw(): void {\r\n this.visibleCanvasWidth = Math.max(this.dorpelDrawing.nativeElement.parentElement.getBoundingClientRect().width, MIN_CANVAS_SIZE);\r\n this.initializeDrawing();\r\n if (this.drawTimer) {\r\n clearTimeout(this.drawTimer);\r\n }\r\n this.drawTimer = setTimeout(() => {\r\n this.graphics.drawDorpel(this.uiStateService.currentDorpel);\r\n }, 100);\r\n }\r\n}\r\n\r\nconst ValidationMessages = {\r\n dorpel: {\r\n required: 'Selecteer een waarde a.u.b.'\r\n },\r\n zaagmaat: {\r\n required: 'Selecteer een waarde a.u.b.',\r\n zaagmatAmountMismatchTooLow: 'De zaagmaat is te kort!',\r\n zaagmatAmountMismatchTooHigh: 'De zaagmaat is te lang!',\r\n },\r\n aantalNeuten: {\r\n required: 'Selecteer een waarde a.u.b.'\r\n },\r\n aantalSluitpotten: {\r\n required: 'Selecteer een waarde a.u.b.'\r\n },\r\n aantal: {\r\n required: 'Het aantal dorpels mag niet 0 zijn',\r\n min: 'Het aantal dorpels mag niet 0 zijn'\r\n },\r\n sumOfMatenNull: 'Vul de deelmaten hieronder in om de dorpel te kunnen tekenen.'\r\n};\r\n","const TooltipTypes = {\r\n neut: {\r\n imagePath: null,\r\n textDescription: \"Kies een neut uit de dropdownlijst om hier een tekening met maten te zien.\"\r\n },\r\n sponningmaat: {\r\n imagePath: null,\r\n textDescription: \"Wilt u een andere maat laat ons dit dan weten in de opmerkingen.\"\r\n }\r\n}\r\n\r\nexport default TooltipTypes;","import { Injectable } from '@angular/core';\r\nimport TooltipTypes from \"../../shared/tooltip-configuration\";\r\nconst TOOLTIP_POSITIONS = {\r\n RIGHT: 0,\r\n BOTTOM: 1,\r\n TOP: 2,\r\n LEFT: 3\r\n};\r\n\r\nconst TOOLTIP_OFFSET = {\r\n TOP: 0,\r\n LEFT: 10\r\n};\r\nconst TOOLTIP_GENERAL_OFFSET = 10;\r\nconst ASSETS_BASE_PATH = \"assets/tooltip-assets/\";\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class TooltipService {\r\n tooltipComponent: any;\r\n assetsPath: string = ASSETS_BASE_PATH;\r\n constructor() { }\r\n\r\n public registerTooltipComponent(component: any): void {\r\n this.tooltipComponent = component;\r\n }\r\n\r\n public showTooltip(targetElement: HTMLElement, options?: any): void {\r\n let tooltipTypeKey = targetElement.getAttribute(\"data-tooltip-type\");\r\n this.tooltipComponent.setOptions(TooltipTypes[tooltipTypeKey]);\r\n let tooltipOptions = this.tooltipComponent.getOptions();\r\n\r\n if (options?.customImageName) {\r\n tooltipOptions.imagePath = `${ASSETS_BASE_PATH}${options.customImageName}`;\r\n }\r\n\r\n if (options?.customTextDescription) {\r\n tooltipOptions.textDescription = options.customTextDescription;\r\n }\r\n\r\n if (options?.imageOnly) {\r\n tooltipOptions.textDescription = null;\r\n }\r\n\r\n if (options?.descriptionOnly) {\r\n tooltipOptions.imagePath = null;\r\n }\r\n\r\n this.tooltipComponent.showTooltip(); //show to update size, then calculate + update position\r\n\r\n let position: string = this.computeTooltipPoisitionString(targetElement);\r\n this.tooltipComponent.setCustomStyle(position);\r\n }\r\n\r\n public hideTooltip(): void {\r\n this.tooltipComponent.hideTooltip();\r\n }\r\n\r\n private getPreferedPositioningOrder(): number[] {\r\n return [\r\n TOOLTIP_POSITIONS.RIGHT,\r\n TOOLTIP_POSITIONS.BOTTOM,\r\n TOOLTIP_POSITIONS.TOP,\r\n TOOLTIP_POSITIONS.LEFT\r\n ];\r\n }\r\n \r\n private computeTooltipPoisitionString(targetElement: HTMLElement): string {\r\n let elementRect = targetElement.getBoundingClientRect();\r\n let positionStyleString = this.getPositioningStyleString(elementRect);\r\n\r\n return positionStyleString;\r\n }\r\n\r\n private getPositioningStyleString(targetRect: ClientRect): string {\r\n let targetTop = Math.round(targetRect.top + window.scrollY);\r\n let targetRight = Math.round(targetRect.right + window.scrollX);\r\n let targetBottom = Math.round(targetRect.top + window.scrollY + targetRect.height);\r\n let targetLeft = Math.round(targetRect.left + window.scrollX);\r\n let positions = this.getPreferedPositioningOrder();\r\n let tooltipBox = this.tooltipComponent.tooltipbox.nativeElement;\r\n let tooltipWidth = tooltipBox.offsetWidth;\r\n let tooltipHeight = tooltipBox.offsetHeight;\r\n\r\n while (positions.length) {\r\n let currentPosition = positions.shift();\r\n\r\n switch(currentPosition) {\r\n case TOOLTIP_POSITIONS.RIGHT:\r\n if (this.fitsRight(targetRight, tooltipWidth)) {\r\n let top = targetTop;\r\n if (window.innerHeight + window.scrollY < top + tooltipHeight) {\r\n top = top - (top + tooltipHeight - (window.innerHeight + window.scrollY)) - TOOLTIP_GENERAL_OFFSET;\r\n }\r\n return `top: ${top}px; left: ${targetRight + TOOLTIP_OFFSET.LEFT}px`;\r\n }\r\n break;\r\n case TOOLTIP_POSITIONS.BOTTOM:\r\n if (this.fitsBottom(targetBottom, tooltipHeight)) {\r\n let left = targetLeft;\r\n if (window.innerWidth + window.scrollX < left + tooltipWidth) {\r\n left = left - (left + tooltipWidth + TOOLTIP_GENERAL_OFFSET - (window.innerWidth + window.scrollX)) - TOOLTIP_GENERAL_OFFSET;\r\n }\r\n return `top: ${targetBottom + TOOLTIP_GENERAL_OFFSET}px; left: ${left}px`;\r\n }\r\n break;\r\n case TOOLTIP_POSITIONS.TOP:\r\n if (this.fitsTop(targetTop, tooltipHeight)) {\r\n let left = targetLeft;\r\n if (window.innerWidth + window.scrollX < left + tooltipWidth) {\r\n left = left - (left + tooltipWidth + TOOLTIP_GENERAL_OFFSET - (window.innerWidth + window.scrollX)) - TOOLTIP_GENERAL_OFFSET;\r\n }\r\n return `top: ${targetTop - tooltipHeight- TOOLTIP_GENERAL_OFFSET}px; left: ${left}px`;\r\n }\r\n break;\r\n case TOOLTIP_POSITIONS.LEFT:\r\n default:\r\n let top = targetTop;\r\n if (window.innerHeight + window.scrollY < top + tooltipHeight) {\r\n top = top - (top + tooltipHeight - (window.innerHeight + window.scrollY)) - TOOLTIP_GENERAL_OFFSET;\r\n }\r\n return `top: ${top}px; left: ${targetLeft - tooltipWidth - TOOLTIP_GENERAL_OFFSET}px`;\r\n }\r\n }\r\n }\r\n\r\n private fitsRight(targetRight: number, tooltipWidth: number): boolean {\r\n return targetRight + 2 * TOOLTIP_GENERAL_OFFSET + tooltipWidth < window.innerWidth + window.scrollX;\r\n }\r\n\r\n private fitsBottom(targetBottom: number, tooltipHeight: number): boolean {\r\n return targetBottom + 2 * TOOLTIP_GENERAL_OFFSET + tooltipHeight < window.innerHeight + window.scrollY;\r\n }\r\n\r\n private fitsTop(targetTop: number, tooltipHeight: number): boolean {\r\n return targetTop - 2 * TOOLTIP_GENERAL_OFFSET - tooltipHeight > window.scrollY;\r\n }\r\n }\r\n","<div *ngIf=\"formGroup\" [formGroup]=\"formGroup\">\r\n <div *ngIf=\"isDaagmaatA else daagmaat\">\r\n <label class=\"form-label\"><b>Vak 1:</b></label>\r\n <div class=\"input-group\">\r\n <input type=\"number\" min=\"0\" class=\"form-control form-control-sm\" aria-describedby=\"maata\" formControlName=\"maatA\"\r\n (change)=\"onMaatAChanged()\" integerOnly/>\r\n <span class=\"input-group-text\">mm</span>\r\n </div>\r\n <luv-validationError [show]=\"showError('maatA')\" [errorMessage]=\"errorMessage('maatA')\">\r\n </luv-validationError>\r\n <!-- <br>\r\n <label for=\"Verstek\" class=\"form-label\">Verstek:</label>\r\n <input class=\"form-control\" type=\"text\" id=\"Verstek\" placeholder=\"Geen\" aria-label=\".form-control-sm example\"> -->\r\n </div>\r\n\r\n <ng-template #daagmaat>\r\n <div *ngIf=\"neutModel.position === NeutPosition.Right\">\r\n <label class=\"form-label\"><b>Vak {{ index + 2 }}:</b></label>\r\n <div class=\"input-group\">\r\n <input type=\"number\" min=\"0\" class=\"form-control\" aria-describedby=\"maatz\" formControlName=\"maatZ\"\r\n (change)=\"onMaatZChanged()\" integerOnly/>\r\n <span class=\"input-group-text\">mm</span>\r\n </div>\r\n <luv-validationError [show]=\"showError('maatZ')\" [errorMessage]=\"errorMessage('maatZ')\">\r\n </luv-validationError>\r\n <!-- <br>\r\n <label for=\"Verstek\" class=\"form-label\">Verstek:</label>\r\n <input class=\"form-control\" type=\"text\" id=\"Verstek\" placeholder=\"Geen\" aria-label=\".form-control-sm example\"> -->\r\n </div>\r\n\r\n <div *ngIf=\"neutModel.position !== NeutPosition.Right\">\r\n <ng-container *ngIf=\"dorpelType !== 'Hefschuifdorpel'\" class=\"col-lg-auto\">\r\n <label class=\"form-label\"><b>Vak {{ index + 2 }} Dagmaat:</b></label>\r\n <div class=\"input-group\">\r\n <input type=\"number\" min=\"0\" class=\"form-control\" aria-describedby=\"daagmaata1\" formControlName=\"daagmaat\"\r\n (change)=\"onDaagmaatChanged(index)\" integerOnly/>\r\n <span class=\"input-group-text\">mm</span>\r\n </div>\r\n <luv-validationError [show]=\"showError('daagmaat')\" [errorMessage]=\"errorMessage('daagmaat')\">\r\n </luv-validationError>\r\n\r\n <div *ngIf=\"isUitvoeringAvailable\">\r\n <label class=\"form-label\"><b>Uitvoering:</b></label>\r\n <select class=\"form-select\" id=\"Sponningsoort\" formControlName=\"sponningsoort\"\r\n (change)=\"onSponningsoortChanged(index)\">\r\n <option value=\"\" disabled selected hidden>Kies</option>\r\n <option>Sponning</option>\r\n <option>Kader</option>\r\n </select>\r\n <luv-validationError [show]=\"showError('sponningsoort')\" [errorMessage]=\"errorMessage('sponningsoort')\">\r\n </luv-validationError>\r\n </div>\r\n\r\n <div *ngIf=\"this.isConversionDaagmaat()\">\r\n <label class=\"form-label\" (mouseenter)=\"showSponningmaatTooltip($event.target)\"\r\n (mouseleave)=\"hideSponningmaatTooltip()\" data-tooltip-type=\"sponningmaat\"><b>Sponningdiepte:</b></label>\r\n <select class=\"form-select\" id=\"Sponningmaat\" formControlName=\"sponningmaat\"\r\n (change)=\"onSponningmaatChanged(index)\">\r\n <option *ngFor=\"let so of sponningmaatOptions\" value=\"{{ so.value }}\">{{ so.value }}mm</option>\r\n </select>\r\n </div>\r\n\r\n <div *ngIf=\"this.isConversionDaagmaat()\">\r\n <label class=\"form-label\"><b>Beglazingsprofiel:</b></label>\r\n <select class=\"form-select\" id=\"Beglazingsprofiel\" formControlName=\"beglazingsprofiel\"\r\n (change)=\"onBeglazingsprofielChanged(index)\">\r\n <option value=\"\" selected>geen</option>\r\n <ng-container *ngFor=\"let glaslat of glaslatten\">\r\n <option *ngIf=\"glaslat.typeAccessoire === 'Beglazingsprofiel'\" [value]=\"glaslat.code\">\r\n {{glaslat.omschrijving\r\n || glaslat.code}}</option>\r\n </ng-container>\r\n </select>\r\n <luv-validationError [show]=\"!!beglazingConflictError\" [errorMessage]=\"beglazingConflictError\">\r\n </luv-validationError>\r\n </div>\r\n\r\n\r\n <div *ngIf=\"this.isConversionDaagmaat() || this.isDKWisselvlak()\">\r\n <label class=\"form-label\"><b>Aanslagprofiel:</b></label>\r\n <select class=\"form-select\" id=\"Aanslagprofiel\" formControlName=\"aanslagprofiel\"\r\n (change)=\"onAanslagprofielChanged(index)\">\r\n <option value=\"\" selected>geen</option>\r\n <ng-container *ngFor=\"let glaslat of glaslatten\">\r\n <option *ngIf=\"glaslat.typeAccessoire === 'Aanslagprofiel'\" [value]=\"glaslat.code\">{{glaslat.omschrijving\r\n || glaslat.code}}</option>\r\n </ng-container>\r\n </select>\r\n <luv-validationError [show]=\"!!aanslagConflictError\" [errorMessage]=\"aanslagConflictError\">\r\n </luv-validationError>\r\n </div>\r\n\r\n <div *ngIf=\"this.isConversionDaagmaat() || this.isDKWisselvlak()\" id=\"GemonteerdWrapper\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" formControlName=\"gemonteerd\" id=\"Gemonteerd\">\r\n <label class=\"form-check-label\" for=\"Gemonteerd\" id=\"GemonteerdLabel\">\r\n Gemonteerd\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"!this.isDKWisselvlak()\">\r\n <label class=\"form-label\"><b>Glaslat:</b></label>\r\n <select class=\"form-select\" id=\"Glaslat\" (change)=\"onGlaslatChanged(index)\"\r\n formControlName=\"glaslat\">\r\n <option value=\"\" selected>geen</option>\r\n <ng-container *ngFor=\"let glaslat of glaslatten\">\r\n <option *ngIf=\"glaslat.typeAccessoire === 'Glaslat'\" [value]=\"glaslat.code\">{{glaslat.omschrijving\r\n || glaslat.code}}</option>\r\n </ng-container>\r\n </select>\r\n <luv-validationError [show]=\"!!glaslatConflictError\" [errorMessage]=\"glaslatConflictError\">\r\n </luv-validationError>\r\n </div>\r\n\r\n <div *ngIf=\"this.isConversionDaagmaat() || this.isDKWisselvlak()\">\r\n <label class=\"form-label\"><b>Damverbreding:</b></label>\r\n <select class=\"form-select\" id=\"Damverbreding\" formControlName=\"damverbreeding\"\r\n (change)=\"onDamverbreedingChanged(index)\">\r\n <option value=\"0\" selected>geen</option>\r\n <option value=\"5\">5mm</option>\r\n <option value=\"10\">10mm</option>\r\n <option value=\"15\">15mm</option>\r\n <option value=\"20\">20mm</option>\r\n </select>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n</div>\r\n<br>","import { Component, OnInit, Input, ChangeDetectorRef, OnChanges, OnDestroy } from \"@angular/core\";\r\nimport { NeutInput } from \"../neut/neut-input\";\r\nimport { FormGroup, FormBuilder, Validators } from '@angular/forms';\r\nimport { NeutModel, NeutUtils } from 'src/app/shared/models/neut.model';\r\nimport { NeutPosition } from '../neut/neut-position';\r\nimport { NeutDto } from 'src/app/shared/api-models/models';\r\nimport { FormComponent } from 'src/app/shared/form-component';\r\nimport { UiStateService } from 'src/app/core/services/ui-state-service';\r\nimport { BaseComponent } from 'src/app/shared/base.component';\r\nimport { filter, takeUntil } from \"rxjs/operators\";\r\nimport { GlaslatDto } from \"../../shared/api-models/glaslatDto\";\r\nimport { GraphicsService } from '../../core/services/graphics.service';\r\nimport { TooltipService } from \"src/app/core/services/tooltip.service\";\r\nimport { DorpelUtils } from \"src/app/shared/models/dorpel-type.model\";\r\n\r\nconst GLASLATTEN_CONFLICT_ERR_MESSAGE = \"In een wisselvlak kan een glaslat, beglazings- of een aanslagprofiel geselecteerd worden, niet meerdere.\";\r\n\r\n@Component({\r\n selector: \"app-daagmaat\",\r\n templateUrl: \"./daagmaat.component.html\",\r\n styleUrls: [\"./daagmaat.component.css\"],\r\n})\r\nexport class DaagmaatComponent extends BaseComponent implements OnInit, OnChanges, OnDestroy {\r\n public formGroup: FormGroup;\r\n public neutModel: NeutModel;\r\n public NeutPosition = NeutPosition;\r\n public isUitvoeringAvailable = false;\r\n private neutenDependentFields: string[] = [\"neut\", \"daagmaat\", \"sponningsoort\", \"maatA\",\r\n \"maatZ\", \"glaslat\", \"sponningmaat\", \"beglazingsprofiel\", \"aanslagprofiel\", \"gemonteerd\", \"damverbreeding\"];\r\n\r\n @Input() public input: NeutInput;\r\n @Input() dorpelCode: string;\r\n @Input() neutDescription: string;\r\n @Input() index: number;\r\n @Input() count: number;\r\n @Input() public dorpelType: 'Binnendorpel' | 'Buitendorpel' | 'Hefschuifdorpel';\r\n @Input() public isDaagmaatA: boolean;\r\n\r\n public glaslatten: GlaslatDto[] = [];\r\n public neuten: NeutDto[] = [];\r\n public sponningmaatOptions: any[] = [];\r\n private defaultSponningmaatValue: number | undefined;\r\n private _formComponent: FormComponent;\r\n public beglazingConflictError: string | null = null;\r\n public aanslagConflictError: string | null = null;\r\n public glaslatConflictError: string | null = null;\r\n\r\n public constructor(private formBuilder: FormBuilder,\r\n private cdRef: ChangeDetectorRef,\r\n private uiStateService: UiStateService,\r\n private graphicsService: GraphicsService,\r\n private tooltipService: TooltipService,) {\r\n super();\r\n }\r\n\r\n public ngOnInit() {\r\n this.neutModel = this.input.model;\r\n this.neuten = this.input.neutenChoices.filter(neut => this.neutMatchesDorpelAndPosition(neut, this.dorpelCode));\r\n this.determineUitvoeringAvailability();\r\n\r\n if (this.dorpelCode) {\r\n this.setSponningmaatOptionsAndSetDefault(this.dorpelCode);\r\n }\r\n\r\n this.formGroup = this.buildForm();\r\n this._formComponent = new FormComponent(this.formGroup);\r\n this.uiStateService.dorpelCode$\r\n .pipe(\r\n filter((dorpelCode) => !!dorpelCode),\r\n takeUntil(this.unsubscribe$))\r\n .subscribe(() => {\r\n this.formGroup = this.buildForm();\r\n this.glaslatten = this.filterGlaslattenChoicesByDorpelsoort(this.input.glaslattenChoices, this.dorpelType);\r\n //we only subscribe to neutenCount field once we know it's enabled\r\n this.subscribeToNeutenCountChanges();\r\n });\r\n }\r\n\r\n private determineUitvoeringAvailability() {\r\n if (this.uiStateService.currentProductType === \"Luvema\") {\r\n this.isUitvoeringAvailable = true;\r\n }\r\n }\r\n\r\n\r\n private filterGlaslattenChoicesByDorpelsoort(glaslattenOptionsList: GlaslatDto[], currentDorpelType?: string): GlaslatDto[] {\r\n if (!currentDorpelType) {\r\n return glaslattenOptionsList;\r\n }\r\n\r\n return glaslattenOptionsList.filter(glaslat => glaslat.dorpelsoort === currentDorpelType);\r\n }\r\n\r\n private subscribeToNeutenCountChanges(): void {\r\n this.uiStateService.neutenCount$\r\n .pipe(takeUntil(this.unsubscribe$))\r\n .subscribe((neutenCount) => {\r\n let enable = !!neutenCount || neutenCount === 0;\r\n this.enableNeutenDependentFields(enable);\r\n });\r\n }\r\n\r\n public ngOnChanges(param) {\r\n if (param.dorpelType) {\r\n this.glaslatten = this.filterGlaslattenChoicesByDorpelsoort(this.input.glaslattenChoices, this.dorpelType);\r\n }\r\n\r\n if (this.neutModel) {\r\n const cachedDaagmaatValue = this.formGroup.get(\"daagmaat\").value;\r\n this.formGroup = this.buildForm();\r\n\r\n if (cachedDaagmaatValue) {\r\n //conserve daagmaat value in case it was filled before selecting the neut and rebuilding the form;\r\n this.uiStateService.updateDaagmaat(cachedDaagmaatValue, this.index);\r\n this.formGroup.get(\"daagmaat\").setValue(cachedDaagmaatValue);\r\n }\r\n\r\n this.resetGlaslattenConflictErrors();\r\n this.enableNeutenDependentFields(!!this.neutModel.omschrijving);\r\n }\r\n\r\n if (param.neutDescription && this.isConversionDaagmaat()) {\r\n this.setSponningmaatOptionsAndSetDefault(this.dorpelCode);\r\n this.uiStateService.populateNeut({\r\n sponningmaat: this.neutModel?.sponningmaat || this.defaultSponningmaatValue\r\n }, this.index);\r\n this.formGroup.get(\"sponningmaat\").setValue(this.neutModel?.sponningmaat || this.defaultSponningmaatValue);\r\n } else {\r\n this.sponningmaatOptions = [];\r\n this.defaultSponningmaatValue = null;\r\n this.formGroup?.get(\"sponningmaat\").setValue(null)\r\n }\r\n }\r\n\r\n public get label(): string {\r\n return NeutUtils.getLabel(this.index, this.count);\r\n }\r\n\r\n public getSelectedNeut(): NeutDto {\r\n if (!this.formGroup) {\r\n return null;\r\n }\r\n const selectedNeutCode = this.formGroup.get('neut');\r\n if (!selectedNeutCode) {\r\n return null;\r\n }\r\n return this.neuten.find(n => n.neutCode === selectedNeutCode.value);\r\n }\r\n\r\n public resetNeutCodeSelection(value) {\r\n if (!this.formGroup) {\r\n return;\r\n }\r\n this.formGroup.get('neut').setValue(value);\r\n }\r\n\r\n public showError(key: string): boolean {\r\n return this._formComponent.showError(key);\r\n }\r\n\r\n public errorMessage(key: string): string {\r\n const formControl = this.formGroup.get(key);\r\n if (formControl.valid || formControl.disabled) {\r\n return '';\r\n }\r\n const [firstError] = Object.keys(formControl.errors);\r\n const error = ValidationMessages[key] ? ValidationMessages[key][firstError] : null;\r\n return error || this._formComponent.errorMessage(key);\r\n }\r\n\r\n private neutMatchesDorpelAndPosition(neut: NeutDto, dorpelCode: string): boolean {\r\n if (neut.dorpelCode !== dorpelCode) {\r\n return false;\r\n }\r\n return neut.positie === NeutUtils.getPositionString(this.neutModel.position);\r\n }\r\n\r\n private enableNeutenDependentFields(shouldEnable: boolean): void {\r\n this.neutenDependentFields.forEach(field => {\r\n let fieldToUpdateValidity = this.formGroup.controls[field];\r\n\r\n if (fieldToUpdateValidity) {\r\n if (shouldEnable) {\r\n fieldToUpdateValidity.enable();\r\n } else {\r\n fieldToUpdateValidity.disable();\r\n }\r\n }\r\n });\r\n }\r\n\r\n private buildForm(): FormGroup {\r\n const formGroup = this.formBuilder.group({\r\n neut: [{ value: this.neutModel?.neut || '', disabled: true }, [Validators.required]],\r\n daagmaat: this.neutModel.position !== NeutPosition.Right ? [{ value: this.neutModel?.daagmaat || '', disabled: true }] : null,\r\n sponningsoort: this.neutModel.position !== NeutPosition.Right ? [{ value: this.neutModel?.sponningsoort || '', disabled: true }] : null,\r\n maatA: this.neutModel.position === NeutPosition.Left ? [{ value: this.neutModel?.maatA || 0, disabled: true }, [Validators.required]] : null,\r\n maatZ: this.neutModel.position === NeutPosition.Right ? [{ value: this.neutModel?.maatZ || 0, disabled: true }, [Validators.required]] : null,\r\n glaslat: [{ value: this.neutModel?.glaslat || '', disabled: true }],\r\n sponningmaat: [{ value: this.neutModel?.sponningmaat, disabled: true }],\r\n beglazingsprofiel: [{ value: this.neutModel?.beglazingsprofiel || '', disabled: true }],\r\n aanslagprofiel: [{ value: this.neutModel?.aanslagprofiel || '', disabled: true }],\r\n gemonteerd: [{ value: this.neutModel?.gemonteerd || false, disabled: true }],\r\n damverbreeding: [{ value: this.neutModel?.damverbreeding || 0, disabled: true }],\r\n position: this.neutModel.position\r\n });\r\n\r\n return formGroup;\r\n }\r\n\r\n public onMaatAChanged(): void {\r\n const maatA = this.formGroup.get('maatA').value;\r\n this.uiStateService.setMaatA(maatA);\r\n }\r\n\r\n public onMaatZChanged(): void {\r\n const maatZ = this.formGroup.get('maatZ').value;\r\n this.uiStateService.setMaatZ(maatZ);\r\n }\r\n\r\n public onDaagmaatChanged(index: number): void {\r\n const daagmaat = this.formGroup.get('daagmaat').value;\r\n this.uiStateService.updateDaagmaat(daagmaat, index);\r\n }\r\n\r\n private resetAanslagprofiel(index): void {\r\n let aanslagprofielField = this.formGroup.get(\"aanslagprofiel\");\r\n if (aanslagprofielField.value) {\r\n this.uiStateService.updateAanslagprofiel(null, index);\r\n aanslagprofielField.setValue(\"\");\r\n this.aanslagConflictError = GLASLATTEN_CONFLICT_ERR_MESSAGE;\r\n }\r\n }\r\n\r\n private resetBeglazingsprofiel(index): void {\r\n let beglazingsField = this.formGroup.get(\"beglazingsprofiel\");\r\n if (beglazingsField.value) {\r\n this.uiStateService.updateBeglazingsprofiel(null, index);\r\n beglazingsField.setValue(\"\");\r\n this.beglazingConflictError = GLASLATTEN_CONFLICT_ERR_MESSAGE;\r\n }\r\n }\r\n\r\n private resetGlaslat(index): void {\r\n let glaslatField = this.formGroup.get(\"glaslat\");\r\n if (glaslatField.value) {\r\n this.uiStateService.updateGlaslat(null, index);\r\n glaslatField.setValue(\"\");\r\n this.glaslatConflictError = GLASLATTEN_CONFLICT_ERR_MESSAGE;\r\n }\r\n }\r\n\r\n private resetGlaslattenConflictErrors(): void {\r\n this.beglazingConflictError = null;\r\n this.aanslagConflictError = null;\r\n this.glaslatConflictError = null;\r\n }\r\n\r\n public onGlaslatChanged(index: number): void {\r\n const glaslat = this.formGroup.get('glaslat').value;\r\n this.uiStateService.updateGlaslat(glaslat, index);\r\n this.resetGlaslattenConflictErrors();\r\n this.resetAanslagprofiel(index);\r\n // this.resetBeglazingsprofiel(index);\r\n this.uiStateService.triggerRedraw();\r\n }\r\n\r\n public onBeglazingsprofielChanged(index: number): void {\r\n const beglazingsprofiel = this.formGroup.get('beglazingsprofiel').value;\r\n this.uiStateService.updateBeglazingsprofiel(beglazingsprofiel, index);\r\n this.resetGlaslattenConflictErrors();\r\n // this.resetGlaslat(index);\r\n this.resetAanslagprofiel(index);\r\n this.uiStateService.triggerRedraw();\r\n }\r\n\r\n public onAanslagprofielChanged(index: number): void {\r\n const aanslagprofiel = this.formGroup.get('aanslagprofiel').value;\r\n this.uiStateService.updateAanslagprofiel(aanslagprofiel, index);\r\n this.resetGlaslattenConflictErrors();\r\n this.resetGlaslat(index);\r\n this.resetBeglazingsprofiel(index);\r\n this.uiStateService.triggerRedraw();\r\n }\r\n\r\n public onDamverbreedingChanged(index: number): void {\r\n const damverbreeding = this.formGroup.get('damverbreeding').value;\r\n this.uiStateService.updateDamverbreeding(damverbreeding, index);\r\n }\r\n\r\n public onSponningsoortChanged(index: number): void {\r\n const sponningsoort = this.formGroup.get('sponningsoort').value;\r\n this.uiStateService.updateSpooningsoort(sponningsoort, index);\r\n this.uiStateService.triggerRedraw();\r\n }\r\n\r\n public isConversionDaagmaat(): boolean {\r\n let isNeutRegularOrW2 = this.neutModel?.omschrijving?.toLocaleLowerCase().indexOf(\"w2\") !== -1 || this.neutModel?.omschrijving?.toLocaleLowerCase().indexOf(\"links\") !== -1 || this.neutModel?.omschrijving?.toLocaleLowerCase().indexOf(\"tussen\") !== -1\r\n return this.dorpelType === \"Buitendorpel\" && (this.neutModel?.omschrijving && !isNeutRegularOrW2);\r\n }\r\n\r\n public isDKWisselvlak(): boolean {\r\n let isNeutDraaiKiep = this.neutModel?.omschrijving?.toLocaleLowerCase().indexOf(\"dk\") !== -1;\r\n return this.dorpelType === \"Buitendorpel\" && (this.neutModel?.omschrijving && isNeutDraaiKiep);\r\n }\r\n\r\n public showSponningmaatTooltip(target: HTMLElement): void {\r\n this.tooltipService.showTooltip(target);\r\n }\r\n\r\n public hideSponningmaatTooltip(): void {\r\n this.tooltipService.hideTooltip();\r\n }\r\n\r\n private setSponningmaatOptionsAndSetDefault(dorpelCode: string) {\r\n let damLevel = DorpelUtils.getDamLevelFromDorpelCode(dorpelCode);\r\n let defaultOption = {\r\n value: damLevel + 10,\r\n isDefault: true,\r\n };\r\n let extraOption = {\r\n value: damLevel + 15,\r\n isDefault: false,\r\n };\r\n\r\n this.sponningmaatOptions = [defaultOption, extraOption];\r\n\r\n if (dorpelCode === \"IW-BU.4272.B\" || dorpelCode === \"IW-BU.4767.B\") {\r\n let exceptionOption = {\r\n value: damLevel + 20,\r\n isDefault: false,\r\n }\r\n this.sponningmaatOptions.push(exceptionOption);\r\n }\r\n\r\n this.defaultSponningmaatValue = defaultOption.value; //ssponningmaat value that is already included in tekening string\r\n }\r\n\r\n public onSponningmaatChanged(index: number) {\r\n const sponningmaat = this.formGroup.get('sponningmaat').value;\r\n\r\n this.uiStateService.updateSponningmaat(parseInt(sponningmaat), index);\r\n this.uiStateService.triggerRedraw();\r\n }\r\n}\r\n\r\nconst ValidationMessages = {\r\n maatA: {\r\n required: 'Selecteer een waarde a.u.b.'\r\n },\r\n sponningsoort: {\r\n required: 'Selecteer een waarde a.u.b.'\r\n },\r\n daagmaat: {\r\n required: 'Selecteer een waarde a.u.b.'\r\n },\r\n maatZ: {\r\n required: 'Selecteer een waarde a.u.b.'\r\n }\r\n}\r\n","<div *ngIf=\"formGroup\" [formGroup]=\"formGroup\">\r\n <div>\r\n <label class=\"form-label\" (mouseenter)=\"showNeutTooltip($event.target)\" (mouseleave)=\"hideNeutTooltip()\"\r\n data-tooltip-type=\"neut\">\r\n <b>{{label }}:</b>\r\n </label>\r\n <input type=\"text\" readonly placeholder=\"Kies\" class=\"form-control\" [ngClass]=\"neutSelectorSpecialClassName\"\r\n id=\"neutDescription\" formControlName=\"neutDescription\" (click)=\"toggleCathegoryList()\" />\r\n <div *ngIf=\"isCathegoryListOpen\" class=\"custom-form-control\">\r\n <ul class=\"cathegories-wrapper\" [ngClass]=\"cathegoriesListSpecialClassName\">\r\n <li *ngFor=\"let neutCathegory of neutenCathegories\" (mouseenter)=\"activateNeutCathegory(neutCathegory)\"\r\n (mouseleave)=\"resetActiveNeutCathegory()\">\r\n <span>{{neutCathegory.description}}</span>\r\n <span class=\"arrow\"><i class=\"fa fa-caret-right\"></i></span>\r\n <ul *ngIf=\"activeNeutCathegory === neutCathegory\" class=\"neut-list-wrapper\">\r\n <li *ngFor=\"let neut of activeNeutCathegory.options\" (click)=\"selectNeut(neut)\">{{neut.omschrijving}}</li>\r\n </ul>\r\n </li>\r\n </ul>\r\n </div>\r\n <luv-validationError [show]=\"showError('neut')\" [errorMessage]=\"errorMessage('neut')\">\r\n </luv-validationError>\r\n <luv-validationError [show]=\"customNeutRemovalErrorMessage\"\r\n [errorMessage]=\"customNeutRemovalErrorMessage\"></luv-validationError>\r\n </div>\r\n\r\n <div *ngIf=\"isVoorsponningActive\" class=\"voorsponning-wrapper\">\r\n <div><label class=\"form-label\"><b>Voorsponning:</b></label></div>\r\n <div class=\"row\">\r\n <div class=\"left-voorsponning col-sm-6\" *ngIf=\"!shouldHideLeftVoorsponning\">\r\n <label *ngIf=\"!shouldHideRightVoorsponning\" class=\"form-label\">Links</label>\r\n <select class=\"form-select\"\r\n [ngClass]=\"{'single': shouldHideRightVoorsponning, 'side-by-side': !shouldHideRightVoorsponning}\"\r\n formControlName=\"linksVoorsponning\" (change)=\"onLinksVoorsponningChanged()\">\r\n <option value=\"0\" [selected]=\"isBinnenDorpel || !input.model.linksVoorsponning\">geen</option>\r\n <option *ngFor=\"let vo of leftVoorsponningOptions\" [value]=\"vo\"\r\n [selected]=\"getVorsponningValue(input.model.linksVoorsponning) == vo\">{{vo}}mm</option>\r\n </select>\r\n </div>\r\n <div class=\"right-voorsponning col-sm-6\" *ngIf=\"!shouldHideRightVoorsponning\">\r\n <label *ngIf=\"!shouldHideLeftVoorsponning\" class=\"form-label\">Rechts</label>\r\n <select class=\"form-select\"\r\n [ngClass]=\"{'single': shouldHideLeftVoorsponning, 'side-by-side': !shouldHideLeftVoorsponning}\"\r\n formControlName=\"rechtsVoorsponning\" (change)=\"onRechtsVoorsponningChanged()\">\r\n <option value=\"0\" [selected]=\"isBinnenDorpel || !input.model.rechtsVoorsponning\">geen</option>\r\n <option *ngFor=\"let vo of rightVoorsponningOptions\" [value]=\"vo\"\r\n [selected]=\"getVorsponningValue(input.model.rechtsVoorsponning) == vo\">{{vo}}mm</option>\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"isSpecialNeut\" class=\"custom-width-wrapper\">\r\n <div class=\"row\">\r\n <div class=\"col-sm-12\">\r\n <label class=\"form-label\"><b>Neutbreedte:</b></label>\r\n <input type=\"number\" class=\"form-control\" [value]=\"specialNeutWidth\" (change)=\"onSpecialNeutCustomWidthChange($event)\" integerOnly/>\r\n </div>\r\n </div>\r\n </div>\r\n</div>","import {\r\n ChangeDetectorRef,\r\n Component,\r\n Input,\r\n Output,\r\n OnChanges,\r\n OnInit,\r\n EventEmitter\r\n} from \"@angular/core\";\r\nimport {\r\n FormBuilder,\r\n FormGroup,\r\n Validators,\r\n} from \"@angular/forms\";\r\nimport { BaseComponent } from \"src/app/shared/base.component\";\r\nimport { NeutModel, NeutUtils, VOORSPONNING_SIZE_MAP, VorsponningSize } from \"src/app/shared/models/neut.model\";\r\nimport { FormComponent } from \"src/app/shared/form-component\";\r\nimport { NeutInput } from \"./neut-input\";\r\nimport { NeutPosition } from \"./neut-position\";\r\nimport { UiStateService } from \"src/app/core/services/ui-state-service\";\r\nimport { filter, takeUntil } from \"rxjs/operators\";\r\nimport { BestellingNeutDto, NeutDto } from \"../../shared/api-models/models\";\r\nimport { GraphicsService } from \"../../core/services/graphics.service\";\r\nimport { TooltipService } from \"../../core/services/tooltip.service\";\r\nimport { DorpelUtils } from \"src/app/shared/models/dorpel-type.model\";\r\n\r\nconst DEFAULT_BUITENDORPEL_VOORSPONNING_VALUE = 6;\r\n\r\nconst MISSING_NEUT_IMAGE_TEXT = \"Er is geen tekening voor deze neut.\";\r\nconst NEUT_VOORSPONNING_ENABLED_KEYWORD = \"Ja\";\r\nconst INCOMPATIBLE_NEUT_AUTOREMOVED_CUSTOM_MESSAGE = \"Kies hier een nieuwe neut, de neut die u hier geselecteerd heeft kan niet hier niet geplaats worden in combinatie met de neut aan de linkerzijde van deze dagmaat.\"\r\n\r\ntype NeutenCathegory = {\r\n description: string,\r\n options: NeutDto[]\r\n}\r\n\r\n@Component({\r\n selector: \"luv-neut\",\r\n templateUrl: \"./neut-horiz.component.html\",\r\n styleUrls: [\"./neut.component.scss\"],\r\n})\r\nexport class NeutComponent extends BaseComponent implements OnInit, OnChanges {\r\n public formGroup: FormGroup;\r\n public neutModel: NeutModel;\r\n public NeutPosition = NeutPosition;\r\n public leftVoorsponningOptions: string[] = [];\r\n public rightVoorsponningOptions: string[] = [];\r\n public customNeutRemovalErrorMessage: string | null = null;\r\n private currentlySelectedNeut: BestellingNeutDto;\r\n private isTooltipResourceCheckInProgress = false;\r\n private shouldAbortTooltipDisplay = false;\r\n\r\n @Input() public input: NeutInput;\r\n @Input() dorpelCode: string;\r\n @Input() index: number;\r\n @Input() count: number;\r\n @Input() schema: string;\r\n\r\n public isSlidingDorpel: boolean;\r\n public isBuitenDorpel: boolean;\r\n public isBinnenDorpel: boolean;\r\n @Output() voorsponningChanged: EventEmitter<any> = new EventEmitter();\r\n @Output() currentNeutChanged: EventEmitter<any> = new EventEmitter();\r\n\r\n public neuten: NeutDto[] = [];\r\n public selectedNeut: NeutDto | null = null;\r\n public neutenCathegories: NeutenCathegory[] = [];\r\n public activeNeutCathegory: NeutenCathegory | null = null;\r\n public isCathegoryListOpen: boolean = false;\r\n public boundClickOutsideListener: any = null;\r\n private _formComponent: FormComponent;\r\n private neutenDependentFields: string[] = [\r\n \"neut\",\r\n \"neutDescription\",\r\n \"linksVoorsponning\",\r\n \"rechtsVoorsponning\",\r\n ];\r\n public voorsponningEnabled: boolean = false;\r\n public shouldHideLeftVoorsponning: boolean = false;\r\n public shouldHideRightVoorsponning: boolean = false;\r\n public isSpecialNeut: boolean = false;\r\n public specialNeutWidth: number = 0;\r\n\r\n private alreadySubscribedToNeutenCount: boolean = false;\r\n private defaultSponningmaatValue: number;\r\n\r\n public constructor(\r\n private formBuilder: FormBuilder,\r\n private cdRef: ChangeDetectorRef,\r\n private uiStateService: UiStateService,\r\n private graphicsService: GraphicsService,\r\n public tooltip: TooltipService\r\n ) {\r\n super();\r\n }\r\n\r\n public ngOnInit() {\r\n this.boundClickOutsideListener = this.clickOutsideListener.bind(this);\r\n this.neutModel = this.input.model;\r\n this.neuten = this.input.neutenChoices.filter((neut) =>\r\n this.neutMatchesDorpelAndPosition(neut, this.dorpelCode)\r\n );\r\n if (this.uiStateService.viewMode === \"Edit\") {\r\n this.setCurrentDorpelType(this.uiStateService.currentDorpel.dorpelCode);\r\n }\r\n this.packNeutenIntoCathegories(this.neuten);\r\n\r\n this.uiStateService.neuten$\r\n .pipe(filter((neuten) => !!neuten))\r\n .pipe(takeUntil(this.unsubscribe$))\r\n .subscribe((neuten) => {\r\n let currentNeut = neuten[this.index];\r\n\r\n if (!currentNeut) {\r\n return;\r\n }\r\n \r\n let prevNeut = neuten[this.index - 1];\r\n this.filterOutIncompatibleNeuten(prevNeut?.neutDescription, currentNeut?.neutCode);\r\n let isLeftVakConversion = this.isConversionVakFollowingNeut(prevNeut?.neutDescription);\r\n let isRightVakConversion = this.isConversionVakFollowingNeut(currentNeut?.neutDescription);\r\n this.setVoorsponningOptions(isLeftVakConversion, isRightVakConversion);\r\n let isFirstNeut = this.index === 0;\r\n let isLastNeut = this.index === neuten.length - 1;\r\n if (!!currentNeut.neutDescription && currentNeut.neutCode !== this.input.model.neut) {\r\n let currentNeutDto: NeutDto = this.uiStateService.getNeutDtoByCodeAndPositie(\r\n currentNeut.neutCode,\r\n currentNeut.positie\r\n );\r\n let isDraaikiep = currentNeutDto ? NeutUtils.isDraaikiep(currentNeutDto.omschrijving) : false; \r\n this.setVoorsponningDefaultValueIfNecessary(isLeftVakConversion, isRightVakConversion, isFirstNeut, isLastNeut, isDraaikiep);\r\n }\r\n });\r\n this.formGroup = this.buildForm();\r\n this._formComponent = new FormComponent(this.formGroup);\r\n //on init (for edit mode) we need to check again if the selected neut has voorsponning activated on the DTO level\r\n\r\n this.computeVoorsponningVisibility();\r\n\r\n this.uiStateService.dorpelCode$\r\n .pipe(\r\n filter((dorpelCode) => !!dorpelCode),\r\n takeUntil(this.unsubscribe$)\r\n )\r\n .subscribe((dorpelCode) => {\r\n this.schema = null; //reset schema value on dorpel change as the neut component does not reinit and keeps old value;\r\n //we only subscribe to sluitpottenCount field once we know it's enabled\r\n\r\n let damLevel = DorpelUtils.getDamLevelFromDorpelCode(dorpelCode);\r\n this.defaultSponningmaatValue = damLevel + 10;\r\n //caution: order is important\r\n this.setCurrentDorpelType(dorpelCode);\r\n this.subscribeToNeutenCountChanges();\r\n // this.setDefaultVoorsponningValues(); // !!! this might be reinstated\r\n });\r\n this.uiStateService.schema$\r\n .pipe(takeUntil(this.unsubscribe$))\r\n .subscribe((schema) => {\r\n this.toggleNeutDisablingBySchema(schema);\r\n });\r\n this.toggleNeutDisablingBySchema();\r\n }\r\n\r\n public isConversionVakFollowingNeut(neutDescription: string): boolean {\r\n /**\r\n * we usually determined if a neut is tussen by targeting the word tussen in description which was only included in regular type neuten\r\n * now draaikiep also include work tussen in description ..so we needed to adjust the rule by excluding dk tussen \r\n * \r\n * also, all draaikiep are determining a conversion neut\r\n */\r\n if (!neutDescription) {\r\n return;\r\n }\r\n let isDraaikiep = neutDescription.toLocaleLowerCase().indexOf(\"dk\") !== -1;\r\n let isNeutRegularOrW2 =\r\n neutDescription.toLocaleLowerCase().indexOf(\"w2\") !== -1 ||\r\n neutDescription.toLocaleLowerCase().indexOf(\"links\") !== -1 ||\r\n (neutDescription.toLocaleLowerCase().indexOf(\"tussen\") !== -1 && !isDraaikiep)\r\n \r\n return this.isBuitenDorpel && (isDraaikiep || !isNeutRegularOrW2);\r\n }\r\n\r\n private setVoorsponningDefaultValueIfNecessary(\r\n isLeftVakConversion: boolean,\r\n isRightVakConversion: boolean,\r\n isFirstNeut: boolean,\r\n isLastNeut: boolean,\r\n isDraaikiep): void {\r\n //reset values\r\n this.uiStateService.populateLeftVoorsponning(this.index, null);\r\n this.uiStateService.populateRightVoorsponning(this.index, null);\r\n this.formGroup.get(\"linksVoorsponning\").setValue(\"0\");\r\n this.formGroup.get(\"rechtsVoorsponning\").setValue(\"0\");\r\n\r\n if(isDraaikiep) {\r\n return;\r\n }\r\n\r\n if (this.isBuitenDorpel && !isLeftVakConversion && !isFirstNeut) {\r\n const linksVoorsponning = VOORSPONNING_SIZE_MAP[\"6x19\"];\r\n this.uiStateService.populateLeftVoorsponning(this.index, linksVoorsponning);\r\n this.formGroup.get(\"linksVoorsponning\").setValue(\"6x19\");\r\n }\r\n\r\n if (this.isBuitenDorpel && !isRightVakConversion && !isLastNeut) {\r\n const rechtsVoorsponning = VOORSPONNING_SIZE_MAP[\"6x19\"];\r\n this.uiStateService.populateRightVoorsponning(this.index, rechtsVoorsponning);\r\n this.formGroup.get(\"rechtsVoorsponning\").setValue(\"6x19\");\r\n }\r\n }\r\n\r\n public getVorsponningValue(vorsponningSize: VorsponningSize): string {\r\n return NeutUtils.getVorsponningValue(vorsponningSize);\r\n }\r\n\r\n private updateNeutenChoices(neuten: NeutDto[], prevNeutDescription: string) {\r\n if (NeutUtils.isRegular(prevNeutDescription)) {\r\n this.neuten = neuten.filter((neut) => {\r\n let description = neut.omschrijving;\r\n return NeutUtils.isRegularTussen(description) || NeutUtils.isRegularRight(description) || NeutUtils.isW3(description) || NeutUtils.isSpecial(description);\r\n });\r\n } else if (NeutUtils.isW1(prevNeutDescription) || NeutUtils.isW5(prevNeutDescription) || NeutUtils.isW3(prevNeutDescription)) {\r\n this.neuten = neuten.filter((neut) => {\r\n let description = neut.omschrijving;\r\n return NeutUtils.isW2(description) || NeutUtils.isW5(description) || NeutUtils.isW4(description) || NeutUtils.isDKMidRight(description) || NeutUtils.isSpecial(description);\r\n });\r\n } else if (NeutUtils.isW2(prevNeutDescription)) {\r\n this.neuten = neuten.filter((neut) => {\r\n let description = neut.omschrijving;\r\n return NeutUtils.isRegularTussen(description) || NeutUtils.isRegularRight(description) || NeutUtils.isW3(description);\r\n });\r\n } else if (NeutUtils.isDKLeft(prevNeutDescription)) {\r\n this.neuten = neuten.filter((neut) =>{\r\n let description = neut.omschrijving;\r\n return NeutUtils.isDKRight(description) || NeutUtils.isDKMidBoth(description) || NeutUtils.isDKMidLeft(description) || NeutUtils.isSpecial(description);\r\n });\r\n } else if (NeutUtils.isDKMidLeft(prevNeutDescription)) {\r\n this.neuten = neuten.filter((neut) =>{\r\n let description = neut.omschrijving;\r\n return NeutUtils.isDKMidRight(description) || NeutUtils.isW2(description) || NeutUtils.isW5(description) || NeutUtils.isW4(description) || NeutUtils.isSpecial(description);\r\n });\r\n } else if (NeutUtils.isDKMidRight(prevNeutDescription) || NeutUtils.isDKMidBoth(prevNeutDescription)) {\r\n this.neuten = neuten.filter((neut) =>{\r\n let description = neut.omschrijving;\r\n return NeutUtils.isDKMidLeft(description) || NeutUtils.isDKMidBoth(description) || NeutUtils.isDKRight(description) || NeutUtils.isSpecial(description);\r\n });\r\n }\r\n }\r\n\r\n public filterOutIncompatibleNeuten(prevNeutDescription: string, currentNeutCode: string) {\r\n //TODO: maybe think of a more neat approach when we can identify neut via flags and not description matching\r\n let neuten = this.input.neutenChoices.filter((neut) =>\r\n this.neutMatchesDorpelAndPosition(neut, this.dorpelCode)\r\n );\r\n if (!prevNeutDescription || !neuten.length) {\r\n this.neuten = neuten;\r\n this.neutenCathegories = [];\r\n this.packNeutenIntoCathegories(this.neuten);\r\n return;\r\n }\r\n\r\n this.updateNeutenChoices(neuten, prevNeutDescription);\r\n\r\n if (currentNeutCode && !this.neuten.find(neut => neut.neutCode === currentNeutCode)) {\r\n this.customNeutRemovalErrorMessage = INCOMPATIBLE_NEUT_AUTOREMOVED_CUSTOM_MESSAGE;\r\n this.selectedNeut = null;\r\n this.neutModel.omschrijving = \"\";\r\n this.neutModel.neut = \"\";\r\n const cleanNeutOrder: BestellingNeutDto = {\r\n neutCode: \"\",\r\n neutDescription: \"\",\r\n isInHouseNeut: null,\r\n };\r\n this.uiStateService.populateNeut(cleanNeutOrder, this.index);\r\n this.resetNeutCodeSelection();\r\n }\r\n this.neutenCathegories = [];\r\n this.packNeutenIntoCathegories(this.neuten);\r\n }\r\n\r\n public toggleCathegoryList() {\r\n this.isCathegoryListOpen = !this.isCathegoryListOpen;\r\n\r\n if (this.isCathegoryListOpen) {\r\n document.body.addEventListener(\"click\", this.boundClickOutsideListener, true);\r\n } else {\r\n document.body.removeEventListener(\"click\", this.boundClickOutsideListener, true);\r\n }\r\n }\r\n\r\n private clickOutsideListener(e: any) {\r\n if (!e.target.closest(`.${this.neutSelectorSpecialClassName}`) && !e.target.closest(`.${this.cathegoriesListSpecialClassName}`)) {\r\n this.closeCathegoryList();\r\n }\r\n }\r\n\r\n public closeCathegoryList() {\r\n this.isCathegoryListOpen = false;\r\n document.body.removeEventListener(\"click\", this.boundClickOutsideListener, true);\r\n }\r\n\r\n public selectNeut(selectedNeut: NeutDto) {\r\n this.selectedNeut = selectedNeut;\r\n this.formGroup.get(\"neut\").setValue(selectedNeut.neutCode);\r\n this.formGroup.get(\"neutDescription\").setValue(selectedNeut.omschrijving);\r\n this.customNeutRemovalErrorMessage = null;\r\n\r\n this.onNeutSelected();\r\n this.closeCathegoryList();\r\n this.resetActiveNeutCathegory();\r\n }\r\n\r\n public activateNeutCathegory(neutCathegory: NeutenCathegory) {\r\n this.activeNeutCathegory = neutCathegory;\r\n }\r\n\r\n public resetActiveNeutCathegory(): void {\r\n this.activeNeutCathegory = null;\r\n }\r\n\r\n private packNeutenIntoCathegories(neuten: NeutDto[]) {\r\n let regulier = [];\r\n let wissel = [];\r\n let draai = [];\r\n let special = [];\r\n\r\n neuten.forEach((neut: NeutDto) => {\r\n if (NeutUtils.isRegular(neut.omschrijving)) {\r\n regulier.push(neut);\r\n }\r\n\r\n if (NeutUtils.isWissel(neut.omschrijving)) {\r\n wissel.push(neut);\r\n }\r\n\r\n if (NeutUtils.isDraaikiep(neut.omschrijving)) {\r\n draai.push(neut)\r\n }\r\n\r\n if (NeutUtils.isSpecial(neut.omschrijving)) {\r\n special.push(neut)\r\n }\r\n });\r\n\r\n if (regulier.length) {\r\n this.neutenCathegories.push({\r\n description: \"Regulier\",\r\n options: regulier\r\n });\r\n }\r\n\r\n if (wissel.length) {\r\n this.neutenCathegories.push({\r\n description: \"Wissel\",\r\n options: wissel\r\n });\r\n }\r\n\r\n if (draai.length) {\r\n this.neutenCathegories.push({\r\n description: \"Draai/Kiep\",\r\n options: draai\r\n });\r\n }\r\n\r\n if (special.length) {\r\n this.neutenCathegories.push({\r\n description: \"Special\",\r\n options: special\r\n });\r\n }\r\n }\r\n\r\n private setCurrentDorpelType(dorpelCode) {\r\n const chosenDorpel = this.uiStateService.dorpelChoices.find(\r\n (d) => d.dorpelCode === dorpelCode\r\n );\r\n let currentDorpelType = chosenDorpel.dorpelsoort;\r\n\r\n this.isSlidingDorpel = currentDorpelType === \"Hefschuifdorpel\";\r\n this.isBuitenDorpel = currentDorpelType === \"Buitendorpel\";\r\n this.isBinnenDorpel = currentDorpelType === \"Binnendorpel\";\r\n }\r\n\r\n private setVoorsponningOptions(isLeftVakConversion: boolean, isRightVakConversion: boolean) {\r\n const isSpecialCaseException = this.uiStateService.currentDorpel.dorpelCode === \"IW-BI.4272.B\";\r\n const { leftOptions, rightOptions } = NeutUtils.getVoorsponningOptions(isLeftVakConversion, isRightVakConversion, isSpecialCaseException, this.isBinnenDorpel, this.isBuitenDorpel)\r\n this.leftVoorsponningOptions = leftOptions;\r\n this.rightVoorsponningOptions = rightOptions;\r\n }\r\n\r\n computeVoorsponningVisibility(): void {\r\n this.shouldHideLeftVoorsponning =\r\n this.neutModel.position === NeutPosition.Left;\r\n this.shouldHideRightVoorsponning =\r\n this.neutModel.position === NeutPosition.Right;\r\n }\r\n\r\n updateVoorsponningVisibility(): void {\r\n if (!this.formGroup) {\r\n //safety check\r\n return;\r\n }\r\n\r\n if (this.shouldHideLeftVoorsponning) {\r\n this.formGroup.controls[\"linksVoorsponning\"].disable();\r\n }\r\n\r\n if (this.shouldHideRightVoorsponning) {\r\n this.formGroup.controls[\"rechtsVoorsponning\"].disable();\r\n }\r\n }\r\n\r\n toggleNeutDisablingBySchema(schema?: string): void {\r\n if (!this.isSlidingDorpel) {\r\n return;\r\n }\r\n\r\n let neutControl = this.formGroup.controls[\"neut\"];\r\n let neutDescription = this.formGroup.controls[\"neutDescription\"];\r\n let hasSchema = !!(this.uiStateService.currentDorpel.schema || schema);\r\n\r\n if (!hasSchema) {\r\n neutControl.disable();\r\n neutDescription.disable();\r\n } else {\r\n neutControl.enable();\r\n neutDescription.enable();\r\n }\r\n }\r\n\r\n //DEFAULT VOORSPONNING VALUES\r\n // setDefaultVoorsponningValues(): void {\r\n // let linksVoorsponning = this.formGroup.get(\"linksVoorsponning\");\r\n // let rechtsVoorsponning = this.formGroup.get(\"rechtsVoorsponning\");\r\n\r\n // if (this.isBuitenDorpel) {\r\n // if(!linksVoorsponning.disabled) {\r\n // linksVoorsponning.setValue(DEFAULT_BUITENDORPEL_VOORSPONNING_VALUE);\r\n // this.uiStateService.populateLeftVoorsponning(this.index, DEFAULT_BUITENDORPEL_VOORSPONNING_VALUE);\r\n // } else {\r\n // linksVoorsponning.setValue(null);\r\n // }\r\n\r\n // if(!rechtsVoorsponning.disabled) {\r\n // rechtsVoorsponning.setValue(DEFAULT_BUITENDORPEL_VOORSPONNING_VALUE);\r\n // this.uiStateService.populateRightVoorsponning(this.index, DEFAULT_BUITENDORPEL_VOORSPONNING_VALUE);\r\n // } else {\r\n // rechtsVoorsponning.setValue(null);\r\n // }\r\n // }\r\n\r\n // this.cdRef.detectChanges();\r\n // }\r\n\r\n private subscribeToNeutenCountChanges(): void {\r\n if (this.alreadySubscribedToNeutenCount) {\r\n return;\r\n }\r\n\r\n this.uiStateService.neutenCount$\r\n .pipe(takeUntil(this.unsubscribe$))\r\n .subscribe((neutenCount) => {\r\n let enable = !!neutenCount || neutenCount === 0;\r\n this.enableNeutenDependentFields(enable);\r\n // this.setDefaultVoorsponningValues(); // !!! this might be reinstated\r\n });\r\n this.alreadySubscribedToNeutenCount = true;\r\n }\r\n\r\n private enableNeutenDependentFields(shouldEnable: boolean): void {\r\n this.voorsponningEnabled = shouldEnable;\r\n this.neutenDependentFields.forEach((field) => {\r\n let fieldToUpdate = this.formGroup.controls[field];\r\n\r\n if (fieldToUpdate) {\r\n if (shouldEnable) {\r\n if (this.isVoorsponningDisabledCase(fieldToUpdate)) {\r\n return;\r\n }\r\n fieldToUpdate.enable();\r\n } else {\r\n fieldToUpdate.disable();\r\n }\r\n }\r\n });\r\n\r\n this.toggleNeutDisablingBySchema();\r\n }\r\n\r\n isVoorsponningDisabledCase(fieldToUpdate) {\r\n return (\r\n (fieldToUpdate === this.formGroup.controls[\"linksVoorsponning\"] &&\r\n this.neutModel.position === NeutPosition.Left) ||\r\n (fieldToUpdate === this.formGroup.controls[\"rechtsVoorsponning\"] &&\r\n this.neutModel.position === NeutPosition.Right)\r\n );\r\n }\r\n\r\n public ngOnChanges(param) {\r\n this.neutModel = this.input.model;\r\n if (param.dorpelCode) {\r\n const dorpelCode = param.dorpelCode.currentValue;\r\n if (dorpelCode) {\r\n this.neuten = this.input.neutenChoices.filter((neut) =>\r\n this.neutMatchesDorpelAndPosition(neut, this.dorpelCode)\r\n );\r\n if (param.dorpelCode.previousValue) {\r\n this.resetNeutCodeSelection();\r\n }\r\n this.currentlySelectedNeut = null;\r\n }\r\n }\r\n if (param.count) {\r\n this.neuten = this.input.neutenChoices.filter((neut) =>\r\n this.neutMatchesDorpelAndPosition(neut, this.dorpelCode)\r\n );\r\n if (this.formGroup) {\r\n const value = this.formGroup.get(\"neut\").value;\r\n if (\r\n value &&\r\n this.neuten.length > 0 &&\r\n this.neuten.findIndex((n) => n.neutCode === value) < 0\r\n ) {\r\n this.resetNeutCodeSelection();\r\n }\r\n }\r\n this.computeVoorsponningVisibility();\r\n this.updateVoorsponningVisibility();\r\n }\r\n\r\n // FILTER BY SCHEMA\r\n // if (param.schema) {\r\n // this.neuten = this.input.neutenChoices.filter(neut => this.neutMatchesDorpelAndPosition(neut, this.dorpelCode))\r\n // .filter(neut => this.neutMatchesSchema(neut, this.schema));\r\n // if (param.schema.previousValue) {\r\n // this.resetNeutCodeSelection('');\r\n // }\r\n // }\r\n\r\n this.cdRef.detectChanges();\r\n }\r\n\r\n public get label(): string {\r\n return NeutUtils.getLabel(this.index, this.count, this.isSlidingDorpel);\r\n }\r\n\r\n public get neutSelectorSpecialClassName(): string {\r\n return `neutSelector${this.index}`;\r\n }\r\n\r\n public get cathegoriesListSpecialClassName(): string {\r\n return `cathegoriesList${this.index}`;\r\n }\r\n\r\n\r\n public get isVoorsponningActive(): boolean {\r\n let selectedNeut: NeutDto = this.getSelectedNeut();\r\n return !!selectedNeut && !NeutUtils.isSpecial(selectedNeut.omschrijving) && !this.isSlidingDorpel && (this.uiStateService.currentProductType === \"Luvema\" || this.uiStateService.currentProductType === \"Isowel\")\r\n }\r\n\r\n\r\n onLinksVoorsponningChanged(): void {\r\n const linksVoorsponning = VOORSPONNING_SIZE_MAP[this.formGroup.get(\"linksVoorsponning\").value];\r\n //tell parent component to set same value on the mirrored vorsponning of the previous neut\r\n this.voorsponningChanged.emit({\r\n targetProperty: \"rechtsVoorsponning\",\r\n value: linksVoorsponning,\r\n targetNeutIndex: this.index - 1,\r\n });\r\n this.uiStateService.populateLeftVoorsponning(this.index, linksVoorsponning);\r\n if (this.uiStateService.currentDorpel.zaagmaat) {\r\n this.uiStateService.triggerRedraw();\r\n }\r\n }\r\n\r\n onRechtsVoorsponningChanged(): void {\r\n const rechtsVoorsponning = VOORSPONNING_SIZE_MAP[this.formGroup.get(\"rechtsVoorsponning\").value];\r\n //tell parent component to set same value on the mirrored vorsponning of the next neut\r\n this.voorsponningChanged.emit({\r\n targetProperty: \"linksVoorsponning\",\r\n value: rechtsVoorsponning,\r\n targetNeutIndex: this.index + 1,\r\n });\r\n this.uiStateService.populateRightVoorsponning(\r\n this.index,\r\n rechtsVoorsponning\r\n );\r\n if (this.uiStateService.currentDorpel.zaagmaat) {\r\n this.uiStateService.triggerRedraw();\r\n }\r\n }\r\n\r\n setLinksVoorsponningValue(voorsponningSize: VorsponningSize): void {\r\n //method called by parent component to mirror-match vorsponning values\r\n if (this.formGroup.get(\"position\").value === NeutPosition.Left) {\r\n return;\r\n }\r\n this.formGroup.get(\"linksVoorsponning\").setValue(NeutUtils.getVorsponningValue(voorsponningSize) || \"0\");\r\n this.uiStateService.populateLeftVoorsponning(this.index, voorsponningSize);\r\n }\r\n\r\n setRechtsVoorsponningValue(voorsponningSize: VorsponningSize): void {\r\n //method called by parent component to mirror-match vorsponning values\r\n if (this.formGroup.get(\"position\").value === NeutPosition.Right) {\r\n return;\r\n }\r\n this.formGroup.get(\"rechtsVoorsponning\").setValue(NeutUtils.getVorsponningValue(voorsponningSize) || \"0\");\r\n this.uiStateService.populateRightVoorsponning(this.index, voorsponningSize);\r\n }\r\n\r\n public getSelectedNeut(): NeutDto {\r\n if (!this.formGroup) {\r\n return null;\r\n }\r\n const selectedNeutCode = this.formGroup.get(\"neut\");\r\n if (!selectedNeutCode) {\r\n return null;\r\n }\r\n return this.neuten.find((n) => n.neutCode === selectedNeutCode.value);\r\n }\r\n\r\n public onSpecialNeutCustomWidthChange(event: any) {\r\n let customWidth = event.target.value ? parseInt(event.target.value) : null;\r\n this.specialNeutWidth = customWidth;\r\n this.uiStateService.populateNeut({customWidth: customWidth}, this.index);\r\n this.uiStateService.updateSpecialNeutCustomWidth(customWidth);\r\n }\r\n\r\n public onNeutSelected() {\r\n //TODO: check this\r\n\r\n const neut: NeutDto = this.getSelectedNeut();\r\n const neutOrder: BestellingNeutDto = {\r\n neutCode: neut.neutCode,\r\n neutDescription: neut.omschrijving,\r\n positie: neut.positie,\r\n isInHouseNeut: neut.isInHouseNeut,\r\n //reset daagmaat conditional values:\r\n aanslagprofiel: undefined,\r\n beglazingsprofiel: undefined,\r\n glaslat: undefined,\r\n gemonteerd: undefined,\r\n damverbreeding: undefined,\r\n customWidth: undefined\r\n };\r\n this.currentlySelectedNeut = neutOrder;\r\n \r\n this.isSpecialNeut = neut ? NeutUtils.isSpecial(neut.omschrijving) : false;\r\n if (this.isSpecialNeut) {\r\n this.specialNeutWidth = parseInt(neut?.neutbreedte) || 0;\r\n neutOrder.customWidth = this.specialNeutWidth;\r\n }\r\n\r\n this.uiStateService.populateNeut(neutOrder, this.index);\r\n this.currentNeutChanged.emit(neutOrder);\r\n }\r\n\r\n public showNeutTooltip(target: HTMLElement) {\r\n let currentNeutSponningmaat = this.uiStateService.currentDorpel.neuten[this.index].sponningmaat;\r\n let sponningmaatValue = currentNeutSponningmaat || this.defaultSponningmaatValue;\r\n let neutCode = this.currentlySelectedNeut?.neutCode;\r\n\r\n if (neutCode) {\r\n //we have a selected neut so we show a custom tooltip\r\n if (neutCode.indexOf(\".W\") === -1) {\r\n //if not wissel neut, even if we have the sponningmaat value set for the current dorpel, we don't use that\r\n //in determining the file name\r\n sponningmaatValue = null;\r\n }\r\n\r\n let neutImageName = this.getCustomNeutTooltipImageName(\r\n neutCode,\r\n sponningmaatValue\r\n );\r\n let loadImageTooltip = () => {\r\n this.isTooltipResourceCheckInProgress = false;\r\n\r\n if (this.shouldAbortTooltipDisplay) {\r\n this.shouldAbortTooltipDisplay = false;\r\n return;\r\n }\r\n\r\n this.tooltip.showTooltip(target, {\r\n customImageName: neutImageName,\r\n imageOnly: true,\r\n });\r\n };\r\n let loadMissingImageTooltip = () => {\r\n this.isTooltipResourceCheckInProgress = false;\r\n\r\n if (this.shouldAbortTooltipDisplay) {\r\n this.shouldAbortTooltipDisplay = false;\r\n return;\r\n }\r\n\r\n this.tooltip.showTooltip(target, {\r\n customTextDescription: MISSING_NEUT_IMAGE_TEXT,\r\n descriptionOnly: true,\r\n });\r\n };\r\n this.attemptResourceLoad(\r\n `${this.tooltip.assetsPath}${neutImageName}`,\r\n loadImageTooltip,\r\n loadMissingImageTooltip\r\n );\r\n } else {\r\n //we show the default tooltip (no neut selection)\r\n this.tooltip.showTooltip(target);\r\n }\r\n }\r\n\r\n public hideNeutTooltip(): void {\r\n if (this.isTooltipResourceCheckInProgress) {\r\n this.shouldAbortTooltipDisplay = true;\r\n }\r\n this.tooltip.hideTooltip();\r\n }\r\n\r\n private attemptResourceLoad(\r\n resourcePath: string,\r\n loadCallback,\r\n failCallback\r\n ): void {\r\n this.shouldAbortTooltipDisplay = false;\r\n this.isTooltipResourceCheckInProgress = true;\r\n let img = new Image();\r\n img.onload = loadCallback;\r\n img.onerror = failCallback;\r\n img.src = resourcePath;\r\n }\r\n\r\n private getCustomNeutTooltipImageName(\r\n neutCode: string,\r\n sponningmaatValue?: number\r\n ): string {\r\n return (\r\n `${neutCode}` +\r\n (sponningmaatValue ? `-S${sponningmaatValue}.png` : `.png`)\r\n );\r\n }\r\n\r\n public resetNeutCodeSelection() {\r\n if (!this.formGroup) {\r\n return;\r\n }\r\n this.formGroup.get(\"neut\").setValue(\"\");\r\n this.formGroup.get(\"neutDescription\").setValue(\"\");\r\n }\r\n\r\n public showError(key: string): boolean {\r\n return this._formComponent.showError(key);\r\n }\r\n\r\n public errorMessage(key: string): string {\r\n const formControl = this.formGroup.get(key);\r\n if (formControl.valid || formControl.disabled) {\r\n return \"\";\r\n }\r\n const [firstError] = Object.keys(formControl.errors);\r\n const error = ValidationMessages[key]\r\n ? ValidationMessages[key][firstError]\r\n : null;\r\n return error || this._formComponent.errorMessage(key);\r\n }\r\n\r\n private neutMatchesDorpelAndPosition(\r\n neut: NeutDto,\r\n dorpelCode: string\r\n ): boolean {\r\n if (!dorpelCode) {\r\n return false;\r\n }\r\n\r\n if (neut.dorpelCode !== dorpelCode) {\r\n return false;\r\n }\r\n\r\n return (\r\n neut.positie === NeutUtils.getPositionString(this.neutModel.position)\r\n );\r\n }\r\n\r\n // FILTER BY SCHEMA\r\n // private neutMatchesSchema(neut: NeutDto, schema: string): boolean {\r\n // return neut.schema.indexOf(schema) !== -1;\r\n // }\r\n\r\n private buildForm(): FormGroup {\r\n const formGroup = this.formBuilder.group({\r\n neut: [\r\n { value: this.neutModel?.neut || \"\", disabled: true },\r\n [Validators.required],\r\n ],\r\n position: this.neutModel.position,\r\n linksVoorsponning: [\r\n {\r\n value: NeutUtils.getVorsponningValue(this.neutModel?.linksVoorsponning) || \"0\",\r\n disabled: !this.voorsponningEnabled,\r\n },\r\n ],\r\n rechtsVoorsponning: [\r\n {\r\n value: NeutUtils.getVorsponningValue(this.neutModel?.rechtsVoorsponning) || \"0\",\r\n disabled: !this.voorsponningEnabled,\r\n },\r\n ],\r\n neutDescription: [\r\n { value: this.neutModel?.omschrijving || \"\", disabled: true },\r\n [Validators.required],\r\n ]\r\n });\r\n\r\n return formGroup;\r\n }\r\n}\r\n\r\nconst ValidationMessages = {\r\n neut: {\r\n required: \"Selecteer een waarde a.u.b.\",\r\n },\r\n maatA: {\r\n required: \"Selecteer een waarde a.u.b.\",\r\n },\r\n sponningsoort: {\r\n required: \"Selecteer een waarde a.u.b.\",\r\n },\r\n maatZ: {\r\n required: \"Selecteer een waarde a.u.b.\",\r\n },\r\n};\r\n","<div class=\"container-fluid\" *ngIf=\"neutInputModels.length > 0\">\r\n <div class=\"row align-items-start justify-content-center\" *ngIf=\"!isCurrentDoorSliding && !isNeutenSectionInvalid && !showDealerContactMessage\">\r\n <div class=\"col bg-white py-4 mx-2 my-2 rounded-4 restricted-size-panel\">\r\n <app-daagmaat\r\n #daagmaatA\r\n [input]=\"neutInputModels[0]\"\r\n [count]=\"count\"\r\n [dorpelCode]=\"currentDorpelCode\"\r\n [dorpelType]=\"currentDorpelType\"\r\n [index]=\"0\"\r\n isDaagmaatA=\"true\"\r\n ></app-daagmaat>\r\n </div>\r\n \r\n <ng-container *ngFor=\"let neut of neutInputModels; let i = index\">\r\n <div class=\"col bg-white py-4 mx-2 my-2 rounded-4 restricted-size-panel\">\r\n <luv-neut\r\n #neut\r\n [input]=\"neut\"\r\n [count]=\"count\"\r\n [dorpelCode]=\"currentDorpelCode\"\r\n [index]=\"i\"\r\n (voorsponningChanged)=\"onNeutVoorsponningChanged($event)\"\r\n (currentNeutChanged)=\"onNeutCodeChanged($event, i)\"\r\n ></luv-neut>\r\n </div>\r\n <div class=\"col bg-white py-4 mx-2 my-2 rounded-4 restricted-size-panel\">\r\n <app-daagmaat\r\n #daagmaat\r\n [input]=\"neut\"\r\n [count]=\"count\"\r\n [neutDescription]=\"neut.model.omschrijving\"\r\n [dorpelCode]=\"currentDorpelCode\"\r\n [dorpelType]=\"currentDorpelType\"\r\n [index]=\"i\"\r\n ></app-daagmaat>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <div class=\"row align-items-start\" *ngIf=\"showDealerContactMessage\">\r\n <div class=\"illogical-combination-message\">\r\n <span>De samenstelling van deze dorpel is niet geschikt om te tekenen. Upload de tekening als bijlage in het vorige scherm of neem direct contact op met ons op +31 (0)317 - 612878</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row align-items-start justify-content-center\" *ngIf=\"isCurrentDoorSliding\">\r\n <ng-container *ngFor=\"let neut of neutInputModels; let i = index\">\r\n <div class=\"col bg-white py-4 mx-2 my-2 rounded-4 restricted-size-panel\">\r\n <luv-neut\r\n #neut\r\n [input]=\"neut\"\r\n [count]=\"count\"\r\n [dorpelCode]=\"currentDorpelCode\"\r\n [schema]=\"currentSchema\"\r\n [index]=\"i\"\r\n ></luv-neut>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div [formGroup]=\"formGroup\" class=\"row align-items-start justify-content-center\" *ngIf=\"canShowRailOptions\">\r\n <div class=\"col bg-white py-4 mx-2 my-2 rounded-4 col-xl-2 justify-content-center restricted-size-panel\">\r\n <label class=\"form-label\"><b>Rail:</b></label>\r\n <select\r\n class=\"form-select\"\r\n id=\"railType\"\r\n formControlName=\"railType\"\r\n (change)=\"onRailTypeChange()\"\r\n >\r\n <option value=\"\" disabled selected hidden>Kies</option>\r\n <option value=\"Hoge rail\">Hoge rail</option>\r\n <option value=\"Lage rail\">Lage rail</option>\r\n </select>\r\n </div>\r\n </div>\r\n</div>\r\n","import {\r\n ChangeDetectorRef,\r\n Component,\r\n OnInit,\r\n QueryList,\r\n ViewChildren,\r\n ViewChild,\r\n} from \"@angular/core\";\r\nimport { forkJoin, Observable, of } from \"rxjs\";\r\nimport { UiStateService } from \"../core/services/ui-state-service\";\r\nimport { filter, takeUntil, tap } from \"rxjs/internal/operators\";\r\nimport { BaseComponent } from \"../shared/base.component\";\r\nimport { NeutModel, NeutUtils, VOORSPONNING_SIZE_MAP } from \"../shared/models/neut.model\";\r\nimport { NeutComponent } from \"./neut/neut.component\";\r\nimport { NeutInput } from \"./neut/neut-input\";\r\nimport { BackendService } from \"../core/services/backend.service\";\r\nimport { NeutDto } from \"../shared/api-models/neutDto\";\r\nimport { ModelFactory } from \"../shared/models/model-factory\";\r\nimport { NeutPosition } from \"./neut/neut-position\";\r\n\r\nimport { DaagmaatComponent } from \"./daagmaat/daagmaat.component\";\r\nimport { GlaslatDto } from \"../shared/api-models/glaslatDto\";\r\n\r\nimport { FormGroup, FormBuilder } from \"@angular/forms\";\r\n\r\n\r\n@Component({\r\n selector: \"luv-neuten\",\r\n templateUrl: \"./neuten-horiz.component.html\",\r\n styleUrls: [\"./neuten.component.scss\"],\r\n})\r\nexport class NeutenComponent extends BaseComponent implements OnInit {\r\n public neutInputModels: NeutInput[] = [];\r\n\r\n @ViewChildren(\"neut\") neutComponents: QueryList<NeutComponent>;\r\n @ViewChildren(\"daagmaat\") daagmatComponents: QueryList<DaagmaatComponent>;\r\n @ViewChild(\"daagmaatA\") daagmatAComponent: DaagmaatComponent;\r\n\r\n public currentDorpelCode: string;\r\n public currentDorpelType: \"Binnendorpel\" | \"Buitendorpel\" | \"Hefschuifdorpel\";\r\n public isCurrentDoorSliding: boolean;\r\n public count: number = 0;\r\n private neuten: NeutDto[] = [];\r\n private filteredGlaslatten: GlaslatDto[] = [];\r\n public canShowRailOptions: boolean = false;\r\n public isNeutenSectionInvalid: boolean = false;\r\n public showDealerContactMessage: boolean = false;\r\n public currentSchema: string = null; //TODO: why set this here and pass down to neuten when in alternative this could be read off the uistate\r\n public formGroup: FormGroup;\r\n public showSponningmaat: boolean = false;\r\n\r\n public constructor(\r\n private uiStateService: UiStateService,\r\n private backendService: BackendService,\r\n private formBuilder: FormBuilder,\r\n private cdRef: ChangeDetectorRef,\r\n ) {\r\n super();\r\n }\r\n\r\n public async ngOnInit(): Promise<void> {\r\n await this.handleInitialValues();\r\n this.formGroup = this.buildForm();\r\n\r\n this.setCurrentDorpelType();\r\n this.updateNeutInputModels();\r\n\r\n this.uiStateService.dorpelCode$\r\n .pipe(filter((code) => !!code))\r\n .pipe(takeUntil(this.unsubscribe$))\r\n .pipe(\r\n tap((dorpelCode) => {\r\n this.currentDorpelCode = dorpelCode;\r\n this.setCurrentDorpelType();\r\n this.updateNeutInputModels();\r\n this.toggleRailTypeEnabledState(false);\r\n this.resetRailType();\r\n })\r\n )\r\n .subscribe((code) => {});\r\n\r\n this.uiStateService.schema$\r\n .pipe(filter((schema) => !!schema))\r\n .pipe(takeUntil(this.unsubscribe$))\r\n .subscribe((schema) => {\r\n this.currentSchema = schema;\r\n this.toggleRailTypeEnabledState(!!schema)\r\n });\r\n\r\n this.uiStateService.neutenCount$\r\n .pipe(takeUntil(this.unsubscribe$))\r\n .subscribe((count) => {\r\n if (!count) {\r\n /* moved validation here (removed filter pipe) cuz we want the uiStateService \r\n to notify even if values are empty or 0 \r\n (to invalidate certain fields in other components) */\r\n this.isNeutenSectionInvalid = true;\r\n this.showDealerContactMessage = false;\r\n return;\r\n }\r\n\r\n this.count = count;\r\n if (count === 1 && !this.isCurrentDoorSliding) {\r\n this.isNeutenSectionInvalid = false;\r\n this.showDealerContactMessage = true;\r\n } else {\r\n this.isNeutenSectionInvalid = false;\r\n this.showDealerContactMessage = false;\r\n }\r\n this.addOrRemoveNeut();\r\n this.cdRef.detectChanges();\r\n });\r\n }\r\n\r\n private toggleRailTypeEnabledState(isEnabled: boolean) {\r\n if (isEnabled) {\r\n this.formGroup.controls[\"railType\"].enable();\r\n } else {\r\n this.formGroup.controls[\"railType\"].disable();\r\n }\r\n }\r\n\r\n private resetRailType(): void {\r\n this.formGroup.get(\"railType\").setValue(\"\");\r\n this.uiStateService.setRailType(\"\");\r\n }\r\n\r\n private getNeuten(isPrefilledOrder: boolean): Observable<NeutDto[]> {\r\n let neutDtos: NeutDto[] = [];\r\n neutDtos = this.uiStateService.neutenChoices;\r\n return isPrefilledOrder ? of(neutDtos) : this.backendService.getNeuten();\r\n }\r\n\r\n private setCurrentDorpelType() {\r\n if (!this.currentDorpelCode) {\r\n return;\r\n }\r\n const dorpelCode = this.currentDorpelCode;\r\n const chosenDorpel = this.uiStateService.dorpelChoices.find(\r\n (d) => d.dorpelCode === dorpelCode\r\n );\r\n this.currentDorpelType = chosenDorpel.dorpelsoort;\r\n this.isCurrentDoorSliding = this.currentDorpelType === \"Hefschuifdorpel\";\r\n this.canShowRailOptions = chosenDorpel.dorpelCode.toLocaleLowerCase().indexOf(\"hs.190\") !== -1;\r\n }\r\n\r\n public getNeutenFormData(): NeutModel[] {\r\n const models = this.neutComponents\r\n .toArray()\r\n .map((comp) => <NeutModel>{\r\n ...comp.formGroup.value,\r\n linksVoorsponning: VOORSPONNING_SIZE_MAP[comp.formGroup.value.linksVoorsponning],\r\n rechtsVoorsponning: VOORSPONNING_SIZE_MAP[comp.formGroup.value.rechtsVoorsponning],\r\n customWidth: comp.specialNeutWidth\r\n });\r\n models.forEach((model) => {\r\n const neutDto = this.neuten.find((n) => n.neutCode === model.neut);\r\n if (neutDto) {\r\n model.omschrijving = neutDto.omschrijving;\r\n }\r\n });\r\n\r\n if (!this.isCurrentDoorSliding) {\r\n //for sliding doors we have no daagmaats and only one neut\r\n const modelDaagmaatA = <NeutModel>this.daagmatAComponent.formGroup.value;\r\n models[0].maatA = modelDaagmaatA.maatA;\r\n\r\n const daagmatCompList = this.daagmatComponents.toArray();\r\n for (let i = 0; i < models.length; i++) {\r\n const daagmatNeutModel = <NeutModel>daagmatCompList[i].formGroup.value;\r\n models[i].daagmaat = daagmatNeutModel.daagmaat;\r\n models[i].sponningsoort = daagmatNeutModel.sponningsoort;\r\n models[i].sponningmaat = daagmatNeutModel.sponningmaat;\r\n models[i].glaslat = daagmatNeutModel.glaslat;\r\n models[i].beglazingsprofiel = daagmatNeutModel.beglazingsprofiel;\r\n models[i].aanslagprofiel = daagmatNeutModel.aanslagprofiel;\r\n models[i].gemonteerd = daagmatNeutModel.gemonteerd;\r\n models[i].damverbreeding = daagmatNeutModel.damverbreeding;\r\n if (i === models.length - 1) {\r\n models[i].maatZ = daagmatNeutModel.maatZ;\r\n }\r\n }\r\n }\r\n\r\n return models;\r\n }\r\n\r\n public validateNeutenComponents(): boolean {\r\n let foundInvalidComponents: boolean = false;\r\n const models = this.neutComponents\r\n .toArray()\r\n .map((comp) => <NeutModel>comp.formGroup.value);\r\n models.forEach((model) => {\r\n const neutDto = this.neuten.find((n) => n.neutCode === model.neut);\r\n if (neutDto && !neutDto.isInHouseNeut) {\r\n foundInvalidComponents = true;\r\n }\r\n });\r\n\r\n return !foundInvalidComponents;\r\n }\r\n\r\n public dataIsValid(): boolean {\r\n const isValid = !this.neutComponents\r\n .toArray()\r\n .some((form) => form.formGroup.invalid);\r\n\r\n if (!isValid) {\r\n this.neutComponents.toArray().forEach((nc) => {\r\n const formGroup = nc.formGroup;\r\n Object.keys(formGroup.controls).forEach((field) => {\r\n const control = formGroup.get(field);\r\n control.markAsTouched();\r\n });\r\n });\r\n }\r\n\r\n return isValid;\r\n }\r\n\r\n public onNeutVoorsponningChanged(data): void {\r\n let targetNeutComponent =\r\n this.neutComponents.toArray()[data.targetNeutIndex];\r\n\r\n if (!targetNeutComponent) {\r\n return;\r\n }\r\n\r\n if (data.targetProperty === \"linksVoorsponning\") {\r\n targetNeutComponent.setLinksVoorsponningValue(data.value);\r\n } else if (data.targetProperty === \"rechtsVoorsponning\") {\r\n targetNeutComponent.setRechtsVoorsponningValue(data.value);\r\n }\r\n }\r\n\r\n public onNeutCodeChanged(neutData: any, index): void {\r\n // this.resetNeutInputModel(index);\r\n this.updateSpecificNeutInputModel(neutData, index);\r\n }\r\n\r\n private updateSpecificNeutInputModel(neutData: any, index) {\r\n let target = this.neutInputModels[index];\r\n\r\n if (target) {\r\n target.model.omschrijving = neutData.neutDescription;\r\n target.model.neut = neutData.neutCode;\r\n target.model.aanslagprofiel = neutData.aanslagprofiel;\r\n target.model.beglazingsprofiel = neutData.beglazingsprofiel;\r\n target.model.glaslat = neutData.glaslat;\r\n target.model.gemonteerd = neutData.gemonteerd;\r\n target.model.damverbreeding = neutData.damverbreeding;\r\n }\r\n }\r\n\r\n private addOrRemoveNeut() {\r\n const dorpel = this.uiStateService.currentDorpel;\r\n\r\n if (this.neutInputModels.length < this.count) {\r\n const dif = this.count - this.neutInputModels.length;\r\n for (let i = 0; i < dif; i++) {\r\n const neutOrder = ModelFactory.createNeut();\r\n const input = {\r\n neutenChoices: this.neuten,\r\n glaslattenChoices: this.filteredGlaslatten,\r\n model: <NeutModel>{\r\n daagmaat: neutOrder.daagmaat,\r\n maatA: dorpel.maatA,\r\n maatZ: dorpel.maatZ,\r\n neut: neutOrder.neutCode,\r\n sponningmaat: neutOrder.sponningmaat,\r\n sponningsoort: neutOrder.sponningsoort,\r\n glaslat: neutOrder.glaslat,\r\n damverbreeding: neutOrder.damverbreeding,\r\n beglazingsprofiel: neutOrder.beglazingsprofiel,\r\n aanslagprofiel: neutOrder.aanslagprofiel,\r\n gemonteerd: neutOrder.gemonteerd,\r\n position: NeutPosition.Center,\r\n },\r\n };\r\n // insert neut second to last, in the center position\r\n this.neutInputModels.splice(this.neutInputModels.length - 1, 0, input);\r\n this.neutInputModels.forEach(\r\n (input, index) =>\r\n (input.model.position = NeutUtils.getPositionFromIndex(\r\n index,\r\n this.neutInputModels.length\r\n ))\r\n );\r\n this.neutInputModels = [...this.neutInputModels];\r\n }\r\n } else if (this.neutInputModels.length > this.count) {\r\n const dif = this.neutInputModels.length - this.count;\r\n for (let i = 0; i < dif; i++) {\r\n this.neutInputModels.splice(this.neutInputModels.length - 2, 1);\r\n this.neutInputModels.forEach(\r\n (input, index) =>\r\n (input.model.position = NeutUtils.getPositionFromIndex(\r\n index,\r\n this.neutInputModels.length\r\n ))\r\n );\r\n this.neutInputModels = [...this.neutInputModels];\r\n }\r\n }\r\n }\r\n\r\n private buildForm(): FormGroup {\r\n const formGroup = this.formBuilder.group({\r\n railType: [{value: \"\", disabled: true}]\r\n });\r\n\r\n return formGroup;\r\n }\r\n\r\n public onRailTypeChange() {\r\n let railType = this.formGroup.get(\"railType\").value;\r\n this.uiStateService.setRailType(railType);\r\n }\r\n\r\n // private resetNeutInputModel(index: number) {\r\n // const dorpel = this.uiStateService.currentDorpel;\r\n // let targetNeut = this.neutInputModels[index].model;\r\n\r\n // if (targetNeut) {\r\n // targetNeut.aanslagprofiel = undefined;\r\n // targetNeut.beglazingsprofiel = undefined;\r\n // targetNeut.glaslat = undefined;\r\n // targetNeut.gemonteerd = undefined;\r\n // targetNeut.damverbreeding = undefined;\r\n // }\r\n // }\r\n\r\n private updateNeutInputModels() {\r\n const dorpel = this.uiStateService.currentDorpel;\r\n const neuten = this.neuten;\r\n const glaslatten = this.filteredGlaslatten;\r\n const values = dorpel.neuten.map((neutOrder, index) => {\r\n const input = {\r\n neutenChoices: neuten,\r\n glaslattenChoices: glaslatten,\r\n model: <NeutModel>{\r\n daagmaat: neutOrder.daagmaat,\r\n maatA: dorpel.maatA,\r\n maatZ: dorpel.maatZ,\r\n neut: neutOrder.neutCode,\r\n sponningmaat: neutOrder.sponningmaat,\r\n sponningsoort: neutOrder.sponningsoort,\r\n glaslat: neutOrder.glaslat,\r\n aanslagprofiel: neutOrder.aanslagprofiel,\r\n beglazingsprofiel: neutOrder.beglazingsprofiel,\r\n gemonteerd: neutOrder.gemonteerd,\r\n damverbreeding: neutOrder.damverbreeding,\r\n omschrijving: neutOrder.neutDescription,\r\n linksVoorsponning: neutOrder.linksVoorsponning,\r\n rechtsVoorsponning: neutOrder.rechtsVoorsponning,\r\n position: NeutUtils.getPositionFromIndex(index, dorpel.neuten.length),\r\n },\r\n };\r\n return input;\r\n });\r\n\r\n values.forEach(\r\n (input, index) =>\r\n (input.model.position = NeutUtils.getPositionFromIndex(\r\n index,\r\n values.length\r\n ))\r\n );\r\n this.neutInputModels = values;\r\n }\r\n\r\n private filterGlaslattenChoicesByProductsoort(\r\n glaslatten: GlaslatDto[]\r\n ): GlaslatDto[] {\r\n let currentProductType: string = this.uiStateService.currentProductType;\r\n if (!currentProductType) {\r\n return glaslatten;\r\n }\r\n\r\n return glaslatten.filter(\r\n (glaslat) =>\r\n glaslat.productsoort.toLowerCase() === currentProductType.toLowerCase()\r\n );\r\n }\r\n\r\n private handleInitialValues(): Promise<void> {\r\n const dorpel = this.uiStateService.currentDorpel;\r\n const isPrefilledOrder = this.uiStateService.fromPrefilledOrder;\r\n return new Promise<void>((resolve, reject) => {\r\n forkJoin(\r\n this.getNeuten(isPrefilledOrder),\r\n this.backendService.getGlaslatten()\r\n )\r\n .pipe(\r\n tap(([neuten, glaslatten]) => {\r\n this.neuten = neuten;\r\n this.filteredGlaslatten =\r\n this.filterGlaslattenChoicesByProductsoort(glaslatten);\r\n this.uiStateService.setNeutenChoices(this.neuten);\r\n })\r\n )\r\n .pipe(takeUntil(this.unsubscribe$))\r\n .subscribe(([neuten, glaslatten]) => {\r\n this.neuten = neuten;\r\n this.filteredGlaslatten =\r\n this.filterGlaslattenChoicesByProductsoort(glaslatten);\r\n this.updateNeutInputModels();\r\n resolve();\r\n });\r\n });\r\n }\r\n}\r\n","<div class=\"row d-flex justify-content-center\">\r\n <div *ngFor=\"let model of sluitpottenModels; let i = index\" class=\"sluitpot-wrapper col bg-white py-4 mx-2 my-2 rounded-4\">\r\n <div>\r\n <label class=\"form-label\"><b>* {{ \"Sluitpot \" + (i + 1) + \": \" }}</b></label>\r\n <select\r\n class=\"form-select\"\r\n [(ngModel)]=\"model.sluitpotCode\"\r\n #sluitpotCode=\"ngModel\"\r\n (change)=\"onSluitpotChanged(i)\"\r\n required\r\n >\r\n <option value=\"\" disabled selected hidden\r\n >Selecteer een waarde a.u.b.</option\r\n >\r\n <option\r\n *ngFor=\"let sluitpot of sluitpotten\"\r\n value=\"{{ sluitpot.sluitpotCode }}\"\r\n >{{ sluitpot.omschrijving }}</option\r\n >\r\n </select>\r\n <luv-validationError\r\n [show]=\"\r\n sluitpotCode.invalid &&\r\n (sluitpotCode.dirty || sluitpotCode.touched || validate)\r\n \"\r\n [errorMessage]=\"getErrorMessage('sluitpotCode', 'required')\"\r\n ></luv-validationError>\r\n </div>\r\n <div>\r\n <label class=\"form-label\"><b>* Hart sluitpot:</b></label>\r\n <div class=\"input-group\">\r\n <input\r\n #maat=\"ngModel\"\r\n required\r\n type=\"number\"\r\n min=\"0\"\r\n class=\"form-control\"\r\n aria-describedby=\"maatq1\"\r\n [(ngModel)]=\"model.maat\"\r\n (change)=\"onMaatQChanged(i)\"\r\n [disabled]=\"!model.sluitpotCode\"\r\n integerOnly\r\n />\r\n <span class=\"input-group-text\">mm</span>\r\n </div>\r\n <luv-validationError\r\n [show]=\"maat.invalid && (maat.dirty || maat.touched || validate)\"\r\n [errorMessage]=\"getErrorMessage('maat', 'required')\"\r\n ></luv-validationError>\r\n </div>\r\n <!-- <div *ngIf=\"model.isNonBlinde\">\r\n <label>* Maat Q2: <i class=\"fa fa-info-circle\" (mouseenter)=\"showQ2Tooltip($event.target)\" (mouseleave)=\"hideQ2Tooltip()\"></i></label>\r\n <div class=\"input-group\">\r\n <input\r\n #maat2=\"ngModel\"\r\n required\r\n type=\"number\"\r\n min=\"0\"\r\n class=\"form-control form-control-sm\"\r\n aria-describedby=\"maat2\"\r\n [(ngModel)]=\"model.maat2\"\r\n (change)=\"onMaatQChanged(i)\"\r\n [disabled]=\"!model.sluitpotCode\"\r\n />\r\n <div class=\"input-group-append\">\r\n <div class=\"bg-primary pl-2 pr-2 pt-1 text-white\">MM</div>\r\n </div>\r\n </div>\r\n <luv-validationError\r\n [show]=\"maat2.invalid && (maat2.dirty || maat2.touched || validate)\"\r\n [errorMessage]=\"getErrorMessage('maat2', 'required')\"\r\n ></luv-validationError>\r\n </div> -->\r\n </div>\r\n</div>\r\n<br>\r\n","import { Component, OnInit } from \"@angular/core\";\r\nimport { BaseComponent } from \"../shared/base.component\";\r\nimport { UiStateService } from \"../core/services/ui-state-service\";\r\nimport { takeUntil } from \"rxjs/internal/operators\";\r\nimport { combineLatest } from \"rxjs\";\r\nimport {\r\n SluitpotDto,\r\n BestellingSluitpotDto,\r\n} from \"../shared/api-models/models\";\r\nimport { BackendService } from \"../core/services/backend.service\";\r\nimport { FormControl } from \"@angular/forms\";\r\nimport { SluitpotModel, SluitpotUtils } from \"../shared/models/sluitpot.model\";\r\nimport { TooltipService } from \"../core/services/tooltip.service\";\r\n\r\n@Component({\r\n selector: \"luv-sluitpotten\",\r\n templateUrl: \"./sluitpot-horiz.component.html\",\r\n styleUrls: [\"./sluitpot.component.scss\"],\r\n})\r\nexport class SluitpotComponent extends BaseComponent implements OnInit {\r\n private _aantalSluitpotten: number = 0;\r\n\r\n public sluitpottenModels: SluitpotModel[] = [];\r\n public validate: boolean = false;\r\n\r\n public sluitpotten: SluitpotDto[] = [];\r\n public get aantalSluitpotten(): number {\r\n return this._aantalSluitpotten;\r\n }\r\n\r\n constructor(\r\n private uiStateService: UiStateService,\r\n private backendService: BackendService,\r\n public tooltip: TooltipService\r\n ) {\r\n super();\r\n }\r\n\r\n public ngOnInit() {\r\n const dorpel = this.uiStateService.currentDorpel;\r\n combineLatest([\r\n this.backendService.getSluitpotten(),\r\n this.uiStateService.sluitpottenCount$,\r\n this.uiStateService.dorpelCode$\r\n ])\r\n .pipe(takeUntil(this.unsubscribe$))\r\n .subscribe(([sluitpotten, count, dorpelCodeValue]) => {\r\n this.sluitpotten = sluitpotten.filter(dto => dto.dorpelCode === dorpelCodeValue);\r\n this.sluitpottenModels = dorpel.sluitpotten.map(\r\n (sluitpotOrder: BestellingSluitpotDto) =>\r\n <SluitpotModel>{\r\n maat: sluitpotOrder.maat,\r\n // maat2: sluitpotOrder.maat2,\r\n sluitpotCode: sluitpotOrder.sluitpotCode || \"\",\r\n omschrijving: sluitpotOrder.omschrijving,\r\n isNonBlinde: SluitpotUtils.isNonBlindeSluitpott(sluitpotOrder.omschrijving)\r\n }\r\n );\r\n this.sluitpottenModels.forEach(model => {\r\n const dto = this.sluitpotten.find(item => item.sluitpotCode === model.sluitpotCode);\r\n if (dto) {\r\n model.omschrijving = dto.omschrijving;\r\n model.isNonBlinde = SluitpotUtils.isNonBlindeSluitpott(dto.omschrijving);\r\n }\r\n });\r\n });\r\n }\r\n\r\n public getSluitpotModels(): SluitpotModel[] {\r\n this.sluitpottenModels.forEach(model => {\r\n const dto = this.sluitpotten.find(item => item.sluitpotCode === model.sluitpotCode);\r\n if (dto) {\r\n model.omschrijving = dto.omschrijving;\r\n model.isNonBlinde = SluitpotUtils.isNonBlindeSluitpott(dto.omschrijving)\r\n }\r\n });\r\n return this.sluitpottenModels;\r\n }\r\n\r\n public errorMessage(formControl: FormControl, key: string): string {\r\n if (formControl.valid) {\r\n return \"\";\r\n }\r\n const [firstError] = Object.keys(formControl.errors);\r\n const error = ValidationMessages[key]\r\n ? ValidationMessages[key][firstError]\r\n : null;\r\n return error;\r\n }\r\n\r\n public getErrorMessage(key, validation): string {\r\n return ValidationMessages[key][validation];\r\n }\r\n\r\n public isControlValid(formControl: FormControl): boolean {\r\n return formControl.invalid && (formControl.dirty || formControl.touched);\r\n }\r\n\r\n public dataIsValid(): boolean {\r\n this.validate = true;\r\n return !this.sluitpottenModels.some((s) => !s.sluitpotCode || !s.maat /*|| (s.isNonBlinde && !s.maat2)*/);\r\n }\r\n\r\n public onMaatQChanged(index: number): void {\r\n let model = this.sluitpottenModels[index];\r\n this.uiStateService.updateSluitpot(model, index);\r\n }\r\n\r\n public showQ2Tooltip(target: HTMLElement): void {\r\n this.tooltip.showTooltip(target, {\r\n customTextDescription: \"Deze maat wordt vanuit de dagkant gemeten.\",\r\n descriptionOnly: true,\r\n });\r\n }\r\n\r\n public hideQ2Tooltip(): void {\r\n this.tooltip.hideTooltip();\r\n }\r\n\r\n public onSluitpotChanged(index: number): void {\r\n let model = this.sluitpottenModels[index];\r\n let code = model.sluitpotCode;\r\n\r\n let omschrijving = this.sluitpotten.find(sp => sp.sluitpotCode === code).omschrijving;\r\n model.omschrijving = omschrijving;\r\n model.isNonBlinde = SluitpotUtils.isNonBlindeSluitpott(omschrijving);\r\n this.uiStateService.updateSluitpot(model, index);\r\n }\r\n}\r\n\r\nconst ValidationMessages = {\r\n sluitpotCode: {\r\n required: \"Selecteer een sluitpot\",\r\n },\r\n maat: {\r\n required: \"MaatQ is een verplicht veld.\",\r\n },\r\n // maat2: {\r\n // required: \"Maat2Q is een verplicht veld.\",\r\n // },\r\n};\r\n","import { Component, Input, Output, EventEmitter } from \"@angular/core\";\r\nimport {\r\n BestellingBewerkingDto\r\n} from \"../../shared/api-models/models\";\r\nimport { BaseComponent } from \"../../shared/base.component\";\r\n\r\n@Component({\r\n selector: \"bewerkingen-pill\",\r\n templateUrl: \"./bewerkingen-pill.component.html\",\r\n styleUrls: [\"./bewerkingen-pill.component.css\"],\r\n})\r\nexport class BewerkingenPillComponent extends BaseComponent {\r\n @Input(\"bewerking\") public bewerking: BestellingBewerkingDto;\r\n @Output() bewerkingRemoved: EventEmitter<any> = new EventEmitter();\r\n\r\n constructor() {\r\n super();\r\n }\r\n\r\n public removePill() {\r\n this.bewerkingRemoved.emit();\r\n }\r\n}\r\n","<div class=\"row justify-content-center\">\r\n <div class=\"col-lg-auto\">\r\n <label><b>Bewerkingen / opties:</b></label>\r\n </div>\r\n</div>\r\n\r\n<div class=\"row justify-content-center\" *ngIf=\"errorMessage\">\r\n <br />\r\n <div class=\"col-lg-auto mb-1\">\r\n <p class=\"bewerkingen-error\">{{errorMessage}}</p>\r\n </div>\r\n</div>\r\n<div class=\"row justify-content-center\">\r\n <div class=\"col-lg-auto mb-1\">\r\n <select [disabled]=\"selectorDisabled\" class=\"form-select\" (change)=\"onBewerkingSelected($event)\">\r\n <option value=\"\" disabled selected hidden>Selecteer een waarde a.u.b.</option>\r\n <option *ngFor=\"let bewerking of bewerkingen\" value=\"{{bewerking.bewerkingCode}}\">{{ bewerking.omschrijving }}\r\n </option>\r\n </select>\r\n </div>\r\n</div>\r\n<br />\r\n<div class=\"row justify-content-center bewerkingen-list-wrapper\">\r\n <ng-container *ngFor=\"let selection of selectedBwCodes; let i = index\">\r\n <div class=\"col bg-white py-4 mx-2 my-4 rounded-4 restricted-width\">\r\n <div class=\"row\">\r\n <bewerkingen-pill [bewerking]=\"selection\" (bewerkingRemoved)=\"onBewerkingRemoved(i)\"></bewerkingen-pill>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col\">\r\n <div *ngIf=\"shouldShowCustomMeasurements(selection.description)\" class=\"custom-width-wrapper col-lg-auto mb-1\">\r\n <label class=\"form-label\" *ngIf=\"showKloosterConfiguration(selection.description)\">(A) Uit de dagkant:</label>\r\n <input *ngIf=\"showKloosterConfiguration(selection.description)\" type=\"number\"\r\n class=\"form-control\" [value]=\"selection.customOffset\"\r\n (change)=\"onBewerkingCustomOffsetChanged($event, i)\" integerOnly/>\r\n <label class=\"form-label\"><span\r\n *ngIf=\"showKloosterConfiguration(selection.description) || showRenovatieConfiguration(selection.description)\">(B)\r\n </span>Diepte:</label>\r\n <input type=\"number\" class=\"form-control\" [value]=\"selection.customDepth\"\r\n (change)=\"onBewerkingCustomDepthChanged($event, i)\" integerOnly/>\r\n <div class=\"row justify-content-center\" *ngIf=\"selectedBwErrors[i]?.depth\">\r\n <div class=\"col-lg-auto mb-1\">\r\n <p class=\"bewerkingen-error\">{{selectedBwErrors[i].depth}}</p>\r\n </div>\r\n </div>\r\n <label class=\"form-label\">\r\n <span *ngIf=\"showKloosterConfiguration(selection.description)\">(C) </span>\r\n <span *ngIf=\"showRenovatieConfiguration(selection.description)\">(A) </span>\r\n Lengte:\r\n </label>\r\n <input type=\"number\" class=\"form-control\" [value]=\"selection.customLength\"\r\n (change)=\"onBewerkingCustomLengthChanged($event, i)\" integerOnly/>\r\n <label *ngIf=\"showKloosterConfiguration(selection.description)\">(D):</label>\r\n <input *ngIf=\"showKloosterConfiguration(selection.description)\" type=\"number\"\r\n class=\"form-control form-control-sm\" [disabled]=\"true\"\r\n [value]=\"neutLengte - selection.customOffset - selection.customLength\" />\r\n <div class=\"row justify-content-center\" *ngIf=\"selectedBwErrors[i]?.overflow\">\r\n <div class=\"col-lg-auto mb-1\">\r\n <p class=\"bewerkingen-error\">{{selectedBwErrors[i].overflow}}</p>\r\n </div>\r\n </div>\r\n </div>\r\n <div *ngIf=\"shouldShowVerstekOption(selection.description)\" class=\"custom-width-wrapper\">\r\n <label class=\"form-label\">Oriëntatie:</label>\r\n <select class=\"form-control\" [(ngModel)]=\"selection.orientatie\"\r\n (change)=\"onVerstekOrentatieChange($event, i)\">\r\n <option value=\"naarBuiten\" [selected]=\"selection.orientatie === 'naarBuiten'\">Naar buiten</option>\r\n <option value=\"naarBinnen\" [selected]=\"selection.orientatie === 'naarBinnen'\">Naar binnen</option>\r\n </select>\r\n </div>\r\n <div *ngIf=\"shouldShowVerstekNeutCutOption(selection.description, i)\" class=\"custom-width-wrapper\"\r\n id=\"neutCutWrapper\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [(ngModel)]=\"selection.cutNeut\"\r\n (change)=\"onCutNeutChanged($event, i)\" id=\"neutCut\">\r\n <label class=\"form-check-label\" for=\"neutCut\" id=\"neutCutLabel\">\r\n Neut laten doorlopen in verstek\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col justify-content-center\" *ngIf=\"showKloosterConfiguration(selection.description) || showRenovatieConfiguration(selection.description)\">\r\n <img src=\"/assets/tooltip-assets/kloostersponning.png\" alt=\"Kloostersponning example\" *ngIf=\"showKloosterConfiguration(selection.description)\">\r\n <img src=\"/assets/tooltip-assets/renovatiesponning.png\" alt=\"Renovatiesponning example\" *ngIf=\"showRenovatieConfiguration(selection.description)\">\r\n </div>\r\n </div>\r\n \r\n </div>\r\n </ng-container>\r\n</div>","<div class=\"bewerking-pill\">\r\n <ng-content></ng-content>\r\n <div class=\"description\">\r\n {{bewerking.description}}\r\n </div>\r\n <div class=\"close remove-button\" aria-label=\"Close\" (click)=\"removePill()\">\r\n <span aria-hidden=\"true\">×</span>\r\n </div>\r\n</div>\r\n\r\n","import { Component, OnInit } from \"@angular/core\";\r\nimport {\r\n BewerkingDto,\r\n BestellingBewerkingDto,\r\n BestellingNeutDto,\r\n} from \"../shared/api-models/models\";\r\nimport { BackendService } from \"../core/services/backend.service\";\r\nimport { UiStateService } from \"../core/services/ui-state-service\";\r\nimport { filter, switchMap, map, takeUntil } from \"rxjs/operators\";\r\nimport { BaseComponent } from \"../shared/base.component\";\r\nimport { BewerkingUtils } from \"../shared/api-models/bewerkingDto\";\r\nimport { GraphicsService } from '../core/services/graphics.service';\r\nimport { DorpelUtils } from \"../shared/models/dorpel-type.model\";\r\n\r\ntype BewerkingError = {\r\n depth: string | null,\r\n overflow: string | null\r\n}\r\n\r\nconst MAX_BEWERKING_DEPTH = 20;\r\n\r\n@Component({\r\n selector: \"app-bewerkingen-horiz\",\r\n templateUrl: \"./bewerkingen-horiz.component.html\",\r\n styleUrls: [\"./bewerkingen-horiz.component.css\"],\r\n})\r\nexport class BewerkingenHorizComponent extends BaseComponent implements OnInit {\r\n public bewerkingen: BewerkingDto[] = [];\r\n public selectedBwCodes: BestellingBewerkingDto[] = [];\r\n public selectedBwErrors: BewerkingError[] = [];\r\n public selectorDisabled: boolean = true;\r\n public errorMessage: string | null = null;\r\n public neutLengte: number = 0;\r\n\r\n constructor(\r\n private backendService: BackendService,\r\n private uiState: UiStateService,\r\n private graphicsService: GraphicsService\r\n ) {\r\n super();\r\n }\r\n\r\n ngOnInit() {\r\n this.uiState.dorpelCode$\r\n .pipe(\r\n filter((dorpelCode) => !!dorpelCode),\r\n switchMap((dorpelCode) =>\r\n this.backendService\r\n .getAllBewerkingen()\r\n .pipe(\r\n map((bws) => bws.filter((bw) => bw.dorpelCode === dorpelCode))\r\n )\r\n ),\r\n takeUntil(this.unsubscribe$)\r\n )\r\n .subscribe((bewerkingen) => {\r\n this.selectorDisabled = this.isSlidingDorpel() && !this.uiState.currentDorpel.schema;\r\n this.bewerkingen = bewerkingen;\r\n\r\n this.selectedBwCodes = this.uiState.currentDorpel.bewerkingen;\r\n\r\n if (this.selectedBwCodes.length) {\r\n this.uiState.setBewerkingenOptions(this.selectedBwCodes);\r\n }\r\n });\r\n\r\n this.uiState.schema$\r\n .pipe(takeUntil(this.unsubscribe$))\r\n .subscribe((schema) => {\r\n this.setDisabledStateBySchema(schema);\r\n });\r\n\r\n this.uiState.neuten$\r\n .pipe(filter((neuten) => !!neuten))\r\n .pipe(takeUntil(this.unsubscribe$))\r\n .subscribe((neuten) => {\r\n if (neuten[0]) {\r\n this.updateNeutHeight(neuten[0]);\r\n }\r\n })\r\n }\r\n\r\n private updateNeutHeight(neut: BestellingNeutDto): void {\r\n let neutDto = this.uiState.getNeutDtoByCodeAndPositie(\r\n neut.neutCode,\r\n neut.positie\r\n );\r\n\r\n if (neutDto && neutDto.neutlengte) {\r\n this.neutLengte = parseInt(neutDto.neutlengte);\r\n }\r\n }\r\n\r\n public onBewerkingSelected(e: any) {\r\n this.errorMessage = null;\r\n\r\n if (e.target.value) {\r\n let bewerking: BestellingBewerkingDto = this.getDataForCode(e.target.value);\r\n\r\n //VALIDATION FOR A CERTAIN EDGE TO NEUT DISTANCE FOR VERSTEK:\r\n\r\n // let verstekError = this.validateVersteksponning(bewerking.description);\r\n\r\n // if (verstekError) {\r\n // this.errorMessage = verstekError;\r\n // return;\r\n // }\r\n\r\n let duplicateBewerkingError = this.preventDuplicateValues(bewerking.description);\r\n if (duplicateBewerkingError) {\r\n this.errorMessage = duplicateBewerkingError;\r\n return;\r\n }\r\n\r\n this.cleanupBewerkingConflicts(bewerking.description);\r\n this.revalidateBwerkingenOptions();\r\n this.selectedBwCodes.push(bewerking);\r\n this.uiState.setBewerkingenOptions(this.selectedBwCodes);\r\n this.uiState.triggerRedraw();\r\n e.target.value = \"\";\r\n }\r\n }\r\n\r\n public showKloosterConfiguration(bewerkingDescription: string): boolean {\r\n return BewerkingUtils.isKloostersponning(bewerkingDescription)\r\n }\r\n\r\n public showRenovatieConfiguration(bewerkingDescription: string): boolean {\r\n return BewerkingUtils.isRenovatiesponning(bewerkingDescription)\r\n }\r\n\r\n\r\n private preventDuplicateValues(bewerkingDescription: string): string | null {\r\n const DUPLICATE_ERROR_MESSAGE = \"U heeft al een klooster/renovatie sponning voor deze zijde ingegeven. verwijder deze eerst voor u een nieuwe aanmaakt.\"\r\n let addingKloostersponnigLeft = BewerkingUtils.isKloostersponningLeft(bewerkingDescription);\r\n let addingKloostersponnigRight = BewerkingUtils.isKloostersponningRight(bewerkingDescription);\r\n let addingRenovatiesponnigLeft = BewerkingUtils.isRenovatiesponningLeft(bewerkingDescription);\r\n let addingRenovatiesponnigRight = BewerkingUtils.isRenovatiesponningRight(bewerkingDescription);\r\n\r\n if (addingKloostersponnigLeft || addingKloostersponnigRight) {\r\n let hasKloostersponningBoth = this.selectedBwCodes.find(bw => BewerkingUtils.isKloostersponningLeftAndRight(bw.description));\r\n return hasKloostersponningBoth ? DUPLICATE_ERROR_MESSAGE : null;\r\n } else if (addingRenovatiesponnigLeft || addingRenovatiesponnigRight) {\r\n let hasRenovatiesponningBoth = this.selectedBwCodes.find(bw => BewerkingUtils.isRenovatiesponningLeftAndRight(bw.description));\r\n return hasRenovatiesponningBoth ? DUPLICATE_ERROR_MESSAGE : null;\r\n }\r\n }\r\n\r\n //VALIDATION FOR A CERTAIN EDGE TO NEUT DISTANCE FOR VERSTEK:\r\n // private validateVersteksponning(bewerkingDescription: string): string | null {\r\n // if (BewerkingUtils.isVersteksponningLeft(bewerkingDescription)) {\r\n // let maatA = this.uiState.currentDorpel.maatA;\r\n // let leftVerstek = this.getVerstekSponningData().angle;\r\n // let minimumLeftNecessarySpace = this.graphicsService.calculateVerstekLengthByAngle(leftVerstek) //make side specific\r\n // if (!maatA || maatA < minimumLeftNecessarySpace) {\r\n // return `maatA must be at least ${minimumLeftNecessarySpace} to add a verstek left`;\r\n // }\r\n // } else if (BewerkingUtils.isVersteksponningRight(bewerkingDescription)) {\r\n // let maatZ = this.uiState.currentDorpel.maatZ;\r\n // let rightVerstek = this.getVerstekSponningData().angle;\r\n // let minimumRightNecessarySpace = this.graphicsService.calculateVerstekLengthByAngle(rightVerstek) //make side specific\r\n\r\n // if (!maatZ || maatZ < minimumRightNecessarySpace) {\r\n // return `maatZ must be at least ${minimumRightNecessarySpace} to add a verstek right`;\r\n // }\r\n // }\r\n\r\n // return null;\r\n // }\r\n\r\n public shouldShowCustomMeasurements(bewerkingDescription: string): boolean {\r\n return !(BewerkingUtils.isVersteksponningLeft(bewerkingDescription) || BewerkingUtils.isVersteksponningRight(bewerkingDescription) || BewerkingUtils.isLosEindstuk(bewerkingDescription));\r\n }\r\n\r\n public shouldShowVerstekOption(bewerkingDescription: string): boolean {\r\n return BewerkingUtils.isVersteksponningLeft(bewerkingDescription) || BewerkingUtils.isVersteksponningRight(bewerkingDescription);\r\n }\r\n\r\n public shouldShowVerstekNeutCutOption(bewerkingDescription: string, index: number): boolean {\r\n return BewerkingUtils.isVersteksponningLeft(bewerkingDescription) || BewerkingUtils.isVersteksponningRight(bewerkingDescription); //customer requested to always show this option\r\n\r\n // let dorpelHeight = DorpelUtils.getThicknessFromDorpelCode(this.uiState.currentDorpel.dorpelCode)\r\n\r\n // if (BewerkingUtils.isVersteksponningLeft(bewerkingDescription)) {\r\n // let shouldShow = (this.uiState.currentDorpel.maatA || 0) < dorpelHeight;\r\n // if (!shouldShow) {\r\n // this.selectedBwCodes[index].cutNeut = null;\r\n // } else if (!this.selectedBwCodes[index].cutNeut) {\r\n // this.selectedBwCodes[index].cutNeut = false;\r\n // }\r\n // return shouldShow;\r\n // }\r\n\r\n // if (BewerkingUtils.isVersteksponningRight(bewerkingDescription)) {\r\n // let shouldShow = (this.uiState.currentDorpel.maatZ || 0) < dorpelHeight;\r\n // if (!shouldShow) {\r\n // this.selectedBwCodes[index].cutNeut = null;\r\n // } else if (!this.selectedBwCodes[index].cutNeut) {\r\n // this.selectedBwCodes[index].cutNeut = false;\r\n // }\r\n // return shouldShow;\r\n // }\r\n\r\n // return false;\r\n }\r\n\r\n private cleanupBewerkingConflicts(newBewerkingDecription: string): void {\r\n let addingKloostersponnigLeft = BewerkingUtils.isKloostersponningLeft(newBewerkingDecription);\r\n let addingKloostersponnigRight = BewerkingUtils.isKloostersponningRight(newBewerkingDecription);\r\n let addingKloostersponnigBoth = BewerkingUtils.isKloostersponningLeftAndRight(newBewerkingDecription);\r\n\r\n let addingRenovatiesponnigLeft = BewerkingUtils.isRenovatiesponningLeft(newBewerkingDecription);\r\n let addingRenovatiesponnigRight = BewerkingUtils.isRenovatiesponningRight(newBewerkingDecription);\r\n let addingRenovatiesponnigBoth = BewerkingUtils.isRenovatiesponningLeftAndRight(newBewerkingDecription);\r\n\r\n let addingVersteksponnigLeft = BewerkingUtils.isVersteksponningLeft(newBewerkingDecription);\r\n let addingVersteksponnigRight = BewerkingUtils.isVersteksponningRight(newBewerkingDecription);\r\n\r\n if (addingKloostersponnigBoth || addingRenovatiesponnigBoth) {\r\n this.selectedBwCodes = [];\r\n } else if (addingKloostersponnigLeft) {\r\n let cleansedList = this.selectedBwCodes.filter(bw => !BewerkingUtils.isRenovatiesponningLeft(bw.description) && !BewerkingUtils.isRenovatiesponningLeftAndRight(bw.description) && !BewerkingUtils.isKloostersponningLeft(bw.description));\r\n this.selectedBwCodes = cleansedList;\r\n } else if (addingKloostersponnigRight) {\r\n let cleansedList = this.selectedBwCodes.filter(bw => !BewerkingUtils.isRenovatiesponningRight(bw.description) && !BewerkingUtils.isRenovatiesponningLeftAndRight(bw.description) && !BewerkingUtils.isKloostersponningRight(bw.description));\r\n this.selectedBwCodes = cleansedList;\r\n } else if (addingRenovatiesponnigLeft) {\r\n let cleansedList = this.selectedBwCodes.filter(bw => !BewerkingUtils.isKloostersponningLeft(bw.description) && !BewerkingUtils.isKloostersponningLeftAndRight(bw.description) && !BewerkingUtils.isRenovatiesponningLeft(bw.description));\r\n this.selectedBwCodes = cleansedList;\r\n } else if (addingRenovatiesponnigRight) {\r\n let cleansedList = this.selectedBwCodes.filter(bw => !BewerkingUtils.isKloostersponningRight(bw.description) && !BewerkingUtils.isKloostersponningLeftAndRight(bw.description) && !BewerkingUtils.isRenovatiesponningRight(bw.description));\r\n this.selectedBwCodes = cleansedList;\r\n } else if (addingVersteksponnigLeft) {\r\n let cleansedList = this.selectedBwCodes.filter(bw => !BewerkingUtils.isKloostersponningLeft(bw.description) && !BewerkingUtils.isRenovatiesponningLeft(bw.description) && !BewerkingUtils.isKloostersponningLeftAndRight(bw.description) && !BewerkingUtils.isRenovatiesponningLeftAndRight(bw.description));\r\n this.selectedBwCodes = cleansedList;\r\n } else if (addingVersteksponnigRight) {\r\n let cleansedList = this.selectedBwCodes.filter(bw => !BewerkingUtils.isKloostersponningRight(bw.description) && !BewerkingUtils.isRenovatiesponningRight(bw.description) && !BewerkingUtils.isKloostersponningLeftAndRight(bw.description) && !BewerkingUtils.isRenovatiesponningLeftAndRight(bw.description));\r\n this.selectedBwCodes = cleansedList;\r\n }\r\n }\r\n\r\n private setDisabledStateBySchema(schema?: string) {\r\n let hasSchema = !!schema;\r\n this.selectorDisabled = !hasSchema;\r\n }\r\n\r\n private revalidateBwerkingenOptions(): boolean {\r\n let isValid = true;\r\n this.selectedBwErrors = [];\r\n for (let i = 0; i < this.selectedBwCodes.length; i++) {\r\n let bw = this.selectedBwCodes[i];\r\n let errorObject: BewerkingError = {\r\n depth: null,\r\n overflow: null\r\n }\r\n\r\n if (!BewerkingUtils.isKloostersponning(bw.description)) {\r\n this.selectedBwErrors.push(errorObject);\r\n continue; //we only validate for klostersponning;\r\n }\r\n\r\n if (bw.customDepth > MAX_BEWERKING_DEPTH) {\r\n errorObject.depth = \"Voor deze neut ondersteunen wij diepte tot 20mm\";\r\n isValid = false;\r\n }\r\n\r\n if (this.neutLengte - bw.customLength - bw.customOffset < 0) {\r\n errorObject.overflow = \"Uw maten zijn gecombineerdbreder dan de neut\";\r\n isValid = false;\r\n }\r\n\r\n this.selectedBwErrors.push(errorObject);\r\n }\r\n\r\n return isValid;\r\n }\r\n\r\n private isSlidingDorpel() {\r\n const dorpelCode = this.uiState.currentDorpel.dorpelCode;\r\n const chosenDorpel = this.uiState.dorpelChoices.find(d => d.dorpelCode === dorpelCode);\r\n let isCurrentDoorSliding = chosenDorpel.dorpelsoort === \"Hefschuifdorpel\";\r\n\r\n return isCurrentDoorSliding;\r\n }\r\n\r\n public onBewerkingRemoved(index: number): void {\r\n this.errorMessage = null;\r\n this.selectedBwCodes.splice(index, 1);\r\n this.revalidateBwerkingenOptions();\r\n this.uiState.setBewerkingenOptions(this.selectedBwCodes);\r\n this.uiState.triggerRedraw();\r\n }\r\n\r\n public onBewerkingCustomDepthChanged(e: any, index: number): void {\r\n this.selectedBwCodes[index].customDepth = e.target.value ? parseInt(e.target.value) : null;\r\n let isValid = this.revalidateBwerkingenOptions();\r\n if (!isValid) return;\r\n this.uiState.setBewerkingenOptions(this.selectedBwCodes);\r\n this.uiState.triggerRedraw();\r\n }\r\n\r\n public onBewerkingCustomOffsetChanged(e: any, index: number): void {\r\n this.selectedBwCodes[index].customOffset = e.target.value ? parseInt(e.target.value) : null;\r\n let isValid = this.revalidateBwerkingenOptions();\r\n if (!isValid) return;\r\n this.uiState.setBewerkingenOptions(this.selectedBwCodes);\r\n this.uiState.triggerRedraw();\r\n }\r\n\r\n public onVerstekOrentatieChange(e: any, index: number): void {\r\n this.selectedBwCodes[index].orientatie = e.target.value;\r\n this.uiState.setBewerkingenOptions(this.selectedBwCodes);\r\n this.uiState.triggerRedraw();\r\n }\r\n\r\n public onCutNeutChanged(e: any, index: number): void {\r\n this.uiState.setBewerkingenOptions(this.selectedBwCodes);\r\n }\r\n\r\n public onBewerkingCustomLengthChanged(e: any, index: number): void {\r\n this.selectedBwCodes[index].customLength = e.target.value ? parseInt(e.target.value) : null;\r\n let isValid = this.revalidateBwerkingenOptions();\r\n if (!isValid) return;\r\n this.uiState.setBewerkingenOptions(this.selectedBwCodes);\r\n this.uiState.triggerRedraw();\r\n }\r\n\r\n public getData(): BestellingBewerkingDto[] {\r\n return this.selectedBwCodes;\r\n }\r\n\r\n public getDataForCode(code: string): BestellingBewerkingDto {\r\n let description = this.bewerkingen.find((b) => b.bewerkingCode === code).omschrijving;\r\n let defaults = BewerkingUtils.getDefaults(description)\r\n let bewerkingData: BestellingBewerkingDto = {\r\n bewerkingCode: code,\r\n description: description,\r\n customDepth: defaults?.depth,\r\n customLength: defaults?.length,\r\n customOffset: defaults?.offset\r\n }\r\n\r\n if (defaults.orientatie) {\r\n bewerkingData.orientatie = defaults.orientatie\r\n }\r\n\r\n if (defaults.cutNeut) {\r\n bewerkingData.cutNeut = defaults.cutNeut\r\n }\r\n\r\n return bewerkingData;\r\n }\r\n\r\n private getVerstekSponningData() { //TODO will read dynamic data from view (field)\r\n return {\r\n angle: 45\r\n }\r\n }\r\n}\r\n","<!-- <div class=\"sticky-top\">\r\n <app-header></app-header>\r\n</div> -->\r\n<div [ngClass]=\"themeSpecialClass\" class=\"container-fluid\">\r\n <luv-dorpel #dorpel [checkOtherFormsValidity]=\"checkOtherFormsValidity.bind(this)\"></luv-dorpel>\r\n <div *ngIf=\"!isDorpelConfigurationDisabled\"> <!-- PRODUCTION-PATCH: remove this wrapper once HS up to par-->\r\n <luv-neuten #neuten></luv-neuten>\r\n <luv-sluitpotten #sluitpotten></luv-sluitpotten>\r\n <app-bewerkingen-horiz #bewerkingen *ngIf=\"showBewerkingen\"></app-bewerkingen-horiz>\r\n <div class=\"container bg-white py-4 rounded-4 text-center\">\r\n <div [formGroup]=\"formGroup\" class=\"row justify-content-center\">\r\n <div class=\"col-sm-12\">\r\n <label for=\"opmerking\" class=\"form-label\"><b>Opmerkingen</b></label>\r\n <textarea class=\"form-control\" id=\"opmerking\" rows=\"3\" formControlName=\"dorpelOpmerking\"></textarea>\r\n </div>\r\n </div>\r\n <br />\r\n <div *ngIf=\"invalidComponentsMessage\" class=\"row justify-content-center invalid-components-message\">\r\n {{invalidComponentsMessage}}</div>\r\n <div class=\"row justify-content-center\">\r\n <div class=\"input-group justify-content-center\">\r\n <button *ngIf=\"viewMode === 'Add'\" type=\"button\"\r\n class=\"action-button btn btn-primary btn-lg px-4 gap-3 border-0 rounded-0\"\r\n (click)=\"clearData()\"><b>Verwijderen</b></button>\r\n <button type=\"button\" class=\"action-button btn btn-primary btn-lg px-4 gap-3 border-0 rounded-0\"\r\n (click)=\"addToCardAndClearData()\"><b>{{addToCartAndClearButtonLabel}}</b></button>\r\n <button type=\"button\" class=\"action-button btn btn-primary btn-lg px-4 gap-3 border-0 rounded-0\"\r\n (click)=\"addToCart()\"><b>{{addToCartButtonLabel}}</b></button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"isDorpelConfigurationDisabled\"> <!-- PRODUCTION-PATCH: remove this content once HS up to par-->\r\n <div class=\"row justify-content-center\">\r\n <div>\r\n <div class=\"col-xl-12\">\r\n <p>We zijn momenteel bezig met onderhoud met betrekking tot de hefschuifdorpels.</p>\r\n <h6>Bestelformulieren aluminium onderdorpels</h6>\r\n <ol>\r\n <li><a\r\n href=\"http://www.luvema.nl/upload/file/quick/Bestelformulier%20(70)%20Onderdorpels%20hefschuifdeuren%20Schema-A.pdf\"\r\n target=\"_blank\">hefschuif schema A</a></li>\r\n <li><a\r\n href=\"http://www.luvema.nl/upload/file/quick/Bestelformulier%20(71)%20Onderdorpels%20hefschuifdeuren%20Schema-C&G.pdf\"\r\n target=\"_blank\">hefschuif schema C & G</a></li>\r\n <li><a\r\n href=\"http://www.luvema.nl/upload/file/quick/Bestelformulier%20(72)%20Onderdorpels%20hefschuifdeuren%20Schema-D.pdf\"\r\n target=\"_blank\">hefschuif schema D</a></li>\r\n <li><a\r\n href=\"http://www.luvema.nl/upload/file/quick/Bestelformulier%20(73)%20Onderdorpels%20hefschuifdeuren%20SPECIALS.pdf\"\r\n target=\"_blank\">hefschuif specials</a></li>\r\n </ol>\r\n <h6>Bestelformulieren ISOWEL Onderdorpels</h6>\r\n <ol>\r\n <li>hefschuif schema A - <a\r\n href=\"http://luvema.nl/upload/file/Bestelformulier%20IW-HS%20schema%20A%20-%202023(1).pdf\"\r\n target=\"_blank\">HS140 / 146</a> of <a\r\n href=\"http://luvema.nl/upload/file/order-forms/Bestelformulier%20IW-HS190%20schema%20A%20-%202023%20(1).pdf\"\r\n target=\"_blank\">HS190</a></li>\r\n <li>hefschuif schema C & G - <a\r\n href=\"http://luvema.nl/upload/file/Bestelformulier%20IW-HS%20schema%20C%20%2B%20G%20-%202023(1).pdf\"\r\n target=\"_blank\">HS140 / 146</a> of <a\r\n href=\"http://luvema.nl/upload/file/order-forms/Bestelformulier%20IW-HS190%20schema%20C%20%2B%20G%20-%202023%20(1).pdf\"\r\n target=\"_blank\">HS190</a></li>\r\n <li>hefschuif special - <a\r\n href=\"http://luvema.nl/upload/file/Bestelformulier%20IW-HS%20special%20-%202023(1).pdf\"\r\n target=\"_blank\">HS140 / 146</a> of <a\r\n href=\"http://luvema.nl/upload/file/order-forms/Bestelformulier%20IW-HS190%20special%20-%202023.pdf\"\r\n target=\"_blank\">HS190</a></li>\r\n </ol>\r\n <div>\r\n <div>Telefoon: +31(0)317-612878</div>\r\n <div>Email: <a href=\"mailto:info@luvema.nl\">info@luvema.nl</a></div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<app-footer></app-footer>","import { Component, OnInit, ViewChild } from \"@angular/core\";\r\nimport { UiStateService } from \"../core/services/ui-state-service\";\r\nimport { Router, ActivatedRoute } from \"@angular/router\";\r\nimport { DorpelComponent } from \"../dorpel/dorpel.component\";\r\nimport { DataStateService } from \"../core/services/data-state.service\";\r\nimport { NeutenComponent } from \"../neuten/neuten.component\";\r\nimport { SluitpotComponent } from \"../sluitpot/sluitpot.component\";\r\nimport { BewerkingenHorizComponent } from \"../bewerkingen-horiz/bewerkingen-horiz.component\";\r\nimport { ModelFactory } from \"../shared/models/model-factory\";\r\nimport { BestellingDorpelDto } from \"../shared/api-models/models\";\r\nimport { environment } from \"../../environments/environment\";\r\nimport { filter, map, takeUntil } from \"rxjs/operators\";\r\nimport { BaseComponent } from \"../shared/base.component\";\r\nimport { Observable } from \"rxjs\";\r\nimport { FormGroup, FormBuilder } from \"@angular/forms\";\r\n\r\n@Component({\r\n selector: \"app-overzicht\",\r\n templateUrl: \"./dorpel-page-horiz.component.html\",\r\n styleUrls: [\"./dorpel-page.component.scss\"],\r\n})\r\nexport class DorpelPageComponent extends BaseComponent implements OnInit {\r\n @ViewChild(\"acc\", { static: true }) acc;\r\n public currentDorpel: BestellingDorpelDto;\r\n public viewMode: \"Edit\" | \"Add\";\r\n public addToCartButtonLabel: string = null;\r\n public addToCartAndClearButtonLabel: string = null;\r\n public customClass: string;\r\n public formGroup: FormGroup;\r\n public invalidComponentsMessage: string | null = null;\r\n\r\n @ViewChild(\"dorpel\") private dorpelForm: DorpelComponent;\r\n @ViewChild(\"neuten\") private neutenForm: NeutenComponent;\r\n @ViewChild(\"sluitpotten\") private sluitpotForm: SluitpotComponent;\r\n @ViewChild(\"bewerkingen\") private bewerkingen: BewerkingenHorizComponent;\r\n private dorpelGuid: string;\r\n private isCurrentDoorSliding: boolean; //PRODUCTION-PATCH: remove this once HS up to par\r\n public showBewerkingen: boolean = true;\r\n\r\n constructor(\r\n private dataState: DataStateService,\r\n private uiStateService: UiStateService, //PRODUCTION-PATCH: remove this once HS up to par\r\n private uiState: UiStateService,\r\n private router: Router,\r\n private formBuilder: FormBuilder,\r\n private activatedRoute: ActivatedRoute\r\n ) {\r\n super();\r\n }\r\n\r\n ngOnInit(): void {\r\n this.dorpelGuid =\r\n this.activatedRoute.snapshot.queryParamMap.get(\"dorpelGuid\");\r\n const productType =\r\n this.activatedRoute.snapshot.paramMap.get(\"productType\");\r\n this.uiState.setProductType(productType); //notify header on refresh\r\n this.customClass = productType.toLowerCase();\r\n\r\n this.currentDorpel = !!this.dorpelGuid\r\n ? this.dataState.getDorpelById(this.dorpelGuid)\r\n : ModelFactory.createBestellingDorpel(productType);\r\n\r\n if (!this.currentDorpel) {\r\n /**\r\n * if we do a refresh in the edit dorpel component, we should navigate to root\r\n * as all the models are empty even if the dorpel guid is conserved in the path.\r\n * there will be no order and no model attached to the guid\r\n */\r\n this.router.navigate([\"/\"]);\r\n }\r\n\r\n this.formGroup = this.buildForm(this.currentDorpel);\r\n this.uiState.viewMode = !!this.dorpelGuid ? \"Edit\" : \"Add\";\r\n this.viewMode = this.uiState.viewMode;\r\n this.addToCartButtonLabel =\r\n this.viewMode === \"Add\"\r\n ? \"Toevoegen aan dorpeloverzicht\"\r\n : \"Wijzigingen opslaan\";\r\n this.addToCartAndClearButtonLabel =\r\n this.viewMode === \"Add\"\r\n ? \"Opslaan en nieuwe dorpel maken\"\r\n : \"Wijzigingen opslaan en nieuwe dorpel toevoegen\";\r\n this.uiState.setCurrentDorpel(this.currentDorpel);\r\n this.uiState.neutenCount$\r\n .pipe(takeUntil(this.unsubscribe$))\r\n .subscribe((count) => {\r\n if (!count) {\r\n this.showBewerkingen = false;\r\n return;\r\n } else {\r\n this.showBewerkingen = true;\r\n }\r\n });\r\n this.uiState.dorpelCode$\r\n .pipe(\r\n filter((dorpelCode) => !!dorpelCode),\r\n takeUntil(this.unsubscribe$)\r\n )\r\n .subscribe((dorpelCode) => {\r\n this.enableDorpelOpmerkingField();\r\n\r\n //PRODUCTION-PATCH: remove this once HS up to par\r\n const chosenDorpel = this.uiStateService.dorpelChoices.find(\r\n (d) => d.dorpelCode === dorpelCode\r\n );\r\n this.isCurrentDoorSliding = chosenDorpel.dorpelsoort === \"Hefschuifdorpel\";\r\n //END\r\n });\r\n }\r\n\r\n get themeSpecialClass() {\r\n let dealerClass = this.uiState.customDealerResources?.customClass;\r\n return dealerClass || this.customClass;\r\n }\r\n\r\n get isFromPrefilledOrder(): boolean {\r\n return !!this.uiState?.fromPrefilledOrder;\r\n }\r\n\r\n get isDorpelConfigurationDisabled(): boolean {\r\n // return this.isCurrentDoorSliding;\r\n return false;\r\n }\r\n\r\n private checkFormValidity(): boolean {\r\n let valid: boolean = true;\r\n\r\n const dorpel = this.dataState.createTempDorpel(this.currentDorpel);\r\n\r\n this.dataState\r\n .addDorpelData(this.dorpelForm.formGroup.value, dorpel)\r\n .addNeutenData(this.neutenForm.getNeutenFormData(), dorpel)\r\n .addSluitpottenData(this.sluitpotForm.getSluitpotModels(), dorpel)\r\n .addBewerkingen(this.bewerkingen?.getData() || [], dorpel);\r\n\r\n valid = valid && this.dorpelForm.validateZaagmaat(dorpel);\r\n\r\n return valid;\r\n }\r\n\r\n public addToCart(preventNavigation = false): void {\r\n const formsValidity = [this.dorpelForm.dataIsValid()];\r\n\r\n formsValidity.push(this.neutenForm.dataIsValid());\r\n formsValidity.push(this.sluitpotForm.dataIsValid());\r\n\r\n if (formsValidity.some((v) => !v) && !environment.disableFieldValidation) {\r\n return;\r\n }\r\n\r\n if (!this.checkFormValidity() && !environment.disableFieldValidation) {\r\n return;\r\n }\r\n\r\n if (!this.neutenForm.validateNeutenComponents()) {\r\n this.invalidComponentsMessage =\r\n \"The current configuration has invalid components\";\r\n return;\r\n } else {\r\n this.invalidComponentsMessage = null;\r\n }\r\n\r\n const state = !!this.dorpelGuid\r\n ? this.dataState.editDorpel(this.dorpelGuid)\r\n : this.dataState.createDorpel(this.currentDorpel);\r\n\r\n state\r\n .addDorpelData(this.dorpelForm.formGroup.value)\r\n .addNeutenData(this.neutenForm.getNeutenFormData())\r\n .addSluitpottenData(this.sluitpotForm.sluitpottenModels)\r\n .addBewerkingen(this.bewerkingen?.getData() || [])\r\n .addDorpelOpmerking(this.formGroup.get(\"dorpelOpmerking\").value);\r\n\r\n state.addDrawing(this.dorpelForm.getDorpelDrawingData());\r\n\r\n // console.log('current state: ');\r\n // console.log(this.dataState.getModel());\r\n\r\n if (!preventNavigation) {\r\n this.router.navigate([this.dataState.homePath]);\r\n }\r\n }\r\n\r\n showSluitpottenComponent$(): Observable<boolean> {\r\n return this.uiState.schema$.pipe(map((s) => !s || s === \"\"));\r\n }\r\n\r\n public checkOtherFormsValidity(): boolean {\r\n return this.neutenForm.dataIsValid();\r\n }\r\n\r\n private buildForm(dorpel: BestellingDorpelDto): FormGroup {\r\n const formGroup = this.formBuilder.group({\r\n dorpelOpmerking: [{ value: dorpel?.opmerking || \"\", disabled: true }],\r\n });\r\n\r\n return formGroup;\r\n }\r\n\r\n private enableDorpelOpmerkingField(): void {\r\n this.formGroup.controls[\"dorpelOpmerking\"].enable();\r\n }\r\n\r\n public clearData(): void {\r\n const currentRoute = this.activatedRoute.snapshot.url.map(segment => segment.path).join('/');\r\n this.router.navigateByUrl(\"/\", { skipLocationChange: true }).then(() => {\r\n this.router.navigate([\"order-form\", this.uiStateService.currentProductType, currentRoute]);\r\n });\r\n }\r\n\r\n public addToCardAndClearData(): void {\r\n this.addToCart(true);\r\n this.clearData();\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { DataStateService } from './data-state.service';\r\nimport { UiStateService } from './ui-state-service';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class CleanupService {\r\n constructor(private stateService: DataStateService, private uiService: UiStateService) { }\r\n\r\n public cleanup() {\r\n this.stateService.setModel(null);\r\n //this.uiService.cleanup();\r\n }\r\n}\r\n","<div class=\"overzicht-wrapper\">\r\n <ngx-spinner bdColor=\"rgba(0,0,0,0.8)\" size=\"medium\" color=\"#bdd6e5\" type=\"ball-atom\" [fullScreen]=\"true\">\r\n <p style=\"color: white\"> uw bestelling wordt verzonden... </p>\r\n </ngx-spinner>\r\n\r\n <div class=\"container px-4 py-5 my-5 text-center bg-white rounded-4\">\r\n <h1 class=\"display-5 fw-bold text-body-emphasis\">Dorpelbestellen.nl</h1>\r\n <h4>Orderoverzicht</h4>\r\n </div>\r\n\r\n <div class=\"container-fluid\">\r\n <div class=\"container bg-white px-4 py-4 my-4 rounded-4\">\r\n <div class=\"col-md-8 page-title\">\r\n <h4>Orderbevestiging</h4>\r\n </div>\r\n <br>\r\n <div class=\"row d-flex\">\r\n <div class=\"col-md-8\">\r\n <div *ngIf=\"logoUrl\" class=\"logo-holder\">\r\n <img id=\"logo\" class=\"rounded img-fluid\" width=\"75\" height=\"30\" [src]=\"logoUrl\">\r\n </div>\r\n <table>\r\n <tr>\r\n <td>\r\n <b>Klant:</b>\r\n </td>\r\n <td>\r\n {{model.opdrachtgever}}\r\n </td>\r\n </tr>\r\n <tr>\r\n <td>\r\n <b>Dealer:</b>\r\n </td>\r\n <td>\r\n {{model.dealerCode}}\r\n </td>\r\n </tr>\r\n <tr>\r\n <td>\r\n <b>Contactpersoon:</b>\r\n </td>\r\n <td>\r\n {{model.contactpersoon}}\r\n </td>\r\n </tr>\r\n <tr>\r\n <td>\r\n <b>Telefoonnummer:</b>\r\n </td>\r\n <td>\r\n {{model.telefoonnummer}}\r\n </td>\r\n </tr>\r\n <tr>\r\n <td>\r\n <b>E-mailadres:</b>\r\n </td>\r\n <td>\r\n {{model.emailadres}}\r\n </td>\r\n </tr>\r\n <tr>\r\n <td>\r\n <b>uw referentie:</b>\r\n </td>\r\n <td>\r\n {{model.uwReferentie}}\r\n </td>\r\n </tr>\r\n <tr>\r\n <td>\r\n <b>Gewenste afleverdatum:</b>\r\n </td>\r\n <td>\r\n {{model.afleverdatum}}\r\n </td>\r\n </tr>\r\n <tr *ngIf=\"model.opmerkingen\">\r\n <td colspan=\"2\">\r\n <b>Opmerkingen:</b>\r\n </td>\r\n </tr>\r\n <tr *ngIf=\"model.opmerkingen\">\r\n <td colspan=\"2\">\r\n {{model.opmerkingen}}\r\n </td>\r\n </tr>\r\n <tr *ngIf=\"model.files.length > 0\">\r\n <td colspan=\"2\">\r\n <b>bijlage:</b>\r\n </td>\r\n </tr>\r\n <tr *ngFor=\"let file of model.files\">\r\n <td colspan=\"2\">\r\n {{file?.name || 'er is geen bijlage geselecteerd'}}\r\n </td>\r\n </tr>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row my-2 justify-content-center\" *ngFor=\"let dorpel of model.dorpels\">\r\n <div class=\"container bg-white px-4 py-4 my-4 rounded-4\">\r\n <h5>{{dorpel.dorpelCode}} - {{dorpel.merk}} - {{dorpel.zaagmaat}}MM ({{dorpel.aantal}} stuks)</h5>\r\n\r\n <div class=\"row my-2\">\r\n <!-- <div class=\"col overzicht-data\" *ngIf=\"dorpel.omschrijving\">\r\n <label for=\"maata\">Dorpeltype:</label><br> {{dorpel.omschrijving}}\r\n </div> -->\r\n <div class=\"col overzicht-data\" *ngIf=\"dorpel.schema\">\r\n <label for=\"maata\">Dorpel Schema:</label><br> {{dorpel.schema}}\r\n </div>\r\n <div class=\"col overzicht-data\" *ngIf=\"dorpel.aantal\">\r\n <label for=\"maata\">Aantal:</label><br> {{dorpel.aantal}}\r\n </div>\r\n <div class=\"col overzicht-data\" *ngIf=\"dorpel.merk\">\r\n <label for=\"referentie\">Merk:</label><br> {{dorpel.merk}}\r\n </div>\r\n <div class=\"col overzicht-data\" *ngIf=\"dorpel.zaagmaat\">\r\n <label for=\"Zaagmaat\">Zaagmaat:</label><br> {{dorpel.zaagmaat}} MM\r\n </div>\r\n <div class=\"col overzicht-data\" *ngIf=\"dorpel.neuten.length\">\r\n <label for=\"Zaagmaat\">Aantal Neuten:</label><br> {{dorpel.neuten.length}}\r\n </div>\r\n <div class=\"col overzicht-data\" *ngIf=\"dorpel.sluitpotten.length\">\r\n <label for=\"Zaagmaat\">Aantal Sluitpotten:</label><br> {{dorpel.sluitpotten.length}}\r\n </div>\r\n </div>\r\n\r\n <div class=\"row my-2 justify-content-center\" *ngIf=\"dorpel.drawing\">\r\n <div class=\"col-md-12 justify-content-center\">\r\n <img class=\"dorpel-drawing\" [src]=\"dorpel.drawing\" alt=\"drawing\">\r\n </div>\r\n </div>\r\n\r\n\r\n <div class=\"row my-2 justify-content-center\">\r\n <div class=\"col overzicht-data\" *ngIf=\"dorpel.firstMaatA\">\r\n <label for=\"firstMaatA\">Vak 2:</label><br> {{dorpel.firstMaatA}} MM\r\n </div>\r\n <div class=\"col overzicht-data\" *ngIf=\"dorpel.deurmaatA\">\r\n <label for=\"deurmaatA\">Deurmaat:</label><br> {{dorpel.deurmaatA}} MM\r\n </div>\r\n <div class=\"col overzicht-data\" *ngIf=\"dorpel.maatB\">\r\n <label for=\"maatB\">Vak 2:</label><br> {{dorpel.maatB}} MM\r\n </div>\r\n <div class=\"col overzicht-data\" *ngIf=\"dorpel.deurmaatB\">\r\n <label for=\"deurmaatB\">Deurmaat:</label><br> {{dorpel.deurmaatB}} MM\r\n </div>\r\n <div class=\"col overzicht-data\" *ngIf=\"dorpel.maatC\">\r\n <label for=\"maatC\">Vak 3:</label><br> {{dorpel.maatC}} MM\r\n </div>\r\n <div class=\"col overzicht-data\" *ngIf=\"dorpel.deurmaatC\">\r\n <label for=\"deurmaatC\">Deurmaat:</label><br> {{dorpel.deurmaatC}} MM\r\n </div>\r\n </div>\r\n <br />\r\n <div class=\"row my-2 justify-content-center\">\r\n <ng-container *ngFor=\"let neut of dorpel.neuten; let i = index\">\r\n <div class=\"col overzicht-data justify-content-center\" *ngIf=\"i == 0 && dorpel.maatA\">\r\n <label for=\"maata\">Vak 1:</label><br> {{dorpel.maatA}} MM\r\n </div>\r\n\r\n <div class=\"col overzicht-data justify-content-center\">\r\n <label>Neut:</label><br />\r\n <div *ngIf=\"neut.neutDescription\">\r\n <span>{{neut.neutDescription}}</span>\r\n </div>\r\n <div *ngIf=\"neut.neutCode\">\r\n <span>{{neut.neutCode}}</span>\r\n </div>\r\n <div *ngIf=\"neut.linksVoorsponning || neut.rechtsVoorsponning\">\r\n <br />\r\n <label>Voorsponning:</label><br />\r\n <div *ngIf=\"neut.linksVoorsponning\">\r\n <span *ngIf=\"neut.linksVoorsponning\">Links -\r\n {{neut.linksVoorsponning.width}}x{{neut.linksVoorsponning.height ||\r\n neut.linksVoorsponning.width}} MM</span><br />\r\n </div>\r\n <div *ngIf=\"neut.rechtsVoorsponning\">\r\n <span *ngIf=\"neut.rechtsVoorsponning\">Rechts -\r\n {{neut.rechtsVoorsponning.width}}x{{neut.rechtsVoorsponning.height ||\r\n neut.rechtsVoorsponning.width}} MM</span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"neut.customWidth\">\r\n <br />\r\n <label>Neutbreedte:</label><br />\r\n <span>{{neut.customWidth}} MM</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col overzicht-data justify-content-center\"\r\n *ngIf=\"i == dorpel.neuten.length-1 && dorpel.maatZ\">\r\n <label for=\"maatZ\">{{getMaatZLabel(i+2, dorpel.dorpelCode, dorpel.schema)}}:</label>\r\n <br> {{dorpel.maatZ}} MM\r\n </div>\r\n\r\n <div class=\"col overzicht-data justify-content-center\" *ngIf=\"i < dorpel.neuten.length-1\">\r\n <div *ngIf=\"!dorpel.schema\">\r\n <div *ngIf=\"neut.daagmaat\">\r\n <br />\r\n <label for=\"daagmaata1\">Vak {{(i+2)}} Dagmaat:</label><br>\r\n <span>{{neut.daagmaat}} MM</span><br>\r\n </div>\r\n <div *ngIf=\"neut.sponningsoort\">\r\n <br />\r\n <label for=\"sponningsoort\">Uitvoering:</label><br>\r\n <span>{{neut.sponningsoort}}</span><br>\r\n </div>\r\n <div *ngIf=\"neut.sponningmaat\">\r\n <br />\r\n <label>Sponningdiepte:</label><br />\r\n <span>{{neut.sponningmaat}} MM</span><br />\r\n </div>\r\n <div *ngIf=\"neut.glaslat\">\r\n <br />\r\n <label for=\"glaslat\">Glaslat:</label><br>\r\n <span>{{neut.glaslat}}</span>\r\n </div>\r\n <div *ngIf=\"neut.beglazingsprofiel\">\r\n <br />\r\n <label for=\"beglazingsprofiel\">Beglazingsprofiel:</label><br>\r\n <span>{{neut.beglazingsprofiel}}</span>\r\n </div>\r\n <div *ngIf=\"neut.aanslagprofiel\">\r\n <br />\r\n <label for=\"aanslagprofiel\">Aanslagprofiel:</label><br>\r\n <span>{{neut.aanslagprofiel}}</span>\r\n </div>\r\n <div *ngIf=\"neut.damverbreeding\">\r\n <br />\r\n <label for=\"damverbreeding\">Damverbreding:</label><br>\r\n <span>{{neut.damverbreeding}}</span>\r\n </div>\r\n <div>\r\n <br />\r\n <label for=\"gemonteerd\">Gemonteerd:</label><br>\r\n <span *ngIf=\"neut.gemonteerd\">Ja</span>\r\n <span *ngIf=\"!neut.gemonteerd\">Nee</span>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <br>\r\n <ng-container *ngFor=\"let sp of dorpel.sluitpotten; let i = index\">\r\n <div class=\"row my-2 justify-content-center\">\r\n <div class=\"col overzicht-data justify-content-center\">\r\n <label>Sluipot {{(i+1)}}</label><br>\r\n {{sp.omschrijving}}{{getSluitpotDimensions(sp)}}\r\n </div>\r\n </div>\r\n </ng-container>\r\n <div *ngIf=\"dorpel.railType\" class=\"row my-2 justify-content-center\">\r\n <div class=\"col overzicht-data justify-content-center\">\r\n <br><br>\r\n <label>Rail:</label><br> {{dorpel.railType}}\r\n </div>\r\n </div>\r\n <div *ngIf=\"getConcatenatedBewerkingen(dorpel)\" class=\"row my-2 justify-content-center\">\r\n <div class=\"col overzicht-data justify-content-center\">\r\n <br><br>\r\n <label for=\"Renovatiesponning\">Bewerkingen / opties:</label><br>\r\n {{getConcatenatedBewerkingen(dorpel)}}\r\n </div>\r\n </div>\r\n <div *ngIf=\"dorpel.opmerking\" class=\"row my-2 justify-content-center\">\r\n <div class=\"col overzicht-data justify-content-center\">\r\n <br><br>\r\n <label for=\"Opmerking\">Opmerking:</label><br> {{dorpel.opmerking}}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <br>\r\n <br>\r\n <div class=\"row my-4 justify-content-center\">\r\n <div class=\"col-sm-6 justify-content-center buttons-wrapper\">\r\n <button type=\"button\" class=\"action-button btn btn-primary btn-lg px-4 gap-3 border-0 rounded-0\"\r\n (click)=\"onGoBackButtonClicked()\"><b>Bestelling wijzigen</b></button>\r\n <button type=\"button\" class=\"action-button btn btn-primary btn-lg px-4 gap-3 border-0 rounded-0\"\r\n (click)=\"onDorpelConfirmButtonClicked()\"><b>Bestelling plaatsen</b></button>\r\n </div>\r\n </div>\r\n </div>\r\n <app-footer></app-footer>\r\n</div>","import { mergeMap, switchMap } from 'rxjs/internal/operators';\r\nimport { Component } from '@angular/core';\r\nimport { DataStateService } from '../core/services/data-state.service';\r\nimport { BestellingDorpelDto, BestellingDto, BestellingSluitpotDto, BewerkingUtils } from '../shared/api-models/models';\r\nimport { ActivatedRoute, Router } from '@angular/router';\r\nimport { BackendService } from '../core/services/backend.service';\r\nimport { BaseComponent } from '../shared/base.component';\r\nimport { Observable, from, of } from 'rxjs';\r\nimport { NgxSpinnerService } from 'ngx-spinner';\r\nimport { UiStateService } from '../core/services/ui-state-service';\r\nimport { CleanupService } from '../core/services/cleanup.service';\r\nimport { Location } from '@angular/common';\r\n\r\n@Component({\r\n templateUrl: './overzicht.component.html',\r\n styleUrls: ['./overzicht.component.scss']\r\n})\r\nexport class OverzichtComponent extends BaseComponent {\r\n\r\n public model: BestellingDto;\r\n public logoUrl: string;\r\n public customClass: string;\r\n\r\n constructor(private dataService: DataStateService, private router: Router,\r\n private _location: Location,\r\n private uiStateService: UiStateService,\r\n private backendService: BackendService,\r\n private spinner: NgxSpinnerService,\r\n private cleanupService: CleanupService,\r\n private activatedRoute: ActivatedRoute) {\r\n super();\r\n }\r\n\r\n ngOnInit() {\r\n this.model = this.dataService.getModel();\r\n this.logoUrl = this.uiStateService.logoUrl;\r\n }\r\n\r\n public onGoBackButtonClicked() {\r\n this._location.back();\r\n }\r\n\r\n public onDorpelConfirmButtonClicked() {\r\n this.spinner.show();\r\n this.postRequest().subscribe(r => {\r\n this.cleanupService.cleanup();\r\n\r\n setTimeout(() => {\r\n this.spinner.hide();\r\n this.router.navigate(['redirect'], { relativeTo: this.activatedRoute.parent });\r\n }, 500);\r\n }, err => {\r\n alert('There was an error processing your request! Please try again');\r\n this.spinner.hide();\r\n console.error(err);\r\n });\r\n }\r\n\r\n public getNeutName(positie: string): string {\r\n switch (positie) {\r\n case 'Links':\r\n return 'Linkerneut';\r\n case 'Tussen':\r\n return 'Middenneut';\r\n case 'Rechts':\r\n return 'Rechterneut';\r\n }\r\n }\r\n\r\n public getMaatZLabel(regularPosition: number, dorpelCode?: string, schema?: string): string {\r\n let isSliding = dorpelCode.toLowerCase().indexOf('hs') !== -1;\r\n\r\n if (!isSliding) {\r\n return `Vak ${regularPosition}`;\r\n }\r\n\r\n if (!schema || schema === 'AL' || schema === 'AR') {\r\n return \"Vak 2\";\r\n }\r\n\r\n if (schema === 'C+G') {\r\n return \"Vak 3\";\r\n }\r\n\r\n return \"Vak 4\";\r\n }\r\n\r\n\r\n public getConcatenatedBewerkingen(dorpel: BestellingDorpelDto): string {\r\n return dorpel.bewerkingen.map(b => {\r\n let hasCustomDimensions: boolean = !!b.customDepth || !!b.customLength || !!b.customOffset;\r\n let hasCustomOrientation: boolean = !!b.orientatie;\r\n let hasNeutCutOption: boolean = b.cutNeut !== null;\r\n let isKloostersponning: boolean = BewerkingUtils.isKloostersponning(b.description);\r\n let isRenovatiesponning: boolean = BewerkingUtils.isRenovatiesponning(b.description);\r\n let lengteLabel = isKloostersponning ? \"(C) Lengte\" : (isRenovatiesponning ? \"(A) Lengte\" : \"\");\r\n\r\n if (hasCustomOrientation) {\r\n let orientatieLabel = b.orientatie == \"naarBuiten\" ? \"Naar Buiten\" : (b.orientatie == \"naarBinnen\" ? \"Naar Binnen\": \"\");\r\n return b.description + (b.orientatie ? ` - Oriëntatie: ${orientatieLabel}` : \"\") + (hasNeutCutOption ? ` - Neut laten doorlopen in verstek: ${b.cutNeut ? \"Ja\" : \"Nee\"}` : \"\");\r\n }\r\n\r\n if (hasCustomDimensions) {\r\n return b.description + (b.customOffset ? ` - (A) Uit de dagkant: ${b.customOffset}mm` : \"\") + (b.customDepth ? ` - (B) Diepte: ${b.customDepth}mm` : \"\") + (b.customLength ? ` - ${lengteLabel}: ${b.customLength}mm` : \"\");\r\n }\r\n\r\n return b.description;\r\n }).join(', ');\r\n }\r\n\r\n public getSluitpotDimensions(sluitpot: BestellingSluitpotDto): string {\r\n let dimensions = \"\";\r\n\r\n if (sluitpot.maat) {\r\n dimensions += ` - ${sluitpot.maat}MM`\r\n }\r\n\r\n if (sluitpot.maat2) {\r\n dimensions += ` - ${sluitpot.maat2}MM`\r\n }\r\n\r\n return dimensions\r\n }\r\n\r\n private prefilledOrderFlowCleanup() {\r\n this.model.prefilledOrderformFile = null;\r\n this.uiStateService.fromPrefilledOrder = false;\r\n }\r\n\r\n private postRequest(): Observable<any> {\r\n const formData = new FormData();\r\n\r\n formData.append('json', JSON.stringify(this.model));\r\n\r\n if (this.uiStateService.fromPrefilledOrder) {\r\n this.prefilledOrderFlowCleanup();\r\n }\r\n\r\n return this.backendService.getOrderNo()\r\n .pipe(switchMap((orderNo: string) => this.uploadAttachments(this.model, orderNo)))\r\n .pipe(switchMap((orderNo: string) => this.backendService.postForm(formData, orderNo)));\r\n }\r\n\r\n private uploadAttachments(model: BestellingDto, orderno: string): Observable<any> {\r\n if (!model.files || model.files.length === 0) {\r\n return of(orderno);\r\n }\r\n\r\n //return forkJoin([model.files.map(f => this.uploadAttachmentFile(f, orderno))]);\r\n return from(model.files)\r\n .pipe(mergeMap(file => this.uploadAttachmentFile(file, orderno)));\r\n }\r\n\r\n private uploadAttachmentFile(file: any, orderno): Observable<any> {\r\n return this.backendService.uploadAttachment(file, orderno);\r\n }\r\n}\r\n\r\n\r\n\r\n","import { Component, OnInit } from '@angular/core';\r\nimport { ActivatedRoute, Router } from '@angular/router';\r\nimport {DataStateService} from '../core/services/data-state.service';\r\n\r\n@Component({\r\n selector: 'app-redirect',\r\n templateUrl: './redirect.component.html',\r\n styleUrls: ['./redirect.component.css']\r\n})\r\nexport class RedirectComponent implements OnInit {\r\n public productType: string;\r\n\r\n constructor(private state: DataStateService,\r\n private activatedRoute: ActivatedRoute,\r\n private router: Router) { }\r\n\r\n ngOnInit(): void {\r\n this.productType = this.activatedRoute.snapshot.paramMap.get('productType');\r\n }\r\n\r\n public onButtonClicked() {\r\n this.router.navigate([this.state.homePath]);\r\n }\r\n\r\n}\r\n","<div class=\"container px-4 py-5 my-5 text-center bg-white rounded-4\">\r\n <h1 class=\"display-5 fw-bold text-body-emphasis\">Dorpelbestellen.nl</h1><br>\r\n <h4> Bedankt voor uw bestelling wij gaan voor u aan de slag! </h4>\r\n <div class=\"gif-wrapper\">\r\n <img src=\"/assets/done.gif\">\r\n </div>\r\n <div class=\"col-lg-6 text-center mx-auto\">\r\n <span>U wordt binnen een aantal seconden doorverwezen naar het Dorpelportaal.</span>\r\n <button type=\"button\" class=\"action-button done-button btn btn-primary btn-lg px-4 gap-3 border-0 rounded-0\"\r\n (click)=\"onButtonClicked()\">\r\n <b>Naar dorpelportaal</b>\r\n </button>\r\n </div>\r\n</div>","import { Component, OnInit } from '@angular/core';\r\nimport { UiStateService } from '../core/services/ui-state-service';\r\nimport { BackendService } from '../core/services/backend.service';\r\nimport { BaseComponent } from '../shared/base.component';\r\nimport { takeUntil } from 'rxjs/internal/operators';\r\nimport { Router, ActivatedRoute } from '@angular/router';\r\nimport { DealerDto } from '../shared/api-models/models';\r\nimport { DataStateService } from '../core/services/data-state.service';\r\nimport { DEALER_GUID_STORAGE_KEY, DealerCustomResources } from './custom-dealer-resource-map';\r\n\r\n\r\nconst NO_PRODUCT = 'none';\r\nconst ASSETS_BASE_PATH = \"assets/\";\r\n\r\n@Component({\r\n selector: 'app-dealers',\r\n templateUrl: './dealers.component.html',\r\n styleUrls: ['./dealers.component.scss']\r\n})\r\nexport class DealersComponent extends BaseComponent implements OnInit {\r\n //default values (no dealer guid);\r\n public seeLuvema: boolean = true;\r\n public seeIsowel: boolean = true;\r\n public seeCentor: boolean = false; //centor controlled by xml flag\r\n public seeHenderson: boolean = false; //henderson removal solicited by customer\r\n public currentDealerGuid: string | null = null;\r\n\r\n // public get customDealerResources(): DealerCustomResources | null {\r\n // return this.uiState.customDealerResources;\r\n // }\r\n\r\n constructor(private uiState: UiStateService,\r\n private backendService: BackendService,\r\n private router: Router,\r\n private dataStateService: DataStateService,\r\n private activatedRoute: ActivatedRoute) {\r\n super();\r\n }\r\n\r\n ngOnInit() {\r\n const dealerGuid = this.activatedRoute.snapshot.paramMap.get('dealerGuid');\r\n this.uiState.setProductType(NO_PRODUCT);\r\n\r\n if (!dealerGuid) {\r\n sessionStorage.removeItem(DEALER_GUID_STORAGE_KEY);\r\n this.dataStateService.setLandingPagePath(`/`);\r\n this.uiState.setCustomDealerResources(null);\r\n return;\r\n }\r\n\r\n sessionStorage.setItem(DEALER_GUID_STORAGE_KEY, dealerGuid);\r\n this.dataStateService.setLandingPagePath(`/${dealerGuid}`);\r\n this.uiState.setCustomDealerResources(dealerGuid);\r\n\r\n this.backendService.getDealers()\r\n .pipe(\r\n takeUntil(this.unsubscribe$))\r\n .subscribe(result => {\r\n let currentDealersGroup: DealerDto[] = result.filter(dealer => dealer.sleutel.toLowerCase() === dealerGuid.toLowerCase());\r\n if (!currentDealersGroup.length) {\r\n this.uiState.setCurrentDealersGroup(null);\r\n return;\r\n }\r\n\r\n let randomDealer = currentDealersGroup[0];\r\n this.seeLuvema = !!randomDealer.luvema;\r\n this.seeIsowel = !!randomDealer.isowel;\r\n this.seeCentor = !!randomDealer.centor;\r\n // this.seeHenderson = !!randomDealer.henderson;\r\n\r\n this.uiState.setCurrentDealersGroup(currentDealersGroup);\r\n });\r\n }\r\n\r\n // goToPortal() {\r\n // if (this.uiState.customDealerResources && this.uiState.customDealerResources.customLink) {\r\n // window.location.href = this.uiState.customDealerResources.customLink\r\n // }\r\n // }\r\n\r\n // getImageLink() {\r\n // return `${ASSETS_BASE_PATH}${this.uiState.customDealerResources?.resourcesFolderName}/logo.jpg`\r\n // }\r\n}\r\n","<div class=\"container px-4 py-5 my-5 text-center bg-white rounded-4\">\r\n <h1 class=\"display-5 fw-bold text-body-emphasis\">Dorpelbestellen.nl</h1>\r\n <div class=\"col-lg-6 text-center mx-auto\">\r\n <p class=\"mb-4\"> Dit portaal is ingericht voor bestaande klanten van <a\r\n href=\"https://www.luvema.nl\" target=\"_blank\"><b>Luvema</b></a>.<br><br>Bent u nog geen klant of heeft u vragen neem dan\r\n <a href=\"https://www.luvema.nl/contact/\" target=\"_blank\"><b>contact</b></a> met ons op.<br><br>\r\n <!--Wilt u alleen profielen bestellen? Dat kan op <a\r\n href=\"https://www.profielbestellen.nl\" target=\"_blank\"><b>profielbestellen.nl</b></a>-->\r\n </p>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-6 d-grid gap-2 d-sm-flex justify-content-sm-center px-4 py-5 my-5\">\r\n <button type=\"button\" class=\"product-button\" [routerLink]=\"['/order-form/Isowel']\">\r\n <img class=\"rounded img-fluid \" width=\"150\" height=\"150\" src=\"assets\\isowel.jpg\">\r\n <h4>Isowel Dorpels</h4>\r\n </button>\r\n </div>\r\n <div class=\"col-6 d-grid gap-2 d-sm-flex justify-content-sm-center px-4 py-5 my-5\">\r\n <button type=\"button\" class=\"product-button\" [routerLink]=\"['/Luvema']\">\r\n <img class=\"rounded img-fluid \" width=\"150\" height=\"150\" src=\"assets\\logo.jpg\">\r\n <h4>Aluminium Dorpels</h4>\r\n </button>\r\n </div>\r\n\r\n </div>\r\n</div>\r\n\r\n<app-footer></app-footer>","import { Component } from '@angular/core';\r\n\r\n@Component({\r\n templateUrl: './luvema-landing.template.html',\r\n styleUrls: ['./luvema-landing.component.css']\r\n})\r\nexport class LuvemaLandingComponent { }","<div class=\"row justify-content-center luvema-lp-wrapper\">\r\n <div>\r\n <div class=\"col-xl-12\">\r\n <p>Helaas is het op dit moment niet meer mogelijk om Luvema dorpels te bestellen via het online portaal. U kunt\r\n deze nog wel bestellen middels onderstaande formulieren.</p>\r\n <h6>Bestelformulieren aluminium onderdorpels:</h6>\r\n <ul>\r\n <li><a href=\"https://luvema.nl/wp-content/uploads/2024/06/Bestelformulier-Lu-BI.pdf\"\r\n target=\"_blank\">Binnensponning BI.5757 / BI.6351</a></li>\r\n <li><a href=\"https://luvema.nl/wp-content/uploads/2024/06/Bestelformulier-Lu-BU.pdf\"\r\n target=\"_blank\">Buitensponning BU.4272 / BU.4767</a>\r\n </li>\r\n <li><a href=\"https://luvema.nl/wp-content/uploads/2024/06/Bestelformulier-Lu-HS-schema-A.pdf\"\r\n target=\"_blank\">Hefschuif schema A – HS.140 / HS.146</a></li>\r\n <li><a href=\"https://luvema.nl/wp-content/uploads/2024/06/Bestelformulier-Lu-HS-schema-C-en-G.pdf\"\r\n target=\"_blank\">Hefschuif schema C & G – HS.140 / HS.146</a></li>\r\n <li><a href=\"https://luvema.nl/wp-content/uploads/2024/06/Bestelformulier-Lu-HS-schema-D.pdf\"\r\n target=\"_blank\">Hefschuif schema D – HS.140 / HS.146</a></li>\r\n <li><a href=\"https://luvema.nl/wp-content/uploads/2024/06/Bestelformulier-Lu-HS-special.pdf\"\r\n target=\"_blank\">Hefschuif specials – HS.140 /HS.146</a></li>\r\n </ul>\r\n <div>\r\n <div>Telefoon: +31(0)317-612878</div>\r\n <div>Email: <a href=\"mailto:info@luvema.nl\">info@luvema.nl</a></div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>","import {NgModule} from '@angular/core';\r\nimport {ActivatedRouteSnapshot, RouterModule, Routes} from '@angular/router';\r\nimport {WelkomComponent} from './welkom/welkom.component';\r\nimport {DorpelPageComponent} from './dorpel-page/dorpel-page.component';\r\nimport {OverzichtComponent} from './overzicht/overzicht.component';\r\nimport {RedirectComponent} from './redirect/redirect.component';\r\nimport {DealersComponent} from './dealers/dealers.component';\r\nimport { LuvemaLandingComponent } from './landing-pages/luvema-landing.component';\r\n\r\nconst routes: Routes = [\r\n {\r\n path: '',\r\n redirectTo: 'products',\r\n pathMatch: 'full'\r\n },\r\n {\r\n path: 'products',\r\n component: DealersComponent\r\n },\r\n {\r\n path: ':dealerGuid',\r\n redirectTo: 'products/:dealerGuid',\r\n pathMatch: 'full'\r\n },\r\n {\r\n path: 'products/Luvema',\r\n component: LuvemaLandingComponent,\r\n pathMatch: 'full'\r\n },\r\n {\r\n path: 'products/:dealerGuid',\r\n component: DealersComponent\r\n },\r\n {\r\n path: 'order-form/:productType',\r\n children: [\r\n {\r\n path: '',\r\n component: WelkomComponent,\r\n canActivate: ['routecheck']\r\n },\r\n {\r\n path: 'dorpel',\r\n component: DorpelPageComponent,\r\n },\r\n {\r\n path: 'overzicht',\r\n component: OverzichtComponent\r\n },\r\n {\r\n path: 'redirect',\r\n component: RedirectComponent // added this for routing from overzicht to redirect\r\n },\r\n ]\r\n }\r\n];\r\n\r\n@NgModule({\r\n imports: [RouterModule.forRoot(routes)],\r\n exports: [RouterModule],\r\n providers: [\r\n {\r\n provide: \"routecheck\",\r\n useValue: (route: ActivatedRouteSnapshot) => {\r\n const productType = route.paramMap.get('productType'); // Get the route parameter\r\n return productType !== \"Luvema\"\r\n }\r\n }\r\n ]\r\n})\r\nexport class AppRoutingModule { }\r\n","import { Component } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { DataStateService } from '../core/services/data-state.service';\r\n\r\n@Component({\r\n selector: 'app-header',\r\n templateUrl: './header.component.html',\r\n styleUrls: ['./header.component.scss']\r\n})\r\nexport class HeaderComponent {\r\n constructor(private router: Router,\r\n private state: DataStateService) { }\r\n\r\n public onHeaderClicked() {\r\n this.router.navigate([this.state.landingPagePath]);\r\n }\r\n}\r\n","<div class=\"container-fluid py-2 header-wrapper sticky-top\">\r\n <h1 class=\"display-8 header-link\" (click)=\"onHeaderClicked()\">Dorpelbestellen.nl</h1>\r\n</div>\r\n","<div #tooltipbox class=\"tooltip-wrapper\" *ngIf=\"isVisible\" [style]=\"customStyle\">\r\n <div class=\"image-wrapper\" *ngIf=\"options?.imagePath\">\r\n <img src=\"{{options.imagePath}}\" alt=\"Tooltip related image\">\r\n </div>\r\n <div class=\"description-wrapper\" *ngIf=\"options?.textDescription\">\r\n <span>{{options.textDescription}}</span>\r\n </div>\r\n</div>","import {Component, ElementRef, ChangeDetectorRef, OnInit, ViewChild} from '@angular/core';\r\nimport {TooltipService} from \"../core/services/tooltip.service\";\r\n\r\n@Component({\r\n selector: 'luv-tooltip',\r\n templateUrl: './tooltip.component.html',\r\n styleUrls: ['./tooltip.component.css']\r\n})\r\nexport class TooltipComponent implements OnInit {\r\n public options: any;\r\n public isVisible: boolean = false;\r\n public customStyle: string;\r\n @ViewChild('tooltipbox')\r\n public tooltipbox: ElementRef;\r\n\r\n constructor(\r\n private tooltipService: TooltipService,\r\n private cdRef: ChangeDetectorRef\r\n ) {}\r\n\r\n ngOnInit(): void {\r\n this.tooltipService.registerTooltipComponent(this);\r\n }\r\n\r\n public setOptions(optionsObject: any): void {\r\n this.options = {};\r\n for (let key in optionsObject) {\r\n this.options[key] = optionsObject[key];\r\n }\r\n }\r\n\r\n public getOptions(): any {\r\n return this.options;\r\n }\r\n\r\n public showTooltip(): void {\r\n this.isVisible = true;\r\n this.cdRef.detectChanges();\r\n }\r\n\r\n public hideTooltip(): void {\r\n this.isVisible = false;\r\n }\r\n\r\n public setCustomStyle(customStyle: string): void {\r\n this.customStyle = customStyle;\r\n }\r\n};\r\n","import { Component, OnInit } from '@angular/core';\r\nimport { UiStateService } from './core/services/ui-state-service';\r\nimport { DEALER_GUID_STORAGE_KEY } from './dealers/custom-dealer-resource-map';\r\nimport { DataStateService } from './core/services/data-state.service';\r\n\r\n@Component({\r\n selector: 'app-root',\r\n templateUrl: './app.component.html',\r\n styleUrls: ['./app.component.scss']\r\n})\r\nexport class AppComponent implements OnInit {\r\n title = 'proef';\r\n\r\n public constructor(private uiState: UiStateService, private dataStateService: DataStateService,) {\r\n\r\n }\r\n\r\n public ngOnInit() {\r\n const cachedDealerGUID = sessionStorage.getItem(DEALER_GUID_STORAGE_KEY);\r\n if (cachedDealerGUID) {\r\n this.uiState.setCustomDealerResources(cachedDealerGUID);\r\n this.dataStateService.setLandingPagePath(`/${cachedDealerGUID}`);\r\n }\r\n }\r\n}\r\n","<div class=\"container-fluid\">\r\n <app-header></app-header>\r\n <router-outlet></router-outlet>\r\n <luv-tooltip></luv-tooltip>\r\n</div>","import { environment } from 'src/environments/environment';\r\nimport { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from \"@angular/common/http\";\r\nimport { Injectable } from \"@angular/core\";\r\nimport { Observable } from \"rxjs\";\r\n\r\n@Injectable()\r\nexport class ApiKeyInterceptor implements HttpInterceptor {\r\n intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\r\n request = request.clone({\r\n setHeaders: {\r\n 'X-Api-Key': this.getApiKey()\r\n }\r\n });\r\n return next.handle(request);\r\n }\r\n\r\n private getApiKey(): string {\r\n return environment.luvemaApiKey;\r\n }\r\n\r\n}\r\n","import { ApiKeyInterceptor } from './services/api-key-interceptor';\r\nimport { ModuleWithProviders, NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';\r\nimport { BackendService } from './services/backend.service';\r\nimport { UiStateService } from './services/ui-state-service';\r\nimport { NgxSpinnerModule } from \"ngx-spinner\";\r\n\r\n@NgModule({\r\n imports: [\r\n CommonModule,\r\n HttpClientModule,\r\n ],\r\n exports: [\r\n CommonModule,\r\n HttpClientModule,\r\n ],\r\n providers: [\r\n BackendService,\r\n UiStateService,\r\n {\r\n provide: HTTP_INTERCEPTORS,\r\n useClass: ApiKeyInterceptor,\r\n multi: true\r\n }\r\n ]\r\n})\r\nexport class CoreModule {\r\n static forRoot(): ModuleWithProviders {\r\n return {\r\n ngModule: CoreModule\r\n };\r\n }\r\n}\r\n","import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\r\nimport { RouterModule } from '@angular/router';\r\nimport { ValidationErrorComponent } from './validation-error/validation-error.component';\r\n\r\n@NgModule({\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n RouterModule,\r\n ],\r\n exports: [\r\n CommonModule,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n RouterModule,\r\n ValidationErrorComponent\r\n ],\r\n declarations: [\r\n ValidationErrorComponent\r\n ]\r\n})\r\nexport class SharedModule {\r\n}","import { BrowserModule } from '@angular/platform-browser';\r\nimport { NgModule } from '@angular/core';\r\n\r\nimport { AppRoutingModule } from './app-routing.module';\r\nimport { AppComponent } from './app.component';\r\n\r\nimport {NgbModule} from '@ng-bootstrap/ng-bootstrap';\r\nimport { WelkomComponent } from './welkom/welkom.component';\r\nimport { DorpelComponent } from './dorpel/dorpel.component';\r\nimport { HeaderComponent } from './header/header.component';\r\nimport { FooterComponent } from './footer/footer.component';\r\nimport { RedirectComponent } from './redirect/redirect.component';\r\nimport { CoreModule } from './core/core.module';\r\nimport { SharedModule } from './shared/shared.module';\r\nimport { NeutenComponent } from './neuten/neuten.component';\r\nimport { SluitpotComponent } from './sluitpot/sluitpot.component';\r\nimport { TooltipComponent } from './tooltip/tooltip.component';\r\nimport { DorpelPageComponent } from './dorpel-page/dorpel-page.component';\r\nimport { NeutComponent } from './neuten/neut/neut.component';\r\nimport { NO_ERRORS_SCHEMA } from '@angular/core';\r\nimport { OverzichtComponent } from './overzicht/overzicht.component';\r\nimport { DealersComponent } from './dealers/dealers.component';\r\nimport { NgxSpinnerModule } from 'ngx-spinner';\r\nimport { BrowserAnimationsModule } from '@angular/platform-browser/animations';\r\nimport { CanvasComponent } from './dorpel/canvas/canvas.component';\r\nimport { DaagmaatComponent } from './neuten/daagmaat/daagmaat.component';\r\nimport { BewerkingenHorizComponent } from './bewerkingen-horiz/bewerkingen-horiz.component';\r\nimport { BewerkingenPillComponent } from './bewerkingen-horiz/bewerkingen-pill/bewerkingen-pill.component';\r\nimport { FileValueAccessorDirective } from './shared/file-value-accessor.directive';\r\nimport { FileFormatValidator } from './shared/file-format-validator';\r\nimport { ResizeListener } from './shared/resize-listener';\r\nimport { LuvemaLandingComponent } from './landing-pages/luvema-landing.component';\r\nimport { IntegerOnlyDirective } from './shared/integer-only.directive';\r\n\r\n@NgModule({\r\n declarations: [\r\n AppComponent,\r\n WelkomComponent,\r\n DorpelPageComponent,\r\n DorpelComponent,\r\n HeaderComponent,\r\n FooterComponent,\r\n RedirectComponent,\r\n NeutenComponent,\r\n NeutComponent,\r\n SluitpotComponent,\r\n TooltipComponent,\r\n OverzichtComponent,\r\n DealersComponent,\r\n CanvasComponent,\r\n DaagmaatComponent,\r\n LuvemaLandingComponent,\r\n BewerkingenHorizComponent,\r\n BewerkingenPillComponent,\r\n FileValueAccessorDirective,\r\n IntegerOnlyDirective,\r\n FileFormatValidator,\r\n ResizeListener\r\n ],\r\n imports: [\r\n BrowserModule,\r\n AppRoutingModule,\r\n NgbModule,\r\n CoreModule,\r\n SharedModule,\r\n NgxSpinnerModule,\r\n BrowserAnimationsModule\r\n ],\r\n schemas: [\r\n NO_ERRORS_SCHEMA\r\n ],\r\n providers: [],\r\n bootstrap: [\r\n AppComponent\r\n ]\r\n})\r\nexport class AppModule { }\r\n","import { enableProdMode } from '@angular/core';\r\nimport { platformBrowserDynamic } from '@angular/platform-browser-dynamic';\r\n\r\nimport { AppModule } from './app/app.module';\r\nimport { environment } from './environments/environment';\r\n\r\nif (environment.production) {\r\n enableProdMode();\r\n}\r\n\r\nplatformBrowserDynamic().bootstrapModule(AppModule)\r\n .catch(err => console.error(err));\r\n","function webpackEmptyAsyncContext(req) {\n\t// Here Promise.resolve().then() is used instead of new Promise() to prevent\n\t// uncaught exception popping up in devtools\n\treturn Promise.resolve().then(function() {\n\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t});\n}\nwebpackEmptyAsyncContext.keys = function() { return []; };\nwebpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;\nmodule.exports = webpackEmptyAsyncContext;\nwebpackEmptyAsyncContext.id = \"zn8P\";"]}