Przeglądaj źródła

debug and enhancements

tigger 2 lat temu
rodzic
commit
fea26326f6

+ 1 - 0
angular.json

@@ -32,6 +32,7 @@
             ],
             "styles": [
               "angularlib/styles/main.theme.scss",
+              "angularlib/styles/pink.theme.scss",
               "src/styles.scss"
             ],
             "scripts": []

+ 31 - 3
src/app/app.component.html

@@ -78,7 +78,8 @@
 </mat-menu>
 
 <mat-menu #settings="matMenu">
-  <button mat-menu-item [matMenuTriggerFor]="themes">{{'themes'|tr:'Themes'}}</button>
+  <button mat-menu-item [matMenuTriggerFor]="themes">{{'theme'|tr:'Theme'}}</button>
+  <button mat-menu-item [matMenuTriggerFor]="language">{{'language'|tr:'Language'}}</button>
 </mat-menu>
 
 <mat-menu #themes="matMenu">
@@ -87,9 +88,36 @@
 </mat-menu>
 
 <mat-menu #lightThemes="matMenu">
-  <button mat-menu-item (click)="changeTheme('theme')">{{'main'|tr:'Main'}}</button>
+  @for(theme of [
+    {name:'theme',label:'main'|tr:'Blue',color:"#3F51B6"},
+    {name:'theme-pink',label:'pink'|tr:'Pink',color:"#e91e63"}
+  ]; track $index) {
+    <button mat-menu-item (click)="changeTheme(theme.name)">
+      <mat-icon style="color:{{theme.color}}">fiber_manual_record</mat-icon>
+      {{theme.label}}</button>
+  }
 </mat-menu>
 
 <mat-menu #darkThemes="matMenu">
-  <button mat-menu-item (click)="changeTheme('dark-theme')">{{'main'|tr:'Main'}}</button>
+  @for(theme of [
+    {name:'dark-theme',label:'main'|tr:'Blue',color:"#3F51B6"},
+    {name:'dark-theme-pink',label:'pink'|tr:'Pink',color:"#e91e63"}
+  ]; track $index) {
+    <button mat-menu-item (click)="changeTheme(theme.name)">
+      <mat-icon style="color:{{theme.color}}">fiber_manual_record</mat-icon>
+      {{theme.label}}</button>
+  }
+</mat-menu>
+
+<mat-menu #language="matMenu">
+  @for(lang of [
+    {name:'en',label:'English',picture:'https://rem.swopt.com/media/images/flags/GBR.png'},
+    {name:'zh',label:'简体中文',picture:'https://rem.swopt.com/media/images/flags/CHN.png'},
+    {name:'ms',label:'Melayu',picture:'https://rem.swopt.com/media/images/flags/MAS.png'}
+  ];track $index) {
+    <button mat-menu-item (click)="changeLanguage(lang.name)">
+      <div class="language-flag" [style.background-image]="'url('+lang.picture+')'">&nbsp;</div>
+      {{lang.label}}
+    </button>
+  }
 </mat-menu>

+ 9 - 0
src/app/app.component.scss

@@ -69,6 +69,15 @@
     #clock_out {display: none;}
 }
 
+.language-flag {
+    display: inline-flex;
+    border-radius: 50%;
+    height: 1.3rem;
+    width: 1.3rem;
+    background-size: cover;
+    background-position: center;
+}
+
 /** Mobile styles */
 @media screen and (pointer: none), (pointer: coarse) {
     .toolbar {display: none;}

+ 16 - 2
src/app/app.component.ts

@@ -9,6 +9,9 @@ import { Title } from '@angular/platform-browser';
 import { LoginService } from 'angularlib/login/login.service';
 import { CommonModule } from '@angular/common';
 import { ChangeTheme } from 'angularlib/ui.state/ui.state.actions';
+import { ChangeLanguage } from 'angularlib/labels/label.actions';
+import { Label } from 'angularlib/labels/label.interface';
+import { ComponentService } from 'angularlib/component.service';
 
 @Component({
   selector: 'app-root',
@@ -49,8 +52,9 @@ export class AppComponent extends BaseComponent implements OnInit {
     protected loginService: LoginService,
     /**Platform Browser title */
     protected pbTitle: Title,
+    protected cs: ComponentService
   ) {
-    super(store);
+    super(store,cs);
   }
 
   @HostListener('window:mousedown')
@@ -69,7 +73,9 @@ export class AppComponent extends BaseComponent implements OnInit {
       return data.data?.title;
     })
     ).subscribe(title => {
-      this.title = title;
+      if (typeof title === 'string')
+        this.title = title;
+      else this.title = this.getLabel(title.key,title.default);
       this.pbTitle.setTitle(this.title);
     });
 
@@ -81,6 +87,14 @@ export class AppComponent extends BaseComponent implements OnInit {
     });
   }
 
