HEX
Server: Apache/2.4.65 (Debian)
System: Linux 88f31f35b0b8 6.1.0-38-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.147-1 (2025-08-02) x86_64
User: www-data (33)
PHP: 8.2.29
Disabled: NONE
Upload Files
File: /var/www/html/wp-content/plugins/bing-webmaster-tools/static/js/main.145ad779.chunk.js.map
{"version":3,"sources":["components/ErrorConstants.tsx","components/APIHelper.tsx","components/withDashboardData.tsx","Constants.ts","components/Header.tsx","components/StartPage.tsx","components/Card.tsx","components/Dashboard.tsx","components/App.tsx","serviceWorker.js","index.js"],"names":["ErrorConstants","HttpStatusCode","Code","Message","baseURL","window","nonceHeader","headers","useFetch","requestUrl","a","withTimeout","Promise","resolve","reject","response","fetch","then","res","json","body","ok","data","error","catch","err","useSubmit","requestData","method","JSON","stringify","promise","timer","timeout","race","_","timeoutInit","status","Response","setTimeout","code","message","result","clearTimeout","console","SetApiKey","apiKey","apiContent","APIKey","failedSubmissions","param","Submissions","isEnabled","AutoSubmissionEnabled","url","StringConstants","ApiKeyHelpLink","BingWebmasterLink","PluginInfoLink","ApiKeyValidationError","UrlSubmitErrorMessage","ApiKeyRegex","RegExp","SubmitUrlRegex","logosvg","xmlns","width","height","viewBox","fill","transform","d","mobileLogoSvg","Header","className","title","onClick","open","Icon","iconName","StartPage","props","useState","setApiKey","TextField","type","value","onChange","event","item","placeholder","validateOnLoad","onGetErrorMessage","test","length","href","target","PrimaryButton","text","error_type","setAPIKeyAdded","addBanner","disabled","Card","tooltipId","useId","tooltipProps","onRenderContent","tooltip","leadingIconName","TooltipHost","closeDelay","directionalHint","id","aria-describedby","children","Dashboard","DashboardModalState","apiKeyInvalid","setApiKeyInvalid","apiSettings","setAPISettings","submissionStats","setSubmissionStats","submissionsList","setSubmissionsList","showApiKeyPopOverMenu","setShowApiKeyPopOverMenu","showAutoSubmissionsPopOverMenu","setShowAutoSubmissionsPopOverMenu","Hidden","modalState","setModalState","selectedOptionAutoSubmissions","setSelectedOptionAutoSubmissions","textFieldValueUrlSubmit","setTextFieldValueUrlSubmit","textFieldValueApiKey","setTextFieldValueApiKey","urlSubmitted","setUrlSubmitted","apiSettingsUpdated","setApiSettingsUpdated","apiKeyUpdated","setApiKeyUpdated","useEffect","CheckApiKeyValidity","GetApiSettings","GetStats","GetAllSubmissions","sort","b","submission_date","urlSubmissionTableColumns","key","name","fieldName","onRender","decodeURI","minWidth","time","Date","setUTCSeconds","getFullYear","format","data-submission","resubmitOnClick","maxWidth","submissionItemString","dataset","submission","submissionItem","parse","RetryFailedSubmissions","hasError","SubmissionErrors","isSubmitted","onMouseEnter","onMouseLeave","UpdateApiKeyModal","EditPrefAutoSubmissionModal","DefaultButton","SubmitUrlModal","Quota","PassedSubmissionCount","FailedSubmissionCount","map","timestamp","formatISO","submitted","blob","Blob","link","document","createElement","URL","createObjectURL","download","click","ShimmeredDetailsList","setKey","items","columns","selectionMode","SelectionMode","none","enableShimmer","undefined","ariaLabelForShimmer","ariaLabelForGrid","listProps","renderedWindowsAhead","renderedWindowsBehind","onRenderCheckbox","checked","val","ChoiceGroup","selectedKey","options","option","UpdateAutoSubmissionsEnabled","trim","SubmitUrl","App","hasAPIKey","setHasAPIKey","bannerList","setBannerList","GetApiKey","notification","concat","slice","closeBannerOnClick","bannerIndexString","index","temp","splice","parseInt","bannerItem","indexOf","data-index","Boolean","location","hostname","match","initializeIcons","rootElement","getElementById","ReactDOM","render","StrictMode","navigator","serviceWorker","ready","registration","unregister"],"mappings":"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","file":"static/js/main.145ad779.chunk.js","sourcesContent":["export const ErrorConstants = {\r\n    NoDataFound: {\r\n      Code: \"NoDataFound\",\r\n      Message: \"No data available\"\r\n    },\r\n\r\n    RequestTimedOut: {\r\n      HttpStatusCode: 408,\r\n      Code: \"RequestTimedOut\",\r\n      Message:\r\n        \"This might be a momentary issue, please try again or check back later\"\r\n    },\r\n\r\n    UrlNotAllowed: {\r\n      Code: \"UrlNotAllowed\",\r\n      Message:\r\n        \"We found that the URL submitted for block is important for Bing users and hence cannot be blocked through Bing Webmaster tools.\"\r\n    }\r\n  };\r\n","import { ErrorConstants } from \"./ErrorConstants\";\r\n\r\ndeclare global {\r\n    interface Window { wpr_object: any; }\r\n}\r\n\r\nconst baseURL = `${window['wpr_object']['api_url']}`;\r\n\r\nexport interface IHttpResponse<T> extends Response {\r\n  data?: T;\r\n  error?: IAPIError;\r\n}\r\n\r\nexport interface IAPIError {\r\n  code: string;\r\n  message: string;\r\n  details?: IAPIErrorDetails[];\r\n}\r\n\r\nexport interface IAPIErrorDetails {\r\n  target: string;\r\n  message: string;\r\n}\r\n\r\nconst nonceHeader = {\r\n  headers: {\r\n    \"X-WP-Nonce\": `${window['wpr_object']['api_nonce']}`\r\n  }\r\n};\r\n\r\nexport async function useFetch<T>(\r\n  requestUrl: RequestInfo\r\n): Promise<IHttpResponse<T>> {\r\n  return withTimeout<T>(\r\n    new Promise((resolve, reject) => {\r\n      let response: IHttpResponse<T>;\r\n      fetch(`${baseURL}${requestUrl}`, nonceHeader)\r\n        .then(res => {\r\n          response = res;\r\n          return res.json();\r\n        })\r\n        .then(body => {\r\n          if (response.ok) {\r\n            response.data = body;\r\n          } else {\r\n            response.error = body;\r\n          }\r\n          resolve(response);\r\n        })\r\n        .catch(err => {\r\n          reject(err);\r\n        });\r\n    })\r\n  );\r\n}\r\n\r\nexport async function useSubmit<T>(\r\n  requestUrl: RequestInfo,\r\n  requestData: any\r\n): Promise<IHttpResponse<T>> {\r\n  return withTimeout<T>(\r\n    new Promise((resolve, reject) => {\r\n      let response: IHttpResponse<T>;\r\n      fetch(`${baseURL}${requestUrl}`, {\r\n        method: \"POST\",\r\n        headers: {\r\n          ...(nonceHeader.headers),\r\n          \"Accept\": \"application/json, text/javascript, */*; q=0.01\",\r\n          \"Content-Type\": \"application/json;charset=UTF-8\"\r\n        },\r\n        body: JSON.stringify(requestData)\r\n      })\r\n        .then(res => {\r\n          response = res;\r\n          return res.json();\r\n        })\r\n        .then(body => {\r\n          if (response.ok) {\r\n            response.data = body;\r\n          } else {\r\n            response.error = body;\r\n          }\r\n          resolve(response);\r\n        })\r\n        .catch(err => {\r\n          reject(err);\r\n        });\r\n    })\r\n  );\r\n}\r\n\r\nexport function withTimeout<T>(\r\n  promise: Promise<IHttpResponse<T>>,\r\n  timeout = 60000\r\n) {\r\n  let timer: ReturnType<typeof setTimeout>;\r\n  return Promise.race<IHttpResponse<T>>([\r\n    promise,\r\n    new Promise<IHttpResponse<T>>((resolve, _) => {\r\n      let response: IHttpResponse<T>;\r\n      const timeoutInit: ResponseInit = {\r\n        status: ErrorConstants.RequestTimedOut.HttpStatusCode\r\n      };\r\n      response = new Response(null, timeoutInit);\r\n      timer = setTimeout(() => {\r\n        response.error = {\r\n          code: ErrorConstants.RequestTimedOut.Code,\r\n          message: ErrorConstants.RequestTimedOut.Message\r\n        };\r\n        resolve(response);\r\n      }, timeout);\r\n    })\r\n  ]).then(result => {\r\n    clearTimeout(timer);\r\n    return result;\r\n  });\r\n}\r\n\r\nexport async function useDownload(\r\n  requestUrl: RequestInfo,\r\n  requestData: any,\r\n  callback?: () => void\r\n): Promise<IHttpResponse<void>> {\r\n  return new Promise((resolve, reject) => {\r\n    let response: any;\r\n    fetch(`${baseURL}${requestUrl}`, {\r\n      method: \"POST\",\r\n      headers: {\r\n        ...(nonceHeader.headers),\r\n        \"Accept\": \"application/json, text/javascript, */*; q=0.01\",\r\n        \"Content-Type\": \"application/json;charset=UTF-8\"\r\n      },\r\n      body: JSON.stringify(requestData)\r\n    })\r\n      .then(res => {\r\n        response = res;\r\n        return res.blob();\r\n      })\r\n      .then(blob => {\r\n        const url: string = window.URL.createObjectURL(blob);\r\n        const a: HTMLAnchorElement = document.createElement(\"a\");\r\n        a.href = url;\r\n        a.download = response.headers\r\n          .get(\"content-disposition\")\r\n          .split(\"filename=\")[1];\r\n        document.body.appendChild(a); // we need to append the element to the dom -> otherwise it will not work in firefox\r\n        a.click();\r\n        resolve(response);\r\n        setTimeout(() => {\r\n          a.remove(); // afterwards we remove the element again\r\n        }, 100);\r\n        if (callback) {\r\n          callback();\r\n        }\r\n      })\r\n      .catch(err => {\r\n        reject(err);\r\n      });\r\n  });\r\n}\r\n","import { IHttpResponse, useFetch, useSubmit } from \"./APIHelper\";\r\nimport {\r\n  ISetApiKeyRequest,\r\n  IGetApiSettingsResponse,\r\n  IGetStatsResponse,\r\n  IGetAllSubmissionsResponse,\r\n  ISubmitUrlResponse,\r\n  ISubmitUrlRequest,\r\n  IGetApiKeyResponse,\r\n  ISetApiKeyResponse,\r\n  IRetryFailedSubmissionsResponse,\r\n  IRetryFailedSubmissionsRequest,\r\n  ISetAutoSubmissionEnabledResponse,\r\n  ISetAutoSubmissionEnabledRequest,\r\n  ICheckApiKeyValidityResponse,\r\n  UrlSubmission,\r\n} from \"./Interfaces\";\r\n\r\nexport async function GetApiKey() {\r\n  let response: IHttpResponse<IGetApiKeyResponse>;\r\n  const url = `apiKey`;\r\n  response = await useFetch<IGetApiKeyResponse>(url).catch((err) => {\r\n    console.error(\"Error while fetching API key.\");\r\n    return err;\r\n  });\r\n  return response;\r\n}\r\n\r\nexport async function SetApiKey(apiKey: string) {\r\n  let response: IHttpResponse<ISetApiKeyResponse>;\r\n  const url = `apiKey`;\r\n  const apiContent: ISetApiKeyRequest = {\r\n    APIKey: apiKey,\r\n  };\r\n  response = await useSubmit<ISetApiKeyResponse>(url, apiContent).catch(\r\n    (err) => {\r\n      console.error(\"Error while updating API key.\");\r\n      return err;\r\n    }\r\n  );\r\n  return response;\r\n}\r\n\r\nexport async function CheckApiKeyValidity() {\r\n  let response: IHttpResponse<ICheckApiKeyValidityResponse>;\r\n  const url = `apiKeyValidity`;\r\n  response = await useFetch<ICheckApiKeyValidityResponse>(url).catch((err) => {\r\n    console.error(\"Error while checking API key validity.\");\r\n    return err;\r\n  });\r\n  return response;\r\n}\r\n\r\nexport async function GetApiSettings() {\r\n  let response: IHttpResponse<IGetApiSettingsResponse>;\r\n  const url = `apiSettings`;\r\n  response = await useFetch<IGetApiSettingsResponse>(url).catch((err) => {\r\n    console.error(\"Error while fetching plugin settings.\");\r\n    return err;\r\n  });\r\n  return response;\r\n}\r\n\r\nexport async function GetStats() {\r\n  let response: IHttpResponse<IGetStatsResponse>;\r\n  const url = `getStats`;\r\n  response = await useFetch<IGetStatsResponse>(url).catch((err) => {\r\n    console.error(\"Error while fetching submission statistics.\");\r\n    return err;\r\n  });\r\n  return response;\r\n}\r\n\r\nexport async function GetAllSubmissions() {\r\n  let response: IHttpResponse<IGetAllSubmissionsResponse>;\r\n  const url = `allSubmissions`;\r\n  response = await useFetch<IGetAllSubmissionsResponse>(url).catch((err) => {\r\n    console.error(\"Error while fetching submitted URLs list.\");\r\n    return err;\r\n  });\r\n  return response;\r\n}\r\n\r\nexport async function RetryFailedSubmissions(\r\n  failedSubmissions: UrlSubmission[]\r\n) {\r\n  const param: IRetryFailedSubmissionsRequest = {\r\n    Submissions: failedSubmissions,\r\n  };\r\n  let response: IHttpResponse<IRetryFailedSubmissionsResponse>;\r\n  const url = `allSubmissions`;\r\n  response = await useSubmit<IRetryFailedSubmissionsResponse>(url, param).catch(\r\n    (err) => {\r\n      console.error(\"Error while retrying failed submissions.\");\r\n      return err;\r\n    }\r\n  );\r\n  return response;\r\n}\r\n\r\nexport async function UpdateAutoSubmissionsEnabled(isEnabled: boolean) {\r\n  const param: ISetAutoSubmissionEnabledRequest = {\r\n    AutoSubmissionEnabled: isEnabled,\r\n  };\r\n  let response: IHttpResponse<ISetAutoSubmissionEnabledResponse>;\r\n  const url = `automaticSubmission`;\r\n  response = await useSubmit<ISetAutoSubmissionEnabledResponse>(\r\n    url,\r\n    param\r\n  ).catch((err) => {\r\n    console.error(\"Error while updating automatic submission settings.\");\r\n    return err;\r\n  });\r\n  return response;\r\n}\r\n\r\nexport async function SubmitUrl(url: string) {\r\n  let response: IHttpResponse<ISubmitUrlResponse>;\r\n  const ep = `submitUrl`;\r\n  const apiContent: ISubmitUrlRequest = {\r\n    url: url,\r\n  };\r\n  response = await useSubmit<ISubmitUrlResponse>(ep, apiContent).catch(\r\n    (err) => {\r\n      console.error(\"Error while submitting URL.\");\r\n      return err;\r\n    }\r\n  );\r\n  return response;\r\n}\r\n","export class StringConstants {\r\n  static readonly ApiKeyHelpLink =\r\n    \"https://docs.microsoft.com/en-us/bingwebmaster/getting-access#using-api-key\";\r\n  static readonly BingWebmasterLink = \"https://bing.com/webmaster\";\r\n  static readonly PluginInfoLink = \"https://aka.ms/BingWordpressPluginAbout\";\r\n  static readonly ApiKeyValidationError =\r\n    \"Invalid API key! (Should be alphanumeric and 32 characters in length.)\";\r\n  // static readonly domain = \"example.com\";\r\n  static readonly UrlSubmitErrorMessage = \"Invalid URL!\";\r\n}\r\n\r\nexport const ApiKeyRegex = RegExp(\"^[a-zA-Z0-9]{0,32}$\");\r\n// eslint-disable-next-line no-useless-escape\r\n// export const urlRegex = RegExp(`^(?:http(s)?:\\/\\/)?[\\w.-]+(?:\\.(${url})+)+[/\\w.\\S]*$`);\r\n\r\n// eslint-disable-next-line no-useless-escape\r\nexport const SubmitUrlRegex = RegExp(\r\n  `^https?:\\\\/\\\\/(www\\\\.)?[-a-zA-Z0-9@:%._\\\\+~#=]{1,256}\\\\.[a-zA-Z0-9()]{1,6}\\\\b([-a-zA-Z0-9()@:%_\\\\+.~#?&//=]*)$`\r\n);\r\n","import \"../scss/Header.scss\";\r\n\r\nimport * as React from \"react\";\r\nimport { Icon } from \"@fluentui/react/lib/Icon\";\r\nimport { StringConstants } from \"../Constants\";\r\n\r\nconst logosvg = (\r\n  <svg\r\n    xmlns=\"http://www.w3.org/2000/svg\"\r\n    width=\"52.793\"\r\n    height=\"21.328\"\r\n    viewBox=\"0 0 52.793 21.328\"\r\n  >\r\n    <g fill=\"#fff\" transform=\"translate(311.5 -796.169)\">\r\n      <path d=\"M-311.5,796.169l4.261,1.5v15l6-3.464-2.942-1.38-1.856-4.62,9.456,3.322v4.83l-10.656,6.146-4.263-2.371Z\" />\r\n      <g transform=\"translate(-290.183 800.152)\">\r\n        <path\r\n          d=\"M2708.543,12811.441v-12.808h3.644a3.981,3.981,0,0,1,2.634.813,2.626,2.626,0,0,1,.974,2.116,3.115,3.115,0,0,1-.59,1.894,3.163,3.163,0,0,1-1.625,1.142v.037a3.26,3.26,0,0,1,2.072.978,3.011,3.011,0,0,1,.777,2.148,3.349,3.349,0,0,1-1.179,2.661,4.388,4.388,0,0,1-2.974,1.019Zm1.5-11.45v4.136h1.536a2.919,2.919,0,0,0,1.938-.594,2.07,2.07,0,0,0,.706-1.675q0-1.868-2.456-1.867Zm0,5.483v4.608h2.036a3.049,3.049,0,0,0,2.05-.625,2.139,2.139,0,0,0,.728-1.714q0-2.268-3.09-2.27Z\"\r\n          transform=\"translate(-2708.543 -12798.358)\"\r\n        />\r\n        <path\r\n          d=\"M2891.153,12795.346a.93.93,0,0,1-.669-.268.907.907,0,0,1-.277-.68.937.937,0,0,1,.947-.955.946.946,0,0,1,.684.271.955.955,0,0,1,0,1.354A.935.935,0,0,1,2891.153,12795.346Zm.715,11.179H2890.4v-9.076h1.465Z\"\r\n          transform=\"translate(-2880.606 -12793.443)\"\r\n        />\r\n        <path\r\n          d=\"M2974.872,12874.426h-1.464v-5.147c0-1.941-.654-2.912-2.071-2.912a2.306,2.306,0,0,0-1.818.826,3.061,3.061,0,0,0-.719,2.086v5.147h-1.465v-9.074h1.465v1.485h.036a3.234,3.234,0,0,1,2.946-1.7,2.8,2.8,0,0,1,2.3.97,4.314,4.314,0,0,1,.795,2.8Z\"\r\n          transform=\"translate(-2953.66 -12861.346)\"\r\n        />\r\n        <path\r\n          d=\"M3154.274,12873.6q0,5.038-4.822,5.038a6.237,6.237,0,0,1-2.909-.63l.384-1.255a4.883,4.883,0,0,0,2.508.658c2.25,0,3.375-1.175,3.375-3.567v-.991h-.036a3.308,3.308,0,0,1-3.077,1.735,3.378,3.378,0,0,1-2.746-1.156,4.864,4.864,0,0,1-1.041-3.271,5.7,5.7,0,0,1,1.121-3.708,3.747,3.747,0,0,1,3.068-1.375,2.877,2.877,0,0,1,2.675,1.483h.036v-1.264h1.465Zm-1.465-3.359v-1.277a2.613,2.613,0,0,0-.737-1.865,2.331,2.331,0,0,0-1.793-.778,2.542,2.542,0,0,0-2.125.987,4.4,4.4,0,0,0-.768,2.764,3.573,3.573,0,0,0,.737,2.37,2.379,2.379,0,0,0,1.951.914,2.464,2.464,0,0,0,1.963-.874A3.262,3.262,0,0,0,3152.809,12870.236Z\"\r\n          transform=\"translate(-3122.798 -12861.29)\"\r\n        />\r\n      </g>\r\n    </g>\r\n  </svg>\r\n);\r\n\r\nconst mobileLogoSvg = (\r\n  <svg\r\n    xmlns=\"http://www.w3.org/2000/svg\"\r\n    width=\"14.92\"\r\n    height=\"21.328\"\r\n    viewBox=\"0 0 14.92 21.328\"\r\n  >\r\n    <g fill=\"#fff\" transform=\"translate(311.5 -796.169)\">\r\n      <path d=\"M-311.5,796.169l4.261,1.5v15l6-3.464-2.942-1.38-1.856-4.62,9.456,3.322v4.83l-10.656,6.146-4.263-2.371Z\" />\r\n    </g>\r\n  </svg>\r\n);\r\n\r\ninterface IRightPanel {\r\n  title: string;\r\n}\r\n\r\nexport const Header: React.FunctionComponent = () => {\r\n\r\n  return (\r\n    <>\r\n      <header className=\"bw-Header\">\r\n        <div className=\"headerLeftElements floatLeft\">\r\n          <span className=\"bingLogo desktopOnly\">{logosvg}</span>\r\n          <span className=\"bingLogoMobile mobileOnly\">{mobileLogoSvg}</span>\r\n          <span className=\"pageTitle\">\r\n            URL Submission plugin\r\n          </span>\r\n        </div>\r\n        <div className=\"headerRightElements floatRight\">\r\n          <span\r\n            title=\"Help\"\r\n            onClick={() =>\r\n              window.open(StringConstants.PluginInfoLink, \"_blank\")\r\n            }\r\n            key=\"headerHelp\"\r\n          >\r\n            <span className=\"desktopOnly\">About this plugin</span>\r\n            <Icon iconName=\"Info\" className=\"bw-Icon\" />\r\n          </span>\r\n        </div>\r\n      </header>\r\n    </>\r\n  );\r\n};\r\n","import \"../scss/StartPage.scss\";\r\n\r\nimport * as React from \"react\";\r\nimport { useState } from \"react\";\r\nimport { PrimaryButton } from \"@fluentui/react/lib/Button\";\r\nimport { Icon } from \"@fluentui/react/lib/Icon\";\r\nimport { TextField } from \"@fluentui/react/lib/TextField\";\r\nimport { SetApiKey } from \"./withDashboardData\";\r\nimport { ApiKeyRegex, StringConstants } from \"../Constants\";\r\n\r\ninterface IStartPage {\r\n  addBanner: (str: string) => void;\r\n  setAPIKeyAdded: () => void;\r\n}\r\n\r\nexport const StartPage: React.FunctionComponent<IStartPage> = (props) => {\r\n  const [apiKey, setApiKey] = useState(\"\");\r\n\r\n  const onSubmitApiKey = (): void => {\r\n    Promise.resolve(SetApiKey(apiKey)).then((response) => {\r\n      if (response?.data?.error_type.length === 0) {\r\n        props.setAPIKeyAdded();\r\n      } else {\r\n        props.addBanner(`Adding API key failed: ${response.data?.error_type}`);\r\n      }\r\n    });\r\n  };\r\n\r\n  return (\r\n    <div className=\"bw-StartPageContent\">\r\n      <div className=\"featuresSection\">\r\n        <h2 className=\"inlineText\">What you can do with this plugin</h2>\r\n\r\n        <div className=\"featuresListContainer\">\r\n          <div className=\"featureItem\">\r\n            <Icon iconName=\"Rocket\" className=\"featureIcon\" />\r\n            <p>Automate URL submissions</p>\r\n          </div>\r\n          <div className=\"featureItem\">\r\n            <Icon iconName=\"Send\" className=\"featureIcon\" />\r\n            <p>Manual URL submissions</p>\r\n          </div>\r\n          <div className=\"featureItem\">\r\n            <Icon iconName=\"NumberField\" className=\"featureIcon\" />\r\n            <p>View stats of submitted URLs</p>\r\n          </div>\r\n          <div className=\"featureItem\">\r\n            <Icon iconName=\"ErrorBadge\" className=\"featureIcon\" />\r\n            <p>View recent submissions</p>\r\n          </div>\r\n          <div className=\"featureItem\">\r\n            <Icon iconName=\"BulletedList\" className=\"featureIcon\" />\r\n            <p>Re-submit recent submissions</p>\r\n          </div>\r\n        </div>\r\n      </div>\r\n\r\n      <div className=\"keyEntrySection\">\r\n        <div className=\"keyEntryCard\">\r\n          <h3>Add API Key To Get Started</h3>\r\n          <p>\r\n            Add valid API key and automate URL submission by clicking on Start\r\n            using this plugin. You can disable auto submission later from plugin\r\n            if needed.\r\n          </p>\r\n          <TextField\r\n            type=\"password\"\r\n            className=\"apiKeyTextField\"\r\n            value={apiKey}\r\n            onChange={(event, item) => {\r\n              setApiKey(item || \"\");\r\n            }}\r\n            placeholder=\"Enter 32 digit API key\"\r\n            validateOnLoad={false}\r\n            onGetErrorMessage={() => {\r\n              return !ApiKeyRegex.test(apiKey) || apiKey.length !== 32\r\n                ? StringConstants.ApiKeyValidationError\r\n                : \"\";\r\n            }}\r\n          />\r\n          <p>\r\n            Don\"t have API key?{\" \"}\r\n            <a href={StringConstants.ApiKeyHelpLink} target=\"_blank\">\r\n              Click here to know how to generate.\r\n            </a>\r\n          </p>\r\n          <div>\r\n            <PrimaryButton\r\n              className=\"button submitButton\"\r\n              text=\"Start using plugin\"\r\n              onClick={onSubmitApiKey}\r\n              disabled={!ApiKeyRegex.test(apiKey) || apiKey.length !== 32}\r\n            />\r\n          </div>\r\n        </div>\r\n      </div>\r\n    </div>\r\n  );\r\n};\r\n","import React from \"react\";\r\nimport { Icon } from \"@fluentui/react/lib/Icon\";\r\nimport { TooltipHost, ITooltipProps } from \"@fluentui/react\";\r\nimport { useId } from \"@uifabric/react-hooks/lib/useId\";\r\n\r\nexport interface ICardProps {\r\n  title: string;\r\n  tooltip: string;\r\n  leadingIconName: string;\r\n  className?: string;\r\n}\r\n\r\nexport const Card: React.FunctionComponent<ICardProps> = (props) => {\r\n  const tooltipId = useId(props.title);\r\n\r\n  const tooltipProps: ITooltipProps = {\r\n    onRenderContent: () => <span>{props.tooltip}</span>,\r\n  };\r\n\r\n  return (\r\n    <div className={\"bw-Card \" + props.className || \"\"}>\r\n      <div className=\"cardHeader\">\r\n        <span className=\"cardTitle\">\r\n          <Icon iconName={props.leadingIconName} className=\"cardTitleIcon\" />\r\n          <span>{props.title}</span>\r\n\r\n          <TooltipHost\r\n            closeDelay={500}\r\n            directionalHint={1}\r\n            id={tooltipId}\r\n            tooltipProps={tooltipProps}\r\n          >\r\n            <Icon\r\n              aria-describedby={tooltipId}\r\n              iconName=\"Info\"\r\n              className=\"info\"\r\n            />\r\n          </TooltipHost>\r\n        </span>\r\n      </div>\r\n      <div className=\"cardContent\">\r\n        {props.children}\r\n      </div>\r\n    </div>\r\n  );\r\n};\r\n","import \"../scss/Dashboard.scss\";\r\n\r\nimport * as React from \"react\";\r\nimport { useState, useEffect } from \"react\";\r\nimport { DefaultButton, PrimaryButton } from \"@fluentui/react/lib/Button\";\r\nimport { Icon } from \"@fluentui/react/lib/Icon\";\r\nimport {\r\n  GetApiSettings,\r\n  GetStats,\r\n  GetAllSubmissions,\r\n  RetryFailedSubmissions,\r\n  SubmitUrl,\r\n  UpdateAutoSubmissionsEnabled,\r\n  SetApiKey,\r\n  CheckApiKeyValidity,\r\n} from \"./withDashboardData\";\r\nimport { ShimmeredDetailsList } from \"@fluentui/react/lib/ShimmeredDetailsList\";\r\nimport {\r\n  IColumn,\r\n  SelectionMode,\r\n  IChoiceGroupOption,\r\n  ChoiceGroup,\r\n  TextField,\r\n} from \"@fluentui/react/lib/index\";\r\nimport { format, formatISO } from \"date-fns\";\r\nimport {\r\n  IGetStatsResponse,\r\n  IGetApiSettingsResponse,\r\n  IGetAllSubmissionsResponse,\r\n  UrlSubmission,\r\n} from \"./Interfaces\";\r\nimport { Card } from \"./Card\";\r\nimport { StringConstants, ApiKeyRegex, SubmitUrlRegex } from \"../Constants\";\r\n\r\ninterface IDashboardProps {\r\n  addBanner: (str: string) => void;\r\n}\r\n\r\nexport const Dashboard: React.FunctionComponent<IDashboardProps> = (props) => {\r\n  enum DashboardModalState {\r\n    Hidden = 0,\r\n    UpdateApiKeyModal = 1,\r\n    EditPrefAutoSubmissionModal = 2,\r\n    SubmitUrlModal = 3,\r\n  }\r\n\r\n  const [apiKeyInvalid, setApiKeyInvalid] = useState<boolean>(false);\r\n  const [apiSettings, setAPISettings] = useState<IGetApiSettingsResponse>();\r\n  const [submissionStats, setSubmissionStats] = useState<IGetStatsResponse>();\r\n  const [submissionsList, setSubmissionsList] = useState<\r\n    IGetAllSubmissionsResponse\r\n  >();\r\n\r\n  // variables to store flyout menu states\r\n  const [showApiKeyPopOverMenu, setShowApiKeyPopOverMenu] = useState<boolean>(\r\n    false\r\n  );\r\n  const [\r\n    showAutoSubmissionsPopOverMenu,\r\n    setShowAutoSubmissionsPopOverMenu,\r\n  ] = useState<boolean>();\r\n\r\n  // variable to control modal display state\r\n  const [modalState, setModalState] = useState<DashboardModalState>(\r\n    DashboardModalState.Hidden\r\n  );\r\n\r\n  // variables storing modal UI controls state\r\n  const [\r\n    selectedOptionAutoSubmissions,\r\n    setSelectedOptionAutoSubmissions,\r\n  ] = useState<string>(\"enable\");\r\n  const [textFieldValueUrlSubmit, setTextFieldValueUrlSubmit] = useState<\r\n    string\r\n  >(\"\");\r\n  const [textFieldValueApiKey, setTextFieldValueApiKey] = useState<string>(\"\");\r\n\r\n  // variables to trigger UI data refresh\r\n  const [urlSubmitted, setUrlSubmitted] = useState<number>(0);\r\n  const [apiSettingsUpdated, setApiSettingsUpdated] = useState<number>(0);\r\n  const [apiKeyUpdated, setApiKeyUpdated] = useState<number>(0);\r\n\r\n  // Check if API key is valid\r\n  useEffect(() => {\r\n    Promise.resolve(CheckApiKeyValidity()).then((response) => {\r\n      if (response && response.data) {\r\n        if (response.data.error_type.length !== 0) {\r\n          props.addBanner(\r\n            \"API Key Validation Error: Please check if site is verified or API key is valid to enable Automatic & Manual URL submission.\"\r\n          );\r\n          setApiKeyInvalid(true);\r\n        }\r\n      }\r\n    });\r\n  }, []);\r\n\r\n  // Get API settings\r\n  useEffect(() => {\r\n    Promise.resolve(GetApiSettings()).then((response) => {\r\n      if (response && response.data && response.data.error_type.length === 0) {\r\n        setAPISettings(response.data);\r\n        setSelectedOptionAutoSubmissions(\r\n          response.data.AutoSubmissionEnabled ? \"enable\" : \"disable\"\r\n        );\r\n      }\r\n    });\r\n  }, [apiKeyUpdated, apiSettingsUpdated]);\r\n\r\n  // Get submissions statistics\r\n  useEffect(() => {\r\n    Promise.resolve(GetStats()).then((response) => {\r\n      if (response && response.data && response.data.error_type.length === 0) {\r\n        setSubmissionStats(response.data);\r\n      }\r\n    });\r\n  }, [apiKeyUpdated, urlSubmitted]);\r\n\r\n  // Get submissions list\r\n  useEffect(() => {\r\n    Promise.resolve(GetAllSubmissions()).then((response) => {\r\n      if (response && response.data && response.data.error_type.length === 0) {\r\n        response.data.Submissions.sort((a, b) =>\r\n          a.submission_date > b.submission_date ? -1 : 1\r\n        );\r\n        setSubmissionsList(response.data);\r\n      }\r\n    });\r\n  }, [apiKeyUpdated, urlSubmitted]);\r\n\r\n  // constants\r\n  const autoSubmissionOptions: IChoiceGroupOption[] = [\r\n    { key: \"enable\", text: \"Enable (recommended)\" },\r\n    { key: \"disable\", text: \"Disable\" },\r\n  ];\r\n  const urlSubmissionTableColumns: IColumn[] = [\r\n    {\r\n      key: \"url\",\r\n      name: \"URL\",\r\n      fieldName: \"url\",\r\n      onRender: (item: UrlSubmission): JSX.Element => {\r\n        return (\r\n          <a href={item.url} target=\"_blank\">\r\n            {decodeURI(item.url)}\r\n          </a>\r\n        );\r\n      },\r\n      minWidth: 250,\r\n    },\r\n    {\r\n      key: \"submittedOn\",\r\n      name: \"Submitted On\",\r\n      fieldName: \"submission_date\",\r\n      onRender: (item: UrlSubmission): string => {\r\n        let time: Date = new Date(0);\r\n        time.setUTCSeconds(item.submission_date);\r\n        let dateString: string =\r\n          time.getFullYear === new Date().getFullYear\r\n            ? format(time, \"d MMM 'at' HH':'mm\", {})\r\n            : format(time, \"d MMM yyyy'at' HH':'mm\", {});\r\n        return dateString;\r\n      },\r\n      minWidth: 150,\r\n    },\r\n    {\r\n      key: \"status\",\r\n      name: \"Status\",\r\n      fieldName: \"error\",\r\n      onRender: (item: UrlSubmission): string => {\r\n        return item.error === \"Success\" ? item.error : `Failed - ${item.error}`;\r\n      },\r\n      minWidth: 200,\r\n    },\r\n    {\r\n      key: \"resubmit\",\r\n      name: \"\",\r\n      onRender: (item: UrlSubmission) => {\r\n        return (\r\n          <Icon\r\n            iconName=\"Sync\"\r\n            data-submission={JSON.stringify(item)}\r\n            className=\"bw-Icon retryIcon\"\r\n            onClick={resubmitOnClick}\r\n          />\r\n        );\r\n      },\r\n      minWidth: 40,\r\n      maxWidth: 70,\r\n      className: \"retryColumn\",\r\n    },\r\n  ];\r\n\r\n  // Function handler for URL submission retries\r\n  const resubmitOnClick = (\r\n    event: React.MouseEvent<HTMLElement, MouseEvent>\r\n  ) => {\r\n    const submissionItemString: string =\r\n      (event.target as HTMLInputElement).dataset.submission ?? \"\";\r\n    const submissionItem: UrlSubmission = JSON.parse(submissionItemString);\r\n    Promise.resolve(RetryFailedSubmissions([submissionItem])).then(\r\n      (response) => {\r\n        if (response && response.data) {\r\n          setUrlSubmitted(urlSubmitted + 1);\r\n          if (\r\n            !response.data.hasError &&\r\n            response.data.error_type.length === 0 &&\r\n            response.data.SubmissionErrors.length >= 1 &&\r\n            response.data.SubmissionErrors[0].isSubmitted\r\n          ) {\r\n            // add new success banner\r\n            props.addBanner(\"Success : URL submitted successfully.\");\r\n          } else {\r\n            // set failed banner\r\n            props.addBanner(\r\n              `Error : Submission failed for URL - ${submissionItem.url}`\r\n            );\r\n          }\r\n        }\r\n      }\r\n    );\r\n  };\r\n\r\n  const onClickUpdateApiKey = (\r\n    event: React.MouseEvent<HTMLElement, MouseEvent>\r\n  ) => {\r\n    setModalState(DashboardModalState.Hidden);\r\n    Promise.resolve(SetApiKey(textFieldValueApiKey)).then((response) => {\r\n      if (response && response.data) {\r\n        setApiKeyUpdated(apiKeyUpdated + 1);\r\n        if (response.data.error_type.length === 0) {\r\n          props.addBanner(\"Success : API key is updated successfully.\");\r\n        } else {\r\n          props.addBanner(\"Error : Unable to update API key.\");\r\n        }\r\n      }\r\n    });\r\n  };\r\n\r\n  const onClickUpdateAutoSubmissions = (\r\n    event: React.MouseEvent<HTMLElement, MouseEvent>\r\n  ) => {\r\n    setModalState(DashboardModalState.Hidden);\r\n    Promise.resolve(\r\n      UpdateAutoSubmissionsEnabled(selectedOptionAutoSubmissions === \"enable\")\r\n    ).then((response) => {\r\n      if (response && response.data) {\r\n        setApiSettingsUpdated(apiSettingsUpdated + 1);\r\n        if (response.data.error_type.length === 0) {\r\n          props.addBanner(\r\n            \"Success : Automatic URL submission preferences updated.\"\r\n          );\r\n        } else {\r\n          props.addBanner(\r\n            \"Error : Automatic URL submission preferences not updated.\"\r\n          );\r\n        }\r\n      }\r\n    });\r\n  };\r\n\r\n  const onClickModalSubmitUrl = (\r\n    event: React.MouseEvent<HTMLElement, MouseEvent>\r\n  ) => {\r\n    // hide modal and submit Url\r\n    setModalState(DashboardModalState.Hidden);\r\n    Promise.resolve(SubmitUrl(textFieldValueUrlSubmit)).then((response) => {\r\n      if (response && response.data) {\r\n        setUrlSubmitted(urlSubmitted + 1);\r\n        if (response.data.error.length === 0) {\r\n          // add new success banner\r\n          props.addBanner(\"Success : URL submitted successfully.\");\r\n        } else {\r\n          // set failed banner\r\n          props.addBanner(\r\n            `Error : Submission failed for URL - ${textFieldValueUrlSubmit}`\r\n          );\r\n        }\r\n      }\r\n    });\r\n  };\r\n\r\n  const downloadUrls = () => {\r\n    let data = submissionsList?.Submissions?.map((item) => {\r\n      let timestamp: Date = new Date(0);\r\n      timestamp.setUTCSeconds(item.submission_date);\r\n      return {\r\n        url: item.url,\r\n        timestamp: formatISO(timestamp),\r\n        submitted: item.error === \"Success\",\r\n        status: item.error,\r\n      };\r\n    });\r\n    const json = JSON.stringify(data);\r\n    const blob = new Blob([json], { type: \"application/json\" });\r\n    const link = document.createElement(\"a\");\r\n    link.href = URL.createObjectURL(blob);\r\n    link.download = \"submissionslist.json\";\r\n    link.click();\r\n  };\r\n\r\n  return (\r\n    <>\r\n      <div\r\n        className={\r\n          \"bw-DashboardContent\" +\r\n          (modalState !== DashboardModalState.Hidden ? \" darken\" : \"\")\r\n        }\r\n      >\r\n        <div className=\"bw-CardRow\">\r\n          <div className=\"bw-CardColumn bw-CardColumn-2 bw-ApiKeyCard\">\r\n            <Card\r\n              title=\"API Key\"\r\n              tooltip=\"API Key is a unique identifier that is used to authenticate API requests.\"\r\n              leadingIconName=\"Permissions\"\r\n              className=\"bw-Card-WithPopOver\"\r\n            >\r\n              <p className=\"cardDescription\">\r\n                ********************************\r\n              </p>\r\n            </Card>\r\n            <div\r\n              className=\"bw-PopOverMenu\"\r\n              onMouseEnter={() => {\r\n                setShowApiKeyPopOverMenu(true);\r\n              }}\r\n              onMouseLeave={() => {\r\n                setShowApiKeyPopOverMenu(false);\r\n              }}\r\n            >\r\n              <Icon iconName=\"MoreVertical\" className=\"moreIcon\" />\r\n              <div className=\"popOverContainer\">\r\n                <ul\r\n                  className={\r\n                    \"popOverPanel\" +\r\n                    (showApiKeyPopOverMenu ? \" openPopOverMenu\" : \"\")\r\n                  }\r\n                >\r\n                  <li\r\n                    onClick={() => {\r\n                      // reset UI controls and display modal\r\n                      setTextFieldValueApiKey(\"\");\r\n                      setModalState(DashboardModalState.UpdateApiKeyModal);\r\n                    }}\r\n                  >\r\n                    Update key\r\n                  </li>\r\n                </ul>\r\n              </div>\r\n            </div>\r\n          </div>\r\n\r\n          <div className=\"bw-CardColumn bw-CardColumn-2\">\r\n            <Card\r\n              title=\"Automate URL submission\"\r\n              className={\r\n                \"bw-Card-WithPopOver \" + (apiKeyInvalid ? \"bw-Disabled\" : \"\")\r\n              }\r\n              tooltip=\"This feature allows to configure automation to submit new, updated & deleted URLs to Bing and stay updated.\"\r\n              leadingIconName=\"Rocket\"\r\n            >\r\n              <p className=\"cardDescription\">\r\n                {apiSettings\r\n                  ? apiSettings.AutoSubmissionEnabled\r\n                    ? \"Enabled\"\r\n                    : \"Disabled\"\r\n                  : \"-\"}\r\n              </p>\r\n            </Card>\r\n            <div\r\n              className={\r\n                \"bw-PopOverMenu \" + (apiKeyInvalid ? \"bw-Disabled\" : \"\")\r\n              }\r\n              onMouseEnter={() => {\r\n                // don't show popover menu if API key is invalid\r\n                !apiKeyInvalid && setShowAutoSubmissionsPopOverMenu(true);\r\n              }}\r\n              onMouseLeave={() => {\r\n                setShowAutoSubmissionsPopOverMenu(false);\r\n              }}\r\n            >\r\n              <Icon iconName=\"MoreVertical\" className=\"moreIcon\" />\r\n              <div className=\"popOverContainer\">\r\n                <ul\r\n                  className={\r\n                    \"popOverPanel\" +\r\n                    (showAutoSubmissionsPopOverMenu ? \" openPopOverMenu\" : \"\")\r\n                  }\r\n                >\r\n                  <li\r\n                    onClick={() => {\r\n                      // reset UI controls settings and display modal\r\n                      setSelectedOptionAutoSubmissions(\r\n                        apiSettings?.AutoSubmissionEnabled\r\n                          ? \"enable\"\r\n                          : \"disable\"\r\n                      );\r\n                      setModalState(\r\n                        DashboardModalState.EditPrefAutoSubmissionModal\r\n                      );\r\n                    }}\r\n                  >\r\n                    Edit preference\r\n                  </li>\r\n                </ul>\r\n              </div>\r\n            </div>\r\n          </div>\r\n        </div>\r\n\r\n        <div className=\"bw-CardRow\">\r\n          <div className=\"bw-CardColumn bw-CardColumn-1 bw-ManualURLSubmissionCard\">\r\n            <Card\r\n              title=\"Manual URL submission\"\r\n              tooltip=\"This feature allows you to submit a URL directly into the Bing index.\"\r\n              leadingIconName=\"Send\"\r\n              className={apiKeyInvalid ? \"bw-Disabled\" : \"\"}\r\n            >\r\n              <p className=\"cardDescription\">\r\n                This feature allows you to submit a URL directly into the Bing\r\n                index.\r\n              </p>\r\n              <DefaultButton\r\n                disabled={apiKeyInvalid}\r\n                onClick={() => {\r\n                  // reset UI controls and display modal\r\n                  setTextFieldValueUrlSubmit(\"\");\r\n                  setModalState(DashboardModalState.SubmitUrlModal);\r\n                }}\r\n                className=\"buttonSubmitUrl\"\r\n                text=\"Submit URL\"\r\n              />\r\n            </Card>\r\n          </div>\r\n        </div>\r\n\r\n        <h2 className=\"sectionTitle\">Overview</h2>\r\n        <div className=\"bw-CardRow\">\r\n          <div className=\"bw-OverviewSection\">\r\n            <div className=\"infoCards\">\r\n              <h4>Quota left for the day</h4>\r\n              <h2>\r\n                {submissionStats && submissionStats.Quota !== null\r\n                  ? submissionStats.Quota\r\n                  : \"-\"}\r\n              </h2>\r\n              <p>(Resets at 00:00 GMT)</p>\r\n            </div>\r\n            <div className=\"infoCards\">\r\n              <h4>Successful submissions</h4>\r\n              <h2>\r\n                {submissionStats &&\r\n                submissionStats.PassedSubmissionCount !== null\r\n                  ? submissionStats.PassedSubmissionCount\r\n                  : \"-\"}\r\n              </h2>\r\n              <p>In last 48 hours</p>\r\n            </div>\r\n            <div className=\"infoCards\">\r\n              <h4>Failed submissions</h4>\r\n              <h2>\r\n                {submissionStats &&\r\n                submissionStats.FailedSubmissionCount !== null\r\n                  ? submissionStats.FailedSubmissionCount\r\n                  : \"-\"}\r\n              </h2>\r\n              <p>In last 48 hours</p>\r\n            </div>\r\n          </div>\r\n        </div>\r\n\r\n        <div className=\"sectionTitleContainer\">\r\n          <h2 className=\"sectionTitle\">URLs submitted</h2>\r\n          <DefaultButton\r\n            disabled={\r\n              submissionsList?.Submissions === null ||\r\n              submissionsList?.Submissions.length === 0\r\n            }\r\n            onClick={downloadUrls}\r\n            className=\"buttonUrlSubmissionsDownload\"\r\n            text=\"Download\"\r\n          />\r\n        </div>\r\n        <div className=\"bw-CardRow\">\r\n          <div className=\"bw-CardColumn bw-CardColumn-1 bw-UrlSubmissions\">\r\n            <ShimmeredDetailsList\r\n              setKey=\"items\"\r\n              items={submissionsList?.Submissions ?? []}\r\n              columns={urlSubmissionTableColumns}\r\n              selectionMode={SelectionMode.none}\r\n              enableShimmer={submissionsList === undefined}\r\n              ariaLabelForShimmer=\"Content is being fetched\"\r\n              ariaLabelForGrid=\"Item details\"\r\n              listProps={{ renderedWindowsAhead: 0, renderedWindowsBehind: 0 }}\r\n              onRenderCheckbox={(props) => {\r\n                return props?.checked ? (\r\n                  <Icon iconName=\"CheckboxComposite\" className=\"\" />\r\n                ) : (\r\n                  <Icon iconName=\"Checkbox\" className=\"\" />\r\n                );\r\n              }}\r\n            />\r\n          </div>\r\n        </div>\r\n\r\n        <div className=\"footnotes\">\r\n          <p className=\"footnotes\">\r\n            Maximum of 20 successful and 20 failed submissions in last 48hrs\r\n            will be displayed.\r\n          </p>\r\n          <p>\r\n            For more information, login to{\" \"}\r\n            <a href={StringConstants.BingWebmasterLink}>Bing Webmaster Tools</a>\r\n            .\r\n          </p>\r\n        </div>\r\n      </div>\r\n      <div\r\n        className={\r\n          \"bw-Modal\" +\r\n          (modalState !== DashboardModalState.Hidden ? \" showModal\" : \"\")\r\n        }\r\n      >\r\n        {modalState === DashboardModalState.UpdateApiKeyModal && (\r\n          <div className={\"modalContainer bw-ModalUpdateApiKey\"}>\r\n            <div className=\"modalHeader\">\r\n              <p className=\"modalTitle\">Update API Key</p>\r\n              <Icon\r\n                iconName=\"ChromeClose\"\r\n                className=\"bw-Icon modalClose\"\r\n                onClick={() => {\r\n                  setModalState(DashboardModalState.Hidden);\r\n                }}\r\n              />\r\n            </div>\r\n            <div className=\"modalContent\">\r\n              <TextField\r\n                placeholder=\"Enter 32 digit API key\"\r\n                className=\"textField\"\r\n                value={textFieldValueApiKey}\r\n                onChange={(event, val) => {\r\n                  setTextFieldValueApiKey(val || \"\");\r\n                }}\r\n                validateOnLoad={false}\r\n                onGetErrorMessage={() => {\r\n                  return !ApiKeyRegex.test(textFieldValueApiKey) ||\r\n                    textFieldValueApiKey.length !== 32\r\n                    ? StringConstants.ApiKeyValidationError\r\n                    : \"\";\r\n                }}\r\n              />\r\n              <p>\r\n                Don’t have API key?{\" \"}\r\n                <a href={StringConstants.ApiKeyHelpLink}>\r\n                  Click here to know how to generate.\r\n                </a>\r\n              </p>\r\n            </div>\r\n            <div className=\"modalFooter\">\r\n              <PrimaryButton\r\n                className=\"button primaryButton\"\r\n                text=\"Update\"\r\n                onClick={onClickUpdateApiKey}\r\n                disabled={\r\n                  !ApiKeyRegex.test(textFieldValueApiKey) ||\r\n                  textFieldValueApiKey.length !== 32\r\n                }\r\n              />\r\n              <DefaultButton\r\n                className=\"button secondaryButton\"\r\n                text=\"Cancel\"\r\n                onClick={() => {\r\n                  setModalState(DashboardModalState.Hidden);\r\n                }}\r\n              />\r\n            </div>\r\n          </div>\r\n        )}\r\n        {modalState === DashboardModalState.EditPrefAutoSubmissionModal && (\r\n          <div className=\"modalContainer bw-ModalEditPreferenceAutoSubmissions\">\r\n            <div className=\"modalHeader\">\r\n              <p className=\"modalTitle\">\r\n                Edit preference for Automate URL Submission\r\n              </p>\r\n              <Icon\r\n                iconName=\"ChromeClose\"\r\n                className=\"bw-Icon modalClose\"\r\n                onClick={() => {\r\n                  setModalState(DashboardModalState.Hidden);\r\n                }}\r\n              />\r\n            </div>\r\n            <div className=\"modalContent\">\r\n              <p className=\"modalDescription\">\r\n                We recommend you to enable automation to submit new, updated &\r\n                deleted URLs to Bing and stay updated.\r\n              </p>\r\n              <ChoiceGroup\r\n                selectedKey={selectedOptionAutoSubmissions}\r\n                options={autoSubmissionOptions}\r\n                onChange={(event, option) => {\r\n                  if (option !== undefined) {\r\n                    setSelectedOptionAutoSubmissions(option.key);\r\n                  }\r\n                }}\r\n              />\r\n            </div>\r\n            <div className=\"modalFooter\">\r\n              <PrimaryButton\r\n                className=\"button primaryButton\"\r\n                text=\"Save\"\r\n                onClick={onClickUpdateAutoSubmissions}\r\n                disabled={\r\n                  (apiSettings?.AutoSubmissionEnabled\r\n                    ? \"enable\"\r\n                    : \"disable\") === selectedOptionAutoSubmissions\r\n                }\r\n              />\r\n              <DefaultButton\r\n                className=\"button secondaryButton\"\r\n                text=\"Cancel\"\r\n                onClick={() => {\r\n                  setModalState(DashboardModalState.Hidden);\r\n                }}\r\n              />\r\n            </div>\r\n          </div>\r\n        )}\r\n\r\n        {modalState === DashboardModalState.SubmitUrlModal && (\r\n          <div className=\"modalContainer bw-ModalUrlSubmit\">\r\n            <div className=\"modalHeader\">\r\n              <p className=\"modalTitle\">Manual URL submission</p>\r\n              <Icon\r\n                iconName=\"ChromeClose\"\r\n                className=\"bw-Icon modalClose\"\r\n                onClick={() => {\r\n                  setModalState(DashboardModalState.Hidden);\r\n                }}\r\n              />\r\n            </div>\r\n            <div className=\"modalContent\">\r\n              <TextField\r\n                placeholder=\"Enter URL to submit\"\r\n                className=\"textField\"\r\n                value={textFieldValueUrlSubmit}\r\n                validateOnLoad={false}\r\n                onGetErrorMessage={() => {\r\n                  return !SubmitUrlRegex.test(textFieldValueUrlSubmit)\r\n                    ? StringConstants.UrlSubmitErrorMessage\r\n                    : \"\";\r\n                }}\r\n                onChange={(event, val) => {\r\n                  setTextFieldValueUrlSubmit(val?.trim() || \"\");\r\n                }}\r\n              />\r\n            </div>\r\n            <div className=\"modalFooter\">\r\n              <PrimaryButton\r\n                className=\"button primaryButton\"\r\n                text=\"Submit URL\"\r\n                disabled={!SubmitUrlRegex.test(textFieldValueUrlSubmit)}\r\n                onClick={onClickModalSubmitUrl}\r\n              />\r\n              <DefaultButton\r\n                className=\"button secondaryButton\"\r\n                text=\"Cancel\"\r\n                onClick={() => {\r\n                  setModalState(DashboardModalState.Hidden);\r\n                }}\r\n              />\r\n            </div>\r\n          </div>\r\n        )}\r\n      </div>\r\n    </>\r\n  );\r\n};\r\n","import \"../scss/_common.scss\";\r\nimport \"../scss/responsiveLayout.scss\";\r\nimport \"../scss/App.scss\";\r\n\r\nimport * as React from \"react\";\r\nimport { useState, useEffect } from \"react\";\r\nimport { GetApiKey } from \"./withDashboardData\";\r\n\r\nimport { Header } from \"./Header\";\r\nimport { StartPage } from \"./StartPage\";\r\nimport { Dashboard } from \"./Dashboard\";\r\nimport { Icon } from \"@fluentui/react/lib/Icon\";\r\n\r\nexport const App: React.FunctionComponent = () => {\r\n  const [hasAPIKey, setHasAPIKey] = useState(false);\r\n\r\n  // variable to store banners\r\n  const [bannerList, setBannerList] = useState<string[]>([]);\r\n\r\n  useEffect(() => {\r\n    const data = Promise.resolve(GetApiKey());\r\n    data.then((response) => {\r\n      if (response && response.data) {\r\n        setHasAPIKey(response.data.hasAPIKey);\r\n      }\r\n    });\r\n  }, []);\r\n\r\n  // Function to add new banner notification\r\n  const addBanner = (notification: string) =>\r\n    setBannerList([notification].concat(bannerList.slice()));\r\n\r\n  // remove banner when close button is clicked\r\n  const closeBannerOnClick = (\r\n    event: React.MouseEvent<HTMLElement, MouseEvent>\r\n  ) => {\r\n    let bannerIndexString: string =\r\n      (event.target as HTMLElement).dataset.index ?? \"0\";\r\n    let temp: string[] = bannerList.slice();\r\n    temp.splice(parseInt(bannerIndexString), 1);\r\n    setBannerList(temp);\r\n  };\r\n\r\n  return (\r\n    <div className=\"bw-App\">\r\n      <Header />\r\n      <div className=\"bw-MainContainer\">\r\n        {bannerList.map((bannerItem, index) => {\r\n          return (\r\n            <div\r\n              className={\r\n                \"bw-Banner\" +\r\n                (bannerItem.length <= 0 ? \" bw-BannerHidden\" : \"\") +\r\n                (bannerItem.indexOf(\"Success\") > -1\r\n                  ? \" bw-BannerSuccess\"\r\n                  : \" bw-BannerFailure\")\r\n              }\r\n            >\r\n              <span>{bannerItem}</span>\r\n              <Icon\r\n                iconName=\"ChromeClose\"\r\n                className=\"closeIcon\"\r\n                data-index={index}\r\n                onClick={closeBannerOnClick}\r\n              />\r\n            </div>\r\n          );\r\n        })}\r\n        {!hasAPIKey && (\r\n          <StartPage\r\n            addBanner={addBanner}\r\n            setAPIKeyAdded={() => {\r\n              setHasAPIKey(true);\r\n              setBannerList([]);\r\n            }}\r\n          />\r\n        )}\r\n        {hasAPIKey && <Dashboard addBanner={addBanner} />}\r\n      </div>\r\n    </div>\r\n  );\r\n};\r\n","// This optional code is used to register a service worker.\r\n// register() is not called by default.\r\n\r\n// This lets the app load faster on subsequent visits in production, and gives\r\n// it offline capabilities. However, it also means that developers (and users)\r\n// will only see deployed updates on subsequent visits to a page, after all the\r\n// existing tabs open on the page have been closed, since previously cached\r\n// resources are updated in the background.\r\n\r\n// To learn more about the benefits of this model and instructions on how to\r\n// opt-in, read https://bit.ly/CRA-PWA\r\n\r\nconst isLocalhost = Boolean(\r\n  window.location.hostname === 'localhost' ||\r\n    // [::1] is the IPv6 localhost address.\r\n    window.location.hostname === '[::1]' ||\r\n    // 127.0.0.0/8 are considered localhost for IPv4.\r\n    window.location.hostname.match(\r\n      /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\r\n    )\r\n);\r\n\r\nexport function register(config) {\r\n  if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\r\n    // The URL constructor is available in all browsers that support SW.\r\n    const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\r\n    if (publicUrl.origin !== window.location.origin) {\r\n      // Our service worker won't work if PUBLIC_URL is on a different origin\r\n      // from what our page is served on. This might happen if a CDN is used to\r\n      // serve assets; see https://github.com/facebook/create-react-app/issues/2374\r\n      return;\r\n    }\r\n\r\n    window.addEventListener('load', () => {\r\n      const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\r\n\r\n      if (isLocalhost) {\r\n        // This is running on localhost. Let's check if a service worker still exists or not.\r\n        checkValidServiceWorker(swUrl, config);\r\n\r\n        // Add some additional logging to localhost, pointing developers to the\r\n        // service worker/PWA documentation.\r\n        navigator.serviceWorker.ready.then(() => {\r\n          console.log(\r\n            'This web app is being served cache-first by a service ' +\r\n              'worker. To learn more, visit https://bit.ly/CRA-PWA'\r\n          );\r\n        });\r\n      } else {\r\n        // Is not localhost. Just register service worker\r\n        registerValidSW(swUrl, config);\r\n      }\r\n    });\r\n  }\r\n}\r\n\r\nfunction registerValidSW(swUrl, config) {\r\n  navigator.serviceWorker\r\n    .register(swUrl)\r\n    .then(registration => {\r\n      registration.onupdatefound = () => {\r\n        const installingWorker = registration.installing;\r\n        if (installingWorker == null) {\r\n          return;\r\n        }\r\n        installingWorker.onstatechange = () => {\r\n          if (installingWorker.state === 'installed') {\r\n            if (navigator.serviceWorker.controller) {\r\n              // At this point, the updated precached content has been fetched,\r\n              // but the previous service worker will still serve the older\r\n              // content until all client tabs are closed.\r\n              console.log(\r\n                'New content is available and will be used when all ' +\r\n                  'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\r\n              );\r\n\r\n              // Execute callback\r\n              if (config && config.onUpdate) {\r\n                config.onUpdate(registration);\r\n              }\r\n            } else {\r\n              // At this point, everything has been precached.\r\n              // It's the perfect time to display a\r\n              // \"Content is cached for offline use.\" message.\r\n              console.log('Content is cached for offline use.');\r\n\r\n              // Execute callback\r\n              if (config && config.onSuccess) {\r\n                config.onSuccess(registration);\r\n              }\r\n            }\r\n          }\r\n        };\r\n      };\r\n    })\r\n    .catch(error => {\r\n      console.error('Error during service worker registration:', error);\r\n    });\r\n}\r\n\r\nfunction checkValidServiceWorker(swUrl, config) {\r\n  // Check if the service worker can be found. If it can't reload the page.\r\n  fetch(swUrl, {\r\n    headers: { 'Service-Worker': 'script' },\r\n  })\r\n    .then(response => {\r\n      // Ensure service worker exists, and that we really are getting a JS file.\r\n      const contentType = response.headers.get('content-type');\r\n      if (\r\n        response.status === 404 ||\r\n        (contentType != null && contentType.indexOf('javascript') === -1)\r\n      ) {\r\n        // No service worker found. Probably a different app. Reload the page.\r\n        navigator.serviceWorker.ready.then(registration => {\r\n          registration.unregister().then(() => {\r\n            window.location.reload();\r\n          });\r\n        });\r\n      } else {\r\n        // Service worker found. Proceed as normal.\r\n        registerValidSW(swUrl, config);\r\n      }\r\n    })\r\n    .catch(() => {\r\n      console.log(\r\n        'No internet connection found. App is running in offline mode.'\r\n      );\r\n    });\r\n}\r\n\r\nexport function unregister() {\r\n  if ('serviceWorker' in navigator) {\r\n    navigator.serviceWorker.ready\r\n      .then(registration => {\r\n        registration.unregister();\r\n      })\r\n      .catch(error => {\r\n        console.error(error.message);\r\n      });\r\n  }\r\n}\r\n","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport './index.css';\r\nimport { App } from './components/App';\r\nimport * as serviceWorker from './serviceWorker';\r\nimport { initializeIcons } from \"@fluentui/react/lib/Icons\";\r\n\r\ninitializeIcons();\r\n\r\nvar rootElement = document.getElementById(\"bwAppRoot\");\r\n\r\nif (rootElement !== null) {\r\n  ReactDOM.render(\r\n    <React.StrictMode>\r\n      <App />\r\n    </React.StrictMode>,\r\n    rootElement\r\n  );\r\n}\r\n\r\n// If you want your app to work offline and load faster, you can change\r\n// unregister() to register() below. Note this comes with some pitfalls.\r\n// Learn more about service workers: https://bit.ly/CRA-PWA\r\nserviceWorker.unregister();\r\n"],"sourceRoot":""}