Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge LD sub sub #1557

Closed
wants to merge 116 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
b3e68e6
removed cards routes and pages associated with MMDL redirect
anyoussefinia Sep 9, 2024
dfe7081
removed deleted components
anyoussefinia Sep 9, 2024
9d00916
added back mistakenly deleted route
anyoussefinia Sep 16, 2024
e818e15
removed MMDL uri from TriageExternalLandingPage
anyoussefinia Sep 17, 2024
062b238
added pdf's and implimentation guides according to faq breakdown mockup
anyoussefinia Sep 22, 2024
4958ef4
added style to remove + icon from FAQ questions
anyoussefinia Sep 24, 2024
c1a331f
added 2 unit tests and the download attribute to implimentation guide…
anyoussefinia Sep 24, 2024
9aab2e4
Merge pull request #1513 from Enterprise-CMCS/oy2-27831
anyoussefinia Sep 25, 2024
33f4300
Merge pull request #1507 from Enterprise-CMCS/oy2-29781-2
anyoussefinia Sep 25, 2024
dccaef7
removed svg icon from filter panel on dashboard
anyoussefinia Sep 26, 2024
154b8ea
attempt to resolve svg still appearing
anyoussefinia Sep 27, 2024
5293cd0
Merge pull request #1515 from Enterprise-CMCS/oy2-27831
anyoussefinia Oct 1, 2024
c453d47
moved pdf related FAQ questions under SPA section
anyoussefinia Oct 17, 2024
d8db898
modify conflicting ids
anyoussefinia Oct 17, 2024
f70981e
remove accidental change
anyoussefinia Oct 17, 2024
e7b0025
change conflicting ids
anyoussefinia Oct 17, 2024
1416509
moved one more SPA related FAQ to the right section
anyoussefinia Oct 17, 2024
fd1923d
Merge branch 'develop' into onemacmmdl
bflynn-cms Oct 20, 2024
0fed43a
Create infrastructure for systemwide and user notifications in OneMAC…
andieswift Oct 20, 2024
a02a347
resolve conflicts
anyoussefinia Oct 22, 2024
7c081fb
Merge pull request #1540 from Enterprise-CMCS/oy2-30455-2
anyoussefinia Oct 22, 2024
588c9b7
test flag
anyoussefinia Oct 28, 2024
d2e289b
test flag
anyoussefinia Oct 28, 2024
be49164
test ssm parameter store
anyoussefinia Oct 28, 2024
26dad8f
test ssm parameter store
anyoussefinia Oct 28, 2024
09eec1b
log client side id
anyoussefinia Oct 28, 2024
f2ded70
attempt differnt way of fetching ssm parameter
anyoussefinia Oct 28, 2024
ab05842
try different path for ssm parameter store
anyoussefinia Oct 28, 2024
a3ad273
correct misname
anyoussefinia Oct 28, 2024
aa69484
log LD client Id during build
anyoussefinia Oct 28, 2024
4e69d8e
reorder fetching ssm parameter to pass as build paramter
anyoussefinia Oct 28, 2024
1f667eb
change order
anyoussefinia Oct 28, 2024
5b952c7
try to set env before build
anyoussefinia Oct 28, 2024
83e8886
rename environment variable
anyoussefinia Oct 28, 2024
77dde2c
added conditional logic
anyoussefinia Oct 30, 2024
20c622d
added unit tests for toggling launch darkly flag
anyoussefinia Oct 30, 2024
e68eede
added unit tests and conditional rendering to App, Home NotificationB…
anyoussefinia Oct 31, 2024
5594fed
fix eslint errors
anyoussefinia Oct 31, 2024
9271941
fix eslint errors
anyoussefinia Oct 31, 2024
8b034ab
consolidate use effects to get rid of eslint errors
anyoussefinia Oct 31, 2024
5ac4c69
add console logs for troubleshooting
anyoussefinia Oct 31, 2024
5cef4c1
more console logs to see why lauch darkly not initializing
anyoussefinia Oct 31, 2024
5cdd29f
remove unused vars
anyoussefinia Oct 31, 2024
ce17a39
remove multiple withLaunchDarklyProvider functions
anyoussefinia Oct 31, 2024
348cecf
remove unused vars
anyoussefinia Oct 31, 2024
b58aefa
test
anyoussefinia Oct 31, 2024
ab47b84
remove waitForInitialization function
anyoussefinia Oct 31, 2024
b1ec949
Create MMDL Notification Banner in OneMAC Application (#1539)
bflynn-cms Nov 1, 2024
2cedfac
revert to testFlag
anyoussefinia Nov 1, 2024
588da37
resolve eslint errors
anyoussefinia Nov 1, 2024
e11f4b3
added console logs for troubleshooting notifications
anyoussefinia Nov 1, 2024
ae2b622
bring in insertNotification Lambda changes
anyoussefinia Nov 1, 2024
6e21f77
remove testFlag from conditional call to notifications api
anyoussefinia Nov 1, 2024
aed162a
removed testFlag from useEffect call to notifications api
anyoussefinia Nov 1, 2024
c9a6d2b
revert changes
anyoussefinia Nov 1, 2024
c4194a0
ignore eslint
anyoussefinia Nov 1, 2024
4db5f86
get/set notification in useEffect
anyoussefinia Nov 3, 2024
3bcb18e
ignore eslint
anyoussefinia Nov 3, 2024
334e49e
ignore eslint
anyoussefinia Nov 3, 2024
c88b125
fix lint errors
anyoussefinia Nov 3, 2024
d4b71c6
remove testFlag from useEffect dependency array
anyoussefinia Nov 3, 2024
ebf46ac
try ignore eslint
anyoussefinia Nov 3, 2024
c3f1acd
remove testFlag use effect
anyoussefinia Nov 3, 2024
c98bcae
ignore eslint
anyoussefinia Nov 3, 2024
29d3d50
try multiple useEffects
anyoussefinia Nov 3, 2024
4918c4d
ignore eslint
anyoussefinia Nov 3, 2024
cbc1883
multiple use effects in Home.js
anyoussefinia Nov 3, 2024
e1a8a29
remove lint error
anyoussefinia Nov 3, 2024
19fe292
ignore link error
anyoussefinia Nov 3, 2024
25db0cc
added logging for troubleshooting
anyoussefinia Nov 3, 2024
b750d35
revert App.tsx
anyoussefinia Nov 4, 2024
f00a3ed
ignore eslint
anyoussefinia Nov 4, 2024
334cd9e
fix import
anyoussefinia Nov 4, 2024
acf8568
added logging for troubleshoot
anyoussefinia Nov 4, 2024
eb14539
fix import
anyoussefinia Nov 4, 2024
d1aa303
revert App.tsx
anyoussefinia Nov 4, 2024
bf8a364
remove flag check for initial render
anyoussefinia Nov 4, 2024
ad2ec33
chaange flag name
anyoussefinia Nov 5, 2024
bb54052
remove console logs
anyoussefinia Nov 6, 2024
7a34abf
remove comments
anyoussefinia Nov 6, 2024
80bfaf3
remove console logs
anyoussefinia Nov 7, 2024
41d2f2c
remove console log
anyoussefinia Nov 7, 2024
706bc97
added logging for troubleshoot
anyoussefinia Nov 8, 2024
0a9fded
add notification state
anyoussefinia Nov 8, 2024
2f00991
added extra logging
anyoussefinia Nov 8, 2024
14aaa63
fix lint error
anyoussefinia Nov 8, 2024
426e93b
add logging
anyoussefinia Nov 8, 2024
a6306fc
add back notifications call on page load
anyoussefinia Nov 8, 2024
f6a3dd0
remove useEffect
anyoussefinia Nov 11, 2024
840a811
add auth state to useEffect
anyoussefinia Nov 11, 2024
2d3b905
added console.logs for debuging
anyoussefinia Nov 11, 2024
6da7d0e
fix lint error
anyoussefinia Nov 11, 2024
ccb079a
remove notifications logic from useCallback
anyoussefinia Nov 11, 2024
7af834b
add another use effect
anyoussefinia Nov 11, 2024
b30333a
add another use effect
anyoussefinia Nov 11, 2024
9fe60e1
remove authState from dep arr
anyoussefinia Nov 12, 2024
9be9172
uncomment code
anyoussefinia Nov 12, 2024
be89241
added console.log
anyoussefinia Nov 12, 2024
854c2e7
lint error
anyoussefinia Nov 12, 2024
1f99825
missing )
anyoussefinia Nov 12, 2024
855a74c
use notificationState
anyoussefinia Nov 12, 2024
be49271
notificationState dep arr
anyoussefinia Nov 12, 2024
7791ef0
test
anyoussefinia Nov 12, 2024
338dbc3
add authState.isAuthenticated to dep arr
anyoussefinia Nov 12, 2024
236a024
fix useEffect
anyoussefinia Nov 12, 2024
4a0cca4
comment out all console logs
anyoussefinia Nov 12, 2024
18ae16f
fix lint error
anyoussefinia Nov 12, 2024
f9fd97c
remove unused var
anyoussefinia Nov 12, 2024
923fc45
remove console logs
anyoussefinia Nov 12, 2024
9c0d653
add back ignore lint
anyoussefinia Nov 13, 2024
cb2136d
try combining useEffects
anyoussefinia Nov 14, 2024
3c04077
revert change
anyoussefinia Nov 14, 2024
08dfbd2
Merge pull request #1545 from Enterprise-CMCS/oy2-30766-0
anyoussefinia Nov 22, 2024
4e04249
Merge branch 'develop' into onemacmmdl
bflynn-cms Nov 25, 2024
c1bba60
Merge pull request #1550 from Enterprise-CMCS/onemacmmdl
anyoussefinia Nov 25, 2024
7789875
Launch Darkly for Subsequent Documentation (#1552)
bflynn-cms Dec 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/build_vars.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var_list=(
COGNITO_TEST_USERS_PASSWORD
NO_EMAIL_DEBUG
REACT_APP_GOOGLE_TAG
REACT_APP_LD_CLIENT_ID
)

set_value() {
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ jobs:
with:
role-to-assume: ${{ env.AWS_OIDC_ROLE_TO_ASSUME }}
aws-region: ${{ env.AWS_DEFAULT_REGION }}
- name: Fetch SSM Parameter
id: fetch_ssm
run: |
LdClientId=$(aws ssm get-parameter --name "/configuration/onemacmmdl/LdClientId" --query "Parameter.Value" --output text)
echo "REACT_APP_LD_CLIENT_ID=${LdClientId}" >> $GITHUB_ENV
- uses: actions/setup-node@v3
with:
node-version: "20.x"
Expand Down
10 changes: 10 additions & 0 deletions services/admin/handlers/insertNotification.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"_comment": "Dates are passed in format YYYY-MM-DD or keywords 'today' or 'x days from now'",
"publicationDate": "2024-01-01",
"expiryDate": "7 days from now",
"header": "New Feature Release",
"body": "We have released a new feature. Check it out now!",
"buttonText": "Learn More",
"buttonLink": "https://example.com/feature",
"notificationType": "user"
}
150 changes: 150 additions & 0 deletions services/admin/handlers/insertNotification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import { DynamoDB } from "aws-sdk";
import { v4 as uuidv4 } from "uuid"; // Import UUID library
import { addDays } from "date-fns"; // Import a date manipulation library like date-fns for handling date parsing

const dynamoDb = new DynamoDB.DocumentClient(
process.env.IS_OFFLINE
? {
endpoint: "http://localhost:8000",
}
: {}
);
const oneMacTableName = process.env.oneMacTableName || "defaultTableName";

// Define types for event and notification record
interface EventInput {
publicationDate?: string;
expiryDate?: string;
header: string;
body: string;
buttonText?: string;
buttonLink?: string;
notificationType: "user" | "system"; // User-friendly notification type input
}

interface NotificationRecord {
pk: string;
sk: string;
GSI1pk: string;
GSI1sk: string;
publicationDate: string;
expiryDate: string;
header: string;
body: string;
buttonText?: string | null;
buttonLink?: string | null;
createdAt: string;
}

// Function to translate notificationType to GSI1pk value
function mapNotificationType(type: "user" | "system"): string {
return type === "user" ? "USER_NOTIFICATION" : "SYSTEM";
}

// Function to handle flexible date inputs
function parseDate(input?: string): string {
// If no input is provided, default to the current date
if (!input) {
return new Date().toISOString();
}

if (input === "today") {
return new Date().toISOString();
}

if (input.includes("days from now")) {
const days = parseInt(input.split(" ")[0], 10);
return addDays(new Date(), days).toISOString();
}

// Assuming user passes YYYY-MM-DD format for easier input
if (/^\d{4}-\d{2}-\d{2}$/.test(input)) {
return new Date(`${input}T00:00:00Z`).toISOString();
}

// Default to current date if input is invalid
return new Date().toISOString();
}

function validateEvent(event: EventInput): void {
const missingParams: string[] = [];

if (!event.header) {
missingParams.push("header");
}
if (!event.body) {
missingParams.push("body");
}
if (!event.notificationType) {
missingParams.push("notificationType");
}
if (missingParams.length > 0) {
throw new Error(`Missing event parameters: ${missingParams.join(", ")}`);
}

console.log("Event passed validation");
}

function generateNotificationId(): string {
return uuidv4();
}

function formatNotificationRecord(event: EventInput): NotificationRecord {
const notificationId = generateNotificationId(); // Generate a UUID for the notification ID
const pk = "SYSTEM"; // System-wide notification
const sk = `NOTIFICATION#${notificationId}`; // Unique notification identifier

// Default values for publicationDate and expiryDate with more user-friendly inputs
const publicationDate = parseDate(event.publicationDate); // Default to current date
const expiryDate = event.expiryDate
? parseDate(event.expiryDate)
: "9999-12-31T23:59:59Z"; // Default to far future date

// Use the translated notificationType
const GSI1pk = mapNotificationType(event.notificationType);
const GSI1sk = `${publicationDate}#${expiryDate}`; // Sort key for GSI based on dates
const createdAt = new Date().toISOString(); // Current timestamp

return {
pk,
sk,
GSI1pk,
GSI1sk,
publicationDate,
expiryDate,
header: event.header,
body: event.body,
buttonText: event.buttonText || null, // Optional field
buttonLink: event.buttonLink || null, // Optional field
createdAt,
};
}

async function insertNotification(record: NotificationRecord): Promise<void> {
const params: DynamoDB.DocumentClient.PutItemInput = {
TableName: oneMacTableName,
Item: record,
};

console.log("Inserting notification", params);

await dynamoDb.put(params).promise();
}

export const main = async (event: EventInput) => {
console.log("insertNotification.main", event);

validateEvent(event);

const notificationRecord = formatNotificationRecord(event);

await insertNotification(notificationRecord);

return {
statusCode: 200,
body: JSON.stringify({
message: "Notification inserted successfully",
record: notificationRecord, // Return the full inserted record
}),
};
};
4 changes: 4 additions & 0 deletions services/admin/serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,7 @@ functions:
- schedule:
rate: rate(6 hours)
timeout: 180

insertNotification:
handler: ./handlers/insertNotification.main
timeout: 180
2 changes: 1 addition & 1 deletion services/app-api/getDetail.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export const getDetails = async (event) => {
if (!userRoleObj.isCMSUser && result.Item.reviewTeam)
delete result.Item.reviewTeam;

result.Item.actions = getActionsForPackage(
result.Item.actions = await getActionsForPackage(
result.Item.componentType,
originalStatus,
!!result.Item.latestRaiResponseTimestamp,
Expand Down
182 changes: 89 additions & 93 deletions services/app-api/getMyPackages.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,106 +19,102 @@ export const getMyPackages = async (email, group) => {
if (!email) return RESPONSE_CODE.USER_NOT_FOUND;
if (!group) return RESPONSE_CODE.DATA_MISSING;

return getUser(email)
.then((user) => {
if (!user) throw RESPONSE_CODE.USER_NOT_AUTHORIZED;
try {
const user = await getUser(email);
if (!user) throw RESPONSE_CODE.USER_NOT_AUTHORIZED;

const userRoleObj = getUserRoleObj(user.roleList);
const territoryList = getActiveTerritories(user.roleList);
const statusMap = userRoleObj.isCMSUser
? cmsStatusUIMap
: stateStatusUIMap;
const userRoleObj = getUserRoleObj(user.roleList);
const territoryList = getActiveTerritories(user.roleList);
const statusMap = userRoleObj.isCMSUser ? cmsStatusUIMap : stateStatusUIMap;

if (
!userRoleObj.canAccessDashboard ||
(Array.isArray(territoryList) && territoryList.length === 0)
) {
throw RESPONSE_CODE.USER_NOT_AUTHORIZED;
}
if (
!userRoleObj.canAccessDashboard ||
(Array.isArray(territoryList) && territoryList.length === 0)
) {
throw RESPONSE_CODE.USER_NOT_AUTHORIZED;
}

const baseParams = {
TableName: process.env.oneMacTableName,
IndexName: "GSI1",
ExclusiveStartKey: null,
ScanIndexForward: false,
ProjectionExpression:
"componentId,componentType,currentStatus,submissionTimestamp,latestRaiResponseTimestamp,lastActivityTimestamp,submitterName,submitterEmail,waiverAuthority, cpocName, reviewTeam, subStatus, finalDispositionDate",
};
const grouppk = "OneMAC#" + group;
let paramList = [];
if (territoryList[0] !== "N/A") {
paramList = territoryList.map((territory) => {
return {
...baseParams,
KeyConditionExpression: "GSI1pk = :pk AND begins_with(GSI1sk,:t1)",
ExpressionAttributeValues: {
":pk": grouppk,
":t1": territory,
},
};
});
} else {
paramList = [
{
...baseParams,
KeyConditionExpression: "GSI1pk = :pk",
ExpressionAttributeValues: {
":pk": grouppk,
},
const baseParams = {
TableName: process.env.oneMacTableName,
IndexName: "GSI1",
ExclusiveStartKey: null,
ScanIndexForward: false,
ProjectionExpression:
"componentId,componentType,currentStatus,submissionTimestamp,latestRaiResponseTimestamp,lastActivityTimestamp,submitterName,submitterEmail,waiverAuthority, cpocName, reviewTeam, subStatus, finalDispositionDate",
};
const grouppk = "OneMAC#" + group;
let paramList = [];
if (territoryList[0] !== "N/A") {
paramList = territoryList.map((territory) => {
return {
...baseParams,
KeyConditionExpression: "GSI1pk = :pk AND begins_with(GSI1sk,:t1)",
ExpressionAttributeValues: {
":pk": grouppk,
":t1": territory,
},
];
}
};
});
} else {
paramList = [
{
...baseParams,
KeyConditionExpression: "GSI1pk = :pk",
ExpressionAttributeValues: {
":pk": grouppk,
},
},
];
}

return Promise.all(
paramList.map(async (params) => {
const promiseItems = [];
do {
const results = await dynamoDb.query(params);
results.Items.map((oneItem) => {
oneItem.actions = getActionsForPackage(
oneItem.componentType,
oneItem.currentStatus,
!!oneItem.latestRaiResponseTimestamp,
oneItem.subStatus,
userRoleObj,
"package"
);
if (oneItem.waiverAuthority)
oneItem.temporaryExtensionType = oneItem.waiverAuthority.slice(
0,
7
);
// Using a for...of loop to ensure async operations are awaited correctly
const allItems = [];
for (const params of paramList) {
const promiseItems = [];
do {
const results = await dynamoDb.query(params);
for (const oneItem of results.Items) {
oneItem.actions = await getActionsForPackage(
oneItem.componentType,
oneItem.currentStatus,
!!oneItem.latestRaiResponseTimestamp,
oneItem.subStatus,
userRoleObj,
"package"
);
if (oneItem.waiverAuthority)
oneItem.temporaryExtensionType = oneItem.waiverAuthority.slice(
0,
7
);

if (statusMap[oneItem.subStatus]) {
oneItem.subStatus = statusMap[oneItem.subStatus];
}
if (statusMap[oneItem.subStatus]) {
oneItem.subStatus = statusMap[oneItem.subStatus];
}

if (!statusMap[oneItem.currentStatus])
console.log(
"%s status of %s not mapped!",
oneItem.pk,
oneItem.currentStatus
);
else {
oneItem.currentStatus = statusMap[oneItem.currentStatus];
if (
oneItem.currentStatus !== Workflow.ONEMAC_STATUS.INACTIVATED
)
promiseItems.push(oneItem);
}
});
params.ExclusiveStartKey = results.LastEvaluatedKey;
} while (params.ExclusiveStartKey);
return promiseItems;
})
).then((values) => {
return values.flat();
});
})
.catch((error) => {
console.log("error is: ", error);
return error;
});
if (!statusMap[oneItem.currentStatus])
console.log(
"%s status of %s not mapped!",
oneItem.pk,
oneItem.currentStatus
);
else {
oneItem.currentStatus = statusMap[oneItem.currentStatus];
if (oneItem.currentStatus !== Workflow.ONEMAC_STATUS.INACTIVATED)
promiseItems.push(oneItem);
}
}
params.ExclusiveStartKey = results.LastEvaluatedKey;
} while (params.ExclusiveStartKey);

allItems.push(...promiseItems);
}

return allItems; // Flattened list of all items
} catch (error) {
console.log("error is: ", error);
return error;
}
};

// get the approver list for a rols and possibly a territory
Expand Down
Loading
Loading