feat: add a notification for changes to starred projects
This commit is contained in:
@@ -144,6 +144,73 @@
|
||||
</li>
|
||||
</ul>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
@@ -159,17 +226,20 @@ import { Router } from "vue-router";
|
||||
import {
|
||||
OfferSummaryRecord,
|
||||
OfferToPlanSummaryRecord,
|
||||
PlanSummaryAndPreviousClaim,
|
||||
} from "../interfaces/records";
|
||||
import {
|
||||
didInfo,
|
||||
displayAmount,
|
||||
getNewOffersToUser,
|
||||
getNewOffersToUserProjects,
|
||||
getStarredProjectsWithChanges,
|
||||
} from "../libs/endorserServer";
|
||||
import { retrieveAccountDids } from "../libs/util";
|
||||
import { logger } from "../utils/logger";
|
||||
import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin";
|
||||
import { createNotifyHelpers, TIMEOUTS } from "@/utils/notify";
|
||||
import * as databaseUtil from "../db/databaseUtil";
|
||||
|
||||
@Component({
|
||||
components: { GiftedDialog, QuickNav, EntityIcon },
|
||||
@@ -186,13 +256,18 @@ export default class NewActivityView extends Vue {
|
||||
apiServer = "";
|
||||
lastAckedOfferToUserJwtId = "";
|
||||
lastAckedOfferToUserProjectsJwtId = "";
|
||||
lastAckedStarredProjectChangesJwtId = "";
|
||||
newOffersToUser: Array<OfferSummaryRecord> = [];
|
||||
newOffersToUserHitLimit = false;
|
||||
newOffersToUserProjects: Array<OfferToPlanSummaryRecord> = [];
|
||||
newOffersToUserProjectsHitLimit = false;
|
||||
newStarredProjectChanges: Array<PlanSummaryAndPreviousClaim> = [];
|
||||
newStarredProjectChangesHitLimit = false;
|
||||
starredProjectIds: Array<string> = [];
|
||||
|
||||
showOffersDetails = false;
|
||||
showOffersToUserProjectsDetails = false;
|
||||
showStarredProjectChangesDetails = false;
|
||||
didInfo = didInfo;
|
||||
displayAmount = displayAmount;
|
||||
|
||||
@@ -206,6 +281,12 @@ export default class NewActivityView extends Vue {
|
||||
this.lastAckedOfferToUserJwtId = settings.lastAckedOfferToUserJwtId || "";
|
||||
this.lastAckedOfferToUserProjectsJwtId =
|
||||
settings.lastAckedOfferToUserProjectsJwtId || "";
|
||||
this.lastAckedStarredProjectChangesJwtId =
|
||||
settings.lastAckedStarredProjectChangesJwtId || "";
|
||||
this.starredProjectIds = databaseUtil.parseJsonField(
|
||||
settings.starredProjectIds,
|
||||
[],
|
||||
);
|
||||
|
||||
this.allContacts = await this.$getAllContacts();
|
||||
|
||||
@@ -229,6 +310,26 @@ export default class NewActivityView extends Vue {
|
||||
this.newOffersToUserProjects = offersToUserProjectsData.data;
|
||||
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
|
||||
} catch (err: any) {
|
||||
logger.error("Error retrieving settings & contacts:", err);
|
||||
@@ -314,5 +415,46 @@ export default class NewActivityView extends Vue {
|
||||
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>
|
||||
|
||||
Reference in New Issue
Block a user