Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Basi-mohd committed Nov 25, 2024
2 parents 0e96522 + 7bc260c commit fd2de5a
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export class AnnouncementService {
return this.http.post<any>(`${this.apiUrl}/announcement/addAnnouncement`, data);
}

getAnnouncement(page: number, row: number): Observable<{ total: number, announcements: announcementGetData[] }> {
return this.http.get<{ total: number, announcements: announcementGetData[] }>(`${this.apiUrl}/announcement/getAnnouncement?page=${page}&row=${row}`);
getAnnouncement(page: number, row: number,userCategoryId : string,userId : string): Observable<{ total: number, announcements: announcementGetData[] }> {
return this.http.get<{ total: number, announcements: announcementGetData[] }>(`${this.apiUrl}/announcement/getAnnouncement?page=${page}&row=${row}&userCategoryId=${userCategoryId}&userId=${userId}`);
}

markAsViewed(announcementId: string, userId: string): Observable<any> {
Expand Down
1 change: 0 additions & 1 deletion client/src/app/modules/home/home.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import { HalfDoughnutChartComponent } from 'src/app/shared/components/charts/hal
import { LineChartComponent } from 'src/app/shared/components/charts/line-chart/line-chart.component';
import { pipeModule } from "../../shared/pipes/pipe.module";
import { NumberShortenerPipe } from 'src/app/shared/pipes/numberShortener.pipe';
import { MatTooltipModule } from '@angular/material/tooltip';

@NgModule({
declarations: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,28 @@ <h3 class="text-md font-medium">Create Announcement</h3>
</div>

</div>
<div class="flex flex-wrap -mx-3 mb-2">
<div class="w-full px-3">
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-password">
Categories
</label>
<ng-select id="category"
class="filter"
placeholder="Select category"
appendTo="body"
[formControlName]="'category'"
[multiple]="true"
bindLabel="categoryName"
(change)="onCategoryChange($event)">
<ng-option [value]="'all'">For all users</ng-option>
<ng-option *ngFor="let category of categories"
[value]="category._id">{{category.categoryName}}</ng-option>
</ng-select>
</div>
<div class="text-gray-700 text-sm mt-[1px] ml-3" >
Default category is for all users,make sure that you have selected the categories properly.
</div>
</div>
<div class="flex flex-wrap -mx-3 mb-2">
<div class="w-full px-3">
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-password">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,25 @@ import { IconsModule } from 'src/app/lib/icons/icons.module';
import { CreateCustomerDialog } from 'src/app/modules/customers/pages/create-customer/create-customer.component';
import { directiveSharedModule } from 'src/app/shared/directives/directives.module';
import { announcementGetData, announcementPostData } from 'src/app/shared/interfaces/announcement.interface';
import { GetCategory } from 'src/app/shared/interfaces/employee.interface';
import { NgSelectModule } from '@ng-select/ng-select';


@Component({
selector: 'app-add-announcement',
templateUrl: './add-announcement.component.html',
styleUrls: ['./add-announcement.component.css'],
standalone: true,
imports: [CommonModule, IconsModule, directiveSharedModule, ReactiveFormsModule, FormsModule],
imports: [CommonModule, IconsModule, directiveSharedModule, ReactiveFormsModule, FormsModule , NgSelectModule],
})
export class AddAnnouncementComponent implements OnDestroy, OnInit {
submit: boolean = false;
isSaving: boolean = false;
userId!: any;
categories: GetCategory[] = [];
isEdit: boolean = false;


private mySubscription!: Subscription;

constructor(
Expand All @@ -42,20 +47,30 @@ export class AddAnnouncementComponent implements OnDestroy, OnInit {
this.userId = res;
});

this.getCategory();

if (this.data?.data) {
this.isEdit = true;
this.formData.patchValue({
title: this.data.data.title,
description: this.data.data.description,
date: this.data.data.date
date: this.data.data.date,
category: this.data.data.category
});
}
}

getCategory(){
this._employeeService.getCategory().subscribe((res)=>{
this.categories = res;
})
}

formData = this.fb.group({
title: ['', Validators.required],
description: ['', Validators.required],
date: [new Date(), Validators.required]
date: [new Date(), Validators.required],
category: [['all']]
});

onSubmit() {
Expand All @@ -69,9 +84,10 @@ export class AddAnnouncementComponent implements OnDestroy, OnInit {
date: this.formData.value.date as Date | null,
userId: this.userId._id,
isEdit: this.isEdit,
_id: this.isEdit ? this.data.data?._id : undefined
_id: this.isEdit ? this.data.data?._id : undefined,
category: this.formData.value.category as string[]
};

this.mySubscription = this._service.createAnnouncement(data).subscribe({
next: (res: any) => {
if (res.success) {
Expand All @@ -98,6 +114,27 @@ export class AddAnnouncementComponent implements OnDestroy, OnInit {
this.dialogRef.close();
}

onCategoryChange(event: any) {
const selectedValues = this.formData.get('category')?.value || [];
const previousValues = event.previousValue || [];

// Case 1: If user selects 'all', remove all other categories
if (selectedValues.includes('all') && !previousValues.includes('all')) {
this.formData.patchValue({
category: ['all']
});
return;
}

// Case 2: If 'all' was previously selected and user selects other categories, remove 'all'
if (previousValues.includes('all') && selectedValues.length > 1) {
const filteredValues = selectedValues.filter((value: string) => value !== 'all');
this.formData.patchValue({
category: filteredValues
});
return;
}
}

ngOnDestroy(): void {
this.mySubscription.unsubscribe()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ export class AnnouncementsComponent implements OnDestroy, OnInit, AfterViewInit
total: number = 0;
page: number = 1;
row: number = 10;
userId!: any;
userId!: string;
userCategoryId!: string;

private subject = new BehaviorSubject<{ page: number, row: number }>({ page: this.page, row: this.row });
@ViewChildren('announcementItem') announcementItems!: QueryList<ElementRef>;
Expand Down Expand Up @@ -66,7 +67,7 @@ export class AnnouncementsComponent implements OnDestroy, OnInit, AfterViewInit
}

getAnnouncementData() {
this._service.getAnnouncement(this.page, this.row).pipe(takeUntil(this.destroy$)).subscribe(
this._service.getAnnouncement(this.page, this.row,this.userCategoryId,this.userId).pipe(takeUntil(this.destroy$)).subscribe(
(res: { total: number, announcements: announcementGetData[] }) => {
if (res) {
this.isLoading = false;
Expand Down Expand Up @@ -173,7 +174,8 @@ export class AnnouncementsComponent implements OnDestroy, OnInit, AfterViewInit

checkPermission() {
this._employeeService.employeeData$.pipe(takeUntil(this.destroy$)).subscribe((data) => {
this.userId = data?._id;
this.userId = data?._id || '';
this.userCategoryId = data?.category._id || '';
this.createAnnouncement = data?.category.privileges.announcement.create;
this.deleteOrEditAnnouncement = data?.category.privileges.announcement.deleteOrEdit;
});
Expand Down
3 changes: 3 additions & 0 deletions client/src/app/shared/interfaces/announcement.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export interface announcementPostData {
userId :String | null | undefined;
isEdit: boolean;
_id: string | undefined;
category: string[]
}

export interface announcementGetData {
Expand All @@ -15,6 +16,8 @@ export interface announcementGetData {
createdDate: Date,
celeb: boolean
viewedBy:string[]
category: string[]
createdBy: string
}


80 changes: 60 additions & 20 deletions server/src/controllers/announcement.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,61 @@ import { NextFunction, Request, Response } from "express";
import announcementModel from "../models/announcement.model";
import { Server } from "socket.io";
import { connectedSockets } from "../service/socket-ioService";
const { ObjectId } = require('mongodb');
import employeeModel from "../models/employee.model";
import { Types } from "mongoose";

export const createAnnouncement = async (req: any, res: Response, next: NextFunction) => {
try {
const { title, description, date, userId, isEdit, _id } = req.body;
const { title, description, date, userId, isEdit, _id, category } = req.body;

const announcementDoc = {
title,
date,
description,
celeb: false,
viewedBy: userId ? [userId] : []
viewedBy: userId ? [userId] : [],
category: category.length > 0 ? category : ['all'],
createdDate: new Date(),
createdBy: userId
};

const query = isEdit ? { _id } : { title };

const saveAnnouncement = await announcementModel.findOneAndUpdate(
query,
announcementDoc,
{
upsert: true,
new: true,
setDefaultsOnInsert: true
}
);
let saveAnnouncement;
if (isEdit) {
// Update existing announcement
saveAnnouncement = await announcementModel.findByIdAndUpdate(
_id,
announcementDoc,
{ new: true }
);
} else {
// Create new announcement
saveAnnouncement = await announcementModel.create(announcementDoc);
}

const userData = await employeeModel.find();


if (saveAnnouncement) {
const socket = req.app.get('io') as Server;
const filteredRoom = Object.keys(connectedSockets).filter(key => key !== userId);
filteredRoom.forEach(room => {
socket.to(room).emit("notifications", 'announcement');

// Filter users based on category
const eligibleUsers = userData.filter(user =>
// If announcement is for 'all' or user's category matches announcement category
category.includes('all') || category.some(cat => user.category?.toString() === cat)
);

// Get eligible user IDs and filter out the creator
const eligibleUserIds = eligibleUsers
.map(user => user._id.toString())
.filter(id => id !== userId);

// Emit notifications only to eligible users who are connected
eligibleUserIds.forEach(userId => {
if (connectedSockets[userId]) {
socket.to(userId).emit("notifications", 'announcement');
}
});

return res.status(200).json({ success: true, message: isEdit ? 'Announcement updated' : 'Announcement created' });
}
return res.status(502).json({ success: false, message: 'Failed to save announcement' });
Expand All @@ -47,15 +70,32 @@ export const getAnnouncement = async (req: Request, res: Response, next: NextFun
try {
const page = Number(req.query.page);
const row = Number(req.query.row);
const userCategoryId = req.query.userCategoryId;
const userId = req.query.userId;
const skip = (page - 1) * row;

const pipeline: any[] = [
{
$match: {
$or: [
{ createdBy: new Types.ObjectId(userId as string) },
{ category: { $in: ['all'] } },
{ category: { $in: [userCategoryId] } }
]
}
},
{ $sort: { createdDate: -1 } },
{ $skip: skip },
{ $limit: row },
];

const totalAnnouncements = await announcementModel.countDocuments();
]

const totalAnnouncements = await announcementModel.countDocuments({
$or: [
{ createdBy: new Types.ObjectId(userId as string) },
{ category: { $in: ['all'] } },
{ category: { $in: [userCategoryId] } }
]
});

const announcementData = await announcementModel.aggregate(pipeline);

Expand Down
15 changes: 14 additions & 1 deletion server/src/controllers/employee.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,20 @@ export const getNotificationCounts = async (req: Request, res: Response, next: N
const token = req.params.token
const jwtPayload = jwt.verify(token, process.env.JWT_SECRET)
const userId = (<any>jwtPayload).id
const announcementCount = await announcementModel.countDocuments({ viewedBy: { $ne: new ObjectId(userId) } });

// Get user's category
const employee = await Employee.findById(userId);
const userCategoryId = employee.category;

// Updated announcement count query
const announcementCount = await announcementModel.countDocuments({
viewedBy: { $ne: new ObjectId(userId) },
$or: [
{ category: { $in: ['all'] } },
{ category: { $in: [userCategoryId] } }
]
});

const assignedJobCount = await enquiryModel.countDocuments({
'preSale.presalePerson': new ObjectId(userId),
$or: [
Expand Down
15 changes: 12 additions & 3 deletions server/src/models/announcement.model.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Schema, Document, model } from "mongoose";
import { Schema, Document, model, Types } from "mongoose";

interface announcment extends Document {
title: String
Expand All @@ -7,6 +7,8 @@ interface announcment extends Document {
createdDate: Date,
celeb: boolean
viewedBy: string[]
category: string[]
createdBy: Types.ObjectId
}

const AnnouncementSchema = new Schema<announcment>({
Expand All @@ -19,8 +21,7 @@ const AnnouncementSchema = new Schema<announcment>({
required: true,
},
createdDate: {
type: Date,
default: () => Date.now()
type: Date
},
date: {
type: Date,
Expand All @@ -32,6 +33,14 @@ const AnnouncementSchema = new Schema<announcment>({
},
viewedBy: {
type: [String]
},
category: {
type: [String]
},
createdBy: {
type: Schema.Types.ObjectId,
ref: 'Employee',
required: true
}
});

Expand Down

0 comments on commit fd2de5a

Please sign in to comment.