Compare commits
No commits in common. "af6888a7bbffc0f3e1535fee317982f93557c8b4" and "e3a4b1d5f16b29801192fd37e1403f0882286cec" have entirely different histories.
af6888a7bb
...
e3a4b1d5f1
11 changed files with 16 additions and 4846 deletions
2
changelog-app-ui/.gitignore
vendored
2
changelog-app-ui/.gitignore
vendored
|
@ -22,5 +22,3 @@ dist-ssr
|
||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
__snapshots__/
|
|
||||||
|
|
4735
changelog-app-ui/package-lock.json
generated
4735
changelog-app-ui/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -29,7 +29,6 @@
|
||||||
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
||||||
"eslint-plugin-react-refresh": "^0.4.9",
|
"eslint-plugin-react-refresh": "^0.4.9",
|
||||||
"globals": "^15.9.0",
|
"globals": "^15.9.0",
|
||||||
"jest": "^29.7.0",
|
|
||||||
"jsdom": "^25.0.0",
|
"jsdom": "^25.0.0",
|
||||||
"vite": "^5.4.1",
|
"vite": "^5.4.1",
|
||||||
"vitest": "^2.0.5"
|
"vitest": "^2.0.5"
|
||||||
|
|
|
@ -20,40 +20,29 @@ function App() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is just temp data that will get updated later
|
|
||||||
//
|
|
||||||
const fakeDate = new Date();
|
|
||||||
fakeDate.setDate(fakeDate.getDate() - 1);
|
|
||||||
const fakeDate2 = new Date();
|
|
||||||
fakeDate2.setDate(fakeDate2.getDate() - 2);
|
|
||||||
const fakeDate3 = new Date();
|
|
||||||
fakeDate3.setDate(fakeDate3.getDate() - 3);
|
|
||||||
const fakeDate4 = new Date();
|
|
||||||
fakeDate4.setDate(fakeDate4.getDate() - 4);
|
|
||||||
|
|
||||||
const tempData = [
|
const tempData = [
|
||||||
{
|
{
|
||||||
body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vitae nibh velit. Vivamus maximus elit et eleifend hendrerit. Praesent ac metus eget risus accumsan finibus. Cras tempor dignissim dolor, ut tempus tortor interdum non. Sed sit amet fringilla turpis. Sed congue feugiat orci, vel iaculis libero venenatis eu.",
|
body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vitae nibh velit. Vivamus maximus elit et eleifend hendrerit. Praesent ac metus eget risus accumsan finibus. Cras tempor dignissim dolor, ut tempus tortor interdum non. Sed sit amet fringilla turpis. Sed congue feugiat orci, vel iaculis libero venenatis eu.",
|
||||||
topics: ["#kubernetes", "#argocd"],
|
topics: ["kubernetes", "argocd"],
|
||||||
date: fakeDate,
|
date: new Date().toLocaleDateString(),
|
||||||
id: 1,
|
id: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vitae nibh velit. Vivamus maximus elit et eleifend hendrerit. Praesent ac metus eget risus accumsan finibus. Cras tempor dignissim dolor, ut tempus tortor interdum non. Sed sit amet fringilla turpis. Sed congue feugiat orci, vel iaculis libero venenatis eu.",
|
body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vitae nibh velit. Vivamus maximus elit et eleifend hendrerit. Praesent ac metus eget risus accumsan finibus. Cras tempor dignissim dolor, ut tempus tortor interdum non. Sed sit amet fringilla turpis. Sed congue feugiat orci, vel iaculis libero venenatis eu.",
|
||||||
topics: ["#react", "#python", "#javascript"],
|
topics: ["react", "python", "javascript"],
|
||||||
date: fakeDate2,
|
date: new Date().toLocaleDateString(),
|
||||||
id: 2,
|
id: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vitae nibh velit. Vivamus maximus elit et eleifend hendrerit. Praesent ac metus eget risus accumsan finibus. Cras tempor dignissim dolor, ut tempus tortor interdum non. Sed sit amet fringilla turpis. Sed congue feugiat orci, vel iaculis libero venenatis eu.",
|
body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vitae nibh velit. Vivamus maximus elit et eleifend hendrerit. Praesent ac metus eget risus accumsan finibus. Cras tempor dignissim dolor, ut tempus tortor interdum non. Sed sit amet fringilla turpis. Sed congue feugiat orci, vel iaculis libero venenatis eu.",
|
||||||
topics: ["#docker", "#proxmox"],
|
topics: ["docker", "proxmox"],
|
||||||
date: fakeDate3,
|
date: new Date().toLocaleDateString(),
|
||||||
id: 3,
|
id: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vitae nibh velit. Vivamus maximus elit et eleifend hendrerit. Praesent ac metus eget risus accumsan finibus. Cras tempor dignissim dolor, ut tempus tortor interdum non. Sed sit amet fringilla turpis. Sed congue feugiat orci, vel iaculis libero venenatis eu.",
|
body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vitae nibh velit. Vivamus maximus elit et eleifend hendrerit. Praesent ac metus eget risus accumsan finibus. Cras tempor dignissim dolor, ut tempus tortor interdum non. Sed sit amet fringilla turpis. Sed congue feugiat orci, vel iaculis libero venenatis eu.",
|
||||||
topics: ["#aws", "#github"],
|
topics: ["aws", "github"],
|
||||||
date: fakeDate4,
|
date: new Date().toLocaleDateString(),
|
||||||
id: 4,
|
id: 4,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -2,46 +2,33 @@ import PropTypes from "prop-types";
|
||||||
import styles from "./changeLogInput.module.css";
|
import styles from "./changeLogInput.module.css";
|
||||||
|
|
||||||
const ChangeLogInput = (props) => {
|
const ChangeLogInput = (props) => {
|
||||||
const handleClick = () => {
|
const handleClick = (e) => {
|
||||||
const topics = getTopics(props.logInput);
|
|
||||||
|
|
||||||
const newEntry = {
|
const newEntry = {
|
||||||
body: props.logInput,
|
body: props.logInput,
|
||||||
topics: topics,
|
topics: ["test"],
|
||||||
date: new Date(),
|
date: new Date().toLocaleDateString(),
|
||||||
id: crypto.randomUUID(),
|
id: crypto.randomUUID(),
|
||||||
};
|
};
|
||||||
|
|
||||||
props.setFeed([newEntry, ...props.feed]);
|
props.setFeed([newEntry, ...props.feed]);
|
||||||
props.setLogInput("");
|
props.setLogInput("");
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<textarea
|
<textarea
|
||||||
rows="1"
|
rows="1"
|
||||||
placeholder="What did you change...?!"
|
placeholder="What did you change..."
|
||||||
className={styles.input}
|
className={styles.input}
|
||||||
onChange={(e) => props.setLogInput(e.target.value)}
|
onChange={(e) => props.setLogInput(e.target.value)}
|
||||||
value={props.logInput}
|
value={props.logInput}
|
||||||
/>
|
/>
|
||||||
<button onClick={handleClick} className={styles.btn}>
|
<button onClick={handleClick} className={styles.btn}>
|
||||||
Log it!
|
Submit
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTopics = (body) => {
|
|
||||||
const re = /#\w+/g;
|
|
||||||
let topics = [];
|
|
||||||
const matchs = [...body.matchAll(re)];
|
|
||||||
|
|
||||||
matchs.forEach((match) => (topics = topics.concat(match[0])));
|
|
||||||
|
|
||||||
return topics;
|
|
||||||
};
|
|
||||||
|
|
||||||
ChangeLogInput.propTypes = {
|
ChangeLogInput.propTypes = {
|
||||||
setLogInput: PropTypes.func,
|
setLogInput: PropTypes.func,
|
||||||
logInput: PropTypes.string,
|
logInput: PropTypes.string,
|
||||||
|
|
|
@ -8,12 +8,6 @@
|
||||||
.input {
|
.input {
|
||||||
outline: 1px solid black;
|
outline: 1px solid black;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
field-sizing: content;
|
|
||||||
/*min-height: 17px;*/
|
|
||||||
/*border: 1px solid #ccc;*/
|
|
||||||
/*max-height: 150px;*/
|
|
||||||
/*overflow-x: hidden;*/
|
|
||||||
/*overflow-y: auto;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { dateParser } from "../utils/dateParser";
|
import { HashTagLink } from "./links";
|
||||||
import { HashTagLink } from "../utils/links";
|
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import styles from "./feed.module.css";
|
import styles from "./feed.module.css";
|
||||||
|
|
||||||
|
@ -32,7 +31,7 @@ const LogEntryCard = ({ body, date, topics }) => {
|
||||||
<p>{body}</p>
|
<p>{body}</p>
|
||||||
<div className={styles.cardBottom}>
|
<div className={styles.cardBottom}>
|
||||||
<FeedTopics topics={topics} />
|
<FeedTopics topics={topics} />
|
||||||
<p>{dateParser(date)}</p>
|
<p>{date}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -52,5 +51,4 @@ LogEntryCard.propTypes = {
|
||||||
topics: PropTypes.array,
|
topics: PropTypes.array,
|
||||||
};
|
};
|
||||||
|
|
||||||
//<p>{date.toLocaleString()}</p>
|
|
||||||
export default Feed;
|
export default Feed;
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Link } from "react-router-dom";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
const HashTagLink = ({ tag }) => {
|
const HashTagLink = ({ tag }) => {
|
||||||
return <a href="#">{tag}</a>;
|
return <a href="#">#{tag}</a>;
|
||||||
};
|
};
|
||||||
|
|
||||||
HashTagLink.propTypes = {
|
HashTagLink.propTypes = {
|
|
@ -1,5 +0,0 @@
|
||||||
const Topic = (props) => {
|
|
||||||
const entries = props.entries;
|
|
||||||
|
|
||||||
const filtered = entries.filter((item) => {});
|
|
||||||
};
|
|
|
@ -1,24 +0,0 @@
|
||||||
function dateParser(date) {
|
|
||||||
/* Returns a time/date formatted string
|
|
||||||
* based on the age of the log entry.
|
|
||||||
* > 24 hrs return the date
|
|
||||||
* < 24 hrs > 1 hr return the number of hours
|
|
||||||
* otherwise return the minutes since the log was entered
|
|
||||||
*/
|
|
||||||
const currentTime = new Date();
|
|
||||||
|
|
||||||
const difference = Math.floor((currentTime - date) / 1000);
|
|
||||||
|
|
||||||
if (difference >= 86400) {
|
|
||||||
// Return date since entry is older than a day
|
|
||||||
return date.toLocaleString();
|
|
||||||
} else if (difference >= 3600) {
|
|
||||||
// Return hours since log entry
|
|
||||||
return `${difference / 3600}h`;
|
|
||||||
} else {
|
|
||||||
// Reteurn Minutes since log entry
|
|
||||||
return `${Math.floor(difference / 60)}m`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export { dateParser };
|
|
|
@ -1,31 +0,0 @@
|
||||||
import { dateParser } from "./dateParser";
|
|
||||||
import { describe, it, expect } from "vitest";
|
|
||||||
|
|
||||||
describe("Date Parser", () => {
|
|
||||||
it("should have 0m for new entries", () => {
|
|
||||||
const currentTime = new Date();
|
|
||||||
const timeString = dateParser(currentTime);
|
|
||||||
expect(timeString).toMatch(/0m/);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should return (n)m for entries older than 30 minutes", () => {
|
|
||||||
const currentTime = new Date();
|
|
||||||
currentTime.setMinutes(currentTime.getMinutes() + 30);
|
|
||||||
const timeString = dateParser(currentTime);
|
|
||||||
expect(timeString).toMatch(/30m/);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should return (n)h for entires aged over an hour", () => {
|
|
||||||
const currentTime = new Date();
|
|
||||||
currentTime.setHours(currentTime.getHours() - 2);
|
|
||||||
const timeString = dateParser(currentTime);
|
|
||||||
expect(timeString).toMatch(/2h/);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should return the date for entries older than 24 hours", () => {
|
|
||||||
const currentTime = new Date();
|
|
||||||
currentTime.setDate(currentTime.getDate() - 1);
|
|
||||||
const timeString = dateParser(currentTime);
|
|
||||||
expect(timeString).toBeTypeOf("string");
|
|
||||||
});
|
|
||||||
});
|
|
Loading…
Reference in a new issue