@geogirafe/lib-geoportal 1.2.0-dev.2666688189 → 1.2.0-dev.2669461096

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.
@@ -3,14 +3,18 @@ export default class OauthComponent extends GirafeHTMLElement {
3
3
  protected templateUrl: string | null;
4
4
  protected styleUrls: string[] | null;
5
5
  template: () => import("uhtml").Hole;
6
- userIconUrl?: string;
7
6
  constructor(name?: string);
8
7
  private registerEvents;
9
8
  getDisplayName(): string;
10
- refreshRender(): void;
9
+ getFullName(): string | null;
10
+ /**
11
+ * Gets the user initials
12
+ * super_admin -> SA
13
+ * Gustave-André de la Girouette -> GG
14
+ * @returns
15
+ */
16
+ getInitials(): string;
11
17
  onLoginClick(): void;
12
18
  onLogoutClick(): Promise<void>;
13
- getUserIconUrl(): Promise<string | undefined>;
14
- private sha256;
15
19
  protected connectedCallback(): void;
16
20
  }
@@ -8,13 +8,12 @@ export default class OauthComponent extends GirafeHTMLElement {
8
8
  return uHtml `<style>
9
9
  .hidden{display:none!important}.gg-rotate90{transform:rotate(90deg)}.gg-rotate180{transform:rotate(180deg)}.gg-rotate270{transform:rotate(270deg)}img{filter:var(--svg-filter)}img.legend-image{filter:var(--svg-map-filter);background:var(--svg-legend-bkg)}div{scrollbar-width:thin}a,a:visited{color:var(--link-color)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes spin-wait{0%{transform:rotate(0)}7%{transform:rotate(360deg)}to{transform:rotate(360deg)}}.gg-spin{animation-name:spin;animation-duration:2s;animation-timing-function:linear;animation-iteration-count:infinite}.gg-spin-wait{animation-name:spin-wait;animation-duration:10s;animation-timing-function:linear;animation-iteration-count:infinite}::-webkit-scrollbar{width:5px}::-webkit-scrollbar-thumb{background:#999}button,input,select,textarea{font:inherit}.gg-button,.gg-select,.gg-input,.gg-textarea{background-color:var(--bkg-color);color:var(--text-color);border:var(--app-standard-border);box-sizing:border-box;cursor:pointer;border-radius:3px;outline:0;margin:0;padding:0 0 0 .5rem;display:inline-block}.gg-label{background-color:var(--bkg-color);color:var(--text-color);border:none;align-items:center;margin:0;padding:0;display:flex}.gg-button,.gg-select,.gg-input,.gg-label{min-height:calc(var(--app-standard-height) / 1.5)}.gg-textarea{max-height:initial;resize:vertical;height:6rem;padding:.5rem;line-height:1.3rem}.gg-input{cursor:text}.gg-checkbox{accent-color:var(--text-color);width:1.2rem}.gg-range{accent-color:var(--text-color)}.gg-button{padding:0 .5rem}.gg-button.active{border:solid 1px var(--text-color-grad1);background-color:var(--bkg-color-grad2)}.gg-button:disabled{background-color:var(--bkg-color-grad1);color:var(--text-color-grad2);cursor:not-allowed;border:none}.gg-button:disabled img{filter:opacity(.6)}.gg-input:disabled,.gg-select:disabled,.gg-textarea:disabled{background-color:var(--bkg-color-grad1);color:var(--text-color-grad2);cursor:not-allowed}.gg-button>img{vertical-align:middle}.gg-icon-button{color:var(--text-color);cursor:pointer;background-color:#0000;border:none;flex-direction:column;justify-content:center;align-items:center;padding:0;display:flex}.gg-icon{justify-content:center;align-items:center;display:flex}.gg-big,.gg-big-withtext{min-width:var(--app-standard-height);min-height:var(--app-standard-height);max-height:var(--app-standard-height)}.gg-big img,.gg-big-withtext img{width:calc(var(--app-standard-height) - 1.5rem);margin:0}.gg-big-withtext span{font-variant:small-caps;padding:0 1rem;font-size:.9rem}.gg-medium,.gg-medium-withtext{min-width:calc(var(--app-standard-height) / 1.2);min-height:calc(var(--app-standard-height) / 1.2);max-height:calc(var(--app-standard-height) / 1.2);flex-direction:row}.gg-medium img{width:calc(var(--app-standard-height) / 2.4);margin:0}.gg-medium-withtext img{width:calc(var(--app-standard-height) / 2.4);margin-left:.5rem}.gg-medium-withtext span{padding:0 1rem 0 .5rem;font-size:.9rem}.gg-small,.gg-small-withtext{min-width:calc(var(--app-standard-height) / 2);min-height:calc(var(--app-standard-height) / 2);max-height:calc(var(--app-standard-height) / 2);flex-direction:row}.gg-small img{width:calc(var(--app-standard-height) / 3);margin:0}.gg-small-withtext img{width:calc(var(--app-standard-height) / 3);margin-left:.5rem}.gg-small-withtext span{padding:0 .5rem 0 .3rem;font-size:.9rem}.gg-button:hover:not(:disabled),.gg-select:hover:not(:disabled),.gg-input:hover:not(:disabled),.gg-textarea:hover:not(:disabled),.gg-icon-button:hover:not(:disabled){background-color:var(--bkg-color-grad1)}.gg-opacity{opacity:.5}.gg-opacity:hover{opacity:1;background-color:#0000}.gg-tabs{cursor:pointer;grid-auto-flow:column;padding-bottom:1rem;font-size:1rem;display:grid}.gg-tab{border:none;border-bottom:var(--app-standard-border);cursor:pointer;color:var(--text-color);background:0 0;padding:.5rem}.gg-tab.active{border-bottom:solid 1px var(--text-color)}.girafe-button-big,.girafe-button-large,.girafe-button-small,.girafe-button-tiny{color:var(--text-color);background-color:#0000;border:none;flex-direction:column;display:flex}.girafe-button-big:hover,.girafe-button-large:hover,.girafe-button-small:hover,.girafe-button-tiny:hover{background-color:var(--bkg-color-grad1);cursor:pointer}.girafe-button-big.dark,.girafe-button-large.dark,.girafe-button-small.dark,.girafe-button-tiny.dark{background-color:var(--bkg-color);filter:invert()}.girafe-button-big{width:var(--app-standard-height);height:var(--app-standard-height);align-items:center;padding:1rem}.girafe-button-big img{overflow:hidden}.girafe-button-large{flex-direction:row}.girafe-button-large img{height:2rem;margin:.3rem}.girafe-button-large span{height:2rem;margin:.3rem;line-height:2rem}.girafe-button-small{min-width:calc(var(--app-standard-height) / 2);height:calc(var(--app-standard-height) / 2);align-items:center;padding:.5rem}.girafe-button-small img{overflow:hidden}.girafe-button-small span{text-align:left;text-overflow:ellipsis;width:100%;overflow:hidden}.girafe-button-tiny{align-items:center;width:1rem;height:1rem;padding:0}.girafe-button-tiny img{overflow:hidden}.girafe-onboarding-theme{background-color:var(--bkg-color)!important;color:var(--text-color)!important}.girafe-onboarding-theme button{background-color:var(--bkg-color)!important;color:var(--text-color)!important;text-shadow:none!important}.girafe-onboarding-theme button.driver-popover-close-btn{z-index:10000}.tippy-box{background-color:var(--bkg-color)!important;border:var(--app-standard-border)!important}.tippy-content{color:var(--text-color)!important}.tippy-arrow{color:var(--bkg-color)!important}.tippy-box[data-theme~=error]{background-color:var(--error-color);white-space:pre-line}div.tippy-box[data-theme=image-popup]{border:var(--app-standard-border)!important;& div.tippy-content{background-color:var(--bkg-color)!important;& img{max-width:20rem;max-height:20rem}}& div.tippy-arrow{color:var(--bkg-color)!important}}
10
10
  </style><style>
11
- .container{border-right:var(--app-standard-border);flex-direction:row;align-items:center;display:flex}.name{text-align:left;flex-direction:column;display:flex}.user-avatar{--svg-filter:none}
11
+ .container{border-right:var(--app-standard-border);flex-direction:row;align-items:center;display:flex}.name{text-align:left;flex-direction:column;display:flex}.avatar-initials{background-color:var(--app-color-grey);color:#000;border-radius:50%;justify-content:center;align-items:center;width:2rem;height:2rem;font-weight:700;display:flex}.gg-icon-button.logged-in{flex-direction:row;gap:.5rem;padding:.5rem}
12
12
  </style>
13
13
  <style>${this.customStyle}</style>
14
- <div class="${this.context.configManager.Config.oauth || this.context.configManager.Config.gmfauth ? '' : 'hidden'}"><div class="${this.state.oauth.status === 'loggedIn' ? 'hidden' : 'container'}"><button class="gg-icon-button gg-medium-withtext" onclick="${() => this.onLoginClick()}"><img alt="menu-icon" src="icons/user.svg"> <span i18n="Login">Login</span></button></div><div class="${this.state.oauth.status !== 'loggedIn' ? 'hidden' : 'container'}"><button class="gg-icon-button gg-medium-withtext" onclick="${() => this.onLogoutClick()}"><img alt="menu-icon" src="${this.userIconUrl ?? 'icons/user.svg'}" class="${this.userIconUrl ? 'user-avatar' : ''}"><div class="name"><span class="${this.state.oauth.userInfo?.given_name ? '' : 'hidden'}">${this.state.oauth.userInfo?.given_name + ' ' + this.state.oauth.userInfo?.family_name}</span> <span>${this.getDisplayName()}</span></div></button></div></div>
14
+ <div class="${this.context.configManager.Config.oauth || this.context.configManager.Config.gmfauth ? '' : 'hidden'}"><div class="${this.state.oauth.status === 'loggedIn' ? 'hidden' : 'container'}"><button class="gg-icon-button gg-medium-withtext" onclick="${() => this.onLoginClick()}"><img alt="menu-icon" src="icons/user.svg"> <span i18n="Login">Login</span></button></div><div class="${this.state.oauth.status !== 'loggedIn' ? 'hidden' : 'container'}"><button class="gg-icon-button logged-in" onclick="${() => this.onLogoutClick()}"><span class="avatar-initials">${this.getInitials()}</span><div class="name"><span class="${this.getFullName() ? '' : 'hidden'}">${this.getFullName()}</span> <span>${this.getDisplayName()}</span></div></button></div></div>
15
15
  ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
16
16
  };
17
- userIconUrl;
18
17
  constructor(name = 'oauth') {
19
18
  super(name);
20
19
  }
@@ -31,11 +30,29 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
31
30
  }
32
31
  return this.state.oauth.userInfo?.email ?? 'Unknown User';
33
32
  }
34
- refreshRender() {
35
- this.getUserIconUrl().then((url) => {
36
- this.userIconUrl = url;
37
- super.refreshRender();
38
- });
33
+ getFullName() {
34
+ if (this.state.oauth.userInfo?.given_name) {
35
+ return `${this.state.oauth.userInfo?.given_name} ${this.state.oauth.userInfo?.family_name}`;
36
+ }
37
+ // No full name
38
+ return null;
39
+ }
40
+ /**
41
+ * Gets the user initials
42
+ * super_admin -> SA
43
+ * Gustave-André de la Girouette -> GG
44
+ * @returns
45
+ */
46
+ getInitials() {
47
+ const name = this.getFullName() ?? this.getDisplayName();
48
+ const parts = name.split(/[\s_-]+/).filter((part) => part.length > 0);
49
+ if (parts.length === 0) {
50
+ return '??';
51
+ }
52
+ else if (parts.length === 1) {
53
+ return parts[0].substring(0, 2).toUpperCase();
54
+ }
55
+ return (parts[0][0] + parts.at(-1)[0]).toUpperCase();
39
56
  }
40
57
  onLoginClick() {
41
58
  if (!this.context.configManager.Config.oauth && !this.context.configManager.Config.gmfauth) {
@@ -51,25 +68,6 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
51
68
  this.context.authManager.logout();
52
69
  }
53
70
  }
54
- async getUserIconUrl() {
55
- if (this.state.oauth.userInfo?.email) {
56
- const hashedEmail = await this.sha256(this.state.oauth.userInfo.email);
57
- const gravatarUrl = `https://www.gravatar.com/avatar/${hashedEmail}?d=mp`;
58
- return gravatarUrl;
59
- }
60
- return undefined;
61
- }
62
- async sha256(message) {
63
- // encode as UTF-8
64
- const msgBuffer = new TextEncoder().encode(message);
65
- // hash the message
66
- const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
67
- // convert ArrayBuffer to Array
68
- const hashArray = Array.from(new Uint8Array(hashBuffer));
69
- // convert bytes to hex string
70
- const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
71
- return hashHex;
72
- }
73
71
  connectedCallback() {
74
72
  super.connectedCallback();
75
73
  super.render();
@@ -12,6 +12,20 @@
12
12
  text-align: left;
13
13
  }
