ode-ngjs-front 1.4.14-develop-b2school.202508181154 → 1.4.14-develop-integration.202508201656
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.
- package/README.md +6 -7
- package/dist/{88bf8796d91b9cb078e8709f0d1df5e5.html → 048f0eccf89021875b26fda0b249c1d4.html} +0 -2
- package/dist/919.js +23 -0
- package/dist/919.js.map +1 -0
- package/dist/ode-ngjs-front.js +3 -3
- package/dist/ode-ngjs-front.js.map +1 -1
- package/dist/ts/directives/business/portal/navbar.directive.d.ts.map +1 -1
- package/dist/ts/modules/widgets.module.d.ts +3 -1
- package/dist/ts/modules/widgets.module.d.ts.map +1 -1
- package/dist/ts/services/theme-helper.service.d.ts.map +1 -1
- package/dist/ts/widgets/cantine-widget/cantine-widget.widget.d.ts.map +1 -1
- package/dist/ts/widgets/ptit-observatoire-widget/ptit-observatoire-widget.widget.d.ts +2 -0
- package/dist/ts/widgets/ptit-observatoire-widget/ptit-observatoire-widget.widget.d.ts.map +1 -0
- package/dist/ts/widgets/screen-time-widget/screen-time-widget.widget.d.ts +87 -0
- package/dist/ts/widgets/screen-time-widget/screen-time-widget.widget.d.ts.map +1 -0
- package/dist/version.txt +1 -1
- package/dist/widgets/cantine-widget/cantine-widget.widget.js +1 -1
- package/dist/widgets/cantine-widget/cantine-widget.widget.js.map +1 -1
- package/dist/widgets/ptit-observatoire-widget/ptit-observatoire-widget.widget.js +2 -0
- package/dist/widgets/ptit-observatoire-widget/ptit-observatoire-widget.widget.js.map +1 -0
- package/dist/widgets/screen-time-widget/screen-time-widget.widget.js +2 -0
- package/dist/widgets/screen-time-widget/screen-time-widget.widget.js.map +1 -0
- package/package.json +3 -2
- package/LICENSE +0 -661
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navbar.directive.d.ts","sourceRoot":"","sources":["../../../../../src/ts/directives/business/portal/navbar.directive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,
|
|
1
|
+
{"version":3,"file":"navbar.directive.d.ts","sourceRoot":"","sources":["../../../../../src/ts/directives/business/portal/navbar.directive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAuB,aAAa,EAAyC,MAAM,gBAAgB,CAAC;AAC3G,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAIxF,qBAAa,UAAW,YAAW,WAAW;IAErC,OAAO,EAAC,cAAc;IACtB,SAAS,EAAE,eAAe;IAC1B,QAAQ,EAAC,kBAAkB;gBAF3B,OAAO,EAAC,cAAc,EACtB,SAAS,EAAE,eAAe,EAC1B,QAAQ,EAAC,kBAAkB;IAE5B,IAAI,CAAC,EAAC,MAAM,CAAC;IACb,qBAAqB,CAAC,EAAC,MAAM,CAAC;IAC9B,eAAe,EAAC,MAAM,CAAM;IAC5B,QAAQ,EAAC,MAAM,CAAM;IACrB,MAAM,EAAC,MAAM,CAAmB;IAChC,cAAc,EAAC,MAAM,CAAoB;IACzC,QAAQ,EAAC,MAAM,CAAM;IACrB,IAAI,EAAC,OAAO,EAAE,CAAM;IAEpB,IAAI,EAAC,OAAO,CAAS;IACrB,IAAI,EAAC,OAAO,CAAS;IAE5B,aAAa;IAKb,QAAQ,CAAC,KAAK,EAAC,GAAG;IAOlB,YAAY,CAAC,KAAK,EAAC,KAAK,EAAE,IAAI,EAAC,MAAM;IAarC,YAAY,CAAC,GAAG,EAAC,OAAO;IAMrB,SAAS,CAAC,UAAU,CAAC,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,eAAe,CAAC,aAAa,CAAC;CASjE;AAMD,UAAU,KAAM,SAAQ,MAAM;IAC7B,IAAI,CAAC,EAAC,MAAM,CAAC;IACb,aAAa,CAAC,EAAC,MAAM,CAAC;IACtB,OAAO,CAAC,EAAC,MAAM,CAAC;IAChB,EAAE,CAAC,EAAC;QACH,WAAW,CAAC,KAAK,EAAC,MAAM,GAAE,OAAO,CAAC;KAClC,CAAC;IAEF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAGD,cAAM,SAAU,YAAW,UAAU,CAAC,KAAK,EAAC,MAAM,EAAC,WAAW,EAAC,WAAW,EAAE,CAAC;IACzE,QAAQ,SAAO;IAElB,QAAQ,MAA8C;IACtD,KAAK;;MAEH;IACF,gBAAgB,UAAQ;IACxB,UAAU,iCAA6E;IACvF,YAAY,SAAU;IACtB,OAAO,WAAiB;IAErB,IAAI,CAAC,KAAK,EAAC,KAAK,EAAE,IAAI,EAAC,MAAM,EAAE,KAAK,EAAC,WAAW,EAAE,WAAW,CAAC,EAAC,WAAW,EAAE,GAAG,IAAI;CA2EtF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,cAE/B"}
|
|
@@ -17,7 +17,9 @@ export declare enum KnownWidget {
|
|
|
17
17
|
lastInfos = "last-infos-widget",
|
|
18
18
|
edumalin = "edumalin-widget",
|
|
19
19
|
mediacentre = "mediacentre-widget",
|
|
20
|
-
cantine = "cantine-widget"
|
|
20
|
+
cantine = "cantine-widget",
|
|
21
|
+
ptitObservatoire = "ptit-observatoire-widget",
|
|
22
|
+
screenTime = "screen-time-widget"
|
|
21
23
|
}
|
|
22
24
|
export declare type WidgetLoader = (widgetName: String) => Promise<void>;
|
|
23
25
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"widgets.module.d.ts","sourceRoot":"","sources":["../../../src/ts/modules/widgets.module.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAQ,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"widgets.module.d.ts","sourceRoot":"","sources":["../../../src/ts/modules/widgets.module.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAQ,OAAO,EAAE,MAAM,SAAS,CAAC;AA4CjD,oBAAY,WAAW;IACnB,SAAS,qBAA2B;IACpC,MAAM,kBAA2B;IACjC,MAAM,kBAA2B;IACjC,QAAQ,cAAqB;IAC7B,MAAM,kBAA2B;IACjC,KAAK,UAAoB;IACzB,QAAQ,oBAA2B;IACnC,GAAG,eAA2B;IAC9B,MAAM,YAAqB;IAC3B,YAAY,mBAAsB;IAClC,YAAY,wBAA2B;IACvC,QAAQ,oBAA2B;IACnC,WAAW,uBAA2B;IACtC,OAAO,mBAA2B;IAClC,SAAS,sBAA4B;IACrC,QAAQ,oBAA2B;IACnC,WAAW,uBAA2B;IACtC,OAAO,mBAA2B;IAClC,gBAAgB,6BAA6B;IAC7C,UAAU,uBAA4B;CAEzC;AACD,oBAAY,YAAY,GAAG,CAAC,UAAU,EAAC,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AA6Z9D;;GAEG;AACH,wBAAgB,eAAe,IAAG,OAAO,CAExC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-helper.service.d.ts","sourceRoot":"","sources":["../../../src/ts/services/theme-helper.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAc,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAItD;;GAEG;AACH,qBAAa,kBAAkB;
|
|
1
|
+
{"version":3,"file":"theme-helper.service.d.ts","sourceRoot":"","sources":["../../../src/ts/services/theme-helper.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAc,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAItD;;GAEG;AACH,qBAAa,kBAAkB;IA+BvB,OAAO,CAAC,WAAW;IA9BvB,MAAM,CAAC,OAAO,WAAyB;IAEvC,OAAO,CAAC,YAAY,CAyBnB;gBAGW,WAAW,EAAC,eAAe;IAIvC,OAAO,KAAK,QAAQ,GAEnB;IAED,uCAAuC;IACvC,IAAI,GAAG,WAEN;IAED,8FAA8F;IACxF,qBAAqB,IAAG,OAAO,CAAC,MAAM,CAAC;IAW7C,4GAA4G;IACtG,oBAAoB,IAAG,OAAO,CAAC,MAAM,CAAC;IAM5C,SAAS,CAAE,GAAG,EAAC,MAAM,GAAG,MAAM;IAa9B;;;OAGG;IACH,mBAAmB,CAAE,QAAQ,EAAC,MAAM,EAAE,QAAQ,EAAC,MAAM;IAYrD,4CAA4C;IAC5C,WAAW,CAAE,KAAK,EAAC,MAAM;IAWzB,iCAAiC;IAC3B,UAAU,CAAE,SAAS,EAAC,MAAM;IA8BlC,qEAAqE;IACrE,UAAU,IAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAIlC,2FAA2F;IACrF,QAAQ,CAAE,KAAK,EAAC,UAAU;IAMhC;;OAEG;IACF,WAAW,CAAE,GAAG,EAAC,OAAO,GAAG,MAAM;IA2BlC,wCAAwC;IACxC,kBAAkB,CAAE,MAAM,EAAC,OAAO,GAAG,MAAM;CAG9C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cantine-widget.widget.d.ts","sourceRoot":"","sources":["../../../../src/ts/widgets/cantine-widget/cantine-widget.widget.ts"],"names":[],"mappings":"AAGA,OAAO,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"cantine-widget.widget.d.ts","sourceRoot":"","sources":["../../../../src/ts/widgets/cantine-widget/cantine-widget.widget.ts"],"names":[],"mappings":"AAGA,OAAO,kBAAkB,CAAC;AAgQ1B,eAAO,MAAM,aAAa,2BAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ptit-observatoire-widget.widget.d.ts","sourceRoot":"","sources":["../../../../src/ts/widgets/ptit-observatoire-widget/ptit-observatoire-widget.widget.ts"],"names":[],"mappings":"AAgIA,eAAO,MAAM,aAAa,oCAAoC,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Moment } from "moment";
|
|
2
|
+
import 'moment/locale/fr';
|
|
3
|
+
export declare class Controller {
|
|
4
|
+
platform: {
|
|
5
|
+
readonly deploymentTag: string;
|
|
6
|
+
readonly cdnDomain: string;
|
|
7
|
+
readonly apps: {
|
|
8
|
+
initialize(app: import("ode-ts-client").App, alternativeApp?: boolean | undefined): Promise<void>;
|
|
9
|
+
getPublicConf(app: import("ode-ts-client").App): Promise<any>;
|
|
10
|
+
getWebAppConf(app: import("ode-ts-client").App): Promise<import("ode-ts-client").IWebApp | undefined>;
|
|
11
|
+
loadI18n(app: import("ode-ts-client").App): Promise<void>;
|
|
12
|
+
};
|
|
13
|
+
readonly theme: import("ode-ts-client").ITheme;
|
|
14
|
+
readonly analytics: {
|
|
15
|
+
parameters<T extends import("ode-ts-client").ITrackingParams>(type: import("ode-ts-client").TrackingType): Promise<T | undefined>;
|
|
16
|
+
xiti(): Promise<import("ode-ts-client").IXitiTrackingParams | undefined>;
|
|
17
|
+
readonly status: import("ode-ts-client").AnalyticStatus;
|
|
18
|
+
};
|
|
19
|
+
readonly idiom: import("ode-ts-client").IIdiom;
|
|
20
|
+
listLanguages(): Promise<string[]>;
|
|
21
|
+
};
|
|
22
|
+
lang: import("ode-ts-client").IIdiom;
|
|
23
|
+
selectedUser: string;
|
|
24
|
+
viewMode: "weekly" | "daily";
|
|
25
|
+
userData: {
|
|
26
|
+
[key: string]: {
|
|
27
|
+
weekly: any;
|
|
28
|
+
daily: any;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
selectedDailyDate: string;
|
|
32
|
+
tempDailyDate: string;
|
|
33
|
+
weekStart: Moment;
|
|
34
|
+
weekEnd: Moment;
|
|
35
|
+
updateChart: () => void;
|
|
36
|
+
todayOnCampus: number;
|
|
37
|
+
todayOffCampus: number;
|
|
38
|
+
todayTotal: number;
|
|
39
|
+
weeklyAvgOnCampus: number;
|
|
40
|
+
weeklyAvgOffCampus: number;
|
|
41
|
+
weeklyTotalAverage: number;
|
|
42
|
+
weeklyAvgSchoolUsePercentage: number;
|
|
43
|
+
weeklyAvgOutOfSchoolPercentage: number;
|
|
44
|
+
fixedTodayOnCampus: number;
|
|
45
|
+
fixedTodayOffCampus: number;
|
|
46
|
+
fixedTodayTotal: number;
|
|
47
|
+
fixedWeeklyAvgOnCampus: number;
|
|
48
|
+
fixedWeeklyAvgOffCampus: number;
|
|
49
|
+
fixedWeeklyTotalAverage: number;
|
|
50
|
+
fixedWeeklyAvgSchoolUsePercentage: number;
|
|
51
|
+
fixedWeeklyAvgOutOfSchoolPercentage: number;
|
|
52
|
+
customWeekMode: boolean;
|
|
53
|
+
customStartDate: string;
|
|
54
|
+
customEndDate: string;
|
|
55
|
+
isParent: boolean;
|
|
56
|
+
hasError: boolean;
|
|
57
|
+
errorMessage: string;
|
|
58
|
+
fetchDataForCurrentUser: () => void;
|
|
59
|
+
fetchLightboxData: () => void;
|
|
60
|
+
showLightbox: boolean;
|
|
61
|
+
showDatePicker: boolean;
|
|
62
|
+
children: {
|
|
63
|
+
id: string;
|
|
64
|
+
name: string;
|
|
65
|
+
userId: string;
|
|
66
|
+
}[];
|
|
67
|
+
selectedChild: null;
|
|
68
|
+
selectedChildHistogram: string;
|
|
69
|
+
toggleDatePicker(show: boolean): void;
|
|
70
|
+
setDateFromPicker(date: string): void;
|
|
71
|
+
commitTempDate(): void;
|
|
72
|
+
toggleLightbox(show: boolean): void;
|
|
73
|
+
private getCurrentSchoolYear;
|
|
74
|
+
private setSelectedDate;
|
|
75
|
+
private setSelectedWeek;
|
|
76
|
+
canGoToPreviousWeek(): boolean;
|
|
77
|
+
canGoToNextWeek(): boolean;
|
|
78
|
+
canGoToPreviousDay(): boolean;
|
|
79
|
+
canGoToNextDay(): boolean;
|
|
80
|
+
changeDay(offset: number): void;
|
|
81
|
+
changeWeek(offset: number): void;
|
|
82
|
+
get selectedDailyDateObj(): Date;
|
|
83
|
+
get selectedDailyDateLabel(): string;
|
|
84
|
+
get weekLabel(): string;
|
|
85
|
+
}
|
|
86
|
+
export declare const odeModuleName = "odeCantineWidgetModule";
|
|
87
|
+
//# sourceMappingURL=screen-time-widget.widget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screen-time-widget.widget.d.ts","sourceRoot":"","sources":["../../../../src/ts/widgets/screen-time-widget/screen-time-widget.widget.ts"],"names":[],"mappings":"AAGA,OAAe,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,kBAAkB,CAAC;AAM1B,qBAAa,UAAU;IACZ,QAAQ;;;;;;;;;;;;;;;;;MAAmB;IAC3B,IAAI,iCAAuB;IAC3B,YAAY,EAAE,MAAM,CAAM;IAC1B,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAY;IAExC,QAAQ,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG;YAAE,MAAM,EAAE,GAAG,CAAC;YAAC,KAAK,EAAE,GAAG,CAAA;SAAE,CAAA;KAAE,CAAM;IAC9D,iBAAiB,EAAE,MAAM,CAAiC;IAC1D,aAAa,EAAE,MAAM,CAAiC;IACtD,SAAS,EAAE,MAAM,CAA+B;IAChD,OAAO,EAAE,MAAM,CAA6B;IAE5C,WAAW,EAAE,MAAM,IAAI,CAAa;IAEpC,aAAa,SAAK;IAClB,cAAc,SAAK;IACnB,UAAU,SAAK;IAEf,iBAAiB,SAAK;IACtB,kBAAkB,SAAK;IACvB,kBAAkB,SAAK;IACvB,4BAA4B,EAAE,MAAM,CAAK;IACzC,8BAA8B,EAAE,MAAM,CAAK;IAG3C,kBAAkB,SAAK;IACvB,mBAAmB,SAAK;IACxB,eAAe,SAAK;IAEpB,sBAAsB,SAAK;IAC3B,uBAAuB,SAAK;IAC5B,uBAAuB,SAAK;IAC5B,iCAAiC,EAAE,MAAM,CAAK;IAC9C,mCAAmC,EAAE,MAAM,CAAK;IAKhD,cAAc,EAAE,OAAO,CAAS;IAChC,eAAe,EAAE,MAAM,CAAM;IAC7B,aAAa,EAAE,MAAM,CAAM;IAE3B,QAAQ,EAAE,OAAO,CAAS;IAE1B,QAAQ,EAAE,OAAO,CAAS;IAC1B,YAAY,EAAE,MAAM,CAAM;IAE1B,uBAAuB,EAAE,MAAM,IAAI,CAAa;IAChD,iBAAiB,EAAE,MAAM,IAAI,CAAa;IAE1C,YAAY,EAAE,OAAO,CAAS;IAC9B,cAAc,EAAE,OAAO,CAAS;IAEhC,QAAQ,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAM;IAC9D,aAAa,OAAQ;IACrB,sBAAsB,SAAM;IAE5B,gBAAgB,CAAC,IAAI,EAAE,OAAO;IAiB9B,iBAAiB,CAAC,IAAI,EAAE,MAAM;IAO9B,cAAc;IAcd,cAAc,CAAC,IAAI,EAAE,OAAO;IA0BnC,OAAO,CAAC,oBAAoB;IAqB5B,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,eAAe;IAOjB,mBAAmB,IAAI,OAAO;IAO9B,eAAe,IAAI,OAAO;IAO1B,kBAAkB,IAAI,OAAO;IAO5B,cAAc,IAAI,OAAO;IAOzB,SAAS,CAAC,MAAM,EAAE,MAAM;IAmBxB,UAAU,CAAC,MAAM,EAAE,MAAM;IAMhC,IAAW,oBAAoB,IAAI,IAAI,CAEtC;IAED,IAAW,sBAAsB,IAAI,MAAM,CAE1C;IAED,IAAW,SAAS,IAAI,MAAM,CAQ7B;CACJ;AAmZD,eAAO,MAAM,aAAa,2BAA2B,CAAC"}
|
package/dist/version.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
ode-ngjs-front
|
|
1
|
+
ode-ngjs-front 20/08/2025 16:57:27
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";(self.webpackChunkode_ngjs_front=self.webpackChunkode_ngjs_front||[]).push([[91],{4798:(e,t,i)=>{i.d(t,{Z:()=>n});const n='<style>.cantine-menu-card{color:#333;justify-content:center;align-items:center;padding:5%;border-radius:10px;box-shadow:0 0 10px rgba(0,0,0,.1)}.cantine-select-wrapper{display:flex;align-items:center;justify-content:center;gap:10px;margin-bottom:20px;font-family:Roboto,sans-serif;color:#333}.cantine-select-wrapper label{font-weight:700;font-size:1em}.cantine-select-wrapper select{padding:6px 10px;border-radius:5px;border:1px solid #ccc;font-size:.95em;font-family:Roboto,sans-serif;background-color:#fff;color:#333;box-shadow:0 2px 5px rgba(0,0,0,.05);transition:border-color .3s ease}.cantine-select-wrapper select:focus{outline:0;border-color:#f7955c}.cantine-select{padding:8px 12px;font-size:1em;border-radius:5px;border:1px solid #ccc;font-family:Roboto,sans-serif;background-color:#fff;color:#333;box-shadow:0 0 5px rgba(0,0,0,.05);max-width:100%}.menu-error-message{padding:1rem;color:#721c24;background-color:#f8d7da;border:1px solid #f5c6cb;border-radius:4px;margin-top:1rem}.cantine-separator{border:none;height:1px;background-color:#ccc;margin:3% 0}.cantine-section{margin-bottom:3%}.cantine-section-title{font-weight:700;font-size:1.1em;display:flex;align-items:center}.cantine-item{margin-left:1%;font-family:Roboto;color:#4a4a4a;font-size:medium}.cantine-item{align-items:center;gap:5px}.cantine-items-container{border-left:2px solid #ccc;margin-left:.8%;padding-left:3%}.cantine-icon{width:1em;height:1em;margin-left:5px;vertical-align:middle;display:inline-block;margin-bottom:10px}.cantine-dot{height:.6em;width:.6em;border-radius:50%;display:inline-block;margin-right:2%}.cantine-arrow-button{background:0 0;border:none;font-size:1.5em;cursor:pointer;opacity:.6;transition:opacity .3s ease}.cantine-arrow-button:hover{opacity:1}.cantine-arrow-button:focus{outline:0}.cantine-allergen-collapse{background-color:#f9f9f9;border-radius:5px;padding:0;display:none;transition:all .3s ease-in-out;font-size:.9em}.cantine-allergen-collapse.open{display:block}.cantine-collapse-toggle{background-color:#f7955c;border:none;padding:0 10px;border-radius:5px;font-weight:700;cursor:pointer;display:block;margin-top:0;color:#fff;font-size:.8em}.cantine-collapse-toggle:hover{background-color:#e6b848}.cantine-red{background-color:red}.cantine-green{background-color:green}.cantine-blue{background-color:#00f}.cantine-pink{background-color:pink}.cantine-yellow{background-color:orange}</style> <div class="widget-dashboard"> <div class="cantine-menu-card"> <h2 style="color:#333;font-family:Roboto,sans-serif;display:flex;align-items:center;justify-content:center;gap:10px"> <i18n>cantine.title</i18n> </h2> <div class="cantine-separator"></div> <div ng-if="ctrl.showUaiDropdown"> <select id="uaiSelect" class="form-control" ng-model="ctrl.selectedUai" ng-options="option.uai as option.name for option in ctrl.schoolOptions" ng-change="ctrl.onUaiSelected()"> <option value="" disabled="disabled" selected="selected" hidden> <i18n>cantine.selectEtablissement</i18n> </option> </select> </div> <div class="cantine-date-navigation" style="display:flex;align-items:center;justify-content:center;gap:10px;position:relative"> <button class="cantine-arrow-button" ng-click="ctrl.changeDate(-1)">←</button> <span style="font-size:1.2em;font-weight:700;cursor:pointer" ng-show="!ctrl.showDatepicker" ng-click="ctrl.toggleDatepicker(true)">{{ ctrl.currentDate }}</span> <input type="date" ng-model="ctrl.pickerDate" ng-blur="ctrl.onDateBlur()" ng-show="ctrl.showDatepicker" style="font-size:1.2em;font-weight:700;cursor:pointer;text-align:center" ng-click="ctrl.toggleDatepicker(true)"/> <button class="cantine-arrow-button" ng-click="ctrl.changeDate(1)">→</button> </div> <div ng-if="ctrl.selectedUai"> <div ng-if="!ctrl.menuUnavailable"> <div class="cantine-section"> <div class="cantine-section-title"> <span class="cantine-dot cantine-red"></span> <i18n>cantine.entree</i18n> </div> <div class="cantine-items-container"> <div class="cantine-item" ng-repeat="item in ctrl.data.entrees"> {{ item.designationMenu && item.designationMenu.trim() !== \'\' ? item.designationMenu : item.nom }} <img ng-if="item.bio" src="/assets/widgets/cantine-widget/cantine-logos/bio-logo.png" alt="Bio" class="cantine-icon" title="Agriculture biologique"> <img ng-if="item.faitmaison" src="/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png" alt="Fait Maison" class="cantine-icon" title="Fait maison"> <img ng-if="item.vegetarien" src="/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png" alt="Vegetarian" class="cantine-icon" title="Végétarien"> <img ng-if="item.local" src="/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png" alt="Local Product" class="cantine-icon" title="Produit local"> <button class="cantine-collapse-toggle" ng-click="item.showAllergies = !item.showAllergies" ng-if="ctrl.getAllergies(item).length > 0"> <i18n>cantine.allergenes</i18n> </button> <div class="cantine-allergen-collapse" ng-class="{\'open\': item.showAllergies}" ng-if="ctrl.getAllergies(item).length > 0"> <span>{{ ctrl.getAllergies(item).join(\', \') }}</span> </div> </div> </div> </div> <div class="cantine-section"> <div class="cantine-section-title"> <span class="cantine-dot cantine-green"></span> <i18n>cantine.plat</i18n> </div> <div class="cantine-items-container"> <div class="cantine-item" ng-repeat="item in ctrl.data.plats"> {{ item.designationMenu && item.designationMenu.trim() !== \'\' ? item.designationMenu : item.nom }} <img ng-if="item.bio" src="/assets/widgets/cantine-widget/cantine-logos/bio-logo.png" alt="Bio" class="cantine-icon" title="Agriculture biologique"> <img ng-if="item.faitmaison" src="/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png" alt="Fait Maison" class="cantine-icon" title="Fait maison"> <img ng-if="item.vegetarien" src="/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png" alt="Vegetarian" class="cantine-icon" title="Végétarien"> <img ng-if="item.local" src="/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png" alt="Local Product" class="cantine-icon" title="Produit local"> <button class="cantine-collapse-toggle" ng-click="item.showAllergies = !item.showAllergies" ng-if="ctrl.getAllergies(item).length > 0"> <i18n>cantine.allergenes</i18n> </button> <div class="cantine-allergen-collapse" ng-class="{\'open\': item.showAllergies}" ng-if="ctrl.getAllergies(item).length > 0"> <span>{{ ctrl.getAllergies(item).join(\', \') }}</span> </div> </div> </div> </div> <div class="cantine-section"> <div class="cantine-section-title"> <span class="cantine-dot cantine-blue"></span> <i18n>cantine.accompagnement</i18n> </div> <div class="cantine-items-container"> <div class="cantine-item" ng-repeat="item in ctrl.data.accompagnements"> {{ item.designationMenu && item.designationMenu.trim() !== \'\' ? item.designationMenu : item.nom }} <img ng-if="item.bio" src="/assets/widgets/cantine-widget/cantine-logos/bio-logo.png" alt="Bio" class="cantine-icon" title="Agriculture biologique"> <img ng-if="item.faitmaison" src="/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png" alt="Fait Maison" class="cantine-icon" title="Fait maison"> <img ng-if="item.vegetarien" src="/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png" alt="Vegetarian" class="cantine-icon" title="Végétarien"> <img ng-if="item.local" src="/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png" alt="Local Product" class="cantine-icon" title="Produit local"> <button class="cantine-collapse-toggle" ng-click="item.showAllergies = !item.showAllergies" ng-if="ctrl.getAllergies(item).length > 0"> <i18n>cantine.allergenes</i18n> </button> <div class="cantine-allergen-collapse" ng-class="{\'open\': item.showAllergies}" ng-if="ctrl.getAllergies(item).length > 0"> <span>{{ ctrl.getAllergies(item).join(\', \') }}</span> </div> </div> </div> </div> <div class="cantine-section"> <div class="cantine-section-title"> <span class="cantine-dot cantine-pink"></span> <i18n>cantine.laitage</i18n> </div> <div class="cantine-items-container"> <div class="cantine-item" ng-repeat="item in ctrl.data.laitage"> {{ item.designationMenu && item.designationMenu.trim() !== \'\' ? item.designationMenu : item.nom }} <img ng-if="item.bio" src="/assets/widgets/cantine-widget/cantine-logos/bio-logo.png" alt="Bio" class="cantine-icon" title="Agriculture biologique"> <img ng-if="item.faitmaison" src="/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png" alt="Fait Maison" class="cantine-icon" title="Fait maison"> <img ng-if="item.vegetarien" src="/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png" alt="Vegetarian" class="cantine-icon" title="Végétarien"> <img ng-if="item.local" src="/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png" alt="Local Product" class="cantine-icon" title="Produit local"> <button class="cantine-collapse-toggle" ng-click="item.showAllergies = !item.showAllergies" ng-if="ctrl.getAllergies(item).length > 0"> <i18n>cantine.allergenes</i18n> </button> <div class="cantine-allergen-collapse" ng-class="{\'open\': item.showAllergies}" ng-if="ctrl.getAllergies(item).length > 0"> <span>{{ ctrl.getAllergies(item).join(\', \') }}</span> </div> </div> </div> </div> <div class="cantine-section"> <div class="cantine-section-title"> <span class="cantine-dot cantine-yellow"></span> <i18n>cantine.dessert</i18n> </div> <div class="cantine-items-container"> <div class="cantine-item" ng-repeat="item in ctrl.data.desserts"> {{ item.designationMenu && item.designationMenu.trim() !== \'\' ? item.designationMenu : item.nom }} <img ng-if="item.bio" src="/assets/widgets/cantine-widget/cantine-logos/bio-logo.png" alt="Bio" class="cantine-icon" title="Agriculture biologique"> <img ng-if="item.faitmaison" src="/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png" alt="Fait Maison" class="cantine-icon" title="Fait maison"> <img ng-if="item.vegetarien" src="/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png" alt="Vegetarian" class="cantine-icon" title="Végétarien"> <img ng-if="item.local" src="/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png" alt="Local Product" class="cantine-icon" title="Produit local"> <button class="cantine-collapse-toggle" ng-click="item.showAllergies = !item.showAllergies" ng-if="ctrl.getAllergies(item).length > 0"> <i18n>cantine.allergenes</i18n> </button> <div class="cantine-allergen-collapse" ng-class="{\'open\': item.showAllergies}" ng-if="ctrl.getAllergies(item).length > 0"> <span>{{ ctrl.getAllergies(item).join(\', \') }}</span> </div> </div> </div> </div> </div> <div ng-if="ctrl.menuUnavailable" class="menu-error-message"> {{ ctrl.unavailableMessage }} </div> </div> </div> </div>'},8544:function(e,t,i){var n=this&&this.__awaiter||function(e,t,i,n){return new(i||(i=Promise))(function(a,s){function o(e){try{c(n.next(e))}catch(e){s(e)}}function l(e){try{c(n.throw(e))}catch(e){s(e)}}function c(e){var t;e.done?a(e.value):(t=e.value,t instanceof i?t:new i(function(e){e(t)})).then(o,l)}c((n=n.apply(e,t||[])).next())})},a=this&&this.__generator||function(e,t){var i,n,a,s,o={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return s={next:l(0),throw:l(1),return:l(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function l(s){return function(l){return function(s){if(i)throw new TypeError("Generator is already executing.");for(;o;)try{if(i=1,n&&(a=2&s[0]?n.return:s[0]?n.throw||((a=n.return)&&a.call(n),0):n.next)&&!(a=a.call(n,s[1])).done)return a;switch(n=0,a&&(s=[2&s[0],a.value]),s[0]){case 0:case 1:a=s;break;case 4:return o.label++,{value:s[1],done:!1};case 5:o.label++,n=s[1],s=[0];continue;case 7:s=o.ops.pop(),o.trys.pop();continue;default:if(!(a=o.trys,(a=a.length>0&&a[a.length-1])||6!==s[0]&&2!==s[0])){o=0;continue}if(3===s[0]&&(!a||s[1]>a[0]&&s[1]<a[3])){o.label=s[1];break}if(6===s[0]&&o.label<a[1]){o.label=a[1],a=s;break}if(a&&o.label<a[2]){o.label=a[2],o.ops.push(s);break}a[2]&&o.ops.pop(),o.trys.pop();continue}s=t.call(e,o)}catch(e){s=[6,e],n=0}finally{i=a=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}([s,l])}}},s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.odeModuleName=void 0;var o=s(i(4202)),l=i(9419),c=s(i(381));i(4470);var r=s(i(9669)),g=function(){function e(e){this.$scope=e,this.data={},this.error=null,this.uaiList=[],this.selectedUai="",this.schoolOptions=[],this.menuUnavailable=!1,this.unavailableMessage="",this.currentDate="",this.pickerDate=new Date,this.showDatepicker=!1,this.previousApiDate="";var t=(0,l.session)().user;this.apiDate=(0,c.default)(this.pickerDate).format("YYYY-MM-DD"),this.updateCurrentDateDisplay();var i=t.uai;if(Array.isArray(i)&&i.length>1)this.loadUserStructures(t.userId);else if("string"==typeof i||Array.isArray(i)&&1===i.length){this.uaiList=Array.isArray(i)?i:[i];var n=Array.isArray(t.structureNames)?t.structureNames:[];this.schoolOptions=this.uaiList.map(function(e,t){return{uai:e,name:n[t]||e}}),this.setupUaiDropdown()}else this.uaiList=[],this.schoolOptions=[],this.selectedUai=""}return e.prototype.onUaiSelected=function(){this.selectedUai&&this.fetchMenu()},Object.defineProperty(e.prototype,"showUaiDropdown",{get:function(){return this.schoolOptions.length>1},enumerable:!1,configurable:!0}),e.prototype.loadUserStructures=function(e){var t;return n(this,void 0,void 0,function(){var i;return a(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,r.default.get("/directory/user/".concat(e))];case 1:return(i=n.sent().data)&&Array.isArray(i.structureNodes)?(this.schoolOptions=i.structureNodes.map(function(e){return{uai:e.UAI,name:e.feederName||e.name||e.UAI}}),this.uaiList=this.schoolOptions.map(function(e){return e.uai}),this.setupUaiDropdown(),null===(t=this.apply)||void 0===t||t.call(this)):this.error="No structures found for user.",[3,3];case 2:return n.sent(),this.error="Failed to load user structures.",[3,3];case 3:return[2]}})})},e.prototype.changeDate=function(e){this.pickerDate.setDate(this.pickerDate.getDate()+e),this.updateDateAndFetch()},e.prototype.processDateSelection=function(){this.updateDateAndFetch(),this.showDatepicker=!1},e.prototype.onDateBlur=function(){this.pickerDate instanceof Date&&!isNaN(this.pickerDate.getTime())&&(this.processDateSelection(),this.$scope.$apply())},e.prototype.toggleDatepicker=function(e){void 0===e&&(e=null),this.showDatepicker=null!==e?e:!this.showDatepicker},e.prototype.updateDateAndFetch=function(){this.apiDate=(0,c.default)(this.pickerDate).format("YYYY-MM-DD"),this.apiDate!==this.previousApiDate&&(this.previousApiDate=this.apiDate,this.updateCurrentDateDisplay(),this.fetchMenu())},e.prototype.updateCurrentDateDisplay=function(){this.currentDate=this.pickerDate.toLocaleDateString("fr-FR",{weekday:"long",day:"2-digit",month:"long"}),this.currentDate=this.currentDate.charAt(0).toUpperCase()+this.currentDate.slice(1)},e.prototype.fetchMenu=function(){var e,t=this;if(!this.selectedUai)return this.data={entrees:[],plats:[],accompagnements:[],desserts:[],laitage:[]},this.menuUnavailable=!0,this.unavailableMessage="Veuillez sélectionner un établissement.",void(null===(e=this.apply)||void 0===e||e.call(this));r.default.get("/appregistry/".concat(this.selectedUai,"/cantine/menu?date=").concat(this.apiDate)).then(function(e){var i,n,a=null===(i=e.data)||void 0===i?void 0:i.menu;Array.isArray(a)&&a.length>0?(t.data={entrees:a.filter(function(e){return"entree"===e.type}),plats:a.filter(function(e){return"plat"===e.type}),accompagnements:a.filter(function(e){return"accompagnement"===e.type}),laitage:a.filter(function(e){return"laitage"===e.type}),desserts:a.filter(function(e){return"dessert"===e.type})},t.menuUnavailable=!1,t.error=null,t.unavailableMessage=""):(t.data={entrees:[],plats:[],accompagnements:[],desserts:[],laitage:[]},t.menuUnavailable=!0,t.unavailableMessage="Menu non disponible pour cette date.",t.error=null),null===(n=t.apply)||void 0===n||n.call(t)}).catch(function(e){var i,n;t.data={entrees:[],plats:[],accompagnements:[],desserts:[],laitage:[]},400===(null===(i=e.response)||void 0===i?void 0:i.status)?(t.menuUnavailable=!0,t.unavailableMessage="Menu indisponible pour cet établissement.",t.error=null):(t.menuUnavailable=!0,t.unavailableMessage="Une erreur est survenue lors du chargement du menu.",t.error=e.message||"Unknown error"),null===(n=t.apply)||void 0===n||n.call(t)})},e.prototype.getAllergies=function(e){return e?Object.keys(e).filter(function(t){return t.startsWith("allerg_")&&0!==e[t]&&void 0!==e[t]}).map(function(e){return e.replace("allerg_","").replace("_"," ")}):[]},e.prototype.setupUaiDropdown=function(){this.schoolOptions.length>1?(this.schoolOptions.unshift({uai:"",name:"Établissement"}),this.selectedUai=""):1===this.schoolOptions.length?(this.selectedUai=this.schoolOptions[0].uai,this.fetchMenu()):this.selectedUai=""},e}(),d=function(){function e(){this.restrict="E",this.template=i(4798).Z,this.scope={},this.bindToController=!0,this.controller=[g],this.controllerAs="ctrl",this.require=["odeCantineWidget"]}return e.prototype.link=function(e,t,i,s){return n(this,void 0,void 0,function(){var t;return a(this,function(i){return(t=null==s?void 0:s[0])&&(t.apply=function(){return e.$apply()}),[2]})})},e}();(0,l.notif)().onLangReady().promise.then(function(){(0,l.conf)().Platform.idiom.addKeys(i(4848))}),t.odeModuleName="odeCantineWidgetModule",o.default.module(t.odeModuleName,[]).directive("odeCantineWidget",function(){return new d})},4848:e=>{e.exports=JSON.parse('{"cantine.title":"Menu du jour","cantine.entree":"Entrée","cantine.laitage":"Laitage","cantine.plat":"Plat","cantine.accompagnement":"Accompagnement","cantine.dessert":"Dessert","cantine.allergenes":"⚠️ Allergènes","cantine.selectUai":"Établissement"}')}}]);
|
|
1
|
+
"use strict";(self.webpackChunkode_ngjs_front=self.webpackChunkode_ngjs_front||[]).push([[91],{4798:(e,t,i)=>{i.d(t,{Z:()=>n});const n='<style>.cantine-menu-card{color:#333;justify-content:center;align-items:center;padding:5%;border-radius:10px;box-shadow:0 0 10px rgba(0,0,0,.1)}.cantine-select-wrapper{display:flex;align-items:center;justify-content:center;gap:10px;margin-bottom:20px;font-family:Roboto,sans-serif;color:#333}.cantine-select-wrapper label{font-weight:700;font-size:1em}.cantine-select-wrapper select{padding:6px 10px;border-radius:5px;border:1px solid #ccc;font-size:.95em;font-family:Roboto,sans-serif;background-color:#fff;color:#333;box-shadow:0 2px 5px rgba(0,0,0,.05);transition:border-color .3s ease}.cantine-select-wrapper select:focus{outline:0;border-color:#f7955c}.cantine-select{padding:8px 12px;font-size:1em;border-radius:5px;border:1px solid #ccc;font-family:Roboto,sans-serif;background-color:#fff;color:#333;box-shadow:0 0 5px rgba(0,0,0,.05);max-width:100%}.menu-error-message{padding:1rem;color:#721c24;background-color:#f8d7da;border:1px solid #f5c6cb;border-radius:4px;margin-top:1rem}.cantine-separator{border:none;height:1px;background-color:#ccc;margin:3% 0}.cantine-section{margin-bottom:3%}.cantine-section-title{font-weight:700;font-size:1.1em;display:flex;align-items:center}.cantine-item{margin-left:1%;font-family:Roboto;color:#4a4a4a;font-size:medium}.cantine-item{align-items:center;gap:5px}.cantine-items-container{border-left:2px solid #ccc;margin-left:.8%;padding-left:3%}.cantine-icon{width:1em;height:1em;margin-left:5px;vertical-align:middle;display:inline-block;margin-bottom:10px}.cantine-dot{height:.6em;width:.6em;border-radius:50%;display:inline-block;margin-right:2%}.cantine-arrow-button{background:0 0;border:none;font-size:1.5em;cursor:pointer;opacity:.6;transition:opacity .3s ease}.cantine-arrow-button:hover{opacity:1}.cantine-arrow-button:focus{outline:0}.cantine-allergen-collapse{background-color:#f9f9f9;border-radius:5px;padding:0;display:none;transition:all .3s ease-in-out;font-size:.9em}.cantine-allergen-collapse.open{display:block}.cantine-collapse-toggle{background-color:#f7955c;border:none;padding:0 10px;border-radius:5px;font-weight:700;cursor:pointer;display:block;margin-top:0;color:#fff;font-size:.8em}.cantine-collapse-toggle:hover{background-color:#e6b848}.cantine-red{background-color:red}.cantine-green{background-color:green}.cantine-blue{background-color:#00f}.cantine-pink{background-color:pink}.cantine-yellow{background-color:orange}</style> <div class="widget-dashboard"> <div class="cantine-menu-card"> <h2 style="color:#333;font-family:Roboto,sans-serif;display:flex;align-items:center;justify-content:center;gap:10px"> <i18n>cantine.title</i18n> </h2> <div class="cantine-separator"></div> <div ng-if="ctrl.noStructuresError" class="menu-error-message"> <i18n>cantine.error.noStructures</i18n> </div> <div ng-if="ctrl.loadStructuresError" class="menu-error-message"> <i18n>cantine.error.loadStructuresFailed</i18n> </div> <div ng-if="ctrl.showUaiDropdown"> <select id="uaiSelect" class="form-control" ng-model="ctrl.selectedUai" ng-options="option.uai as option.name for option in ctrl.schoolOptions" ng-change="ctrl.onUaiSelected()"> <option value="" disabled="disabled" selected="selected" hidden> <i18n>cantine.selectEtablissement</i18n> </option> </select> </div> <div class="cantine-date-navigation" style="display:flex;align-items:center;justify-content:center;gap:10px;position:relative"> <button class="cantine-arrow-button" ng-click="ctrl.changeDate(-1)">←</button> <span style="font-size:1.2em;font-weight:700;cursor:pointer" ng-show="!ctrl.showDatepicker" ng-click="ctrl.toggleDatepicker(true)">{{ ctrl.currentDate }}</span> <input type="date" ng-model="ctrl.pickerDate" ng-blur="ctrl.onDateBlur()" ng-show="ctrl.showDatepicker" style="font-size:1.2em;font-weight:700;cursor:pointer;text-align:center" ng-click="ctrl.toggleDatepicker(true)"/> <button class="cantine-arrow-button" ng-click="ctrl.changeDate(1)">→</button> </div> <div ng-if="ctrl.selectedUai"> <div ng-if="!ctrl.menuUnavailable"> <div class="cantine-section"> <div class="cantine-section-title"> <span class="cantine-dot cantine-red"></span> <i18n>cantine.entree</i18n> </div> <div class="cantine-items-container"> <div class="cantine-item" ng-repeat="item in ctrl.data.entrees"> {{ item.designationMenu && item.designationMenu.trim() !== \'\' ? item.designationMenu : item.nom }} <img ng-if="item.bio" src="/assets/widgets/cantine-widget/cantine-logos/bio-logo.png" alt="Bio" class="cantine-icon" title="Agriculture biologique"> <img ng-if="item.faitmaison" src="/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png" alt="Fait Maison" class="cantine-icon" title="Fait maison"> <img ng-if="item.vegetarien" src="/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png" alt="Vegetarian" class="cantine-icon" title="Végétarien"> <img ng-if="item.local" src="/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png" alt="Local Product" class="cantine-icon" title="Produit local"> <button class="cantine-collapse-toggle" ng-click="item.showAllergies = !item.showAllergies" ng-if="ctrl.getAllergies(item).length > 0"> <i18n>cantine.allergenes</i18n> </button> <div class="cantine-allergen-collapse" ng-class="{\'open\': item.showAllergies}" ng-if="ctrl.getAllergies(item).length > 0"> <span>{{ ctrl.getAllergies(item).join(\', \') }}</span> </div> </div> </div> </div> <div class="cantine-section"> <div class="cantine-section-title"> <span class="cantine-dot cantine-green"></span> <i18n>cantine.plat</i18n> </div> <div class="cantine-items-container"> <div class="cantine-item" ng-repeat="item in ctrl.data.plats"> {{ item.designationMenu && item.designationMenu.trim() !== \'\' ? item.designationMenu : item.nom }} <img ng-if="item.bio" src="/assets/widgets/cantine-widget/cantine-logos/bio-logo.png" alt="Bio" class="cantine-icon" title="Agriculture biologique"> <img ng-if="item.faitmaison" src="/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png" alt="Fait Maison" class="cantine-icon" title="Fait maison"> <img ng-if="item.vegetarien" src="/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png" alt="Vegetarian" class="cantine-icon" title="Végétarien"> <img ng-if="item.local" src="/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png" alt="Local Product" class="cantine-icon" title="Produit local"> <button class="cantine-collapse-toggle" ng-click="item.showAllergies = !item.showAllergies" ng-if="ctrl.getAllergies(item).length > 0"> <i18n>cantine.allergenes</i18n> </button> <div class="cantine-allergen-collapse" ng-class="{\'open\': item.showAllergies}" ng-if="ctrl.getAllergies(item).length > 0"> <span>{{ ctrl.getAllergies(item).join(\', \') }}</span> </div> </div> </div> </div> <div class="cantine-section"> <div class="cantine-section-title"> <span class="cantine-dot cantine-blue"></span> <i18n>cantine.accompagnement</i18n> </div> <div class="cantine-items-container"> <div class="cantine-item" ng-repeat="item in ctrl.data.accompagnements"> {{ item.designationMenu && item.designationMenu.trim() !== \'\' ? item.designationMenu : item.nom }} <img ng-if="item.bio" src="/assets/widgets/cantine-widget/cantine-logos/bio-logo.png" alt="Bio" class="cantine-icon" title="Agriculture biologique"> <img ng-if="item.faitmaison" src="/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png" alt="Fait Maison" class="cantine-icon" title="Fait maison"> <img ng-if="item.vegetarien" src="/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png" alt="Vegetarian" class="cantine-icon" title="Végétarien"> <img ng-if="item.local" src="/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png" alt="Local Product" class="cantine-icon" title="Produit local"> <button class="cantine-collapse-toggle" ng-click="item.showAllergies = !item.showAllergies" ng-if="ctrl.getAllergies(item).length > 0"> <i18n>cantine.allergenes</i18n> </button> <div class="cantine-allergen-collapse" ng-class="{\'open\': item.showAllergies}" ng-if="ctrl.getAllergies(item).length > 0"> <span>{{ ctrl.getAllergies(item).join(\', \') }}</span> </div> </div> </div> </div> <div class="cantine-section"> <div class="cantine-section-title"> <span class="cantine-dot cantine-pink"></span> <i18n>cantine.laitage</i18n> </div> <div class="cantine-items-container"> <div class="cantine-item" ng-repeat="item in ctrl.data.laitage"> {{ item.designationMenu && item.designationMenu.trim() !== \'\' ? item.designationMenu : item.nom }} <img ng-if="item.bio" src="/assets/widgets/cantine-widget/cantine-logos/bio-logo.png" alt="Bio" class="cantine-icon" title="Agriculture biologique"> <img ng-if="item.faitmaison" src="/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png" alt="Fait Maison" class="cantine-icon" title="Fait maison"> <img ng-if="item.vegetarien" src="/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png" alt="Vegetarian" class="cantine-icon" title="Végétarien"> <img ng-if="item.local" src="/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png" alt="Local Product" class="cantine-icon" title="Produit local"> <button class="cantine-collapse-toggle" ng-click="item.showAllergies = !item.showAllergies" ng-if="ctrl.getAllergies(item).length > 0"> <i18n>cantine.allergenes</i18n> </button> <div class="cantine-allergen-collapse" ng-class="{\'open\': item.showAllergies}" ng-if="ctrl.getAllergies(item).length > 0"> <span>{{ ctrl.getAllergies(item).join(\', \') }}</span> </div> </div> </div> </div> <div class="cantine-section"> <div class="cantine-section-title"> <span class="cantine-dot cantine-yellow"></span> <i18n>cantine.dessert</i18n> </div> <div class="cantine-items-container"> <div class="cantine-item" ng-repeat="item in ctrl.data.desserts"> {{ item.designationMenu && item.designationMenu.trim() !== \'\' ? item.designationMenu : item.nom }} <img ng-if="item.bio" src="/assets/widgets/cantine-widget/cantine-logos/bio-logo.png" alt="Bio" class="cantine-icon" title="Agriculture biologique"> <img ng-if="item.faitmaison" src="/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png" alt="Fait Maison" class="cantine-icon" title="Fait maison"> <img ng-if="item.vegetarien" src="/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png" alt="Vegetarian" class="cantine-icon" title="Végétarien"> <img ng-if="item.local" src="/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png" alt="Local Product" class="cantine-icon" title="Produit local"> <button class="cantine-collapse-toggle" ng-click="item.showAllergies = !item.showAllergies" ng-if="ctrl.getAllergies(item).length > 0"> <i18n>cantine.allergenes</i18n> </button> <div class="cantine-allergen-collapse" ng-class="{\'open\': item.showAllergies}" ng-if="ctrl.getAllergies(item).length > 0"> <span>{{ ctrl.getAllergies(item).join(\', \') }}</span> </div> </div> </div> </div> </div> <div ng-if="ctrl.menuUnavailable" class="menu-error-message"> <div ng-if="ctrl.selectInstitutionError"> <i18n>cantine.error.selectInstitution</i18n> </div> <div ng-if="ctrl.menuNotAvailableError"> <i18n>cantine.error.menuNotAvailable</i18n> </div> <div ng-if="ctrl.menuUnavailableForInstitutionError"> <i18n>cantine.error.menuUnavailableForInstitution</i18n> </div> <div ng-if="ctrl.loadMenuError"> <i18n>cantine.error.loadMenuFailed</i18n> </div> </div> </div> </div> </div>'},8544:function(e,t,i){var n=this&&this.__awaiter||function(e,t,i,n){return new(i||(i=Promise))(function(a,r){function s(e){try{l(n.next(e))}catch(e){r(e)}}function o(e){try{l(n.throw(e))}catch(e){r(e)}}function l(e){var t;e.done?a(e.value):(t=e.value,t instanceof i?t:new i(function(e){e(t)})).then(s,o)}l((n=n.apply(e,t||[])).next())})},a=this&&this.__generator||function(e,t){var i,n,a,r,s={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return r={next:o(0),throw:o(1),return:o(2)},"function"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function o(r){return function(o){return function(r){if(i)throw new TypeError("Generator is already executing.");for(;s;)try{if(i=1,n&&(a=2&r[0]?n.return:r[0]?n.throw||((a=n.return)&&a.call(n),0):n.next)&&!(a=a.call(n,r[1])).done)return a;switch(n=0,a&&(r=[2&r[0],a.value]),r[0]){case 0:case 1:a=r;break;case 4:return s.label++,{value:r[1],done:!1};case 5:s.label++,n=r[1],r=[0];continue;case 7:r=s.ops.pop(),s.trys.pop();continue;default:if(!(a=s.trys,(a=a.length>0&&a[a.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!a||r[1]>a[0]&&r[1]<a[3])){s.label=r[1];break}if(6===r[0]&&s.label<a[1]){s.label=a[1],a=r;break}if(a&&s.label<a[2]){s.label=a[2],s.ops.push(r);break}a[2]&&s.ops.pop(),s.trys.pop();continue}r=t.call(e,s)}catch(e){r=[6,e],n=0}finally{i=a=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}([r,o])}}},r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.odeModuleName=void 0;var s=r(i(4202)),o=i(9419),l=r(i(381));i(4470);var c=r(i(9669)),g=function(){function e(e){this.$scope=e,this.data={},this.error=null,this.uaiList=[],this.selectedUai="",this.schoolOptions=[],this.menuUnavailable=!1,this.noStructuresError=!1,this.loadStructuresError=!1,this.selectInstitutionError=!1,this.menuNotAvailableError=!1,this.menuUnavailableForInstitutionError=!1,this.loadMenuError=!1,this.currentDate="",this.pickerDate=new Date,this.showDatepicker=!1,this.previousApiDate="";var t=(0,o.session)().user;this.apiDate=(0,l.default)(this.pickerDate).format("YYYY-MM-DD"),this.updateCurrentDateDisplay();var i=t.uai;if(Array.isArray(i)&&i.length>1)this.loadUserStructures(t.userId);else if("string"==typeof i||Array.isArray(i)&&1===i.length){this.uaiList=Array.isArray(i)?i:[i];var n=Array.isArray(t.structureNames)?t.structureNames:[];this.schoolOptions=this.uaiList.map(function(e,t){return{uai:e,name:n[t]||e}}),this.setupUaiDropdown()}else this.uaiList=[],this.schoolOptions=[],this.selectedUai=""}return e.prototype.onUaiSelected=function(){this.selectedUai&&this.fetchMenu()},Object.defineProperty(e.prototype,"showUaiDropdown",{get:function(){return this.schoolOptions.length>1},enumerable:!1,configurable:!0}),e.prototype.loadUserStructures=function(e){var t;return n(this,void 0,void 0,function(){var i;return a(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,c.default.get("/directory/user/".concat(e))];case 1:return(i=n.sent().data)&&Array.isArray(i.structureNodes)?(this.schoolOptions=i.structureNodes.map(function(e){return{uai:e.UAI,name:e.feederName||e.name||e.UAI}}),this.uaiList=this.schoolOptions.map(function(e){return e.uai}),this.setupUaiDropdown(),null===(t=this.apply)||void 0===t||t.call(this)):(this.clearAllErrorFlags(),this.noStructuresError=!0),[3,3];case 2:return n.sent(),this.clearAllErrorFlags(),this.loadStructuresError=!0,[3,3];case 3:return[2]}})})},e.prototype.changeDate=function(e){this.pickerDate.setDate(this.pickerDate.getDate()+e),this.updateDateAndFetch()},e.prototype.processDateSelection=function(){this.updateDateAndFetch(),this.showDatepicker=!1},e.prototype.onDateBlur=function(){this.pickerDate instanceof Date&&!isNaN(this.pickerDate.getTime())&&(this.processDateSelection(),this.$scope.$apply())},e.prototype.toggleDatepicker=function(e){void 0===e&&(e=null),this.showDatepicker=null!==e?e:!this.showDatepicker},e.prototype.updateDateAndFetch=function(){this.apiDate=(0,l.default)(this.pickerDate).format("YYYY-MM-DD"),this.apiDate!==this.previousApiDate&&(this.previousApiDate=this.apiDate,this.updateCurrentDateDisplay(),this.fetchMenu())},e.prototype.updateCurrentDateDisplay=function(){var e="en"===((0,o.session)().currentLanguage||"fr")?"en-US":"fr-FR";this.currentDate=this.pickerDate.toLocaleDateString(e,{weekday:"long",day:"2-digit",month:"long"}),this.currentDate=this.currentDate.charAt(0).toUpperCase()+this.currentDate.slice(1)},e.prototype.fetchMenu=function(){var e,t=this;if(!this.selectedUai)return this.data={entrees:[],plats:[],accompagnements:[],desserts:[],laitage:[]},this.menuUnavailable=!0,this.clearAllErrorFlags(),this.selectInstitutionError=!0,void(null===(e=this.apply)||void 0===e||e.call(this));c.default.get("/appregistry/".concat(this.selectedUai,"/cantine/menu?date=").concat(this.apiDate)).then(function(e){var i,n,a=null===(i=e.data)||void 0===i?void 0:i.menu;Array.isArray(a)&&a.length>0?(t.data={entrees:a.filter(function(e){return"entree"===e.type}),plats:a.filter(function(e){return"plat"===e.type}),accompagnements:a.filter(function(e){return"accompagnement"===e.type}),laitage:a.filter(function(e){return"laitage"===e.type}),desserts:a.filter(function(e){return"dessert"===e.type})},t.menuUnavailable=!1,t.error=null,t.selectInstitutionError=!1,t.menuNotAvailableError=!1,t.menuUnavailableForInstitutionError=!1,t.loadMenuError=!1,t.noStructuresError=!1,t.loadStructuresError=!1):(t.data={entrees:[],plats:[],accompagnements:[],desserts:[],laitage:[]},t.menuUnavailable=!0,t.clearAllErrorFlags(),t.menuNotAvailableError=!0,t.error=null),null===(n=t.apply)||void 0===n||n.call(t)}).catch(function(e){var i,n;t.data={entrees:[],plats:[],accompagnements:[],desserts:[],laitage:[]},400===(null===(i=e.response)||void 0===i?void 0:i.status)?(t.menuUnavailable=!0,t.clearAllErrorFlags(),t.menuUnavailableForInstitutionError=!0,t.error=null):(t.menuUnavailable=!0,t.clearAllErrorFlags(),t.loadMenuError=!0,t.error=e.message||"Unknown error"),null===(n=t.apply)||void 0===n||n.call(t)})},e.prototype.getAllergies=function(e){return e?Object.keys(e).filter(function(t){return t.startsWith("allerg_")&&0!==e[t]&&void 0!==e[t]}).map(function(e){return e.replace("allerg_","").replace("_"," ")}):[]},e.prototype.clearAllErrorFlags=function(){this.noStructuresError=!1,this.loadStructuresError=!1,this.selectInstitutionError=!1,this.menuNotAvailableError=!1,this.menuUnavailableForInstitutionError=!1,this.loadMenuError=!1},e.prototype.setupUaiDropdown=function(){if(this.schoolOptions.length>1){var e="en"===((0,o.session)().currentLanguage||"fr")?"Institution":"Établissement";this.schoolOptions.unshift({uai:"",name:e}),this.selectedUai=""}else 1===this.schoolOptions.length?(this.selectedUai=this.schoolOptions[0].uai,this.fetchMenu()):this.selectedUai=""},e}(),u=function(){function e(){this.restrict="E",this.template=i(4798).Z,this.scope={},this.bindToController=!0,this.controller=[g],this.controllerAs="ctrl",this.require=["odeCantineWidget"]}return e.prototype.link=function(e,t,i,r){return n(this,void 0,void 0,function(){var t;return a(this,function(i){return(t=null==r?void 0:r[0])&&(t.apply=function(){return e.$apply()}),[2]})})},e}();(0,o.notif)().onLangReady().promise.then(function(e){if("en"===e)(0,o.conf)().Platform.idiom.addKeys(i(4884));else(0,o.conf)().Platform.idiom.addKeys(i(4848))}),t.odeModuleName="odeCantineWidgetModule",s.default.module(t.odeModuleName,[]).directive("odeCantineWidget",function(){return new u})},4884:e=>{e.exports=JSON.parse('{"cantine.title":"Today\'s Menu","cantine.entree":"Starter","cantine.laitage":"Dairy","cantine.plat":"Main Course","cantine.accompagnement":"Side Dish","cantine.dessert":"Dessert","cantine.allergenes":"⚠️ Allergens","cantine.selectUai":"Institution","cantine.error.noStructures":"No structures found for user.","cantine.error.loadStructuresFailed":"Failed to load user structures.","cantine.error.selectInstitution":"Please select an institution.","cantine.error.menuNotAvailable":"Menu not available for this date.","cantine.error.menuUnavailableForInstitution":"Menu unavailable for this institution.","cantine.error.loadMenuFailed":"An error occurred while loading the menu."}')},4848:e=>{e.exports=JSON.parse('{"cantine.title":"Menu du jour","cantine.entree":"Entrée","cantine.laitage":"Laitage","cantine.plat":"Plat","cantine.accompagnement":"Accompagnement","cantine.dessert":"Dessert","cantine.allergenes":"⚠️ Allergènes","cantine.selectUai":"Établissement","cantine.error.noStructures":"Aucune structure trouvée pour l\'utilisateur.","cantine.error.loadStructuresFailed":"Échec du chargement des structures utilisateur.","cantine.error.selectInstitution":"Veuillez sélectionner un établissement.","cantine.error.menuNotAvailable":"Menu non disponible pour cette date.","cantine.error.menuUnavailableForInstitution":"Menu indisponible pour cet établissement.","cantine.error.loadMenuFailed":"Une erreur est survenue lors du chargement du menu."}')}}]);
|
|
2
2
|
//# sourceMappingURL=cantine-widget.widget.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"widgets/cantine-widget/cantine-widget.widget.js","mappings":"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","sources":["webpack://ode-ngjs-front/./src/ts/widgets/cantine-widget/cantine-widget.widget.html","webpack://ode-ngjs-front/./src/ts/widgets/cantine-widget/cantine-widget.widget.ts"],"sourcesContent":["// Module\nvar code = \"<style>.cantine-menu-card{color:#333;justify-content:center;align-items:center;padding:5%;border-radius:10px;box-shadow:0 0 10px rgba(0,0,0,.1)}.cantine-select-wrapper{display:flex;align-items:center;justify-content:center;gap:10px;margin-bottom:20px;font-family:Roboto,sans-serif;color:#333}.cantine-select-wrapper label{font-weight:700;font-size:1em}.cantine-select-wrapper select{padding:6px 10px;border-radius:5px;border:1px solid #ccc;font-size:.95em;font-family:Roboto,sans-serif;background-color:#fff;color:#333;box-shadow:0 2px 5px rgba(0,0,0,.05);transition:border-color .3s ease}.cantine-select-wrapper select:focus{outline:0;border-color:#f7955c}.cantine-select{padding:8px 12px;font-size:1em;border-radius:5px;border:1px solid #ccc;font-family:Roboto,sans-serif;background-color:#fff;color:#333;box-shadow:0 0 5px rgba(0,0,0,.05);max-width:100%}.menu-error-message{padding:1rem;color:#721c24;background-color:#f8d7da;border:1px solid #f5c6cb;border-radius:4px;margin-top:1rem}.cantine-separator{border:none;height:1px;background-color:#ccc;margin:3% 0}.cantine-section{margin-bottom:3%}.cantine-section-title{font-weight:700;font-size:1.1em;display:flex;align-items:center}.cantine-item{margin-left:1%;font-family:Roboto;color:#4a4a4a;font-size:medium}.cantine-item{align-items:center;gap:5px}.cantine-items-container{border-left:2px solid #ccc;margin-left:.8%;padding-left:3%}.cantine-icon{width:1em;height:1em;margin-left:5px;vertical-align:middle;display:inline-block;margin-bottom:10px}.cantine-dot{height:.6em;width:.6em;border-radius:50%;display:inline-block;margin-right:2%}.cantine-arrow-button{background:0 0;border:none;font-size:1.5em;cursor:pointer;opacity:.6;transition:opacity .3s ease}.cantine-arrow-button:hover{opacity:1}.cantine-arrow-button:focus{outline:0}.cantine-allergen-collapse{background-color:#f9f9f9;border-radius:5px;padding:0;display:none;transition:all .3s ease-in-out;font-size:.9em}.cantine-allergen-collapse.open{display:block}.cantine-collapse-toggle{background-color:#f7955c;border:none;padding:0 10px;border-radius:5px;font-weight:700;cursor:pointer;display:block;margin-top:0;color:#fff;font-size:.8em}.cantine-collapse-toggle:hover{background-color:#e6b848}.cantine-red{background-color:red}.cantine-green{background-color:green}.cantine-blue{background-color:#00f}.cantine-pink{background-color:pink}.cantine-yellow{background-color:orange}</style> <div class=\\\"widget-dashboard\\\"> <div class=\\\"cantine-menu-card\\\"> <h2 style=\\\"color:#333;font-family:Roboto,sans-serif;display:flex;align-items:center;justify-content:center;gap:10px\\\"> <i18n>cantine.title</i18n> </h2> <div class=\\\"cantine-separator\\\"></div> <div ng-if=\\\"ctrl.showUaiDropdown\\\"> <select id=\\\"uaiSelect\\\" class=\\\"form-control\\\" ng-model=\\\"ctrl.selectedUai\\\" ng-options=\\\"option.uai as option.name for option in ctrl.schoolOptions\\\" ng-change=\\\"ctrl.onUaiSelected()\\\"> <option value=\\\"\\\" disabled=\\\"disabled\\\" selected=\\\"selected\\\" hidden> <i18n>cantine.selectEtablissement</i18n> </option> </select> </div> <div class=\\\"cantine-date-navigation\\\" style=\\\"display:flex;align-items:center;justify-content:center;gap:10px;position:relative\\\"> <button class=\\\"cantine-arrow-button\\\" ng-click=\\\"ctrl.changeDate(-1)\\\">←</button> <span style=\\\"font-size:1.2em;font-weight:700;cursor:pointer\\\" ng-show=\\\"!ctrl.showDatepicker\\\" ng-click=\\\"ctrl.toggleDatepicker(true)\\\">{{ ctrl.currentDate }}</span> <input type=\\\"date\\\" ng-model=\\\"ctrl.pickerDate\\\" ng-blur=\\\"ctrl.onDateBlur()\\\" ng-show=\\\"ctrl.showDatepicker\\\" style=\\\"font-size:1.2em;font-weight:700;cursor:pointer;text-align:center\\\" ng-click=\\\"ctrl.toggleDatepicker(true)\\\"/> <button class=\\\"cantine-arrow-button\\\" ng-click=\\\"ctrl.changeDate(1)\\\">→</button> </div> <div ng-if=\\\"ctrl.selectedUai\\\"> <div ng-if=\\\"!ctrl.menuUnavailable\\\"> <div class=\\\"cantine-section\\\"> <div class=\\\"cantine-section-title\\\"> <span class=\\\"cantine-dot cantine-red\\\"></span> <i18n>cantine.entree</i18n> </div> <div class=\\\"cantine-items-container\\\"> <div class=\\\"cantine-item\\\" ng-repeat=\\\"item in ctrl.data.entrees\\\"> {{ item.designationMenu && item.designationMenu.trim() !== '' ? item.designationMenu : item.nom }} <img ng-if=\\\"item.bio\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/bio-logo.png\\\" alt=\\\"Bio\\\" class=\\\"cantine-icon\\\" title=\\\"Agriculture biologique\\\"> <img ng-if=\\\"item.faitmaison\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png\\\" alt=\\\"Fait Maison\\\" class=\\\"cantine-icon\\\" title=\\\"Fait maison\\\"> <img ng-if=\\\"item.vegetarien\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png\\\" alt=\\\"Vegetarian\\\" class=\\\"cantine-icon\\\" title=\\\"Végétarien\\\"> <img ng-if=\\\"item.local\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png\\\" alt=\\\"Local Product\\\" class=\\\"cantine-icon\\\" title=\\\"Produit local\\\"> <button class=\\\"cantine-collapse-toggle\\\" ng-click=\\\"item.showAllergies = !item.showAllergies\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <i18n>cantine.allergenes</i18n> </button> <div class=\\\"cantine-allergen-collapse\\\" ng-class=\\\"{'open': item.showAllergies}\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <span>{{ ctrl.getAllergies(item).join(', ') }}</span> </div> </div> </div> </div> <div class=\\\"cantine-section\\\"> <div class=\\\"cantine-section-title\\\"> <span class=\\\"cantine-dot cantine-green\\\"></span> <i18n>cantine.plat</i18n> </div> <div class=\\\"cantine-items-container\\\"> <div class=\\\"cantine-item\\\" ng-repeat=\\\"item in ctrl.data.plats\\\"> {{ item.designationMenu && item.designationMenu.trim() !== '' ? item.designationMenu : item.nom }} <img ng-if=\\\"item.bio\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/bio-logo.png\\\" alt=\\\"Bio\\\" class=\\\"cantine-icon\\\" title=\\\"Agriculture biologique\\\"> <img ng-if=\\\"item.faitmaison\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png\\\" alt=\\\"Fait Maison\\\" class=\\\"cantine-icon\\\" title=\\\"Fait maison\\\"> <img ng-if=\\\"item.vegetarien\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png\\\" alt=\\\"Vegetarian\\\" class=\\\"cantine-icon\\\" title=\\\"Végétarien\\\"> <img ng-if=\\\"item.local\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png\\\" alt=\\\"Local Product\\\" class=\\\"cantine-icon\\\" title=\\\"Produit local\\\"> <button class=\\\"cantine-collapse-toggle\\\" ng-click=\\\"item.showAllergies = !item.showAllergies\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <i18n>cantine.allergenes</i18n> </button> <div class=\\\"cantine-allergen-collapse\\\" ng-class=\\\"{'open': item.showAllergies}\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <span>{{ ctrl.getAllergies(item).join(', ') }}</span> </div> </div> </div> </div> <div class=\\\"cantine-section\\\"> <div class=\\\"cantine-section-title\\\"> <span class=\\\"cantine-dot cantine-blue\\\"></span> <i18n>cantine.accompagnement</i18n> </div> <div class=\\\"cantine-items-container\\\"> <div class=\\\"cantine-item\\\" ng-repeat=\\\"item in ctrl.data.accompagnements\\\"> {{ item.designationMenu && item.designationMenu.trim() !== '' ? item.designationMenu : item.nom }} <img ng-if=\\\"item.bio\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/bio-logo.png\\\" alt=\\\"Bio\\\" class=\\\"cantine-icon\\\" title=\\\"Agriculture biologique\\\"> <img ng-if=\\\"item.faitmaison\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png\\\" alt=\\\"Fait Maison\\\" class=\\\"cantine-icon\\\" title=\\\"Fait maison\\\"> <img ng-if=\\\"item.vegetarien\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png\\\" alt=\\\"Vegetarian\\\" class=\\\"cantine-icon\\\" title=\\\"Végétarien\\\"> <img ng-if=\\\"item.local\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png\\\" alt=\\\"Local Product\\\" class=\\\"cantine-icon\\\" title=\\\"Produit local\\\"> <button class=\\\"cantine-collapse-toggle\\\" ng-click=\\\"item.showAllergies = !item.showAllergies\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <i18n>cantine.allergenes</i18n> </button> <div class=\\\"cantine-allergen-collapse\\\" ng-class=\\\"{'open': item.showAllergies}\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <span>{{ ctrl.getAllergies(item).join(', ') }}</span> </div> </div> </div> </div> <div class=\\\"cantine-section\\\"> <div class=\\\"cantine-section-title\\\"> <span class=\\\"cantine-dot cantine-pink\\\"></span> <i18n>cantine.laitage</i18n> </div> <div class=\\\"cantine-items-container\\\"> <div class=\\\"cantine-item\\\" ng-repeat=\\\"item in ctrl.data.laitage\\\"> {{ item.designationMenu && item.designationMenu.trim() !== '' ? item.designationMenu : item.nom }} <img ng-if=\\\"item.bio\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/bio-logo.png\\\" alt=\\\"Bio\\\" class=\\\"cantine-icon\\\" title=\\\"Agriculture biologique\\\"> <img ng-if=\\\"item.faitmaison\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png\\\" alt=\\\"Fait Maison\\\" class=\\\"cantine-icon\\\" title=\\\"Fait maison\\\"> <img ng-if=\\\"item.vegetarien\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png\\\" alt=\\\"Vegetarian\\\" class=\\\"cantine-icon\\\" title=\\\"Végétarien\\\"> <img ng-if=\\\"item.local\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png\\\" alt=\\\"Local Product\\\" class=\\\"cantine-icon\\\" title=\\\"Produit local\\\"> <button class=\\\"cantine-collapse-toggle\\\" ng-click=\\\"item.showAllergies = !item.showAllergies\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <i18n>cantine.allergenes</i18n> </button> <div class=\\\"cantine-allergen-collapse\\\" ng-class=\\\"{'open': item.showAllergies}\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <span>{{ ctrl.getAllergies(item).join(', ') }}</span> </div> </div> </div> </div> <div class=\\\"cantine-section\\\"> <div class=\\\"cantine-section-title\\\"> <span class=\\\"cantine-dot cantine-yellow\\\"></span> <i18n>cantine.dessert</i18n> </div> <div class=\\\"cantine-items-container\\\"> <div class=\\\"cantine-item\\\" ng-repeat=\\\"item in ctrl.data.desserts\\\"> {{ item.designationMenu && item.designationMenu.trim() !== '' ? item.designationMenu : item.nom }} <img ng-if=\\\"item.bio\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/bio-logo.png\\\" alt=\\\"Bio\\\" class=\\\"cantine-icon\\\" title=\\\"Agriculture biologique\\\"> <img ng-if=\\\"item.faitmaison\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png\\\" alt=\\\"Fait Maison\\\" class=\\\"cantine-icon\\\" title=\\\"Fait maison\\\"> <img ng-if=\\\"item.vegetarien\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png\\\" alt=\\\"Vegetarian\\\" class=\\\"cantine-icon\\\" title=\\\"Végétarien\\\"> <img ng-if=\\\"item.local\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png\\\" alt=\\\"Local Product\\\" class=\\\"cantine-icon\\\" title=\\\"Produit local\\\"> <button class=\\\"cantine-collapse-toggle\\\" ng-click=\\\"item.showAllergies = !item.showAllergies\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <i18n>cantine.allergenes</i18n> </button> <div class=\\\"cantine-allergen-collapse\\\" ng-class=\\\"{'open': item.showAllergies}\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <span>{{ ctrl.getAllergies(item).join(', ') }}</span> </div> </div> </div> </div> </div> <div ng-if=\\\"ctrl.menuUnavailable\\\" class=\\\"menu-error-message\\\"> {{ ctrl.unavailableMessage }} </div> </div> </div> </div>\";\n// Exports\nexport default code;","import angular, { IAttributes, IController, IDirective, IScope } from \"angular\";\nimport { conf, notif, session } from \"../../utils\";\nimport moment from \"moment\";\nimport 'moment/locale/fr';\nimport axios from 'axios';\n\nclass Controller implements IController {\n data: any = {};\n error: string | null = null;\n uaiList: string[] = [];\n selectedUai: string = '';\n schoolOptions: { uai: string; name: string }[] = [];\n\n menuUnavailable: boolean = false;\n unavailableMessage: string = '';\n\n apiDate: string;\n currentDate: string = '';\n pickerDate: Date = new Date();\n showDatepicker: boolean = false;\n previousApiDate: string = '';\n\n public apply?: () => void;\n\n constructor(private $scope: IScope) {\n const user = session().user;\n\n this.apiDate = moment(this.pickerDate).format('YYYY-MM-DD');\n this.updateCurrentDateDisplay();\n\n const uaiFromSession = user.uai;\n if (Array.isArray(uaiFromSession) && uaiFromSession.length > 1) {\n this.loadUserStructures(user.userId);\n } else if (typeof uaiFromSession === 'string' || (Array.isArray(uaiFromSession) && uaiFromSession.length === 1)) {\n this.uaiList = Array.isArray(uaiFromSession) ? uaiFromSession : [uaiFromSession];\n const nameList = Array.isArray(user.structureNames) ? user.structureNames : [];\n\n this.schoolOptions = this.uaiList.map((uai, i) => ({ uai, name: nameList[i] || uai }));\n\n this.setupUaiDropdown(); // 🔹 call helper\n } else {\n this.uaiList = [];\n this.schoolOptions = [];\n this.selectedUai = '';\n }\n }\n\n onUaiSelected() {\n if (this.selectedUai) {\n this.fetchMenu();\n }\n }\n\n get showUaiDropdown(): boolean {\n return this.schoolOptions.length > 1;\n }\n\n async loadUserStructures(userId: string) {\n try {\n const { data } = await axios.get(`/directory/user/${userId}`);\n if (data && Array.isArray(data.structureNodes)) {\n this.schoolOptions = data.structureNodes.map((node: any) => ({\n uai: node.UAI,\n name: node.feederName || node.name || node.UAI,\n }));\n this.uaiList = this.schoolOptions.map(opt => opt.uai);\n\n this.setupUaiDropdown(); // 🔹 call helper\n this.apply?.();\n } else {\n this.error = \"No structures found for user.\";\n }\n } catch {\n this.error = \"Failed to load user structures.\";\n }\n }\n\n changeDate(delta: number): void {\n this.pickerDate.setDate(this.pickerDate.getDate() + delta);\n this.updateDateAndFetch();\n }\n\n processDateSelection(): void {\n this.updateDateAndFetch();\n this.showDatepicker = false;\n }\n\n onDateBlur(): void {\n if (this.pickerDate instanceof Date && !isNaN(this.pickerDate.getTime())) {\n this.processDateSelection();\n this.$scope.$apply();\n }\n }\n\n toggleDatepicker(forceOpen: boolean | null = null): void {\n if (forceOpen !== null) {\n this.showDatepicker = forceOpen;\n } else {\n this.showDatepicker = !this.showDatepicker;\n }\n }\n\n private updateDateAndFetch() {\n this.apiDate = moment(this.pickerDate).format('YYYY-MM-DD');\n if (this.apiDate !== this.previousApiDate) {\n this.previousApiDate = this.apiDate;\n this.updateCurrentDateDisplay();\n this.fetchMenu();\n }\n }\n\n private updateCurrentDateDisplay() {\n const options: Intl.DateTimeFormatOptions = {\n weekday: 'long',\n day: '2-digit',\n month: 'long',\n };\n this.currentDate = this.pickerDate.toLocaleDateString('fr-FR', options);\n this.currentDate = this.currentDate.charAt(0).toUpperCase() + this.currentDate.slice(1);\n }\n\n fetchMenu() {\n if (!this.selectedUai) {\n this.data = { entrees: [], plats: [], accompagnements: [], desserts: [], laitage: [] };\n this.menuUnavailable = true;\n this.unavailableMessage = \"Veuillez sélectionner un établissement.\";\n this.apply?.();\n return;\n }\n\n axios.get(`/appregistry/${this.selectedUai}/cantine/menu?date=${this.apiDate}`)\n .then(response => {\n const menu = response.data?.menu;\n\n if (Array.isArray(menu) && menu.length > 0) {\n this.data = {\n entrees: menu.filter((item: any) => item.type === \"entree\"),\n plats: menu.filter((item: any) => item.type === \"plat\"),\n accompagnements: menu.filter((item: any) => item.type === \"accompagnement\"),\n laitage: menu.filter((item: any) => item.type === \"laitage\"),\n desserts: menu.filter((item: any) => item.type === \"dessert\"),\n };\n this.menuUnavailable = false;\n this.error = null;\n this.unavailableMessage = '';\n } else {\n this.data = { entrees: [], plats: [], accompagnements: [], desserts: [], laitage: [] };\n this.menuUnavailable = true;\n this.unavailableMessage = \"Menu non disponible pour cette date.\";\n this.error = null;\n }\n\n this.apply?.();\n })\n .catch(error => {\n this.data = { entrees: [], plats: [], accompagnements: [], desserts: [], laitage: [] };\n\n if (error.response?.status === 400) {\n this.menuUnavailable = true;\n this.unavailableMessage = \"Menu indisponible pour cet établissement.\";\n this.error = null;\n } else {\n this.menuUnavailable = true;\n this.unavailableMessage = \"Une erreur est survenue lors du chargement du menu.\";\n this.error = error.message || \"Unknown error\";\n }\n\n this.apply?.();\n });\n }\n\n getAllergies(item: any): string[] {\n if (!item) return [];\n return Object.keys(item)\n .filter(k => k.startsWith(\"allerg_\") && item[k] !== 0 && item[k] !== undefined)\n .map(k => k.replace(\"allerg_\", \"\").replace(\"_\", \" \"));\n }\n\n // 🔹 New helper method\n private setupUaiDropdown() {\n if (this.schoolOptions.length > 1) {\n this.schoolOptions.unshift({ uai: '', name: 'Établissement' });\n this.selectedUai = '';\n } else if (this.schoolOptions.length === 1) {\n this.selectedUai = this.schoolOptions[0].uai;\n this.fetchMenu();\n } else {\n this.selectedUai = '';\n }\n }\n}\n\nclass Directive implements IDirective<IScope, JQLite, IAttributes, IController[]> {\n restrict = \"E\";\n template = require(\"./cantine-widget.widget.html\").default;\n scope = {};\n bindToController = true;\n controller = [Controller];\n controllerAs = \"ctrl\";\n require = [\"odeCantineWidget\"];\n\n async link(scope: IScope, elem: JQLite, attrs: IAttributes, controllers?: IController[]) {\n const ctrl = controllers?.[0] as Controller | undefined;\n if (ctrl) {\n ctrl.apply = () => scope.$apply();\n }\n }\n}\n\nfunction DirectiveFactory() {\n return new Directive();\n}\n\nnotif()\n .onLangReady()\n .promise.then(() => {\n conf().Platform.idiom.addKeys(require(\"./i18n/fr.json\"));\n });\n\nexport const odeModuleName = \"odeCantineWidgetModule\";\nangular.module(odeModuleName, []).directive(\"odeCantineWidget\", DirectiveFactory);\n"],"names":["$scope","data","error","uaiList","selectedUai","schoolOptions","menuUnavailable","unavailableMessage","currentDate","pickerDate","Date","showDatepicker","previousApiDate","user","session","this","apiDate","format","updateCurrentDateDisplay","uaiFromSession","uai","Array","isArray","length","loadUserStructures","userId","structureNames","map","i","name","setupUaiDropdown","onUaiSelected","fetchMenu","get","structureNodes","node","UAI","feederName","opt","apply","changeDate","delta","setDate","getDate","updateDateAndFetch","processDateSelection","onDateBlur","isNaN","getTime","$apply","toggleDatepicker","forceOpen","toLocaleDateString","weekday","day","month","charAt","toUpperCase","slice","entrees","plats","accompagnements","desserts","laitage","then","response","menu","filter","item","type","catch","status","message","getAllergies","Object","keys","k","startsWith","undefined","replace","unshift","restrict","template","scope","bindToController","controller","Controller","controllerAs","require","link","elem","attrs","controllers","ctrl","notif","onLangReady","promise","conf","Platform","idiom","addKeys","odeModuleName","module","directive","Directive"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"widgets/cantine-widget/cantine-widget.widget.js","mappings":"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","sources":["webpack://ode-ngjs-front/./src/ts/widgets/cantine-widget/cantine-widget.widget.html","webpack://ode-ngjs-front/./src/ts/widgets/cantine-widget/cantine-widget.widget.ts"],"sourcesContent":["// Module\nvar code = \"<style>.cantine-menu-card{color:#333;justify-content:center;align-items:center;padding:5%;border-radius:10px;box-shadow:0 0 10px rgba(0,0,0,.1)}.cantine-select-wrapper{display:flex;align-items:center;justify-content:center;gap:10px;margin-bottom:20px;font-family:Roboto,sans-serif;color:#333}.cantine-select-wrapper label{font-weight:700;font-size:1em}.cantine-select-wrapper select{padding:6px 10px;border-radius:5px;border:1px solid #ccc;font-size:.95em;font-family:Roboto,sans-serif;background-color:#fff;color:#333;box-shadow:0 2px 5px rgba(0,0,0,.05);transition:border-color .3s ease}.cantine-select-wrapper select:focus{outline:0;border-color:#f7955c}.cantine-select{padding:8px 12px;font-size:1em;border-radius:5px;border:1px solid #ccc;font-family:Roboto,sans-serif;background-color:#fff;color:#333;box-shadow:0 0 5px rgba(0,0,0,.05);max-width:100%}.menu-error-message{padding:1rem;color:#721c24;background-color:#f8d7da;border:1px solid #f5c6cb;border-radius:4px;margin-top:1rem}.cantine-separator{border:none;height:1px;background-color:#ccc;margin:3% 0}.cantine-section{margin-bottom:3%}.cantine-section-title{font-weight:700;font-size:1.1em;display:flex;align-items:center}.cantine-item{margin-left:1%;font-family:Roboto;color:#4a4a4a;font-size:medium}.cantine-item{align-items:center;gap:5px}.cantine-items-container{border-left:2px solid #ccc;margin-left:.8%;padding-left:3%}.cantine-icon{width:1em;height:1em;margin-left:5px;vertical-align:middle;display:inline-block;margin-bottom:10px}.cantine-dot{height:.6em;width:.6em;border-radius:50%;display:inline-block;margin-right:2%}.cantine-arrow-button{background:0 0;border:none;font-size:1.5em;cursor:pointer;opacity:.6;transition:opacity .3s ease}.cantine-arrow-button:hover{opacity:1}.cantine-arrow-button:focus{outline:0}.cantine-allergen-collapse{background-color:#f9f9f9;border-radius:5px;padding:0;display:none;transition:all .3s ease-in-out;font-size:.9em}.cantine-allergen-collapse.open{display:block}.cantine-collapse-toggle{background-color:#f7955c;border:none;padding:0 10px;border-radius:5px;font-weight:700;cursor:pointer;display:block;margin-top:0;color:#fff;font-size:.8em}.cantine-collapse-toggle:hover{background-color:#e6b848}.cantine-red{background-color:red}.cantine-green{background-color:green}.cantine-blue{background-color:#00f}.cantine-pink{background-color:pink}.cantine-yellow{background-color:orange}</style> <div class=\\\"widget-dashboard\\\"> <div class=\\\"cantine-menu-card\\\"> <h2 style=\\\"color:#333;font-family:Roboto,sans-serif;display:flex;align-items:center;justify-content:center;gap:10px\\\"> <i18n>cantine.title</i18n> </h2> <div class=\\\"cantine-separator\\\"></div> <div ng-if=\\\"ctrl.noStructuresError\\\" class=\\\"menu-error-message\\\"> <i18n>cantine.error.noStructures</i18n> </div> <div ng-if=\\\"ctrl.loadStructuresError\\\" class=\\\"menu-error-message\\\"> <i18n>cantine.error.loadStructuresFailed</i18n> </div> <div ng-if=\\\"ctrl.showUaiDropdown\\\"> <select id=\\\"uaiSelect\\\" class=\\\"form-control\\\" ng-model=\\\"ctrl.selectedUai\\\" ng-options=\\\"option.uai as option.name for option in ctrl.schoolOptions\\\" ng-change=\\\"ctrl.onUaiSelected()\\\"> <option value=\\\"\\\" disabled=\\\"disabled\\\" selected=\\\"selected\\\" hidden> <i18n>cantine.selectEtablissement</i18n> </option> </select> </div> <div class=\\\"cantine-date-navigation\\\" style=\\\"display:flex;align-items:center;justify-content:center;gap:10px;position:relative\\\"> <button class=\\\"cantine-arrow-button\\\" ng-click=\\\"ctrl.changeDate(-1)\\\">←</button> <span style=\\\"font-size:1.2em;font-weight:700;cursor:pointer\\\" ng-show=\\\"!ctrl.showDatepicker\\\" ng-click=\\\"ctrl.toggleDatepicker(true)\\\">{{ ctrl.currentDate }}</span> <input type=\\\"date\\\" ng-model=\\\"ctrl.pickerDate\\\" ng-blur=\\\"ctrl.onDateBlur()\\\" ng-show=\\\"ctrl.showDatepicker\\\" style=\\\"font-size:1.2em;font-weight:700;cursor:pointer;text-align:center\\\" ng-click=\\\"ctrl.toggleDatepicker(true)\\\"/> <button class=\\\"cantine-arrow-button\\\" ng-click=\\\"ctrl.changeDate(1)\\\">→</button> </div> <div ng-if=\\\"ctrl.selectedUai\\\"> <div ng-if=\\\"!ctrl.menuUnavailable\\\"> <div class=\\\"cantine-section\\\"> <div class=\\\"cantine-section-title\\\"> <span class=\\\"cantine-dot cantine-red\\\"></span> <i18n>cantine.entree</i18n> </div> <div class=\\\"cantine-items-container\\\"> <div class=\\\"cantine-item\\\" ng-repeat=\\\"item in ctrl.data.entrees\\\"> {{ item.designationMenu && item.designationMenu.trim() !== '' ? item.designationMenu : item.nom }} <img ng-if=\\\"item.bio\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/bio-logo.png\\\" alt=\\\"Bio\\\" class=\\\"cantine-icon\\\" title=\\\"Agriculture biologique\\\"> <img ng-if=\\\"item.faitmaison\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png\\\" alt=\\\"Fait Maison\\\" class=\\\"cantine-icon\\\" title=\\\"Fait maison\\\"> <img ng-if=\\\"item.vegetarien\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png\\\" alt=\\\"Vegetarian\\\" class=\\\"cantine-icon\\\" title=\\\"Végétarien\\\"> <img ng-if=\\\"item.local\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png\\\" alt=\\\"Local Product\\\" class=\\\"cantine-icon\\\" title=\\\"Produit local\\\"> <button class=\\\"cantine-collapse-toggle\\\" ng-click=\\\"item.showAllergies = !item.showAllergies\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <i18n>cantine.allergenes</i18n> </button> <div class=\\\"cantine-allergen-collapse\\\" ng-class=\\\"{'open': item.showAllergies}\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <span>{{ ctrl.getAllergies(item).join(', ') }}</span> </div> </div> </div> </div> <div class=\\\"cantine-section\\\"> <div class=\\\"cantine-section-title\\\"> <span class=\\\"cantine-dot cantine-green\\\"></span> <i18n>cantine.plat</i18n> </div> <div class=\\\"cantine-items-container\\\"> <div class=\\\"cantine-item\\\" ng-repeat=\\\"item in ctrl.data.plats\\\"> {{ item.designationMenu && item.designationMenu.trim() !== '' ? item.designationMenu : item.nom }} <img ng-if=\\\"item.bio\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/bio-logo.png\\\" alt=\\\"Bio\\\" class=\\\"cantine-icon\\\" title=\\\"Agriculture biologique\\\"> <img ng-if=\\\"item.faitmaison\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png\\\" alt=\\\"Fait Maison\\\" class=\\\"cantine-icon\\\" title=\\\"Fait maison\\\"> <img ng-if=\\\"item.vegetarien\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png\\\" alt=\\\"Vegetarian\\\" class=\\\"cantine-icon\\\" title=\\\"Végétarien\\\"> <img ng-if=\\\"item.local\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png\\\" alt=\\\"Local Product\\\" class=\\\"cantine-icon\\\" title=\\\"Produit local\\\"> <button class=\\\"cantine-collapse-toggle\\\" ng-click=\\\"item.showAllergies = !item.showAllergies\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <i18n>cantine.allergenes</i18n> </button> <div class=\\\"cantine-allergen-collapse\\\" ng-class=\\\"{'open': item.showAllergies}\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <span>{{ ctrl.getAllergies(item).join(', ') }}</span> </div> </div> </div> </div> <div class=\\\"cantine-section\\\"> <div class=\\\"cantine-section-title\\\"> <span class=\\\"cantine-dot cantine-blue\\\"></span> <i18n>cantine.accompagnement</i18n> </div> <div class=\\\"cantine-items-container\\\"> <div class=\\\"cantine-item\\\" ng-repeat=\\\"item in ctrl.data.accompagnements\\\"> {{ item.designationMenu && item.designationMenu.trim() !== '' ? item.designationMenu : item.nom }} <img ng-if=\\\"item.bio\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/bio-logo.png\\\" alt=\\\"Bio\\\" class=\\\"cantine-icon\\\" title=\\\"Agriculture biologique\\\"> <img ng-if=\\\"item.faitmaison\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png\\\" alt=\\\"Fait Maison\\\" class=\\\"cantine-icon\\\" title=\\\"Fait maison\\\"> <img ng-if=\\\"item.vegetarien\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png\\\" alt=\\\"Vegetarian\\\" class=\\\"cantine-icon\\\" title=\\\"Végétarien\\\"> <img ng-if=\\\"item.local\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png\\\" alt=\\\"Local Product\\\" class=\\\"cantine-icon\\\" title=\\\"Produit local\\\"> <button class=\\\"cantine-collapse-toggle\\\" ng-click=\\\"item.showAllergies = !item.showAllergies\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <i18n>cantine.allergenes</i18n> </button> <div class=\\\"cantine-allergen-collapse\\\" ng-class=\\\"{'open': item.showAllergies}\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <span>{{ ctrl.getAllergies(item).join(', ') }}</span> </div> </div> </div> </div> <div class=\\\"cantine-section\\\"> <div class=\\\"cantine-section-title\\\"> <span class=\\\"cantine-dot cantine-pink\\\"></span> <i18n>cantine.laitage</i18n> </div> <div class=\\\"cantine-items-container\\\"> <div class=\\\"cantine-item\\\" ng-repeat=\\\"item in ctrl.data.laitage\\\"> {{ item.designationMenu && item.designationMenu.trim() !== '' ? item.designationMenu : item.nom }} <img ng-if=\\\"item.bio\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/bio-logo.png\\\" alt=\\\"Bio\\\" class=\\\"cantine-icon\\\" title=\\\"Agriculture biologique\\\"> <img ng-if=\\\"item.faitmaison\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png\\\" alt=\\\"Fait Maison\\\" class=\\\"cantine-icon\\\" title=\\\"Fait maison\\\"> <img ng-if=\\\"item.vegetarien\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png\\\" alt=\\\"Vegetarian\\\" class=\\\"cantine-icon\\\" title=\\\"Végétarien\\\"> <img ng-if=\\\"item.local\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png\\\" alt=\\\"Local Product\\\" class=\\\"cantine-icon\\\" title=\\\"Produit local\\\"> <button class=\\\"cantine-collapse-toggle\\\" ng-click=\\\"item.showAllergies = !item.showAllergies\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <i18n>cantine.allergenes</i18n> </button> <div class=\\\"cantine-allergen-collapse\\\" ng-class=\\\"{'open': item.showAllergies}\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <span>{{ ctrl.getAllergies(item).join(', ') }}</span> </div> </div> </div> </div> <div class=\\\"cantine-section\\\"> <div class=\\\"cantine-section-title\\\"> <span class=\\\"cantine-dot cantine-yellow\\\"></span> <i18n>cantine.dessert</i18n> </div> <div class=\\\"cantine-items-container\\\"> <div class=\\\"cantine-item\\\" ng-repeat=\\\"item in ctrl.data.desserts\\\"> {{ item.designationMenu && item.designationMenu.trim() !== '' ? item.designationMenu : item.nom }} <img ng-if=\\\"item.bio\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/bio-logo.png\\\" alt=\\\"Bio\\\" class=\\\"cantine-icon\\\" title=\\\"Agriculture biologique\\\"> <img ng-if=\\\"item.faitmaison\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/fait-maison-logo.png\\\" alt=\\\"Fait Maison\\\" class=\\\"cantine-icon\\\" title=\\\"Fait maison\\\"> <img ng-if=\\\"item.vegetarien\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/vegetarien-logo.png\\\" alt=\\\"Vegetarian\\\" class=\\\"cantine-icon\\\" title=\\\"Végétarien\\\"> <img ng-if=\\\"item.local\\\" src=\\\"/assets/widgets/cantine-widget/cantine-logos/produit-local-logo.png\\\" alt=\\\"Local Product\\\" class=\\\"cantine-icon\\\" title=\\\"Produit local\\\"> <button class=\\\"cantine-collapse-toggle\\\" ng-click=\\\"item.showAllergies = !item.showAllergies\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <i18n>cantine.allergenes</i18n> </button> <div class=\\\"cantine-allergen-collapse\\\" ng-class=\\\"{'open': item.showAllergies}\\\" ng-if=\\\"ctrl.getAllergies(item).length > 0\\\"> <span>{{ ctrl.getAllergies(item).join(', ') }}</span> </div> </div> </div> </div> </div> <div ng-if=\\\"ctrl.menuUnavailable\\\" class=\\\"menu-error-message\\\"> <div ng-if=\\\"ctrl.selectInstitutionError\\\"> <i18n>cantine.error.selectInstitution</i18n> </div> <div ng-if=\\\"ctrl.menuNotAvailableError\\\"> <i18n>cantine.error.menuNotAvailable</i18n> </div> <div ng-if=\\\"ctrl.menuUnavailableForInstitutionError\\\"> <i18n>cantine.error.menuUnavailableForInstitution</i18n> </div> <div ng-if=\\\"ctrl.loadMenuError\\\"> <i18n>cantine.error.loadMenuFailed</i18n> </div> </div> </div> </div> </div>\";\n// Exports\nexport default code;","import angular, { IAttributes, IController, IDirective, IScope } from \"angular\";\nimport { conf, notif, session } from \"../../utils\";\nimport moment from \"moment\";\nimport 'moment/locale/fr';\nimport axios from 'axios';\n\nclass Controller implements IController {\n data: any = {};\n error: string | null = null;\n uaiList: string[] = [];\n selectedUai: string = '';\n schoolOptions: { uai: string; name: string }[] = [];\n\n menuUnavailable: boolean = false;\n noStructuresError: boolean = false;\n loadStructuresError: boolean = false;\n selectInstitutionError: boolean = false;\n menuNotAvailableError: boolean = false;\n menuUnavailableForInstitutionError: boolean = false;\n loadMenuError: boolean = false;\n\n apiDate: string;\n currentDate: string = '';\n pickerDate: Date = new Date();\n showDatepicker: boolean = false;\n previousApiDate: string = '';\n\n public apply?: () => void;\n\n constructor(private $scope: IScope) {\n const user = session().user;\n\n this.apiDate = moment(this.pickerDate).format('YYYY-MM-DD');\n this.updateCurrentDateDisplay();\n\n const uaiFromSession = user.uai;\n if (Array.isArray(uaiFromSession) && uaiFromSession.length > 1) {\n this.loadUserStructures(user.userId);\n } else if (typeof uaiFromSession === 'string' || (Array.isArray(uaiFromSession) && uaiFromSession.length === 1)) {\n this.uaiList = Array.isArray(uaiFromSession) ? uaiFromSession : [uaiFromSession];\n const nameList = Array.isArray(user.structureNames) ? user.structureNames : [];\n\n this.schoolOptions = this.uaiList.map((uai, i) => ({ uai, name: nameList[i] || uai }));\n\n this.setupUaiDropdown(); // 🔹 call helper\n } else {\n this.uaiList = [];\n this.schoolOptions = [];\n this.selectedUai = '';\n }\n }\n\n onUaiSelected() {\n if (this.selectedUai) {\n this.fetchMenu();\n }\n }\n\n get showUaiDropdown(): boolean {\n return this.schoolOptions.length > 1;\n }\n\n async loadUserStructures(userId: string) {\n try {\n const { data } = await axios.get(`/directory/user/${userId}`);\n if (data && Array.isArray(data.structureNodes)) {\n this.schoolOptions = data.structureNodes.map((node: any) => ({\n uai: node.UAI,\n name: node.feederName || node.name || node.UAI,\n }));\n this.uaiList = this.schoolOptions.map(opt => opt.uai);\n\n this.setupUaiDropdown(); // 🔹 call helper\n this.apply?.();\n } else {\n this.clearAllErrorFlags();\n this.noStructuresError = true;\n }\n } catch {\n this.clearAllErrorFlags();\n this.loadStructuresError = true;\n }\n }\n\n changeDate(delta: number): void {\n this.pickerDate.setDate(this.pickerDate.getDate() + delta);\n this.updateDateAndFetch();\n }\n\n processDateSelection(): void {\n this.updateDateAndFetch();\n this.showDatepicker = false;\n }\n\n onDateBlur(): void {\n if (this.pickerDate instanceof Date && !isNaN(this.pickerDate.getTime())) {\n this.processDateSelection();\n this.$scope.$apply();\n }\n }\n\n toggleDatepicker(forceOpen: boolean | null = null): void {\n if (forceOpen !== null) {\n this.showDatepicker = forceOpen;\n } else {\n this.showDatepicker = !this.showDatepicker;\n }\n }\n\n private updateDateAndFetch() {\n this.apiDate = moment(this.pickerDate).format('YYYY-MM-DD');\n if (this.apiDate !== this.previousApiDate) {\n this.previousApiDate = this.apiDate;\n this.updateCurrentDateDisplay();\n this.fetchMenu();\n }\n }\n\n private updateCurrentDateDisplay() {\n const options: Intl.DateTimeFormatOptions = {\n weekday: 'long',\n day: '2-digit',\n month: 'long',\n };\n \n // Get current language from session or default to French\n const currentLang = session().currentLanguage || 'fr';\n const locale = currentLang === 'en' ? 'en-US' : 'fr-FR';\n \n this.currentDate = this.pickerDate.toLocaleDateString(locale, options);\n this.currentDate = this.currentDate.charAt(0).toUpperCase() + this.currentDate.slice(1);\n }\n\n fetchMenu() {\n if (!this.selectedUai) {\n this.data = { entrees: [], plats: [], accompagnements: [], desserts: [], laitage: [] };\n this.menuUnavailable = true;\n this.clearAllErrorFlags();\n this.selectInstitutionError = true;\n this.apply?.();\n return;\n }\n\n axios.get(`/appregistry/${this.selectedUai}/cantine/menu?date=${this.apiDate}`)\n .then(response => {\n const menu = response.data?.menu;\n\n if (Array.isArray(menu) && menu.length > 0) {\n this.data = {\n entrees: menu.filter((item: any) => item.type === \"entree\"),\n plats: menu.filter((item: any) => item.type === \"plat\"),\n accompagnements: menu.filter((item: any) => item.type === \"accompagnement\"),\n laitage: menu.filter((item: any) => item.type === \"laitage\"),\n desserts: menu.filter((item: any) => item.type === \"dessert\"),\n };\n this.menuUnavailable = false;\n this.error = null;\n this.selectInstitutionError = false;\n this.menuNotAvailableError = false;\n this.menuUnavailableForInstitutionError = false;\n this.loadMenuError = false;\n this.noStructuresError = false;\n this.loadStructuresError = false;\n } else {\n this.data = { entrees: [], plats: [], accompagnements: [], desserts: [], laitage: [] };\n this.menuUnavailable = true;\n this.clearAllErrorFlags();\n this.menuNotAvailableError = true;\n this.error = null;\n }\n\n this.apply?.();\n })\n .catch(error => {\n this.data = { entrees: [], plats: [], accompagnements: [], desserts: [], laitage: [] };\n\n if (error.response?.status === 400) {\n this.menuUnavailable = true;\n this.clearAllErrorFlags();\n this.menuUnavailableForInstitutionError = true;\n this.error = null;\n } else {\n this.menuUnavailable = true;\n this.clearAllErrorFlags();\n this.loadMenuError = true;\n this.error = error.message || \"Unknown error\";\n }\n\n this.apply?.();\n });\n }\n\n getAllergies(item: any): string[] {\n if (!item) return [];\n return Object.keys(item)\n .filter(k => k.startsWith(\"allerg_\") && item[k] !== 0 && item[k] !== undefined)\n .map(k => k.replace(\"allerg_\", \"\").replace(\"_\", \" \"));\n }\n\n // 🔹 Helper method to clear all error flags\n private clearAllErrorFlags() {\n this.noStructuresError = false;\n this.loadStructuresError = false;\n this.selectInstitutionError = false;\n this.menuNotAvailableError = false;\n this.menuUnavailableForInstitutionError = false;\n this.loadMenuError = false;\n }\n\n // 🔹 New helper method\n private setupUaiDropdown() {\n if (this.schoolOptions.length > 1) {\n const currentLang = session().currentLanguage || 'fr';\n const institutionText = currentLang === 'en' ? 'Institution' : 'Établissement';\n this.schoolOptions.unshift({ uai: '', name: institutionText });\n this.selectedUai = '';\n } else if (this.schoolOptions.length === 1) {\n this.selectedUai = this.schoolOptions[0].uai;\n this.fetchMenu();\n } else {\n this.selectedUai = '';\n }\n }\n}\n\nclass Directive implements IDirective<IScope, JQLite, IAttributes, IController[]> {\n restrict = \"E\";\n template = require(\"./cantine-widget.widget.html\").default;\n scope = {};\n bindToController = true;\n controller = [Controller];\n controllerAs = \"ctrl\";\n require = [\"odeCantineWidget\"];\n\n async link(scope: IScope, elem: JQLite, attrs: IAttributes, controllers?: IController[]) {\n const ctrl = controllers?.[0] as Controller | undefined;\n if (ctrl) {\n ctrl.apply = () => scope.$apply();\n }\n }\n}\n\nfunction DirectiveFactory() {\n return new Directive();\n}\n\nnotif()\n .onLangReady()\n .promise.then((lang: any): void => {\n switch (lang) {\n case \"en\":\n conf().Platform.idiom.addKeys(require(\"./i18n/en.json\"));\n break;\n default:\n conf().Platform.idiom.addKeys(require(\"./i18n/fr.json\"));\n break;\n }\n });\n\nexport const odeModuleName = \"odeCantineWidgetModule\";\nangular.module(odeModuleName, []).directive(\"odeCantineWidget\", DirectiveFactory);\n"],"names":["$scope","data","error","uaiList","selectedUai","schoolOptions","menuUnavailable","noStructuresError","loadStructuresError","selectInstitutionError","menuNotAvailableError","menuUnavailableForInstitutionError","loadMenuError","currentDate","pickerDate","Date","showDatepicker","previousApiDate","user","session","this","apiDate","format","updateCurrentDateDisplay","uaiFromSession","uai","Array","isArray","length","loadUserStructures","userId","structureNames","map","i","name","setupUaiDropdown","onUaiSelected","fetchMenu","get","structureNodes","node","UAI","feederName","opt","apply","clearAllErrorFlags","changeDate","delta","setDate","getDate","updateDateAndFetch","processDateSelection","onDateBlur","isNaN","getTime","$apply","toggleDatepicker","forceOpen","locale","currentLanguage","toLocaleDateString","weekday","day","month","charAt","toUpperCase","slice","entrees","plats","accompagnements","desserts","laitage","then","response","menu","filter","item","type","catch","status","message","getAllergies","Object","keys","k","startsWith","undefined","replace","institutionText","unshift","restrict","template","scope","bindToController","controller","Controller","controllerAs","require","link","elem","attrs","controllers","ctrl","notif","onLangReady","promise","lang","conf","Platform","idiom","addKeys","odeModuleName","module","directive","Directive"],"sourceRoot":""}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";(self.webpackChunkode_ngjs_front=self.webpackChunkode_ngjs_front||[]).push([[443],{7601:(t,e,r)=>{r.d(e,{Z:()=>i});const i='<style>.ptit-observatoire-widget-container{box-sizing:border-box;background:#358284;padding:10px;border-radius:6px;overflow:hidden}.ptit-observatoire-widget-content{display:flex;flex-direction:column;gap:10px;box-sizing:border-box;width:100%;height:100%;background-color:#fff;border-radius:3px;padding:10px}.ptit-observatoire-widget-form{width:100%;display:flex;flex-direction:column;gap:10px}.ptit-observatoire-widget-select{background-color:#fff;padding:15px;border:1px solid #c1c1ca;color:#c1c1ca;border-radius:10px}.ptit-observatoire-submit-button{display:flex;align-items:center;gap:10px;background-color:#173a37;color:#fff;border:none;padding:10px 15px;border-radius:30px}.ptit-observatoire-plus-icon{display:flex;align-items:center;justify-content:center;line-height:100%;text-align:center;background-color:#2c6262;border-radius:50%;width:30px;height:30px}.ptit-observatoire-modal-form{display:flex;flex-direction:column;gap:15px}.ptit-observatoire-modal-form-legend{text-transform:uppercase;color:#7caaac;font-weight:700}.ptit-observatoire-modal-form-textarea{width:100%}.ptit-observatoire-modal-options-container{display:flex;flex-wrap:wrap;gap:5px}</style> <div class="ptit-observatoire-widget-container"> <div class="ptit-observatoire-widget-content"> <p> <i18n>ptitObservatoire.title</i18n> </p> <div class="widget-body" dnd-nodrag> <form class="ptit-observatoire-widget-form" ng-submit="ctrl.startObservation()"> <select class="ptit-observatoire-widget-select" name="student" ng-model="ctrl.formData.student_id"> <option value="" selected="selected"> </option> <option ng-repeat="student in ctrl.studentsList" value="{{student.id}}"> {{student.fullName}} </option> </select> <button type="submit" class="ptit-observatoire-submit-button"> <span class="ptit-observatoire-plus-icon">+</span> <span> <i18n>ptitObservatoire.newObservation</i18n> </span> </button> </form> </div> </div> <ode-modal visible="ctrl.showLightbox" on-close="ctrl.showLightbox=false" size="lg" dnd-nodrag> <ode-modal-title> <h2> <i18n>ptitObservatoire.modal.title</i18n> </h2> </ode-modal-title> <ode-modal-body> <form class="ptit-observatoire-modal-form" ng-submit="ctrl.handleObservationSubmit(); ctrl.showLightbox=false"> <fieldset> <legend class="ptit-observatoire-modal-form-legend"> <i18n>ptitObservatoire.modal.observation</i18n> </legend> <textarea class="ptit-observatoire-modal-form-textarea" name="content" ng-model="ctrl.formData[\'content\']" i18n-placeholder="ptitObservatoire.modal.textarea.placeholder"></textarea> </fieldset> <fieldset> <legend class="ptit-observatoire-modal-form-legend"> <i18n>ptitObservatoire.modal.evaluation</i18n> </legend> <label for="strengths"> <input type="radio" id="strength" name="assessment_type" ng-model="ctrl.formData[\'assessment_type\']" ng-value="\'strength\'"/> <i18n>ptitObservatoire.modal.evaluation.strength</i18n> </label> <label for="neutral"> <input type="radio" id="neutral" name="assessment_type" ng-model="ctrl.formData[\'assessment_type\']" ng-value="\'neutral\'"/> <i18n>ptitObservatoire.modal.evaluation.neutral</i18n> </label> <label for="difficulties"> <input type="radio" id="difficulties" name="assessment_type" ng-model="ctrl.formData[\'assessment_type\']" ng-value="\'difficulties\'"/> <i18n>ptitObservatoire.modal.evaluation.difficulties</i18n> </label> </fieldset> <fieldset> <legend class="ptit-observatoire-modal-form-legend"> <i18n>ptitObservatoire.modal.categories</i18n> </legend> <div class="ptit-observatoire-modal-options-container"> <label ng-repeat="category in ctrl.observationCategories"> <input type="radio" name="{{category.name}}" ng-model="ctrl.formData[\'category_id\']" ng-value="category.id"/> {{ category.name }} </label> </div> </fieldset> <fieldset> <legend class="ptit-observatoire-modal-form-legend"> <i18n>ptitObservatoire.modal.options</i18n> </legend> <label> <input type="checkbox" ng-model="ctrl.formData[\'private\']"/> <i18n>ptitObservatoire.modal.options.private</i18n> </label> </fieldset> <button type="submit" class="ptit-observatoire-submit-button"> <i18n>ptitObservatoire.modal.save</i18n> </button> </form> </ode-modal-body> </ode-modal> </div>'},5883:function(t,e,r){var i=this&&this.__assign||function(){return i=Object.assign||function(t){for(var e,r=1,i=arguments.length;r<i;r++)for(var o in e=arguments[r])Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t},i.apply(this,arguments)},o=this&&this.__awaiter||function(t,e,r,i){return new(r||(r=Promise))(function(o,n){function a(t){try{l(i.next(t))}catch(t){n(t)}}function s(t){try{l(i.throw(t))}catch(t){n(t)}}function l(t){var e;t.done?o(t.value):(e=t.value,e instanceof r?e:new r(function(t){t(e)})).then(a,s)}l((i=i.apply(t,e||[])).next())})},n=this&&this.__generator||function(t,e){var r,i,o,n,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return n={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(n[Symbol.iterator]=function(){return this}),n;function s(n){return function(s){return function(n){if(r)throw new TypeError("Generator is already executing.");for(;a;)try{if(r=1,i&&(o=2&n[0]?i.return:n[0]?i.throw||((o=i.return)&&o.call(i),0):i.next)&&!(o=o.call(i,n[1])).done)return o;switch(i=0,o&&(n=[2&n[0],o.value]),n[0]){case 0:case 1:o=n;break;case 4:return a.label++,{value:n[1],done:!1};case 5:a.label++,i=n[1],n=[0];continue;case 7:n=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==n[0]&&2!==n[0])){a=0;continue}if(3===n[0]&&(!o||n[1]>o[0]&&n[1]<o[3])){a.label=n[1];break}if(6===n[0]&&a.label<o[1]){a.label=o[1],o=n;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(n);break}o[2]&&a.ops.pop(),a.trys.pop();continue}n=e.call(t,a)}catch(t){n=[6,t],i=0}finally{r=o=0}if(5&n[0])throw n[1];return{value:n[0]?n[1]:void 0,done:!0}}([n,s])}}},a=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.odeModuleName=void 0;var s=a(r(4202)),l=r(9419),d=r(6731),c=function(){function t(){this.formData={},this.observationCategories=[],this.studentsList=[],this.showLightbox=!1}return t.prototype.startObservation=function(){this.formData.student_id&&(this.showLightbox=!0)},t.prototype.handleObservationSubmit=function(){return o(this,void 0,void 0,function(){var t;return n(this,function(e){switch(e.label){case 0:return t={data:{type:"observations",attributes:i(i({},this.formData),{teacher_id:1,date:(new Date).toISOString().substring(0,10)})}},[4,this.saveObservation(t)];case 1:return e.sent(),[2]}})})},t.prototype.saveObservation=function(t){return o(this,void 0,void 0,function(){var e;return n(this,function(r){switch(r.label){case 0:return r.trys.push([0,2,,3]),[4,(0,l.http)().postJson("/appregistry/ptitObservatoire/observations",t)];case 1:return r.sent(),d.notify.success("ptitObservatoire.notify.save.success"),[3,3];case 2:return e=r.sent(),console.error("Error saving observation:",e),d.notify.error("ptitObservatoire.notify.save.error"),[3,3];case 3:return[2]}})})},t}(),u=function(){function t(){this.restrict="E",this.template=r(7601).Z,this.scope={},this.bindToController=!0,this.controller=[c],this.controllerAs="ctrl",this.require=["odePtitObservatoireWidget"]}return t.prototype.link=function(t,e,r,i){return o(this,void 0,void 0,function(){var e,r;return n(this,function(o){switch(o.label){case 0:return(e=i?i[0]:null)?[4,Promise.all([this.getObservationCategories(),this.getStudentsList()])]:[2];case 1:return r=o.sent(),e.observationCategories=r[0],e.studentsList=r[1],t.$applyAsync(),[2]}})})},t.prototype.getStudentsList=function(){return o(this,void 0,void 0,function(){var t;return n(this,function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),[4,(0,l.http)().get("/appregistry/ptitObservatoire/students")];case 1:return[2,e.sent().map(function(t){return{id:t.id,fullName:t.attributes.full_name}})];case 2:return t=e.sent(),console.error("Error fetching students:",t),[2,[]];case 3:return[2]}})})},t.prototype.getObservationCategories=function(){return o(this,void 0,void 0,function(){var t;return n(this,function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),[4,(0,l.http)().get("/appregistry/ptitObservatoire/observations/categories")];case 1:return[2,e.sent().map(function(t){return{id:t.id,name:t.attributes.name}})];case 2:return t=e.sent(),console.error("Error fetching categories:",t),[2,[]];case 3:return[2]}})})},t}();(0,l.notif)().onLangReady().promise.then(function(t){(0,l.conf)().Platform.idiom.addKeys(r(5512))}),e.odeModuleName="odePtitObservatoireWidgetModule",s.default.module(e.odeModuleName,[]).directive("odePtitObservatoireWidget",function(){return new u})},5512:t=>{t.exports=JSON.parse('{"ptitObservatoire.title":"Centraliser mes observations","ptitObservatoire.newObservation":"Nouvelle observation","ptitObservatoire.selectStudent":"Sélectionner un élève","ptitObservatoire.modal.title":"Saisie de l\'Observation","ptitObservatoire.modal.observation":"Observation","ptitObservatoire.modal.evaluation":"Évaluation","ptitObservatoire.modal.evaluation.strength":"Forces","ptitObservatoire.modal.evaluation.neutral":"Neutre","ptitObservatoire.modal.evaluation.difficulties":"Difficultés","ptitObservatoire.modal.categories":"Catégories","ptitObservatoire.modal.options":"Options","ptitObservatoire.modal.options.private":"Observation privée","ptitObservatoire.modal.save":"Enregistrer l\'observation","ptitObservatoire.notify.save.success":"Observation enregistrée avec succès","ptitObservatoire.notify.save.error":"Une erreur est survenue lors de l\'enregistrement de l\'observation","ptitObservatoire.modal.textarea.placeholder":"Je suis bienveillant et factuel : J\'écris ce que j\'ai vu et entendu"}')}}]);
|
|
2
|
+
//# sourceMappingURL=ptit-observatoire-widget.widget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widgets/ptit-observatoire-widget/ptit-observatoire-widget.widget.js","mappings":"gIAGA,QAFW,+iI,+wDCDX,iBACA,UACA,UAaA,0BACC,KAAAA,SAAsC,CAAC,EAChC,KAAAC,sBAA+C,GAC/C,KAAAC,aAA0B,GAC1B,KAAAC,cAAe,CAiCvB,QA9BC,YAAAC,iBAAA,WACKC,KAAKL,SAASM,aACjBD,KAAKF,cAAe,EAEtB,EAEM,YAAAI,wBAAN,W,8FAYC,OAXMC,EAAO,CACZC,KAAM,CACLC,KAAM,eACNC,WAAY,EAAF,KACNN,KAAKL,UAAQ,CAChB,WAAc,EACd,MAAQ,IAAIY,MAAOC,cAAcC,UAAU,EAAG,QAKjD,GAAMT,KAAKU,gBAAgBP,I,cAA3B,S,UAGK,YAAAO,gBAAN,SAAsBP,G,8FAEpB,O,sBAAA,IAAM,IAAAQ,QAAOC,SAAS,6CAA8CT,I,cAApE,SACA,EAAAU,OAAOC,QAAQ,wC,+BAEfC,QAAQC,MAAM,4BAA6B,GAC3C,EAAAH,OAAOG,MAAM,sC,6BAGhB,EArCA,GAwCA,0BACC,KAAAC,SAAW,IACX,KAAAC,SAAW,UACX,KAAAC,MAAQ,CAAC,EACT,KAAAC,kBAAmB,EACnB,KAAAC,WAAa,CAACC,GACd,KAAAC,aAAe,OACf,KAAAC,QAAU,CAAC,4BA8CZ,QA5CO,YAAAC,KAAN,SAAWN,EAAeO,EAAcC,EAAoBC,G,gGAI3D,OAHMC,EAA0BD,EAC5BA,EAAY,GACb,MAK+C,GAAME,QAAQC,IAAI,CACnE/B,KAAKgC,2BACLhC,KAAKiC,qBALL,I,cAGD,EAAkD,SAAjDJ,EAAKjC,sBAAqB,KAAEiC,EAAKhC,aAAY,KAK9CsB,EAAMe,c,UAGD,YAAAD,gBAAN,W,8FAEc,O,sBAAA,IAAM,IAAAtB,QAAOwB,IAAI,2C,OAE7B,MAAO,CAAP,EAFY,SAEDC,IAAI,SACdC,GACI,OACJC,GAAID,EAAQC,GACZC,SAAUF,EAAQ/B,WAAWkC,UAFzB,I,OAML,O,WADAzB,QAAQC,MAAM,2BAA4B,GACnC,CAAC,EAAD,I,uBAIH,YAAAgB,yBAAN,W,8FAEc,O,sBAAA,IAAM,IAAArB,QAAOwB,IAAI,0D,OAC7B,MAAO,CAAP,EADY,SACDC,IAAI,SAACK,GAA2D,OAC1EH,GAAIG,EAASH,GACbI,KAAMD,EAASnC,WAAWoC,KAFgD,I,OAM3E,O,WADA3B,QAAQC,MAAM,6BAA8B,GACrC,CAAC,EAAD,I,uBAGV,EArDA,IA6DA,IAAA2B,SACEC,cACAC,QAAQC,KAAK,SAACC,IAGZ,IAAAC,QAAOC,SAASC,MAAMC,QAAQ,EAAQ,MAGzC,GAIY,EAAAC,cAAgB,kCAC7B,UACEC,OAAO,EAAAD,cAAe,IACtBE,UAAU,4BApBZ,WACC,OAAO,IAAIC,CACZ,E","sources":["webpack://ode-ngjs-front/./src/ts/widgets/ptit-observatoire-widget/ptit-observatoire-widget.widget.html","webpack://ode-ngjs-front/./src/ts/widgets/ptit-observatoire-widget/ptit-observatoire-widget.widget.ts"],"sourcesContent":["// Module\nvar code = \"<style>.ptit-observatoire-widget-container{box-sizing:border-box;background:#358284;padding:10px;border-radius:6px;overflow:hidden}.ptit-observatoire-widget-content{display:flex;flex-direction:column;gap:10px;box-sizing:border-box;width:100%;height:100%;background-color:#fff;border-radius:3px;padding:10px}.ptit-observatoire-widget-form{width:100%;display:flex;flex-direction:column;gap:10px}.ptit-observatoire-widget-select{background-color:#fff;padding:15px;border:1px solid #c1c1ca;color:#c1c1ca;border-radius:10px}.ptit-observatoire-submit-button{display:flex;align-items:center;gap:10px;background-color:#173a37;color:#fff;border:none;padding:10px 15px;border-radius:30px}.ptit-observatoire-plus-icon{display:flex;align-items:center;justify-content:center;line-height:100%;text-align:center;background-color:#2c6262;border-radius:50%;width:30px;height:30px}.ptit-observatoire-modal-form{display:flex;flex-direction:column;gap:15px}.ptit-observatoire-modal-form-legend{text-transform:uppercase;color:#7caaac;font-weight:700}.ptit-observatoire-modal-form-textarea{width:100%}.ptit-observatoire-modal-options-container{display:flex;flex-wrap:wrap;gap:5px}</style> <div class=\\\"ptit-observatoire-widget-container\\\"> <div class=\\\"ptit-observatoire-widget-content\\\"> <p> <i18n>ptitObservatoire.title</i18n> </p> <div class=\\\"widget-body\\\" dnd-nodrag> <form class=\\\"ptit-observatoire-widget-form\\\" ng-submit=\\\"ctrl.startObservation()\\\"> <select class=\\\"ptit-observatoire-widget-select\\\" name=\\\"student\\\" ng-model=\\\"ctrl.formData.student_id\\\"> <option value=\\\"\\\" selected=\\\"selected\\\"> </option> <option ng-repeat=\\\"student in ctrl.studentsList\\\" value=\\\"{{student.id}}\\\"> {{student.fullName}} </option> </select> <button type=\\\"submit\\\" class=\\\"ptit-observatoire-submit-button\\\"> <span class=\\\"ptit-observatoire-plus-icon\\\">+</span> <span> <i18n>ptitObservatoire.newObservation</i18n> </span> </button> </form> </div> </div> <ode-modal visible=\\\"ctrl.showLightbox\\\" on-close=\\\"ctrl.showLightbox=false\\\" size=\\\"lg\\\" dnd-nodrag> <ode-modal-title> <h2> <i18n>ptitObservatoire.modal.title</i18n> </h2> </ode-modal-title> <ode-modal-body> <form class=\\\"ptit-observatoire-modal-form\\\" ng-submit=\\\"ctrl.handleObservationSubmit(); ctrl.showLightbox=false\\\"> <fieldset> <legend class=\\\"ptit-observatoire-modal-form-legend\\\"> <i18n>ptitObservatoire.modal.observation</i18n> </legend> <textarea class=\\\"ptit-observatoire-modal-form-textarea\\\" name=\\\"content\\\" ng-model=\\\"ctrl.formData['content']\\\" i18n-placeholder=\\\"ptitObservatoire.modal.textarea.placeholder\\\"></textarea> </fieldset> <fieldset> <legend class=\\\"ptit-observatoire-modal-form-legend\\\"> <i18n>ptitObservatoire.modal.evaluation</i18n> </legend> <label for=\\\"strengths\\\"> <input type=\\\"radio\\\" id=\\\"strength\\\" name=\\\"assessment_type\\\" ng-model=\\\"ctrl.formData['assessment_type']\\\" ng-value=\\\"'strength'\\\"/> <i18n>ptitObservatoire.modal.evaluation.strength</i18n> </label> <label for=\\\"neutral\\\"> <input type=\\\"radio\\\" id=\\\"neutral\\\" name=\\\"assessment_type\\\" ng-model=\\\"ctrl.formData['assessment_type']\\\" ng-value=\\\"'neutral'\\\"/> <i18n>ptitObservatoire.modal.evaluation.neutral</i18n> </label> <label for=\\\"difficulties\\\"> <input type=\\\"radio\\\" id=\\\"difficulties\\\" name=\\\"assessment_type\\\" ng-model=\\\"ctrl.formData['assessment_type']\\\" ng-value=\\\"'difficulties'\\\"/> <i18n>ptitObservatoire.modal.evaluation.difficulties</i18n> </label> </fieldset> <fieldset> <legend class=\\\"ptit-observatoire-modal-form-legend\\\"> <i18n>ptitObservatoire.modal.categories</i18n> </legend> <div class=\\\"ptit-observatoire-modal-options-container\\\"> <label ng-repeat=\\\"category in ctrl.observationCategories\\\"> <input type=\\\"radio\\\" name=\\\"{{category.name}}\\\" ng-model=\\\"ctrl.formData['category_id']\\\" ng-value=\\\"category.id\\\"/> {{ category.name }} </label> </div> </fieldset> <fieldset> <legend class=\\\"ptit-observatoire-modal-form-legend\\\"> <i18n>ptitObservatoire.modal.options</i18n> </legend> <label> <input type=\\\"checkbox\\\" ng-model=\\\"ctrl.formData['private']\\\"/> <i18n>ptitObservatoire.modal.options.private</i18n> </label> </fieldset> <button type=\\\"submit\\\" class=\\\"ptit-observatoire-submit-button\\\"> <i18n>ptitObservatoire.modal.save</i18n> </button> </form> </ode-modal-body> </ode-modal> </div>\";\n// Exports\nexport default code;","import angular, { IAttributes, IController, IDirective, IScope } from \"angular\";\nimport { conf, http, notif } from \"../../utils\";\nimport { notify } from \"../../services\";\n\ninterface Student {\n\tid: number,\n\tfullName: string\n}\n\ninterface ObservationCategory {\n\tid: number,\n\tname: string\n}\n\n/* Controller for the directive */\nclass Controller implements IController {\n\tformData: { [key: string]: string } = {};\n\tpublic observationCategories: ObservationCategory[] = [];\n\tpublic studentsList: Student[] = [];\n\tpublic showLightbox = false;\n\n\n\tstartObservation() {\n\t\tif (this.formData.student_id) {\n\t\t\tthis.showLightbox = true;\n\t\t}\n\t}\n\n\tasync handleObservationSubmit() {\n\t\tconst body = {\n\t\t\tdata: {\n\t\t\t\ttype: \"observations\",\n\t\t\t\tattributes: {\n\t\t\t\t\t...this.formData,\n\t\t\t\t\t\"teacher_id\": 1, // TODO: change when respone updated from ptit observatoire\n\t\t\t\t\t\"date\": new Date().toISOString().substring(0, 10),\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tawait this.saveObservation(body)\n\t}\n\n\tasync saveObservation(body: any): Promise<void> {\n\t\ttry {\n\t\t\tawait http().postJson(\"/appregistry/ptitObservatoire/observations\", body)\n\t\t\tnotify.success(\"ptitObservatoire.notify.save.success\")\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Error saving observation:\", error);\n\t\t\tnotify.error(\"ptitObservatoire.notify.save.error\")\n\t\t}\n\t}\n}\n\n/* Directive */\nclass Directive implements IDirective<IScope, JQLite, IAttributes, IController[]> {\n\trestrict = 'E';\n\ttemplate = require('./ptit-observatoire-widget.widget.html').default;\n\tscope = {};\n\tbindToController = true;\n\tcontroller = [Controller];\n\tcontrollerAs = 'ctrl';\n\trequire = ['odePtitObservatoireWidget'];\n\n\tasync link(scope: IScope, elem: JQLite, attrs: IAttributes, controllers?: IController[]) {\n\t\tconst ctrl: Controller | null = controllers\n\t\t\t? (controllers[0] as Controller)\n\t\t\t: null;\n\t\tif (!ctrl) {\n\t\t\treturn;\n\t\t}\n\n\t\t[ctrl.observationCategories, ctrl.studentsList] = await Promise.all([\n\t\t\tthis.getObservationCategories(),\n\t\t\tthis.getStudentsList(),\n\t\t]);\n\n\t\tscope.$applyAsync();\n\t}\n\n\tasync getStudentsList(): Promise<Student[]> {\n\t\ttry {\n\t\t\tconst res = await http().get(\"/appregistry/ptitObservatoire/students\");\n\n\t\t\treturn res.map((\n\t\t\t\tstudent: { id: number, attributes: { full_name: string } }\n\t\t\t) => ({\n\t\t\t\tid: student.id,\n\t\t\t\tfullName: student.attributes.full_name\n\t\t\t}));\n\t\t} catch (e) {\n\t\t\tconsole.error(\"Error fetching students:\", e);\n\t\t\treturn [];\n\t\t}\n\t}\n\n\tasync getObservationCategories(): Promise<ObservationCategory[]> {\n\t\ttry {\n\t\t\tconst res = await http().get(\"/appregistry/ptitObservatoire/observations/categories\");\n\t\t\treturn res.map((category: { id: number; attributes: { name: string } }) => ({\n\t\t\t\tid: category.id,\n\t\t\t\tname: category.attributes.name,\n\t\t\t}));\n\t\t} catch (e) {\n\t\t\tconsole.error(\"Error fetching categories:\", e);\n\t\t\treturn [];\n\t\t}\n\t}\n}\n\n/** The P'tit observatoire widget. */\nfunction DirectiveFactory() {\n\treturn new Directive();\n}\n\n// Preload translations\nnotif()\n\t.onLangReady()\n\t.promise.then((lang) => {\n\t\tswitch (lang) {\n\t\t\tdefault:\n\t\t\t\tconf().Platform.idiom.addKeys(require(\"./i18n/fr.json\"));\n\t\t\t\tbreak;\n\t\t}\n\t});\n\n// THIS ANGULAR MODULE WILL BE DYNAMICALLY ADDED TO THE APPLICATION.\n// RESPECT THE NAMING CONVENTION BY EXPORTING THE MODULE NAME :\nexport const odeModuleName = \"odePtitObservatoireWidgetModule\";\nangular\n\t.module(odeModuleName, [])\n\t.directive(\"odePtitObservatoireWidget\", DirectiveFactory);\n"],"names":["formData","observationCategories","studentsList","showLightbox","startObservation","this","student_id","handleObservationSubmit","body","data","type","attributes","Date","toISOString","substring","saveObservation","http","postJson","notify","success","console","error","restrict","template","scope","bindToController","controller","Controller","controllerAs","require","link","elem","attrs","controllers","ctrl","Promise","all","getObservationCategories","getStudentsList","$applyAsync","get","map","student","id","fullName","full_name","category","name","notif","onLangReady","promise","then","lang","conf","Platform","idiom","addKeys","odeModuleName","module","directive","Directive"],"sourceRoot":""}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";(self.webpackChunkode_ngjs_front=self.webpackChunkode_ngjs_front||[]).push([[202],{5688:(e,t,a)=>{a.d(t,{Z:()=>r});const r='<style>.screen-time-summary{padding:16px;font-family:Roboto,sans-serif;display:flex;flex-direction:column;gap:12px}.title{padding-bottom:6px;font-size:16px;color:#4a4a4a;font-weight:700;border-bottom:1px solid #e0e0e0}.modal-title{display:block;width:100%}.modal-body{margin:1rem 0!important}.summary-row{display:flex;gap:12px}.summary-row:nth-of-type(2){margin-top:10px}.summary-block{flex:1;background:#e5f5ff;border-radius:12px;padding:12px;box-shadow:0 1px 3px rgba(0,0,0,.1)}.summary-block .label{font-size:16px;color:#4a4a4a;font-weight:700;margin-bottom:4px}.summary-block .value{font-size:32px;color:#333}.percentage-bar-container{width:100%;height:10px;background-color:#e0e0e0;border-radius:5px;margin-top:5px;display:flex;overflow:hidden}.percentage-bar{height:100%;transition:width .5s ease-in-out;border-radius:5px}.legend{display:flex;gap:16px;align-items:center;margin-top:10px;font-size:10px;color:#333}.legend-item{display:flex;align-items:center;gap:6px}.legend-square{width:16px;height:16px;border-radius:4px}.custom-select{appearance:none;border:none;padding:8px 32px 8px 12px;border-radius:6px;font-size:16px;color:#333;font-family:Roboto,sans-serif;background:#fff url("data:image/svg+xml,%3Csvg fill=\'none\' stroke=\'%23666\' stroke-width=\'2\' viewBox=\'0 0 24 24\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cpath stroke-linecap=\'round\' stroke-linejoin=\'round\' d=\'M19 9l-7 7-7-7\'%3E%3C/path%3E%3C/svg%3E") no-repeat right 10px center;background-size:16px;cursor:pointer;min-width:150px}.custom-select:focus{outline:0;box-shadow:0 0 0 2px rgba(42,156,200,.3)}.see-more{display:flex;justify-content:flex-end;margin-top:8px;padding-left:4px}.see-more button{background-color:transparent;border:none;font-family:Roboto,sans-serif;font-weight:600;font-size:16px;line-height:24px;padding:6px 12px;cursor:pointer;color:#2a9cc8;border-radius:4px;transition:background-color .2s ease}.see-more button:hover{background-color:#f0f8fc}.centered-controls{margin:0 auto 20px auto;width:fit-content;text-align:center}.view-controls{display:flex;width:100%;flex-direction:row;justify-content:space-between;margin-bottom:16px}.control-group{display:flex;align-items:center}.close-button-container{display:flex;justify-content:flex-end;margin-top:20px}.close-button{width:84px;height:40px;padding:8px 16px;background:#ff8d2e;color:#fff;font-size:16px;font-weight:700;border:none;border-radius:8px;cursor:pointer;transition:background .3s ease}.close-button:hover{background:#e67c24}.date-controls{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.nav-button{background:0 0;border:none;font-size:24px;cursor:pointer}.date-navigation{display:flex;align-items:center;justify-content:center;gap:1rem}.date-navigation button{background:0 0;border:none;font-size:1.5rem;cursor:pointer}.date-navigation button:disabled{color:#d3d3d3;cursor:not-allowed}.selected-date{cursor:pointer;font-weight:700}.error-message{background-color:#ffe5e5;color:#c00;border:1px solid #c00;padding:12px;border-radius:6px;font-size:14px;font-weight:500}.info-popover{position:absolute;z-index:10;display:block;width:90%;background-color:#fff;border:1px solid #e0e0e0;box-shadow:0 4px 6px 0 rgba(0,0,0,.08);font-size:1.5rem;line-height:1.8;padding:1rem;border-radius:6px}</style> <div class="screen-time-widget-container"> <div class="screen-time-summary"> <div class="title"> <div class="label"> <i18n>screenTime.title.uppercase</i18n> </div> </div> <div ng-if="ctrl.isParent"> <select id="userSelect" class="custom-select" ng-model="ctrl.selectedUser" ng-options="child.userId as child.name for child in ctrl.children" ng-change="ctrl.fetchDataForCurrentUser()"> </select> </div> <div class="error-message" ng-if="ctrl.errorMessage"> {{ ctrl.errorMessage }} </div> <div ng-if="!ctrl.errorMessage"> <div class="summary-row"> <div class="summary-block"> <div class="label"> <i18n>screenTime.today</i18n> </div> <div class="value">{{ ctrl.todayTotal | duration }}</div> </div> </div> <div class="summary-row"> <div class="summary-block"> <div class="label"> <i18n>screenTime.weekAverage</i18n> </div> <div class="value">{{ ctrl.weeklyTotalAverage | duration }}</div> </div> </div> <div class="legend"> <div class="see-more"> <button ng-click="ctrl.toggleLightbox(true)"> <i18n>screenTime.displayDetails</i18n> </button> </div> </div> </div> </div> <ode-modal visible="ctrl.showLightbox" on-close="ctrl.toggleLightbox(false)" size="lg" dnd-nodrag> <ode-modal-title class="modal-title"> <h2> <i18n>screenTime.title.normal</i18n> <popover> <popover-opener><i class="fa-solid fa-circle-info"></i></popover-opener> <popover-content class="info-popover"> <ul> <li> <i18n>screenTime.information.first</i18n> </li> <li> <i18n>screenTime.information.second</i18n> </li> <li> <i18n>screenTime.information.third</i18n> </li> <li> <i18n>screenTime.information.fourth</i18n> </li> </ul> </popover-content> </popover> </h2> <div class="view-controls"> <div class="control-group"> <label style="font-size:14px" for="userSelect"> <i18n>screenTime.user</i18n> :</label> <div ng-if="ctrl.isParent"> <select id="userSelect" class="custom-select" ng-model="ctrl.selectedChildHistogram" ng-options="child.userId as child.name for child in ctrl.children"> </select> </div> </div> <div class="control-group"> <label for="viewMode"> <i18n>screenTime.viewMode</i18n> :</label> <select id="viewMode" class="custom-select" ng-model="ctrl.viewMode" ng-change="ctrl.updateChart()"> <option value="weekly"> [[ctrl.lang.translate("screenTime.viewMode.weekly")]] </option> <option value="daily"> [[ctrl.lang.translate("screenTime.viewMode.daily")]] </option> </select> </div> </div> </ode-modal-title> <ode-modal-body class="modal-body"> <div class="date-selectors centered-controls" ng-if="ctrl.showLightbox"> <div class="date-navigation" ng-if="ctrl.viewMode === \'daily\'"> <button ng-click="ctrl.changeDay(-1)" ng-disabled="!ctrl.canGoToPreviousDay()">←</button> <div ng-if="!ctrl.showDatePicker" class="selected-date" ng-click="ctrl.toggleDatePicker(true)"> {{ ctrl.selectedDailyDateLabel }} </div> <input type="date" ng-if="ctrl.showDatePicker" ng-model="ctrl.tempDailyDate" ng-change="ctrl.commitTempDate()"/> <button ng-click="ctrl.changeDay(1)" ng-disabled="!ctrl.canGoToNextDay()">→</button> </div> <div class="date-navigation" ng-if="ctrl.viewMode === \'weekly\'"> <button ng-click="ctrl.changeWeek(-1)" ng-disabled="!ctrl.canGoToPreviousWeek()">←</button> <div class="selected-date">{{ ctrl.weekLabel }}</div> <button ng-click="ctrl.changeWeek(1)" ng-disabled="!ctrl.canGoToNextWeek()">→</button> </div> </div> <canvas id="myChart" style="width:100%;height:500px;max-height:500px"></canvas> </ode-modal-body> </ode-modal> </div>'},58:function(e,t,a){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.odeModuleName=t.Controller=void 0;var o=r(a(4202)),i=a(9419),n=a(5668),s=r(a(381));a(4470),n.Chart.register.apply(n.Chart,n.registerables),s.default.locale("fr");var l=function(){function e(){this.platform=(0,i.conf)().Platform,this.lang=this.platform.idiom,this.selectedUser="",this.viewMode="weekly",this.userData={},this.selectedDailyDate=(0,s.default)().format("YYYY-MM-DD"),this.tempDailyDate=(0,s.default)().format("YYYY-MM-DD"),this.weekStart=(0,s.default)().startOf("isoWeek"),this.weekEnd=(0,s.default)().endOf("isoWeek"),this.updateChart=function(){},this.todayOnCampus=0,this.todayOffCampus=0,this.todayTotal=0,this.weeklyAvgOnCampus=0,this.weeklyAvgOffCampus=0,this.weeklyTotalAverage=0,this.weeklyAvgSchoolUsePercentage=0,this.weeklyAvgOutOfSchoolPercentage=0,this.fixedTodayOnCampus=0,this.fixedTodayOffCampus=0,this.fixedTodayTotal=0,this.fixedWeeklyAvgOnCampus=0,this.fixedWeeklyAvgOffCampus=0,this.fixedWeeklyTotalAverage=0,this.fixedWeeklyAvgSchoolUsePercentage=0,this.fixedWeeklyAvgOutOfSchoolPercentage=0,this.customWeekMode=!1,this.customStartDate="",this.customEndDate="",this.isParent=!1,this.hasError=!1,this.errorMessage="",this.fetchDataForCurrentUser=function(){},this.fetchLightboxData=function(){},this.showLightbox=!1,this.showDatePicker=!1,this.children=[],this.selectedChild=null,this.selectedChildHistogram=""}return e.prototype.toggleDatePicker=function(e){var t=this;this.showDatePicker=e,e&&(this.tempDailyDate=this.selectedDailyDate,setTimeout(function(){if(t.tempDailyDate){var e=document.querySelector('input[type="date"]');e&&(e.value=t.tempDailyDate)}},0))},e.prototype.setDateFromPicker=function(e){var t=(0,s.default)(e).format("YYYY-MM-DD");this.showDatePicker=!1,this.setSelectedDate(t),this.fetchLightboxData()},e.prototype.commitTempDate=function(){var e=(0,s.default)(this.tempDailyDate).format("YYYY-MM-DD");(0,s.default)(e).isValid()?(this.setSelectedDate(e),this.showDatePicker=!1,this.fetchLightboxData()):(this.tempDailyDate=this.selectedDailyDate,this.showDatePicker=!1)},e.prototype.toggleLightbox=function(e){this.showLightbox=e,e&&(this.fixedTodayOnCampus=this.todayOnCampus,this.fixedTodayOffCampus=this.todayOffCampus,this.fixedTodayTotal=this.todayTotal,this.fixedWeeklyAvgOnCampus=this.weeklyAvgOnCampus,this.fixedWeeklyAvgOffCampus=this.weeklyAvgOffCampus,this.fixedWeeklyTotalAverage=this.weeklyTotalAverage,this.fixedWeeklyAvgSchoolUsePercentage=this.weeklyAvgSchoolUsePercentage,this.fixedWeeklyAvgOutOfSchoolPercentage=this.weeklyAvgOutOfSchoolPercentage,this.selectedDailyDate||(this.selectedDailyDate=(0,s.default)().format("YYYY-MM-DD")),this.weekStart&&this.weekEnd||(this.weekStart=(0,s.default)().startOf("isoWeek"),this.weekEnd=(0,s.default)().endOf("isoWeek")),this.selectedChildHistogram=this.selectedUser)},e.prototype.getCurrentSchoolYear=function(){var e=(0,s.default)(),t=e.year(),a=e.month()<8?(0,s.default)({year:t-1,month:8,day:1}):(0,s.default)({year:t,month:8,day:1}),r=a.clone().add(1,"year").subtract(1,"day");return{schoolYearStart:a.startOf("day"),schoolYearEnd:r.endOf("day")}},e.prototype.setSelectedDate=function(e){var t=(0,s.default)(e);this.selectedDailyDate=t.format("YYYY-MM-DD"),this.weekStart=t.clone().startOf("isoWeek"),this.weekEnd=t.clone().endOf("isoWeek")},e.prototype.setSelectedWeek=function(e){this.weekStart=e.clone().startOf("isoWeek"),this.weekEnd=this.weekStart.clone().endOf("isoWeek"),this.selectedDailyDate=this.weekStart.format("YYYY-MM-DD")},e.prototype.canGoToPreviousWeek=function(){var e=this.weekStart.clone().subtract(1,"week"),t=this.getCurrentSchoolYear(),a=t.schoolYearStart,r=t.schoolYearEnd;return e.isBetween(a,r)},e.prototype.canGoToNextWeek=function(){var e=this.weekStart.clone().add(1,"week"),t=this.getCurrentSchoolYear(),a=t.schoolYearStart,r=t.schoolYearEnd;return e.isBetween(a,r)},e.prototype.canGoToPreviousDay=function(){var e=(0,s.default)(this.selectedDailyDate).subtract(1,"day"),t=this.getCurrentSchoolYear(),a=t.schoolYearStart,r=t.schoolYearEnd;return e.isBetween(a,r)},e.prototype.canGoToNextDay=function(){var e=(0,s.default)(this.selectedDailyDate).add(1,"day"),t=this.getCurrentSchoolYear(),a=t.schoolYearStart,r=t.schoolYearEnd;return e.isBetween(a,r)},e.prototype.changeDay=function(e){var t=this,a=(0,s.default)(this.selectedDailyDate).add(e,"days");this.setSelectedDate(a),this.tempDailyDate=this.selectedDailyDate,this.fetchLightboxData(),this.showDatePicker&&setTimeout(function(){var e=document.querySelector('input[type="date"]');e&&(e.value=t.tempDailyDate)},0)},e.prototype.changeWeek=function(e){var t=this.weekStart.clone().add(e,"weeks");this.setSelectedWeek(t),this.fetchLightboxData()},Object.defineProperty(e.prototype,"selectedDailyDateObj",{get:function(){return new Date(this.selectedDailyDate)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"selectedDailyDateLabel",{get:function(){return(0,s.default)(this.selectedDailyDate).format("dddd D MMMM YYYY")},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"weekLabel",{get:function(){var e=this.weekStart.format("dddd D MMMM"),t=this.weekEnd.format("dddd D MMMM"),a=this.lang.translate("screenTime.from"),r=this.lang.translate("screenTime.to");return"".concat(a," ").concat(e," ").concat(r," ").concat(t)},enumerable:!1,configurable:!0}),e}();function c(e,t,a,r,o,i){t.children=d(t);var n="/appregistry/screen-time/".concat(a,"/weekly?startDate=").concat(o,"&endDate=").concat(i),s="/appregistry/screen-time/".concat(a,"/daily?date=").concat(r);return Promise.all([e.get(n),e.get(s)]).then(function(e){var a=e[0],r=e[1];return t.hasError=!1,t.errorMessage="",{weekly:a.data.dailySummaries.reduce(function(e,t){return e[t.date]={duration:t.durationMinutes,schoolUsePercentage:t.schoolUsePercentage/100},e},{}),daily:r.data.durations.map(function(e){return{hour:e.hour,duration:e.durationMinutes,schoolUsePercentage:e.schoolUsePercentage/100}})}}).catch(function(e){return t.hasError=!0,404===(null==e?void 0:e.status)?t.errorMessage=t.lang.translate("screenTime.error.404"):t.errorMessage=t.lang.translate("screenTime.error.generic"),console.error("Error fetching data for current user and dates:",e),Promise.reject(e)})}function d(e){var t=(0,i.session)().user.children;return e.isParent=!1,t&&Object.keys(t).length>0?(e.isParent=!0,Object.entries(t).map(function(e){var t=e[0],a=e[1];return{id:t,name:"".concat(a.firstName," ").concat(a.lastName),userId:t}})):[]}t.Controller=l;var u=function(){function e(){this.restrict="E",this.template=a(5688).Z,this.scope={},this.bindToController=!0,this.controller=[l],this.controllerAs="ctrl",this.require=["odeScreenTimeWidget"]}return e.prototype.link=function(e,t,a,r){var l=r?r[0]:null;if(l){var u=o.default.injector(["ng"]).get("$http"),h=(0,i.session)().user.userId;l.fetchDataForCurrentUser();var f=null,m=function(e,t,a,r){return"".concat(e,"_daily_").concat(t,"_weekly_").concat(a,"_").concat(r)};l.fetchDataForCurrentUser=function(){l.errorMessage="",l.hasError=!1;var t=m(l.selectedUser,(0,s.default)().format("YYYY-MM-DD"),(0,s.default)().startOf("isoWeek").format("YYYY-MM-DD"),(0,s.default)().endOf("isoWeek").format("YYYY-MM-DD"));c(u,l,l.selectedUser,(0,s.default)().format("YYYY-MM-DD"),(0,s.default)().startOf("isoWeek").format("YYYY-MM-DD"),(0,s.default)().endOf("isoWeek").format("YYYY-MM-DD")).then(function(a){var r,o,i,n,c,d,u,h,f,m;l.userData[t]={weekly:a.weekly,daily:a.daily},r=a.weekly,o=0,i=0,n=0,c=(0,s.default)().format("YYYY-MM-DD"),d=0,u=0,h=0,f=0,m=0,Object.keys(r).forEach(function(e){var t=r[e],a=t.duration||0,l=t.schoolUsePercentage||0,p=a*l,g=a*(1-l);o+=p,i+=g,n++,h+=p,f+=g,m+=a,(0,s.default)(e).format("YYYY-MM-DD")===c&&(d=p,u=g)}),l.todayOnCampus=d,l.todayOffCampus=u,l.todayTotal=d+u,l.weeklyAvgOnCampus=n>0?o/n:0,l.weeklyAvgOffCampus=n>0?i/n:0,l.weeklyTotalAverage=l.weeklyAvgOnCampus+l.weeklyAvgOffCampus,m>0?(l.weeklyAvgSchoolUsePercentage=h/m*100,l.weeklyAvgOutOfSchoolPercentage=f/m*100):(l.weeklyAvgSchoolUsePercentage=0,l.weeklyAvgOutOfSchoolPercentage=0),e.$applyAsync()}).catch(function(t){e.$applyAsync(),console.error("Error fetching initial data for current user:",t)})},l.fetchLightboxData=function(){var t=l.selectedChildHistogram||l.selectedUser;if(t){var a=m(t,l.selectedDailyDate,l.weekStart.format("YYYY-MM-DD"),l.weekEnd.format("YYYY-MM-DD"));c(u,l,t,l.selectedDailyDate,l.weekStart.format("YYYY-MM-DD"),l.weekEnd.format("YYYY-MM-DD")).then(function(t){l.userData[a]={weekly:t.weekly,daily:t.daily},l.showLightbox&&setTimeout(function(){return l.updateChart()},50),e.$applyAsync()}).catch(function(e){console.error("Error fetching data for lightbox:",e)})}},l.updateChart=function(){var e=t[0].querySelector("#myChart");if(e){var a=e.getContext("2d");if(a){var r=[],o=[],i=l.selectedChildHistogram||l.selectedUser,c=m(i,l.selectedDailyDate,l.weekStart.format("YYYY-MM-DD"),l.weekEnd.format("YYYY-MM-DD")),d=l.userData[c];if(d){var u="weekly"===l.viewMode?d.weekly:d.daily;if(u){if("weekly"===l.viewMode)Object.keys(u).sort().forEach(function(e){var t=u[e];r.push((0,s.default)(e).format("ddd D")),o.push(t.duration/60)});else u.forEach(function(e){r.push("".concat(e.hour,"h")),o.push(e.duration)});f?(f.data.labels=r,f.data.datasets[0].data=o,f.options={plugins:{tooltip:{callbacks:{label:function(e){var t=e.raw;if("weekly"===l.viewMode){var a=Math.floor(t),r=Math.round(60*(t-a));return 0===r?"".concat(e.dataset.label,": ").concat(a,"h"):"".concat(e.dataset.label,": ").concat(a,"h ").concat(r,"m")}return"".concat(e.dataset.label,": ").concat(t," ").concat(l.lang.translate("screenTime.minutes"))}}}},scales:{x:{stacked:!0},y:{stacked:!0,beginAtZero:!0,title:{display:!0,text:"weekly"===l.viewMode?l.lang.translate("screenTime.hours"):l.lang.translate("screenTime.minutes")}}}},f.update()):f=new n.Chart(a,{type:"bar",data:{labels:r,datasets:[{label:l.lang.translate("screenTime.totalUsage"),data:o,backgroundColor:"#2A9CC8"}]},options:{plugins:{tooltip:{callbacks:{label:function(e){var t=e.raw;if("weekly"===l.viewMode){var a=Math.floor(t),r=Math.round(60*(t-a));return 0===r?"".concat(e.dataset.label,": ").concat(a,"h"):"".concat(e.dataset.label,": ").concat(a,"h ").concat(r,"m")}return"".concat(e.dataset.label,": ").concat(t," ").concat(l.lang.translate("screenTime.minutes"))}}},legend:{display:!1,position:"bottom"}},responsive:!0,scales:{x:{stacked:!0},y:{stacked:!0,beginAtZero:!0,title:{display:!0,text:"weekly"===l.viewMode?l.lang.translate("screenTime.hours"):l.lang.translate("screenTime.minutes")}}}}})}}}}},l.children=d(l),l.isParent&&l.children.length>0?(l.selectedUser||(l.selectedUser=l.children[0].userId),l.fetchDataForCurrentUser()):!l.isParent&&h?(l.selectedUser=h,l.fetchDataForCurrentUser()):(l.hasError=!0,l.errorMessage=l.lang.translate("screenTime.error.noUser"),e.$applyAsync()),e.$watch(function(){return l.viewMode},function(e,t){e!==t&&l.showLightbox&&setTimeout(function(){return l.updateChart()},50)}),e.$watch(function(){return l.selectedChildHistogram},function(e,t){e!==t&&l.showLightbox&&l.fetchLightboxData()}),e.$watch(function(){return l.showLightbox},function(e){e?(l.selectedChildHistogram=l.selectedUser,setTimeout(function(){l.updateChart()},100)):f&&(f.destroy(),f=null)})}},e}();t.odeModuleName="odeCantineWidgetModule",o.default.module(t.odeModuleName,[]).filter("duration",function(){return function(e){if(isNaN(e)||null===e||e<0)return"0m";var t=Math.floor(e),a=Math.floor(t/60),r=t%60,o="";return a>0&&(o+="".concat(a,"h")),(r>0||0===a&&0===t)&&(o+="".concat(r,"m")),o.trim()||"0m"}}).directive("odeScreenTimeWidget",function(){return new u}),(0,i.notif)().onLangReady().promise.then(function(e){if(function(e){try{"en"===e?(a(2243),s.default.locale("en-gb")):(a(4470),s.default.locale("fr"))}catch(e){console.warn("Failed to load moment locale:",e),s.default.locale("fr")}}(e),"en"===e)(0,i.conf)().Platform.idiom.addKeys(a(5840));else(0,i.conf)().Platform.idiom.addKeys(a(1245))})},5840:e=>{e.exports=JSON.parse('{"screenTime.title.normal":"Screen Time","screenTime.title.uppercase":"SCREEN TIME","screenTime.today":"Today","screenTime.weekAverage":"Week Average","screenTime.displayDetails":"View Details","screenTime.user":"User","screenTime.viewMode":"Display","screenTime.viewMode.weekly":"Weekly","screenTime.viewMode.daily":"Daily","screenTime.modal.close":"Close","screenTime.information.first":"\'Screen Time\' is a feature implemented by the Bouches-du-Rhône Department.","screenTime.information.second":"It allows measuring the student\'s activity time on the laptop provided by the Department during school hours and outside school hours.","screenTime.information.third":"\'Screen Time\' only observes the opening and closing of the student\'s session on their computer.","screenTime.information.fourth":"The feature does not record any personal usage or internet browsing data.","screenTime.error.generic":"A technical problem has occurred. If the problem persists, contact your school administrator.","screenTime.error.404":"Error identifying the user. Contact your school administrator.","screenTime.error.noUser":"No user available to display screen time data.","screenTime.totalUsage":"Total usage","screenTime.hours":"Hours","screenTime.minutes":"Minutes","screenTime.from":"from","screenTime.to":"to"}')},1245:e=>{e.exports=JSON.parse('{"screenTime.title.normal":"Temps d\'écran","screenTime.title.uppercase":"TEMPS D\'ÉCRAN","screenTime.today":"Aujourd\'hui","screenTime.weekAverage":"Moyenne de la semaine","screenTime.displayDetails":"Voir le détail","screenTime.user":"Utilisateur","screenTime.viewMode":"Affichage","screenTime.viewMode.weekly":"Hebdomadaire","screenTime.viewMode.daily":"Quotidien","screenTime.modal.close":"Fermer","screenTime.information.first":"\'Temps d\'écran\' est une fonctionnalité mise en place par le Département des Bouches-du-Rhône.","screenTime.information.second":"Elle permet de mesurer le temps d\'activité de l\'élève sur l\'ordinateur portable mis à disposition par le Département pendant le temps scolaire et en dehors du temps scolaire.","screenTime.information.third":"\'Temps d\'écran\' observe uniquement l\'ouverture et la fermeture de la session par l\'élève sur son ordinateur.","screenTime.information.fourth":"La fonctionnalité n\'enregistre aucune donnée personnelle d\'utilisation ou de navigation internet.","screenTime.error.generic":"Un problème technique est survenu. Si le problème persiste contactez l’administrateur de votre établissement.","screenTime.error.404":"Erreur lors de l’identification de l’utilisateur. Contactez l’administrateur de votre établissement.","screenTime.error.noUser":"Aucun utilisateur disponible pour afficher les données de temps d\'écran.","screenTime.totalUsage":"Usage total","screenTime.hours":"Heures","screenTime.minutes":"Minutes","screenTime.from":"du","screenTime.to":"au"}')}}]);
|
|
2
|
+
//# sourceMappingURL=screen-time-widget.widget.js.map
|