+  /**
+   * change application language
+   * @param {string} language
+   */
+  protected changeLanguage(language: string) {
+    this.store.dispatch(new ChangeLanguage(language));
+  }
+
   protected setDefaultTheme() {
     if (localStorage.getItem('theme')) {
       this.theme = localStorage.getItem('theme') as string;

+ 5 - 5
src/app/dashboard/dashboard.component.html

@@ -72,7 +72,7 @@
               </linearGradient>
             </defs>
           </svg>
-          <h1>Welcome</h1>
+          <h1>{{'welcome'|tr:'Welcome'}}</h1>
         </div>
       </div>
       <div class="divider" role="separator" aria-label="Divider"></div>
@@ -84,10 +84,10 @@
           </div>
         } @else {
           <master-menu [menu]="{
-            'leave':[
-              {label:'New Leave',disabled:true},
-              {label:'Leave History',disabled:true},
-              {label:'Leave Approval',disabled:true}
+            'leave_application':[
+              {label:{key:'new_leave',default:'New Leave'},disabled:true},
+              {label:{key:'leave_history',default:'Leave History'},disabled:true},
+              {label:{key:'leave_approval',default:'Leave Approval'},disabled:true}
             ],
             'quotation':[
               {label:{key:'purchase_quotation',default:'Purchase Quotation'},route:'/quotation/purchase'},

+ 174 - 160
src/app/dashboard/dashboard.component.scss

@@ -1,179 +1,193 @@
 :host {
-    --bright-blue: oklch(51.01% 0.274 263.83);
-    --electric-violet: oklch(53.18% 0.28 296.97);
-    --french-violet: oklch(47.66% 0.246 305.88);
-    --vivid-pink: oklch(69.02% 0.277 332.77);
-    --hot-red: oklch(61.42% 0.238 15.34);
-    --orange-red: oklch(63.32% 0.24 31.68);
-
-    --gray-900: oklch(19.37% 0.006 300.98);
-    --gray-700: oklch(36.98% 0.014 302.71);
-    --gray-400: oklch(70.9% 0.015 304.04);
-
-    --red-to-pink-to-purple-vertical-gradient: linear-gradient(
-      180deg,
-      var(--orange-red) 0%,
-      var(--vivid-pink) 50%,
-      var(--electric-violet) 100%
-    );
-
-    --red-to-pink-to-purple-horizontal-gradient: linear-gradient(
-      90deg,
-      var(--orange-red) 0%,
-      var(--vivid-pink) 50%,
-      var(--electric-violet) 100%
-    );
-
-    --pill-accent: var(--bright-blue);
-
-    font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
-      Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
-      "Segoe UI Symbol";
-    box-sizing: border-box;
-    -webkit-font-smoothing: antialiased;
-    -moz-osx-font-smoothing: grayscale;
-  }
-
-  h1 {
-    font-size: 3.125rem;
-    font-weight: 500;
-    line-height: 100%;
-    letter-spacing: -0.125rem;
-    margin: 0;
-    font-family: "Inter Tight", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
-      Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
-      "Segoe UI Symbol";
-  }
-
-  p {
-    margin: 0;
-    color: var(--gray-700);
-  }
-
-  main {
-    width: 100%;
-    min-height: 100%;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    padding: 1rem;
-    box-sizing: inherit;
-    position: relative;
-  }
-
-  .angular-logo {
-    max-width: 9.2rem;
-  }
-
-  .content {
-    display: flex;
-    justify-content: space-around;
-    width: 100%;
-    margin-bottom: 3rem;
-  }
-
-  .content > [class$='-side'] {
-    flex-grow: 1;
-  }
-
-  .content > .left-side {
-    display: flex;
-    flex-direction: column;
-    align-items: end;
-  }
-
-  .content h1 {
-    margin-top: 1.75rem;
-  }
-
-  .content p {
-    margin-top: 1.5rem;
-  }
-
-  .divider {
-    width: 1px;
-    background: var(--red-to-pink-to-purple-vertical-gradient);
-    margin-inline: 0.5rem;
-  }
-
-  .login {
-    max-width: 350px;
-  }
-
-  .pill-group {
-    display: flex;
-    flex-direction: column;
-    align-items: start;
-    flex-wrap: wrap;
-    gap: 1.25rem;
-  }
-
+  --bright-blue: oklch(51.01% 0.274 263.83);
+  --bright-blue-bright: oklch(95.00% 0.274 263.83);
+  --electric-violet: oklch(53.18% 0.28 296.97);
+  --electric-violet-bright: oklch(95.00% 0.28 296.97);
+  --french-violet: oklch(47.66% 0.246 305.88);
+  --french-violet-bright: oklch(95.00% 0.246 305.88);
+  --vivid-pink: oklch(69.02% 0.277 332.77);
+  --vivid-pink-bright: oklch(95.00% 0.277 332.77);
+  --hot-red: oklch(61.42% 0.238 15.34);
+  --hot-red-bright: oklch(95.00% 0.238 15.34);
+  --orange-red: oklch(63.32% 0.24 31.68);
+  --orange-red-bright: oklch(95.00% 0.24 31.68)
+
+  --gray-900: oklch(19.37% 0.006 300.98);
+  --gray-700: oklch(36.98% 0.014 302.71);
+  --gray-400: oklch(70.9% 0.015 304.04);
+
+  --red-to-pink-to-purple-vertical-gradient: linear-gradient(
+    180deg,
+    var(--orange-red) 0%,
+    var(--vivid-pink) 50%,
+    var(--electric-violet) 100%
+  );
+
+  --red-to-pink-to-purple-horizontal-gradient: linear-gradient(
+    90deg,
+    var(--orange-red) 0%,
+    var(--vivid-pink) 50%,
+    var(--electric-violet) 100%
+  );
+
+  --pill-accent: var(--bright-blue);
+
+  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
+    Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
+    "Segoe UI Symbol";
+  box-sizing: border-box;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+h1 {
+  font-size: 3.125rem;
+  font-weight: 500;
+  line-height: 100%;
+  letter-spacing: -0.125rem;
+  margin: 0;
+  font-family: "Inter Tight", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
+    Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
+    "Segoe UI Symbol";
+}
+
+p {
+  margin: 0;
+}
+
+main {
+  width: 100%;
+  min-height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  padding: 1rem;
+  box-sizing: inherit;
+  position: relative;
+}
+
+.angular-logo {
+  max-width: 9.2rem;
+}
+
+.content {
+  display: flex;
+  justify-content: space-around;
+  width: 100%;
+  max-width: 700px;
+  margin-bottom: 3rem;
+}
+
+.content h1 {
+  margin-top: 1.75rem;
+}
+
+.content p {
+  margin-top: 1.5rem;
+}
+
+.divider {
+  width: 1px;
+  background: var(--red-to-pink-to-purple-vertical-gradient);
+  margin-inline: 0.5rem;
+}
+
+.pill-group {
+  display: flex;
+  flex-direction: column;
+  align-items: start;
+  flex-wrap: wrap;
+  gap: 1.25rem;
+}
+
+.pill {
+  display: flex;
+  align-items: center;
+  --pill-accent: var(--bright-blue);
+  background: color-mix(in srgb, var(--pill-accent) 5%, transparent);
+  color: var(--pill-accent);
+  padding-inline: 0.75rem;
+  padding-block: 0.375rem;
+  border-radius: 2.75rem;
+  border: 0;
+  transition: background 0.3s ease;
+  font-family: var(--inter-font);
+  font-size: 0.875rem;
+  font-style: normal;
+  font-weight: 500;
+  line-height: 1.4rem;
+  letter-spacing: -0.00875rem;
+  text-decoration: none;
+}
+
+.pill:hover {
+  background: color-mix(in srgb, var(--pill-accent) 15%, transparent);
+}
+
+.pill-group .pill:nth-child(6n + 1) {
+  --pill-accent: var(--bright-blue);
+}
+.pill-group .pill:nth-child(6n + 2) {
+  --pill-accent: var(--french-violet);
+}
+.pill-group .pill:nth-child(6n + 3),
+.pill-group .pill:nth-child(6n + 4),
+.pill-group .pill:nth-child(6n + 5) {
+  --pill-accent: var(--hot-red);
+}
+
+.pill-group svg {
+  margin-inline-start: 0.25rem;
+}
+
+.social-links {
+  display: flex;
+  align-items: center;
+  gap: 0.73rem;
+  margin-top: 1.5rem;
+}
+
+.social-links path {
+  transition: fill 0.3s ease;
+  fill: var(--gray-400);
+}
+
+.social-links a:hover svg path {
+  fill: var(--gray-900);
+}
+
+[class*='dark-theme'] {
   .pill {
-    display: flex;
-    align-items: center;
-    --pill-accent: var(--bright-blue);
-    background: color-mix(in srgb, var(--pill-accent) 5%, transparent);
-    color: var(--pill-accent);
-    padding-inline: 0.75rem;
-    padding-block: 0.375rem;
-    border-radius: 2.75rem;
-    border: 0;
-    transition: background 0.3s ease;
-    font-family: var(--inter-font);
-    font-size: 0.875rem;
-    font-style: normal;
-    font-weight: 500;
-    line-height: 1.4rem;
-    letter-spacing: -0.00875rem;
-    text-decoration: none;
+    background: color-mix(in srgb, var(--pill-accent) 10%, transparent);
   }
 
   .pill:hover {
-    background: color-mix(in srgb, var(--pill-accent) 15%, transparent);
+    background: color-mix(in srgb, var(--pill-accent) 20%, transparent);
   }
 
   .pill-group .pill:nth-child(6n + 1) {
-    --pill-accent: var(--bright-blue);
+    --pill-accent: var(--bright-blue-bright);
   }
   .pill-group .pill:nth-child(6n + 2) {
-    --pill-accent: var(--french-violet);
+    --pill-accent: var(--french-violet-bright);
   }
   .pill-group .pill:nth-child(6n + 3),
   .pill-group .pill:nth-child(6n + 4),
   .pill-group .pill:nth-child(6n + 5) {
-    --pill-accent: var(--hot-red);
+    --pill-accent: var(--hot-red-bright);
   }
+}
 
-  .pill-group svg {
-    margin-inline-start: 0.25rem;
-  }
-
-  .social-links {
-    display: flex;
-    align-items: center;
-    gap: 0.73rem;
-    margin-top: 1.5rem;
-  }
-
-  .social-links path {
-    transition: fill 0.3s ease;
-    fill: var(--gray-400);
+@media screen and (pointer: none), (pointer: coarse) {
+  .content {
+    flex-direction: column;
+    width: 100%;
   }
 
-  .social-links a:hover svg path {
-    fill: var(--gray-900);
+  .divider {
+    height: 1px;
+    width: 100%;
+    background: var(--red-to-pink-to-purple-horizontal-gradient);
+    margin-block: 1.5rem;
   }
-
-  @media screen and (pointer: none), (pointer: coarse) {
-    .content {
-      flex-direction: column;
-      width: 100%;
-    }
-
-    .divider {
-      height: 1px;
-      width: 100%;
-      background: var(--red-to-pink-to-purple-horizontal-gradient);
-      margin-block: 1.5rem;
-    }
-  }
+}

+ 2 - 0
src/app/dashboard/dashboard.component.ts

@@ -7,6 +7,7 @@ import { LoginService } from 'angularlib/login/login.service';
 import { MasterMenuComponent } from 'angularlib/menu/master.menu/master.menu.component';
 import { CommonModule } from '@angular/common';
 import { ComponentService } from 'angularlib/component.service';
+import { LabelModule } from 'angularlib/labels/label.module';
 
 @Component({
   selector: 'app-dashboard',
@@ -15,6 +16,7 @@ import { ComponentService } from 'angularlib/component.service';
     CommonModule,
     RouterModule,
     LoginModule,
+    LabelModule,
     MasterMenuComponent
   ],
   providers: [ComponentService],

+ 1 - 1
src/app/quotation/quotation.module.ts

@@ -12,7 +12,7 @@ import { CommonModule } from '@angular/common';
 import { LabelModule } from 'angularlib/labels/label.module';
 
 const routes: Routes = [
-  { path: '', component: QuotationComponent, canActivate: [AuthGuard], data: {title: 'Sales Quotation',serviceId: ServiceID.Submission, type: 'sales'} },
+  { path: '', component: QuotationComponent, canActivate: [AuthGuard], data: {title: {key:'sales_quotation',default:'Sales Quotation'},serviceId: ServiceID.Submission, type: 'sales'} },
 ]
 
 @NgModule({

+ 1 - 0
src/app/quotation/styles.scss

@@ -38,6 +38,7 @@ mat-sidenav {
 .flex-container > #details {
     flex-grow: 2;
     max-width: 66.66%;
+    padding: 1rem;
 }
 
 #toggle {

+ 1 - 1
src/app/quotation/template.html

@@ -28,7 +28,7 @@
             <mat-card id="details">
                 <div *ngIf="activeDocument?.listingController?.table?.data?.length === 0 && activeDocument?.listingController?.process?.hasActiveProcesses === false"
                     class="no-items"><h1>{{('no_items_found'|tr:'No items found').toUpperCase()}}</h1></div>
-                <ng-container *ngTemplateOutlet="docDetails"></ng-container>
+                <div *ngTemplateOutlet="docDetails"></div>
             </mat-card>
         </div>