@@ -97,76 +97,35 @@ export function formatDateAndTime(dateTimeObject) {
98// Returns an array of unique grants categories
98// Returns an array of unique grants categories
99export function getGrantsCategories() {
99export function getGrantsCategories() {
100− const paths = fs.readdirSync(directories("grants"));
100+ const years = fs.readdirSync(directories("grants"), { withFileTypes: true }).filter((f) => f.isDirectory());
101− const uniqueCategories = paths
101+ const uniqueCategories = Array.from(new Set(years.map((yearDir) => {
102− // Get only markdown files
102+ return fs.readdirSync(join(directories("grants"), yearDir.name), { withFileTypes: true })
103− .filter((path) => parse(path).ext === ".md")
103+ .filter((path) => parse(path.name).ext === ".md")
104− // Parse frontmatter
106− matter(fs.readFileSync(join(directories("grants"), path)), options)
104+ .map((path) => matter(fs.readFileSync(join(directories("grants"), yearDir.name, path.name)), options))
108− // Each markdown file has an array of categories. Collapse these arrays into one array.
109− .reduce((acc, metadata) => {
106+ .reduce((acc, metadata) => {
110− return [...acc, ...metadata.data.taxonomies.grant_category];
107+ return [...acc, ...metadata.data.taxonomies.grant_category]
112− // Deduplicate single array of categories such that the output is an array where each category is represented only once.
109+ }).flat()));
113− .reduce((acc, uniqueItem) => {
114− if (acc.includes(uniqueItem)) {
117− return [...acc, uniqueItem];
119 return uniqueCategories;
110 return uniqueCategories;
122// Returns an array of unique grants types
113// Returns an array of unique grants types
123export function getGrantsTypes() {
115export function getGrantsTypes() {
124− const paths = fs.readdirSync(directories("grants"));
116+ const years = fs.readdirSync(directories("grants"), { withFileTypes: true }).filter((f) => f.isDirectory());
125− const uniqueTypes = paths
117+ const uniqueTypes = Array.from(new Set(years.map((yearDir) => {
126− // Get only markdown files
118+ return fs.readdirSync(join(directories("grants"), yearDir.name), { withFileTypes: true })
127− .filter((path) => parse(path).ext === ".md")
119+ .filter((path) => parse(path.name).ext === ".md")
128− // Parse frontmatter to JSON
130− matter(fs.readFileSync(join(directories("grants"), path)), options)
120+ .map((path) => matter(fs.readFileSync(join(directories("grants"), yearDir.name, path.name)), options))
132− // Each markdown file has an array of types. Collapse these arrays into one array.
133− .reduce((acc, metadata) => {
122+ .reduce((acc, metadata) => {
134− return [...acc, ...metadata.data.taxonomies.grant_type];
123+ return [...acc, ...metadata.data.taxonomies.grant_type]
136− // Deduplicate single array of types such that the output is an array where each type is represented only once.
125+ }).flat()));
137− .reduce((acc, uniqueItem) => {
138− if (acc.includes(uniqueItem)) {
141− return [...acc, uniqueItem];
143 return uniqueTypes;
126 return uniqueTypes;
146−// Returns a number which represents how many grants are open, or uncompleted
147−export function getOpenGrantsCount() {
148− const paths = fs.readdirSync(directories("grants"));
150− // Get only markdown files
151− .filter((path) => parse(path).ext === ".md")
152− // Parse frontmatter to JSON
154− matter(fs.readFileSync(join(directories("grants"), path)), options)
156− // Count grants which are both uncompleted and not assigned
157− .reduce((acc, metadata) => {
159− !metadata.data.extra.completed &&
160− !metadata.data.extra.canceled &&
161− metadata.data.extra.assignee?.[0] === ""
170// Groups arrays into an array of arrays with 2 members
129// Groups arrays into an array of arrays with 2 members
171export const pair = (arr) =>
130export const pair = (arr) =>
172 arr.reduce(function (rows, key, index) {
131 arr.reduce(function (rows, key, index) {