qiskit.org/hooks/event-conversion-utils.ts

437 lines
14 KiB
TypeScript
Raw Normal View History

import Airtable from "airtable";
import {
CommunityEvent,
CommunityEventType,
COMMUNITY_EVENT_TYPES,
COMMUNITY_EVENT_TYPE_OPTIONS,
WorldRegion,
WORLD_REGIONS,
} from "../types/events";
import {
AirtableRecords,
getImageUrl,
findImageAttachment,
} from "./airtable-conversion-utils";
// TODO: Understand why this import worked with '../' and not with '~/'
// The types has been moved outside the store, check if this works as expected
export type SeminarSeriesEvent = {
date: string;
startDate: string;
endDate: string;
startDateAndTime?: string | null;
image: string;
institution: string;
location: string;
speaker: string;
title: string;
to: string;
};
test(hooks): increase coverage (#3395) * new tests for advocate, airtable and event conversion utils * fix lint * new tests for advocate, airtable and event conversion utils * improve test coverage * hooks with 100% coverage 😁 * fix lint * [WIP] * fix test * fix lint * fix mkdir in parallel * fix date test * fix character * new tests for advocate, airtable and event conversion utils * fix lint * new tests for advocate, airtable and event conversion utils * improve test coverage * hooks with 100% coverage 😁 * fix lint * [WIP] * fix test * fix lint * fix mkdir in parallel * fix date test * fix character * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * fix(#3395): remove unnecesary file Signed-off-by: Pablo Aragón <pablo.aragon@ibm.com> * Update tests/hooks/utils/conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/utils/conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * fix(#3395): remove unnecesary file Signed-off-by: Pablo Aragón <pablo.aragon@ibm.com> * fake mock data * fix test * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/advocate-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/advocate-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/ecosystem-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/ecosystem-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/event-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/event-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Apply suggestions from code review Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * fix: change Member interfecae for already existent * fix test * fix lint * improve test description Signed-off-by: Pablo Aragón <pablo.aragon@ibm.com> * Apply suggestions from code review Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * changes from PR suggestions * fix test --------- Signed-off-by: Pablo Aragón <pablo.aragon@ibm.com> Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com>
2023-07-24 17:38:07 +08:00
export const RECORD_FIELDS_IDS = Object.freeze({
name: "fldTqTxKr3ZzUhzKT",
startDate: "fldPGzoUf9wxsBDYJ",
endDate: "fldeFv42sqOY7oMy0",
startDateAndTime: "fldF2COMbzANgkOh8",
types: "fldarZoYRJvETevow",
website: "fldBPq3LMa5aZDBZm",
location: "fldSjeniJtud6M5j3",
regions: "fldBCXzoxvcoxsKIK",
image: "fldco5xB6dy9MG7y8",
institution: "fldLVMuuhZVGwh4qZ",
showOnEventsPage: "fldi1ThdDnUQakxWo",
showOnSeminarSeriesPage: "fldl6in6TPajnxPMs",
speaker: "fldyeOkGwMbfMRvPu",
Feat/include latest changes nuxt 3 (#3106) * fix: no events found typo (#2966) Co-Authored-By: Ryan Rogers <79115152+ryanrrogers@users.noreply.github.com> * feat(events): add description to EventCard (#2965) Co-Authored-By: Randy <6276074+techtolentino@users.noreply.github.com> * feat: Create SECURITIY.md (#2979) Co-Authored-By: Luciano Bello <lbello@gmail.com> Co-Authored-By: Yaiza <17231966+y4izus@users.noreply.github.com> Co-Authored-By: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> * chore: update labels to match the ones we have https: //github.com/Qiskit/qiskit.org/commit/627017d51ae6d5fa552273be56faf2c150969b94 Co-Authored-By: Yaiza <17231966+y4izus@users.noreply.github.com> * feat(events): Calendar added via Iframe (airtable) (#2995) Co-Authored-By: Esperanza Molina <108661074+memolina2323@users.noreply.github.com> Co-Authored-By: Yaiza <17231966+y4izus@users.noreply.github.com> * feat: update 'Entanglement in action' preview image (#3006) Co-Authored-By: Frank Harkins <frankharkins@hotmail.co.uk> * feat: update slack invite link (#3015) Co-Authored-By: Junye Huang <7631333+HuangJunye@users.noreply.github.com> * feat(events): Shows extra info on all the tabs (#3012) Co-Authored-By: Esperanza Molina <108661074+memolina2323@users.noreply.github.com> Co-Authored-By: Yaiza <17231966+y4izus@users.noreply.github.com> * ci: exclude ecosystem/ subdirectories from rclone sync (#3011) Co-Authored-By: Luciano Bello <lbello@gmail.com> * fix(code-cell): horizontal content overflow (#3040) * feat: Segment Tracking added to event tabs (#3060) Co-Authored-By: Esperanza Molina <108661074+memolina2323@users.noreply.github.com> * chore: update qiskit web components version (#3080) Co-Authored-By: Randy <6276074+techtolentino@users.noreply.github.com> * feat: replace StackExchange with Support Channels (#3067) Co-Authored-By: Junye Huang <7631333+HuangJunye@users.noreply.github.com> Co-Authored-By: Randy <6276074+techtolentino@users.noreply.github.com> * chore: fresh fetched content * feat: added Near Term Algorithm Design landing page (#3098) Co-Authored-By: Sanket Panda <6241840+pandasa123@users.noreply.github.com> Co-Authored-By: Frank Harkins <frankharkins@hotmail.co.uk> --------- Co-authored-by: Ryan Rogers <79115152+ryanrrogers@users.noreply.github.com> Co-authored-by: Randy <6276074+techtolentino@users.noreply.github.com> Co-authored-by: Luciano Bello <lbello@gmail.com> Co-authored-by: Yaiza <17231966+y4izus@users.noreply.github.com> Co-authored-by: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Co-authored-by: Esperanza Molina <108661074+memolina2323@users.noreply.github.com> Co-authored-by: Frank Harkins <frankharkins@hotmail.co.uk> Co-authored-by: Junye Huang <7631333+HuangJunye@users.noreply.github.com> Co-authored-by: Sanket Panda <6241840+pandasa123@users.noreply.github.com>
2023-04-06 21:16:04 +08:00
abstract: "fldBqkIigePRu4oZd",
} as const);
const AIRTABLE_BASE_ID = "appYREKB18uC7y8ul";
class EventsAirtableRecords extends AirtableRecords {
constructor(
apiKey: string,
view: string,
recordFields?: Record<string, any>
) {
super(
apiKey,
AIRTABLE_BASE_ID,
"Event Calendar",
view,
undefined,
recordFields
);
test(hooks): increase coverage (#3395) * new tests for advocate, airtable and event conversion utils * fix lint * new tests for advocate, airtable and event conversion utils * improve test coverage * hooks with 100% coverage 😁 * fix lint * [WIP] * fix test * fix lint * fix mkdir in parallel * fix date test * fix character * new tests for advocate, airtable and event conversion utils * fix lint * new tests for advocate, airtable and event conversion utils * improve test coverage * hooks with 100% coverage 😁 * fix lint * [WIP] * fix test * fix lint * fix mkdir in parallel * fix date test * fix character * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * fix(#3395): remove unnecesary file Signed-off-by: Pablo Aragón <pablo.aragon@ibm.com> * Update tests/hooks/utils/conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/utils/conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * fix(#3395): remove unnecesary file Signed-off-by: Pablo Aragón <pablo.aragon@ibm.com> * fake mock data * fix test * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/advocate-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/advocate-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/ecosystem-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/ecosystem-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/event-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/event-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Apply suggestions from code review Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * fix: change Member interfecae for already existent * fix test * fix lint * improve test description Signed-off-by: Pablo Aragón <pablo.aragon@ibm.com> * Apply suggestions from code review Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * changes from PR suggestions * fix test --------- Signed-off-by: Pablo Aragón <pablo.aragon@ibm.com> Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com>
2023-07-24 17:38:07 +08:00
this.airtableBase = new Airtable({ apiKey: this.apiKey }).base(
AIRTABLE_BASE_ID
);
}
/**
* Sort the events by their start date.
* @param events The events to sort.
* @param direction The direction to sort the events in.
* @returns The sorted events.
*/
private sortEventsByStartDate<T extends CommunityEvent | SeminarSeriesEvent>(
events: T[],
direction: "asc" | "desc"
): T[] {
return events.sort((a, b) => {
const aDate = new Date(a.startDate);
const bDate = new Date(b.startDate);
if (direction === "asc") {
return aDate.getTime() - bDate.getTime();
} else {
return bDate.getTime() - aDate.getTime();
}
});
}
/**
* Get the Airtable query for the events.
* @param filterFormula The Airtable filter formula to use.
* @returns The Airtable query.
*/
getEventsQuery(filterFormula: string): Airtable.Query<{}> {
test(hooks): increase coverage (#3395) * new tests for advocate, airtable and event conversion utils * fix lint * new tests for advocate, airtable and event conversion utils * improve test coverage * hooks with 100% coverage 😁 * fix lint * [WIP] * fix test * fix lint * fix mkdir in parallel * fix date test * fix character * new tests for advocate, airtable and event conversion utils * fix lint * new tests for advocate, airtable and event conversion utils * improve test coverage * hooks with 100% coverage 😁 * fix lint * [WIP] * fix test * fix lint * fix mkdir in parallel * fix date test * fix character * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * fix(#3395): remove unnecesary file Signed-off-by: Pablo Aragón <pablo.aragon@ibm.com> * Update tests/hooks/utils/conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/utils/conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * fix(#3395): remove unnecesary file Signed-off-by: Pablo Aragón <pablo.aragon@ibm.com> * fake mock data * fix test * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/advocate-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/advocate-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/ecosystem-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/ecosystem-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/event-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/event-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Apply suggestions from code review Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * fix: change Member interfecae for already existent * fix test * fix lint * improve test description Signed-off-by: Pablo Aragón <pablo.aragon@ibm.com> * Apply suggestions from code review Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * changes from PR suggestions * fix test --------- Signed-off-by: Pablo Aragón <pablo.aragon@ibm.com> Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com>
2023-07-24 17:38:07 +08:00
return this.airtableBase("Event Calendar").select({
filterByFormula: filterFormula,
});
}
/**
* Check whether an event happens within a predetermined number of days before
* or after today.
* If the "days" parameter is positive, the event must happen in the future,
* between today and the given number of days after today.
* If the "days" parameter is negative, the event must happen in the past,
* between today and the given number of days before today.
* @param event The event to check.
* @param days The number of days before and after today.
* @returns Whether the event happens within the specified range.
*/
isEventInDateRange(
event: CommunityEvent | SeminarSeriesEvent,
days: number
): boolean {
const { startDate, endDate } = event;
const today: Date = new Date();
today.setUTCHours(0, 0, 0, 0);
const eventStartDate: Date = new Date(startDate);
const eventEndDate: Date = new Date(endDate);
const isFutureRange: boolean = days >= 0;
const isOngoingEvent: boolean =
eventStartDate <= today && today <= eventEndDate;
const isToday: boolean =
eventStartDate.getDate() === today.getDate() &&
eventStartDate.getMonth() === today.getMonth() &&
eventStartDate.getFullYear() === today.getFullYear();
let eventDateToCheck: Date;
// Determine which date to check based on the days parameter and checking if
// the event's dates are valid.
if (isFutureRange && isOngoingEvent) {
return true;
} else if (isFutureRange && isToday) {
return true;
} else if (!isFutureRange && isToday) {
return false;
} else if (!isFutureRange && !isNaN(eventEndDate.getTime())) {
eventDateToCheck = eventEndDate;
} else if (!isNaN(eventStartDate.getTime())) {
eventDateToCheck = eventStartDate;
} else {
return false;
}
let rangeStart: Date;
let rangeEnd: Date;
// Determine the range of dates to check.
if (isFutureRange) {
rangeStart = new Date(today);
rangeEnd = new Date(today.getTime() + days * 24 * 60 * 60 * 1000);
} else {
rangeStart = new Date(today.getTime() + days * 24 * 60 * 60 * 1000);
rangeEnd = new Date(today);
2020-04-08 15:48:46 +08:00
}
return eventDateToCheck >= rangeStart && eventDateToCheck <= rangeEnd;
}
/**
* Fetch the community events from Airtable, convert them to the
* CommunityEvent type, and return them sorted by their start date.
* @param days The number of days before and after today to fetch events for.
* @returns The community events.
*/
async fetchCommunityEvents(days: number): Promise<CommunityEvent[]> {
if (!this.recordFields) {
this.recordFields = await this.getAllFieldNames(RECORD_FIELDS_IDS);
}
const communityEvents: CommunityEvent[] = [];
const filterFormula = `{${this.recordFields.showOnEventsPage}}`;
await this.getEventsQuery(filterFormula).eachPage(
async (records, nextPage) => {
for (const record of records) {
this.id = record.id;
const communityEvent = await this.convertToCommunityEvent(record);
if (this.isEventInDateRange(communityEvent, days)) {
communityEvents.push(communityEvent);
}
}
nextPage();
}
);
const sortedCommunityEvents = this.sortEventsByStartDate(
communityEvents,
days > 0 ? "asc" : "desc"
);
return Promise.resolve(sortedCommunityEvents);
}
/**
* Fetch the seminar series events from Airtable, convert them to the
* SeminarSeriesEvent type, and return them sorted by their start date.
* @param days The number of days before and after today to fetch events for.
* @returns The seminar series events.
*/
async fetchSeminarSeriesEvents(days: number): Promise<SeminarSeriesEvent[]> {
if (!this.recordFields) {
this.recordFields = await this.getAllFieldNames(RECORD_FIELDS_IDS);
}
const seminarSeriesEvents: SeminarSeriesEvent[] = [];
const filterFormula = `{${this.recordFields.showOnSeminarSeriesPage}}`;
await this.getEventsQuery(filterFormula).eachPage(
async (records, nextPage) => {
for (const record of records) {
this.id = record.id;
const seminarSeriesEvent = await this.convertToSeminarSeriesEvent(
record
);
if (typeof seminarSeriesEvent.to !== "undefined") {
if (this.isEventInDateRange(seminarSeriesEvent, days)) {
seminarSeriesEvents.push(seminarSeriesEvent);
}
}
}
nextPage();
}
);
const sortedSeminarSeriesEvents = this.sortEventsByStartDate(
seminarSeriesEvents,
days > 0 ? "asc" : "desc"
);
return Promise.resolve(sortedSeminarSeriesEvents);
}
/**
* Convert an Airtable record to a CommunityEvent.
* @param record The Airtable record to convert.
* @returns The converted CommunityEvent.
*/
async convertToCommunityEvent(
record: Record<string, any>
): Promise<CommunityEvent> {
const event = {
endDate: (record.get(this.recordFields!.endDate) as string) || "",
location:
(record.get(this.recordFields!.location) as string) ||
WORLD_REGIONS.tbd,
regions: (record.get(this.recordFields!.regions) as WorldRegion[]) || [
WORLD_REGIONS.tbd,
],
speaker: (record.get(this.recordFields!.speaker) as string) || "",
title: (record.get(this.recordFields!.name) as string) || "",
to: (record.get(this.recordFields!.website) as string) || "",
Feat/include latest changes nuxt 3 (#3106) * fix: no events found typo (#2966) Co-Authored-By: Ryan Rogers <79115152+ryanrrogers@users.noreply.github.com> * feat(events): add description to EventCard (#2965) Co-Authored-By: Randy <6276074+techtolentino@users.noreply.github.com> * feat: Create SECURITIY.md (#2979) Co-Authored-By: Luciano Bello <lbello@gmail.com> Co-Authored-By: Yaiza <17231966+y4izus@users.noreply.github.com> Co-Authored-By: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> * chore: update labels to match the ones we have https: //github.com/Qiskit/qiskit.org/commit/627017d51ae6d5fa552273be56faf2c150969b94 Co-Authored-By: Yaiza <17231966+y4izus@users.noreply.github.com> * feat(events): Calendar added via Iframe (airtable) (#2995) Co-Authored-By: Esperanza Molina <108661074+memolina2323@users.noreply.github.com> Co-Authored-By: Yaiza <17231966+y4izus@users.noreply.github.com> * feat: update 'Entanglement in action' preview image (#3006) Co-Authored-By: Frank Harkins <frankharkins@hotmail.co.uk> * feat: update slack invite link (#3015) Co-Authored-By: Junye Huang <7631333+HuangJunye@users.noreply.github.com> * feat(events): Shows extra info on all the tabs (#3012) Co-Authored-By: Esperanza Molina <108661074+memolina2323@users.noreply.github.com> Co-Authored-By: Yaiza <17231966+y4izus@users.noreply.github.com> * ci: exclude ecosystem/ subdirectories from rclone sync (#3011) Co-Authored-By: Luciano Bello <lbello@gmail.com> * fix(code-cell): horizontal content overflow (#3040) * feat: Segment Tracking added to event tabs (#3060) Co-Authored-By: Esperanza Molina <108661074+memolina2323@users.noreply.github.com> * chore: update qiskit web components version (#3080) Co-Authored-By: Randy <6276074+techtolentino@users.noreply.github.com> * feat: replace StackExchange with Support Channels (#3067) Co-Authored-By: Junye Huang <7631333+HuangJunye@users.noreply.github.com> Co-Authored-By: Randy <6276074+techtolentino@users.noreply.github.com> * chore: fresh fetched content * feat: added Near Term Algorithm Design landing page (#3098) Co-Authored-By: Sanket Panda <6241840+pandasa123@users.noreply.github.com> Co-Authored-By: Frank Harkins <frankharkins@hotmail.co.uk> --------- Co-authored-by: Ryan Rogers <79115152+ryanrrogers@users.noreply.github.com> Co-authored-by: Randy <6276074+techtolentino@users.noreply.github.com> Co-authored-by: Luciano Bello <lbello@gmail.com> Co-authored-by: Yaiza <17231966+y4izus@users.noreply.github.com> Co-authored-by: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Co-authored-by: Esperanza Molina <108661074+memolina2323@users.noreply.github.com> Co-authored-by: Frank Harkins <frankharkins@hotmail.co.uk> Co-authored-by: Junye Huang <7631333+HuangJunye@users.noreply.github.com> Co-authored-by: Sanket Panda <6241840+pandasa123@users.noreply.github.com>
2023-04-06 21:16:04 +08:00
abstract: record.get(this.recordFields!.abstract) || "",
date: this.formatDates(...this.getDates(record)),
image: await this.getImage(record),
startDate: this.getStartDate(record),
startDateAndTime: this.formatTime(
record.get(this.recordFields!.startDateAndTime) || null
),
types: this.getEventTypes(record),
};
return event;
}
2020-04-08 15:48:46 +08:00
/**
* Convert an Airtable record to a SeminarSeriesEvent.
* @param record The Airtable record to convert.
* @returns The converted SeminarSeriesEvent.
*/
async convertToSeminarSeriesEvent(
record: Record<string, any>
): Promise<SeminarSeriesEvent> {
const event = {
endDate: record.get(this.recordFields!.endDate) || "",
institution: record.get(this.recordFields!.institution) || "",
location: record.get(this.recordFields!.location) || WORLD_REGIONS.tbd,
speaker: record.get(this.recordFields!.speaker) || "",
title: record.get(this.recordFields!.name) || "",
to: record.get(this.recordFields!.website) || "",
Feat/include latest changes nuxt 3 (#3106) * fix: no events found typo (#2966) Co-Authored-By: Ryan Rogers <79115152+ryanrrogers@users.noreply.github.com> * feat(events): add description to EventCard (#2965) Co-Authored-By: Randy <6276074+techtolentino@users.noreply.github.com> * feat: Create SECURITIY.md (#2979) Co-Authored-By: Luciano Bello <lbello@gmail.com> Co-Authored-By: Yaiza <17231966+y4izus@users.noreply.github.com> Co-Authored-By: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> * chore: update labels to match the ones we have https: //github.com/Qiskit/qiskit.org/commit/627017d51ae6d5fa552273be56faf2c150969b94 Co-Authored-By: Yaiza <17231966+y4izus@users.noreply.github.com> * feat(events): Calendar added via Iframe (airtable) (#2995) Co-Authored-By: Esperanza Molina <108661074+memolina2323@users.noreply.github.com> Co-Authored-By: Yaiza <17231966+y4izus@users.noreply.github.com> * feat: update 'Entanglement in action' preview image (#3006) Co-Authored-By: Frank Harkins <frankharkins@hotmail.co.uk> * feat: update slack invite link (#3015) Co-Authored-By: Junye Huang <7631333+HuangJunye@users.noreply.github.com> * feat(events): Shows extra info on all the tabs (#3012) Co-Authored-By: Esperanza Molina <108661074+memolina2323@users.noreply.github.com> Co-Authored-By: Yaiza <17231966+y4izus@users.noreply.github.com> * ci: exclude ecosystem/ subdirectories from rclone sync (#3011) Co-Authored-By: Luciano Bello <lbello@gmail.com> * fix(code-cell): horizontal content overflow (#3040) * feat: Segment Tracking added to event tabs (#3060) Co-Authored-By: Esperanza Molina <108661074+memolina2323@users.noreply.github.com> * chore: update qiskit web components version (#3080) Co-Authored-By: Randy <6276074+techtolentino@users.noreply.github.com> * feat: replace StackExchange with Support Channels (#3067) Co-Authored-By: Junye Huang <7631333+HuangJunye@users.noreply.github.com> Co-Authored-By: Randy <6276074+techtolentino@users.noreply.github.com> * chore: fresh fetched content * feat: added Near Term Algorithm Design landing page (#3098) Co-Authored-By: Sanket Panda <6241840+pandasa123@users.noreply.github.com> Co-Authored-By: Frank Harkins <frankharkins@hotmail.co.uk> --------- Co-authored-by: Ryan Rogers <79115152+ryanrrogers@users.noreply.github.com> Co-authored-by: Randy <6276074+techtolentino@users.noreply.github.com> Co-authored-by: Luciano Bello <lbello@gmail.com> Co-authored-by: Yaiza <17231966+y4izus@users.noreply.github.com> Co-authored-by: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Co-authored-by: Esperanza Molina <108661074+memolina2323@users.noreply.github.com> Co-authored-by: Frank Harkins <frankharkins@hotmail.co.uk> Co-authored-by: Junye Huang <7631333+HuangJunye@users.noreply.github.com> Co-authored-by: Sanket Panda <6241840+pandasa123@users.noreply.github.com>
2023-04-06 21:16:04 +08:00
abstract: record.get(this.recordFields!.abstract) || "",
date: this.formatDates(...this.getDates(record)),
image: await this.getImage(record),
startDate: this.getStartDate(record),
};
return event;
}
dateParts(date: Date): [string, string, string] {
const year = new Intl.DateTimeFormat("en-US", {
year: "numeric",
timeZone: "UTC",
}).format(date);
const month = new Intl.DateTimeFormat("en-US", {
month: "long",
timeZone: "UTC",
}).format(date);
const day = new Intl.DateTimeFormat("en-US", {
day: "numeric",
timeZone: "UTC",
}).format(date);
return [year, month, day];
}
filterWithWhitelist<W>(list: any[], whitelist: readonly W[]): W[] {
return list.filter((type): type is W => whitelist.includes(type));
}
2020-04-08 15:48:46 +08:00
formatDates(startDate?: Date, endDate?: Date): string {
if (!startDate) {
return "TBD";
}
const [startYear, startMonth, startDay] = this.dateParts(startDate);
if (!endDate || startDate.getTime() === endDate.getTime()) {
return `${startMonth} ${startDay}, ${startYear}`;
}
2020-04-08 15:48:46 +08:00
const [endYear, endMonth, endDay] = this.dateParts(endDate);
if (startYear !== endYear) {
return `${startMonth} ${startDay}, ${startYear} - ${endMonth} ${endDay}, ${endYear}`;
}
if (startMonth !== endMonth) {
return `${startMonth} ${startDay} - ${endMonth} ${endDay}, ${startYear}`;
}
if (startDay !== endDay) {
return `${startMonth} ${startDay}-${endDay}, ${startYear}`;
}
test(hooks): increase coverage (#3395) * new tests for advocate, airtable and event conversion utils * fix lint * new tests for advocate, airtable and event conversion utils * improve test coverage * hooks with 100% coverage 😁 * fix lint * [WIP] * fix test * fix lint * fix mkdir in parallel * fix date test * fix character * new tests for advocate, airtable and event conversion utils * fix lint * new tests for advocate, airtable and event conversion utils * improve test coverage * hooks with 100% coverage 😁 * fix lint * [WIP] * fix test * fix lint * fix mkdir in parallel * fix date test * fix character * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * fix(#3395): remove unnecesary file Signed-off-by: Pablo Aragón <pablo.aragon@ibm.com> * Update tests/hooks/utils/conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/utils/conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * fix(#3395): remove unnecesary file Signed-off-by: Pablo Aragón <pablo.aragon@ibm.com> * fake mock data * fix test * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/advocate-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/advocate-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/ecosystem-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/airtable-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/ecosystem-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/event-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Update tests/hooks/event-conversion-utils.spec.ts Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * Apply suggestions from code review Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * fix: change Member interfecae for already existent * fix test * fix lint * improve test description Signed-off-by: Pablo Aragón <pablo.aragon@ibm.com> * Apply suggestions from code review Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com> * changes from PR suggestions * fix test --------- Signed-off-by: Pablo Aragón <pablo.aragon@ibm.com> Co-authored-by: Eddybrando Vásquez <eddybrando.vasquez@gmail.com>
2023-07-24 17:38:07 +08:00
throw new Error("Unreachable: should have been covered by a case.");
}
2020-04-08 15:48:46 +08:00
/**
* Format a date and time to a string with only the time in UTC.
* @param startDateAndTime The date and time to format.
* @returns The formatted time.
*/
formatTime(startDateAndTime: string | null): string | null {
if (!startDateAndTime) {
return null;
}
const formattedStartDateAndTime = new Date(startDateAndTime);
return new Intl.DateTimeFormat("en-US", {
hour: "numeric",
minute: "numeric",
timeZone: "UTC",
timeZoneName: "short",
}).format(formattedStartDateAndTime);
}
2020-04-08 15:48:46 +08:00
/**
* Get the event's types.
* @param record The event's record.
* @returns The event's types.
*/
private getEventTypes(record: Record<string, any>): CommunityEventType[] {
const value = record.get(this.recordFields!.types) || [];
const valueList = (Array.isArray(value) ? value : [value]) as string[];
const communityEventTypes = this.filterWithWhitelist(
valueList,
COMMUNITY_EVENT_TYPE_OPTIONS
);
const noTypes = communityEventTypes.length === 0;
return noTypes ? [COMMUNITY_EVENT_TYPES.talks] : communityEventTypes;
}
2020-04-08 15:48:46 +08:00
/**
* Get the event's image.
* @param record The event's record.
* @returns Promise resolving to the event's image URL.
*/
public async getImage(record: Record<string, any>): Promise<string> {
const fallbackImage = "/images/events/no-picture.jpg";
const attachments = record.get(this.recordFields!.image);
const imageAttachment = attachments && findImageAttachment(attachments);
const imageUrl = imageAttachment && getImageUrl(imageAttachment);
if (!imageUrl) {
return fallbackImage;
}
const imagePublicPath = `/images/events/downloaded/${this.id}.jpg`;
return await this.storeImage(imageUrl, `public/${imagePublicPath}`)
.then(() => imagePublicPath)
.catch(() => fallbackImage);
2020-04-08 15:48:46 +08:00
}
/**
* Get the event's start date.
* @param record The event's record.
* @returns The event's start date.
*/
public getStartDate(record: Record<string, any>): string {
if (record.get(this.recordFields!.startDateAndTime)) {
const startDateAndTime = record.get(this.recordFields!.startDateAndTime);
const startDate = new Date(startDateAndTime);
return startDate.toISOString().split("T")[0];
}
return record.get(this.recordFields!.startDate) || "";
2020-04-08 15:48:46 +08:00
}
/**
* Get the event's start and end dates.
* @param record The event's record.
* @returns The event's start and end dates.
*/
public getDates(
record: Record<string, any>
): [Date | undefined, Date | undefined] {
const recordStartDate = this.getStartDate(record);
const recordEndDate = record.get(this.recordFields!.endDate) as
| string
| undefined;
2020-04-08 15:48:46 +08:00
let startDate: Date | undefined;
let endDate: Date | undefined;
if (recordStartDate) {
startDate = new Date(recordStartDate);
}
2020-04-08 15:48:46 +08:00
if (recordEndDate) {
endDate = new Date(recordEndDate);
}
return [startDate, endDate];
}
2020-04-08 15:48:46 +08:00
}
export default EventsAirtableRecords;