@posiwise/user-module 0.0.132 → 0.0.134
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -66,7 +66,7 @@ import * as i5$2 from 'primeng/table';
|
|
|
66
66
|
import * as i6$4 from 'primeng/api';
|
|
67
67
|
import moment from 'moment';
|
|
68
68
|
import * as i4$2 from 'primeng/autocomplete';
|
|
69
|
-
import * as i5$3 from 'primeng/
|
|
69
|
+
import * as i5$3 from 'primeng/tabs';
|
|
70
70
|
|
|
71
71
|
class AccountComponent {
|
|
72
72
|
constructor(router) {
|
|
@@ -3112,8 +3112,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
3112
3112
|
}] } });
|
|
3113
3113
|
|
|
3114
3114
|
class UserProfilePageComponent extends AppBaseComponent {
|
|
3115
|
-
|
|
3116
|
-
|
|
3115
|
+
onTabChange(value) {
|
|
3116
|
+
const item = this.items.find(i => i.id === value);
|
|
3117
|
+
if (item) {
|
|
3118
|
+
this.activeItem = item;
|
|
3119
|
+
}
|
|
3117
3120
|
}
|
|
3118
3121
|
constructor(injector, profileService, modalService, scriptLoader) {
|
|
3119
3122
|
super(injector);
|
|
@@ -3146,6 +3149,7 @@ class UserProfilePageComponent extends AppBaseComponent {
|
|
|
3146
3149
|
}
|
|
3147
3150
|
];
|
|
3148
3151
|
[this.activeItem] = this.items;
|
|
3152
|
+
this.activeTabValue = this.activeItem?.id;
|
|
3149
3153
|
}
|
|
3150
3154
|
get allowEdit() {
|
|
3151
3155
|
return (this.loggedInUserDetails?.slug === this.slug || this.permissionService.isSuperAdmin());
|
|
@@ -3249,7 +3253,6 @@ class UserProfilePageComponent extends AppBaseComponent {
|
|
|
3249
3253
|
const maxAttempts = 100; // 10 seconds max wait time
|
|
3250
3254
|
const checkJQuery = () => {
|
|
3251
3255
|
if (window['jQuery']) {
|
|
3252
|
-
console.log('jQuery detected, loading vertical-timeline');
|
|
3253
3256
|
callback();
|
|
3254
3257
|
}
|
|
3255
3258
|
else if (attempts < maxAttempts) {
|
|
@@ -3257,7 +3260,6 @@ class UserProfilePageComponent extends AppBaseComponent {
|
|
|
3257
3260
|
setTimeout(checkJQuery, 100);
|
|
3258
3261
|
}
|
|
3259
3262
|
else {
|
|
3260
|
-
console.log('jQuery not available, loading it now for user profile');
|
|
3261
3263
|
// Load jQuery since it's needed
|
|
3262
3264
|
this.loadJQueryForUserProfile(callback);
|
|
3263
3265
|
}
|
|
@@ -3271,7 +3273,6 @@ class UserProfilePageComponent extends AppBaseComponent {
|
|
|
3271
3273
|
script.crossOrigin = 'anonymous';
|
|
3272
3274
|
script.async = false;
|
|
3273
3275
|
script.onload = () => {
|
|
3274
|
-
console.log('jQuery loaded for user profile');
|
|
3275
3276
|
callback();
|
|
3276
3277
|
};
|
|
3277
3278
|
script.onerror = () => {
|
|
@@ -3282,7 +3283,6 @@ class UserProfilePageComponent extends AppBaseComponent {
|
|
|
3282
3283
|
fallbackScript.crossOrigin = 'anonymous';
|
|
3283
3284
|
fallbackScript.async = false;
|
|
3284
3285
|
fallbackScript.onload = () => {
|
|
3285
|
-
console.log('jQuery loaded from Google CDN for user profile');
|
|
3286
3286
|
callback();
|
|
3287
3287
|
};
|
|
3288
3288
|
fallbackScript.onerror = () => {
|
|
@@ -3296,15 +3296,12 @@ class UserProfilePageComponent extends AppBaseComponent {
|
|
|
3296
3296
|
super.ngOnDestroy();
|
|
3297
3297
|
}
|
|
3298
3298
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: UserProfilePageComponent, deps: [{ token: i0.Injector }, { token: i1$1.ProfileService }, { token: i1.NgbModal }, { token: i1$1.ScriptLoaderService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3299
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.18", type: UserProfilePageComponent, isStandalone: false, selector: "pw-user-profile-page",
|
|
3299
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.18", type: UserProfilePageComponent, isStandalone: false, selector: "pw-user-profile-page", usesInheritance: true, ngImport: i0, template: "<!-- User Profile Starts -->\n<!-- Basic User Details Starts -->\n<section id=\"user-profile\"\n *ngIf=\"user\">\n <div class=\"row\">\n <div class=\"col-12\">\n <div class=\"dashboard\">\n <div class=\"media row py-3 align-items-center\">\n <div class=\"col-3 col-sm-2\">\n <div class=\"align-self-center halfway-fab text-center\">\n <!-- User Avatar -->\n <a class=\"profile-image\">\n <img [src]=\"image\"\n width=\"100\"\n height=\"100\"\n class=\"rounded-circle img-border width-100\"\n alt=\"User Male\"\n (error)=\"handleImageError($event, 'assets/img/icons/male.png')\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\" />\n <div class=\"ms-4 ps-3 ms-sm-0 ps-sm-0 overlay\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\"\n *ngIf=\"allowEdit\">\n <div class=\"overlay-text\">\n <!-- Change Profile Pic -->\n <a aria-label=\"Navigate to Target\">\n {{ 'User.Profile.Change' | transloco }}\n </a>\n </div>\n </div>\n </a>\n </div>\n </div>\n <div class=\"col-9 col-sm-5\">\n <div class=\"align-self-start halfway-fab ps-3 pt-2\">\n <div>\n <strong class=\"font-medium-2 text-uppercase\"\n *ngIf=\"user?.last_name\">\n {{\n user?.first_name\n ? user?.first_name + ' ' + user?.last_name\n : 'Update Profile'\n }}\n </strong>\n <strong class=\"font-medium-2 text-uppercase\"\n *ngIf=\"!user?.last_name\">\n {{ user?.first_name ? user?.first_name : 'Update Profile' }}\n </strong>\n <p class=\"font-small-4\">{{ userProfile?.headline }}</p>\n </div>\n </div>\n </div>\n <div class=\"col-12 col-sm-5\">\n <div class=\"profile-cover-buttons\"\n *ngIf=\"!allowEdit\">\n <div class=\"d-flex halfway-fab align-self-end\">\n <div class=\"text-end d-none d-sm-none d-md-none d-lg-block\">\n <button type=\"button\"\n (click)=\"followUser()\"\n class=\"btn btn-outline-primary btn-raised me-2\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n {{ isFollowing ? 'Following' : 'Follow' }}\n </button>\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-3\"\n (click)=\"sendMessageSlug()\">\n <i class=\"fa fa-mail-bulk\" aria-hidden=\"true\"></i> Message\n </button>\n </div>\n <div class=\"text-end d-block d-sm-block d-md-block d-lg-none\">\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-2\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-3\">\n <i class=\"fa fa-mail-bulk\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</section>\n<!-- Basic User Details Ends -->\n<section>\n <div class=\"container-fluid pw-tab overflow-hidden\">\n <p-tabs [value]=\"activeTabValue\" (valueChange)=\"onTabChange($event)\">\n <p-tablist>\n <p-tab *ngFor=\"let item of items\" [value]=\"item.id\">\n <i *ngIf=\"item.icon\" [class]=\"item.icon\" aria-hidden=\"true\"></i>\n <span>{{ item.label }}</span>\n </p-tab>\n </p-tablist>\n </p-tabs>\n <div class=\"dashboard\">\n <div class=\"dashboard-body\">\n <div class=\"w-100 text-center mt-3\"\n *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n <ng-template [ngIf]=\"user && activeItem.id === 'about'\">\n <pw-user-about [user]=\"user\"\n [isEdit]=\"allowEdit\"\n (saveEvent)=\"getUserBySlug()\">\n </pw-user-about>\n </ng-template>\n <ng-template [ngIf]=\"activeItem.id === 'projects'\">\n <pw-user-projects [user]=\"user\"\n [isEdit]=\"allowEdit\"></pw-user-projects>\n </ng-template>\n <ng-template [ngIf]=\"activeItem.id === 'portfolio'\">\n <pw-portfolios [user]=\"user\"\n [isEdit]=\"allowEdit\"></pw-portfolios>\n </ng-template>\n </div>\n </div>\n </div>\n</section>\n<ng-template #content\n let-modal>\n <div class=\"card m-0\">\n <div class=\"card-content\">\n <div class=\"card-title\">\n <h3 class=\"modal-title\">{{ 'User.Profile.ProfilePicture' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"card-header\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n aspectRatio=\"auto\"\n [userAvatar]=\"image\"\n (imageSelectionEvent)=\"onImageSelection($event)\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.card-body{padding:10px!important}.py-3{padding-top:4rem!important;padding-bottom:0rem!important}.overlay-text{margin-left:-19px;margin-top:5px;text-align:center}::ng-deep .pw-tab .p-tabs .p-tab.p-highlight,::ng-deep .pw-tab .p-tabs .p-tab[aria-selected=true]{background-color:#1769e1!important;box-shadow:none!important;color:#fff!important}::ng-deep .pw-tab .p-tabs .p-tab.p-highlight:hover,::ng-deep .pw-tab .p-tabs .p-tab[aria-selected=true]:hover{background-color:#1769e1!important;color:#fff!important}\n"], dependencies: [{ kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i5$3.Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: i5$3.TabList, selector: "p-tablist" }, { kind: "component", type: i5$3.Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: i5.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "style", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i9$1.ProfileImageCropperComponent, selector: "pw-image-cropper", inputs: ["aspectRatio", "dynamicData"], outputs: ["imageSelectionEvent", "closeEvent", "fileChangeEvent"] }, { kind: "component", type: UserAboutComponent, selector: "pw-user-about", inputs: ["user", "isEdit"], outputs: ["saveEvent"] }, { kind: "component", type: PortfoliosComponent, selector: "pw-portfolios", inputs: ["user", "isEdit"] }, { kind: "component", type: UserProjectsComponent, selector: "pw-user-projects", inputs: ["user", "isEdit"] }, { kind: "pipe", type: i11.TranslocoPipe, name: "transloco" }] }); }
|
|
3300
3300
|
}
|
|
3301
3301
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: UserProfilePageComponent, decorators: [{
|
|
3302
3302
|
type: Component,
|
|
3303
|
-
args: [{ selector: 'pw-user-profile-page', standalone: false, template: "<!-- User Profile Starts -->\n<!-- Basic User Details Starts -->\n<section id=\"user-profile\"\n *ngIf=\"user\">\n <div class=\"row\">\n <div class=\"col-12\">\n <div class=\"dashboard\">\n <div class=\"media row py-3 align-items-center\">\n <div class=\"col-3 col-sm-2\">\n <div class=\"align-self-center halfway-fab text-center\">\n <!-- User Avatar -->\n <a class=\"profile-image\">\n <img [src]=\"image\"\n width=\"100\"\n height=\"100\"\n class=\"rounded-circle img-border width-100\"\n alt=\"User Male\"\n (error)=\"handleImageError($event, 'assets/img/icons/male.png')\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\" />\n <div class=\"ms-4 ps-3 ms-sm-0 ps-sm-0 overlay\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\"\n *ngIf=\"allowEdit\">\n <div class=\"overlay-text\">\n <!-- Change Profile Pic -->\n <a aria-label=\"Navigate to Target\">\n {{ 'User.Profile.Change' | transloco }}\n </a>\n </div>\n </div>\n </a>\n </div>\n </div>\n <div class=\"col-9 col-sm-5\">\n <div class=\"align-self-start halfway-fab ps-3 pt-2\">\n <div>\n <strong class=\"font-medium-2 text-uppercase\"\n *ngIf=\"user?.last_name\">\n {{\n user?.first_name\n ? user?.first_name + ' ' + user?.last_name\n : 'Update Profile'\n }}\n </strong>\n <strong class=\"font-medium-2 text-uppercase\"\n *ngIf=\"!user?.last_name\">\n {{ user?.first_name ? user?.first_name : 'Update Profile' }}\n </strong>\n <p class=\"font-small-4\">{{ userProfile?.headline }}</p>\n </div>\n </div>\n </div>\n <div class=\"col-12 col-sm-5\">\n <div class=\"profile-cover-buttons\"\n *ngIf=\"!allowEdit\">\n <div class=\"d-flex halfway-fab align-self-end\">\n <div class=\"text-end d-none d-sm-none d-md-none d-lg-block\">\n <button type=\"button\"\n (click)=\"followUser()\"\n class=\"btn btn-outline-primary btn-raised me-2\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n {{ isFollowing ? 'Following' : 'Follow' }}\n </button>\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-3\"\n (click)=\"sendMessageSlug()\">\n <i class=\"fa fa-mail-bulk\" aria-hidden=\"true\"></i> Message\n </button>\n </div>\n <div class=\"text-end d-block d-sm-block d-md-block d-lg-none\">\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-2\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-3\">\n <i class=\"fa fa-mail-bulk\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</section>\n<!-- Basic User Details Ends -->\n<section>\n <div class=\"container-fluid pw-tab overflow-hidden\">\n <p-
|
|
3304
|
-
}], ctorParameters: () => [{ type: i0.Injector }, { type: i1$1.ProfileService }, { type: i1.NgbModal }, { type: i1$1.ScriptLoaderService }]
|
|
3305
|
-
type: ViewChild,
|
|
3306
|
-
args: ['menuItems', { static: true }]
|
|
3307
|
-
}] } });
|
|
3303
|
+
args: [{ selector: 'pw-user-profile-page', standalone: false, template: "<!-- User Profile Starts -->\n<!-- Basic User Details Starts -->\n<section id=\"user-profile\"\n *ngIf=\"user\">\n <div class=\"row\">\n <div class=\"col-12\">\n <div class=\"dashboard\">\n <div class=\"media row py-3 align-items-center\">\n <div class=\"col-3 col-sm-2\">\n <div class=\"align-self-center halfway-fab text-center\">\n <!-- User Avatar -->\n <a class=\"profile-image\">\n <img [src]=\"image\"\n width=\"100\"\n height=\"100\"\n class=\"rounded-circle img-border width-100\"\n alt=\"User Male\"\n (error)=\"handleImageError($event, 'assets/img/icons/male.png')\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\" />\n <div class=\"ms-4 ps-3 ms-sm-0 ps-sm-0 overlay\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\"\n *ngIf=\"allowEdit\">\n <div class=\"overlay-text\">\n <!-- Change Profile Pic -->\n <a aria-label=\"Navigate to Target\">\n {{ 'User.Profile.Change' | transloco }}\n </a>\n </div>\n </div>\n </a>\n </div>\n </div>\n <div class=\"col-9 col-sm-5\">\n <div class=\"align-self-start halfway-fab ps-3 pt-2\">\n <div>\n <strong class=\"font-medium-2 text-uppercase\"\n *ngIf=\"user?.last_name\">\n {{\n user?.first_name\n ? user?.first_name + ' ' + user?.last_name\n : 'Update Profile'\n }}\n </strong>\n <strong class=\"font-medium-2 text-uppercase\"\n *ngIf=\"!user?.last_name\">\n {{ user?.first_name ? user?.first_name : 'Update Profile' }}\n </strong>\n <p class=\"font-small-4\">{{ userProfile?.headline }}</p>\n </div>\n </div>\n </div>\n <div class=\"col-12 col-sm-5\">\n <div class=\"profile-cover-buttons\"\n *ngIf=\"!allowEdit\">\n <div class=\"d-flex halfway-fab align-self-end\">\n <div class=\"text-end d-none d-sm-none d-md-none d-lg-block\">\n <button type=\"button\"\n (click)=\"followUser()\"\n class=\"btn btn-outline-primary btn-raised me-2\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n {{ isFollowing ? 'Following' : 'Follow' }}\n </button>\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-3\"\n (click)=\"sendMessageSlug()\">\n <i class=\"fa fa-mail-bulk\" aria-hidden=\"true\"></i> Message\n </button>\n </div>\n <div class=\"text-end d-block d-sm-block d-md-block d-lg-none\">\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-2\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-3\">\n <i class=\"fa fa-mail-bulk\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</section>\n<!-- Basic User Details Ends -->\n<section>\n <div class=\"container-fluid pw-tab overflow-hidden\">\n <p-tabs [value]=\"activeTabValue\" (valueChange)=\"onTabChange($event)\">\n <p-tablist>\n <p-tab *ngFor=\"let item of items\" [value]=\"item.id\">\n <i *ngIf=\"item.icon\" [class]=\"item.icon\" aria-hidden=\"true\"></i>\n <span>{{ item.label }}</span>\n </p-tab>\n </p-tablist>\n </p-tabs>\n <div class=\"dashboard\">\n <div class=\"dashboard-body\">\n <div class=\"w-100 text-center mt-3\"\n *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n <ng-template [ngIf]=\"user && activeItem.id === 'about'\">\n <pw-user-about [user]=\"user\"\n [isEdit]=\"allowEdit\"\n (saveEvent)=\"getUserBySlug()\">\n </pw-user-about>\n </ng-template>\n <ng-template [ngIf]=\"activeItem.id === 'projects'\">\n <pw-user-projects [user]=\"user\"\n [isEdit]=\"allowEdit\"></pw-user-projects>\n </ng-template>\n <ng-template [ngIf]=\"activeItem.id === 'portfolio'\">\n <pw-portfolios [user]=\"user\"\n [isEdit]=\"allowEdit\"></pw-portfolios>\n </ng-template>\n </div>\n </div>\n </div>\n</section>\n<ng-template #content\n let-modal>\n <div class=\"card m-0\">\n <div class=\"card-content\">\n <div class=\"card-title\">\n <h3 class=\"modal-title\">{{ 'User.Profile.ProfilePicture' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"card-header\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n aspectRatio=\"auto\"\n [userAvatar]=\"image\"\n (imageSelectionEvent)=\"onImageSelection($event)\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.card-body{padding:10px!important}.py-3{padding-top:4rem!important;padding-bottom:0rem!important}.overlay-text{margin-left:-19px;margin-top:5px;text-align:center}::ng-deep .pw-tab .p-tabs .p-tab.p-highlight,::ng-deep .pw-tab .p-tabs .p-tab[aria-selected=true]{background-color:#1769e1!important;box-shadow:none!important;color:#fff!important}::ng-deep .pw-tab .p-tabs .p-tab.p-highlight:hover,::ng-deep .pw-tab .p-tabs .p-tab[aria-selected=true]:hover{background-color:#1769e1!important;color:#fff!important}\n"] }]
|
|
3304
|
+
}], ctorParameters: () => [{ type: i0.Injector }, { type: i1$1.ProfileService }, { type: i1.NgbModal }, { type: i1$1.ScriptLoaderService }] });
|
|
3308
3305
|
|
|
3309
3306
|
const primeNgModules = [
|
|
3310
3307
|
CalendarModule,
|