|
@ -144,6 +144,73 @@ |
|
|
</li> |
|
|
</li> |
|
|
</ul> |
|
|
</ul> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<!-- Starred Projects with Changes Section --> |
|
|
|
|
|
<div |
|
|
|
|
|
class="flex justify-between mt-6" |
|
|
|
|
|
data-testId="showStarredProjectChanges" |
|
|
|
|
|
> |
|
|
|
|
|
<div> |
|
|
|
|
|
<span class="text-lg font-medium" |
|
|
|
|
|
>{{ newStarredProjectChanges.length |
|
|
|
|
|
}}{{ newStarredProjectChangesHitLimit ? "+" : "" }}</span |
|
|
|
|
|
> |
|
|
|
|
|
<span class="text-lg font-medium ml-4" |
|
|
|
|
|
>Starred Project{{ |
|
|
|
|
|
newStarredProjectChanges.length === 1 ? "" : "s" |
|
|
|
|
|
}} |
|
|
|
|
|
With Changes</span |
|
|
|
|
|
> |
|
|
|
|
|
<font-awesome |
|
|
|
|
|
v-if="newStarredProjectChanges.length > 0" |
|
|
|
|
|
:icon=" |
|
|
|
|
|
showStarredProjectChangesDetails ? 'chevron-down' : 'chevron-right' |
|
|
|
|
|
" |
|
|
|
|
|
class="cursor-pointer ml-4 mr-4 text-lg" |
|
|
|
|
|
@click="expandStarredProjectChangesAndMarkRead()" |
|
|
|
|
|
/> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div v-if="showStarredProjectChangesDetails" class="ml-4 mt-4"> |
|
|
|
|
|
<ul class="list-disc ml-4"> |
|
|
|
|
|
<li |
|
|
|
|
|
v-for="projectChange in newStarredProjectChanges" |
|
|
|
|
|
:key="projectChange.plan.handleId" |
|
|
|
|
|
class="mt-4 relative group" |
|
|
|
|
|
> |
|
|
|
|
|
<span class="font-medium">{{ |
|
|
|
|
|
projectChange.plan.name || "Unnamed Project" |
|
|
|
|
|
}}</span> |
|
|
|
|
|
<span v-if="projectChange.plan.description" class="text-gray-600"> |
|
|
|
|
|
- {{ projectChange.plan.description }} |
|
|
|
|
|
</span> |
|
|
|
|
|
<router-link |
|
|
|
|
|
:to="{ |
|
|
|
|
|
path: '/plan/' + encodeURIComponent(projectChange.plan.handleId), |
|
|
|
|
|
}" |
|
|
|
|
|
class="text-blue-500" |
|
|
|
|
|
> |
|
|
|
|
|
<font-awesome |
|
|
|
|
|
icon="external-link-alt" |
|
|
|
|
|
class="pl-2 text-blue-500 cursor-pointer" |
|
|
|
|
|
/> |
|
|
|
|
|
</router-link> |
|
|
|
|
|
<!-- New line that appears on hover --> |
|
|
|
|
|
<div |
|
|
|
|
|
class="absolute left-0 w-full text-left text-gray-500 text-sm hidden group-hover:flex cursor-pointer items-center" |
|
|
|
|
|
@click=" |
|
|
|
|
|
markStarredProjectChangesAsReadStartingWith( |
|
|
|
|
|
projectChange.plan.handleId, |
|
|
|
|
|
) |
|
|
|
|
|
" |
|
|
|
|
|
> |
|
|
|
|
|
<span class="inline-block w-8 h-px bg-gray-500 mr-2" /> |
|
|
|
|
|
Click to keep all above as new changes |
|
|
|
|
|
</div> |
|
|
|
|
|
</li> |
|
|
|
|
|
</ul> |
|
|
|
|
|
</div> |
|
|
</section> |
|
|
</section> |
|
|
</template> |
|
|
</template> |
|
|
|
|
|
|
|
@ -159,17 +226,20 @@ import { Router } from "vue-router"; |
|
|
import { |
|
|
import { |
|
|
OfferSummaryRecord, |
|
|
OfferSummaryRecord, |
|
|
OfferToPlanSummaryRecord, |
|
|
OfferToPlanSummaryRecord, |
|
|
|
|
|
PlanSummaryAndPreviousClaim, |
|
|
} from "../interfaces/records"; |
|
|
} from "../interfaces/records"; |
|
|
import { |
|
|
import { |
|
|
didInfo, |
|
|
didInfo, |
|
|
displayAmount, |
|
|
displayAmount, |
|
|
getNewOffersToUser, |
|
|
getNewOffersToUser, |
|
|
getNewOffersToUserProjects, |
|
|
getNewOffersToUserProjects, |
|
|
|
|
|
getStarredProjectsWithChanges, |
|
|
} from "../libs/endorserServer"; |
|
|
} from "../libs/endorserServer"; |
|
|
import { retrieveAccountDids } from "../libs/util"; |
|
|
import { retrieveAccountDids } from "../libs/util"; |
|
|
import { logger } from "../utils/logger"; |
|
|
import { logger } from "../utils/logger"; |
|
|
import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin"; |
|
|
import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin"; |
|
|
import { createNotifyHelpers, TIMEOUTS } from "@/utils/notify"; |
|
|
import { createNotifyHelpers, TIMEOUTS } from "@/utils/notify"; |
|
|
|
|
|
import * as databaseUtil from "../db/databaseUtil"; |
|
|
|
|
|
|
|
|
@Component({ |
|
|
@Component({ |
|
|
components: { GiftedDialog, QuickNav, EntityIcon }, |
|
|
components: { GiftedDialog, QuickNav, EntityIcon }, |
|
@ -186,13 +256,18 @@ export default class NewActivityView extends Vue { |
|
|
apiServer = ""; |
|
|
apiServer = ""; |
|
|
lastAckedOfferToUserJwtId = ""; |
|
|
lastAckedOfferToUserJwtId = ""; |
|
|
lastAckedOfferToUserProjectsJwtId = ""; |
|
|
lastAckedOfferToUserProjectsJwtId = ""; |
|
|
|
|
|
lastAckedStarredProjectChangesJwtId = ""; |
|
|
newOffersToUser: Array<OfferSummaryRecord> = []; |
|
|
newOffersToUser: Array<OfferSummaryRecord> = []; |
|
|
newOffersToUserHitLimit = false; |
|
|
newOffersToUserHitLimit = false; |
|
|
newOffersToUserProjects: Array<OfferToPlanSummaryRecord> = []; |
|
|
newOffersToUserProjects: Array<OfferToPlanSummaryRecord> = []; |
|
|
newOffersToUserProjectsHitLimit = false; |
|
|
newOffersToUserProjectsHitLimit = false; |
|
|
|
|
|
newStarredProjectChanges: Array<PlanSummaryAndPreviousClaim> = []; |
|
|
|
|
|
newStarredProjectChangesHitLimit = false; |
|
|
|
|
|
starredProjectIds: Array<string> = []; |
|
|
|
|
|
|
|
|
showOffersDetails = false; |
|
|
showOffersDetails = false; |
|
|
showOffersToUserProjectsDetails = false; |
|
|
showOffersToUserProjectsDetails = false; |
|
|
|
|
|
showStarredProjectChangesDetails = false; |
|
|
didInfo = didInfo; |
|
|
didInfo = didInfo; |
|
|
displayAmount = displayAmount; |
|
|
displayAmount = displayAmount; |
|
|
|
|
|
|
|
@ -206,6 +281,12 @@ export default class NewActivityView extends Vue { |
|
|
this.lastAckedOfferToUserJwtId = settings.lastAckedOfferToUserJwtId || ""; |
|
|
this.lastAckedOfferToUserJwtId = settings.lastAckedOfferToUserJwtId || ""; |
|
|
this.lastAckedOfferToUserProjectsJwtId = |
|
|
this.lastAckedOfferToUserProjectsJwtId = |
|
|
settings.lastAckedOfferToUserProjectsJwtId || ""; |
|
|
settings.lastAckedOfferToUserProjectsJwtId || ""; |
|
|
|
|
|
this.lastAckedStarredProjectChangesJwtId = |
|
|
|
|
|
settings.lastAckedStarredProjectChangesJwtId || ""; |
|
|
|
|
|
this.starredProjectIds = databaseUtil.parseJsonField( |
|
|
|
|
|
settings.starredProjectIds, |
|
|
|
|
|
[], |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
this.allContacts = await this.$getAllContacts(); |
|
|
this.allContacts = await this.$getAllContacts(); |
|
|
|
|
|
|
|
@ -229,6 +310,26 @@ export default class NewActivityView extends Vue { |
|
|
this.newOffersToUserProjects = offersToUserProjectsData.data; |
|
|
this.newOffersToUserProjects = offersToUserProjectsData.data; |
|
|
this.newOffersToUserProjectsHitLimit = offersToUserProjectsData.hitLimit; |
|
|
this.newOffersToUserProjectsHitLimit = offersToUserProjectsData.hitLimit; |
|
|
|
|
|
|
|
|
|
|
|
// Load starred project changes if user has starred projects |
|
|
|
|
|
if (this.starredProjectIds.length > 0) { |
|
|
|
|
|
try { |
|
|
|
|
|
const starredProjectChangesData = await getStarredProjectsWithChanges( |
|
|
|
|
|
this.axios, |
|
|
|
|
|
this.apiServer, |
|
|
|
|
|
this.activeDid, |
|
|
|
|
|
this.starredProjectIds, |
|
|
|
|
|
this.lastAckedStarredProjectChangesJwtId, |
|
|
|
|
|
); |
|
|
|
|
|
this.newStarredProjectChanges = starredProjectChangesData.data; |
|
|
|
|
|
this.newStarredProjectChangesHitLimit = |
|
|
|
|
|
starredProjectChangesData.hitLimit; |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
logger.warn("Failed to load starred project changes:", error); |
|
|
|
|
|
this.newStarredProjectChanges = []; |
|
|
|
|
|
this.newStarredProjectChangesHitLimit = false; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any |
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any |
|
|
} catch (err: any) { |
|
|
} catch (err: any) { |
|
|
logger.error("Error retrieving settings & contacts:", err); |
|
|
logger.error("Error retrieving settings & contacts:", err); |
|
@ -314,5 +415,46 @@ export default class NewActivityView extends Vue { |
|
|
TIMEOUTS.STANDARD, |
|
|
TIMEOUTS.STANDARD, |
|
|
); |
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async expandStarredProjectChangesAndMarkRead() { |
|
|
|
|
|
this.showStarredProjectChangesDetails = |
|
|
|
|
|
!this.showStarredProjectChangesDetails; |
|
|
|
|
|
if ( |
|
|
|
|
|
this.showStarredProjectChangesDetails && |
|
|
|
|
|
this.newStarredProjectChanges.length > 0 |
|
|
|
|
|
) { |
|
|
|
|
|
await this.$updateSettings({ |
|
|
|
|
|
lastAckedStarredProjectChangesJwtId: |
|
|
|
|
|
this.newStarredProjectChanges[0].plan.jwtId, |
|
|
|
|
|
}); |
|
|
|
|
|
this.notify.info( |
|
|
|
|
|
"The starred project changes are now marked as viewed. Click in the list to keep them as new.", |
|
|
|
|
|
TIMEOUTS.LONG, |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async markStarredProjectChangesAsReadStartingWith(jwtId: string) { |
|
|
|
|
|
const index = this.newStarredProjectChanges.findIndex( |
|
|
|
|
|
(change) => change.plan.jwtId === jwtId, |
|
|
|
|
|
); |
|
|
|
|
|
if (index !== -1 && index < this.newStarredProjectChanges.length - 1) { |
|
|
|
|
|
// Set to the next change's jwtId |
|
|
|
|
|
await this.$updateSettings({ |
|
|
|
|
|
lastAckedStarredProjectChangesJwtId: |
|
|
|
|
|
this.newStarredProjectChanges[index + 1].plan.jwtId, |
|
|
|
|
|
}); |
|
|
|
|
|
} else { |
|
|
|
|
|
// it's the last entry (or not found), so just keep it the same |
|
|
|
|
|
await this.$updateSettings({ |
|
|
|
|
|
lastAckedStarredProjectChangesJwtId: |
|
|
|
|
|
this.lastAckedStarredProjectChangesJwtId, |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
this.notify.info( |
|
|
|
|
|
"All starred project changes above that line are marked as unread.", |
|
|
|
|
|
TIMEOUTS.STANDARD, |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
</script> |
|
|
</script> |
|
|