From 611769ac853a8be17fd126f89006a782a8572082 Mon Sep 17 00:00:00 2001 From: Ogefest Date: Sat, 23 Oct 2021 17:48:20 +0200 Subject: [PATCH] front updated --- pom.xml | 2 +- src/main/resources/META-INF/resources/asset-manifest.json | 6 +++--- src/main/resources/META-INF/resources/index.html | 2 +- .../META-INF/resources/static/js/main.61eb00ba.chunk.js | 2 -- .../META-INF/resources/static/js/main.61eb00ba.chunk.js.map | 1 - 5 files changed, 5 insertions(+), 8 deletions(-) delete mode 100644 src/main/resources/META-INF/resources/static/js/main.61eb00ba.chunk.js delete mode 100644 src/main/resources/META-INF/resources/static/js/main.61eb00ba.chunk.js.map diff --git a/pom.xml b/pom.xml index f0b674d..864315f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.ogefest filehunter - 0.3.2-SNAPSHOT + 0.4-SNAPSHOT 3.8.1 true diff --git a/src/main/resources/META-INF/resources/asset-manifest.json b/src/main/resources/META-INF/resources/asset-manifest.json index 6f86c85..361775f 100644 --- a/src/main/resources/META-INF/resources/asset-manifest.json +++ b/src/main/resources/META-INF/resources/asset-manifest.json @@ -1,8 +1,8 @@ { "files": { "main.css": "/static/css/main.ee01ecee.chunk.css", - "main.js": "/static/js/main.61eb00ba.chunk.js", - "main.js.map": "/static/js/main.61eb00ba.chunk.js.map", + "main.js": "/static/js/main.0998ecba.chunk.js", + "main.js.map": "/static/js/main.0998ecba.chunk.js.map", "runtime-main.js": "/static/js/runtime-main.80fb9e64.js", "runtime-main.js.map": "/static/js/runtime-main.80fb9e64.js.map", "static/css/2.ee8d6a27.chunk.css": "/static/css/2.ee8d6a27.chunk.css", @@ -21,6 +21,6 @@ "static/css/2.ee8d6a27.chunk.css", "static/js/2.6733b7d9.chunk.js", "static/css/main.ee01ecee.chunk.css", - "static/js/main.61eb00ba.chunk.js" + "static/js/main.0998ecba.chunk.js" ] } \ No newline at end of file diff --git a/src/main/resources/META-INF/resources/index.html b/src/main/resources/META-INF/resources/index.html index aa0e839..8beb864 100644 --- a/src/main/resources/META-INF/resources/index.html +++ b/src/main/resources/META-INF/resources/index.html @@ -1 +1 @@ -Filehunter
\ No newline at end of file +Filehunter
\ No newline at end of file diff --git a/src/main/resources/META-INF/resources/static/js/main.61eb00ba.chunk.js b/src/main/resources/META-INF/resources/static/js/main.61eb00ba.chunk.js deleted file mode 100644 index 501a45d..0000000 --- a/src/main/resources/META-INF/resources/static/js/main.61eb00ba.chunk.js +++ /dev/null @@ -1,2 +0,0 @@ -(this["webpackJsonpfilehunter-front"]=this["webpackJsonpfilehunter-front"]||[]).push([[0],{24:function(e,t,s){},25:function(e,t,s){},38:function(e,t,s){"use strict";s.r(t);var n=s(1),i=s.n(n),a=s(16),c=s.n(a),l=(s(24),s(25),s(26),s(19)),r=s(6),o=s(2),d=s(3),h=s(5),b=s(4),j=s(7),m=s(0),u=(i.a.Component,function(e){Object(h.a)(s,e);var t=Object(b.a)(s);function s(){return Object(o.a)(this,s),t.apply(this,arguments)}return Object(d.a)(s,[{key:"render",value:function(){return Object(m.jsx)("nav",{class:"navbar navbar-expand-lg navbar-light",children:Object(m.jsxs)("div",{class:"container-fluid",children:[Object(m.jsx)("span",{class:"badge bg-primary",children:"FH"})," ",Object(m.jsx)("a",{class:"navbar-brand",href:"/",children:"Filehunter"}),Object(m.jsx)("button",{class:"navbar-toggler",type:"button","data-bs-toggle":"collapse","data-bs-target":"#navbarSupportedContent","aria-controls":"navbarSupportedContent","aria-expanded":"false","aria-label":"Toggle navigation",children:Object(m.jsx)("span",{class:"navbar-toggler-icon"})}),Object(m.jsx)("div",{class:"collapse navbar-collapse",id:"navbarSupportedContent",children:Object(m.jsxs)("ul",{class:"navbar-nav ms-auto mb-1 mb-lg-0",children:[Object(m.jsx)("li",{class:"nav-item",children:Object(m.jsxs)("a",{class:"nav-link","aria-current":"page",href:"/",children:[Object(m.jsx)("i",{class:"bi bi-search"})," Search"]})}),Object(m.jsx)("li",{class:"nav-item",children:Object(m.jsxs)("a",{href:"/gui/index",class:"nav-link menu-item nav-active",children:[Object(m.jsx)("i",{class:"bi bi-folder2-open"})," Indexes"]})}),Object(m.jsx)("li",{class:"nav-item",children:Object(m.jsxs)("a",{rel:"noreferrer",href:"".concat("","/api-doc"),target:"_blank",class:"nav-link menu-item",children:[Object(m.jsx)("i",{class:"bi bi-code-slash"})," API Doc"]})}),Object(m.jsx)("li",{class:"nav-item",children:Object(m.jsxs)("a",{rel:"noreferrer",href:"https://github.com/Ogefest/filehunter",target:"_blank",class:"nav-link menu-item",children:[Object(m.jsx)("i",{class:"bi bi-github"})," Github"]})})]})})]})})}}]),s}(i.a.Component)),x=function(e){Object(h.a)(s,e);var t=Object(b.a)(s);function s(e){var n;return Object(o.a)(this,s),(n=t.call(this,e)).getColorByName=n.getColorByName.bind(Object(j.a)(n)),n}return Object(d.a)(s,[{key:"getColorByName",value:function(e){for(var t=0,s=0;s>8*s&255).toString(16)).substr(-2)}return n}},{key:"humanFileSize",value:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:2,n=t?1e3:1024;if(Math.abs(e)=n&&a\n
\n FH Filehunter\n \n
\n \n
\n
\n \n\n )\n }\n}\n\nexport default Navbar;","import React from 'react';\nconst API_URL = process.env.REACT_APP_API_URL\n\nclass SystemTaskStatus extends React.Component {\n constructor(props) {\n super(props)\n\n this.refreshInterval = 10000\n this.refreshStatus = this.refreshStatus.bind(this)\n } \n \n componentDidMount() {\n this.refreshStatus()\n }\n\n refreshStatus() {\n fetch(`${API_URL}/system/status`)\n .then(res => res.json())\n .then((result) => {\n this.result = result;\n\n setTimeout(this.refreshStatus, this.refreshInterval)\n this.setState({});\n });\n }\n\n render() {\n\n if (this.result === undefined) {\n return(\"\")\n }\n if (this.result.currentTask !== \"\") {\n this.refreshInterval = 1000\n } else {\n this.refreshInterval = 10000\n return(\"\")\n }\n\n return(\n Task {this.result.currentTask}\n )\n }\n}\n\nexport default SystemTaskStatus","import React from 'react';\nconst API_URL = process.env.REACT_APP_API_URL\n\n\nclass SearchResultRow extends React.Component {\n\n constructor(props) {\n super(props)\n\n this.getColorByName = this.getColorByName.bind(this)\n }\n\n getColorByName(str) {\n var hash = 0;\n for (var i = 0; i < str.length; i++) {\n hash = str.charCodeAt(i) + ((hash << 5) - hash);\n }\n var colour = '#';\n for (var i = 0; i < 3; i++) {\n var value = (hash >> (i * 8)) & 0xFF;\n colour += ('00' + value.toString(16)).substr(-2);\n }\n return colour;\n } \n \n humanFileSize(bytes, si=true, dp=2) {\n const thresh = si ? 1000 : 1024;\n \n if (Math.abs(bytes) < thresh) {\n return bytes + ' B';\n }\n \n const units = si \n ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] \n : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];\n let u = -1;\n const r = 10**dp;\n \n do {\n bytes /= thresh;\n ++u;\n } while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1);\n \n \n return bytes.toFixed(dp) + ' ' + units[u];\n } \n\n render() {\n let iconclass = \"bi-file-earmark\"\n if (this.props.params.type === 'd') {\n iconclass = \"bi-folder2\"\n }\n\n let badgeColor = this.getColorByName(this.props.params.indexname)\n let fileSize = this.humanFileSize(this.props.params.size)\n\n return (\n
\n \n {/*
{this.props.params.name}
*/}\n \n
\n
\n \n \n {/* {this.props.params.indexname} */}\n \n {this.props.params.name}\n {this.props.params.indexname}\n {/* {this.props.params.indexname} */}\n {fileSize}\n
\n
\n \n
\n \n {this.props.params.path}\n
\n \n
\n )\n }\n \n}\n\nexport default SearchResultRow","import React from \"react\";\n\nclass EmptySearchResult extends React.Component {\n\n render() {\n return (\n
\n
\n
\n\n\n
\n Empty search results\n
\n\n
\n
\n
\n )\n }\n\n}\n\nexport default EmptySearchResult","import React from 'react'\nconst API_URL = process.env.REACT_APP_API_URL\n\nclass SearchAdvanced extends React.Component {\n\n constructor(props) {\n super(props)\n this.indexList = []\n this.indexName = \"\"\n this.extension = \"\"\n this.minmultiplier = 1024 * 1024\n this.maxmultiplier = 1024 * 1024\n\n this.filters = { minsize: 0, maxsize: 0 }\n\n this.state = {\n filters: {\n minsize: 0, maxsize: 0\n },\n }\n\n }\n\n componentDidMount() {\n fetch(`${API_URL}/index/list`)\n .then(res => res.json())\n .then((result) => {\n this.indexList = result;\n this.requestFinished = true\n this.setState({ filters: this.filters })\n });\n }\n\n handleAdvancedFilterChange(e) {\n\n let k = e.target.name;\n let v = e.target.value;\n\n if (v.trim().length == 0) {\n delete this.filters[k]\n } else {\n if (k === 'modified_after' || k === 'modified_before') {\n v = Date.parse(v)\n }\n\n this.filters[k] = v;\n }\n if (k === \"maxsize\" && v != '0') {\n this.filters[k] = parseInt(v) * this.maxmultiplier;\n }\n if (k === \"minsize\" && v != '0') {\n this.filters[k] = parseInt(v) * this.minmultiplier;\n }\n\n this.props.update(this.filters)\n this.setState({ filters: this.filters })\n }\n\n handleUiHelper(e) {\n\n if (e.target.name === \"maxmultiplier\") {\n this.maxmultiplier = parseInt(e.target.value)\n }\n if (e.target.name === \"minmultiplier\") {\n this.minmultiplier = parseInt(e.target.value)\n }\n\n if (e.target.name === 'maxsizerange') {\n this.filters['maxsize'] = parseInt(e.target.value) * this.maxmultiplier\n }\n if (e.target.name === 'minsizerange') {\n this.filters['minsize'] = parseInt(e.target.value) * this.minmultiplier\n }\n\n this.props.update(this.filters)\n this.setState({ filters: this.filters })\n }\n\n render() {\n return (\n
\n
\n\n
\n \n
\n
\n\n \n
\n\n
\n\n\n
\n\n
\n \n
\n
\n \n
\n\n
\n\n\n
\n\n
\n \n
\n
\n \n
\n\n
\n\n\n
\n\n
\n \n
\n
\n \n
\n\n
\n\n
\n\n
\n \n
\n
\n \n
\n\n
\n\n
\n\n
\n \n
\n
\n \n
\n
\n \n
\n\n
\n\n
\n\n
\n \n
\n
\n \n\n
\n
\n \n
\n
\n \n
\n\n
\n\n
\n\n
\n \n
\n
\n \n\n
\n
\n \n
\n
\n \n
\n\n
\n\n\n
\n\n )\n }\n}\n\nexport default SearchAdvanced","import React from 'react';\nimport SearchResultRow from './SearchResultRow.js'\nimport EmptySearchResult from './EmptySearchResult.js';\nimport SearchAdvanced from './SearchAdvanced.js';\nconst API_URL = process.env.REACT_APP_API_URL\n\n\nclass SearchForm extends React.Component {\n\n constructor(props) {\n super(props);\n this.state = {\n value: null,\n searchResultRows: []\n };\n this.sr = []\n this.lastQuery = \"\"\n this.currentQuery = \"\"\n // this.advancedFilterQuery = \"\"\n this.activeQuery = false\n this.searchTimeout = null\n this.advancedFilters = {}\n\n this.updateAdvancedFilterQuery = this.updateAdvancedFilterQuery.bind(this)\n\n }\n\n componentDidMount() {\n // this.intervalId = setInterval(this.handleSearch.bind(this), 500);\n }\n componentWillUnmount() {\n clearInterval(this.intervalId)\n }\n\n updateAdvancedFilterQuery(s) {\n this.advancedFilters = s\n\n // let asd = new URLSearchParams(s).toString();\n\n\n // if (this.currentQuery == \"\") {\n // this.advancedFilterQuery = this.advancedFilterQuery.trim().substring(3)\n // }\n\n this.handleSearch()\n }\n\n handleSearch() {\n\n let combinedQuery = this.currentQuery;\n let qs = Object.keys(this.advancedFilters)\n .map(key => `filter[${encodeURIComponent(key)}]=${encodeURIComponent(this.advancedFilters[key])}`)\n .join('&');\n\n\n if (combinedQuery === \"\" || combinedQuery === this.lastQuery) {\n return;\n }\n if (this.activeQuery === true) {\n return;\n }\n this.activeQuery = true\n\n // console.log(this.advancedFilters);\n\n // let asd = new URLSearchParams(this.advancedFilters).toString();\n\n\n\n\n fetch(`${API_URL}/search?q=${encodeURIComponent(combinedQuery)}&${qs}`)\n .then(res => res.json())\n .then((result) => {\n this.lastQuery = combinedQuery + qs;\n this.activeQuery = false;\n\n this.sr = []\n result.map((item) => (\n this.sr.push()\n ))\n if (this.sr.length === 0) {\n this.sr.push()\n }\n\n this.setState({ searchResultRows: this.sr })\n })\n }\n\n handleInputChange(e) {\n this.currentQuery = e.target.value\n if (this.searchTimeout != null) {\n clearTimeout(this.searchTimeout)\n }\n this.searchTimeout = setTimeout(this.handleSearch.bind(this), 300);\n }\n\n render() {\n return (\n
\n
\n
\n
\n \n \n \n
\n
\n
\n\n
\n\n
\n \n
\n\n
\n {this.state.searchResultRows}\n
\n\n
\n
\n )\n }\n}\n\nexport default SearchForm","import React from 'react'\nconst API_URL = process.env.REACT_APP_API_URL\n\nclass ReindexState extends React.Component {\n\n\n constructor(props) {\n super(props)\n console.log(props)\n\n this.state = { clicked: false }\n\n this.handleClick = this.handleClick.bind(this)\n }\n\n handleClick() {\n\n if (this.state.clicked === true) {\n return\n }\n\n fetch(`${API_URL}/index/reindex/${this.props.indextype}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n })\n .then(response => {\n this.setState({ clicked: true })\n })\n\n return false\n }\n\n render() {\n // console.log(this.state.clicked)\n\n return (\n \n )\n }\n\n}\n\nexport default ReindexState","import React from \"react\";\n\nclass EmptyIndexList extends React.Component {\n\n render() {\n return (\n
\n\n\n
\n
\n\n\n
\n You have no indexed directories. Click button below to add directory.\n
\n\n \n\n
\n
\n
\n )\n }\n\n}\n\nexport default EmptyIndexList","import React from 'react';\nimport ReindexState from './ReindexState';\nimport EmptyIndexList from './EmptyIndexList';\nconst API_URL = process.env.REACT_APP_API_URL\n\nclass IndexInfo extends React.Component {\n\n // const history = useHistory()\n\n constructor(props) {\n super(props)\n\n this.result = []\n this.requestFinished = false\n\n this.handleRemove = this.handleRemove.bind(this)\n\n }\n\n componentDidMount() {\n this.refreshList()\n\n }\n\n refreshList() {\n fetch(`${API_URL}/index/list`)\n .then(res => res.json())\n .then((result) => {\n this.result = result;\n this.requestFinished = true\n this.setState({});\n });\n }\n\n\n handleRemove(row) {\n if (window.confirm(\"Are you sure?\")) {\n\n fetch(`${API_URL}/index/remove/${row.name}`, {\n method: 'DELETE',\n headers: { 'Content-Type': 'application/json' }, \n })\n .then(res => res.json())\n .then((result) => {\n this.result = result;\n this.setState({});\n }); \n }\n return false\n }\n\n render() {\n\n if (this.requestFinished === false) {\n return(\"\")\n }\n\n if (this.result.length === 0) {\n return (\n \n )\n }\n\n return (\n \n
\n
\n
\n

List of indexes New

\n \n \n \n \n \n \n \n \n \n \n \n {this.result.map(directoryRow => (\n \n \n \n \n \n\n \n \n ))}\n \n
NamePathsIgnoreLast indexed 
{directoryRow.name}\n {directoryRow.path.map(pathRow => (\n {pathRow}\n ))}\n \n {directoryRow.ignorePath.map(pathRow => (\n {pathRow}\n ))}\n {directoryRow.ignorePhrase.map(pathRow => (\n *{pathRow}*\n ))} \n {directoryRow.ignoreExtension.map(pathRow => (\n *.{pathRow}\n ))}\n \n {new Date(directoryRow.lastStructureIndexed).toLocaleDateString()}\n  \n {new Date(directoryRow.lastStructureIndexed).toLocaleTimeString()}\n \n \n this.handleRemove(directoryRow)} href=\"#\" class=\"btn btn-danger btn-sm me-1\">\n \n
\n
\n
\n\n
\n\n )\n }\n}\n\nexport default IndexInfo","import React from 'react';\nimport { withRouter } from \"react-router\";\nconst API_URL = process.env.REACT_APP_API_URL\n\n\nclass IndexForm extends React.Component {\n constructor(props) {\n super(props)\n\n this.state = {\n formData: {\n \"extractMetadata\": true,\n \"ignoreExtension\": [],\n \"ignorePath\": [],\n \"ignorePhrase\": [],\n \"indexMode\": \"full\",\n \"intervalUpdateMetadata\": 3600,\n \"name\": \"\",\n \"path\": []\n }\n }\n\n this.handleSubmit = this.handleSubmit.bind(this)\n this.handleFormEdit = this.handleFormEdit.bind(this)\n }\n\n componentDidMount() {\n let id = this.props.match.params.name;\n if (id !== undefined) {\n fetch(`${API_URL}/index/get/${id}`)\n .then(res => res.json())\n .then((result) => {\n this.setState({ formData: result });\n });\n }\n\n }\n\n handleSubmit(event) {\n\n event.preventDefault();\n\n fetch(`${API_URL}/index/set`, {\n method: 'POST',\n body: JSON.stringify(this.state.formData),\n headers: { 'Content-Type': 'application/json' },\n })\n .then(response => {\n console.log(response)\n window.location = \"/gui/index\"\n })\n }\n\n handleFormEdit(event) {\n\n if (event.type !== \"change\") {\n return\n }\n\n let formData = this.state.formData\n\n switch (event.target.id) {\n case \"inputName\":\n formData.name = event.target.value.replace(/[^a-z0-9\\-]+/gi, \"\")\n break\n case \"inputPath\":\n formData.path = event.target.value.split(\",\")\n break\n case \"inputPathIgnore\":\n formData.ignorePath = event.target.value.split(\",\")\n break\n case \"inputPhraseIgnore\":\n formData.ignorePhrase = event.target.value.split(\",\")\n break\n case \"inputExtIgnore\":\n formData.ignoreExtension = event.target.value.split(\",\")\n break\n case \"inputUpdateStructure\":\n formData.intervalUpdateStructure = event.target.value.replace(/[^0-9]+/gi, \"\")\n break\n case \"inputExtractMetadata\":\n formData.extractMetadata = event.target.checked\n break\n }\n\n this.setState({ formData: formData })\n }\n\n render() {\n let id = this.props.match.params.name\n let formEditing = true\n if (id === undefined) {\n formEditing = false\n }\n\n return (\n
\n
\n
\n

{formEditing ? \"Edit\" : \"Create\"} index

\n
\n
\n \n
\n \n
\n
\n {/* Input desription */}\n
\n
\n\n
\n \n
\n \n
\n
\n Full path to index, you can add here multiple paths separate them with coma
eg. (/home/user/dir1,/home/user/dir2)
\n
\n
\n\n

Filter settings

\n\n
\n \n
\n \n
\n
\n Ignore paths from indexing separated by coma
eg. (/home/user/dir1/unwanted-path,/home/user/dir2/some/unwanted)
\n
\n
\n\n
\n \n
\n \n
\n
\n Ignore file/directory paths with phrase separated by coma. You can use * to match more files/directories
eg. (.git,vendor,attr*)
\n
\n
\n\n
\n \n
\n \n
\n
\n Ignore file extensions separated by coma
eg. (jpg,mp4,tmp)
\n
\n
\n\n\n

Reindex settings

\n\n
\n \n
\n \n
\n
\n Refresh directory structure interval in seconds.\n
\n
\n\n
\n \n
\n \n
\n
\n Enable this option when Filehunter should extract metadata/content from files and make it searchable\n
\n
\n\n
\n
\n Cancel\n \n
\n
\n\n\n
\n
\n
\n
\n )\n }\n}\n\nexport default withRouter(IndexForm)","import './App.css';\nimport \"bootstrap-icons/font/bootstrap-icons.css\";\nimport { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom';\nimport Navbar from './Navbar.js';\nimport SearchForm from './Searchform.js';\nimport IndexInfo from './IndexInfo';\nimport IndexForm from './IndexForm';\n\nfunction App() {\n return (\n
\n
\n \n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n \n \n
\n
\n );\n}\n\nexport default App;\n\n","const reportWebVitals = onPerfEntry => {\n if (onPerfEntry && onPerfEntry instanceof Function) {\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n getCLS(onPerfEntry);\n getFID(onPerfEntry);\n getFCP(onPerfEntry);\n getLCP(onPerfEntry);\n getTTFB(onPerfEntry);\n });\n }\n};\n\nexport default reportWebVitals;\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport './index.css';\nimport App from './App';\nimport reportWebVitals from './reportWebVitals';\nimport 'bootstrap';\nimport 'bootstrap/dist/css/bootstrap.min.css';\n\n\nReactDOM.render(\n \n \n ,\n document.getElementById('root')\n);\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals();\n"],"sourceRoot":""} \ No newline at end of file