fix: fix remaining problems with recent plan changes
This commit is contained in:
@@ -367,6 +367,22 @@ export function didInfo(
|
|||||||
return didInfoForContact(did, activeDid, contact, allMyDids).displayName;
|
return didInfoForContact(did, activeDid, contact, allMyDids).displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In some contexts (eg. agent), a blank really is nobody.
|
||||||
|
*/
|
||||||
|
export function didInfoOrNobody(
|
||||||
|
did: string | undefined,
|
||||||
|
activeDid: string | undefined,
|
||||||
|
allMyDids: string[],
|
||||||
|
contacts: Contact[],
|
||||||
|
): string {
|
||||||
|
if (did == null) {
|
||||||
|
return "Nobody";
|
||||||
|
} else {
|
||||||
|
return didInfo(did, activeDid, allMyDids, contacts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return text description without any references to "you" as user
|
* return text description without any references to "you" as user
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -255,6 +255,7 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else>The changes did not affect essential project data.</div>
|
||||||
<!-- New line that appears on hover -->
|
<!-- New line that appears on hover -->
|
||||||
<div
|
<div
|
||||||
class="absolute left-0 w-full text-left text-gray-500 text-sm hidden group-hover:flex cursor-pointer items-center"
|
class="absolute left-0 w-full text-left text-gray-500 text-sm hidden group-hover:flex cursor-pointer items-center"
|
||||||
@@ -290,6 +291,7 @@ import {
|
|||||||
} from "../interfaces/records";
|
} from "../interfaces/records";
|
||||||
import {
|
import {
|
||||||
didInfo,
|
didInfo,
|
||||||
|
didInfoOrNobody,
|
||||||
displayAmount,
|
displayAmount,
|
||||||
getNewOffersToUser,
|
getNewOffersToUser,
|
||||||
getNewOffersToUserProjects,
|
getNewOffersToUserProjects,
|
||||||
@@ -413,7 +415,7 @@ export default class NewActivityView extends Vue {
|
|||||||
async expandOffersToUserAndMarkRead() {
|
async expandOffersToUserAndMarkRead() {
|
||||||
this.showOffersDetails = !this.showOffersDetails;
|
this.showOffersDetails = !this.showOffersDetails;
|
||||||
if (this.showOffersDetails) {
|
if (this.showOffersDetails) {
|
||||||
await this.$updateSettings({
|
await this.$saveUserSettings(this.activeDid, {
|
||||||
lastAckedOfferToUserJwtId: this.newOffersToUser[0].jwtId,
|
lastAckedOfferToUserJwtId: this.newOffersToUser[0].jwtId,
|
||||||
});
|
});
|
||||||
// note that we don't update this.lastAckedOfferToUserJwtId in case they
|
// note that we don't update this.lastAckedOfferToUserJwtId in case they
|
||||||
@@ -431,12 +433,12 @@ export default class NewActivityView extends Vue {
|
|||||||
);
|
);
|
||||||
if (index !== -1 && index < this.newOffersToUser.length - 1) {
|
if (index !== -1 && index < this.newOffersToUser.length - 1) {
|
||||||
// Set to the next offer's jwtId
|
// Set to the next offer's jwtId
|
||||||
await this.$updateSettings({
|
await this.$saveUserSettings(this.activeDid, {
|
||||||
lastAckedOfferToUserJwtId: this.newOffersToUser[index + 1].jwtId,
|
lastAckedOfferToUserJwtId: this.newOffersToUser[index + 1].jwtId,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// it's the last entry (or not found), so just keep it the same
|
// it's the last entry (or not found), so just keep it the same
|
||||||
await this.$updateSettings({
|
await this.$saveUserSettings(this.activeDid, {
|
||||||
lastAckedOfferToUserJwtId: this.lastAckedOfferToUserJwtId,
|
lastAckedOfferToUserJwtId: this.lastAckedOfferToUserJwtId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -450,7 +452,7 @@ export default class NewActivityView extends Vue {
|
|||||||
this.showOffersToUserProjectsDetails =
|
this.showOffersToUserProjectsDetails =
|
||||||
!this.showOffersToUserProjectsDetails;
|
!this.showOffersToUserProjectsDetails;
|
||||||
if (this.showOffersToUserProjectsDetails) {
|
if (this.showOffersToUserProjectsDetails) {
|
||||||
await this.$updateSettings({
|
await this.$saveUserSettings(this.activeDid, {
|
||||||
lastAckedOfferToUserProjectsJwtId:
|
lastAckedOfferToUserProjectsJwtId:
|
||||||
this.newOffersToUserProjects[0].jwtId,
|
this.newOffersToUserProjects[0].jwtId,
|
||||||
});
|
});
|
||||||
@@ -469,13 +471,13 @@ export default class NewActivityView extends Vue {
|
|||||||
);
|
);
|
||||||
if (index !== -1 && index < this.newOffersToUserProjects.length - 1) {
|
if (index !== -1 && index < this.newOffersToUserProjects.length - 1) {
|
||||||
// Set to the next offer's jwtId
|
// Set to the next offer's jwtId
|
||||||
await this.$updateSettings({
|
await this.$saveUserSettings(this.activeDid, {
|
||||||
lastAckedOfferToUserProjectsJwtId:
|
lastAckedOfferToUserProjectsJwtId:
|
||||||
this.newOffersToUserProjects[index + 1].jwtId,
|
this.newOffersToUserProjects[index + 1].jwtId,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// it's the last entry (or not found), so just keep it the same
|
// it's the last entry (or not found), so just keep it the same
|
||||||
await this.$updateSettings({
|
await this.$saveUserSettings(this.activeDid, {
|
||||||
lastAckedOfferToUserProjectsJwtId:
|
lastAckedOfferToUserProjectsJwtId:
|
||||||
this.lastAckedOfferToUserProjectsJwtId,
|
this.lastAckedOfferToUserProjectsJwtId,
|
||||||
});
|
});
|
||||||
@@ -493,7 +495,7 @@ export default class NewActivityView extends Vue {
|
|||||||
this.showStarredProjectChangesDetails &&
|
this.showStarredProjectChangesDetails &&
|
||||||
this.newStarredProjectChanges.length > 0
|
this.newStarredProjectChanges.length > 0
|
||||||
) {
|
) {
|
||||||
await this.$updateSettings({
|
await this.$saveUserSettings(this.activeDid, {
|
||||||
lastAckedStarredProjectChangesJwtId:
|
lastAckedStarredProjectChangesJwtId:
|
||||||
this.newStarredProjectChanges[0].plan.jwtId,
|
this.newStarredProjectChanges[0].plan.jwtId,
|
||||||
});
|
});
|
||||||
@@ -510,13 +512,13 @@ export default class NewActivityView extends Vue {
|
|||||||
);
|
);
|
||||||
if (index !== -1 && index < this.newStarredProjectChanges.length - 1) {
|
if (index !== -1 && index < this.newStarredProjectChanges.length - 1) {
|
||||||
// Set to the next change's jwtId
|
// Set to the next change's jwtId
|
||||||
await this.$updateSettings({
|
await this.$saveUserSettings(this.activeDid, {
|
||||||
lastAckedStarredProjectChangesJwtId:
|
lastAckedStarredProjectChangesJwtId:
|
||||||
this.newStarredProjectChanges[index + 1].plan.jwtId,
|
this.newStarredProjectChanges[index + 1].plan.jwtId,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// it's the last entry (or not found), so just keep it the same
|
// it's the last entry (or not found), so just keep it the same
|
||||||
await this.$updateSettings({
|
await this.$saveUserSettings(this.activeDid, {
|
||||||
lastAckedStarredProjectChangesJwtId:
|
lastAckedStarredProjectChangesJwtId:
|
||||||
this.lastAckedStarredProjectChangesJwtId,
|
this.lastAckedStarredProjectChangesJwtId,
|
||||||
});
|
});
|
||||||
@@ -527,19 +529,6 @@ export default class NewActivityView extends Vue {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Normalizes values for comparison - treats null, undefined, and empty string as equivalent
|
|
||||||
*
|
|
||||||
* @param value The value to normalize
|
|
||||||
* @returns The normalized value (null for null/undefined/empty, otherwise the original value)
|
|
||||||
*/
|
|
||||||
normalizeValueForComparison(value: unknown): unknown {
|
|
||||||
if (value === null || value === undefined || value === "") {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Analyzes differences between current plans and their previous claims
|
* Analyzes differences between current plans and their previous claims
|
||||||
*
|
*
|
||||||
@@ -554,7 +543,6 @@ export default class NewActivityView extends Vue {
|
|||||||
this.planDifferences = {};
|
this.planDifferences = {};
|
||||||
|
|
||||||
for (const planChange of planChanges) {
|
for (const planChange of planChanges) {
|
||||||
console.log("planChange", planChange);
|
|
||||||
const currentPlan: PlanSummaryRecord = planChange.plan;
|
const currentPlan: PlanSummaryRecord = planChange.plan;
|
||||||
const wrappedClaim: GenericCredWrapper<PlanActionClaim> =
|
const wrappedClaim: GenericCredWrapper<PlanActionClaim> =
|
||||||
planChange.wrappedClaimBefore;
|
planChange.wrappedClaimBefore;
|
||||||
@@ -562,7 +550,7 @@ export default class NewActivityView extends Vue {
|
|||||||
// Extract the actual claim from the wrapped claim
|
// Extract the actual claim from the wrapped claim
|
||||||
let previousClaim: PlanActionClaim;
|
let previousClaim: PlanActionClaim;
|
||||||
|
|
||||||
const embeddedClaim: string = wrappedClaim.claim;
|
const embeddedClaim: PlanActionClaim = wrappedClaim.claim;
|
||||||
if (
|
if (
|
||||||
embeddedClaim &&
|
embeddedClaim &&
|
||||||
typeof embeddedClaim === "object" &&
|
typeof embeddedClaim === "object" &&
|
||||||
@@ -611,10 +599,14 @@ export default class NewActivityView extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compare location (combine latitude and longitude into one row)
|
// Compare location (combine latitude and longitude into one row)
|
||||||
const oldLat = previousClaim.location?.geo?.latitude;
|
const oldLat = this.normalizeValueForComparison(
|
||||||
const oldLon = previousClaim.location?.geo?.longitude;
|
previousClaim.location?.geo?.latitude,
|
||||||
const newLat = currentPlan.locLat;
|
);
|
||||||
const newLon = currentPlan.locLon;
|
const oldLon = this.normalizeValueForComparison(
|
||||||
|
previousClaim.location?.geo?.longitude,
|
||||||
|
);
|
||||||
|
const newLat = this.normalizeValueForComparison(currentPlan.locLat);
|
||||||
|
const newLon = this.normalizeValueForComparison(currentPlan.locLon);
|
||||||
|
|
||||||
if (!R.equals(oldLat, newLat) || !R.equals(oldLon, newLon)) {
|
if (!R.equals(oldLat, newLat) || !R.equals(oldLon, newLon)) {
|
||||||
differences.location = {
|
differences.location = {
|
||||||
@@ -624,8 +616,18 @@ export default class NewActivityView extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compare agent (issuer)
|
// Compare agent (issuer)
|
||||||
const oldAgent = previousClaim.agent?.identifier;
|
const oldAgent = didInfoOrNobody(
|
||||||
const newAgent = currentPlan.agentDid;
|
previousClaim.agent?.identifier,
|
||||||
|
this.activeDid,
|
||||||
|
this.allMyDids,
|
||||||
|
this.allContacts,
|
||||||
|
);
|
||||||
|
const newAgent = didInfoOrNobody(
|
||||||
|
currentPlan.agentDid,
|
||||||
|
this.activeDid,
|
||||||
|
this.allMyDids,
|
||||||
|
this.allContacts,
|
||||||
|
);
|
||||||
const normalizedOldAgent = this.normalizeValueForComparison(oldAgent);
|
const normalizedOldAgent = this.normalizeValueForComparison(oldAgent);
|
||||||
const normalizedNewAgent = this.normalizeValueForComparison(newAgent);
|
const normalizedNewAgent = this.normalizeValueForComparison(newAgent);
|
||||||
if (!R.equals(normalizedOldAgent, normalizedNewAgent)) {
|
if (!R.equals(normalizedOldAgent, normalizedNewAgent)) {
|
||||||
@@ -639,9 +641,9 @@ export default class NewActivityView extends Vue {
|
|||||||
const oldStartTime = previousClaim.startTime;
|
const oldStartTime = previousClaim.startTime;
|
||||||
const newStartTime = currentPlan.startTime;
|
const newStartTime = currentPlan.startTime;
|
||||||
const normalizedOldStartTime =
|
const normalizedOldStartTime =
|
||||||
this.normalizeValueForComparison(oldStartTime);
|
this.normalizeDateForComparison(oldStartTime);
|
||||||
const normalizedNewStartTime =
|
const normalizedNewStartTime =
|
||||||
this.normalizeValueForComparison(newStartTime);
|
this.normalizeDateForComparison(newStartTime);
|
||||||
if (!R.equals(normalizedOldStartTime, normalizedNewStartTime)) {
|
if (!R.equals(normalizedOldStartTime, normalizedNewStartTime)) {
|
||||||
differences.startTime = {
|
differences.startTime = {
|
||||||
old: oldStartTime,
|
old: oldStartTime,
|
||||||
@@ -652,8 +654,8 @@ export default class NewActivityView extends Vue {
|
|||||||
// Compare end time
|
// Compare end time
|
||||||
const oldEndTime = previousClaim.endTime;
|
const oldEndTime = previousClaim.endTime;
|
||||||
const newEndTime = currentPlan.endTime;
|
const newEndTime = currentPlan.endTime;
|
||||||
const normalizedOldEndTime = this.normalizeValueForComparison(oldEndTime);
|
const normalizedOldEndTime = this.normalizeDateForComparison(oldEndTime);
|
||||||
const normalizedNewEndTime = this.normalizeValueForComparison(newEndTime);
|
const normalizedNewEndTime = this.normalizeDateForComparison(newEndTime);
|
||||||
if (!R.equals(normalizedOldEndTime, normalizedNewEndTime)) {
|
if (!R.equals(normalizedOldEndTime, normalizedNewEndTime)) {
|
||||||
differences.endTime = {
|
differences.endTime = {
|
||||||
old: oldEndTime,
|
old: oldEndTime,
|
||||||
@@ -705,6 +707,38 @@ export default class NewActivityView extends Vue {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes values for comparison - treats null, undefined, and empty string as equivalent
|
||||||
|
*
|
||||||
|
* @param value The value to normalize
|
||||||
|
* @returns The normalized value (null for null/undefined/empty, otherwise the original value)
|
||||||
|
*/
|
||||||
|
normalizeValueForComparison<T>(value: T | null | undefined): T | null {
|
||||||
|
if (value === null || value === undefined || value === "") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes date values for comparison by converting strings to Date objects
|
||||||
|
* Returns null for null/undefined/empty values, Date objects for valid date strings
|
||||||
|
*/
|
||||||
|
normalizeDateForComparison(value: unknown): Date | null {
|
||||||
|
if (value === null || value === undefined || value === "") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (typeof value === "string") {
|
||||||
|
const date = new Date(value);
|
||||||
|
// Check if the date is valid
|
||||||
|
return isNaN(date.getTime()) ? null : date;
|
||||||
|
}
|
||||||
|
if (value instanceof Date) {
|
||||||
|
return isNaN(value.getTime()) ? null : value;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the differences for a specific plan by handle ID
|
* Gets the differences for a specific plan by handle ID
|
||||||
*
|
*
|
||||||
@@ -817,11 +851,11 @@ export default class NewActivityView extends Vue {
|
|||||||
* @returns A formatted location string
|
* @returns A formatted location string
|
||||||
*/
|
*/
|
||||||
formatLocationValue(
|
formatLocationValue(
|
||||||
latitude: number | undefined,
|
latitude: number | undefined | null,
|
||||||
longitude: number | undefined,
|
longitude: number | undefined | null,
|
||||||
isOldValue: boolean = false,
|
isOldValue: boolean = false,
|
||||||
): string {
|
): string {
|
||||||
if (latitude === undefined && longitude === undefined) {
|
if (latitude == null && longitude == null) {
|
||||||
return "Not set";
|
return "Not set";
|
||||||
}
|
}
|
||||||
// If there's any location data, show generic labels instead of coordinates
|
// If there's any location data, show generic labels instead of coordinates
|
||||||
|
|||||||
Reference in New Issue
Block a user