14
14
 
15
- .user-avatar {
16
- --svg-filter: none;
15
+ .avatar-initials {
16
+ display: flex;
17
+ align-items: center;
18
+ justify-content: center;
19
+ width: 2rem;
20
+ height: 2rem;
21
+ border-radius: 50%;
22
+ background-color: var(--app-color-grey);
23
+ color: black;
24
+ font-weight: bold;
25
+ }
26
+
27
+ .gg-icon-button.logged-in {
28
+ flex-direction: row;
29
+ gap: 0.5rem;
30
+ padding: 0.5rem;
17
31
  }
@@ -11,7 +11,7 @@ export default class MobileOauthComponent extends OauthComponent {
11
11
  .container{filter:drop-shadow(0 4px 7px #0004382c);background-color:#fff;border-radius:8px;flex-direction:column;padding:1em;display:flex}.container:active{background-color:#c6ceda}.container>button{background:0 0;border:none;flex-direction:column;flex:1;justify-content:center;align-items:center;display:flex}.container>button>img{opacity:.7;width:25%;padding-bottom:1em}.container>button>span{color:#3f68a7;flex:1;justify-content:center;align-items:center;font-size:1.2em;font-weight:600;display:flex}
12
12
  </style>
13
13
  <style>${this.customStyle}</style>
14
- <div class="${this.context.configManager.Config.oauth || this.context.configManager.Config.gmfauth ? '' : 'hidden'}"><div class="${this.state.oauth.status === 'loggedIn' ? 'hidden' : 'container'}"><button class="gg-icon-button gg-medium-withtext" onclick="${() => this.onLoginClick()}"><img alt="menu-icon" src="icons/user.svg"> <span i18n="Login">Login</span></button></div><div class="${this.state.oauth.status !== 'loggedIn' ? 'hidden' : 'container'}"><button class="gg-icon-button gg-medium-withtext" onclick="${() => this.onLogoutClick()}"><img alt="menu-icon" src="${this.userIconUrl ?? 'icons/user.svg'}" class="${this.userIconUrl ? 'user-avatar' : ''}"><div class="name"><span class="${this.state.oauth.userInfo?.given_name ? '' : 'hidden'}">${this.state.oauth.userInfo?.given_name + ' ' + this.state.oauth.userInfo?.family_name}</span> <span>${this.getDisplayName()}</span></div></button></div></div>
14
+ <div class="${this.context.configManager.Config.oauth || this.context.configManager.Config.gmfauth ? '' : 'hidden'}"><div class="${this.state.oauth.status === 'loggedIn' ? 'hidden' : 'container'}"><button class="gg-icon-button gg-medium-withtext" onclick="${() => this.onLoginClick()}"><img alt="menu-icon" src="icons/user.svg"> <span i18n="Login">Login</span></button></div><div class="${this.state.oauth.status !== 'loggedIn' ? 'hidden' : 'container'}"><button class="gg-icon-button logged-in" onclick="${() => this.onLogoutClick()}"><span class="avatar-initials">${this.getInitials()}</span><div class="name"><span class="${this.getFullName() ? '' : 'hidden'}">${this.getFullName()}</span> <span>${this.getDisplayName()}</span></div></button></div></div>
15
15
  ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
16
16
  };
17
17
  constructor() {
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "name": "GeoGirafe PSC",
6
6
  "url": "https://doc.geogirafe.org"
7
7
  },
8
- "version": "1.2.0-dev.2666688189",
8
+ "version": "1.2.0-dev.2669461096",
9
9
  "type": "module",
10
10
  "engines": {
11
11
  "node": ">=20.19.0"
@@ -1 +1 @@
1
- {"version":"1.2.0-dev.2666688189", "build":"2666688189", "date":"10/07/2026"}
1
+ {"version":"1.2.0-dev.2669461096", "build":"2669461096", "date":"11/07/2026"}