mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-17 16:37:43 +00:00
refactor: make prettier work for angular
This commit is contained in:
parent
292e66615d
commit
d34ab71f16
152 changed files with 6731 additions and 6044 deletions
12
.github/dependabot.yml
vendored
12
.github/dependabot.yml
vendored
|
|
@ -9,11 +9,11 @@ updates:
|
||||||
directory: '/' # Location of package manifests
|
directory: '/' # Location of package manifests
|
||||||
schedule:
|
schedule:
|
||||||
interval: 'monthly'
|
interval: 'monthly'
|
||||||
# - package-ecosystem: "npm" # See documentation for possible values
|
# - package-ecosystem: "npm" # See documentation for possible values
|
||||||
# directory: "/tools/schematics/" # Location of package manifests
|
# directory: "/tools/schematics/" # Location of package manifests
|
||||||
# schedule:
|
# schedule:
|
||||||
# interval: "monthly"
|
# interval: "monthly"
|
||||||
- package-ecosystem: "github-actions"
|
- package-ecosystem: 'github-actions'
|
||||||
directory: "/"
|
directory: '/'
|
||||||
schedule:
|
schedule:
|
||||||
interval: monthly
|
interval: monthly
|
||||||
|
|
|
||||||
|
|
@ -11,16 +11,10 @@
|
||||||
"endOfLine": "auto",
|
"endOfLine": "auto",
|
||||||
"printWidth": 90,
|
"printWidth": 90,
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
|
||||||
"files": "*.component.html",
|
|
||||||
"options": {
|
|
||||||
"parser": "angular"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"files": "*.html",
|
"files": "*.html",
|
||||||
"options": {
|
"options": {
|
||||||
"parser": "html"
|
"parser": "angular"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
8
package-lock.json
generated
8
package-lock.json
generated
|
|
@ -121,7 +121,7 @@
|
||||||
"nightwatch": "^3.6.3",
|
"nightwatch": "^3.6.3",
|
||||||
"object-path": "^0.11.8",
|
"object-path": "^0.11.8",
|
||||||
"p-throttle": "^3.1.0",
|
"p-throttle": "^3.1.0",
|
||||||
"prettier": "^3.4.2",
|
"prettier": "^3.5.1",
|
||||||
"pretty-quick": "^4.0.0",
|
"pretty-quick": "^4.0.0",
|
||||||
"query-string": "^7.1.1",
|
"query-string": "^7.1.1",
|
||||||
"rxjs": "^6.6.7",
|
"rxjs": "^6.6.7",
|
||||||
|
|
@ -21014,9 +21014,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/prettier": {
|
"node_modules/prettier": {
|
||||||
"version": "3.4.2",
|
"version": "3.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.1.tgz",
|
||||||
"integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
|
"integrity": "sha512-hPpFQvHwL3Qv5AdRvBFMhnKo4tYxp0ReXiPn2bxkiohEX6mBeBwEpBSQTkD458RaaDKQMYSp4hX4UtfUTA5wDw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"prettier": "bin/prettier.cjs"
|
"prettier": "bin/prettier.cjs"
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@
|
||||||
"nightwatch": "^3.6.3",
|
"nightwatch": "^3.6.3",
|
||||||
"object-path": "^0.11.8",
|
"object-path": "^0.11.8",
|
||||||
"p-throttle": "^3.1.0",
|
"p-throttle": "^3.1.0",
|
||||||
"prettier": "^3.4.2",
|
"prettier": "^3.5.1",
|
||||||
"pretty-quick": "^4.0.0",
|
"pretty-quick": "^4.0.0",
|
||||||
"query-string": "^7.1.1",
|
"query-string": "^7.1.1",
|
||||||
"rxjs": "^6.6.7",
|
"rxjs": "^6.6.7",
|
||||||
|
|
|
||||||
|
|
@ -1,104 +1,111 @@
|
||||||
@if (isShowUi$|async) { @if ((globalThemeService.backgroundImg$|async); as bgImage) {
|
@if (isShowUi$ | async) {
|
||||||
<div
|
@if (globalThemeService.backgroundImg$ | async; as bgImage) {
|
||||||
[style.background]="'url(' + bgImage + ')'"
|
|
||||||
class="bg-image"
|
|
||||||
></div>
|
|
||||||
}
|
|
||||||
<!--TODO move inside page container somehow -->
|
|
||||||
@if (layoutService.isShowAddTaskBar$|async) {
|
|
||||||
<add-task-bar
|
|
||||||
(blurred)="layoutService.hideAddTaskBar()"
|
|
||||||
[isElevated]="true"
|
|
||||||
class="global"
|
|
||||||
></add-task-bar>
|
|
||||||
} @if ((layoutService.isShowAddTaskBar$|async)) {
|
|
||||||
<div
|
|
||||||
(click)="layoutService.hideAddTaskBar()"
|
|
||||||
@fade
|
|
||||||
class="backdrop"
|
|
||||||
></div>
|
|
||||||
} @if (layoutService.isShowSearchBar$|async) {
|
|
||||||
<search-bar (blurred)="layoutService.hideSearchBar()"></search-bar>
|
|
||||||
} @if ((layoutService.isShowSearchBar$|async)) {
|
|
||||||
<div
|
|
||||||
(click)="layoutService.hideSearchBar()"
|
|
||||||
@fade
|
|
||||||
class="backdrop"
|
|
||||||
></div>
|
|
||||||
}
|
|
||||||
<!-- -->
|
|
||||||
@if (isShowFocusOverlay$|async) {
|
|
||||||
<focus-mode-overlay @warp></focus-mode-overlay>
|
|
||||||
} @else {
|
|
||||||
<mat-sidenav-container [dir]="isRTL ? 'rtl' : 'ltr'">
|
|
||||||
<mat-sidenav
|
|
||||||
(closedStart)="layoutService.hideSideNav()"
|
|
||||||
[mode]="(layoutService.isNavOver$|async) ? 'over' : 'side'"
|
|
||||||
[opened]="(layoutService.isShowSideNav$|async)"
|
|
||||||
position="start"
|
|
||||||
>
|
|
||||||
<side-nav></side-nav>
|
|
||||||
@if (workContextService.isActiveWorkContextProject$|async) { }
|
|
||||||
</mat-sidenav>
|
|
||||||
<mat-sidenav-content>
|
|
||||||
<header
|
|
||||||
[class.isNotScrolled]="!(layoutService.isScrolled$|async)"
|
|
||||||
class="header-wrapper"
|
|
||||||
>
|
|
||||||
<main-header></main-header>
|
|
||||||
@if ((workContextService.isActiveWorkContextProject$|async)) {
|
|
||||||
<bookmark-bar></bookmark-bar>
|
|
||||||
}
|
|
||||||
<banner></banner>
|
|
||||||
</header>
|
|
||||||
<div
|
<div
|
||||||
#routeWrapper
|
[style.background]="'url(' + bgImage + ')'"
|
||||||
[@warpRoute]="getPage(o)"
|
class="bg-image"
|
||||||
class="route-wrapper"
|
></div>
|
||||||
>
|
}
|
||||||
<router-outlet #o="outlet"></router-outlet>
|
<!--TODO move inside page container somehow -->
|
||||||
</div>
|
@if (layoutService.isShowAddTaskBar$ | async) {
|
||||||
<global-progress-bar></global-progress-bar>
|
<add-task-bar
|
||||||
</mat-sidenav-content>
|
(blurred)="layoutService.hideAddTaskBar()"
|
||||||
</mat-sidenav-container>
|
[isElevated]="true"
|
||||||
|
class="global"
|
||||||
|
></add-task-bar>
|
||||||
|
}
|
||||||
|
@if (layoutService.isShowAddTaskBar$ | async) {
|
||||||
|
<div
|
||||||
|
(click)="layoutService.hideAddTaskBar()"
|
||||||
|
@fade
|
||||||
|
class="backdrop"
|
||||||
|
></div>
|
||||||
|
}
|
||||||
|
@if (layoutService.isShowSearchBar$ | async) {
|
||||||
|
<search-bar (blurred)="layoutService.hideSearchBar()"></search-bar>
|
||||||
|
}
|
||||||
|
@if (layoutService.isShowSearchBar$ | async) {
|
||||||
|
<div
|
||||||
|
(click)="layoutService.hideSearchBar()"
|
||||||
|
@fade
|
||||||
|
class="backdrop"
|
||||||
|
></div>
|
||||||
|
}
|
||||||
|
<!-- -->
|
||||||
|
@if (isShowFocusOverlay$ | async) {
|
||||||
|
<focus-mode-overlay @warp></focus-mode-overlay>
|
||||||
|
} @else {
|
||||||
|
<mat-sidenav-container [dir]="isRTL ? 'rtl' : 'ltr'">
|
||||||
|
<mat-sidenav
|
||||||
|
(closedStart)="layoutService.hideSideNav()"
|
||||||
|
[mode]="(layoutService.isNavOver$ | async) ? 'over' : 'side'"
|
||||||
|
[opened]="layoutService.isShowSideNav$ | async"
|
||||||
|
position="start"
|
||||||
|
>
|
||||||
|
<side-nav></side-nav>
|
||||||
|
@if (workContextService.isActiveWorkContextProject$ | async) {}
|
||||||
|
</mat-sidenav>
|
||||||
|
<mat-sidenav-content>
|
||||||
|
<header
|
||||||
|
[class.isNotScrolled]="!(layoutService.isScrolled$ | async)"
|
||||||
|
class="header-wrapper"
|
||||||
|
>
|
||||||
|
<main-header></main-header>
|
||||||
|
@if (workContextService.isActiveWorkContextProject$ | async) {
|
||||||
|
<bookmark-bar></bookmark-bar>
|
||||||
|
}
|
||||||
|
<banner></banner>
|
||||||
|
</header>
|
||||||
|
<div
|
||||||
|
#routeWrapper
|
||||||
|
[@warpRoute]="getPage(o)"
|
||||||
|
class="route-wrapper"
|
||||||
|
>
|
||||||
|
<router-outlet #o="outlet"></router-outlet>
|
||||||
|
</div>
|
||||||
|
<global-progress-bar></global-progress-bar>
|
||||||
|
</mat-sidenav-content>
|
||||||
|
</mat-sidenav-container>
|
||||||
|
}
|
||||||
|
<!-- -->
|
||||||
}
|
}
|
||||||
<!-- -->
|
@if (
|
||||||
} @if (!(syncTriggerService.afterInitialSyncDoneAndDataLoadedInitially$|async) ||
|
!(syncTriggerService.afterInitialSyncDoneAndDataLoadedInitially$ | async) ||
|
||||||
(imexMetaService.isDataImportInProgress$|async)) {
|
(imexMetaService.isDataImportInProgress$ | async)
|
||||||
<div class="loading-full-page-wrapper">
|
) {
|
||||||
<global-progress-bar></global-progress-bar>
|
<div class="loading-full-page-wrapper">
|
||||||
<div class="app-loading">
|
<global-progress-bar></global-progress-bar>
|
||||||
<div class="productivity-tip">
|
<div class="app-loading">
|
||||||
<h2 id="heading">{{ productivityTipTitle }}</h2>
|
<div class="productivity-tip">
|
||||||
<p id="text">{{ productivityTipText }}</p>
|
<h2 id="heading">{{ productivityTipTitle }}</h2>
|
||||||
|
<p id="text">{{ productivityTipText }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="spinner">
|
||||||
|
<div class="double-bounce1"></div>
|
||||||
|
<div class="double-bounce2"></div>
|
||||||
|
</div>
|
||||||
|
<svg
|
||||||
|
class="logo"
|
||||||
|
viewBox="0 0 64 64"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M 0.65537046,34.582787 32.452267,63.855301 63.791548,0.94356422 30.222644,47.722023 Z"
|
||||||
|
id="path3395"
|
||||||
|
style="
|
||||||
|
fill: #000000;
|
||||||
|
fill-opacity: 1;
|
||||||
|
fill-rule: evenodd;
|
||||||
|
stroke: none;
|
||||||
|
stroke-width: 1.46761858;
|
||||||
|
stroke-linecap: butt;
|
||||||
|
stroke-linejoin: bevel;
|
||||||
|
stroke-miterlimit: 13.80000019;
|
||||||
|
stroke-dasharray: none;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="spinner">
|
|
||||||
<div class="double-bounce1"></div>
|
|
||||||
<div class="double-bounce2"></div>
|
|
||||||
</div>
|
|
||||||
<svg
|
|
||||||
class="logo"
|
|
||||||
viewBox="0 0 64 64"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M 0.65537046,34.582787 32.452267,63.855301 63.791548,0.94356422 30.222644,47.722023 Z"
|
|
||||||
id="path3395"
|
|
||||||
style="
|
|
||||||
fill: #000000;
|
|
||||||
fill-opacity: 1;
|
|
||||||
fill-rule: evenodd;
|
|
||||||
stroke: none;
|
|
||||||
stroke-width: 1.46761858;
|
|
||||||
stroke-linecap: butt;
|
|
||||||
stroke-linejoin: bevel;
|
|
||||||
stroke-miterlimit: 13.80000019;
|
|
||||||
stroke-dasharray: none;
|
|
||||||
stroke-opacity: 1;
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
<!-- -->
|
<!-- -->
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
@if ((globalProgressBarService.label$|async); as label) {
|
@if (globalProgressBarService.label$ | async; as label) {
|
||||||
<div
|
<div
|
||||||
[@fadeOut]
|
[@fadeOut]
|
||||||
class="badge"
|
class="badge"
|
||||||
>
|
>
|
||||||
{{label|translate}}
|
{{ label | translate }}
|
||||||
</div>
|
</div>
|
||||||
} @if ((globalProgressBarService.isShowGlobalProgressBar$|async)) {
|
}
|
||||||
<div [@fadeInOutBottom]>
|
@if (globalProgressBarService.isShowGlobalProgressBar$ | async) {
|
||||||
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
<div [@fadeInOutBottom]>
|
||||||
</div>
|
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<!--<div class="badge">Some test text</div>-->
|
<!--<div class="badge">Some test text</div>-->
|
||||||
|
|
|
||||||
|
|
@ -1,48 +1,50 @@
|
||||||
@let activeWorkContextTypeAndId = workContextService.activeWorkContextTypeAndId$|async;
|
@let activeWorkContextTypeAndId = workContextService.activeWorkContextTypeAndId$ | async;
|
||||||
|
|
||||||
<!--<div class="wrapper ">-->
|
<!--<div class="wrapper ">-->
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
@if (!(layoutService.isNavAlwaysVisible$|async)) {
|
@if (!(layoutService.isNavAlwaysVisible$ | async)) {
|
||||||
<button
|
<button
|
||||||
(click)="layoutService.toggleSideNav()"
|
(click)="layoutService.toggleSideNav()"
|
||||||
class="burger-trigger tour-burgerTrigger"
|
class="burger-trigger tour-burgerTrigger"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
>
|
>
|
||||||
<mat-icon>menu</mat-icon>
|
<mat-icon>menu</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
<!---->
|
<!---->
|
||||||
@if (activeWorkContextTypeAndId) {
|
@if (activeWorkContextTypeAndId) {
|
||||||
<div
|
<div
|
||||||
[matTooltip]="T.MH.GO_TO_TASK_LIST|translate"
|
[matTooltip]="T.MH.GO_TO_TASK_LIST | translate"
|
||||||
class="current-work-context-title"
|
class="current-work-context-title"
|
||||||
mat-ripple
|
mat-ripple
|
||||||
routerLink="/active/tasks"
|
routerLink="/active/tasks"
|
||||||
>
|
>
|
||||||
{{ workContextService.activeWorkContextTitle$|async }}
|
{{ workContextService.activeWorkContextTitle$ | async }}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
[mat-menu-trigger-for]="activeWorkContextMenu"
|
[mat-menu-trigger-for]="activeWorkContextMenu"
|
||||||
[matTooltip]="T.MH.PROJECT_MENU|translate"
|
[matTooltip]="T.MH.PROJECT_MENU | translate"
|
||||||
class="project-settings-btn hide-xxxs"
|
class="project-settings-btn hide-xxxs"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
>
|
>
|
||||||
<mat-icon>more_vert</mat-icon>
|
<mat-icon>more_vert</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<mat-menu #activeWorkContextMenu="matMenu">
|
<mat-menu #activeWorkContextMenu="matMenu">
|
||||||
<ng-template matMenuContent>
|
<ng-template matMenuContent>
|
||||||
<work-context-menu
|
<work-context-menu
|
||||||
[contextId]="activeWorkContextTypeAndId.activeId"
|
[contextId]="activeWorkContextTypeAndId.activeId"
|
||||||
[contextType]="activeWorkContextTypeAndId.activeType"
|
[contextType]="activeWorkContextTypeAndId.activeType"
|
||||||
></work-context-menu>
|
></work-context-menu>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
}
|
}
|
||||||
|
|
||||||
<nav class="action-nav">
|
<nav class="action-nav">
|
||||||
<button
|
<button
|
||||||
(click)="layoutService.showAddTaskBar()"
|
(click)="layoutService.showAddTaskBar()"
|
||||||
matTooltip="{{T.MH.ADD_NEW_TASK|translate}} {{kb.addNewTask?'['+kb.addNewTask+']':''}}"
|
matTooltip="{{ T.MH.ADD_NEW_TASK | translate }} {{
|
||||||
|
kb.addNewTask ? '[' + kb.addNewTask + ']' : ''
|
||||||
|
}}"
|
||||||
class="hide-xs tour-addBtn"
|
class="hide-xs tour-addBtn"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
>
|
>
|
||||||
|
|
@ -51,40 +53,42 @@
|
||||||
|
|
||||||
<button
|
<button
|
||||||
(click)="layoutService.showSearchBar()"
|
(click)="layoutService.showSearchBar()"
|
||||||
matTooltip="{{T.MH.SHOW_SEARCH_BAR|translate}} {{kb.showSearchBar?'['+kb.showSearchBar+']':''}}"
|
matTooltip="{{ T.MH.SHOW_SEARCH_BAR | translate }} {{
|
||||||
|
kb.showSearchBar ? '[' + kb.showSearchBar + ']' : ''
|
||||||
|
}}"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
>
|
>
|
||||||
<mat-icon>search</mat-icon>
|
<mat-icon>search</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@let isOnline = isOnline$|async;
|
@let isOnline = isOnline$ | async;
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@let isSyncEnabled = syncProviderService.isEnabled$|async;
|
@let isSyncEnabled = syncProviderService.isEnabled$ | async;
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="sync-btn"
|
class="sync-btn"
|
||||||
matTooltip="{{T.MH.TRIGGER_SYNC|translate}}"
|
matTooltip="{{ T.MH.TRIGGER_SYNC | translate }}"
|
||||||
(click)="isSyncEnabled ? sync() : setupSync()"
|
(click)="isSyncEnabled ? sync() : setupSync()"
|
||||||
(longPress)="setupSync()"
|
(longPress)="setupSync()"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
>
|
>
|
||||||
@if (isSyncEnabled) {
|
@if (isSyncEnabled) {
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@if(isOnline) {
|
@if (isOnline) {
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<mat-icon [class.spin]="(syncProviderService.isSyncing$|async)">sync</mat-icon>
|
<mat-icon [class.spin]="syncProviderService.isSyncing$ | async">sync</mat-icon>
|
||||||
@let isInSync = syncProviderService.isCurrentProviderInSync$|async;
|
@let isInSync = syncProviderService.isCurrentProviderInSync$ | async;
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@if (isInSync) {
|
@if (isInSync) {
|
||||||
<mat-icon class="sync-success-check-ico">check</mat-icon>
|
<mat-icon class="sync-success-check-ico">check</mat-icon>
|
||||||
}
|
}
|
||||||
<!-- -->
|
<!-- -->
|
||||||
|
} @else {
|
||||||
|
<mat-icon>wifi_off</mat-icon>
|
||||||
|
}
|
||||||
|
<!-- -->
|
||||||
} @else {
|
} @else {
|
||||||
<mat-icon>wifi_off</mat-icon>
|
<mat-icon>sync_disabled</mat-icon>
|
||||||
}
|
|
||||||
<!-- -->
|
|
||||||
} @else {
|
|
||||||
<mat-icon>sync_disabled</mat-icon>
|
|
||||||
}
|
}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
@ -109,58 +113,68 @@
|
||||||
<!-- </mat-icon>-->
|
<!-- </mat-icon>-->
|
||||||
<!-- </button>-->
|
<!-- </button>-->
|
||||||
|
|
||||||
@if (!(globalConfigService.cfg$|async)?.focusMode?.isAlwaysUseFocusMode) {
|
@if (!(globalConfigService.cfg$ | async)?.focusMode?.isAlwaysUseFocusMode) {
|
||||||
<button
|
<button
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
matTooltip="Enter focus mode {{kb.goToFocusMode?'['+kb.goToFocusMode+']':''}}"
|
matTooltip="Enter focus mode {{
|
||||||
class="hide-xxs"
|
kb.goToFocusMode ? '[' + kb.goToFocusMode + ']' : ''
|
||||||
(click)="enableFocusMode()"
|
}}"
|
||||||
>
|
class="hide-xxs"
|
||||||
<mat-icon>center_focus_strong</mat-icon>
|
(click)="enableFocusMode()"
|
||||||
</button>
|
>
|
||||||
|
<mat-icon>center_focus_strong</mat-icon>
|
||||||
|
</button>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="play-btn-wrapper">
|
<div class="play-btn-wrapper">
|
||||||
@if ((taskService.currentTask$|async); as currentTask) {
|
@if (taskService.currentTask$ | async; as currentTask) {
|
||||||
<div
|
<div
|
||||||
@fade
|
@fade
|
||||||
class="current-task-title"
|
class="current-task-title"
|
||||||
>
|
>
|
||||||
<div class="title">{{ currentTask.title }}</div>
|
<div class="title">{{ currentTask.title }}</div>
|
||||||
@if ((currentTaskContext$|async); as currentTaskContext) {
|
@if (currentTaskContext$ | async; as currentTaskContext) {
|
||||||
<tag
|
<tag
|
||||||
@expandFadeHorizontal
|
@expandFadeHorizontal
|
||||||
[tag]="currentTaskContext"
|
[tag]="currentTaskContext"
|
||||||
class="project"
|
class="project"
|
||||||
></tag>
|
></tag>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
} @if ((taskService.currentTaskId$|async)) {
|
}
|
||||||
<div class="pulse-circle"></div>
|
@if (taskService.currentTaskId$ | async) {
|
||||||
|
<div class="pulse-circle"></div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
(click)="taskService.toggleStartTask()"
|
(click)="taskService.toggleStartTask()"
|
||||||
[color]="(taskService.currentTaskId$|async)? 'accent': 'primary'"
|
[color]="(taskService.currentTaskId$ | async) ? 'accent' : 'primary'"
|
||||||
matTooltip="{{T.MH.TOGGLE_TRACK_TIME|translate}}"
|
matTooltip="{{ T.MH.TOGGLE_TRACK_TIME | translate }}"
|
||||||
[matTooltipPosition]="(pomodoroService.isEnabled$|async)? 'left': 'below'"
|
[matTooltipPosition]="(pomodoroService.isEnabled$ | async) ? 'left' : 'below'"
|
||||||
class="play-btn tour-playBtn mat-elevation-z3"
|
class="play-btn tour-playBtn mat-elevation-z3"
|
||||||
mat-mini-fab
|
mat-mini-fab
|
||||||
>
|
>
|
||||||
@if ((pomodoroService.isEnabled$|async)) { @if ((pomodoroService.isBreak$|async))
|
@if (pomodoroService.isEnabled$ | async) {
|
||||||
{
|
@if (pomodoroService.isBreak$ | async) {
|
||||||
<mat-icon>free_breakfast</mat-icon>
|
<mat-icon>free_breakfast</mat-icon>
|
||||||
} @if (!(pomodoroService.isBreak$|async)) { @if
|
}
|
||||||
(!(taskService.currentTaskId$|async)) {
|
@if (!(pomodoroService.isBreak$ | async)) {
|
||||||
<mat-icon>play_arrow</mat-icon>
|
@if (!(taskService.currentTaskId$ | async)) {
|
||||||
} @if ((taskService.currentTaskId$|async)) {
|
<mat-icon>play_arrow</mat-icon>
|
||||||
<mat-icon>pause</mat-icon>
|
}
|
||||||
} } } @if (!(pomodoroService.isEnabled$|async)) { @if
|
@if (taskService.currentTaskId$ | async) {
|
||||||
(!(taskService.currentTaskId$|async)) {
|
<mat-icon>pause</mat-icon>
|
||||||
<mat-icon>play_arrow</mat-icon>
|
}
|
||||||
} @if ((taskService.currentTaskId$|async)) {
|
}
|
||||||
<mat-icon>pause</mat-icon>
|
}
|
||||||
} }
|
@if (!(pomodoroService.isEnabled$ | async)) {
|
||||||
|
@if (!(taskService.currentTaskId$ | async)) {
|
||||||
|
<mat-icon>play_arrow</mat-icon>
|
||||||
|
}
|
||||||
|
@if (taskService.currentTaskId$ | async) {
|
||||||
|
<mat-icon>pause</mat-icon>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
class="circle-svg"
|
class="circle-svg"
|
||||||
|
|
@ -182,86 +196,96 @@
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@if ((pomodoroService.cfg$|async)?.isEnabled) {
|
@if ((pomodoroService.cfg$ | async)?.isEnabled) {
|
||||||
<div class="pomodoro-label">
|
<div class="pomodoro-label">
|
||||||
{{ (pomodoroService.currentSessionTime$|async|msToMinuteClockString) }}
|
{{ pomodoroService.currentSessionTime$ | async | msToMinuteClockString }}
|
||||||
</div>
|
</div>
|
||||||
<div class="pomodoro-controls">
|
<div class="pomodoro-controls">
|
||||||
<button
|
<button
|
||||||
(click)="pomodoroService.finishPomodoroSession()"
|
(click)="pomodoroService.finishPomodoroSession()"
|
||||||
[matTooltip]="T.F.POMODORO.S.SESSION_SKIP|translate"
|
[matTooltip]="T.F.POMODORO.S.SESSION_SKIP | translate"
|
||||||
matTooltipPosition="left"
|
matTooltipPosition="left"
|
||||||
class="pomodoro-btn"
|
class="pomodoro-btn"
|
||||||
color=""
|
color=""
|
||||||
mat-mini-fab
|
mat-mini-fab
|
||||||
>
|
>
|
||||||
<mat-icon>skip_next</mat-icon>
|
<mat-icon>skip_next</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
(click)="pomodoroService.stop()"
|
(click)="pomodoroService.stop()"
|
||||||
[matTooltip]="T.F.POMODORO.S.RESET|translate"
|
[matTooltip]="T.F.POMODORO.S.RESET | translate"
|
||||||
matTooltipPosition="left"
|
matTooltipPosition="left"
|
||||||
class="pomodoro-btn"
|
class="pomodoro-btn"
|
||||||
color=""
|
color=""
|
||||||
mat-mini-fab
|
mat-mini-fab
|
||||||
>
|
>
|
||||||
<mat-icon>restart_alt</mat-icon>
|
<mat-icon>restart_alt</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if ((simpleCounterService.enabledSimpleCounters$|async); as enabledSimpleCounters) {
|
@if (simpleCounterService.enabledSimpleCounters$ | async; as enabledSimpleCounters) {
|
||||||
@if (enabledSimpleCounters.length) {
|
@if (enabledSimpleCounters.length) {
|
||||||
<div class="simple-counter-buttons-outer-wrapper">
|
<div class="simple-counter-buttons-outer-wrapper">
|
||||||
<button
|
<button
|
||||||
(click)="isShowSimpleCounterBtnsMobile=!isShowSimpleCounterBtnsMobile"
|
(click)="isShowSimpleCounterBtnsMobile = !isShowSimpleCounterBtnsMobile"
|
||||||
class="simple-counter-mobile-trigger show-xs-only"
|
class="simple-counter-mobile-trigger show-xs-only"
|
||||||
[color]="isCounterRunning(enabledSimpleCounters) ? 'accent':''"
|
[color]="isCounterRunning(enabledSimpleCounters) ? 'accent' : ''"
|
||||||
mat-mini-fab
|
mat-mini-fab
|
||||||
>
|
>
|
||||||
@if (!isShowSimpleCounterBtnsMobile) {
|
@if (!isShowSimpleCounterBtnsMobile) {
|
||||||
<mat-icon>timer</mat-icon>
|
<mat-icon>timer</mat-icon>
|
||||||
} @if (isShowSimpleCounterBtnsMobile) {
|
}
|
||||||
<mat-icon>close</mat-icon>
|
@if (isShowSimpleCounterBtnsMobile) {
|
||||||
}
|
<mat-icon>close</mat-icon>
|
||||||
</button>
|
}
|
||||||
<div
|
</button>
|
||||||
class="simple-counter-buttons"
|
<div
|
||||||
[class.isVisibleMobile]="isShowSimpleCounterBtnsMobile"
|
class="simple-counter-buttons"
|
||||||
>
|
[class.isVisibleMobile]="isShowSimpleCounterBtnsMobile"
|
||||||
@for (simpleCounter of enabledSimpleCounters; track trackById($index,
|
>
|
||||||
simpleCounter)) {
|
@for (
|
||||||
<simple-counter-button
|
simpleCounter of enabledSimpleCounters;
|
||||||
[matTooltip]="simpleCounter.title"
|
track trackById($index, simpleCounter)
|
||||||
[simpleCounter]="simpleCounter"
|
) {
|
||||||
></simple-counter-button>
|
<simple-counter-button
|
||||||
}
|
[matTooltip]="simpleCounter.title"
|
||||||
</div>
|
[simpleCounter]="simpleCounter"
|
||||||
</div>
|
></simple-counter-button>
|
||||||
} }
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="toggle-notes-btn tour-issuePanelTrigger e2e-toggle-issue-provider-panel"
|
class="toggle-notes-btn tour-issuePanelTrigger e2e-toggle-issue-provider-panel"
|
||||||
[disabled]="!(isRouteWithSidePanel$|async)"
|
[disabled]="!(isRouteWithSidePanel$ | async)"
|
||||||
[class.isActive]="(layoutService.isShowIssuePanel$|async)"
|
[class.isActive]="layoutService.isShowIssuePanel$ | async"
|
||||||
[class.isRouteWithRightPanel]="(isRouteWithRightPanel$|async)"
|
[class.isRouteWithRightPanel]="isRouteWithRightPanel$ | async"
|
||||||
(click)="layoutService.toggleAddTaskPanel()"
|
(click)="layoutService.toggleAddTaskPanel()"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
matTooltip="{{T.MH.TOGGLE_SHOW_ISSUE_PANEL|translate}} {{kb.toggleIssuePanel?'['+kb.toggleIssuePanel+']':''}}"
|
matTooltip="{{ T.MH.TOGGLE_SHOW_ISSUE_PANEL | translate }} {{
|
||||||
|
kb.toggleIssuePanel ? '[' + kb.toggleIssuePanel + ']' : ''
|
||||||
|
}}"
|
||||||
>
|
>
|
||||||
<mat-icon class="note-ico">playlist_add</mat-icon>
|
<mat-icon class="note-ico">playlist_add</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="toggle-notes-btn e2e-toggle-notes-btn"
|
class="toggle-notes-btn e2e-toggle-notes-btn"
|
||||||
[title]="!(isRouteWithSidePanel$|async) ? (T.MH.NOTES_PANEL_INFO|translate) : ''"
|
[title]="
|
||||||
[disabled]="!(isRouteWithSidePanel$|async)"
|
!(isRouteWithSidePanel$ | async) ? (T.MH.NOTES_PANEL_INFO | translate) : ''
|
||||||
[class.isActive]="(layoutService.isShowNotes$|async)"
|
"
|
||||||
[class.isRouteWithRightPanel]="(isRouteWithRightPanel$|async)"
|
[disabled]="!(isRouteWithSidePanel$ | async)"
|
||||||
|
[class.isActive]="layoutService.isShowNotes$ | async"
|
||||||
|
[class.isRouteWithRightPanel]="isRouteWithRightPanel$ | async"
|
||||||
(click)="layoutService.toggleNotes()"
|
(click)="layoutService.toggleNotes()"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
matTooltip="{{T.MH.TOGGLE_SHOW_NOTES|translate}} {{kb.openProjectNotes?'['+kb.openProjectNotes+']':''}}"
|
matTooltip="{{ T.MH.TOGGLE_SHOW_NOTES | translate }} {{
|
||||||
|
kb.openProjectNotes ? '[' + kb.openProjectNotes + ']' : ''
|
||||||
|
}}"
|
||||||
>
|
>
|
||||||
<mat-icon class="note-ico">comment</mat-icon>
|
<mat-icon class="note-ico">comment</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
<button
|
<button
|
||||||
#routeBtn
|
#routeBtn
|
||||||
[routerLink]="[type() ==='TAG' ? 'tag' :'project', workContext().id, 'tasks']"
|
[routerLink]="[type() === 'TAG' ? 'tag' : 'project', workContext().id, 'tasks']"
|
||||||
routerLinkActive="isActiveRoute"
|
routerLinkActive="isActiveRoute"
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
<section class="main">
|
<section class="main">
|
||||||
@if ((workContextService.mainWorkContext$|async); as mainContext) {
|
@if (workContextService.mainWorkContext$ | async; as mainContext) {
|
||||||
<side-nav-item
|
<side-nav-item
|
||||||
#menuEntry
|
#menuEntry
|
||||||
[type]="WorkContextType.TAG"
|
[type]="WorkContextType.TAG"
|
||||||
[defaultIcon]="mainContext.icon"
|
[defaultIcon]="mainContext.icon"
|
||||||
[workContext]="mainContext"
|
[workContext]="mainContext"
|
||||||
[activeWorkContextId]="activeWorkContextId"
|
[activeWorkContextId]="activeWorkContextId"
|
||||||
></side-nav-item>
|
></side-nav-item>
|
||||||
}
|
}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
routerLinkActive="isActiveRoute"
|
routerLinkActive="isActiveRoute"
|
||||||
>
|
>
|
||||||
<mat-icon svgIcon="early_on"></mat-icon>
|
<mat-icon svgIcon="early_on"></mat-icon>
|
||||||
<span class="text">{{ T.MH.SCHEDULE|translate }}</span>
|
<span class="text">{{ T.MH.SCHEDULE | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
@ -28,132 +28,135 @@
|
||||||
routerLinkActive="isActiveRoute"
|
routerLinkActive="isActiveRoute"
|
||||||
>
|
>
|
||||||
<mat-icon>edit_calendar</mat-icon>
|
<mat-icon>edit_calendar</mat-icon>
|
||||||
<span class="text">{{ T.MH.PLANNER|translate }}</span>
|
<span class="text">{{ T.MH.PLANNER | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@if (nonHiddenProjects$|async; as projectList) {
|
@if (nonHiddenProjects$ | async; as projectList) {
|
||||||
<section class="projects tour-projects">
|
<section class="projects tour-projects">
|
||||||
<div class="g-multi-btn-wrapper">
|
<div class="g-multi-btn-wrapper">
|
||||||
|
<button
|
||||||
|
#menuEntry
|
||||||
|
#projectExpandBtn
|
||||||
|
(click)="toggleExpandProjects()"
|
||||||
|
(keydown)="toggleExpandProjectsLeftRight($event)"
|
||||||
|
[class.isExpanded]="isProjectsExpanded"
|
||||||
|
class="expand-btn"
|
||||||
|
mat-menu-item
|
||||||
|
>
|
||||||
|
<mat-icon>expand_more</mat-icon>
|
||||||
|
<span class="title">{{ T.MH.PROJECTS | translate }}</span>
|
||||||
|
</button>
|
||||||
|
<!-- <button-->
|
||||||
|
<!-- #projectVisibilityBtn-->
|
||||||
|
<!-- mat-icon-button-->
|
||||||
|
<!-- class="additional-btn"-->
|
||||||
|
<!-- >-->
|
||||||
|
<!-- <mat-icon>visibility</mat-icon>-->
|
||||||
|
<!-- </button>-->
|
||||||
|
<button
|
||||||
|
[style.display]="projectList.length ? '' : 'none'"
|
||||||
|
class="additional-btn"
|
||||||
|
#projectExpandBtn2
|
||||||
|
mat-icon-button
|
||||||
|
>
|
||||||
|
<mat-icon>more_vert</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
(click)="addProject()"
|
||||||
|
class="additional-btn"
|
||||||
|
mat-icon-button
|
||||||
|
[matTooltip]="T.MH.CREATE_PROJECT | translate"
|
||||||
|
>
|
||||||
|
<mat-icon>add</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<!-- [leftClickTriggerEl]="projectVisibilityBtn"-->
|
||||||
|
<context-menu
|
||||||
|
[contextMenu]="contextMenu"
|
||||||
|
[leftClickTriggerEl]="projectExpandBtn2"
|
||||||
|
[rightClickTriggerEl]="projectExpandBtn"
|
||||||
|
></context-menu>
|
||||||
|
<ng-template #contextMenu>
|
||||||
|
@for (project of allProjects$ | async; track project.id) {
|
||||||
|
<button
|
||||||
|
mat-menu-item
|
||||||
|
(click)="toggleProjectVisibility(project)"
|
||||||
|
>
|
||||||
|
@if (!project.isHiddenFromMenu) {
|
||||||
|
<mat-icon>visibility</mat-icon>
|
||||||
|
}
|
||||||
|
@if (project.isHiddenFromMenu) {
|
||||||
|
<mat-icon>visibility_off</mat-icon>
|
||||||
|
}
|
||||||
|
{{ project.title }}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</ng-template>
|
||||||
|
<div
|
||||||
|
[@standardList]="projectList?.length"
|
||||||
|
cdkDropList
|
||||||
|
(cdkDropListDropped)="dropOnProjectList(projectList, $event)"
|
||||||
|
>
|
||||||
|
@for (project of projectList; track project.id) {
|
||||||
|
<side-nav-item
|
||||||
|
#menuEntry
|
||||||
|
cdkDrag
|
||||||
|
[cdkDragData]="project"
|
||||||
|
[cdkDragStartDelay]="IS_TOUCH_PRIMARY ? DRAG_DELAY_FOR_TOUCH_LONGER : 0"
|
||||||
|
(keydown)="checkFocusProject($event)"
|
||||||
|
[workContext]="project"
|
||||||
|
[type]="WorkContextType.PROJECT"
|
||||||
|
[defaultIcon]="'folder_special'"
|
||||||
|
[activeWorkContextId]="activeWorkContextId"
|
||||||
|
></side-nav-item>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
}
|
||||||
|
@if (tagList$ | async; as tagList) {
|
||||||
|
<section class="tags">
|
||||||
<button
|
<button
|
||||||
#menuEntry
|
#menuEntry
|
||||||
#projectExpandBtn
|
#tagExpandBtn
|
||||||
(click)="toggleExpandProjects()"
|
(click)="toggleExpandTags()"
|
||||||
(keydown)="toggleExpandProjectsLeftRight($event)"
|
(keydown)="toggleExpandTagsLeftRight($event)"
|
||||||
[class.isExpanded]="isProjectsExpanded"
|
[class.isExpanded]="isTagsExpanded"
|
||||||
class="expand-btn"
|
class="expand-btn"
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
>
|
>
|
||||||
|
<span class="title">{{ T.MH.TAGS | translate }}</span>
|
||||||
<mat-icon>expand_more</mat-icon>
|
<mat-icon>expand_more</mat-icon>
|
||||||
<span class="title">{{ T.MH.PROJECTS|translate }}</span>
|
|
||||||
</button>
|
</button>
|
||||||
<!-- <button-->
|
<div
|
||||||
<!-- #projectVisibilityBtn-->
|
[@standardList]="tagList?.length"
|
||||||
<!-- mat-icon-button-->
|
cdkDropList
|
||||||
<!-- class="additional-btn"-->
|
(cdkDropListDropped)="dropOnTagList(tagList, $event)"
|
||||||
<!-- >-->
|
|
||||||
<!-- <mat-icon>visibility</mat-icon>-->
|
|
||||||
<!-- </button>-->
|
|
||||||
<button
|
|
||||||
[style.display]="projectList.length ? '' : 'none'"
|
|
||||||
class="additional-btn"
|
|
||||||
#projectExpandBtn2
|
|
||||||
mat-icon-button
|
|
||||||
>
|
>
|
||||||
<mat-icon>more_vert</mat-icon>
|
@for (tag of tagList; track tag.id) {
|
||||||
</button>
|
<side-nav-item
|
||||||
<button
|
#menuEntry
|
||||||
(click)="addProject()"
|
cdkDrag
|
||||||
class="additional-btn"
|
[cdkDragData]="tag"
|
||||||
mat-icon-button
|
[cdkDragStartDelay]="IS_TOUCH_PRIMARY ? DRAG_DELAY_FOR_TOUCH_LONGER : 0"
|
||||||
[matTooltip]="T.MH.CREATE_PROJECT|translate"
|
(keydown)="checkFocusTag($event)"
|
||||||
>
|
[workContext]="tag"
|
||||||
<mat-icon>add</mat-icon>
|
[type]="WorkContextType.TAG"
|
||||||
</button>
|
[defaultIcon]="'style'"
|
||||||
</div>
|
[activeWorkContextId]="activeWorkContextId"
|
||||||
<!-- [leftClickTriggerEl]="projectVisibilityBtn"-->
|
></side-nav-item>
|
||||||
<context-menu
|
}
|
||||||
[contextMenu]="contextMenu"
|
</div>
|
||||||
[leftClickTriggerEl]="projectExpandBtn2"
|
@if (!tagList.length && isTagsExpanded) {
|
||||||
[rightClickTriggerEl]="projectExpandBtn"
|
<div class="no-tags-info">{{ T.MH.NO_TAG_INFO | translate }}</div>
|
||||||
></context-menu>
|
|
||||||
<ng-template #contextMenu>
|
|
||||||
@for (project of (allProjects$|async); track project.id) {
|
|
||||||
<button
|
|
||||||
mat-menu-item
|
|
||||||
(click)="toggleProjectVisibility(project)"
|
|
||||||
>
|
|
||||||
@if (!project.isHiddenFromMenu) {
|
|
||||||
<mat-icon>visibility</mat-icon>
|
|
||||||
} @if (project.isHiddenFromMenu) {
|
|
||||||
<mat-icon>visibility_off</mat-icon>
|
|
||||||
} {{ project.title }}
|
|
||||||
</button>
|
|
||||||
}
|
}
|
||||||
</ng-template>
|
<!-- <button (click)="addTag()"-->
|
||||||
<div
|
<!-- *ngIf="isTagsExpanded"-->
|
||||||
[@standardList]="projectList?.length"
|
<!-- #menuEntry mat-menu-item>-->
|
||||||
cdkDropList
|
<!-- <mat-icon>add</mat-icon>-->
|
||||||
(cdkDropListDropped)="dropOnProjectList(projectList, $event)"
|
<!-- {{T.MH.CREATE_TAG|translate}}-->
|
||||||
>
|
<!-- </button>-->
|
||||||
@for (project of projectList; track project.id) {
|
</section>
|
||||||
<side-nav-item
|
|
||||||
#menuEntry
|
|
||||||
cdkDrag
|
|
||||||
[cdkDragData]="project"
|
|
||||||
[cdkDragStartDelay]="IS_TOUCH_PRIMARY ? DRAG_DELAY_FOR_TOUCH_LONGER : 0"
|
|
||||||
(keydown)="checkFocusProject($event)"
|
|
||||||
[workContext]="project"
|
|
||||||
[type]="WorkContextType.PROJECT"
|
|
||||||
[defaultIcon]="'folder_special'"
|
|
||||||
[activeWorkContextId]="activeWorkContextId"
|
|
||||||
></side-nav-item>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
} @if ((tagList$|async); as tagList) {
|
|
||||||
<section class="tags">
|
|
||||||
<button
|
|
||||||
#menuEntry
|
|
||||||
#tagExpandBtn
|
|
||||||
(click)="toggleExpandTags()"
|
|
||||||
(keydown)="toggleExpandTagsLeftRight($event)"
|
|
||||||
[class.isExpanded]="isTagsExpanded"
|
|
||||||
class="expand-btn"
|
|
||||||
mat-menu-item
|
|
||||||
>
|
|
||||||
<span class="title">{{ T.MH.TAGS|translate }}</span>
|
|
||||||
<mat-icon>expand_more</mat-icon>
|
|
||||||
</button>
|
|
||||||
<div
|
|
||||||
[@standardList]="tagList?.length"
|
|
||||||
cdkDropList
|
|
||||||
(cdkDropListDropped)="dropOnTagList(tagList, $event)"
|
|
||||||
>
|
|
||||||
@for (tag of tagList; track tag.id) {
|
|
||||||
<side-nav-item
|
|
||||||
#menuEntry
|
|
||||||
cdkDrag
|
|
||||||
[cdkDragData]="tag"
|
|
||||||
[cdkDragStartDelay]="IS_TOUCH_PRIMARY ? DRAG_DELAY_FOR_TOUCH_LONGER : 0"
|
|
||||||
(keydown)="checkFocusTag($event)"
|
|
||||||
[workContext]="tag"
|
|
||||||
[type]="WorkContextType.TAG"
|
|
||||||
[defaultIcon]="'style'"
|
|
||||||
[activeWorkContextId]="activeWorkContextId"
|
|
||||||
></side-nav-item>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
@if (!tagList.length && isTagsExpanded) {
|
|
||||||
<div class="no-tags-info">{{ T.MH.NO_TAG_INFO|translate }}</div>
|
|
||||||
}
|
|
||||||
<!-- <button (click)="addTag()"-->
|
|
||||||
<!-- *ngIf="isTagsExpanded"-->
|
|
||||||
<!-- #menuEntry mat-menu-item>-->
|
|
||||||
<!-- <mat-icon>add</mat-icon>-->
|
|
||||||
<!-- {{T.MH.CREATE_TAG|translate}}-->
|
|
||||||
<!-- </button>-->
|
|
||||||
</section>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<!--<section class="other-task-level-section">-->
|
<!--<section class="other-task-level-section">-->
|
||||||
|
|
@ -168,7 +171,7 @@
|
||||||
routerLinkActive="isActiveRoute"
|
routerLinkActive="isActiveRoute"
|
||||||
>
|
>
|
||||||
<mat-icon svgIcon="repeat"></mat-icon>
|
<mat-icon svgIcon="repeat"></mat-icon>
|
||||||
<span class="text">{{ T.MH.REPEAT_SCHEDULED|translate }}</span>
|
<span class="text">{{ T.MH.REPEAT_SCHEDULED | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
#menuEntry
|
#menuEntry
|
||||||
|
|
@ -177,7 +180,7 @@
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
>
|
>
|
||||||
<mat-icon>help_center</mat-icon>
|
<mat-icon>help_center</mat-icon>
|
||||||
<span class="text">{{ T.MH.HELP|translate }}</span>
|
<span class="text">{{ T.MH.HELP | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<mat-menu #helpMenu="matMenu">
|
<mat-menu #helpMenu="matMenu">
|
||||||
|
|
@ -188,7 +191,7 @@
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<mat-icon>help_center</mat-icon>
|
<mat-icon>help_center</mat-icon>
|
||||||
<span class="text">{{ T.MH.HM.GET_HELP_ONLINE|translate }}</span>
|
<span class="text">{{ T.MH.HM.GET_HELP_ONLINE | translate }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
|
|
@ -198,7 +201,7 @@
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<mat-icon>bug_report</mat-icon>
|
<mat-icon>bug_report</mat-icon>
|
||||||
<span class="text">{{ T.MH.HM.REPORT_A_PROBLEM|translate }}</span>
|
<span class="text">{{ T.MH.HM.REPORT_A_PROBLEM | translate }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
|
|
@ -207,7 +210,7 @@
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<mat-icon>volunteer_activism</mat-icon>
|
<mat-icon>volunteer_activism</mat-icon>
|
||||||
<span class="text">{{ T.MH.HM.CONTRIBUTE|translate }}</span>
|
<span class="text">{{ T.MH.HM.CONTRIBUTE | translate }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
|
|
@ -216,7 +219,7 @@
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<mat-icon>forum</mat-icon>
|
<mat-icon>forum</mat-icon>
|
||||||
<span class="text">{{ T.MH.HM.REDDIT_COMMUNITY|translate }}</span>
|
<span class="text">{{ T.MH.HM.REDDIT_COMMUNITY | translate }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
@ -224,30 +227,30 @@
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
>
|
>
|
||||||
<mat-icon>directions</mat-icon>
|
<mat-icon>directions</mat-icon>
|
||||||
<span class="text">{{ T.MH.HM.START_WELCOME|translate }}</span>
|
<span class="text">{{ T.MH.HM.START_WELCOME | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
@if (IS_MOUSE_PRIMARY) {
|
@if (IS_MOUSE_PRIMARY) {
|
||||||
<button
|
<button
|
||||||
(click)="startTour(TourId.KeyboardNav)"
|
(click)="startTour(TourId.KeyboardNav)"
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
>
|
>
|
||||||
<mat-icon>directions</mat-icon>
|
<mat-icon>directions</mat-icon>
|
||||||
<span class="text">{{ T.MH.HM.KEYBOARD|translate }}</span>
|
<span class="text">{{ T.MH.HM.KEYBOARD | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
<button
|
<button
|
||||||
(click)="startTour(TourId.Sync)"
|
(click)="startTour(TourId.Sync)"
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
>
|
>
|
||||||
<mat-icon>directions</mat-icon>
|
<mat-icon>directions</mat-icon>
|
||||||
<span class="text">{{ T.MH.HM.SYNC|translate }}</span>
|
<span class="text">{{ T.MH.HM.SYNC | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
(click)="startTour(TourId.IssueProviders)"
|
(click)="startTour(TourId.IssueProviders)"
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
>
|
>
|
||||||
<mat-icon>directions</mat-icon>
|
<mat-icon>directions</mat-icon>
|
||||||
<span class="text">{{ T.MH.HM.CALENDARS|translate }}</span>
|
<span class="text">{{ T.MH.HM.CALENDARS | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
|
@ -260,7 +263,7 @@
|
||||||
routerLinkActive="isActiveRoute"
|
routerLinkActive="isActiveRoute"
|
||||||
>
|
>
|
||||||
<mat-icon>settings</mat-icon>
|
<mat-icon>settings</mat-icon>
|
||||||
<span class="text">{{ T.MH.SETTINGS|translate }}</span>
|
<span class="text">{{ T.MH.SETTINGS | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,51 +1,52 @@
|
||||||
<button
|
<button
|
||||||
[routerLink]="[base,contextId,'quick-history']"
|
[routerLink]="[base, contextId, 'quick-history']"
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
>
|
>
|
||||||
<mat-icon>history</mat-icon>
|
<mat-icon>history</mat-icon>
|
||||||
<span class="text">{{T.MH.QUICK_HISTORY|translate}}</span>
|
<span class="text">{{ T.MH.QUICK_HISTORY | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
[routerLink]="[base,contextId,'worklog']"
|
[routerLink]="[base, contextId, 'worklog']"
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
>
|
>
|
||||||
<mat-icon>date_range</mat-icon>
|
<mat-icon>date_range</mat-icon>
|
||||||
<span class="text">{{T.MH.WORKLOG|translate}}</span>
|
<span class="text">{{ T.MH.WORKLOG | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@if (isForProject || contextId ===TODAY_TAG_ID) {
|
@if (isForProject || contextId === TODAY_TAG_ID) {
|
||||||
<button
|
<button
|
||||||
[routerLink]="[base,contextId,'metrics']"
|
[routerLink]="[base, contextId, 'metrics']"
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
>
|
>
|
||||||
<mat-icon>donut_large</mat-icon>
|
<mat-icon>donut_large</mat-icon>
|
||||||
<span class="text">{{T.MH.METRICS|translate}}</span>
|
<span class="text">{{ T.MH.METRICS | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
[routerLink]="[base,contextId,'settings']"
|
[routerLink]="[base, contextId, 'settings']"
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
>
|
>
|
||||||
<mat-icon>settings</mat-icon>
|
<mat-icon>settings</mat-icon>
|
||||||
<span class="text">{{T.MH.SETTINGS|translate}}</span>
|
<span class="text">{{ T.MH.SETTINGS | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@if (!isForProject && contextId !== TODAY_TAG_ID) {
|
@if (!isForProject && contextId !== TODAY_TAG_ID) {
|
||||||
<button
|
<button
|
||||||
(click)="deleteTag()"
|
(click)="deleteTag()"
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
>
|
>
|
||||||
<mat-icon class="color-warn-i">delete_forever</mat-icon>
|
<mat-icon class="color-warn-i">delete_forever</mat-icon>
|
||||||
<span class="text">{{T.MH.DELETE_TAG|translate}}</span>
|
<span class="text">{{ T.MH.DELETE_TAG | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
} @if (isForProject) {
|
}
|
||||||
<button
|
@if (isForProject) {
|
||||||
(click)="deleteProject()"
|
<button
|
||||||
mat-menu-item
|
(click)="deleteProject()"
|
||||||
>
|
mat-menu-item
|
||||||
<mat-icon class="color-warn-i">delete_forever</mat-icon>
|
>
|
||||||
<span class="text">{{ T.MH.DELETE_PROJECT|translate }}</span>
|
<mat-icon class="color-warn-i">delete_forever</mat-icon>
|
||||||
</button>
|
<span class="text">{{ T.MH.DELETE_PROJECT | translate }}</span>
|
||||||
|
</button>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,79 +1,85 @@
|
||||||
@if ((activeBanner$|async); as banner) {
|
@if (activeBanner$ | async; as banner) {
|
||||||
<div
|
<div
|
||||||
[@banner]
|
[@banner]
|
||||||
[class.isError]="banner.type==='ERROR'"
|
[class.isError]="banner.type === 'ERROR'"
|
||||||
class="content-wrapper"
|
class="content-wrapper"
|
||||||
>
|
>
|
||||||
@if (banner.progress$ && (banner.progress$|async); as progress) { @if (progress>0) {
|
@if (banner.progress$ && (banner.progress$ | async); as progress) {
|
||||||
<mat-progress-bar
|
@if (progress > 0) {
|
||||||
mode="determinate"
|
<mat-progress-bar
|
||||||
[value]="progress"
|
mode="determinate"
|
||||||
></mat-progress-bar>
|
[value]="progress"
|
||||||
} }
|
></mat-progress-bar>
|
||||||
<div class="inner-content-wrapper">
|
}
|
||||||
@if (banner.img) {
|
|
||||||
<div class="motivational-img-wrapper">
|
|
||||||
<img [src]="banner.img" />
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
<div class="message-wrapper">
|
<div class="inner-content-wrapper">
|
||||||
@if (banner.ico) {
|
@if (banner.img) {
|
||||||
<mat-icon>{{banner.ico}}</mat-icon>
|
<div class="motivational-img-wrapper">
|
||||||
} @if (banner.svgIco) {
|
<img [src]="banner.img" />
|
||||||
<mat-icon [svgIcon]="banner.svgIco"></mat-icon>
|
</div>
|
||||||
}
|
}
|
||||||
<!-- -->
|
<div class="message-wrapper">
|
||||||
@if(banner.timer$) {
|
@if (banner.ico) {
|
||||||
<div class="message">
|
<mat-icon>{{ banner.ico }}</mat-icon>
|
||||||
<strong>{{banner.timer$|async|msToMinuteClockString}}</strong> –
|
}
|
||||||
{{banner.msg|translate:banner.translateParams}}
|
@if (banner.svgIco) {
|
||||||
|
<mat-icon [svgIcon]="banner.svgIco"></mat-icon>
|
||||||
|
}
|
||||||
|
<!-- -->
|
||||||
|
@if (banner.timer$) {
|
||||||
|
<div class="message">
|
||||||
|
<strong>{{ banner.timer$ | async | msToMinuteClockString }}</strong> –
|
||||||
|
{{ banner.msg | translate: banner.translateParams }}
|
||||||
|
</div>
|
||||||
|
} @else {
|
||||||
|
<div
|
||||||
|
[innerHTML]="banner.msg | translate: banner.translateParams"
|
||||||
|
class="message"
|
||||||
|
></div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="buttons">
|
||||||
|
@if (!banner.action2 && !banner.isHideDismissBtn) {
|
||||||
|
<button
|
||||||
|
(click)="dismiss(banner.id)"
|
||||||
|
color="primary"
|
||||||
|
mat-button
|
||||||
|
tabindex="1"
|
||||||
|
>
|
||||||
|
{{ T.G.DISMISS | translate }}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
@if (banner.action) {
|
||||||
|
<button
|
||||||
|
(click)="action(banner.id, banner.action)"
|
||||||
|
color="primary"
|
||||||
|
mat-button
|
||||||
|
tabindex="1"
|
||||||
|
>
|
||||||
|
{{ banner.action.label | translate: banner.translateParams }}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
@if (banner.action2) {
|
||||||
|
<button
|
||||||
|
(click)="action(banner.id, banner.action2)"
|
||||||
|
color="primary"
|
||||||
|
mat-button
|
||||||
|
tabindex="1"
|
||||||
|
>
|
||||||
|
{{ banner.action2.label | translate: banner.translateParams }}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
@if (banner.action3) {
|
||||||
|
<button
|
||||||
|
(click)="action(banner.id, banner.action3)"
|
||||||
|
color="primary"
|
||||||
|
mat-button
|
||||||
|
tabindex="1"
|
||||||
|
>
|
||||||
|
{{ banner.action3.label | translate: banner.translateParams }}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
} @else {
|
|
||||||
<div
|
|
||||||
[innerHTML]="banner.msg|translate:banner.translateParams"
|
|
||||||
class="message"
|
|
||||||
></div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div class="buttons">
|
|
||||||
@if (!banner.action2 && !banner.isHideDismissBtn) {
|
|
||||||
<button
|
|
||||||
(click)="dismiss(banner.id)"
|
|
||||||
color="primary"
|
|
||||||
mat-button
|
|
||||||
tabindex="1"
|
|
||||||
>
|
|
||||||
{{T.G.DISMISS|translate}}
|
|
||||||
</button>
|
|
||||||
} @if (banner.action) {
|
|
||||||
<button
|
|
||||||
(click)="action(banner.id, banner.action)"
|
|
||||||
color="primary"
|
|
||||||
mat-button
|
|
||||||
tabindex="1"
|
|
||||||
>
|
|
||||||
{{banner.action.label|translate:banner.translateParams}}
|
|
||||||
</button>
|
|
||||||
} @if (banner.action2) {
|
|
||||||
<button
|
|
||||||
(click)="action(banner.id, banner.action2)"
|
|
||||||
color="primary"
|
|
||||||
mat-button
|
|
||||||
tabindex="1"
|
|
||||||
>
|
|
||||||
{{banner.action2.label|translate:banner.translateParams}}
|
|
||||||
</button>
|
|
||||||
} @if (banner.action3) {
|
|
||||||
<button
|
|
||||||
(click)="action(banner.id, banner.action3)"
|
|
||||||
color="primary"
|
|
||||||
mat-button
|
|
||||||
tabindex="1"
|
|
||||||
>
|
|
||||||
{{banner.action3.label|translate:banner.translateParams}}
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,25 @@
|
||||||
<div
|
<div
|
||||||
(click)="!data.actionStr && close()"
|
(click)="!data.actionStr && close()"
|
||||||
[class.error]="data.type==='ERROR'"
|
[class.error]="data.type === 'ERROR'"
|
||||||
[class.success]="data.type==='SUCCESS'"
|
[class.success]="data.type === 'SUCCESS'"
|
||||||
class="wrapper"
|
class="wrapper"
|
||||||
>
|
>
|
||||||
@if (!data.ico) { @if (data.type==='SUCCESS') {
|
@if (!data.ico) {
|
||||||
<mat-icon class="snack-icon">check_circle </mat-icon>
|
@if (data.type === 'SUCCESS') {
|
||||||
} @if (data.type==='ERROR') {
|
<mat-icon class="snack-icon">check_circle </mat-icon>
|
||||||
<mat-icon class="snack-icon">error </mat-icon>
|
}
|
||||||
} } @if (data.ico) {
|
@if (data.type === 'ERROR') {
|
||||||
<mat-icon class="snack-icon">{{data.ico}}</mat-icon>
|
<mat-icon class="snack-icon">error </mat-icon>
|
||||||
} @if (data.svgIco) {
|
}
|
||||||
<mat-icon
|
}
|
||||||
[svgIcon]="data.svgIco"
|
@if (data.ico) {
|
||||||
class="snack-icon"
|
<mat-icon class="snack-icon">{{ data.ico }}</mat-icon>
|
||||||
></mat-icon>
|
}
|
||||||
|
@if (data.svgIco) {
|
||||||
|
<mat-icon
|
||||||
|
[svgIcon]="data.svgIco"
|
||||||
|
class="snack-icon"
|
||||||
|
></mat-icon>
|
||||||
}
|
}
|
||||||
|
|
||||||
<span
|
<span
|
||||||
|
|
@ -24,25 +29,26 @@
|
||||||
|
|
||||||
<div class="button-wrapper">
|
<div class="button-wrapper">
|
||||||
@if (data.actionStr) {
|
@if (data.actionStr) {
|
||||||
<button
|
<button
|
||||||
(click)="actionClick()"
|
(click)="actionClick()"
|
||||||
class="action"
|
class="action"
|
||||||
color="accent"
|
color="accent"
|
||||||
mat-button
|
mat-button
|
||||||
>
|
>
|
||||||
{{data.actionStr|translate}}
|
{{ data.actionStr | translate }}
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (!data.actionStr) {
|
@if (!data.actionStr) {
|
||||||
<button
|
<button
|
||||||
class="close-btn"
|
class="close-btn"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
>
|
>
|
||||||
<mat-icon>close</mat-icon>
|
<mat-icon>close</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
} @if (data.promise||data.showWhile$||data.isSpinner) {
|
}
|
||||||
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
@if (data.promise || data.showWhile$ || data.isSpinner) {
|
||||||
|
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,46 @@
|
||||||
@let nrOfPlannerItemsForTomorrow =
|
@let nrOfPlannerItemsForTomorrow =
|
||||||
(addTasksForTomorrowService.nrOfPlannerItemsForTomorrow$|async);
|
addTasksForTomorrowService.nrOfPlannerItemsForTomorrow$ | async;
|
||||||
<!---->
|
<!---->
|
||||||
@let plannedForToday = (addTasksForTomorrowService.allPlannedForTodayNotOnToday$|async);
|
@let plannedForToday = addTasksForTomorrowService.allPlannedForTodayNotOnToday$ | async;
|
||||||
<!---->
|
<!---->
|
||||||
|
|
||||||
@if (workContextService.isToday &&(isAlwaysShowIfAny() ||
|
@if (
|
||||||
(workContextService.activeWorkContext$|async)?.taskIds.length ===0) && plannedForToday) {
|
workContextService.isToday &&
|
||||||
<div class="wrap-add-planned">
|
(isAlwaysShowIfAny() ||
|
||||||
@if (plannedForToday?.length) {
|
(workContextService.activeWorkContext$ | async)?.taskIds.length === 0) &&
|
||||||
<button
|
plannedForToday
|
||||||
(click)="addTasksForTomorrowService.movePlannedTasksToToday(plannedForToday)"
|
) {
|
||||||
class="add-scheduled"
|
<div class="wrap-add-planned">
|
||||||
color=""
|
@if (plannedForToday?.length) {
|
||||||
mat-stroked-button
|
<button
|
||||||
tabindex="1"
|
(click)="addTasksForTomorrowService.movePlannedTasksToToday(plannedForToday)"
|
||||||
>
|
class="add-scheduled"
|
||||||
<mat-icon>playlist_add</mat-icon>
|
color=""
|
||||||
{{ T.WW.ADD_SCHEDULED_FOR_TODAY|translate:{ nr: plannedForToday.length } }}
|
mat-stroked-button
|
||||||
</button>
|
tabindex="1"
|
||||||
}
|
>
|
||||||
<!---->
|
<mat-icon>playlist_add</mat-icon>
|
||||||
@if (plannedForToday.length === 0 && nrOfPlannerItemsForTomorrow) {
|
{{ T.WW.ADD_SCHEDULED_FOR_TODAY | translate: { nr: plannedForToday.length } }}
|
||||||
<!---->
|
</button>
|
||||||
@if (nrOfPlannerItemsForTomorrow) {
|
}
|
||||||
<button
|
<!---->
|
||||||
class="add-scheduled"
|
@if (plannedForToday.length === 0 && nrOfPlannerItemsForTomorrow) {
|
||||||
(click)="addTasksForTomorrowService.addAllPlannedToDayAndCreateRepeatable()"
|
<!---->
|
||||||
color=""
|
@if (nrOfPlannerItemsForTomorrow) {
|
||||||
mat-stroked-button
|
<button
|
||||||
tabindex="1"
|
class="add-scheduled"
|
||||||
>
|
(click)="addTasksForTomorrowService.addAllPlannedToDayAndCreateRepeatable()"
|
||||||
<mat-icon>playlist_add</mat-icon>
|
color=""
|
||||||
{{ T.WW.ADD_SCHEDULED_FOR_TOMORROW|translate:{ nr: nrOfPlannerItemsForTomorrow } }}
|
mat-stroked-button
|
||||||
</button>
|
tabindex="1"
|
||||||
} }
|
>
|
||||||
</div>
|
<mat-icon>playlist_add</mat-icon>
|
||||||
|
{{
|
||||||
|
T.WW.ADD_SCHEDULED_FOR_TOMORROW
|
||||||
|
| translate: { nr: nrOfPlannerItemsForTomorrow }
|
||||||
|
}}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,125 +1,130 @@
|
||||||
@if (bookmarkService.isShowBookmarks$|async) {
|
@if (bookmarkService.isShowBookmarks$ | async) {
|
||||||
<div
|
|
||||||
#bookmarkBar
|
|
||||||
[@slide]="{value:'*',params:{elHeight:(bookmarkBarHeight)}}"
|
|
||||||
class="global-bookmark-list-outer"
|
|
||||||
>
|
|
||||||
@if (isDragOver) {
|
|
||||||
<div
|
<div
|
||||||
@fade
|
#bookmarkBar
|
||||||
class="bgc-accent drag-over-msg"
|
[@slide]="{ value: '*', params: { elHeight: bookmarkBarHeight } }"
|
||||||
|
class="global-bookmark-list-outer"
|
||||||
>
|
>
|
||||||
<mat-icon>add</mat-icon>
|
@if (isDragOver) {
|
||||||
{{T.F.BOOKMARK.BAR.DROP|translate}}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
<div class="controls-and-list-wrapper">
|
|
||||||
<div class="list-controls">
|
|
||||||
@if (!isEditMode) {
|
|
||||||
<button
|
|
||||||
(menuClosed)="isContextMenuDisabled = false"
|
|
||||||
(menuOpened)="isContextMenuDisabled = true"
|
|
||||||
[matMenuTriggerFor]="menu"
|
|
||||||
[style.pointer-events]="isContextMenuDisabled ? 'none' : 'all'"
|
|
||||||
mat-stroked-button
|
|
||||||
>
|
|
||||||
<mat-icon>more_vert</mat-icon>
|
|
||||||
</button>
|
|
||||||
} @if (isEditMode) {
|
|
||||||
<button
|
|
||||||
(click)="isEditMode=false; isContextMenuDisabled=false"
|
|
||||||
mat-stroked-button
|
|
||||||
>
|
|
||||||
<mat-icon>check</mat-icon>
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
<mat-menu #menu="matMenu">
|
|
||||||
<ng-template matMenuContent>
|
|
||||||
<button
|
|
||||||
(click)="openEditDialog()"
|
|
||||||
color=""
|
|
||||||
mat-menu-item
|
|
||||||
>
|
|
||||||
<mat-icon>add</mat-icon>
|
|
||||||
{{T.F.BOOKMARK.BAR.ADD|translate}}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
(click)="isEditMode=!isEditMode"
|
|
||||||
color=""
|
|
||||||
mat-menu-item
|
|
||||||
>
|
|
||||||
<mat-icon>edit</mat-icon>
|
|
||||||
{{T.F.BOOKMARK.BAR.EDIT|translate}}
|
|
||||||
</button>
|
|
||||||
</ng-template>
|
|
||||||
</mat-menu>
|
|
||||||
</div>
|
|
||||||
@let bookmarks = (bookmarkService.bookmarks$|async);
|
|
||||||
<div
|
|
||||||
[class.isEditMode]="isEditMode"
|
|
||||||
cdkDropList
|
|
||||||
cdkDropListOrientation="horizontal"
|
|
||||||
[cdkDropListData]="bookmarks"
|
|
||||||
(cdkDropListDropped)="drop($event)"
|
|
||||||
class="global-bookmark-list-inner"
|
|
||||||
>
|
|
||||||
@if (!bookmarks?.length) {
|
|
||||||
<div class="msg">{{T.F.BOOKMARK.BAR.NO_BOOKMARKS|translate}}</div>
|
|
||||||
} @for (bookmark of bookmarks; track trackByFn($index, bookmark)) {
|
|
||||||
<div
|
<div
|
||||||
class="global-bookmark"
|
@fade
|
||||||
cdkDrag
|
class="bgc-accent drag-over-msg"
|
||||||
draggable="false"
|
|
||||||
>
|
>
|
||||||
<a
|
<mat-icon>add</mat-icon>
|
||||||
[enlargeImg]="bookmark.type==='IMG'&& bookmark.path"
|
{{ T.F.BOOKMARK.BAR.DROP | translate }}
|
||||||
[href]="bookmark.path"
|
</div>
|
||||||
[style.background-image]="bookmark.type==='IMG'&& 'url('+bookmark.path+')'"
|
}
|
||||||
[title]="bookmark.path"
|
<div class="controls-and-list-wrapper">
|
||||||
aria-label="open global bookmark"
|
<div class="list-controls">
|
||||||
bookmarkLink
|
@if (!isEditMode) {
|
||||||
color=""
|
<button
|
||||||
draggable="false"
|
(menuClosed)="isContextMenuDisabled = false"
|
||||||
mat-stroked-button
|
(menuOpened)="isContextMenuDisabled = true"
|
||||||
target="_blank"
|
[matMenuTriggerFor]="menu"
|
||||||
type="{{bookmark.type}}"
|
[style.pointer-events]="isContextMenuDisabled ? 'none' : 'all'"
|
||||||
>
|
mat-stroked-button
|
||||||
@if (bookmark.icon) {
|
>
|
||||||
<mat-icon>{{bookmark.icon}} </mat-icon>
|
<mat-icon>more_vert</mat-icon>
|
||||||
} {{bookmark.title}}
|
</button>
|
||||||
</a>
|
}
|
||||||
@if (isEditMode) {
|
@if (isEditMode) {
|
||||||
<div class="controls">
|
|
||||||
@if (isEditMode) {
|
|
||||||
<mat-icon
|
|
||||||
@fade
|
|
||||||
class="drag-handle bgc-400"
|
|
||||||
svgIcon="drag_handle"
|
|
||||||
></mat-icon>
|
|
||||||
}
|
|
||||||
<button
|
<button
|
||||||
(click)="openEditDialog(bookmark)"
|
(click)="isEditMode = false; isContextMenuDisabled = false"
|
||||||
aria-label="open edit dialog"
|
mat-stroked-button
|
||||||
class="edit-btn"
|
|
||||||
color="primary"
|
|
||||||
mat-raised-button
|
|
||||||
>
|
>
|
||||||
<mat-icon>edit</mat-icon>
|
<mat-icon>check</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button
|
}
|
||||||
(click)="remove(bookmark.id)"
|
<mat-menu #menu="matMenu">
|
||||||
aria-label="remove bookmark"
|
<ng-template matMenuContent>
|
||||||
class="trash-btn"
|
<button
|
||||||
color="warn"
|
(click)="openEditDialog()"
|
||||||
mat-raised-button
|
color=""
|
||||||
|
mat-menu-item
|
||||||
|
>
|
||||||
|
<mat-icon>add</mat-icon>
|
||||||
|
{{ T.F.BOOKMARK.BAR.ADD | translate }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
(click)="isEditMode = !isEditMode"
|
||||||
|
color=""
|
||||||
|
mat-menu-item
|
||||||
|
>
|
||||||
|
<mat-icon>edit</mat-icon>
|
||||||
|
{{ T.F.BOOKMARK.BAR.EDIT | translate }}
|
||||||
|
</button>
|
||||||
|
</ng-template>
|
||||||
|
</mat-menu>
|
||||||
|
</div>
|
||||||
|
@let bookmarks = bookmarkService.bookmarks$ | async;
|
||||||
|
<div
|
||||||
|
[class.isEditMode]="isEditMode"
|
||||||
|
cdkDropList
|
||||||
|
cdkDropListOrientation="horizontal"
|
||||||
|
[cdkDropListData]="bookmarks"
|
||||||
|
(cdkDropListDropped)="drop($event)"
|
||||||
|
class="global-bookmark-list-inner"
|
||||||
|
>
|
||||||
|
@if (!bookmarks?.length) {
|
||||||
|
<div class="msg">{{ T.F.BOOKMARK.BAR.NO_BOOKMARKS | translate }}</div>
|
||||||
|
}
|
||||||
|
@for (bookmark of bookmarks; track trackByFn($index, bookmark)) {
|
||||||
|
<div
|
||||||
|
class="global-bookmark"
|
||||||
|
cdkDrag
|
||||||
|
draggable="false"
|
||||||
>
|
>
|
||||||
<mat-icon>delete_forever</mat-icon>
|
<a
|
||||||
</button>
|
[enlargeImg]="bookmark.type === 'IMG' && bookmark.path"
|
||||||
</div>
|
[href]="bookmark.path"
|
||||||
|
[style.background-image]="
|
||||||
|
bookmark.type === 'IMG' && 'url(' + bookmark.path + ')'
|
||||||
|
"
|
||||||
|
[title]="bookmark.path"
|
||||||
|
aria-label="open global bookmark"
|
||||||
|
bookmarkLink
|
||||||
|
color=""
|
||||||
|
draggable="false"
|
||||||
|
mat-stroked-button
|
||||||
|
target="_blank"
|
||||||
|
type="{{ bookmark.type }}"
|
||||||
|
>
|
||||||
|
@if (bookmark.icon) {
|
||||||
|
<mat-icon>{{ bookmark.icon }} </mat-icon>
|
||||||
|
}
|
||||||
|
{{ bookmark.title }}
|
||||||
|
</a>
|
||||||
|
@if (isEditMode) {
|
||||||
|
<div class="controls">
|
||||||
|
@if (isEditMode) {
|
||||||
|
<mat-icon
|
||||||
|
@fade
|
||||||
|
class="drag-handle bgc-400"
|
||||||
|
svgIcon="drag_handle"
|
||||||
|
></mat-icon>
|
||||||
|
}
|
||||||
|
<button
|
||||||
|
(click)="openEditDialog(bookmark)"
|
||||||
|
aria-label="open edit dialog"
|
||||||
|
class="edit-btn"
|
||||||
|
color="primary"
|
||||||
|
mat-raised-button
|
||||||
|
>
|
||||||
|
<mat-icon>edit</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
(click)="remove(bookmark.id)"
|
||||||
|
aria-label="remove bookmark"
|
||||||
|
class="trash-btn"
|
||||||
|
color="warn"
|
||||||
|
mat-raised-button
|
||||||
|
>
|
||||||
|
<mat-icon>delete_forever</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,90 +1,94 @@
|
||||||
@if (bookmarkCopy) {
|
@if (bookmarkCopy) {
|
||||||
<form
|
<form
|
||||||
#form="ngForm"
|
#form="ngForm"
|
||||||
(submit)="$event.preventDefault();submit()"
|
(submit)="$event.preventDefault(); submit()"
|
||||||
>
|
>
|
||||||
<h1 mat-dialog-title>
|
<h1 mat-dialog-title>
|
||||||
{{ (bookmarkCopy.id ? (T.F.BOOKMARK.DIALOG_EDIT.EDIT_BOOKMARK) :
|
{{
|
||||||
(T.F.BOOKMARK.DIALOG_EDIT.ADD_BOOKMARK)) |translate }}
|
(bookmarkCopy.id
|
||||||
</h1>
|
? T.F.BOOKMARK.DIALOG_EDIT.EDIT_BOOKMARK
|
||||||
<mat-dialog-content>
|
: T.F.BOOKMARK.DIALOG_EDIT.ADD_BOOKMARK
|
||||||
<div class="form-wrapper">
|
) | translate
|
||||||
<mat-form-field>
|
}}
|
||||||
<mat-label>{{(T.G.TITLE|translate)}}</mat-label>
|
</h1>
|
||||||
<input
|
<mat-dialog-content>
|
||||||
[(ngModel)]="bookmarkCopy.title"
|
<div class="form-wrapper">
|
||||||
autofocus="autofocus"
|
|
||||||
matInput
|
|
||||||
name="title"
|
|
||||||
type="text"
|
|
||||||
/>
|
|
||||||
</mat-form-field>
|
|
||||||
<mat-form-field>
|
|
||||||
<mat-label>{{mapTypeToLabel(bookmarkCopy.type)|translate}}</mat-label>
|
|
||||||
<input
|
|
||||||
[(ngModel)]="bookmarkCopy.path"
|
|
||||||
matInput
|
|
||||||
name="path"
|
|
||||||
required
|
|
||||||
type="text"
|
|
||||||
/>
|
|
||||||
</mat-form-field>
|
|
||||||
<mat-form-field>
|
|
||||||
<mat-label>{{(T.F.BOOKMARK.DIALOG_EDIT.SELECT_TYPE|translate)}}</mat-label>
|
|
||||||
<mat-select
|
|
||||||
[(ngModel)]="bookmarkCopy.type"
|
|
||||||
name="type"
|
|
||||||
required="true"
|
|
||||||
>
|
|
||||||
@for (type of types; track trackByIndex($index, type)) {
|
|
||||||
<mat-option [value]="type.type">{{ (type.title|translate) }} </mat-option>
|
|
||||||
}
|
|
||||||
</mat-select>
|
|
||||||
</mat-form-field>
|
|
||||||
<div class="custom-icon-wrapper">
|
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{(T.F.BOOKMARK.DIALOG_EDIT.SELECT_ICON|translate)}}</mat-label>
|
<mat-label>{{ T.G.TITLE | translate }}</mat-label>
|
||||||
<input
|
<input
|
||||||
[(ngModel)]="bookmarkCopy.icon"
|
[(ngModel)]="bookmarkCopy.title"
|
||||||
[formControl]="iconControl"
|
autofocus="autofocus"
|
||||||
[matAutocomplete]="auto"
|
|
||||||
matInput
|
matInput
|
||||||
|
name="title"
|
||||||
type="text"
|
type="text"
|
||||||
/>
|
/>
|
||||||
<mat-icon matPrefix="">{{bookmarkCopy.icon}}</mat-icon>
|
|
||||||
<mat-autocomplete
|
|
||||||
#auto="matAutocomplete"
|
|
||||||
[autoActiveFirstOption]="true"
|
|
||||||
>
|
|
||||||
@for (icon of (filteredIcons$|async); track trackByIndex($index, icon)) {
|
|
||||||
<mat-option [value]="icon">
|
|
||||||
<mat-icon>{{icon}}</mat-icon>
|
|
||||||
<span>{{icon}}</span>
|
|
||||||
</mat-option>
|
|
||||||
}
|
|
||||||
</mat-autocomplete>
|
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>{{ mapTypeToLabel(bookmarkCopy.type) | translate }}</mat-label>
|
||||||
|
<input
|
||||||
|
[(ngModel)]="bookmarkCopy.path"
|
||||||
|
matInput
|
||||||
|
name="path"
|
||||||
|
required
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>{{ T.F.BOOKMARK.DIALOG_EDIT.SELECT_TYPE | translate }}</mat-label>
|
||||||
|
<mat-select
|
||||||
|
[(ngModel)]="bookmarkCopy.type"
|
||||||
|
name="type"
|
||||||
|
required="true"
|
||||||
|
>
|
||||||
|
@for (type of types; track trackByIndex($index, type)) {
|
||||||
|
<mat-option [value]="type.type">{{ type.title | translate }} </mat-option>
|
||||||
|
}
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
<div class="custom-icon-wrapper">
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>{{ T.F.BOOKMARK.DIALOG_EDIT.SELECT_ICON | translate }}</mat-label>
|
||||||
|
<input
|
||||||
|
[(ngModel)]="bookmarkCopy.icon"
|
||||||
|
[formControl]="iconControl"
|
||||||
|
[matAutocomplete]="auto"
|
||||||
|
matInput
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
<mat-icon matPrefix="">{{ bookmarkCopy.icon }}</mat-icon>
|
||||||
|
<mat-autocomplete
|
||||||
|
#auto="matAutocomplete"
|
||||||
|
[autoActiveFirstOption]="true"
|
||||||
|
>
|
||||||
|
@for (icon of filteredIcons$ | async; track trackByIndex($index, icon)) {
|
||||||
|
<mat-option [value]="icon">
|
||||||
|
<mat-icon>{{ icon }}</mat-icon>
|
||||||
|
<span>{{ icon }}</span>
|
||||||
|
</mat-option>
|
||||||
|
}
|
||||||
|
</mat-autocomplete>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</mat-dialog-content>
|
||||||
</mat-dialog-content>
|
<mat-dialog-actions align="end">
|
||||||
<mat-dialog-actions align="end">
|
<button
|
||||||
<button
|
(click)="close()"
|
||||||
(click)="close()"
|
color="primary"
|
||||||
color="primary"
|
mat-button
|
||||||
mat-button
|
type="button"
|
||||||
type="button"
|
>
|
||||||
>
|
{{ T.G.CANCEL | translate }}
|
||||||
{{T.G.CANCEL|translate}}
|
</button>
|
||||||
</button>
|
<button
|
||||||
<button
|
[disabled]="!form.valid"
|
||||||
[disabled]="!form.valid"
|
color="primary"
|
||||||
color="primary"
|
mat-stroked-button
|
||||||
mat-stroked-button
|
type="submit"
|
||||||
type="submit"
|
>
|
||||||
>
|
<mat-icon>save</mat-icon>
|
||||||
<mat-icon>save</mat-icon>
|
{{ T.G.SAVE | translate }}
|
||||||
{{T.G.SAVE|translate}}
|
</button>
|
||||||
</button>
|
</mat-dialog-actions>
|
||||||
</mat-dialog-actions>
|
</form>
|
||||||
</form>
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,44 @@
|
||||||
<collapsible
|
<collapsible
|
||||||
[isExpanded]="isExpanded"
|
[isExpanded]="isExpanded"
|
||||||
[isIconBefore]="true"
|
[isIconBefore]="true"
|
||||||
[title]="(section?.title|translate)"
|
[title]="section?.title | translate"
|
||||||
>
|
>
|
||||||
<!--[icon]="section?.icon"-->
|
<!--[icon]="section?.icon"-->
|
||||||
|
|
||||||
@if (section?.help||section?.helpArr) {
|
@if (section?.help || section?.helpArr) {
|
||||||
<help-section>
|
<help-section>
|
||||||
@if (section?.help) {
|
@if (section?.help) {
|
||||||
<div [innerHtml]="section?.help|translate"></div>
|
<div [innerHtml]="section?.help | translate"></div>
|
||||||
} @if (section?.helpArr) { @for (helpSection of section?.helpArr; track
|
}
|
||||||
trackByIndex($index, helpSection)) { @if (helpSection.h) {
|
@if (section?.helpArr) {
|
||||||
<div class="mat-caption">{{helpSection.h|translate}}</div>
|
@for (helpSection of section?.helpArr; track trackByIndex($index, helpSection)) {
|
||||||
} @if (helpSection.p) {
|
@if (helpSection.h) {
|
||||||
<p [innerHTML]="helpSection.p|translate"></p>
|
<div class="mat-caption">{{ helpSection.h | translate }}</div>
|
||||||
} @if (helpSection.p2) {
|
}
|
||||||
<p [innerHTML]="helpSection.p2|translate"></p>
|
@if (helpSection.p) {
|
||||||
} @if (helpSection.p3) {
|
<p [innerHTML]="helpSection.p | translate"></p>
|
||||||
<p [innerHTML]="helpSection.p3|translate"></p>
|
}
|
||||||
} @if (helpSection.p4) {
|
@if (helpSection.p2) {
|
||||||
<p [innerHTML]="helpSection.p4|translate"></p>
|
<p [innerHTML]="helpSection.p2 | translate"></p>
|
||||||
} } }
|
}
|
||||||
</help-section>
|
@if (helpSection.p3) {
|
||||||
|
<p [innerHTML]="helpSection.p3 | translate"></p>
|
||||||
|
}
|
||||||
|
@if (helpSection.p4) {
|
||||||
|
<p [innerHTML]="helpSection.p4 | translate"></p>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</help-section>
|
||||||
}
|
}
|
||||||
<div class="form-wrapper {{section?.key}}">
|
<div class="form-wrapper {{ section?.key }}">
|
||||||
@if (section?.items && !section?.customSection) {
|
@if (section?.items && !section?.customSection) {
|
||||||
<config-form
|
<config-form
|
||||||
(save)="onSave($event)"
|
(save)="onSave($event)"
|
||||||
[cfg]="cfg"
|
[cfg]="cfg"
|
||||||
[formCfg]="section?.items"
|
[formCfg]="section?.items"
|
||||||
[sectionKey]="section?.key"
|
[sectionKey]="section?.key"
|
||||||
></config-form>
|
></config-form>
|
||||||
}
|
}
|
||||||
|
|
||||||
<ng-template
|
<ng-template
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
class="width100"
|
class="width100"
|
||||||
[hideRequiredMarker]="true"
|
[hideRequiredMarker]="true"
|
||||||
>
|
>
|
||||||
<mat-label>{{ 'GCF.SOUND.VOLUME' | translate}}</mat-label>
|
<mat-label>{{ 'GCF.SOUND.VOLUME' | translate }}</mat-label>
|
||||||
<mat-slider
|
<mat-slider
|
||||||
class="width100"
|
class="width100"
|
||||||
[min]="0"
|
[min]="0"
|
||||||
|
|
@ -26,10 +26,10 @@
|
||||||
</mat-slider>
|
</mat-slider>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="width100">
|
<mat-form-field class="width100">
|
||||||
<mat-label>{{ 'GCF.SOUND.DONE_SOUND' | translate}}</mat-label>
|
<mat-label>{{ 'GCF.SOUND.DONE_SOUND' | translate }}</mat-label>
|
||||||
<mat-select formControlName="doneSound">
|
<mat-select formControlName="doneSound">
|
||||||
@for (sound of soundOpts; track sound) {
|
@for (sound of soundOpts; track sound) {
|
||||||
<mat-option [value]="sound.value">{{sound.label}}</mat-option>
|
<mat-option [value]="sound.value">{{ sound.label }}</mat-option>
|
||||||
}
|
}
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
@ -42,14 +42,14 @@
|
||||||
matInput
|
matInput
|
||||||
[checked]="this.config?.isIncreaseDoneSoundPitch"
|
[checked]="this.config?.isIncreaseDoneSoundPitch"
|
||||||
formControlName="isIncreaseDoneSoundPitch"
|
formControlName="isIncreaseDoneSoundPitch"
|
||||||
>{{'GCF.SOUND.IS_INCREASE_DONE_PITCH' | translate}}</mat-slide-toggle
|
>{{ 'GCF.SOUND.IS_INCREASE_DONE_PITCH' | translate }}</mat-slide-toggle
|
||||||
>
|
>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="width100">
|
<mat-form-field class="width100">
|
||||||
<mat-label>{{'GCF.SOUND.BREAK_REMINDER_SOUND' | translate }}</mat-label>
|
<mat-label>{{ 'GCF.SOUND.BREAK_REMINDER_SOUND' | translate }}</mat-label>
|
||||||
<mat-select formControlName="breakReminderSound">
|
<mat-select formControlName="breakReminderSound">
|
||||||
@for (sound of soundOpts; track sound) {
|
@for (sound of soundOpts; track sound) {
|
||||||
<mat-option [value]="sound.value">{{sound.label}}</mat-option>
|
<mat-option [value]="sound.value">{{ sound.label }}</mat-option>
|
||||||
}
|
}
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import { GlobalConfigState } from './global-config.model';
|
import { GlobalConfigState } from './global-config.model';
|
||||||
import { DEFAULT_PROJECT_ID } from '../project/project.const';
|
import { DEFAULT_PROJECT_ID } from '../project/project.const';
|
||||||
import { TRACKING_INTERVAL } from 'src/app/app.constants';
|
import { TRACKING_INTERVAL } from 'src/app/app.constants';
|
||||||
import {getDefaultVoice} from 'src/app/features/domina-mode/getAvailableVoices'
|
import { getDefaultVoice } from 'src/app/features/domina-mode/getAvailableVoices';
|
||||||
const minute = 60 * 1000;
|
const minute = 60 * 1000;
|
||||||
const defaultVoice = getDefaultVoice();
|
const defaultVoice = getDefaultVoice();
|
||||||
console.log("Setting default voice as"+ defaultVoice);
|
console.log('Setting default voice as' + defaultVoice);
|
||||||
|
|
||||||
export const DEFAULT_DAY_START = '9:00';
|
export const DEFAULT_DAY_START = '9:00';
|
||||||
export const DEFAULT_GLOBAL_CONFIG: GlobalConfigState = {
|
export const DEFAULT_GLOBAL_CONFIG: GlobalConfigState = {
|
||||||
|
|
@ -63,8 +63,7 @@ export const DEFAULT_GLOBAL_CONFIG: GlobalConfigState = {
|
||||||
interval: 5 * minute,
|
interval: 5 * minute,
|
||||||
volume: 75,
|
volume: 75,
|
||||||
text: 'Your current task is: ${currentTaskTitle}',
|
text: 'Your current task is: ${currentTaskTitle}',
|
||||||
voice:defaultVoice ,
|
voice: defaultVoice,
|
||||||
|
|
||||||
},
|
},
|
||||||
focusMode: {
|
focusMode: {
|
||||||
isAlwaysUseFocusMode: false,
|
isAlwaysUseFocusMode: false,
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,7 @@
|
||||||
import { ConfigFormSection, DominaModeConfig } from '../global-config.model';
|
import { ConfigFormSection, DominaModeConfig } from '../global-config.model';
|
||||||
import { T } from '../../../t.const';
|
import { T } from '../../../t.const';
|
||||||
import { speak } from '../../../util/speak';
|
import { speak } from '../../../util/speak';
|
||||||
import {getAvailableVoices} from '../../domina-mode/getAvailableVoices'
|
import { getAvailableVoices } from '../../domina-mode/getAvailableVoices';
|
||||||
|
|
||||||
|
|
||||||
export const DOMINA_MODE_FORM: ConfigFormSection<DominaModeConfig> = {
|
export const DOMINA_MODE_FORM: ConfigFormSection<DominaModeConfig> = {
|
||||||
title: T.F.DOMINA_MODE.FORM.TITLE,
|
title: T.F.DOMINA_MODE.FORM.TITLE,
|
||||||
|
|
@ -53,17 +52,17 @@ export const DOMINA_MODE_FORM: ConfigFormSection<DominaModeConfig> = {
|
||||||
if (txt.length <= 1) {
|
if (txt.length <= 1) {
|
||||||
txt = 'No text configured for domina mode';
|
txt = 'No text configured for domina mode';
|
||||||
}
|
}
|
||||||
speak(txt, model.volume,model.voice);
|
speak(txt, model.volume, model.voice);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key:'voice',
|
key: 'voice',
|
||||||
type:'select',
|
type: 'select',
|
||||||
templateOptions:{
|
templateOptions: {
|
||||||
label:"Select a Voice",
|
label: 'Select a Voice',
|
||||||
description:"Choose a voice",
|
description: 'Choose a voice',
|
||||||
required:false,
|
required: false,
|
||||||
},
|
},
|
||||||
hooks: {
|
hooks: {
|
||||||
onInit: (field) => {
|
onInit: (field) => {
|
||||||
|
|
@ -71,17 +70,14 @@ export const DOMINA_MODE_FORM: ConfigFormSection<DominaModeConfig> = {
|
||||||
voices = getAvailableVoices();
|
voices = getAvailableVoices();
|
||||||
//console.log(voices);
|
//console.log(voices);
|
||||||
|
|
||||||
if(field.templateOptions){
|
if (field.templateOptions) {
|
||||||
field.templateOptions.options = voices.map(voiceName=>({
|
field.templateOptions.options = voices.map((voiceName) => ({
|
||||||
label:voiceName.name,
|
label: voiceName.name,
|
||||||
value: voiceName.voiceURI,
|
value: voiceName.voiceURI,
|
||||||
|
}));
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,6 @@ export type DominaModeConfig = Readonly<{
|
||||||
interval: number;
|
interval: number;
|
||||||
volume: number;
|
volume: number;
|
||||||
voice: string;
|
voice: string;
|
||||||
|
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export type FocusModeConfig = Readonly<{
|
export type FocusModeConfig = Readonly<{
|
||||||
|
|
|
||||||
|
|
@ -18,20 +18,20 @@
|
||||||
(optionSelected)="onIconSelect($event.option.value)"
|
(optionSelected)="onIconSelect($event.option.value)"
|
||||||
[autoActiveFirstOption]="false"
|
[autoActiveFirstOption]="false"
|
||||||
>
|
>
|
||||||
@for (icon of (filteredIcons); track trackByIndex($index, icon)) {
|
@for (icon of filteredIcons; track trackByIndex($index, icon)) {
|
||||||
<mat-option [value]="icon">
|
<mat-option [value]="icon">
|
||||||
<mat-icon>{{icon}}</mat-icon>
|
<mat-icon>{{ icon }}</mat-icon>
|
||||||
<span>{{icon}}</span>
|
<span>{{ icon }}</span>
|
||||||
</mat-option>
|
</mat-option>
|
||||||
}
|
}
|
||||||
</mat-autocomplete>
|
</mat-autocomplete>
|
||||||
|
|
||||||
@if(IS_ELECTRON && !isLinux){
|
@if (IS_ELECTRON && !isLinux) {
|
||||||
<mat-icon
|
<mat-icon
|
||||||
matSuffix
|
matSuffix
|
||||||
type="button"
|
type="button"
|
||||||
[matTooltip]="'Open system emoji picker if any'"
|
[matTooltip]="'Open system emoji picker if any'"
|
||||||
(click)="openEmojiPicker()"
|
(click)="openEmojiPicker()"
|
||||||
>add_reaction</mat-icon
|
>add_reaction</mat-icon
|
||||||
>
|
>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,21 +3,21 @@
|
||||||
class="list-wrapper"
|
class="list-wrapper"
|
||||||
>
|
>
|
||||||
@for (innerField of field.fieldGroup; track trackByFn(i, innerField); let i = $index) {
|
@for (innerField of field.fieldGroup; track trackByFn(i, innerField); let i = $index) {
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<formly-field
|
<formly-field
|
||||||
[field]="innerField"
|
[field]="innerField"
|
||||||
class="field"
|
class="field"
|
||||||
></formly-field>
|
></formly-field>
|
||||||
<button
|
<button
|
||||||
(click)="removeItem(i)"
|
(click)="removeItem(i)"
|
||||||
color="warn"
|
color="warn"
|
||||||
mat-mini-fab
|
mat-mini-fab
|
||||||
type="button"
|
type="button"
|
||||||
class="remove-btn"
|
class="remove-btn"
|
||||||
>
|
>
|
||||||
<mat-icon>delete_forever</mat-icon>
|
<mat-icon>delete_forever</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -28,6 +28,6 @@
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<mat-icon>add</mat-icon>
|
<mat-icon>add</mat-icon>
|
||||||
{{ to.addText | translate}}
|
{{ to.addText | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@
|
||||||
[readonly]="to.readonly"
|
[readonly]="to.readonly"
|
||||||
matNativeControl
|
matNativeControl
|
||||||
>
|
>
|
||||||
<option [ngValue]="false">{{T.G.NONE | translate}}</option>
|
<option [ngValue]="false">{{ T.G.NONE | translate }}</option>
|
||||||
@for (opt of projectService.list$|async; track trackById($index, opt)) {
|
@for (opt of projectService.list$ | async; track trackById($index, opt)) {
|
||||||
<option [ngValue]="opt.id">{{ opt.title }}</option>
|
<option [ngValue]="opt.id">{{ opt.title }}</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,14 @@
|
||||||
|
|
||||||
export const getAvailableVoices = (): SpeechSynthesisVoice[] => {
|
export const getAvailableVoices = (): SpeechSynthesisVoice[] => {
|
||||||
const synth = window.speechSynthesis;
|
const synth = window.speechSynthesis;
|
||||||
return synth.getVoices()
|
return synth.getVoices();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export const getDefaultVoice = (): string => {
|
export const getDefaultVoice = (): string => {
|
||||||
const voices = window.speechSynthesis.getVoices();
|
const voices = window.speechSynthesis.getVoices();
|
||||||
if (voices.length === 0) {
|
if (voices.length === 0) {
|
||||||
return "null";
|
return 'null';
|
||||||
}
|
}
|
||||||
//"null" should theoretically use the default voice
|
//"null" should theoretically use the default voice
|
||||||
const defaultVoice = voices.find(voice => voice.default);
|
const defaultVoice = voices.find((voice) => voice.default);
|
||||||
return defaultVoice ? defaultVoice.voiceURI : voices[0].voiceURI;
|
return defaultVoice ? defaultVoice.voiceURI : voices[0].voiceURI;
|
||||||
}
|
};
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ export class DominaModeEffects {
|
||||||
if (txt.length <= 1) {
|
if (txt.length <= 1) {
|
||||||
txt = currentTask.title;
|
txt = currentTask.title;
|
||||||
}
|
}
|
||||||
speak(txt, cfg.volume,cfg.voice);
|
speak(txt, cfg.volume, cfg.voice);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,34 @@
|
||||||
<form
|
<form
|
||||||
(submit)="$event.preventDefault();onSubmit($event)"
|
(submit)="$event.preventDefault(); onSubmit($event)"
|
||||||
novalidate
|
novalidate
|
||||||
>
|
>
|
||||||
@if(selectedMode() !== FocusModeMode.Flowtime) {
|
@if (selectedMode() !== FocusModeMode.Flowtime) {
|
||||||
<h1>{{T.F.FOCUS_MODE.SET_FOCUS_SESSION_DURATION|translate}}</h1>
|
<h1>{{ T.F.FOCUS_MODE.SET_FOCUS_SESSION_DURATION | translate }}</h1>
|
||||||
} @if (task$|async; as task) {
|
}
|
||||||
<div class="for-task">
|
@if (task$ | async; as task) {
|
||||||
<div class="label">for task</div>
|
<div class="for-task">
|
||||||
<div>"<em>{{task?.title}}</em>"</div>
|
<div class="label">for task</div>
|
||||||
</div>
|
<div>
|
||||||
<div style="text-align: center; margin-bottom: 8px">
|
"<em>{{ task?.title }}</em
|
||||||
<button
|
>"
|
||||||
mat-stroked-button
|
</div>
|
||||||
type="button"
|
</div>
|
||||||
(click)="selectDifferentTask()"
|
<div style="text-align: center; margin-bottom: 8px">
|
||||||
>
|
<button
|
||||||
<!-- <mat-icon>arrow_back_ios</mat-icon>-->
|
mat-stroked-button
|
||||||
{{T.F.FOCUS_MODE.SELECT_ANOTHER_TASK|translate}}
|
type="button"
|
||||||
</button>
|
(click)="selectDifferentTask()"
|
||||||
</div>
|
>
|
||||||
} @if(selectedMode() !== FocusModeMode.Flowtime) {
|
<!-- <mat-icon>arrow_back_ios</mat-icon>-->
|
||||||
|
{{ T.F.FOCUS_MODE.SELECT_ANOTHER_TASK | translate }}
|
||||||
<input-duration-slider
|
</button>
|
||||||
[model]="sessionDuration$|async"
|
</div>
|
||||||
(modelChange)="onFocusModeDurationChanged($event)"
|
}
|
||||||
></input-duration-slider>
|
@if (selectedMode() !== FocusModeMode.Flowtime) {
|
||||||
|
<input-duration-slider
|
||||||
|
[model]="sessionDuration$ | async"
|
||||||
|
(modelChange)="onFocusModeDurationChanged($event)"
|
||||||
|
></input-duration-slider>
|
||||||
}
|
}
|
||||||
<button
|
<button
|
||||||
style="margin-top: 16px"
|
style="margin-top: 16px"
|
||||||
|
|
@ -32,6 +36,6 @@
|
||||||
color="primary"
|
color="primary"
|
||||||
mat-raised-button
|
mat-raised-button
|
||||||
>
|
>
|
||||||
{{T.F.FOCUS_MODE.START_FOCUS_SESSION|translate}}
|
{{ T.F.FOCUS_MODE.START_FOCUS_SESSION | translate }}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -1,128 +1,137 @@
|
||||||
@let isCountTimeDown = isCountTimeDown$|async;
|
<!--@let isCountTimeDown = isCountTimeDown$|async;-->
|
||||||
<!-- -->
|
<!--<!– –>-->
|
||||||
@if (taskService.currentTask$|async; as task) {
|
<!--@if (taskService.currentTask$|async; as task) {-->
|
||||||
<task-title
|
<!-- <task-title-->
|
||||||
(valueEdited)="updateTaskTitleIfChanged($event.wasChanged, $event.newVal)"
|
<!-- (valueEdited)="updateTaskTitleIfChanged($event.wasChanged, $event.newVal)"-->
|
||||||
[value]="task.title"
|
<!-- [value]="task.title"-->
|
||||||
class="task-title"
|
<!-- class="task-title"-->
|
||||||
></task-title>
|
<!-- ></task-title>-->
|
||||||
<div class="progress-wrapper">
|
<!-- <div class="progress-wrapper">-->
|
||||||
@if (isCountTimeDown) {
|
<!-- @if (isCountTimeDown) {-->
|
||||||
<progress-circle [progress]="sessionProgress$|async"></progress-circle>
|
<!-- <progress-circle [progress]="sessionProgress$|async"></progress-circle>-->
|
||||||
} @else {
|
<!-- } @else {-->
|
||||||
<progress-circle [autoRotationDuration]="60000"></progress-circle>
|
<!-- <progress-circle [autoRotationDuration]="60000"></progress-circle>-->
|
||||||
}
|
<!-- }-->
|
||||||
<div class="progress-label-wrapper">
|
<!-- <div class="progress-label-wrapper">-->
|
||||||
<div
|
<!-- <div-->
|
||||||
class="focus-time"
|
<!-- class="focus-time"-->
|
||||||
title="Focus time"
|
<!-- title="Focus time"-->
|
||||||
>
|
<!-- >-->
|
||||||
<!-- {{focusModeTimeToGo / 60000}}min-->
|
<!-- <!– {{focusModeTimeToGo / 60000}}min–>-->
|
||||||
@if(isCountTimeDown) { {{ (timeToGo$|async|msToMinuteClockString) }} } @else { {{
|
<!-- @if (isCountTimeDown) {-->
|
||||||
(timeElapsed$|async|msToMinuteClockString) }} }
|
<!-- {{ (timeToGo$|async|msToMinuteClockString) }}-->
|
||||||
</div>
|
<!-- } @else {-->
|
||||||
<!-- <div class="task-times">-->
|
<!-- {{ (timeElapsed$|async|msToMinuteClockString) }}-->
|
||||||
<!-- {{task.timeSpent|msToString}}/{{task.timeEstimate|msToString}}-->
|
<!-- }-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
</div>
|
<!-- <!– <div class="task-times">–>-->
|
||||||
</div>
|
<!-- <!– {{task.timeSpent|msToString}}/{{task.timeEstimate|msToString}}–>-->
|
||||||
@if ((simpleCounterService.enabledSimpleCounters$|async); as enabledSimpleCounters) { @if
|
<!-- <!– </div>–>-->
|
||||||
(enabledSimpleCounters.length) {
|
<!-- </div>-->
|
||||||
<section class="simple-counter-buttons">
|
<!-- </div>-->
|
||||||
@for (simpleCounter of enabledSimpleCounters; track trackById($index, simpleCounter)) {
|
<!-- @if ((simpleCounterService.enabledSimpleCounters$|async); as enabledSimpleCounters) {-->
|
||||||
<simple-counter-button
|
<!-- @if () {-->
|
||||||
[class.isHiddenWithoutFocus]="!simpleCounter.isOn"
|
<!-- } (enabledSimpleCounters.length) {-->
|
||||||
[simpleCounter]="simpleCounter"
|
<!-- <section class="simple-counter-buttons">-->
|
||||||
></simple-counter-button>
|
<!-- @for (simpleCounter of enabledSimpleCounters; track trackById($index, simpleCounter))-->
|
||||||
}
|
<!-- {-->
|
||||||
</section>
|
<!-- <simple-counter-button-->
|
||||||
} }
|
<!-- [class.isHiddenWithoutFocus]="!simpleCounter.isOn"-->
|
||||||
<section class="controls">
|
<!-- [simpleCounter]="simpleCounter"-->
|
||||||
<button
|
<!-- ></simple-counter-button>-->
|
||||||
mat-icon-button
|
<!-- }-->
|
||||||
[matTooltip]="T.F.FOCUS_MODE.FINISH_TASK_AND_SELECT_NEXT|translate"
|
<!-- </section>-->
|
||||||
(click)="finishCurrentTask();"
|
<!-- }-->
|
||||||
>
|
<!-- }-->
|
||||||
<mat-icon>done</mat-icon>
|
<!-- <section class="controls">-->
|
||||||
</button>
|
<!-- <button-->
|
||||||
<button
|
<!-- mat-icon-button-->
|
||||||
mat-icon-button
|
<!-- [matTooltip]="T.F.FOCUS_MODE.FINISH_TASK_AND_SELECT_NEXT|translate"-->
|
||||||
[matTooltip]="T.F.FOCUS_MODE.GO_TO_PROCRASTINATION|translate"
|
<!-- (click)="finishCurrentTask();"-->
|
||||||
(click)="getProcrastinationHelp()"
|
<!-- >-->
|
||||||
>
|
<!-- <mat-icon>done</mat-icon>-->
|
||||||
<mat-icon>flash_on</mat-icon>
|
<!-- </button>-->
|
||||||
</button>
|
<!-- <button-->
|
||||||
@if (task.issueId && task.issueType !== ICAL_TYPE) {
|
<!-- mat-icon-button-->
|
||||||
<a
|
<!-- [matTooltip]="T.F.FOCUS_MODE.GO_TO_PROCRASTINATION|translate"-->
|
||||||
mat-icon-button
|
<!-- (click)="getProcrastinationHelp()"-->
|
||||||
[matTooltip]="T.F.FOCUS_MODE.OPEN_ISSUE_IN_BROWSER|translate"
|
<!-- >-->
|
||||||
target="_blank"
|
<!-- <mat-icon>flash_on</mat-icon>-->
|
||||||
[href]="issueUrl$|async"
|
<!-- </button>-->
|
||||||
>
|
<!-- @if (task.issueId && task.issueType !== ICAL_TYPE) {-->
|
||||||
@if (task.issuePoints) {
|
<!-- <a-->
|
||||||
<div class="mini-badge bgc-primary">{{ task.issuePoints }}</div>
|
<!-- mat-icon-button-->
|
||||||
}
|
<!-- [matTooltip]="T.F.FOCUS_MODE.OPEN_ISSUE_IN_BROWSER|translate"-->
|
||||||
<mat-icon [svgIcon]="task.issueType|issueIcon"></mat-icon>
|
<!-- target="_blank"-->
|
||||||
</a>
|
<!-- [href]="issueUrl$|async"-->
|
||||||
}
|
<!-- >-->
|
||||||
<button
|
<!-- @if (task.issuePoints) {-->
|
||||||
(click)="isShowNotes=!isShowNotes"
|
<!-- <div class="mini-badge bgc-primary">{{ task.issuePoints }}</div>-->
|
||||||
[matTooltip]="T.F.FOCUS_MODE.SHOW_HIDE_NOTES_AND_ATTACHMENTS|translate"
|
<!-- }-->
|
||||||
class="ico-btn show-additional-info-btn"
|
<!-- <mat-icon [svgIcon]="task.issueType|issueIcon"></mat-icon>-->
|
||||||
color=""
|
<!-- </a>-->
|
||||||
mat-icon-button
|
<!-- }-->
|
||||||
>
|
<!-- <button-->
|
||||||
@if (!isShowNotes) {
|
<!-- (click)="isShowNotes=!isShowNotes"-->
|
||||||
<mat-icon>chat</mat-icon>
|
<!-- [matTooltip]="T.F.FOCUS_MODE.SHOW_HIDE_NOTES_AND_ATTACHMENTS|translate"-->
|
||||||
} @if (isShowNotes) {
|
<!-- class="ico-btn show-additional-info-btn"-->
|
||||||
<mat-icon>expand_less</mat-icon>
|
<!-- color=""-->
|
||||||
}
|
<!-- mat-icon-button-->
|
||||||
</button>
|
<!-- >-->
|
||||||
</section>
|
<!-- @if (!isShowNotes) {-->
|
||||||
@if (isShowNotes) {
|
<!-- <mat-icon>chat</mat-icon>-->
|
||||||
<div
|
<!-- }-->
|
||||||
style="height: 100px"
|
<!-- @if (isShowNotes) {-->
|
||||||
@expand
|
<!-- <mat-icon>expand_less</mat-icon>-->
|
||||||
></div>
|
<!-- }-->
|
||||||
|
<!-- </button>-->
|
||||||
|
<!-- </section>-->
|
||||||
|
<!-- @if (isShowNotes) {-->
|
||||||
|
<!-- <div-->
|
||||||
|
<!-- style="height: 100px"-->
|
||||||
|
<!-- @expand-->
|
||||||
|
<!-- ></div>-->
|
||||||
|
|
||||||
<div
|
<!-- <div-->
|
||||||
class="notes-and-attachments"
|
<!-- class="notes-and-attachments"-->
|
||||||
@slideInOutFromBottom
|
<!-- @slideInOutFromBottom-->
|
||||||
>
|
<!-- >-->
|
||||||
<button
|
<!-- <button-->
|
||||||
(click)="isShowNotes=false"
|
<!-- (click)="isShowNotes=false"-->
|
||||||
class="hide-notes-btn"
|
<!-- class="hide-notes-btn"-->
|
||||||
color=""
|
<!-- color=""-->
|
||||||
mat-mini-fab
|
<!-- mat-mini-fab-->
|
||||||
>
|
<!-- >-->
|
||||||
<mat-icon>expand_less</mat-icon>
|
<!-- <mat-icon>expand_less</mat-icon>-->
|
||||||
</button>
|
<!-- </button>-->
|
||||||
|
|
||||||
<div class="notes-panel">
|
<!-- <div class="notes-panel">-->
|
||||||
<inline-markdown
|
<!-- <inline-markdown-->
|
||||||
(blur)="isFocusNotes=false"
|
<!-- (blur)="isFocusNotes=false"-->
|
||||||
(blurred)="isFocusNotes=false"
|
<!-- (blurred)="isFocusNotes=false"-->
|
||||||
(changed)="changeTaskNotes($event); isFocusNotes=false"
|
<!-- (changed)="changeTaskNotes($event); isFocusNotes=false"-->
|
||||||
[isFocus]="isFocusNotes"
|
<!-- [isFocus]="isFocusNotes"-->
|
||||||
[isShowControls]="true"
|
<!-- [isShowControls]="true"-->
|
||||||
[model]="task.notes|| defaultTaskNotes"
|
<!-- [model]="task.notes|| defaultTaskNotes"-->
|
||||||
></inline-markdown>
|
<!-- ></inline-markdown>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
@if (task.attachments.length) {
|
<!-- @if (task.attachments.length) {-->
|
||||||
<div
|
<!-- <div-->
|
||||||
class="attachment-list-wrapper"
|
<!-- class="attachment-list-wrapper"-->
|
||||||
@fade
|
<!-- @fade-->
|
||||||
>
|
<!-- >-->
|
||||||
<task-attachment-list
|
<!-- <task-attachment-list-->
|
||||||
[taskId]="task.id"
|
<!-- [taskId]="task.id"-->
|
||||||
[attachments]="task.attachments"
|
<!-- [attachments]="task.attachments"-->
|
||||||
></task-attachment-list>
|
<!-- ></task-attachment-list>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
}
|
<!-- }-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
} @if (isDragOver) {
|
<!-- }-->
|
||||||
<div class="bgc-accent drag-over-msg">
|
<!-- @if (isDragOver) {-->
|
||||||
<mat-icon>add</mat-icon>
|
<!-- <div class="bgc-accent drag-over-msg">-->
|
||||||
{{ T.F.TASK.CMP.DROP_ATTACHMENT|translate:{ title: task.title } }}
|
<!-- <mat-icon>add</mat-icon>-->
|
||||||
</div>
|
<!-- {{ T.F.TASK.CMP.DROP_ATTACHMENT|translate:{ title: task.title } }}-->
|
||||||
} }
|
<!-- </div>-->
|
||||||
|
<!-- }-->
|
||||||
|
<!--}-->
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,82 @@
|
||||||
<div class="mac-os-drag-bar"></div>
|
<div class="mac-os-drag-bar"></div>
|
||||||
|
|
||||||
@if (!(isPomodoroEnabled$|async)) {
|
@if (!(isPomodoroEnabled$ | async)) {
|
||||||
<header>
|
<header>
|
||||||
<banner></banner>
|
<banner></banner>
|
||||||
</header>
|
</header>
|
||||||
@if (activePage()) {
|
@if (activePage()) {
|
||||||
<main>
|
<main>
|
||||||
@if (activePage() === FocusModePage.ProcrastinationHelp) {
|
@if (activePage() === FocusModePage.ProcrastinationHelp) {
|
||||||
<button
|
<button
|
||||||
class="close-btn"
|
class="close-btn"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
(click)="leaveProcrastinationHelp()"
|
(click)="leaveProcrastinationHelp()"
|
||||||
>
|
>
|
||||||
<mat-icon>close</mat-icon>
|
<mat-icon>close</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
} @if (activePage() !== FocusModePage.ProcrastinationHelp) {
|
}
|
||||||
|
@if (activePage() !== FocusModePage.ProcrastinationHelp) {
|
||||||
|
<button
|
||||||
|
class="close-btn"
|
||||||
|
mat-icon-button
|
||||||
|
(click)="closeOverlay()"
|
||||||
|
>
|
||||||
|
<mat-icon>close</mat-icon>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
|
||||||
|
<ng-template #selectModeTpl>
|
||||||
|
<mat-button-toggle-group
|
||||||
|
class="focus-mode-select-mode"
|
||||||
|
[value]="selectedMode()"
|
||||||
|
(change)="selectMode($event.value)"
|
||||||
|
>
|
||||||
|
<mat-button-toggle [value]="FocusModeMode.Flowtime">Flowtime</mat-button-toggle>
|
||||||
|
<!-- <mat-button-toggle [value]="FocusModeMode.Pomodoro">Pomodoro</mat-button-toggle>-->
|
||||||
|
<mat-button-toggle [value]="FocusModeMode.Countdown"
|
||||||
|
>Countdown</mat-button-toggle
|
||||||
|
>
|
||||||
|
</mat-button-toggle-group>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
@switch (activePage()) {
|
||||||
|
<!-- -->
|
||||||
|
@case (FocusModePage.ProcrastinationHelp) {
|
||||||
|
<div
|
||||||
|
class="scroll-container"
|
||||||
|
@warpIn
|
||||||
|
>
|
||||||
|
<procrastination></procrastination>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@case (FocusModePage.TaskSelection) {
|
||||||
|
<ng-container *ngTemplateOutlet="selectModeTpl"></ng-container>
|
||||||
|
<focus-mode-task-selection
|
||||||
|
style="margin-bottom: auto; margin-top: -32px"
|
||||||
|
@warpIn
|
||||||
|
></focus-mode-task-selection>
|
||||||
|
}
|
||||||
|
@case (FocusModePage.DurationSelection) {
|
||||||
|
<ng-container *ngTemplateOutlet="selectModeTpl"></ng-container>
|
||||||
|
<focus-mode-duration-selection
|
||||||
|
style="margin-bottom: auto; margin-top: -32px"
|
||||||
|
@warpIn
|
||||||
|
></focus-mode-duration-selection>
|
||||||
|
}
|
||||||
|
@case (FocusModePage.Preparation) {
|
||||||
|
<focus-mode-preparation @warpIn></focus-mode-preparation>
|
||||||
|
}
|
||||||
|
@case (FocusModePage.Main) {
|
||||||
|
<focus-mode-main @warpIn></focus-mode-main>
|
||||||
|
}
|
||||||
|
@case (FocusModePage.SessionDone) {
|
||||||
|
<focus-mode-task-done @warpIn></focus-mode-task-done>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</main>
|
||||||
|
}
|
||||||
|
} @else {
|
||||||
<button
|
<button
|
||||||
class="close-btn"
|
class="close-btn"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
|
|
@ -22,76 +84,24 @@
|
||||||
>
|
>
|
||||||
<mat-icon>close</mat-icon>
|
<mat-icon>close</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
}
|
<div class="pomodoro-info-wrapper">
|
||||||
|
<div class="pomodoro-info-msg">{{ T.F.FOCUS_MODE.POMODORO_INFO | translate }}</div>
|
||||||
<ng-template #selectModeTpl>
|
<div style="text-align: center">
|
||||||
<mat-button-toggle-group
|
<button
|
||||||
class="focus-mode-select-mode"
|
mat-stroked-button
|
||||||
[value]="selectedMode()"
|
color="primary"
|
||||||
(change)="selectMode($event.value)"
|
(click)="deactivatePomodoro()"
|
||||||
>
|
>
|
||||||
<mat-button-toggle [value]="FocusModeMode.Flowtime">Flowtime</mat-button-toggle>
|
<mat-icon>alarm_off</mat-icon>
|
||||||
<!-- <mat-button-toggle [value]="FocusModeMode.Pomodoro">Pomodoro</mat-button-toggle>-->
|
{{ T.F.FOCUS_MODE.POMODORO_DISABLE | translate }}
|
||||||
<mat-button-toggle [value]="FocusModeMode.Countdown">Countdown</mat-button-toggle>
|
</button>
|
||||||
</mat-button-toggle-group>
|
<button
|
||||||
</ng-template>
|
mat-stroked-button
|
||||||
|
(click)="cancelFocusSession()"
|
||||||
<!-- -->
|
>
|
||||||
@switch (activePage()) {
|
<mat-icon>arrow_back</mat-icon>
|
||||||
<!-- -->
|
{{ T.F.FOCUS_MODE.BACK_TO_PLANNING | translate }}
|
||||||
@case (FocusModePage.ProcrastinationHelp) {
|
</button>
|
||||||
<div
|
</div>
|
||||||
class="scroll-container"
|
|
||||||
@warpIn
|
|
||||||
>
|
|
||||||
<procrastination></procrastination>
|
|
||||||
</div>
|
</div>
|
||||||
} @case (FocusModePage.TaskSelection) {
|
|
||||||
<ng-container *ngTemplateOutlet="selectModeTpl"></ng-container>
|
|
||||||
<focus-mode-task-selection
|
|
||||||
style="margin-bottom: auto; margin-top: -32px"
|
|
||||||
@warpIn
|
|
||||||
></focus-mode-task-selection>
|
|
||||||
} @case (FocusModePage.DurationSelection) {
|
|
||||||
<ng-container *ngTemplateOutlet="selectModeTpl"></ng-container>
|
|
||||||
<focus-mode-duration-selection
|
|
||||||
style="margin-bottom: auto; margin-top: -32px"
|
|
||||||
@warpIn
|
|
||||||
></focus-mode-duration-selection>
|
|
||||||
} @case (FocusModePage.Preparation) {
|
|
||||||
<focus-mode-preparation @warpIn></focus-mode-preparation>
|
|
||||||
} @case (FocusModePage.Main) {
|
|
||||||
<focus-mode-main @warpIn></focus-mode-main>
|
|
||||||
} @case (FocusModePage.SessionDone) {
|
|
||||||
<focus-mode-task-done @warpIn></focus-mode-task-done>
|
|
||||||
} }
|
|
||||||
</main>
|
|
||||||
} } @else {
|
|
||||||
<button
|
|
||||||
class="close-btn"
|
|
||||||
mat-icon-button
|
|
||||||
(click)="closeOverlay()"
|
|
||||||
>
|
|
||||||
<mat-icon>close</mat-icon>
|
|
||||||
</button>
|
|
||||||
<div class="pomodoro-info-wrapper">
|
|
||||||
<div class="pomodoro-info-msg">{{ T.F.FOCUS_MODE.POMODORO_INFO|translate }}</div>
|
|
||||||
<div style="text-align: center">
|
|
||||||
<button
|
|
||||||
mat-stroked-button
|
|
||||||
color="primary"
|
|
||||||
(click)="deactivatePomodoro()"
|
|
||||||
>
|
|
||||||
<mat-icon>alarm_off</mat-icon>
|
|
||||||
{{ T.F.FOCUS_MODE.POMODORO_DISABLE|translate }}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
mat-stroked-button
|
|
||||||
(click)="cancelFocusSession()"
|
|
||||||
>
|
|
||||||
<mat-icon>arrow_back</mat-icon>
|
|
||||||
{{ T.F.FOCUS_MODE.BACK_TO_PLANNING|translate }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,27 @@
|
||||||
@if (countdown$|async; as countdown) { @if (countdown > 0) {
|
@if (countdown$ | async; as countdown) {
|
||||||
<section>
|
@if (countdown > 0) {
|
||||||
<div class="action-msg">{{T.F.FOCUS_MODE.GET_READY|translate}}</div>
|
<section>
|
||||||
<ol>
|
<div class="action-msg">{{ T.F.FOCUS_MODE.GET_READY | translate }}</div>
|
||||||
<li>{{T.F.FOCUS_MODE.PREP_STRETCH|translate}}</li>
|
<ol>
|
||||||
<li>{{T.F.FOCUS_MODE.PREP_SIT_UPRIGHT|translate}}</li>
|
<li>{{ T.F.FOCUS_MODE.PREP_STRETCH | translate }}</li>
|
||||||
<li>{{T.F.FOCUS_MODE.PREP_GET_MENTALLY_READY|translate}}</li>
|
<li>{{ T.F.FOCUS_MODE.PREP_SIT_UPRIGHT | translate }}</li>
|
||||||
</ol>
|
<li>{{ T.F.FOCUS_MODE.PREP_GET_MENTALLY_READY | translate }}</li>
|
||||||
<div class="countdown-timer">{{countdown}}</div>
|
</ol>
|
||||||
<!-- <div style="text-align: center">-->
|
<div class="countdown-timer">{{ countdown }}</div>
|
||||||
<!-- <button-->
|
<!-- <div style="text-align: center">-->
|
||||||
<!-- type="submit"-->
|
<!-- <button-->
|
||||||
<!-- color="primary"-->
|
<!-- type="submit"-->
|
||||||
<!-- mat-raised-button-->
|
<!-- color="primary"-->
|
||||||
<!-- (click)="startSession()"-->
|
<!-- mat-raised-button-->
|
||||||
<!-- >-->
|
<!-- (click)="startSession()"-->
|
||||||
<!-- Start Focus Session-->
|
<!-- >-->
|
||||||
<!-- </button>-->
|
<!-- Start Focus Session-->
|
||||||
<!-- </div>-->
|
<!-- </button>-->
|
||||||
</section>
|
<!-- </div>-->
|
||||||
} } @else {
|
</section>
|
||||||
<section @fade>
|
}
|
||||||
<div class="action-msg">{{T.F.FOCUS_MODE.GOGOGO|translate}}</div>
|
} @else {
|
||||||
</section>
|
<section @fade>
|
||||||
|
<div class="action-msg">{{ T.F.FOCUS_MODE.GOGOGO | translate }}</div>
|
||||||
|
</section>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,12 @@
|
||||||
<h1>Focus Session Completed!</h1>
|
<h1>Focus Session Completed!</h1>
|
||||||
|
|
||||||
<div class="msg">
|
<div class="msg">
|
||||||
<div class="worked-for-label">{{T.F.FOCUS_MODE.WORKED_FOR|translate}}</div>
|
<div class="worked-for-label">{{ T.F.FOCUS_MODE.WORKED_FOR | translate }}</div>
|
||||||
<div class="worked-for-value">{{6213000|msToString:true}}</div>
|
<div class="worked-for-value">{{ 6213000 | msToString: true }}</div>
|
||||||
<!-- <div class="worked-for-value">{{timeElapsed$|async|msToString:true}}</div>-->
|
<!-- <div class="worked-for-value">{{timeElapsed$|async|msToString:true}}</div>-->
|
||||||
|
|
||||||
<div class="task-title-label">{{T.F.FOCUS_MODE.ON|translate}}</div>
|
<div class="task-title-label">{{ T.F.FOCUS_MODE.ON | translate }}</div>
|
||||||
<div class="task-title">{{taskTitle$|async}}</div>
|
<div class="task-title">{{ taskTitle$ | async }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn-wrapper">
|
<div class="btn-wrapper">
|
||||||
|
|
@ -21,24 +21,25 @@
|
||||||
color="primary"
|
color="primary"
|
||||||
(click)="closeFocusOverlay()"
|
(click)="closeFocusOverlay()"
|
||||||
>
|
>
|
||||||
{{T.F.FOCUS_MODE.BACK_TO_PLANNING|translate}}
|
{{ T.F.FOCUS_MODE.BACK_TO_PLANNING | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@if (!(currentTask$|async)) {
|
@if (!(currentTask$ | async)) {
|
||||||
<button
|
<button
|
||||||
mat-raised-button
|
mat-raised-button
|
||||||
color="primary"
|
color="primary"
|
||||||
(click)="startNextFocusSession()"
|
(click)="startNextFocusSession()"
|
||||||
>
|
>
|
||||||
{{T.F.FOCUS_MODE.START_NEXT_FOCUS_SESSION|translate}}
|
{{ T.F.FOCUS_MODE.START_NEXT_FOCUS_SESSION | translate }}
|
||||||
</button>
|
</button>
|
||||||
} @if ((currentTask$|async)) {
|
}
|
||||||
<button
|
@if (currentTask$ | async) {
|
||||||
mat-raised-button
|
<button
|
||||||
color="primary"
|
mat-raised-button
|
||||||
(click)="continueWithFocusSession()"
|
color="primary"
|
||||||
>
|
(click)="continueWithFocusSession()"
|
||||||
{{T.F.FOCUS_MODE.CONTINUE_FOCUS_SESSION|translate}}
|
>
|
||||||
</button>
|
{{ T.F.FOCUS_MODE.CONTINUE_FOCUS_SESSION | translate }}
|
||||||
|
</button>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
<form
|
<form
|
||||||
(submit)="$event.preventDefault();onSubmit($event)"
|
(submit)="$event.preventDefault(); onSubmit($event)"
|
||||||
novalidate
|
novalidate
|
||||||
>
|
>
|
||||||
<h1>{{T.F.FOCUS_MODE.SELECT_TASK|translate}}</h1>
|
<h1>{{ T.F.FOCUS_MODE.SELECT_TASK | translate }}</h1>
|
||||||
|
|
||||||
<select-task
|
<select-task
|
||||||
(taskChange)="onTaskChange($event)"
|
(taskChange)="onTaskChange($event)"
|
||||||
[initialTask]="initialTask$|async"
|
[initialTask]="initialTask$ | async"
|
||||||
[isIncludeDoneTasks]="false"
|
[isIncludeDoneTasks]="false"
|
||||||
>
|
>
|
||||||
</select-task>
|
</select-task>
|
||||||
|
|
@ -17,6 +17,6 @@
|
||||||
color="primary"
|
color="primary"
|
||||||
mat-raised-button
|
mat-raised-button
|
||||||
>
|
>
|
||||||
{{T.F.FOCUS_MODE.NEXT|translate}}
|
{{ T.F.FOCUS_MODE.NEXT | translate }}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -2,65 +2,72 @@
|
||||||
class="dialog-content"
|
class="dialog-content"
|
||||||
mat-dialog-content
|
mat-dialog-content
|
||||||
>
|
>
|
||||||
<p>{{T.F.TIME_TRACKING.D_IDLE.IDLE_FOR|translate}}</p>
|
<p>{{ T.F.TIME_TRACKING.D_IDLE.IDLE_FOR | translate }}</p>
|
||||||
<div class="time">{{idleTime$|async|msToString:true}}</div>
|
<div class="time">{{ idleTime$ | async | msToString: true }}</div>
|
||||||
|
|
||||||
<div class="track-to-items">
|
<div class="track-to-items">
|
||||||
@for (item of trackItems; track item) {
|
@for (item of trackItems; track item) {
|
||||||
<div class="track-to-item">
|
<div class="track-to-item">
|
||||||
<div class="first-block">
|
<div class="first-block">
|
||||||
<mat-button-toggle-group [(ngModel)]="item.type">
|
<mat-button-toggle-group [(ngModel)]="item.type">
|
||||||
<mat-button-toggle value="BREAK">
|
<mat-button-toggle value="BREAK">
|
||||||
<mat-icon>free_breakfast</mat-icon>
|
<mat-icon>free_breakfast</mat-icon>
|
||||||
</mat-button-toggle>
|
</mat-button-toggle>
|
||||||
<!-- <mat-button-toggle value="TASK_AND_BREAK">-->
|
<!-- <mat-button-toggle value="TASK_AND_BREAK">-->
|
||||||
<!-- <mat-icon>track_changes</mat-icon>-->
|
<!-- <mat-icon>track_changes</mat-icon>-->
|
||||||
<!-- +-->
|
<!-- +-->
|
||||||
<!-- <mat-icon>free_breakfast</mat-icon>-->
|
<!-- <mat-icon>free_breakfast</mat-icon>-->
|
||||||
<!-- </mat-button-toggle>-->
|
<!-- </mat-button-toggle>-->
|
||||||
<mat-button-toggle value="TASK">
|
<mat-button-toggle value="TASK">
|
||||||
<mat-icon>track_changes</mat-icon>
|
<mat-icon>track_changes</mat-icon>
|
||||||
</mat-button-toggle>
|
</mat-button-toggle>
|
||||||
</mat-button-toggle-group>
|
</mat-button-toggle-group>
|
||||||
<select-task
|
<select-task
|
||||||
[isIncludeDoneTasks]="true"
|
[isIncludeDoneTasks]="true"
|
||||||
[initialTask]="item.task"
|
[initialTask]="item.task"
|
||||||
(taskChange)="onTaskChange(item, $event)"
|
(taskChange)="onTaskChange(item, $event)"
|
||||||
[class.isDisabled]="item.type==='BREAK'"
|
[class.isDisabled]="item.type === 'BREAK'"
|
||||||
>
|
|
||||||
</select-task>
|
|
||||||
<section class="simple-counter-section">
|
|
||||||
@for (simpleCounterBtn of item.simpleCounterToggleBtns; track simpleCounterBtn)
|
|
||||||
{
|
|
||||||
<button
|
|
||||||
mat-mini-fab
|
|
||||||
class="simple-counter"
|
|
||||||
type="button"
|
|
||||||
(click)="simpleCounterBtn.isTrackTo=!simpleCounterBtn.isTrackTo"
|
|
||||||
[matTooltip]="(simpleCounterBtn.isTrackTo ? T.F.TIME_TRACKING.D_IDLE.SIMPLE_COUNTER_TOOLTIP_DISABLE : T.F.TIME_TRACKING.D_IDLE.SIMPLE_COUNTER_TOOLTIP)|translate:{ title: simpleCounterBtn.title }"
|
|
||||||
[color]="simpleCounterBtn.isTrackTo ? 'primary' : ''"
|
|
||||||
>
|
>
|
||||||
<mat-icon>{{simpleCounterBtn.icon}}</mat-icon>
|
</select-task>
|
||||||
</button>
|
<section class="simple-counter-section">
|
||||||
}
|
@for (
|
||||||
</section>
|
simpleCounterBtn of item.simpleCounterToggleBtns;
|
||||||
</div>
|
track simpleCounterBtn
|
||||||
<input-duration-slider
|
) {
|
||||||
[(model)]="item.time"
|
<button
|
||||||
[label]="T.F.TASK.D_TIME.TIME_SPENT|translate"
|
mat-mini-fab
|
||||||
>
|
class="simple-counter"
|
||||||
</input-duration-slider>
|
type="button"
|
||||||
<div>
|
(click)="simpleCounterBtn.isTrackTo = !simpleCounterBtn.isTrackTo"
|
||||||
<button
|
[matTooltip]="
|
||||||
mat-icon-button
|
(simpleCounterBtn.isTrackTo
|
||||||
[color]="'warn'"
|
? T.F.TIME_TRACKING.D_IDLE.SIMPLE_COUNTER_TOOLTIP_DISABLE
|
||||||
(click)="removeTrackItem(item)"
|
: T.F.TIME_TRACKING.D_IDLE.SIMPLE_COUNTER_TOOLTIP
|
||||||
[disabled]="trackItems.length <= 1"
|
) | translate: { title: simpleCounterBtn.title }
|
||||||
|
"
|
||||||
|
[color]="simpleCounterBtn.isTrackTo ? 'primary' : ''"
|
||||||
|
>
|
||||||
|
<mat-icon>{{ simpleCounterBtn.icon }}</mat-icon>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
<input-duration-slider
|
||||||
|
[(model)]="item.time"
|
||||||
|
[label]="T.F.TASK.D_TIME.TIME_SPENT | translate"
|
||||||
>
|
>
|
||||||
<mat-icon>delete_forever</mat-icon>
|
</input-duration-slider>
|
||||||
</button>
|
<div>
|
||||||
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
[color]="'warn'"
|
||||||
|
(click)="removeTrackItem(item)"
|
||||||
|
[disabled]="trackItems.length <= 1"
|
||||||
|
>
|
||||||
|
<mat-icon>delete_forever</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<div style="text-align: center; margin-top: 8px">
|
<div style="text-align: center; margin-top: 8px">
|
||||||
|
|
@ -69,7 +76,7 @@
|
||||||
(click)="addTrackItem()"
|
(click)="addTrackItem()"
|
||||||
>
|
>
|
||||||
<mat-icon>add</mat-icon>
|
<mat-icon>add</mat-icon>
|
||||||
{{T.F.TIME_TRACKING.D_IDLE.ADD_ENTRY|translate}}
|
{{ T.F.TIME_TRACKING.D_IDLE.ADD_ENTRY | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -85,7 +92,7 @@
|
||||||
mat-button
|
mat-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
{{T.G.CANCEL|translate}}
|
{{ T.G.CANCEL | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
@ -95,6 +102,6 @@
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
<mat-icon>save</mat-icon>
|
<mat-icon>save</mat-icon>
|
||||||
{{T.G.SAVE|translate}}
|
{{ T.G.SAVE | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,103 +1,112 @@
|
||||||
@if (isTaskDataLoadedIfNeeded) {
|
@if (isTaskDataLoadedIfNeeded) {
|
||||||
<form (submit)="$event.preventDefault();track()">
|
<form (submit)="$event.preventDefault(); track()">
|
||||||
<div
|
|
||||||
class="dialog-content"
|
|
||||||
mat-dialog-content
|
|
||||||
>
|
|
||||||
<p>{{T.F.TIME_TRACKING.D_IDLE.IDLE_FOR|translate}}</p>
|
|
||||||
<div class="time">{{idleTime$|async|msToString:true}}</div>
|
|
||||||
<div
|
<div
|
||||||
class="split-btn"
|
class="dialog-content"
|
||||||
style="text-align: center"
|
mat-dialog-content
|
||||||
>
|
>
|
||||||
<button
|
<p>{{ T.F.TIME_TRACKING.D_IDLE.IDLE_FOR | translate }}</p>
|
||||||
mat-icon-button
|
<div class="time">{{ idleTime$ | async | msToString: true }}</div>
|
||||||
[matTooltip]="T.F.TIME_TRACKING.D_IDLE.SPLIT_TIME|translate"
|
<div
|
||||||
(click)="showSplit()"
|
class="split-btn"
|
||||||
type="button"
|
style="text-align: center"
|
||||||
>
|
>
|
||||||
<mat-icon>call_split</mat-icon>
|
<button
|
||||||
</button>
|
mat-icon-button
|
||||||
</div>
|
[matTooltip]="T.F.TIME_TRACKING.D_IDLE.SPLIT_TIME | translate"
|
||||||
<div class="track-to-label">
|
(click)="showSplit()"
|
||||||
@if (!isCreate) {
|
type="button"
|
||||||
<span>{{T.F.TIME_TRACKING.D_IDLE.TRACK_TO|translate}}</span>
|
>
|
||||||
} @if (isCreate) {
|
<mat-icon>call_split</mat-icon>
|
||||||
<span [innerHTML]="T.F.TIME_TRACKING.D_IDLE.CREATE_AND_TRACK|translate"></span>
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="track-to-label">
|
||||||
|
@if (!isCreate) {
|
||||||
|
<span>{{ T.F.TIME_TRACKING.D_IDLE.TRACK_TO | translate }}</span>
|
||||||
|
}
|
||||||
|
@if (isCreate) {
|
||||||
|
<span
|
||||||
|
[innerHTML]="T.F.TIME_TRACKING.D_IDLE.CREATE_AND_TRACK | translate"
|
||||||
|
></span>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<select-task
|
||||||
|
(taskChange)="onTaskChange($event)"
|
||||||
|
[isIncludeDoneTasks]="true"
|
||||||
|
[initialTask]="selectedTask"
|
||||||
|
></select-task>
|
||||||
|
<section class="simple-counter-section">
|
||||||
|
@for (simpleCounterBtn of simpleCounterToggleBtns; track simpleCounterBtn) {
|
||||||
|
<button
|
||||||
|
mat-mini-fab
|
||||||
|
class="simple-counter"
|
||||||
|
type="button"
|
||||||
|
(click)="simpleCounterBtn.isTrackTo = !simpleCounterBtn.isTrackTo"
|
||||||
|
[matTooltip]="
|
||||||
|
(simpleCounterBtn.isTrackTo
|
||||||
|
? T.F.TIME_TRACKING.D_IDLE.SIMPLE_COUNTER_TOOLTIP_DISABLE
|
||||||
|
: T.F.TIME_TRACKING.D_IDLE.SIMPLE_COUNTER_TOOLTIP
|
||||||
|
) | translate: { title: simpleCounterBtn.title }
|
||||||
|
"
|
||||||
|
[color]="simpleCounterBtn.isTrackTo ? 'primary' : ''"
|
||||||
|
>
|
||||||
|
<mat-icon>{{ simpleCounterBtn.icon }}</mat-icon>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</section>
|
||||||
|
@if ((configService.takeABreak$ | async)?.isTakeABreakEnabled) {
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 16px;
|
||||||
|
margin-bottom: -8px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<mat-checkbox
|
||||||
|
[(ngModel)]="isResetBreakTimer"
|
||||||
|
[ngModelOptions]="{ standalone: true }"
|
||||||
|
>
|
||||||
|
{{ T.F.TIME_TRACKING.D_IDLE.RESET_BREAK_REMINDER_TIMER | translate }}
|
||||||
|
</mat-checkbox>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<select-task
|
|
||||||
(taskChange)="onTaskChange($event)"
|
|
||||||
[isIncludeDoneTasks]="true"
|
|
||||||
[initialTask]="selectedTask"
|
|
||||||
></select-task>
|
|
||||||
<section class="simple-counter-section">
|
|
||||||
@for (simpleCounterBtn of simpleCounterToggleBtns; track simpleCounterBtn) {
|
|
||||||
<button
|
|
||||||
mat-mini-fab
|
|
||||||
class="simple-counter"
|
|
||||||
type="button"
|
|
||||||
(click)="simpleCounterBtn.isTrackTo=!simpleCounterBtn.isTrackTo"
|
|
||||||
[matTooltip]="(simpleCounterBtn.isTrackTo ? T.F.TIME_TRACKING.D_IDLE.SIMPLE_COUNTER_TOOLTIP_DISABLE : T.F.TIME_TRACKING.D_IDLE.SIMPLE_COUNTER_TOOLTIP)|translate:{ title: simpleCounterBtn.title }"
|
|
||||||
[color]="simpleCounterBtn.isTrackTo ? 'primary' : ''"
|
|
||||||
>
|
|
||||||
<mat-icon>{{simpleCounterBtn.icon}}</mat-icon>
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
</section>
|
|
||||||
@if ((configService.takeABreak$|async)?.isTakeABreakEnabled) {
|
|
||||||
<div
|
<div
|
||||||
style="
|
align="center"
|
||||||
display: flex;
|
mat-dialog-actions
|
||||||
justify-content: center;
|
|
||||||
margin-top: 16px;
|
|
||||||
margin-bottom: -8px;
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<mat-checkbox
|
<button
|
||||||
[(ngModel)]="isResetBreakTimer"
|
(click)="skipTrack()"
|
||||||
[ngModelOptions]="
|
color=""
|
||||||
{standalone: true}"
|
mat-button
|
||||||
|
type="button"
|
||||||
>
|
>
|
||||||
{{ T.F.TIME_TRACKING.D_IDLE.RESET_BREAK_REMINDER_TIMER|translate }}
|
<mat-icon>skip_next</mat-icon>
|
||||||
</mat-checkbox>
|
{{ T.F.TIME_TRACKING.D_IDLE.SKIP | translate }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
(click)="trackAsBreak()"
|
||||||
|
color="primary"
|
||||||
|
mat-stroked-button
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<mat-icon>free_breakfast</mat-icon>
|
||||||
|
{{ T.F.TIME_TRACKING.D_IDLE.BREAK | translate }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
[disabled]="!(selectedTask || newTaskTitle)"
|
||||||
|
color="primary"
|
||||||
|
mat-stroked-button
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
@if (!isCreate) {
|
||||||
|
<mat-icon>track_changes</mat-icon>
|
||||||
|
}
|
||||||
|
@if (isCreate) {
|
||||||
|
<mat-icon>add</mat-icon>
|
||||||
|
}
|
||||||
|
{{ T.F.TIME_TRACKING.D_IDLE.TASK | translate }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
}
|
</form>
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
align="center"
|
|
||||||
mat-dialog-actions
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
(click)="skipTrack()"
|
|
||||||
color=""
|
|
||||||
mat-button
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<mat-icon>skip_next</mat-icon>
|
|
||||||
{{T.F.TIME_TRACKING.D_IDLE.SKIP|translate}}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
(click)="trackAsBreak()"
|
|
||||||
color="primary"
|
|
||||||
mat-stroked-button
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<mat-icon>free_breakfast</mat-icon>
|
|
||||||
{{T.F.TIME_TRACKING.D_IDLE.BREAK|translate}}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
[disabled]="!(selectedTask||newTaskTitle)"
|
|
||||||
color="primary"
|
|
||||||
mat-stroked-button
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
@if (!isCreate) {
|
|
||||||
<mat-icon>track_changes</mat-icon>
|
|
||||||
} @if (isCreate) {
|
|
||||||
<mat-icon>add</mat-icon>
|
|
||||||
} {{T.F.TIME_TRACKING.D_IDLE.TASK|translate}}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,37 @@
|
||||||
@if (isLoading()) {
|
@if (isLoading()) {
|
||||||
<div class="spinner">
|
<div class="spinner">
|
||||||
<mat-spinner diameter="50"></mat-spinner>
|
<mat-spinner diameter="50"></mat-spinner>
|
||||||
</div>
|
</div>
|
||||||
} @else if (error()) {
|
} @else if (error()) {
|
||||||
<error-card
|
<error-card
|
||||||
[errorTxt]="error()"
|
[errorTxt]="error()"
|
||||||
[actionAdvice]="'Check your config!'"
|
[actionAdvice]="'Check your config!'"
|
||||||
></error-card>
|
></error-card>
|
||||||
} @else if (!agendaItems()?.length) {
|
} @else if (!agendaItems()?.length) {
|
||||||
<div class="empty">No items found (already added are not shown)</div>
|
<div class="empty">No items found (already added are not shown)</div>
|
||||||
} @else {
|
} @else {
|
||||||
<div class="agenda">
|
<div class="agenda">
|
||||||
@for (day of agendaItems(); track day.dayStr) {
|
@for (day of agendaItems(); track day.dayStr) {
|
||||||
<div class="agenda-day">
|
<div class="agenda-day">
|
||||||
<h4>{{ day.dayStr|date:'shortDate' }}</h4>
|
<h4>{{ day.dayStr | date: 'shortDate' }}</h4>
|
||||||
<div
|
<div
|
||||||
class="item-list"
|
class="item-list"
|
||||||
[@standardList]="day.itemsForDay.length"
|
[@standardList]="day.itemsForDay.length"
|
||||||
>
|
>
|
||||||
@for (item of day.itemsForDay; track item.issueData.id) {
|
@for (item of day.itemsForDay; track item.issueData.id) {
|
||||||
<issue-preview-item
|
<issue-preview-item
|
||||||
[issueProviderId]="issueProvider().id"
|
[issueProviderId]="issueProvider().id"
|
||||||
[itemData]="item"
|
[itemData]="item"
|
||||||
[customTitleStr]="(item.issueData?.start|date:'shortTime') + ' – ' + item.issueData?.title"
|
[customTitleStr]="
|
||||||
(addIssue)="addIssue($event)"
|
(item.issueData?.start | date: 'shortTime') +
|
||||||
></issue-preview-item>
|
' – ' +
|
||||||
}
|
item.issueData?.title
|
||||||
</div>
|
"
|
||||||
|
(addIssue)="addIssue($event)"
|
||||||
|
></issue-preview-item>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
@if (isShowIntro()) {
|
@if (isShowIntro()) {
|
||||||
<issue-panel-intro></issue-panel-intro>
|
<issue-panel-intro></issue-panel-intro>
|
||||||
}
|
}
|
||||||
|
|
||||||
<mat-tab-group
|
<mat-tab-group
|
||||||
|
|
@ -15,29 +15,29 @@
|
||||||
[selectedIndex]="selectedTabIndex()"
|
[selectedIndex]="selectedTabIndex()"
|
||||||
>
|
>
|
||||||
@for (entry of issueProvidersMapped(); track entry.issueProvider.id) {
|
@for (entry of issueProvidersMapped(); track entry.issueProvider.id) {
|
||||||
<mat-tab>
|
<mat-tab>
|
||||||
<ng-template mat-tab-label>
|
<ng-template mat-tab-label>
|
||||||
<div
|
<div
|
||||||
cdkDrag
|
cdkDrag
|
||||||
cdkDragRootElement=".mat-mdc-tab"
|
cdkDragRootElement=".mat-mdc-tab"
|
||||||
cdkDragPreviewClass="issue-provider-drag-preview"
|
cdkDragPreviewClass="issue-provider-drag-preview"
|
||||||
class="tab-header-item"
|
class="tab-header-item"
|
||||||
[class.disabled]="!entry.issueProvider.isEnabled"
|
[class.disabled]="!entry.issueProvider.isEnabled"
|
||||||
(longPressIOS)="openEditIssueProvider(entry.issueProvider)"
|
(longPressIOS)="openEditIssueProvider(entry.issueProvider)"
|
||||||
(longPress)="openEditIssueProvider(entry.issueProvider)"
|
(longPress)="openEditIssueProvider(entry.issueProvider)"
|
||||||
>
|
>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
[svgIcon]="entry.issueProvider.issueProviderKey|issueIcon"
|
[svgIcon]="entry.issueProvider.issueProviderKey | issueIcon"
|
||||||
[matTooltip]="entry.tooltip"
|
[matTooltip]="entry.tooltip"
|
||||||
matTooltipPosition="above"
|
matTooltipPosition="above"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<div class="initials">{{ entry.initials }}</div>
|
<div class="initials">{{ entry.initials }}</div>
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<ng-template matTabContent>
|
<ng-template matTabContent>
|
||||||
<issue-provider-tab [issueProvider]="entry.issueProvider"></issue-provider-tab>
|
<issue-provider-tab [issueProvider]="entry.issueProvider"></issue-provider-tab>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
}
|
}
|
||||||
|
|
||||||
<mat-tab>
|
<mat-tab>
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,12 @@
|
||||||
|
|
||||||
<div class="title">{{ customTitleStr() || itemData().title }}</div>
|
<div class="title">{{ customTitleStr() || itemData().title }}</div>
|
||||||
|
|
||||||
@if(itemData().issueType !== ICAL_TYPE) {
|
@if (itemData().issueType !== ICAL_TYPE) {
|
||||||
<button
|
<button
|
||||||
class="open-issue"
|
class="open-issue"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
(click)="openIssue()"
|
(click)="openIssue()"
|
||||||
>
|
>
|
||||||
<mat-icon>open_in_new</mat-icon>
|
<mat-icon>open_in_new</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,125 +8,128 @@
|
||||||
<mat-icon>settings</mat-icon>
|
<mat-icon>settings</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<div class="title">{{ issueProviderTooltip() }}</div>
|
<div class="title">{{ issueProviderTooltip() }}</div>
|
||||||
@let defaultP = defaultProject(); @if (defaultP) {
|
@let defaultP = defaultProject();
|
||||||
<mat-icon class="arrow">arrow_forward</mat-icon>
|
@if (defaultP) {
|
||||||
<div class="default-project">{{ defaultP.title }}</div>
|
<mat-icon class="arrow">arrow_forward</mat-icon>
|
||||||
|
<div class="default-project">{{ defaultP.title }}</div>
|
||||||
}
|
}
|
||||||
</header>
|
</header>
|
||||||
@let ip = issueProvider();
|
@let ip = issueProvider();
|
||||||
<!---->
|
<!---->
|
||||||
|
|
||||||
@if (ip.isEnabled) {
|
@if (ip.isEnabled) {
|
||||||
<!---->
|
<!---->
|
||||||
@if (ip.issueProviderKey === 'JIRA') {
|
@if (ip.issueProviderKey === 'JIRA') {
|
||||||
<div [ngClass]="HelperClasses.isHideForAdvancedFeatures">
|
<div [ngClass]="HelperClasses.isHideForAdvancedFeatures">
|
||||||
<p [innerHTML]="T.G.EXTENSION_INFO|translate"></p>
|
<p [innerHTML]="T.G.EXTENSION_INFO | translate"></p>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
<!---->
|
|
||||||
@if(ip.issueProviderKey === 'ICAL') {
|
|
||||||
<issue-panel-calendar-agenda [issueProvider]="ip"></issue-panel-calendar-agenda>
|
|
||||||
|
|
||||||
} @else {
|
|
||||||
<form
|
|
||||||
class="example-form"
|
|
||||||
style="width: 100%; margin: 8px 0 16px"
|
|
||||||
>
|
|
||||||
<mat-form-field
|
|
||||||
style="width: 100%; margin: 0"
|
|
||||||
appearance="outline"
|
|
||||||
>
|
|
||||||
<!-- <mat-icon matPrefix>filter_alt</mat-icon>-->
|
|
||||||
<!-- <mat-label>Filter</mat-label>-->
|
|
||||||
<mat-label>Search</mat-label>
|
|
||||||
<mat-icon
|
|
||||||
matPrefix
|
|
||||||
style="opacity: 0.5"
|
|
||||||
>search</mat-icon
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
#searchTextEl
|
|
||||||
[ngModel]="searchText()"
|
|
||||||
(ngModelChange)="searchText.set($event)"
|
|
||||||
autocomplete="off"
|
|
||||||
matInput
|
|
||||||
name="search"
|
|
||||||
placeholder="Search"
|
|
||||||
/>
|
|
||||||
|
|
||||||
@if (isPinned()) {
|
|
||||||
<mat-icon
|
|
||||||
class="keep-ico"
|
|
||||||
matSuffix
|
|
||||||
svgIcon="keep_filled"
|
|
||||||
style="cursor: pointer"
|
|
||||||
(click)="unPinSearch()"
|
|
||||||
[matTooltip]="'Clear pinned search query'"
|
|
||||||
></mat-icon>
|
|
||||||
} @else if(ip?.pinnedSearch?.length||searchText()?.length >= SEARCH_MIN_LENGTH) {
|
|
||||||
<mat-icon
|
|
||||||
class="keep-ico"
|
|
||||||
matSuffix
|
|
||||||
svgIcon="keep"
|
|
||||||
style="cursor: pointer"
|
|
||||||
(click)="pinSearch()"
|
|
||||||
[matTooltip]="'Remember search query'"
|
|
||||||
></mat-icon>
|
|
||||||
}
|
|
||||||
<!-- -->
|
|
||||||
@if (searchText().length ===0 && issueProviderHelpLink()) {
|
|
||||||
<mat-hint
|
|
||||||
><a
|
|
||||||
[href]="issueProviderHelpLink()"
|
|
||||||
target="_blank"
|
|
||||||
>{{ISSUE_PROVIDER_HUMANIZED[ip.issueProviderKey]}} search syntax</a
|
|
||||||
></mat-hint
|
|
||||||
>
|
|
||||||
}
|
|
||||||
<!-- @if (searchText()?.length > 0) {-->
|
|
||||||
<!-- <mat-icon-->
|
|
||||||
<!-- style="cursor: pointer"-->
|
|
||||||
<!-- matSuffix-->
|
|
||||||
<!-- (click)="searchText.set('')"-->
|
|
||||||
<!-- >close</mat-icon-->
|
|
||||||
<!-- >-->
|
|
||||||
<!-- }-->
|
|
||||||
</mat-form-field>
|
|
||||||
</form>
|
|
||||||
}
|
|
||||||
<!---->
|
|
||||||
@if (isLoading()) {
|
|
||||||
<div class="spinner">
|
|
||||||
<mat-spinner diameter="50"></mat-spinner>
|
|
||||||
</div>
|
|
||||||
} @else if (error()) {
|
|
||||||
<error-card
|
|
||||||
[errorTxt]="error()"
|
|
||||||
[actionAdvice]="'Check your config!'"
|
|
||||||
></error-card>
|
|
||||||
} @else if (!issueItems()?.length && searchText()?.length > 0) {
|
|
||||||
<div class="empty">No items found (already added are not shown)</div>
|
|
||||||
} @else {
|
|
||||||
<div
|
|
||||||
class="item-list"
|
|
||||||
[@standardList]="issueItems()?.length"
|
|
||||||
>
|
|
||||||
<!-- (cdkDropListDropped)="drop($event)"-->
|
|
||||||
|
|
||||||
@for (item of issueItems(); track item.issueData.id) {
|
|
||||||
<!-- <div style="display: flex; align-items: center">-->
|
|
||||||
<!-- <button-->
|
|
||||||
<!-- mat-icon-button-->
|
|
||||||
<!-- color=""-->
|
|
||||||
<!-- >-->
|
|
||||||
<!-- <mat-icon>add</mat-icon>-->
|
|
||||||
<!-- </button>-->
|
|
||||||
<issue-preview-item
|
|
||||||
[issueProviderId]="ip.id"
|
|
||||||
[itemData]="item"
|
|
||||||
(addIssue)="addIssue($event)"
|
|
||||||
></issue-preview-item>
|
|
||||||
<!-- </div>-->
|
|
||||||
}
|
}
|
||||||
</div>
|
<!---->
|
||||||
} }
|
@if (ip.issueProviderKey === 'ICAL') {
|
||||||
|
<issue-panel-calendar-agenda [issueProvider]="ip"></issue-panel-calendar-agenda>
|
||||||
|
} @else {
|
||||||
|
<form
|
||||||
|
class="example-form"
|
||||||
|
style="width: 100%; margin: 8px 0 16px"
|
||||||
|
>
|
||||||
|
<mat-form-field
|
||||||
|
style="width: 100%; margin: 0"
|
||||||
|
appearance="outline"
|
||||||
|
>
|
||||||
|
<!-- <mat-icon matPrefix>filter_alt</mat-icon>-->
|
||||||
|
<!-- <mat-label>Filter</mat-label>-->
|
||||||
|
<mat-label>Search</mat-label>
|
||||||
|
<mat-icon
|
||||||
|
matPrefix
|
||||||
|
style="opacity: 0.5"
|
||||||
|
>search</mat-icon
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
#searchTextEl
|
||||||
|
[ngModel]="searchText()"
|
||||||
|
(ngModelChange)="searchText.set($event)"
|
||||||
|
autocomplete="off"
|
||||||
|
matInput
|
||||||
|
name="search"
|
||||||
|
placeholder="Search"
|
||||||
|
/>
|
||||||
|
|
||||||
|
@if (isPinned()) {
|
||||||
|
<mat-icon
|
||||||
|
class="keep-ico"
|
||||||
|
matSuffix
|
||||||
|
svgIcon="keep_filled"
|
||||||
|
style="cursor: pointer"
|
||||||
|
(click)="unPinSearch()"
|
||||||
|
[matTooltip]="'Clear pinned search query'"
|
||||||
|
></mat-icon>
|
||||||
|
} @else if (
|
||||||
|
ip?.pinnedSearch?.length || searchText()?.length >= SEARCH_MIN_LENGTH
|
||||||
|
) {
|
||||||
|
<mat-icon
|
||||||
|
class="keep-ico"
|
||||||
|
matSuffix
|
||||||
|
svgIcon="keep"
|
||||||
|
style="cursor: pointer"
|
||||||
|
(click)="pinSearch()"
|
||||||
|
[matTooltip]="'Remember search query'"
|
||||||
|
></mat-icon>
|
||||||
|
}
|
||||||
|
<!-- -->
|
||||||
|
@if (searchText().length === 0 && issueProviderHelpLink()) {
|
||||||
|
<mat-hint
|
||||||
|
><a
|
||||||
|
[href]="issueProviderHelpLink()"
|
||||||
|
target="_blank"
|
||||||
|
>{{ ISSUE_PROVIDER_HUMANIZED[ip.issueProviderKey] }} search syntax</a
|
||||||
|
></mat-hint
|
||||||
|
>
|
||||||
|
}
|
||||||
|
<!-- @if (searchText()?.length > 0) {-->
|
||||||
|
<!-- <mat-icon-->
|
||||||
|
<!-- style="cursor: pointer"-->
|
||||||
|
<!-- matSuffix-->
|
||||||
|
<!-- (click)="searchText.set('')"-->
|
||||||
|
<!-- >close</mat-icon-->
|
||||||
|
<!-- >-->
|
||||||
|
<!-- }-->
|
||||||
|
</mat-form-field>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
<!---->
|
||||||
|
@if (isLoading()) {
|
||||||
|
<div class="spinner">
|
||||||
|
<mat-spinner diameter="50"></mat-spinner>
|
||||||
|
</div>
|
||||||
|
} @else if (error()) {
|
||||||
|
<error-card
|
||||||
|
[errorTxt]="error()"
|
||||||
|
[actionAdvice]="'Check your config!'"
|
||||||
|
></error-card>
|
||||||
|
} @else if (!issueItems()?.length && searchText()?.length > 0) {
|
||||||
|
<div class="empty">No items found (already added are not shown)</div>
|
||||||
|
} @else {
|
||||||
|
<div
|
||||||
|
class="item-list"
|
||||||
|
[@standardList]="issueItems()?.length"
|
||||||
|
>
|
||||||
|
<!-- (cdkDropListDropped)="drop($event)"-->
|
||||||
|
|
||||||
|
@for (item of issueItems(); track item.issueData.id) {
|
||||||
|
<!-- <div style="display: flex; align-items: center">-->
|
||||||
|
<!-- <button-->
|
||||||
|
<!-- mat-icon-button-->
|
||||||
|
<!-- color=""-->
|
||||||
|
<!-- >-->
|
||||||
|
<!-- <mat-icon>add</mat-icon>-->
|
||||||
|
<!-- </button>-->
|
||||||
|
<issue-preview-item
|
||||||
|
[issueProviderId]="ip.id"
|
||||||
|
[itemData]="item"
|
||||||
|
(addIssue)="addIssue($event)"
|
||||||
|
></issue-preview-item>
|
||||||
|
<!-- </div>-->
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<h1 mat-dialog-title>
|
<h1 mat-dialog-title>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
class="dialog-header-icon"
|
class="dialog-header-icon"
|
||||||
[svgIcon]="(issueProviderKey)|issueIcon"
|
[svgIcon]="issueProviderKey | issueIcon"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<!-- TODO improve title -->
|
<!-- TODO improve title -->
|
||||||
|
|
||||||
|
|
@ -20,95 +20,108 @@
|
||||||
(ngSubmit)="submit()"
|
(ngSubmit)="submit()"
|
||||||
>
|
>
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
@if (configFormSection?.help||configFormSection?.helpArr) {
|
@if (configFormSection?.help || configFormSection?.helpArr) {
|
||||||
<help-section>
|
<help-section>
|
||||||
@if (configFormSection?.help) {
|
@if (configFormSection?.help) {
|
||||||
<div [innerHtml]="configFormSection?.help|translate"></div>
|
<div [innerHtml]="configFormSection?.help | translate"></div>
|
||||||
} @if (configFormSection?.helpArr) { @for (helpSection of
|
}
|
||||||
configFormSection?.helpArr; track helpSection) { @if (helpSection.h) {
|
@if (configFormSection?.helpArr) {
|
||||||
<div class="mat-caption">{{ helpSection.h|translate }}</div>
|
@for (helpSection of configFormSection?.helpArr; track helpSection) {
|
||||||
} @if (helpSection.p) {
|
@if (helpSection.h) {
|
||||||
<p [innerHTML]="helpSection.p|translate"></p>
|
<div class="mat-caption">{{ helpSection.h | translate }}</div>
|
||||||
} @if (helpSection.p2) {
|
}
|
||||||
<p [innerHTML]="helpSection.p2|translate"></p>
|
@if (helpSection.p) {
|
||||||
} @if (helpSection.p3) {
|
<p [innerHTML]="helpSection.p | translate"></p>
|
||||||
<p [innerHTML]="helpSection.p3|translate"></p>
|
}
|
||||||
} @if (helpSection.p4) {
|
@if (helpSection.p2) {
|
||||||
<p [innerHTML]="helpSection.p4|translate"></p>
|
<p [innerHTML]="helpSection.p2 | translate"></p>
|
||||||
} } }
|
}
|
||||||
</help-section>
|
@if (helpSection.p3) {
|
||||||
} @if (isEdit) {
|
<p [innerHTML]="helpSection.p3 | translate"></p>
|
||||||
<div style="margin-bottom: 32px">
|
}
|
||||||
<mat-slide-toggle
|
@if (helpSection.p4) {
|
||||||
[ngModel]="model.isEnabled"
|
<p [innerHTML]="helpSection.p4 | translate"></p>
|
||||||
(ngModelChange)="changeEnabled($event)"
|
}
|
||||||
[ngModelOptions]="{standalone: true}"
|
}
|
||||||
>
|
}
|
||||||
{{ T.G.ENABLED|translate }}
|
</help-section>
|
||||||
</mat-slide-toggle>
|
}
|
||||||
</div>
|
@if (isEdit) {
|
||||||
|
<div style="margin-bottom: 32px">
|
||||||
|
<mat-slide-toggle
|
||||||
|
[ngModel]="model.isEnabled"
|
||||||
|
(ngModelChange)="changeEnabled($event)"
|
||||||
|
[ngModelOptions]="{ standalone: true }"
|
||||||
|
>
|
||||||
|
{{ T.G.ENABLED | translate }}
|
||||||
|
</mat-slide-toggle>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@if (model.isEnabled) {
|
@if (model.isEnabled) {
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@if (issueProviderKey === ICAL_TYPE) {
|
@if (issueProviderKey === ICAL_TYPE) {
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@if(d.calendarContextInfoTarget === 'GOOGLE'){
|
@if (d.calendarContextInfoTarget === 'GOOGLE') {
|
||||||
<div class="tpl">
|
<div class="tpl">
|
||||||
<p>
|
<p>
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
href="https://support.google.com/calendar/answer/37648?hl=en#zippy=%2Cget-your-calendar-view-only"
|
href="https://support.google.com/calendar/answer/37648?hl=en#zippy=%2Cget-your-calendar-view-only"
|
||||||
>How to get the iCal url for Google Calendar (view only)?</a
|
>How to get the iCal url for Google Calendar (view only)?</a
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
<!-- <p [innerHTML]="T.G.EXTENSION_INFO|translate"></p>-->
|
<!-- <p [innerHTML]="T.G.EXTENSION_INFO|translate"></p>-->
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@if(d.calendarContextInfoTarget === 'OUTLOOK365'){
|
@if (d.calendarContextInfoTarget === 'OUTLOOK365') {
|
||||||
<div class="tpl">
|
<div class="tpl">
|
||||||
<p>
|
<p>
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
href="https://support.pushpay.com/s/article/How-do-I-get-an-iCal-link-from-Office-365"
|
href="https://support.pushpay.com/s/article/How-do-I-get-an-iCal-link-from-Office-365"
|
||||||
>How to get the iCal url for Outlook 365 (ICS)?</a
|
>How to get the iCal url for Outlook 365 (ICS)?</a
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
<!-- <p [innerHTML]="T.G.EXTENSION_INFO|translate"></p>-->
|
<!-- <p [innerHTML]="T.G.EXTENSION_INFO|translate"></p>-->
|
||||||
</div>
|
</div>
|
||||||
} }
|
}
|
||||||
<!-- -->
|
}
|
||||||
@if (issueProviderKey === 'JIRA') {
|
<!-- -->
|
||||||
<div [ngClass]="HelperClasses.isHideForAdvancedFeatures">
|
@if (issueProviderKey === 'JIRA') {
|
||||||
<p [innerHTML]="T.G.EXTENSION_INFO|translate"></p>
|
<div [ngClass]="HelperClasses.isHideForAdvancedFeatures">
|
||||||
</div>
|
<p [innerHTML]="T.G.EXTENSION_INFO | translate"></p>
|
||||||
}
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<formly-form
|
<formly-form
|
||||||
[model]="model"
|
[model]="model"
|
||||||
(modelChange)="formlyModelChange($event)"
|
(modelChange)="formlyModelChange($event)"
|
||||||
[fields]="fields"
|
[fields]="fields"
|
||||||
[form]="form"
|
[form]="form"
|
||||||
></formly-form>
|
></formly-form>
|
||||||
|
|
||||||
@switch (issueProviderKey) {
|
@switch (issueProviderKey) {
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@case ("JIRA") {
|
@case ('JIRA') {
|
||||||
<jira-additonal-cfg
|
<jira-additonal-cfg
|
||||||
[section]="configFormSection"
|
[section]="configFormSection"
|
||||||
[cfg]="model"
|
[cfg]="model"
|
||||||
(modelChange)="customCfgCmpSave($event)"
|
(modelChange)="customCfgCmpSave($event)"
|
||||||
></jira-additonal-cfg>
|
></jira-additonal-cfg>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
} @case ("OPEN_PROJECT") {
|
}
|
||||||
<open-project-additional-cfg
|
@case ('OPEN_PROJECT') {
|
||||||
[section]="configFormSection"
|
<open-project-additional-cfg
|
||||||
[cfg]="model"
|
[section]="configFormSection"
|
||||||
(modelChange)="customCfgCmpSave($event)"
|
[cfg]="model"
|
||||||
></open-project-additional-cfg>
|
(modelChange)="customCfgCmpSave($event)"
|
||||||
<!-- -->
|
></open-project-additional-cfg>
|
||||||
} } }
|
<!-- -->
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</mat-dialog-content>
|
</mat-dialog-content>
|
||||||
|
|
||||||
<mat-dialog-actions align="end">
|
<mat-dialog-actions align="end">
|
||||||
|
|
@ -118,39 +131,39 @@
|
||||||
mat-button
|
mat-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
{{ T.G.CANCEL|translate }}
|
{{ T.G.CANCEL | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@if (isEdit) {
|
@if (isEdit) {
|
||||||
<button
|
<button
|
||||||
(click)="remove()"
|
(click)="remove()"
|
||||||
color="warn"
|
color="warn"
|
||||||
mat-button
|
mat-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<mat-icon>delete_forever</mat-icon>
|
<mat-icon>delete_forever</mat-icon>
|
||||||
{{ T.G.DELETE|translate }}
|
{{ T.G.DELETE | translate }}
|
||||||
</button>
|
</button>
|
||||||
} @else {
|
} @else {
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@if (isConnectionWorks()) {
|
@if (isConnectionWorks()) {
|
||||||
<div class="success-info">
|
<div class="success-info">
|
||||||
<mat-icon>check</mat-icon>
|
<mat-icon>check</mat-icon>
|
||||||
</div>
|
</div>
|
||||||
} @else {
|
} @else {
|
||||||
<button
|
<button
|
||||||
(click)="testConnection()"
|
(click)="testConnection()"
|
||||||
mat-button
|
mat-button
|
||||||
color="primary"
|
color="primary"
|
||||||
type="button"
|
type="button"
|
||||||
[disabled]="form.invalid"
|
[disabled]="form.invalid"
|
||||||
>
|
>
|
||||||
<mat-icon>online_prediction</mat-icon>
|
<mat-icon>online_prediction</mat-icon>
|
||||||
Test
|
Test
|
||||||
<!-- {{ T.G.DELETE|translate }}-->
|
<!-- {{ T.G.DELETE|translate }}-->
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
<!-- -->
|
<!-- -->
|
||||||
}
|
}
|
||||||
<button
|
<button
|
||||||
color="primary"
|
color="primary"
|
||||||
|
|
@ -159,7 +172,7 @@
|
||||||
[disabled]="form.invalid"
|
[disabled]="form.invalid"
|
||||||
>
|
>
|
||||||
<mat-icon>save</mat-icon>
|
<mat-icon>save</mat-icon>
|
||||||
{{ T.G.SAVE|translate }}
|
{{ T.G.SAVE | translate }}
|
||||||
</button>
|
</button>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,42 @@
|
||||||
@if (task?.issueType===JIRA_TYPE) {
|
@if (task?.issueType === JIRA_TYPE) {
|
||||||
<jira-issue-content
|
<jira-issue-content
|
||||||
[issue]="issueData()"
|
[issue]="issueData()"
|
||||||
[task]="task"
|
[task]="task"
|
||||||
></jira-issue-content>
|
></jira-issue-content>
|
||||||
} @if (task?.issueType===GITHUB_TYPE) {
|
}
|
||||||
<github-issue-content
|
@if (task?.issueType === GITHUB_TYPE) {
|
||||||
[issue]="issueData()"
|
<github-issue-content
|
||||||
[task]="task"
|
[issue]="issueData()"
|
||||||
></github-issue-content>
|
[task]="task"
|
||||||
} @if (task?.issueType===REDMINE_TYPE) {
|
></github-issue-content>
|
||||||
<redmine-issue-content
|
}
|
||||||
[issue]="issueData()"
|
@if (task?.issueType === REDMINE_TYPE) {
|
||||||
[task]="task"
|
<redmine-issue-content
|
||||||
></redmine-issue-content>
|
[issue]="issueData()"
|
||||||
} @if (task?.issueType===GITLAB_TYPE) {
|
[task]="task"
|
||||||
<gitlab-issue-content
|
></redmine-issue-content>
|
||||||
[issue]="issueData()"
|
}
|
||||||
[task]="task"
|
@if (task?.issueType === GITLAB_TYPE) {
|
||||||
></gitlab-issue-content>
|
<gitlab-issue-content
|
||||||
} @if (task?.issueType===CALDAV_TYPE) {
|
[issue]="issueData()"
|
||||||
<caldav-issue-content
|
[task]="task"
|
||||||
[issue]="issueData()"
|
></gitlab-issue-content>
|
||||||
[task]="task"
|
}
|
||||||
></caldav-issue-content>
|
@if (task?.issueType === CALDAV_TYPE) {
|
||||||
} @if (task?.issueType===OPEN_PROJECT_TYPE) {
|
<caldav-issue-content
|
||||||
<open-project-issue-content
|
[issue]="issueData()"
|
||||||
[issue]="issueData()"
|
[task]="task"
|
||||||
[task]="task"
|
></caldav-issue-content>
|
||||||
></open-project-issue-content>
|
}
|
||||||
} @if (task?.issueType===GITEA_TYPE) {
|
@if (task?.issueType === OPEN_PROJECT_TYPE) {
|
||||||
<gitea-issue-content
|
<open-project-issue-content
|
||||||
[issue]="issueData()"
|
[issue]="issueData()"
|
||||||
[task]="task"
|
[task]="task"
|
||||||
></gitea-issue-content>
|
></open-project-issue-content>
|
||||||
|
}
|
||||||
|
@if (task?.issueType === GITEA_TYPE) {
|
||||||
|
<gitea-issue-content
|
||||||
|
[issue]="issueData()"
|
||||||
|
[task]="task"
|
||||||
|
></gitea-issue-content>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,21 @@
|
||||||
@if (task?.issueType === JIRA_TYPE) {
|
@if (task?.issueType === JIRA_TYPE) {
|
||||||
<jira-issue-header [task]="task"></jira-issue-header>
|
<jira-issue-header [task]="task"></jira-issue-header>
|
||||||
} @if (task?.issueType === GITHUB_TYPE) {
|
}
|
||||||
<github-issue-header [task]="task"></github-issue-header>
|
@if (task?.issueType === GITHUB_TYPE) {
|
||||||
} @if (task?.issueType === REDMINE_TYPE) {
|
<github-issue-header [task]="task"></github-issue-header>
|
||||||
<redmine-issue-header [task]="task"></redmine-issue-header>
|
}
|
||||||
} @if (task?.issueType === GITLAB_TYPE) {
|
@if (task?.issueType === REDMINE_TYPE) {
|
||||||
<gitlab-issue-header [task]="task"></gitlab-issue-header>
|
<redmine-issue-header [task]="task"></redmine-issue-header>
|
||||||
} @if (task?.issueType === CALDAV_TYPE) {
|
}
|
||||||
<caldav-issue-header [task]="task"></caldav-issue-header>
|
@if (task?.issueType === GITLAB_TYPE) {
|
||||||
} @if (task?.issueType === OPEN_PROJECT_TYPE) {
|
<gitlab-issue-header [task]="task"></gitlab-issue-header>
|
||||||
<open-project-issue-header [task]="task"></open-project-issue-header>
|
}
|
||||||
} @if (task?.issueType === GITEA_TYPE) {
|
@if (task?.issueType === CALDAV_TYPE) {
|
||||||
<gitea-issue-header [task]="task"></gitea-issue-header>
|
<caldav-issue-header [task]="task"></caldav-issue-header>
|
||||||
|
}
|
||||||
|
@if (task?.issueType === OPEN_PROJECT_TYPE) {
|
||||||
|
<open-project-issue-header [task]="task"></open-project-issue-header>
|
||||||
|
}
|
||||||
|
@if (task?.issueType === GITEA_TYPE) {
|
||||||
|
<gitea-issue-header [task]="task"></gitea-issue-header>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,51 +1,54 @@
|
||||||
<ng-container>
|
<ng-container>
|
||||||
@if (task()?.issueWasUpdated) {
|
@if (task()?.issueWasUpdated) {
|
||||||
<div
|
<div
|
||||||
@expand
|
@expand
|
||||||
style="text-align: center"
|
style="text-align: center"
|
||||||
>
|
|
||||||
<button
|
|
||||||
(click)="hideUpdates()"
|
|
||||||
color="accent"
|
|
||||||
mat-raised-button
|
|
||||||
>
|
>
|
||||||
{{T.F.CALDAV.ISSUE_CONTENT.MARK_AS_CHECKED|translate}}
|
<button
|
||||||
</button>
|
(click)="hideUpdates()"
|
||||||
</div>
|
color="accent"
|
||||||
|
mat-raised-button
|
||||||
|
>
|
||||||
|
{{ T.F.CALDAV.ISSUE_CONTENT.MARK_AS_CHECKED | translate }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper">
|
||||||
<table class="issue-table">
|
<table class="issue-table">
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.CALDAV.ISSUE_CONTENT.SUMMARY|translate}}</th>
|
<th>{{ T.F.CALDAV.ISSUE_CONTENT.SUMMARY | translate }}</th>
|
||||||
<td><strong>{{issue?.summary}}</strong></td>
|
<td>
|
||||||
|
<strong>{{ issue?.summary }}</strong>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.CALDAV.ISSUE_CONTENT.STATUS|translate}}</th>
|
<th>{{ T.F.CALDAV.ISSUE_CONTENT.STATUS | translate }}</th>
|
||||||
<td>{{issue?.completed}}</td>
|
<td>{{ issue?.completed }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@if (issue?.labels?.length) {
|
@if (issue?.labels?.length) {
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.CALDAV.ISSUE_CONTENT.LABELS|translate}}</th>
|
<th>{{ T.F.CALDAV.ISSUE_CONTENT.LABELS | translate }}</th>
|
||||||
<td>
|
<td>
|
||||||
<mat-chip-listbox>
|
<mat-chip-listbox>
|
||||||
@for (label of issue?.labels; track label) {
|
@for (label of issue?.labels; track label) {
|
||||||
<mat-chip-option [title]="label">{{label}} </mat-chip-option>
|
<mat-chip-option [title]="label">{{ label }} </mat-chip-option>
|
||||||
}
|
}
|
||||||
</mat-chip-listbox>
|
</mat-chip-listbox>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
} @if (issue?.note) {
|
}
|
||||||
<tr>
|
@if (issue?.note) {
|
||||||
<th>{{T.F.CALDAV.ISSUE_CONTENT.DESCRIPTION|translate}}</th>
|
<tr>
|
||||||
<td class="issue-description">
|
<th>{{ T.F.CALDAV.ISSUE_CONTENT.DESCRIPTION | translate }}</th>
|
||||||
<div
|
<td class="issue-description">
|
||||||
[data]="issue?.note"
|
<div
|
||||||
class="description markdown"
|
[data]="issue?.note"
|
||||||
markdown
|
class="description markdown"
|
||||||
></div>
|
markdown
|
||||||
</td>
|
></div>
|
||||||
</tr>
|
</td>
|
||||||
|
</tr>
|
||||||
}
|
}
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
@if (task()?.issueWasUpdated) {
|
@if (task()?.issueWasUpdated) {
|
||||||
<mat-icon
|
<mat-icon
|
||||||
color="accent"
|
color="accent"
|
||||||
style="margin-right: 8px"
|
style="margin-right: 8px"
|
||||||
>update
|
>update
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
} @if (!task()?.issueWasUpdated) {
|
}
|
||||||
<mat-icon
|
@if (!task()?.issueWasUpdated) {
|
||||||
style="margin-right: 8px"
|
<mat-icon
|
||||||
svgIcon="caldav"
|
style="margin-right: 8px"
|
||||||
>
|
svgIcon="caldav"
|
||||||
</mat-icon>
|
>
|
||||||
|
</mat-icon>
|
||||||
}
|
}
|
||||||
<span class="tab-label-text">Caldav</span>
|
<span class="tab-label-text">Caldav</span>
|
||||||
|
|
|
||||||
|
|
@ -1,72 +1,74 @@
|
||||||
<ng-container>
|
<ng-container>
|
||||||
@if (task()?.issueWasUpdated) {
|
@if (task()?.issueWasUpdated) {
|
||||||
<div
|
<div
|
||||||
@expand
|
@expand
|
||||||
style="text-align: center"
|
style="text-align: center"
|
||||||
>
|
|
||||||
<button
|
|
||||||
(click)="hideUpdates()"
|
|
||||||
color="accent"
|
|
||||||
mat-raised-button
|
|
||||||
>
|
>
|
||||||
{{T.F.GITEA.ISSUE_CONTENT.MARK_AS_CHECKED|translate}}
|
<button
|
||||||
</button>
|
(click)="hideUpdates()"
|
||||||
</div>
|
color="accent"
|
||||||
|
mat-raised-button
|
||||||
|
>
|
||||||
|
{{ T.F.GITEA.ISSUE_CONTENT.MARK_AS_CHECKED | translate }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper">
|
||||||
<table class="issue-table">
|
<table class="issue-table">
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.GITEA.ISSUE_CONTENT.SUMMARY|translate}}</th>
|
<th>{{ T.F.GITEA.ISSUE_CONTENT.SUMMARY | translate }}</th>
|
||||||
<td>
|
<td>
|
||||||
<a
|
<a
|
||||||
[href]="issue?.html_url"
|
[href]="issue?.html_url"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
><strong>{{issue?.title}} #{{issue?.number}}</strong></a
|
><strong>{{ issue?.title }} #{{ issue?.number }}</strong></a
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.GITEA.ISSUE_CONTENT.PROJECT|translate}}</th>
|
<th>{{ T.F.GITEA.ISSUE_CONTENT.PROJECT | translate }}</th>
|
||||||
<td>{{issue?.repository.name}}</td>
|
<td>{{ issue?.repository.name }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.GITEA.ISSUE_CONTENT.STATUS|translate}}</th>
|
<th>{{ T.F.GITEA.ISSUE_CONTENT.STATUS | translate }}</th>
|
||||||
<td>{{issue?.state}}</td>
|
<td>{{ issue?.state }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@if (issue?.assignee?.web_url) {
|
@if (issue?.assignee?.web_url) {
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.GITEA.ISSUE_CONTENT.ASSIGNEE|translate}}</th>
|
<th>{{ T.F.GITEA.ISSUE_CONTENT.ASSIGNEE | translate }}</th>
|
||||||
<td>
|
<td>
|
||||||
<a
|
<a
|
||||||
[href]="issue?.assignee?.web_url"
|
[href]="issue?.assignee?.web_url"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>{{issue?.assignee?.username}}</a
|
>{{ issue?.assignee?.username }}</a
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
} @if (issue?.labels?.length) {
|
}
|
||||||
<tr>
|
@if (issue?.labels?.length) {
|
||||||
<th>{{T.F.GITEA.ISSUE_CONTENT.LABELS|translate}}</th>
|
<tr>
|
||||||
<td>
|
<th>{{ T.F.GITEA.ISSUE_CONTENT.LABELS | translate }}</th>
|
||||||
<mat-chip-listbox>
|
<td>
|
||||||
@for (label of issue?.labels; track label) {
|
<mat-chip-listbox>
|
||||||
<mat-chip-option [title]="label.name">{{label.name}} </mat-chip-option>
|
@for (label of issue?.labels; track label) {
|
||||||
}
|
<mat-chip-option [title]="label.name">{{ label.name }} </mat-chip-option>
|
||||||
</mat-chip-listbox>
|
}
|
||||||
</td>
|
</mat-chip-listbox>
|
||||||
</tr>
|
</td>
|
||||||
} @if (issue?.body) {
|
</tr>
|
||||||
<tr>
|
}
|
||||||
<th>{{T.F.GITEA.ISSUE_CONTENT.DESCRIPTION|translate}}</th>
|
@if (issue?.body) {
|
||||||
<td class="issue-description">
|
<tr>
|
||||||
<div
|
<th>{{ T.F.GITEA.ISSUE_CONTENT.DESCRIPTION | translate }}</th>
|
||||||
[data]="issue?.body"
|
<td class="issue-description">
|
||||||
class="description markdown"
|
<div
|
||||||
markdown
|
[data]="issue?.body"
|
||||||
></div>
|
class="description markdown"
|
||||||
</td>
|
markdown
|
||||||
</tr>
|
></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
}
|
}
|
||||||
</table>
|
</table>
|
||||||
<div style="text-align: center">
|
<div style="text-align: center">
|
||||||
|
|
@ -78,7 +80,7 @@
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<mat-icon>textsms</mat-icon>
|
<mat-icon>textsms</mat-icon>
|
||||||
{{T.F.GITEA.ISSUE_CONTENT.WRITE_A_COMMENT|translate}}
|
{{ T.F.GITEA.ISSUE_CONTENT.WRITE_A_COMMENT | translate }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
@if (task()?.issueWasUpdated) {
|
@if (task()?.issueWasUpdated) {
|
||||||
<mat-icon
|
<mat-icon
|
||||||
color="accent"
|
color="accent"
|
||||||
style="margin-right: 8px"
|
style="margin-right: 8px"
|
||||||
>update
|
>update
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
} @if (!task()?.issueWasUpdated) {
|
}
|
||||||
<mat-icon
|
@if (!task()?.issueWasUpdated) {
|
||||||
style="margin-right: 8px"
|
<mat-icon
|
||||||
svgIcon="gitea"
|
style="margin-right: 8px"
|
||||||
>
|
svgIcon="gitea"
|
||||||
</mat-icon>
|
>
|
||||||
|
</mat-icon>
|
||||||
}
|
}
|
||||||
<span class="tab-label-text">Gitea</span>
|
<span class="tab-label-text">Gitea</span>
|
||||||
|
|
|
||||||
|
|
@ -1,156 +1,172 @@
|
||||||
<ng-container>
|
<ng-container>
|
||||||
@if (task()?.issueWasUpdated) {
|
@if (task()?.issueWasUpdated) {
|
||||||
<div
|
<div
|
||||||
@expand
|
@expand
|
||||||
style="text-align: center"
|
style="text-align: center"
|
||||||
>
|
|
||||||
<button
|
|
||||||
(click)="hideUpdates()"
|
|
||||||
color="accent"
|
|
||||||
mat-raised-button
|
|
||||||
>
|
>
|
||||||
{{T.F.GITHUB.ISSUE_CONTENT.MARK_AS_CHECKED|translate}}
|
<button
|
||||||
</button>
|
(click)="hideUpdates()"
|
||||||
</div>
|
color="accent"
|
||||||
|
mat-raised-button
|
||||||
|
>
|
||||||
|
{{ T.F.GITHUB.ISSUE_CONTENT.MARK_AS_CHECKED | translate }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper">
|
||||||
<table class="issue-table">
|
<table class="issue-table">
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.GITHUB.ISSUE_CONTENT.SUMMARY|translate}}</th>
|
<th>{{ T.F.GITHUB.ISSUE_CONTENT.SUMMARY | translate }}</th>
|
||||||
<td>
|
<td>
|
||||||
<a
|
<a
|
||||||
[href]="issue?.html_url"
|
[href]="issue?.html_url"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
><strong>{{issue?.title}} #{{issue?.number}}</strong></a
|
><strong>{{ issue?.title }} #{{ issue?.number }}</strong></a
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.GITHUB.ISSUE_CONTENT.STATUS|translate}}</th>
|
<th>{{ T.F.GITHUB.ISSUE_CONTENT.STATUS | translate }}</th>
|
||||||
<td>{{issue?.state}}</td>
|
<td>{{ issue?.state }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@if (issue?.assignee?.html_url) {
|
@if (issue?.assignee?.html_url) {
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.GITHUB.ISSUE_CONTENT.ASSIGNEE|translate}}</th>
|
<th>{{ T.F.GITHUB.ISSUE_CONTENT.ASSIGNEE | translate }}</th>
|
||||||
<td>
|
<td>
|
||||||
<a
|
<a
|
||||||
[href]="issue?.assignee?.html_url"
|
[href]="issue?.assignee?.html_url"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>{{issue?.assignee?.login}}</a
|
>{{ issue?.assignee?.login }}</a
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
} @if (issue?.labels?.length) {
|
}
|
||||||
<tr>
|
@if (issue?.labels?.length) {
|
||||||
<th>{{T.F.GITHUB.ISSUE_CONTENT.LABELS|translate}}</th>
|
<tr>
|
||||||
<td>
|
<th>{{ T.F.GITHUB.ISSUE_CONTENT.LABELS | translate }}</th>
|
||||||
<mat-chip-listbox>
|
<td>
|
||||||
@for (label of issue?.labels; track trackByIndex($index, label)) {
|
<mat-chip-listbox>
|
||||||
<mat-chip-option [title]="label.description">{{label.name}} </mat-chip-option>
|
@for (label of issue?.labels; track trackByIndex($index, label)) {
|
||||||
}
|
<mat-chip-option [title]="label.description"
|
||||||
</mat-chip-listbox>
|
>{{ label.name }}
|
||||||
</td>
|
</mat-chip-option>
|
||||||
</tr>
|
}
|
||||||
} @if (issue?.body && !isCollapsedIssueSummary()) {
|
</mat-chip-listbox>
|
||||||
<tr>
|
</td>
|
||||||
<th>{{T.F.GITHUB.ISSUE_CONTENT.DESCRIPTION|translate}}</th>
|
</tr>
|
||||||
<td class="issue-description">
|
}
|
||||||
<div
|
@if (issue?.body && !isCollapsedIssueSummary()) {
|
||||||
[data]="issue?.body"
|
<tr>
|
||||||
class="description markdown"
|
<th>{{ T.F.GITHUB.ISSUE_CONTENT.DESCRIPTION | translate }}</th>
|
||||||
markdown
|
<td class="issue-description">
|
||||||
></div>
|
<div
|
||||||
</td>
|
[data]="issue?.body"
|
||||||
</tr>
|
class="description markdown"
|
||||||
|
markdown
|
||||||
|
></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
}
|
}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
@if (issue?.comments?.length) {
|
@if (issue?.comments?.length) {
|
||||||
<div>
|
<div>
|
||||||
@if (isCollapsedIssueComments()) {
|
@if (isCollapsedIssueComments()) {
|
||||||
<div style="text-align: center">
|
<div style="text-align: center">
|
||||||
<button
|
<button
|
||||||
mat-stroked-button
|
mat-stroked-button
|
||||||
class="load-comments-and-all-data"
|
class="load-comments-and-all-data"
|
||||||
(click)="isForceShowDescription=true; isForceShowAllComments= true"
|
(click)="isForceShowDescription = true; isForceShowAllComments = true"
|
||||||
>
|
|
||||||
<mat-icon>download</mat-icon>
|
|
||||||
@if (isCollapsedIssueSummary()) {
|
|
||||||
<span style="text-overflow: ellipsis; overflow: hidden; white-space: nowrap"
|
|
||||||
>{{T.F.GITHUB.ISSUE_CONTENT.LOAD_DESCRIPTION_AND_ALL_COMMENTS|translate}}</span
|
|
||||||
>
|
|
||||||
} @if (!isCollapsedIssueSummary()) {
|
|
||||||
{{T.F.GITHUB.ISSUE_CONTENT.LOAD_ALL_COMMENTS|translate:{ nr:
|
|
||||||
issue?.comments?.length } }} }
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<h3 class="last-comment-headline">
|
|
||||||
{{T.F.GITHUB.ISSUE_CONTENT.LAST_COMMENT|translate}}
|
|
||||||
</h3>
|
|
||||||
<div class="comment isLastComment">
|
|
||||||
<!--<img [src]="comment.author.avatarUrl"-->
|
|
||||||
<!--class="author-avatar">-->
|
|
||||||
<div class="name-and-comment-content">
|
|
||||||
<div>
|
|
||||||
<span class="author-name">{{lastComment().user?.login}}</span>
|
|
||||||
<span class="when"
|
|
||||||
>{{T.F.GITHUB.ISSUE_CONTENT.AT|translate}}
|
|
||||||
{{lastComment().created_at|date:'short'}}</span
|
|
||||||
>
|
>
|
||||||
|
<mat-icon>download</mat-icon>
|
||||||
|
@if (isCollapsedIssueSummary()) {
|
||||||
|
<span
|
||||||
|
style="text-overflow: ellipsis; overflow: hidden; white-space: nowrap"
|
||||||
|
>{{
|
||||||
|
T.F.GITHUB.ISSUE_CONTENT.LOAD_DESCRIPTION_AND_ALL_COMMENTS | translate
|
||||||
|
}}</span
|
||||||
|
>
|
||||||
|
}
|
||||||
|
@if (!isCollapsedIssueSummary()) {
|
||||||
|
{{
|
||||||
|
T.F.GITHUB.ISSUE_CONTENT.LOAD_ALL_COMMENTS
|
||||||
|
| translate: { nr: issue?.comments?.length }
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@if (lastComment().body) {
|
<h3 class="last-comment-headline">
|
||||||
<div
|
{{ T.F.GITHUB.ISSUE_CONTENT.LAST_COMMENT | translate }}
|
||||||
[innerHTML]="lastComment().body|markdown|async"
|
</h3>
|
||||||
class="markdown"
|
<div class="comment isLastComment">
|
||||||
></div>
|
<!--<img [src]="comment.author.avatarUrl"-->
|
||||||
}
|
<!--class="author-avatar">-->
|
||||||
</div>
|
<div class="name-and-comment-content">
|
||||||
</div>
|
<div>
|
||||||
} @if (!isCollapsedIssueComments()) { @for (comment of
|
<span class="author-name">{{ lastComment().user?.login }}</span>
|
||||||
(issue?.comments|sort:'created_at'); track trackByIndex($index, comment)) {
|
<span class="when"
|
||||||
<div class="comment">
|
>{{ T.F.GITHUB.ISSUE_CONTENT.AT | translate }}
|
||||||
<!--<img [src]="comment.author.avatarUrl"-->
|
{{ lastComment().created_at | date: 'short' }}</span
|
||||||
<!--class="author-avatar">-->
|
>
|
||||||
<div class="name-and-comment-content">
|
</div>
|
||||||
<div>
|
@if (lastComment().body) {
|
||||||
<span class="author-name">{{comment.user?.login}}</span>
|
<div
|
||||||
<span class="when"
|
[innerHTML]="lastComment().body | markdown | async"
|
||||||
>{{T.F.GITHUB.ISSUE_CONTENT.AT|translate}}
|
class="markdown"
|
||||||
{{comment.created_at|date:'short'}}</span
|
></div>
|
||||||
>
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@if (comment.body) {
|
}
|
||||||
<div
|
@if (!isCollapsedIssueComments()) {
|
||||||
[innerHTML]="comment?.body|markdown|async"
|
@for (
|
||||||
class="markdown"
|
comment of issue?.comments | sort: 'created_at';
|
||||||
></div>
|
track trackByIndex($index, comment)
|
||||||
|
) {
|
||||||
|
<div class="comment">
|
||||||
|
<!--<img [src]="comment.author.avatarUrl"-->
|
||||||
|
<!--class="author-avatar">-->
|
||||||
|
<div class="name-and-comment-content">
|
||||||
|
<div>
|
||||||
|
<span class="author-name">{{ comment.user?.login }}</span>
|
||||||
|
<span class="when"
|
||||||
|
>{{ T.F.GITHUB.ISSUE_CONTENT.AT | translate }}
|
||||||
|
{{ comment.created_at | date: 'short' }}</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
@if (comment.body) {
|
||||||
|
<div
|
||||||
|
[innerHTML]="comment?.body | markdown | async"
|
||||||
|
class="markdown"
|
||||||
|
></div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
}
|
||||||
|
<!-- <div-->
|
||||||
|
<!-- *ngFor="let comment of (issue?.comments|sort:'created_at'); trackBy: trackByIndex"-->
|
||||||
|
<!-- class="comment"-->
|
||||||
|
<!-- >-->
|
||||||
|
<!-- <!–<img [src]="comment.author.avatarUrl"–>-->
|
||||||
|
<!-- <!–class="author-avatar">–>-->
|
||||||
|
<!-- <div class="name-and-comment-content">-->
|
||||||
|
<!-- <div>-->
|
||||||
|
<!-- <span class="author-name">{{comment.user?.login}}</span>-->
|
||||||
|
<!-- <span class="when"-->
|
||||||
|
<!-- >{{T.F.GITHUB.ISSUE_CONTENT.AT|translate}}-->
|
||||||
|
<!-- {{comment.created_at|date:'short'}}</span-->
|
||||||
|
<!-- >-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- <div-->
|
||||||
|
<!-- *ngIf="comment.body"-->
|
||||||
|
<!-- [innerHTML]="comment?.body|markdown"-->
|
||||||
|
<!-- class="markdown"-->
|
||||||
|
<!-- ></div>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </div>-->
|
||||||
</div>
|
</div>
|
||||||
} }
|
|
||||||
<!-- <div-->
|
|
||||||
<!-- *ngFor="let comment of (issue?.comments|sort:'created_at'); trackBy: trackByIndex"-->
|
|
||||||
<!-- class="comment"-->
|
|
||||||
<!-- >-->
|
|
||||||
<!-- <!–<img [src]="comment.author.avatarUrl"–>-->
|
|
||||||
<!-- <!–class="author-avatar">–>-->
|
|
||||||
<!-- <div class="name-and-comment-content">-->
|
|
||||||
<!-- <div>-->
|
|
||||||
<!-- <span class="author-name">{{comment.user?.login}}</span>-->
|
|
||||||
<!-- <span class="when"-->
|
|
||||||
<!-- >{{T.F.GITHUB.ISSUE_CONTENT.AT|translate}}-->
|
|
||||||
<!-- {{comment.created_at|date:'short'}}</span-->
|
|
||||||
<!-- >-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- <div-->
|
|
||||||
<!-- *ngIf="comment.body"-->
|
|
||||||
<!-- [innerHTML]="comment?.body|markdown"-->
|
|
||||||
<!-- class="markdown"-->
|
|
||||||
<!-- ></div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<div style="text-align: center">
|
<div style="text-align: center">
|
||||||
|
|
@ -162,7 +178,7 @@
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<mat-icon>textsms</mat-icon>
|
<mat-icon>textsms</mat-icon>
|
||||||
{{T.F.GITHUB.ISSUE_CONTENT.WRITE_A_COMMENT|translate}}
|
{{ T.F.GITHUB.ISSUE_CONTENT.WRITE_A_COMMENT | translate }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<!--<pre><code>-->
|
<!--<pre><code>-->
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
@if (task()?.issueWasUpdated) {
|
@if (task()?.issueWasUpdated) {
|
||||||
<mat-icon
|
<mat-icon
|
||||||
color="accent"
|
color="accent"
|
||||||
style="margin-right: 8px"
|
style="margin-right: 8px"
|
||||||
>update
|
>update
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
} @if (!task()?.issueWasUpdated) {
|
}
|
||||||
<mat-icon
|
@if (!task()?.issueWasUpdated) {
|
||||||
style="margin-right: 8px"
|
<mat-icon
|
||||||
svgIcon="github"
|
style="margin-right: 8px"
|
||||||
>
|
svgIcon="github"
|
||||||
</mat-icon>
|
>
|
||||||
|
</mat-icon>
|
||||||
}
|
}
|
||||||
<span class="tab-label-text">Github</span>
|
<span class="tab-label-text">Github</span>
|
||||||
|
|
|
||||||
|
|
@ -3,26 +3,28 @@
|
||||||
class="dialog-header-icon"
|
class="dialog-header-icon"
|
||||||
svgIcon="gitlab"
|
svgIcon="gitlab"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<span>{{ T.F.GITLAB.DIALOG_SUBMIT_WORKLOG.TITLE|translate }}</span>
|
<span>{{ T.F.GITLAB.DIALOG_SUBMIT_WORKLOG.TITLE | translate }}</span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
@if (isLoading) {
|
@if (isLoading) {
|
||||||
<div class="loading-wrapper">
|
<div class="loading-wrapper">
|
||||||
<mat-progress-spinner
|
<mat-progress-spinner
|
||||||
class="example-margin"
|
class="example-margin"
|
||||||
[color]="'primary'"
|
[color]="'primary'"
|
||||||
[mode]="'indeterminate'"
|
[mode]="'indeterminate'"
|
||||||
>
|
>
|
||||||
</mat-progress-spinner>
|
</mat-progress-spinner>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<h3>For gitlab project: <strong>{{ (issueProviderCfg$|async)?.project }}</strong></h3>
|
<h3>
|
||||||
|
For gitlab project: <strong>{{ (issueProviderCfg$ | async)?.project }}</strong>
|
||||||
|
</h3>
|
||||||
|
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper">
|
||||||
<table
|
<table
|
||||||
[dataSource]="tmpTasks$|async"
|
[dataSource]="tmpTasks$ | async"
|
||||||
class="summary-table"
|
class="summary-table"
|
||||||
mat-table
|
mat-table
|
||||||
>
|
>
|
||||||
|
|
@ -31,7 +33,7 @@
|
||||||
*matHeaderCellDef
|
*matHeaderCellDef
|
||||||
mat-header-cell
|
mat-header-cell
|
||||||
>
|
>
|
||||||
{{ T.F.GITLAB.DIALOG_SUBMIT_WORKLOG.T_TITLE|translate }} Title
|
{{ T.F.GITLAB.DIALOG_SUBMIT_WORKLOG.T_TITLE | translate }} Title
|
||||||
</th>
|
</th>
|
||||||
<td
|
<td
|
||||||
*matCellDef="let tmpTask"
|
*matCellDef="let tmpTask"
|
||||||
|
|
@ -46,13 +48,13 @@
|
||||||
*matHeaderCellDef
|
*matHeaderCellDef
|
||||||
mat-header-cell
|
mat-header-cell
|
||||||
>
|
>
|
||||||
{{ T.F.GITLAB.DIALOG_SUBMIT_WORKLOG.T_ALREADY_TRACKED|translate }}
|
{{ T.F.GITLAB.DIALOG_SUBMIT_WORKLOG.T_ALREADY_TRACKED | translate }}
|
||||||
</th>
|
</th>
|
||||||
<td
|
<td
|
||||||
*matCellDef="let tmpTask"
|
*matCellDef="let tmpTask"
|
||||||
mat-cell
|
mat-cell
|
||||||
>
|
>
|
||||||
{{ tmpTask.timeTrackedAlreadyRemote|msToClockString }}
|
{{ tmpTask.timeTrackedAlreadyRemote | msToClockString }}
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
|
@ -61,22 +63,22 @@
|
||||||
*matHeaderCellDef
|
*matHeaderCellDef
|
||||||
mat-header-cell
|
mat-header-cell
|
||||||
>
|
>
|
||||||
{{ T.F.GITLAB.DIALOG_SUBMIT_WORKLOG.T_TO_BE_SUBMITTED|translate }}
|
{{ T.F.GITLAB.DIALOG_SUBMIT_WORKLOG.T_TO_BE_SUBMITTED | translate }}
|
||||||
</th>
|
</th>
|
||||||
<td
|
<td
|
||||||
*matCellDef="let tmpTask"
|
*matCellDef="let tmpTask"
|
||||||
mat-cell
|
mat-cell
|
||||||
>
|
>
|
||||||
@if (tmpTask.isPastTrackedData) {
|
@if (tmpTask.isPastTrackedData) {
|
||||||
<span
|
<span
|
||||||
class="past-info-ico"
|
class="past-info-ico"
|
||||||
[matTooltip]="T.F.GITLAB.DIALOG_SUBMIT_WORKLOG.PAST_DAY_INFO|translate"
|
[matTooltip]="T.F.GITLAB.DIALOG_SUBMIT_WORKLOG.PAST_DAY_INFO | translate"
|
||||||
>!!!</span
|
>!!!</span
|
||||||
>
|
>
|
||||||
}
|
}
|
||||||
<inline-input
|
<inline-input
|
||||||
(changed)="updateTimeSpentTodayForTask(tmpTask, $event)"
|
(changed)="updateTimeSpentTodayForTask(tmpTask, $event)"
|
||||||
[displayValue]="tmpTask.timeToSubmit|msToClockString"
|
[displayValue]="tmpTask.timeToSubmit | msToClockString"
|
||||||
[type]="'duration'"
|
[type]="'duration'"
|
||||||
[value]="tmpTask.timeToSubmit"
|
[value]="tmpTask.timeToSubmit"
|
||||||
>
|
>
|
||||||
|
|
@ -85,11 +87,14 @@
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<tr
|
<tr
|
||||||
*matHeaderRowDef="['title', 'timeTrackedAlreadyRemote','timeToSubmit']"
|
*matHeaderRowDef="['title', 'timeTrackedAlreadyRemote', 'timeToSubmit']"
|
||||||
mat-header-row
|
mat-header-row
|
||||||
></tr>
|
></tr>
|
||||||
<tr
|
<tr
|
||||||
*matRowDef="let row; columns: ['title','timeTrackedAlreadyRemote','timeToSubmit']"
|
*matRowDef="
|
||||||
|
let row;
|
||||||
|
columns: ['title', 'timeTrackedAlreadyRemote', 'timeToSubmit']
|
||||||
|
"
|
||||||
mat-row
|
mat-row
|
||||||
></tr>
|
></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
@ -97,8 +102,14 @@
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="total-msg"
|
class="total-msg"
|
||||||
[innerHTML]="T.F.GITLAB.DIALOG_SUBMIT_WORKLOG.TOTAL_MSG|translate:{totalTimeToSubmit: totalTimeToSubmit$|async|msToString,
|
[innerHTML]="
|
||||||
nrOfTasksToSubmit: (tmpTasksToTrack$|async)?.length}"
|
T.F.GITLAB.DIALOG_SUBMIT_WORKLOG.TOTAL_MSG
|
||||||
|
| translate
|
||||||
|
: {
|
||||||
|
totalTimeToSubmit: totalTimeToSubmit$ | async | msToString,
|
||||||
|
nrOfTasksToSubmit: (tmpTasksToTrack$ | async)?.length,
|
||||||
|
}
|
||||||
|
"
|
||||||
></div>
|
></div>
|
||||||
</mat-dialog-content>
|
</mat-dialog-content>
|
||||||
|
|
||||||
|
|
@ -109,7 +120,7 @@
|
||||||
mat-button
|
mat-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
{{ T.G.CANCEL|translate }}
|
{{ T.G.CANCEL | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
@ -122,6 +133,6 @@
|
||||||
class="dialog-header-icon"
|
class="dialog-header-icon"
|
||||||
svgIcon="gitlab"
|
svgIcon="gitlab"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
{{ T.G.SUBMIT|translate }}
|
{{ T.G.SUBMIT | translate }}
|
||||||
</button>
|
</button>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,28 @@
|
||||||
<ng-container>
|
<ng-container>
|
||||||
@if (task()?.issueWasUpdated) {
|
@if (task()?.issueWasUpdated) {
|
||||||
<div
|
<div
|
||||||
@expand
|
@expand
|
||||||
style="text-align: center"
|
style="text-align: center"
|
||||||
>
|
|
||||||
<button
|
|
||||||
(click)="hideUpdates()"
|
|
||||||
color="accent"
|
|
||||||
mat-raised-button
|
|
||||||
>
|
>
|
||||||
{{T.F.GITLAB.ISSUE_CONTENT.MARK_AS_CHECKED|translate}}
|
<button
|
||||||
</button>
|
(click)="hideUpdates()"
|
||||||
</div>
|
color="accent"
|
||||||
|
mat-raised-button
|
||||||
|
>
|
||||||
|
{{ T.F.GITLAB.ISSUE_CONTENT.MARK_AS_CHECKED | translate }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper">
|
||||||
<table class="issue-table">
|
<table class="issue-table">
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.GITLAB.ISSUE_CONTENT.SUMMARY|translate}}</th>
|
<th>{{ T.F.GITLAB.ISSUE_CONTENT.SUMMARY | translate }}</th>
|
||||||
<td>
|
<td>
|
||||||
<a
|
<a
|
||||||
[href]="issue?.html_url"
|
[href]="issue?.html_url"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
><strong>{{issue?.title}} #{{issue?.number}}</strong></a
|
><strong>{{ issue?.title }} #{{ issue?.number }}</strong></a
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -31,68 +31,72 @@
|
||||||
<!-- <td>{{issue?.project}}</td>-->
|
<!-- <td>{{issue?.project}}</td>-->
|
||||||
<!-- </tr>-->
|
<!-- </tr>-->
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.GITLAB.ISSUE_CONTENT.STATUS|translate}}</th>
|
<th>{{ T.F.GITLAB.ISSUE_CONTENT.STATUS | translate }}</th>
|
||||||
<td>{{issue?.state}}</td>
|
<td>{{ issue?.state }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@if (issue?.assignee?.web_url) {
|
@if (issue?.assignee?.web_url) {
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.GITLAB.ISSUE_CONTENT.ASSIGNEE|translate}}</th>
|
<th>{{ T.F.GITLAB.ISSUE_CONTENT.ASSIGNEE | translate }}</th>
|
||||||
<td>
|
<td>
|
||||||
<a
|
<a
|
||||||
[href]="issue?.assignee?.web_url"
|
[href]="issue?.assignee?.web_url"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>{{issue?.assignee?.username}}</a
|
>{{ issue?.assignee?.username }}</a
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
} @if (issue?.labels?.length) {
|
}
|
||||||
<tr>
|
@if (issue?.labels?.length) {
|
||||||
<th>{{T.F.GITLAB.ISSUE_CONTENT.LABELS|translate}}</th>
|
<tr>
|
||||||
<td>
|
<th>{{ T.F.GITLAB.ISSUE_CONTENT.LABELS | translate }}</th>
|
||||||
<mat-chip-listbox>
|
<td>
|
||||||
@for (label of issue?.labels; track label) {
|
<mat-chip-listbox>
|
||||||
<mat-chip-option [title]="label">{{label}} </mat-chip-option>
|
@for (label of issue?.labels; track label) {
|
||||||
}
|
<mat-chip-option [title]="label">{{ label }} </mat-chip-option>
|
||||||
</mat-chip-listbox>
|
}
|
||||||
</td>
|
</mat-chip-listbox>
|
||||||
</tr>
|
</td>
|
||||||
} @if (issue?.body) {
|
</tr>
|
||||||
<tr>
|
}
|
||||||
<th>{{T.F.GITLAB.ISSUE_CONTENT.DESCRIPTION|translate}}</th>
|
@if (issue?.body) {
|
||||||
<td class="issue-description">
|
<tr>
|
||||||
<div
|
<th>{{ T.F.GITLAB.ISSUE_CONTENT.DESCRIPTION | translate }}</th>
|
||||||
[data]="issue?.body"
|
<td class="issue-description">
|
||||||
class="description markdown"
|
<div
|
||||||
markdown
|
[data]="issue?.body"
|
||||||
></div>
|
class="description markdown"
|
||||||
</td>
|
markdown
|
||||||
</tr>
|
></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
}
|
}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
@if (issue?.comments) {
|
@if (issue?.comments) {
|
||||||
<div>
|
<div>
|
||||||
@for (comment of (issue?.comments|sort:'created_at'); track trackByIndex($index,
|
@for (
|
||||||
comment)) {
|
comment of issue?.comments | sort: 'created_at';
|
||||||
<div class="comment">
|
track trackByIndex($index, comment)
|
||||||
<div class="name-and-comment-content">
|
) {
|
||||||
<div>
|
<div class="comment">
|
||||||
<span class="author-name">{{comment.author?.username}}</span>
|
<div class="name-and-comment-content">
|
||||||
<span class="when"
|
<div>
|
||||||
>{{T.F.GITLAB.ISSUE_CONTENT.AT|translate}}
|
<span class="author-name">{{ comment.author?.username }}</span>
|
||||||
{{comment.created_at|date:'short'}}</span
|
<span class="when"
|
||||||
>
|
>{{ T.F.GITLAB.ISSUE_CONTENT.AT | translate }}
|
||||||
|
{{ comment.created_at | date: 'short' }}</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
@if (comment.body) {
|
||||||
|
<div
|
||||||
|
[innerHTML]="comment?.body | markdown | async"
|
||||||
|
class="markdown"
|
||||||
|
></div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@if (comment.body) {
|
}
|
||||||
<div
|
|
||||||
[innerHTML]="comment?.body|markdown|async"
|
|
||||||
class="markdown"
|
|
||||||
></div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<div style="text-align: center">
|
<div style="text-align: center">
|
||||||
|
|
@ -104,7 +108,7 @@
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<mat-icon>textsms</mat-icon>
|
<mat-icon>textsms</mat-icon>
|
||||||
{{T.F.GITLAB.ISSUE_CONTENT.WRITE_A_COMMENT|translate}}
|
{{ T.F.GITLAB.ISSUE_CONTENT.WRITE_A_COMMENT | translate }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
@if (task()?.issueWasUpdated) {
|
@if (task()?.issueWasUpdated) {
|
||||||
<mat-icon
|
<mat-icon
|
||||||
color="accent"
|
color="accent"
|
||||||
style="margin-right: 8px"
|
style="margin-right: 8px"
|
||||||
>update
|
>update
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
} @if (!task()?.issueWasUpdated) {
|
}
|
||||||
<mat-icon
|
@if (!task()?.issueWasUpdated) {
|
||||||
style="margin-right: 8px"
|
<mat-icon
|
||||||
svgIcon="gitlab"
|
style="margin-right: 8px"
|
||||||
>
|
svgIcon="gitlab"
|
||||||
</mat-icon>
|
>
|
||||||
|
</mat-icon>
|
||||||
}
|
}
|
||||||
<span class="tab-label-text">Gitlab</span>
|
<span class="tab-label-text">Gitlab</span>
|
||||||
|
|
|
||||||
|
|
@ -1,134 +1,140 @@
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
@if (task?.issueWasUpdated) {
|
@if (task?.issueWasUpdated) {
|
||||||
<div
|
<div
|
||||||
[@expand]
|
[@expand]
|
||||||
class="updates"
|
class="updates"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
(click)="hideUpdates()"
|
(click)="hideUpdates()"
|
||||||
color="accent"
|
color="accent"
|
||||||
mat-raised-button
|
mat-raised-button
|
||||||
>
|
>
|
||||||
{{T.F.JIRA.ISSUE_CONTENT.MARK_AS_CHECKED|translate}}
|
{{ T.F.JIRA.ISSUE_CONTENT.MARK_AS_CHECKED | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
|
<h3 class="mat-h3">{{ T.F.JIRA.ISSUE_CONTENT.LIST_OF_CHANGES | translate }}</h3>
|
||||||
|
<ul class="changelog">
|
||||||
|
@for (entry of issue?.changelog; track entry) {
|
||||||
|
<li>
|
||||||
|
@if (entry.author) {
|
||||||
|
<em>{{ entry.author.displayName }}</em>
|
||||||
|
}
|
||||||
|
{{ T.F.JIRA.ISSUE_CONTENT.CHANGED | translate }}
|
||||||
|
<strong>{{ entry.field }}</strong>
|
||||||
|
{{ T.F.JIRA.ISSUE_CONTENT.ON | translate }}
|
||||||
|
{{ entry.created | date: 'short' }}
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="mat-h3">{{T.F.JIRA.ISSUE_CONTENT.LIST_OF_CHANGES|translate}}</h3>
|
|
||||||
<ul class="changelog">
|
|
||||||
@for (entry of issue?.changelog; track entry) {
|
|
||||||
<li>
|
|
||||||
@if (entry.author) {
|
|
||||||
<em>{{entry.author.displayName}}</em>
|
|
||||||
} {{T.F.JIRA.ISSUE_CONTENT.CHANGED|translate}}
|
|
||||||
<strong>{{entry.field}}</strong>
|
|
||||||
{{T.F.JIRA.ISSUE_CONTENT.ON|translate}} {{entry.created|date:'short'}}
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<table class="issue-table">
|
<table class="issue-table">
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.JIRA.ISSUE_CONTENT.SUMMARY|translate}}</th>
|
<th>{{ T.F.JIRA.ISSUE_CONTENT.SUMMARY | translate }}</th>
|
||||||
<td class="summary">
|
<td class="summary">
|
||||||
<strong
|
<strong
|
||||||
><a
|
><a
|
||||||
[href]="issueUrl$|async"
|
[href]="issueUrl$ | async"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>{{issue?.key}} {{issue?.summary}}</a
|
>{{ issue?.key }} {{ issue?.summary }}</a
|
||||||
></strong
|
></strong
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.JIRA.ISSUE_CONTENT.STATUS|translate}}</th>
|
<th>{{ T.F.JIRA.ISSUE_CONTENT.STATUS | translate }}</th>
|
||||||
<td>
|
<td>
|
||||||
<!--<img [src]="issue?.status?.iconUrl"-->
|
<!--<img [src]="issue?.status?.iconUrl"-->
|
||||||
<!--*ngIf="issue?.status?.iconUrl">-->
|
<!--*ngIf="issue?.status?.iconUrl">-->
|
||||||
{{issue?.status?.name}}
|
{{ issue?.status?.name }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@if (issue?.storyPoints) {
|
@if (issue?.storyPoints) {
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.JIRA.ISSUE_CONTENT.STORY_POINTS|translate}}</th>
|
<th>{{ T.F.JIRA.ISSUE_CONTENT.STORY_POINTS | translate }}</th>
|
||||||
<td>{{issue?.storyPoints}}</td>
|
<td>{{ issue?.storyPoints }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.JIRA.ISSUE_CONTENT.ASSIGNEE|translate}}</th>
|
<th>{{ T.F.JIRA.ISSUE_CONTENT.ASSIGNEE | translate }}</th>
|
||||||
<td>{{issue?.assignee?.displayName || '–'}}</td>
|
<td>{{ issue?.assignee?.displayName || '–' }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@if (issue?.timespent || issue?.timeestimate) {
|
@if (issue?.timespent || issue?.timeestimate) {
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.JIRA.ISSUE_CONTENT.WORKLOG|translate}}</th>
|
<th>{{ T.F.JIRA.ISSUE_CONTENT.WORKLOG | translate }}</th>
|
||||||
<td>
|
<td>
|
||||||
{{(issue?.timespent * 1000)|msToString}} / {{(issue?.timeestimate *
|
{{ issue?.timespent * 1000 | msToString }} /
|
||||||
1000)|msToString}}
|
{{ issue?.timeestimate * 1000 | msToString }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
} @if ((jiraSubTasks$|async); as jiraSubTasks) {
|
}
|
||||||
<tr>
|
@if (jiraSubTasks$ | async; as jiraSubTasks) {
|
||||||
<th>{{T.F.JIRA.ISSUE_CONTENT.SUB_TASKS|translate}}</th>
|
<tr>
|
||||||
<td>
|
<th>{{ T.F.JIRA.ISSUE_CONTENT.SUB_TASKS | translate }}</th>
|
||||||
<ul class="subtask-list">
|
<td>
|
||||||
@for (st of jiraSubTasks; track st) {
|
<ul class="subtask-list">
|
||||||
<li>
|
@for (st of jiraSubTasks; track st) {
|
||||||
<a
|
<li>
|
||||||
target="_blank"
|
<a
|
||||||
[href]="st.href"
|
target="_blank"
|
||||||
>
|
[href]="st.href"
|
||||||
{{st.key}} {{st.summary}}</a
|
>
|
||||||
>
|
{{ st.key }} {{ st.summary }}</a
|
||||||
</li>
|
>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
@if (jiraRelatedIssues$ | async; as relatedIssues) {
|
||||||
|
<tr>
|
||||||
|
<th>{{ T.F.JIRA.ISSUE_CONTENT.RELATED | translate }}</th>
|
||||||
|
<td>
|
||||||
|
<ul class="related-issue-list">
|
||||||
|
@for (ri of relatedIssues; track ri.id) {
|
||||||
|
<li>
|
||||||
|
<i>{{ ri.relatedHow }} => </i>
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
[href]="ri['href']"
|
||||||
|
>{{ ri.key }} {{ ri.summary }}</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
@if (issue?.components?.length) {
|
||||||
|
<tr>
|
||||||
|
<th>{{ T.F.JIRA.ISSUE_CONTENT.COMPONENTS | translate }}</th>
|
||||||
|
<td>
|
||||||
|
<mat-chip-listbox>
|
||||||
|
@for (component of issue?.components; track trackByIndex($index, component)) {
|
||||||
|
<mat-chip-option [title]="component.description"
|
||||||
|
>{{ component.name }}
|
||||||
|
</mat-chip-option>
|
||||||
|
}
|
||||||
|
</mat-chip-listbox>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
@if (issue?.description) {
|
||||||
|
<tr class="description-row">
|
||||||
|
<th>{{ T.F.JIRA.ISSUE_CONTENT.DESCRIPTION | translate }}</th>
|
||||||
|
<td>
|
||||||
|
@if (description) {
|
||||||
|
<div
|
||||||
|
[data]="description"
|
||||||
|
class="issue-description markdown"
|
||||||
|
markdown
|
||||||
|
></div>
|
||||||
}
|
}
|
||||||
</ul>
|
</td>
|
||||||
</td>
|
</tr>
|
||||||
</tr>
|
|
||||||
} @if ((jiraRelatedIssues$|async); as relatedIssues) {
|
|
||||||
<tr>
|
|
||||||
<th>{{T.F.JIRA.ISSUE_CONTENT.RELATED|translate}}</th>
|
|
||||||
<td>
|
|
||||||
<ul class="related-issue-list">
|
|
||||||
@for (ri of relatedIssues; track ri.id) {
|
|
||||||
<li>
|
|
||||||
<i>{{ri.relatedHow}} => </i>
|
|
||||||
<a
|
|
||||||
target="_blank"
|
|
||||||
[href]="ri['href']"
|
|
||||||
>{{ri.key}} {{ri.summary}}</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
} @if (issue?.components?.length) {
|
|
||||||
<tr>
|
|
||||||
<th>{{T.F.JIRA.ISSUE_CONTENT.COMPONENTS|translate}}</th>
|
|
||||||
<td>
|
|
||||||
<mat-chip-listbox>
|
|
||||||
@for (component of issue?.components; track trackByIndex($index, component)) {
|
|
||||||
<mat-chip-option [title]="component.description"
|
|
||||||
>{{component.name}}
|
|
||||||
</mat-chip-option>
|
|
||||||
}
|
|
||||||
</mat-chip-listbox>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
} @if (issue?.description) {
|
|
||||||
<tr class="description-row">
|
|
||||||
<th>{{T.F.JIRA.ISSUE_CONTENT.DESCRIPTION|translate}}</th>
|
|
||||||
<td>
|
|
||||||
@if (description) {
|
|
||||||
<div
|
|
||||||
[data]="description"
|
|
||||||
class="issue-description markdown"
|
|
||||||
markdown
|
|
||||||
></div>
|
|
||||||
}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
}
|
}
|
||||||
<!-- <tr *ngIf="attachments?.length">-->
|
<!-- <tr *ngIf="attachments?.length">-->
|
||||||
<!-- <th>{{T.F.JIRA.ISSUE_CONTENT.ATTACHMENTS|translate}}</th>-->
|
<!-- <th>{{T.F.JIRA.ISSUE_CONTENT.ATTACHMENTS|translate}}</th>-->
|
||||||
|
|
@ -141,43 +147,45 @@
|
||||||
<!-- </td>-->
|
<!-- </td>-->
|
||||||
<!-- </tr>-->
|
<!-- </tr>-->
|
||||||
@if (issue?.comments) {
|
@if (issue?.comments) {
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.JIRA.ISSUE_CONTENT.COMMENTS|translate}}</th>
|
<th>{{ T.F.JIRA.ISSUE_CONTENT.COMMENTS | translate }}</th>
|
||||||
<td>
|
<td>
|
||||||
@for (comment of (issue?.comments|sort:'created'); track trackByIndex($index,
|
@for (
|
||||||
comment)) {
|
comment of issue?.comments | sort: 'created';
|
||||||
<div class="comment">
|
track trackByIndex($index, comment)
|
||||||
<img
|
) {
|
||||||
[src]="comment.author.avatarUrl"
|
<div class="comment">
|
||||||
class="author-avatar"
|
<img
|
||||||
/>
|
[src]="comment.author.avatarUrl"
|
||||||
<div class="name-and-comment-content">
|
class="author-avatar"
|
||||||
<div>
|
/>
|
||||||
<span class="author-name">{{comment.author.displayName}}</span>
|
<div class="name-and-comment-content">
|
||||||
<span class="when"
|
<div>
|
||||||
>{{T.F.JIRA.ISSUE_CONTENT.AT|translate}}
|
<span class="author-name">{{ comment.author.displayName }}</span>
|
||||||
{{comment.created|date:'short'}}</span
|
<span class="when"
|
||||||
>
|
>{{ T.F.JIRA.ISSUE_CONTENT.AT | translate }}
|
||||||
|
{{ comment.created | date: 'short' }}</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
@if (comment.body) {
|
||||||
|
<div
|
||||||
|
[innerHTML]="comment.body | jiraToMarkdown | markdown | async"
|
||||||
|
class="markdown"
|
||||||
|
></div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@if (comment.body) {
|
}
|
||||||
<div
|
<a
|
||||||
[innerHTML]="comment.body|jiraToMarkdown|markdown|async"
|
[href]="issueUrl$ | async"
|
||||||
class="markdown"
|
mat-stroked-button
|
||||||
></div>
|
target="_blank"
|
||||||
}
|
>
|
||||||
</div>
|
<mat-icon>textsms</mat-icon>
|
||||||
</div>
|
{{ T.F.JIRA.ISSUE_CONTENT.WRITE_A_COMMENT | translate }}</a
|
||||||
}
|
>
|
||||||
<a
|
</td>
|
||||||
[href]="issueUrl$|async"
|
</tr>
|
||||||
mat-stroked-button
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<mat-icon>textsms</mat-icon>
|
|
||||||
{{T.F.JIRA.ISSUE_CONTENT.WRITE_A_COMMENT|translate}}</a
|
|
||||||
>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
}
|
}
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,23 @@
|
||||||
@if ((isOnline$|async)) { @if (task()?.issueWasUpdated) {
|
@if (isOnline$ | async) {
|
||||||
<mat-icon
|
@if (task()?.issueWasUpdated) {
|
||||||
color="accent"
|
<mat-icon
|
||||||
style="margin-right: 8px"
|
color="accent"
|
||||||
>update
|
style="margin-right: 8px"
|
||||||
</mat-icon>
|
>update
|
||||||
} @if (!task()?.issueWasUpdated) {
|
</mat-icon>
|
||||||
<mat-icon
|
}
|
||||||
style="margin-right: 8px"
|
@if (!task()?.issueWasUpdated) {
|
||||||
svgIcon="jira"
|
<mat-icon
|
||||||
>
|
style="margin-right: 8px"
|
||||||
</mat-icon>
|
svgIcon="jira"
|
||||||
} } @else {
|
>
|
||||||
<mat-icon
|
</mat-icon>
|
||||||
[matTooltip]="'No internet!'"
|
}
|
||||||
style="margin-right: 8px"
|
} @else {
|
||||||
>cloud_off
|
<mat-icon
|
||||||
</mat-icon>
|
[matTooltip]="'No internet!'"
|
||||||
|
style="margin-right: 8px"
|
||||||
|
>cloud_off
|
||||||
|
</mat-icon>
|
||||||
}
|
}
|
||||||
<span class="tab-label-text">Jira</span>
|
<span class="tab-label-text">Jira</span>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<form
|
<form
|
||||||
(submit)="$event.preventDefault();submitWorklog()"
|
(submit)="$event.preventDefault(); submitWorklog()"
|
||||||
class="mat-body"
|
class="mat-body"
|
||||||
name="time-estimate-form"
|
name="time-estimate-form"
|
||||||
>
|
>
|
||||||
|
|
@ -8,21 +8,22 @@
|
||||||
class="dialog-header-icon"
|
class="dialog-header-icon"
|
||||||
svgIcon="jira"
|
svgIcon="jira"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<span>{{T.F.JIRA.DIALOG_WORKLOG.TITLE|translate}}</span>
|
<span>{{ T.F.JIRA.DIALOG_WORKLOG.TITLE | translate }}</span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
<p>
|
<p>
|
||||||
{{T.F.JIRA.DIALOG_WORKLOG.SUBMIT_WORKLOG_FOR|translate}}
|
{{ T.F.JIRA.DIALOG_WORKLOG.SUBMIT_WORKLOG_FOR | translate }}
|
||||||
<strong>{{issue.key}} {{issue.summary}}</strong>.
|
<strong>{{ issue.key }} {{ issue.summary }}</strong
|
||||||
|
>.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{{T.F.JIRA.DIALOG_WORKLOG.CURRENTLY_LOGGED|translate}}
|
{{ T.F.JIRA.DIALOG_WORKLOG.CURRENTLY_LOGGED | translate }}
|
||||||
<strong>{{(timeLogged)|msToString}}</strong>
|
<strong>{{ timeLogged | msToString }}</strong>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="form-wrapper">
|
<div class="form-wrapper">
|
||||||
<mat-label>{{T.F.JIRA.DIALOG_WORKLOG.TIME_SPENT|translate}}</mat-label>
|
<mat-label>{{ T.F.JIRA.DIALOG_WORKLOG.TIME_SPENT | translate }}</mat-label>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<input
|
<input
|
||||||
[(ngModel)]="timeSpent"
|
[(ngModel)]="timeSpent"
|
||||||
|
|
@ -37,7 +38,7 @@
|
||||||
class="suffix-wrapper"
|
class="suffix-wrapper"
|
||||||
matSuffix
|
matSuffix
|
||||||
[matMenuTriggerFor]="contextMenu"
|
[matMenuTriggerFor]="contextMenu"
|
||||||
[matTooltip]="T.F.JIRA.DIALOG_WORKLOG.TIME_SPENT_TOOLTIP|translate"
|
[matTooltip]="T.F.JIRA.DIALOG_WORKLOG.TIME_SPENT_TOOLTIP | translate"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
|
|
@ -57,29 +58,31 @@
|
||||||
<mat-menu #contextMenu="matMenu">
|
<mat-menu #contextMenu="matMenu">
|
||||||
<ng-template matMenuContent>
|
<ng-template matMenuContent>
|
||||||
@for (opt of defaultTimeOptions; track opt) {
|
@for (opt of defaultTimeOptions; track opt) {
|
||||||
<button
|
<button
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
type="button"
|
type="button"
|
||||||
(click)="fill(opt.value)"
|
(click)="fill(opt.value)"
|
||||||
>
|
>
|
||||||
{{opt.label|translate}} ({{(getTimeToLogForMode(opt.value)|msToString)}})
|
{{ opt.label | translate }} ({{
|
||||||
</button>
|
getTimeToLogForMode(opt.value) | msToString
|
||||||
|
}})
|
||||||
|
</button>
|
||||||
}
|
}
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
|
||||||
@if (defaultTimeCheckboxContent) {
|
@if (defaultTimeCheckboxContent) {
|
||||||
<mat-checkbox
|
<mat-checkbox
|
||||||
[@expandFade]
|
[@expandFade]
|
||||||
[checked]="defaultTimeCheckboxContent.isChecked"
|
[checked]="defaultTimeCheckboxContent.isChecked"
|
||||||
(change)="defaultTimeCheckboxContent.isChecked = $event.checked"
|
(change)="defaultTimeCheckboxContent.isChecked = $event.checked"
|
||||||
style="margin-bottom: 20px"
|
style="margin-bottom: 20px"
|
||||||
>{{defaultTimeCheckboxContent.label|translate}}
|
>{{ defaultTimeCheckboxContent.label | translate }}
|
||||||
</mat-checkbox>
|
</mat-checkbox>
|
||||||
}
|
}
|
||||||
|
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{T.F.JIRA.DIALOG_WORKLOG.STARTED|translate}}</mat-label>
|
<mat-label>{{ T.F.JIRA.DIALOG_WORKLOG.STARTED | translate }}</mat-label>
|
||||||
<input
|
<input
|
||||||
[(ngModel)]="started"
|
[(ngModel)]="started"
|
||||||
matInput
|
matInput
|
||||||
|
|
@ -87,7 +90,7 @@
|
||||||
required
|
required
|
||||||
type="datetime-local"
|
type="datetime-local"
|
||||||
/>
|
/>
|
||||||
<mat-error>{{T.F.JIRA.DIALOG_WORKLOG.INVALID_DATE|translate}}</mat-error>
|
<mat-error>{{ T.F.JIRA.DIALOG_WORKLOG.INVALID_DATE | translate }}</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Comment</mat-label>
|
<mat-label>Comment</mat-label>
|
||||||
|
|
@ -112,7 +115,7 @@
|
||||||
mat-button
|
mat-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
{{T.G.CANCEL|translate}}
|
{{ T.G.CANCEL | translate }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-primary submit-button"
|
class="btn btn-primary submit-button"
|
||||||
|
|
@ -121,7 +124,7 @@
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
<mat-icon>save</mat-icon>
|
<mat-icon>save</mat-icon>
|
||||||
{{T.F.JIRA.DIALOG_WORKLOG.SAVE_WORKLOG|translate}}
|
{{ T.F.JIRA.DIALOG_WORKLOG.SAVE_WORKLOG | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
|
|
|
||||||
|
|
@ -3,36 +3,38 @@
|
||||||
class="dialog-header-icon"
|
class="dialog-header-icon"
|
||||||
svgIcon="jira"
|
svgIcon="jira"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<span>{{T.F.JIRA.DIALOG_TRANSITION.TITLE|translate}}</span>
|
<span>{{ T.F.JIRA.DIALOG_TRANSITION.TITLE | translate }}</span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.JIRA.DIALOG_TRANSITION.TASK_NAME|translate}}</th>
|
<th>{{ T.F.JIRA.DIALOG_TRANSITION.TASK_NAME | translate }}</th>
|
||||||
<td>{{data.task ? data.task?.title : '–'}}</td>
|
<td>{{ data.task ? data.task?.title : '–' }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.JIRA.DIALOG_TRANSITION.CURRENT_STATUS|translate}}</th>
|
<th>{{ T.F.JIRA.DIALOG_TRANSITION.CURRENT_STATUS | translate }}</th>
|
||||||
<td>{{data.issue?.status ? data.issue?.status?.name : '–'}}</td>
|
<td>{{ data.issue?.status ? data.issue?.status?.name : '–' }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.JIRA.DIALOG_TRANSITION.CURRENT_ASSIGNEE|translate}}</th>
|
<th>{{ T.F.JIRA.DIALOG_TRANSITION.CURRENT_ASSIGNEE | translate }}</th>
|
||||||
<td>{{data.issue?.assignee ? data.issue?.assignee?.displayName : '–'}}</td>
|
<td>{{ data.issue?.assignee ? data.issue?.assignee?.displayName : '–' }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<label>{{T.F.JIRA.DIALOG_TRANSITION.CHOOSE_STATUS|translate}}</label>
|
<label>{{ T.F.JIRA.DIALOG_TRANSITION.CHOOSE_STATUS | translate }}</label>
|
||||||
<mat-select [(ngModel)]="chosenTransition">
|
<mat-select [(ngModel)]="chosenTransition">
|
||||||
<!--<mat-option value="DO_NOT">Don't transition</mat-option>-->
|
<!--<mat-option value="DO_NOT">Don't transition</mat-option>-->
|
||||||
<!--<mat-option value="ALWAYS_ASK">Always open dialog</mat-option>-->
|
<!--<mat-option value="ALWAYS_ASK">Always open dialog</mat-option>-->
|
||||||
@for (transition of (availableTransitions$|async); track trackByIndex($index,
|
@for (
|
||||||
transition)) {
|
transition of availableTransitions$ | async;
|
||||||
<mat-option [value]="transition">
|
track trackByIndex($index, transition)
|
||||||
<!--<img [src]="transition.to.iconUrl">-->
|
) {
|
||||||
{{transition.name}}
|
<mat-option [value]="transition">
|
||||||
</mat-option>
|
<!--<img [src]="transition.to.iconUrl">-->
|
||||||
|
{{ transition.name }}
|
||||||
|
</mat-option>
|
||||||
}
|
}
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
@ -47,7 +49,7 @@
|
||||||
mat-button
|
mat-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
{{T.G.CANCEL|translate}}
|
{{ T.G.CANCEL | translate }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
(click)="transitionIssue()"
|
(click)="transitionIssue()"
|
||||||
|
|
@ -55,7 +57,7 @@
|
||||||
color="primary"
|
color="primary"
|
||||||
mat-stroked-button
|
mat-stroked-button
|
||||||
>
|
>
|
||||||
{{T.F.JIRA.DIALOG_TRANSITION.TITLE|translate}}
|
{{ T.F.JIRA.DIALOG_TRANSITION.TITLE | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
|
|
|
||||||
|
|
@ -1,84 +1,89 @@
|
||||||
<form [formGroup]="form">
|
<form [formGroup]="form">
|
||||||
<h3 class="sub-section-heading">{{ T.F.JIRA.CFG_CMP.TRANSITION|translate }}</h3>
|
<h3 class="sub-section-heading">{{ T.F.JIRA.CFG_CMP.TRANSITION | translate }}</h3>
|
||||||
<mat-slide-toggle
|
<mat-slide-toggle
|
||||||
[ngModel]="cfg.isTransitionIssuesEnabled"
|
[ngModel]="cfg.isTransitionIssuesEnabled"
|
||||||
(ngModelChange)="partialModelChange({isTransitionIssuesEnabled: $event})"
|
(ngModelChange)="partialModelChange({ isTransitionIssuesEnabled: $event })"
|
||||||
[ngModelOptions]="{standalone: true}"
|
[ngModelOptions]="{ standalone: true }"
|
||||||
name="isTransitionIssuesEnabled"
|
name="isTransitionIssuesEnabled"
|
||||||
style="margin-bottom: 8px"
|
style="margin-bottom: 8px"
|
||||||
>
|
>
|
||||||
{{ T.F.JIRA.CFG_CMP.ENABLE_TRANSITIONS|translate }}
|
{{ T.F.JIRA.CFG_CMP.ENABLE_TRANSITIONS | translate }}
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
|
|
||||||
@if (cfg.isTransitionIssuesEnabled) {
|
@if (cfg.isTransitionIssuesEnabled) {
|
||||||
<section @expand>
|
<section @expand>
|
||||||
<mat-form-field>
|
|
||||||
<mat-label
|
|
||||||
>{{ T.F.JIRA.CFG_CMP.SELECT_ISSUE_FOR_TRANSITIONS|translate }}
|
|
||||||
</mat-label>
|
|
||||||
<input
|
|
||||||
[formControl]="issueSuggestionsCtrl"
|
|
||||||
[matAutocomplete]="autoEl"
|
|
||||||
class="border-color-primary"
|
|
||||||
matInput
|
|
||||||
/>
|
|
||||||
<mat-autocomplete
|
|
||||||
#autoEl="matAutocomplete"
|
|
||||||
(optionSelected)="updateTransitionOptions()"
|
|
||||||
[autoActiveFirstOption]="true"
|
|
||||||
[displayWith]="displayIssueWith"
|
|
||||||
>
|
|
||||||
@if ((isLoading$|async)) {
|
|
||||||
<mat-option
|
|
||||||
[value]="issueSuggestionsCtrl.value"
|
|
||||||
class="is-loading"
|
|
||||||
>
|
|
||||||
<mat-spinner diameter="50"></mat-spinner>
|
|
||||||
</mat-option>
|
|
||||||
}
|
|
||||||
<!---->
|
|
||||||
@for (issue of (filteredIssueSuggestions$|async); track issue.issueData.id) {
|
|
||||||
<mat-option [value]="issue"><span>{{ issue?.title }}</span> </mat-option>
|
|
||||||
}
|
|
||||||
</mat-autocomplete>
|
|
||||||
</mat-form-field>
|
|
||||||
@for (opt of transitionConfigOpts; track opt) {
|
|
||||||
<div>
|
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<!-- @if (opt.key==='OPEN') {-->
|
<mat-label
|
||||||
<!-- <label>{{ T.F.JIRA.CFG_CMP.OPEN|translate }}</label>-->
|
>{{ T.F.JIRA.CFG_CMP.SELECT_ISSUE_FOR_TRANSITIONS | translate }}
|
||||||
<!-- }-->
|
</mat-label>
|
||||||
@if (opt.key==='IN_PROGRESS') {
|
<input
|
||||||
<label>{{ T.F.JIRA.CFG_CMP.IN_PROGRESS|translate }}</label>
|
[formControl]="issueSuggestionsCtrl"
|
||||||
} @if (opt.key==='DONE') {
|
[matAutocomplete]="autoEl"
|
||||||
<label>{{ T.F.JIRA.CFG_CMP.DONE|translate }}</label>
|
class="border-color-primary"
|
||||||
}
|
matInput
|
||||||
<!-- TODO check for a better way to do this -->
|
/>
|
||||||
<!-- <mat-select [(ngModel)]="cfg.transitionConfig[opt.key]"-->
|
<mat-autocomplete
|
||||||
<mat-select
|
#autoEl="matAutocomplete"
|
||||||
(ngModelChange)="setTransition(opt.key, $event)"
|
(optionSelected)="updateTransitionOptions()"
|
||||||
[ngModelOptions]="{standalone: true}"
|
[autoActiveFirstOption]="true"
|
||||||
[ngModel]="getTransition(opt.key)"
|
[displayWith]="displayIssueWith"
|
||||||
>
|
>
|
||||||
<mat-option value="DO_NOT">{{ T.F.JIRA.CFG_CMP.DO_NOT|translate }}</mat-option>
|
@if (isLoading$ | async) {
|
||||||
<mat-option value="ALWAYS_ASK"
|
<mat-option
|
||||||
>{{ T.F.JIRA.CFG_CMP.ALWAYS_ASK|translate }}
|
[value]="issueSuggestionsCtrl.value"
|
||||||
</mat-option>
|
class="is-loading"
|
||||||
@for (transition of cfg.availableTransitions; track transition) {
|
>
|
||||||
<mat-option [value]="transition"> {{ transition.name }} </mat-option>
|
<mat-spinner diameter="50"></mat-spinner>
|
||||||
|
</mat-option>
|
||||||
}
|
}
|
||||||
</mat-select>
|
<!---->
|
||||||
|
@for (issue of filteredIssueSuggestions$ | async; track issue.issueData.id) {
|
||||||
|
<mat-option [value]="issue"
|
||||||
|
><span>{{ issue?.title }}</span>
|
||||||
|
</mat-option>
|
||||||
|
}
|
||||||
|
</mat-autocomplete>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
@for (opt of transitionConfigOpts; track opt) {
|
||||||
}
|
<div>
|
||||||
</section>
|
<mat-form-field>
|
||||||
|
<!-- @if (opt.key==='OPEN') {-->
|
||||||
|
<!-- <label>{{ T.F.JIRA.CFG_CMP.OPEN|translate }}</label>-->
|
||||||
|
<!-- }-->
|
||||||
|
@if (opt.key === 'IN_PROGRESS') {
|
||||||
|
<label>{{ T.F.JIRA.CFG_CMP.IN_PROGRESS | translate }}</label>
|
||||||
|
}
|
||||||
|
@if (opt.key === 'DONE') {
|
||||||
|
<label>{{ T.F.JIRA.CFG_CMP.DONE | translate }}</label>
|
||||||
|
}
|
||||||
|
<!-- TODO check for a better way to do this -->
|
||||||
|
<!-- <mat-select [(ngModel)]="cfg.transitionConfig[opt.key]"-->
|
||||||
|
<mat-select
|
||||||
|
(ngModelChange)="setTransition(opt.key, $event)"
|
||||||
|
[ngModelOptions]="{ standalone: true }"
|
||||||
|
[ngModel]="getTransition(opt.key)"
|
||||||
|
>
|
||||||
|
<mat-option value="DO_NOT">{{
|
||||||
|
T.F.JIRA.CFG_CMP.DO_NOT | translate
|
||||||
|
}}</mat-option>
|
||||||
|
<mat-option value="ALWAYS_ASK"
|
||||||
|
>{{ T.F.JIRA.CFG_CMP.ALWAYS_ASK | translate }}
|
||||||
|
</mat-option>
|
||||||
|
@for (transition of cfg.availableTransitions; track transition) {
|
||||||
|
<mat-option [value]="transition"> {{ transition.name }} </mat-option>
|
||||||
|
}
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</section>
|
||||||
}
|
}
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h3 class="sub-section-heading">
|
<h3 class="sub-section-heading">
|
||||||
{{ T.F.JIRA.CFG_CMP.MAP_CUSTOM_FIELDS|translate }}
|
{{ T.F.JIRA.CFG_CMP.MAP_CUSTOM_FIELDS | translate }}
|
||||||
</h3>
|
</h3>
|
||||||
<p>{{ T.F.JIRA.CFG_CMP.MAP_CUSTOM_FIELDS_INFO|translate }}</p>
|
<p>{{ T.F.JIRA.CFG_CMP.MAP_CUSTOM_FIELDS_INFO | translate }}</p>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
|
|
@ -86,14 +91,14 @@
|
||||||
mat-raised-button
|
mat-raised-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
{{ T.F.JIRA.CFG_CMP.LOAD_SUGGESTIONS|translate }}
|
{{ T.F.JIRA.CFG_CMP.LOAD_SUGGESTIONS | translate }}
|
||||||
</button>
|
</button>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ T.F.JIRA.CFG_CMP.STORY_POINTS|translate }}</mat-label>
|
<mat-label>{{ T.F.JIRA.CFG_CMP.STORY_POINTS | translate }}</mat-label>
|
||||||
<input
|
<input
|
||||||
[formControl]="customFieldSuggestionsCtrl"
|
[formControl]="customFieldSuggestionsCtrl"
|
||||||
[matAutocomplete]="storyPointAutoEl"
|
[matAutocomplete]="storyPointAutoEl"
|
||||||
|
|
@ -105,11 +110,13 @@
|
||||||
#storyPointAutoEl="matAutocomplete"
|
#storyPointAutoEl="matAutocomplete"
|
||||||
[autoActiveFirstOption]="true"
|
[autoActiveFirstOption]="true"
|
||||||
>
|
>
|
||||||
@for (field of (filteredCustomFieldSuggestions$|async); track
|
@for (
|
||||||
trackByCustomFieldId($index, field)) {
|
field of filteredCustomFieldSuggestions$ | async;
|
||||||
<mat-option [value]="field.id"
|
track trackByCustomFieldId($index, field)
|
||||||
><span>{{ field?.id }}: {{ field?.name }}</span>
|
) {
|
||||||
</mat-option>
|
<mat-option [value]="field.id"
|
||||||
|
><span>{{ field?.id }}: {{ field?.name }}</span>
|
||||||
|
</mat-option>
|
||||||
}
|
}
|
||||||
</mat-autocomplete>
|
</mat-autocomplete>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
|
||||||
|
|
@ -1,64 +1,67 @@
|
||||||
<ng-container>
|
<ng-container>
|
||||||
@if (task()?.issueWasUpdated) {
|
@if (task()?.issueWasUpdated) {
|
||||||
<div
|
<div
|
||||||
@expand
|
@expand
|
||||||
style="text-align: center"
|
style="text-align: center"
|
||||||
>
|
|
||||||
<button
|
|
||||||
(click)="hideUpdates()"
|
|
||||||
color="accent"
|
|
||||||
mat-raised-button
|
|
||||||
>
|
>
|
||||||
{{T.F.OPEN_PROJECT.ISSUE_CONTENT.MARK_AS_CHECKED|translate}}
|
<button
|
||||||
</button>
|
(click)="hideUpdates()"
|
||||||
</div>
|
color="accent"
|
||||||
|
mat-raised-button
|
||||||
|
>
|
||||||
|
{{ T.F.OPEN_PROJECT.ISSUE_CONTENT.MARK_AS_CHECKED | translate }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper">
|
||||||
<table class="issue-table">
|
<table class="issue-table">
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.OPEN_PROJECT.ISSUE_CONTENT.SUMMARY|translate}}</th>
|
<th>{{ T.F.OPEN_PROJECT.ISSUE_CONTENT.SUMMARY | translate }}</th>
|
||||||
<td>
|
<td>
|
||||||
<a
|
<a
|
||||||
[href]="issue?.url"
|
[href]="issue?.url"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
><strong>{{issue?.subject}} #{{issue?.id}}</strong></a
|
><strong>{{ issue?.subject }} #{{ issue?.id }}</strong></a
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@if (issue?._embedded.type?.name) {
|
@if (issue?._embedded.type?.name) {
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.OPEN_PROJECT.ISSUE_CONTENT.TYPE|translate}}</th>
|
<th>{{ T.F.OPEN_PROJECT.ISSUE_CONTENT.TYPE | translate }}</th>
|
||||||
<td>{{issue?._embedded.type.name}}</td>
|
<td>{{ issue?._embedded.type.name }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
} @if (issue?._embedded.status) {
|
}
|
||||||
<tr>
|
@if (issue?._embedded.status) {
|
||||||
<th>{{T.F.OPEN_PROJECT.ISSUE_CONTENT.STATUS|translate}}</th>
|
<tr>
|
||||||
<td>
|
<th>{{ T.F.OPEN_PROJECT.ISSUE_CONTENT.STATUS | translate }}</th>
|
||||||
<span
|
<td>
|
||||||
class="dot"
|
<span
|
||||||
[style.backgroud-color]="issue?._embedded.status.color"
|
class="dot"
|
||||||
></span
|
[style.backgroud-color]="issue?._embedded.status.color"
|
||||||
>{{issue?._embedded.status.name}}
|
></span
|
||||||
</td>
|
>{{ issue?._embedded.status.name }}
|
||||||
</tr>
|
</td>
|
||||||
} @if (issue?._embedded.assignee?.name) {
|
</tr>
|
||||||
<tr>
|
}
|
||||||
<th>{{T.F.OPEN_PROJECT.ISSUE_CONTENT.ASSIGNEE|translate}}</th>
|
@if (issue?._embedded.assignee?.name) {
|
||||||
<td>{{issue?._embedded.assignee.name}}</td>
|
<tr>
|
||||||
</tr>
|
<th>{{ T.F.OPEN_PROJECT.ISSUE_CONTENT.ASSIGNEE | translate }}</th>
|
||||||
} @if (issue?.description?.raw || issue?.description?.html) {
|
<td>{{ issue?._embedded.assignee.name }}</td>
|
||||||
<tr>
|
</tr>
|
||||||
<th>{{T.F.OPEN_PROJECT.ISSUE_CONTENT.DESCRIPTION|translate}}</th>
|
}
|
||||||
<td class="issue-description">
|
@if (issue?.description?.raw || issue?.description?.html) {
|
||||||
<div
|
<tr>
|
||||||
[data]="issue?.description.raw || issue?.description.html"
|
<th>{{ T.F.OPEN_PROJECT.ISSUE_CONTENT.DESCRIPTION | translate }}</th>
|
||||||
class="description markdown"
|
<td class="issue-description">
|
||||||
markdown
|
<div
|
||||||
></div>
|
[data]="issue?.description.raw || issue?.description.html"
|
||||||
</td>
|
class="description markdown"
|
||||||
</tr>
|
markdown
|
||||||
|
></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
}
|
}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
@if (task()?.issueWasUpdated) {
|
@if (task()?.issueWasUpdated) {
|
||||||
<mat-icon
|
<mat-icon
|
||||||
color="accent"
|
color="accent"
|
||||||
style="margin-right: 8px"
|
style="margin-right: 8px"
|
||||||
>update
|
>update
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
} @if (!task()?.issueWasUpdated) {
|
}
|
||||||
<mat-icon
|
@if (!task()?.issueWasUpdated) {
|
||||||
style="margin-right: 8px"
|
<mat-icon
|
||||||
svgIcon="open_project"
|
style="margin-right: 8px"
|
||||||
>
|
svgIcon="open_project"
|
||||||
</mat-icon>
|
>
|
||||||
|
</mat-icon>
|
||||||
}
|
}
|
||||||
<span class="tab-label-text">OpenProject</span>
|
<span class="tab-label-text">OpenProject</span>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<form
|
<form
|
||||||
(submit)="$event.preventDefault();postTime()"
|
(submit)="$event.preventDefault(); postTime()"
|
||||||
class="mat-body"
|
class="mat-body"
|
||||||
name="time-estimate-form"
|
name="time-estimate-form"
|
||||||
>
|
>
|
||||||
|
|
@ -8,31 +8,33 @@
|
||||||
class="dialog-header-icon"
|
class="dialog-header-icon"
|
||||||
svgIcon="open_project"
|
svgIcon="open_project"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<span>{{T.F.OPEN_PROJECT.DIALOG_TRACK_TIME.TITLE|translate}}</span>
|
<span>{{ T.F.OPEN_PROJECT.DIALOG_TRACK_TIME.TITLE | translate }}</span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
<p>
|
<p>
|
||||||
{{T.F.OPEN_PROJECT.DIALOG_TRACK_TIME.SUBMIT_TIME_FOR|translate}}<br />
|
{{ T.F.OPEN_PROJECT.DIALOG_TRACK_TIME.SUBMIT_TIME_FOR | translate }}<br />
|
||||||
<strong>
|
<strong>
|
||||||
<a
|
<a
|
||||||
[href]="workPackage?.url"
|
[href]="workPackage?.url"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
{{workPackage.id}} {{workPackage.subject}}</a
|
{{ workPackage.id }} {{ workPackage.subject }}</a
|
||||||
></strong
|
></strong
|
||||||
>.
|
>.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{{T.F.OPEN_PROJECT.DIALOG_TRACK_TIME.CURRENTLY_LOGGED|translate}}
|
{{ T.F.OPEN_PROJECT.DIALOG_TRACK_TIME.CURRENTLY_LOGGED | translate }}
|
||||||
<strong>{{(timeLoggedForWorkPackage)|msToString}}</strong>
|
<strong>{{ timeLoggedForWorkPackage | msToString }}</strong>
|
||||||
</p>
|
</p>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<div class="form-wrapper">
|
<div class="form-wrapper">
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{T.F.OPEN_PROJECT.DIALOG_TRACK_TIME.TIME_SPENT|translate}}</mat-label>
|
<mat-label>{{
|
||||||
|
T.F.OPEN_PROJECT.DIALOG_TRACK_TIME.TIME_SPENT | translate
|
||||||
|
}}</mat-label>
|
||||||
<input
|
<input
|
||||||
[(ngModel)]="timeSpent"
|
[(ngModel)]="timeSpent"
|
||||||
inputDuration="optional"
|
inputDuration="optional"
|
||||||
|
|
@ -45,7 +47,7 @@
|
||||||
class="suffix-wrapper"
|
class="suffix-wrapper"
|
||||||
matSuffix
|
matSuffix
|
||||||
[matMenuTriggerFor]="contextMenu"
|
[matMenuTriggerFor]="contextMenu"
|
||||||
[matTooltip]="T.F.JIRA.DIALOG_WORKLOG.TIME_SPENT_TOOLTIP|translate"
|
[matTooltip]="T.F.JIRA.DIALOG_WORKLOG.TIME_SPENT_TOOLTIP | translate"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
|
|
@ -65,29 +67,33 @@
|
||||||
<mat-menu #contextMenu="matMenu">
|
<mat-menu #contextMenu="matMenu">
|
||||||
<ng-template matMenuContent>
|
<ng-template matMenuContent>
|
||||||
@for (opt of defaultTimeOptions; track opt) {
|
@for (opt of defaultTimeOptions; track opt) {
|
||||||
<button
|
<button
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
type="button"
|
type="button"
|
||||||
(click)="fill(opt.value)"
|
(click)="fill(opt.value)"
|
||||||
>
|
>
|
||||||
{{opt.label|translate}} ({{(getTimeToLogForMode(opt.value)|msToString)}})
|
{{ opt.label | translate }} ({{
|
||||||
</button>
|
getTimeToLogForMode(opt.value) | msToString
|
||||||
|
}})
|
||||||
|
</button>
|
||||||
}
|
}
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
|
||||||
@if (defaultTimeCheckboxContent) {
|
@if (defaultTimeCheckboxContent) {
|
||||||
<mat-checkbox
|
<mat-checkbox
|
||||||
[@expandFade]
|
[@expandFade]
|
||||||
[checked]="defaultTimeCheckboxContent.isChecked"
|
[checked]="defaultTimeCheckboxContent.isChecked"
|
||||||
(change)="defaultTimeCheckboxContent.isChecked = $event.checked"
|
(change)="defaultTimeCheckboxContent.isChecked = $event.checked"
|
||||||
style="margin-bottom: 20px"
|
style="margin-bottom: 20px"
|
||||||
>{{defaultTimeCheckboxContent.label|translate}}
|
>{{ defaultTimeCheckboxContent.label | translate }}
|
||||||
</mat-checkbox>
|
</mat-checkbox>
|
||||||
}
|
}
|
||||||
|
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{T.F.OPEN_PROJECT.DIALOG_TRACK_TIME.STARTED|translate}}</mat-label>
|
<mat-label>{{
|
||||||
|
T.F.OPEN_PROJECT.DIALOG_TRACK_TIME.STARTED | translate
|
||||||
|
}}</mat-label>
|
||||||
<input
|
<input
|
||||||
[(ngModel)]="started"
|
[(ngModel)]="started"
|
||||||
matInput
|
matInput
|
||||||
|
|
@ -95,19 +101,21 @@
|
||||||
required
|
required
|
||||||
type="datetime-local"
|
type="datetime-local"
|
||||||
/>
|
/>
|
||||||
<mat-error
|
<mat-error>{{
|
||||||
>{{T.F.OPEN_PROJECT.DIALOG_TRACK_TIME.INVALID_DATE|translate}}</mat-error
|
T.F.OPEN_PROJECT.DIALOG_TRACK_TIME.INVALID_DATE | translate
|
||||||
>
|
}}</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{T.F.OPEN_PROJECT.DIALOG_TRACK_TIME.ACTIVITY|translate}}</mat-label>
|
<mat-label>{{
|
||||||
|
T.F.OPEN_PROJECT.DIALOG_TRACK_TIME.ACTIVITY | translate
|
||||||
|
}}</mat-label>
|
||||||
<mat-select
|
<mat-select
|
||||||
[(ngModel)]="activityId"
|
[(ngModel)]="activityId"
|
||||||
name="activity"
|
name="activity"
|
||||||
>
|
>
|
||||||
@for (activity of (activities$|async); track activity) {
|
@for (activity of activities$ | async; track activity) {
|
||||||
<mat-option [value]="activity.id"> {{activity.name}} </mat-option>
|
<mat-option [value]="activity.id"> {{ activity.name }} </mat-option>
|
||||||
}
|
}
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
@ -134,7 +142,7 @@
|
||||||
mat-button
|
mat-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
{{T.G.CANCEL|translate}}
|
{{ T.G.CANCEL | translate }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
color="primary"
|
color="primary"
|
||||||
|
|
@ -142,7 +150,7 @@
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
<mat-icon>save</mat-icon>
|
<mat-icon>save</mat-icon>
|
||||||
{{T.F.OPEN_PROJECT.DIALOG_TRACK_TIME.POST_TIME|translate}}
|
{{ T.F.OPEN_PROJECT.DIALOG_TRACK_TIME.POST_TIME | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
|
|
|
||||||
|
|
@ -3,31 +3,35 @@
|
||||||
class="dialog-header-icon"
|
class="dialog-header-icon"
|
||||||
svgIcon="open_project"
|
svgIcon="open_project"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<span>{{ T.F.OPEN_PROJECT.DIALOG_TRANSITION.TITLE|translate }}</span>
|
<span>{{ T.F.OPEN_PROJECT.DIALOG_TRANSITION.TITLE | translate }}</span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ T.F.OPEN_PROJECT.DIALOG_TRANSITION.TASK_NAME|translate }}</th>
|
<th>{{ T.F.OPEN_PROJECT.DIALOG_TRANSITION.TASK_NAME | translate }}</th>
|
||||||
<td>{{ data.task ? data.task?.title : '–' }}</td>
|
<td>{{ data.task ? data.task?.title : '–' }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ T.F.OPEN_PROJECT.DIALOG_TRANSITION.CURRENT_STATUS|translate }}</th>
|
<th>{{ T.F.OPEN_PROJECT.DIALOG_TRANSITION.CURRENT_STATUS | translate }}</th>
|
||||||
<td>
|
<td>
|
||||||
{{ data.issue?._embedded?.status?.name ? data.issue?._embedded?.status?.name : '–'
|
{{
|
||||||
|
data.issue?._embedded?.status?.name ? data.issue?._embedded?.status?.name : '–'
|
||||||
}}
|
}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ T.F.OPEN_PROJECT.DIALOG_TRANSITION.CURRENT_ASSIGNEE|translate }}</th>
|
<th>{{ T.F.OPEN_PROJECT.DIALOG_TRANSITION.CURRENT_ASSIGNEE | translate }}</th>
|
||||||
<td>
|
<td>
|
||||||
{{ data.issue?._embedded?.assignee?.name ? data.issue?._embedded?.assignee?.name :
|
{{
|
||||||
'–' }}
|
data.issue?._embedded?.assignee?.name
|
||||||
|
? data.issue?._embedded?.assignee?.name
|
||||||
|
: '–'
|
||||||
|
}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ T.F.OPEN_PROJECT.DIALOG_TRANSITION.PERCENTAGE_DONE|translate }}</th>
|
<th>{{ T.F.OPEN_PROJECT.DIALOG_TRANSITION.PERCENTAGE_DONE | translate }}</th>
|
||||||
<td>
|
<td>
|
||||||
<!-- TODO: The 'tickInterval' property no longer exists -->
|
<!-- TODO: The 'tickInterval' property no longer exists -->
|
||||||
<mat-slider
|
<mat-slider
|
||||||
|
|
@ -45,16 +49,18 @@
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<label>{{ T.F.OPEN_PROJECT.DIALOG_TRANSITION.CHOOSE_STATUS|translate }}</label>
|
<label>{{ T.F.OPEN_PROJECT.DIALOG_TRANSITION.CHOOSE_STATUS | translate }}</label>
|
||||||
<mat-select [(ngModel)]="chosenTransition">
|
<mat-select [(ngModel)]="chosenTransition">
|
||||||
<!--<mat-option value="DO_NOT">Don't transition</mat-option>-->
|
<!--<mat-option value="DO_NOT">Don't transition</mat-option>-->
|
||||||
<!--<mat-option value="ALWAYS_ASK">Always open dialog</mat-option>-->
|
<!--<mat-option value="ALWAYS_ASK">Always open dialog</mat-option>-->
|
||||||
@for (transition of (availableTransitions$|async); track trackByIndex($index,
|
@for (
|
||||||
transition)) {
|
transition of availableTransitions$ | async;
|
||||||
<mat-option [value]="transition">
|
track trackByIndex($index, transition)
|
||||||
<!--<img [src]="transition.to.iconUrl">-->
|
) {
|
||||||
{{ transition.name }}
|
<mat-option [value]="transition">
|
||||||
</mat-option>
|
<!--<img [src]="transition.to.iconUrl">-->
|
||||||
|
{{ transition.name }}
|
||||||
|
</mat-option>
|
||||||
}
|
}
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
@ -69,7 +75,7 @@
|
||||||
mat-button
|
mat-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
{{ T.G.CANCEL|translate }}
|
{{ T.G.CANCEL | translate }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
(click)="transitionIssue()"
|
(click)="transitionIssue()"
|
||||||
|
|
@ -77,7 +83,7 @@
|
||||||
color="primary"
|
color="primary"
|
||||||
mat-stroked-button
|
mat-stroked-button
|
||||||
>
|
>
|
||||||
{{ T.F.OPEN_PROJECT.DIALOG_TRANSITION.TITLE|translate }}
|
{{ T.F.OPEN_PROJECT.DIALOG_TRANSITION.TITLE | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
|
|
|
||||||
|
|
@ -1,100 +1,106 @@
|
||||||
<form [formGroup]="form">
|
<form [formGroup]="form">
|
||||||
<h3 class="sub-section-heading">{{ T.F.OPEN_PROJECT.CFG_CMP.TRANSITION|translate }}</h3>
|
<h3 class="sub-section-heading">
|
||||||
|
{{ T.F.OPEN_PROJECT.CFG_CMP.TRANSITION | translate }}
|
||||||
|
</h3>
|
||||||
<mat-slide-toggle
|
<mat-slide-toggle
|
||||||
[ngModel]="cfg.isTransitionIssuesEnabled"
|
[ngModel]="cfg.isTransitionIssuesEnabled"
|
||||||
(ngModelChange)="partialModelChange({isTransitionIssuesEnabled: $event})"
|
(ngModelChange)="partialModelChange({ isTransitionIssuesEnabled: $event })"
|
||||||
[ngModelOptions]="{standalone: true}"
|
[ngModelOptions]="{ standalone: true }"
|
||||||
name="isTransitionIssuesEnabled"
|
name="isTransitionIssuesEnabled"
|
||||||
style="margin-bottom: 8px"
|
style="margin-bottom: 8px"
|
||||||
>
|
>
|
||||||
{{ T.F.OPEN_PROJECT.CFG_CMP.ENABLE_TRANSITIONS|translate }}
|
{{ T.F.OPEN_PROJECT.CFG_CMP.ENABLE_TRANSITIONS | translate }}
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
|
|
||||||
@if (cfg.isTransitionIssuesEnabled) {
|
@if (cfg.isTransitionIssuesEnabled) {
|
||||||
<section @expand>
|
<section @expand>
|
||||||
<mat-form-field>
|
|
||||||
<mat-label>
|
|
||||||
{{ T.F.OPEN_PROJECT.CFG_CMP.SELECT_ISSUE_FOR_TRANSITIONS|translate }}
|
|
||||||
</mat-label>
|
|
||||||
<input
|
|
||||||
[formControl]="issueSuggestionsCtrl"
|
|
||||||
[matAutocomplete]="autoEl"
|
|
||||||
class="border-color-primary"
|
|
||||||
matInput
|
|
||||||
/>
|
|
||||||
<mat-autocomplete
|
|
||||||
#autoEl="matAutocomplete"
|
|
||||||
(optionSelected)="updateTransitionOptions()"
|
|
||||||
[autoActiveFirstOption]="true"
|
|
||||||
[displayWith]="displayIssueWith"
|
|
||||||
>
|
|
||||||
@if ((isLoading$|async)) {
|
|
||||||
<mat-option
|
|
||||||
[value]="issueSuggestionsCtrl.value"
|
|
||||||
class="is-loading"
|
|
||||||
>
|
|
||||||
<mat-spinner diameter="50"></mat-spinner>
|
|
||||||
</mat-option>
|
|
||||||
} @for (issue of (filteredIssueSuggestions$|async); track issue.issueData.id) {
|
|
||||||
<mat-option [value]="issue"><span>{{ issue?.title }}</span> </mat-option>
|
|
||||||
}
|
|
||||||
</mat-autocomplete>
|
|
||||||
</mat-form-field>
|
|
||||||
@for (opt of transitionConfigOpts; track opt.key) {
|
|
||||||
<div>
|
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<!-- @if (opt.key==='OPEN') {-->
|
<mat-label>
|
||||||
<!-- <label> {{ T.F.OPEN_PROJECT.CFG_CMP.OPEN|translate }} </label>-->
|
{{ T.F.OPEN_PROJECT.CFG_CMP.SELECT_ISSUE_FOR_TRANSITIONS | translate }}
|
||||||
<!-- } -->
|
</mat-label>
|
||||||
@if (opt.key==='IN_PROGRESS') {
|
<input
|
||||||
<label> {{ T.F.OPEN_PROJECT.CFG_CMP.IN_PROGRESS|translate }} </label>
|
[formControl]="issueSuggestionsCtrl"
|
||||||
} @if (opt.key==='DONE') {
|
[matAutocomplete]="autoEl"
|
||||||
<label> {{ T.F.OPEN_PROJECT.CFG_CMP.DONE|translate }} </label>
|
class="border-color-primary"
|
||||||
}
|
matInput
|
||||||
<mat-select
|
/>
|
||||||
(ngModelChange)="setTransition(opt.key, $event)"
|
<mat-autocomplete
|
||||||
[ngModelOptions]="{standalone: true}"
|
#autoEl="matAutocomplete"
|
||||||
[ngModel]="getTransition(opt.key)"
|
(optionSelected)="updateTransitionOptions()"
|
||||||
|
[autoActiveFirstOption]="true"
|
||||||
|
[displayWith]="displayIssueWith"
|
||||||
>
|
>
|
||||||
<mat-option value="DO_NOT">
|
@if (isLoading$ | async) {
|
||||||
{{ T.F.OPEN_PROJECT.CFG_CMP.DO_NOT|translate }}
|
<mat-option
|
||||||
</mat-option>
|
[value]="issueSuggestionsCtrl.value"
|
||||||
<mat-option value="ALWAYS_ASK">
|
class="is-loading"
|
||||||
{{ T.F.OPEN_PROJECT.CFG_CMP.ALWAYS_ASK|translate }}
|
>
|
||||||
</mat-option>
|
<mat-spinner diameter="50"></mat-spinner>
|
||||||
@for (transition of cfg.availableTransitions; track transition.id) {
|
</mat-option>
|
||||||
<mat-option [value]="transition"> {{ transition.name }} </mat-option>
|
|
||||||
}
|
}
|
||||||
</mat-select>
|
@for (issue of filteredIssueSuggestions$ | async; track issue.issueData.id) {
|
||||||
|
<mat-option [value]="issue"
|
||||||
|
><span>{{ issue?.title }}</span>
|
||||||
|
</mat-option>
|
||||||
|
}
|
||||||
|
</mat-autocomplete>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
@if (showSetProgressOption(opt.key)) {
|
@for (opt of transitionConfigOpts; track opt.key) {
|
||||||
<div>
|
<div>
|
||||||
<mat-checkbox
|
<mat-form-field>
|
||||||
[ngModel]="this.cfg.isSetProgressOnTaskDone"
|
<!-- @if (opt.key==='OPEN') {-->
|
||||||
(ngModelChange)="partialModelChange({isSetProgressOnTaskDone: $event})"
|
<!-- <label> {{ T.F.OPEN_PROJECT.CFG_CMP.OPEN|translate }} </label>-->
|
||||||
[ngModelOptions]="{standalone: true}"
|
<!-- } -->
|
||||||
>
|
@if (opt.key === 'IN_PROGRESS') {
|
||||||
{{ T.F.OPEN_PROJECT.CFG_CMP.PROGRESS_ON_SAVE|translate }}
|
<label> {{ T.F.OPEN_PROJECT.CFG_CMP.IN_PROGRESS | translate }} </label>
|
||||||
</mat-checkbox>
|
}
|
||||||
<!-- TODO: The 'tickInterval' property no longer exists -->
|
@if (opt.key === 'DONE') {
|
||||||
@if (this.cfg.isSetProgressOnTaskDone) {
|
<label> {{ T.F.OPEN_PROJECT.CFG_CMP.DONE | translate }} </label>
|
||||||
<mat-slider
|
}
|
||||||
thumbLabel
|
<mat-select
|
||||||
[displayWith]="displayThumbWith"
|
(ngModelChange)="setTransition(opt.key, $event)"
|
||||||
min="0"
|
[ngModelOptions]="{ standalone: true }"
|
||||||
max="100"
|
[ngModel]="getTransition(opt.key)"
|
||||||
step="5"
|
>
|
||||||
aria-label="units"
|
<mat-option value="DO_NOT">
|
||||||
[ngModel]="this.cfg.progressOnDone"
|
{{ T.F.OPEN_PROJECT.CFG_CMP.DO_NOT | translate }}
|
||||||
(ngModelChange)="partialModelChange({progressOnDone: $event})"
|
</mat-option>
|
||||||
[ngModelOptions]="{standalone: true}"
|
<mat-option value="ALWAYS_ASK">
|
||||||
><input matSliderThumb
|
{{ T.F.OPEN_PROJECT.CFG_CMP.ALWAYS_ASK | translate }}
|
||||||
/></mat-slider>
|
</mat-option>
|
||||||
}
|
@for (transition of cfg.availableTransitions; track transition.id) {
|
||||||
</div>
|
<mat-option [value]="transition"> {{ transition.name }} </mat-option>
|
||||||
|
}
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
@if (showSetProgressOption(opt.key)) {
|
||||||
|
<div>
|
||||||
|
<mat-checkbox
|
||||||
|
[ngModel]="this.cfg.isSetProgressOnTaskDone"
|
||||||
|
(ngModelChange)="partialModelChange({ isSetProgressOnTaskDone: $event })"
|
||||||
|
[ngModelOptions]="{ standalone: true }"
|
||||||
|
>
|
||||||
|
{{ T.F.OPEN_PROJECT.CFG_CMP.PROGRESS_ON_SAVE | translate }}
|
||||||
|
</mat-checkbox>
|
||||||
|
<!-- TODO: The 'tickInterval' property no longer exists -->
|
||||||
|
@if (this.cfg.isSetProgressOnTaskDone) {
|
||||||
|
<mat-slider
|
||||||
|
thumbLabel
|
||||||
|
[displayWith]="displayThumbWith"
|
||||||
|
min="0"
|
||||||
|
max="100"
|
||||||
|
step="5"
|
||||||
|
aria-label="units"
|
||||||
|
[ngModel]="this.cfg.progressOnDone"
|
||||||
|
(ngModelChange)="partialModelChange({ progressOnDone: $event })"
|
||||||
|
[ngModelOptions]="{ standalone: true }"
|
||||||
|
><input matSliderThumb
|
||||||
|
/></mat-slider>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</section>
|
||||||
}
|
|
||||||
</section>
|
|
||||||
}
|
}
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -4,48 +4,48 @@
|
||||||
[href]="issue?.url"
|
[href]="issue?.url"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
{{issue?.tracker.name}} #{{issue?.id}}
|
{{ issue?.tracker.name }} #{{ issue?.id }}
|
||||||
</a>
|
</a>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper">
|
||||||
<table class="issue-table">
|
<table class="issue-table">
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.REDMINE.ISSUE_CONTENT.AUTHOR|translate}}</th>
|
<th>{{ T.F.REDMINE.ISSUE_CONTENT.AUTHOR | translate }}</th>
|
||||||
<td>{{issue?.author.name}}</td>
|
<td>{{ issue?.author.name }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.REDMINE.ISSUE_CONTENT.STATUS|translate}}</th>
|
<th>{{ T.F.REDMINE.ISSUE_CONTENT.STATUS | translate }}</th>
|
||||||
<td>{{issue?.status.name}}</td>
|
<td>{{ issue?.status.name }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.REDMINE.ISSUE_CONTENT.PRIORITY|translate}}</th>
|
<th>{{ T.F.REDMINE.ISSUE_CONTENT.PRIORITY | translate }}</th>
|
||||||
<td>{{issue?.priority.name}}</td>
|
<td>{{ issue?.priority.name }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@if (issue?.description) {
|
@if (issue?.description) {
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{T.F.REDMINE.ISSUE_CONTENT.DESCRIPTION|translate}}</th>
|
<th>{{ T.F.REDMINE.ISSUE_CONTENT.DESCRIPTION | translate }}</th>
|
||||||
<td>{{issue?.description}}</td>
|
<td>{{ issue?.description }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (task()?.issueWasUpdated) {
|
@if (task()?.issueWasUpdated) {
|
||||||
<div
|
<div
|
||||||
@expand
|
@expand
|
||||||
style="text-align: center"
|
style="text-align: center"
|
||||||
>
|
|
||||||
<button
|
|
||||||
(click)="hideUpdates()"
|
|
||||||
color="accent"
|
|
||||||
mat-raised-button
|
|
||||||
>
|
>
|
||||||
{{T.F.REDMINE.ISSUE_CONTENT.MARK_AS_CHECKED|translate}}
|
<button
|
||||||
</button>
|
(click)="hideUpdates()"
|
||||||
</div>
|
color="accent"
|
||||||
|
mat-raised-button
|
||||||
|
>
|
||||||
|
{{ T.F.REDMINE.ISSUE_CONTENT.MARK_AS_CHECKED | translate }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
@if (task()?.issueWasUpdated) {
|
@if (task()?.issueWasUpdated) {
|
||||||
<mat-icon
|
<mat-icon
|
||||||
color="accent"
|
color="accent"
|
||||||
style="margin-right: 8px"
|
style="margin-right: 8px"
|
||||||
>update
|
>update
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
} @if (!task()?.issueWasUpdated) {
|
}
|
||||||
<mat-icon
|
@if (!task()?.issueWasUpdated) {
|
||||||
style="margin-right: 8px"
|
<mat-icon
|
||||||
svgIcon="redmine"
|
style="margin-right: 8px"
|
||||||
>
|
svgIcon="redmine"
|
||||||
</mat-icon>
|
>
|
||||||
|
</mat-icon>
|
||||||
}
|
}
|
||||||
<span class="tab-label-text">Redmine</span>
|
<span class="tab-label-text">Redmine</span>
|
||||||
|
|
|
||||||
|
|
@ -1,98 +1,104 @@
|
||||||
<div class="wrapper mat-elevation-z1">
|
<div class="wrapper mat-elevation-z1">
|
||||||
<help-section>
|
<help-section>
|
||||||
<p>{{T.F.METRIC.EVAL_FORM.HELP_P1|translate}}</p>
|
<p>{{ T.F.METRIC.EVAL_FORM.HELP_P1 | translate }}</p>
|
||||||
<p><a routerLink="/metrics">{{T.F.METRIC.EVAL_FORM.HELP_LINK_TXT|translate}}</a></p>
|
<p>
|
||||||
|
<a routerLink="/metrics">{{ T.F.METRIC.EVAL_FORM.HELP_LINK_TXT | translate }}</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 class="mat-h3">{{T.F.METRIC.EVAL_FORM.HELP_H1|translate}}</h3>
|
<h3 class="mat-h3">{{ T.F.METRIC.EVAL_FORM.HELP_H1 | translate }}</h3>
|
||||||
<p>{{T.F.METRIC.EVAL_FORM.HELP_P2|translate}}</p>
|
<p>{{ T.F.METRIC.EVAL_FORM.HELP_P2 | translate }}</p>
|
||||||
</help-section>
|
</help-section>
|
||||||
|
|
||||||
@if (metricForDay) {
|
@if (metricForDay) {
|
||||||
<form
|
<form
|
||||||
#f="ngForm"
|
#f="ngForm"
|
||||||
name="form"
|
name="form"
|
||||||
novalidate
|
novalidate
|
||||||
>
|
>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{T.F.METRIC.EVAL_FORM.MOOD|translate}}</mat-label>
|
<mat-label>{{ T.F.METRIC.EVAL_FORM.MOOD | translate }}</mat-label>
|
||||||
<input
|
<input
|
||||||
#mood="ngModel"
|
#mood="ngModel"
|
||||||
(ngModelChange)="updateMood($event)"
|
(ngModelChange)="updateMood($event)"
|
||||||
[ngModel]="metricForDay.mood"
|
[ngModel]="metricForDay.mood"
|
||||||
matInput
|
matInput
|
||||||
max="10"
|
max="10"
|
||||||
maxlength="2"
|
maxlength="2"
|
||||||
min="1"
|
min="1"
|
||||||
name="mood"
|
name="mood"
|
||||||
required
|
required
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
<mat-hint>{{T.F.METRIC.EVAL_FORM.MOOD_HINT|translate}}</mat-hint>
|
<mat-hint>{{ T.F.METRIC.EVAL_FORM.MOOD_HINT | translate }}</mat-hint>
|
||||||
@if (mood.invalid && (mood.dirty || mood.touched)) {
|
@if (mood.invalid && (mood.dirty || mood.touched)) {
|
||||||
<mat-error> {{T.V.E_1TO10|translate}} </mat-error>
|
<mat-error> {{ T.V.E_1TO10 | translate }} </mat-error>
|
||||||
}
|
}
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{T.F.METRIC.EVAL_FORM.PRODUCTIVITY|translate}}</mat-label>
|
<mat-label>{{ T.F.METRIC.EVAL_FORM.PRODUCTIVITY | translate }}</mat-label>
|
||||||
<input
|
<input
|
||||||
#productivity="ngModel"
|
#productivity="ngModel"
|
||||||
(ngModelChange)="updateProductivity($event)"
|
(ngModelChange)="updateProductivity($event)"
|
||||||
[ngModel]="metricForDay.productivity"
|
[ngModel]="metricForDay.productivity"
|
||||||
matInput
|
matInput
|
||||||
max="10"
|
max="10"
|
||||||
maxlength="2"
|
maxlength="2"
|
||||||
min="1"
|
min="1"
|
||||||
name="productivity"
|
name="productivity"
|
||||||
required
|
required
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
<mat-hint>{{T.F.METRIC.EVAL_FORM.PRODUCTIVITY_HINT|translate}}</mat-hint>
|
<mat-hint>{{ T.F.METRIC.EVAL_FORM.PRODUCTIVITY_HINT | translate }}</mat-hint>
|
||||||
@if (productivity.invalid && (productivity.dirty || productivity.touched)) {
|
@if (productivity.invalid && (productivity.dirty || productivity.touched)) {
|
||||||
<mat-error> {{T.V.E_1TO10|translate}} </mat-error>
|
<mat-error> {{ T.V.E_1TO10 | translate }} </mat-error>
|
||||||
}
|
}
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
<chip-list-input
|
<chip-list-input
|
||||||
(addItem)="addObstruction($event)"
|
(addItem)="addObstruction($event)"
|
||||||
(addNewItem)="addNewObstruction($event)"
|
(addNewItem)="addNewObstruction($event)"
|
||||||
(removeItem)="removeObstruction($event)"
|
(removeItem)="removeObstruction($event)"
|
||||||
[label]="T.F.METRIC.EVAL_FORM.OBSTRUCTIONS|translate"
|
[label]="T.F.METRIC.EVAL_FORM.OBSTRUCTIONS | translate"
|
||||||
[model]="metricForDay.obstructions"
|
[model]="metricForDay.obstructions"
|
||||||
[suggestions]="(obstructionService.obstructions$|async)"
|
[suggestions]="obstructionService.obstructions$ | async"
|
||||||
></chip-list-input>
|
></chip-list-input>
|
||||||
<chip-list-input
|
<chip-list-input
|
||||||
(addItem)="addImprovement($event)"
|
(addItem)="addImprovement($event)"
|
||||||
(addNewItem)="addNewImprovement($event)"
|
(addNewItem)="addNewImprovement($event)"
|
||||||
(removeItem)="removeImprovement($event)"
|
(removeItem)="removeImprovement($event)"
|
||||||
[label]="T.F.METRIC.EVAL_FORM.IMPROVEMENTS|translate"
|
[label]="T.F.METRIC.EVAL_FORM.IMPROVEMENTS | translate"
|
||||||
[model]="metricForDay.improvements"
|
[model]="metricForDay.improvements"
|
||||||
[suggestions]="(improvementService.improvements$|async)"
|
[suggestions]="improvementService.improvements$ | async"
|
||||||
></chip-list-input>
|
></chip-list-input>
|
||||||
<chip-list-input
|
<chip-list-input
|
||||||
(addItem)="addImprovementTomorrow($event)"
|
(addItem)="addImprovementTomorrow($event)"
|
||||||
(addNewItem)="addNewImprovementTomorrow($event)"
|
(addNewItem)="addNewImprovementTomorrow($event)"
|
||||||
(additionalAction)="toggleImprovementRepeat($event)"
|
(additionalAction)="toggleImprovementRepeat($event)"
|
||||||
(removeItem)="removeImprovementTomorrow($event)"
|
(removeItem)="removeImprovementTomorrow($event)"
|
||||||
[additionalActionTooltipUnToggle]="T.F.METRIC.EVAL_FORM.DISABLE_REPEAT_EVERY_DAY|translate"
|
[additionalActionTooltipUnToggle]="
|
||||||
[additionalActionTooltip]="T.F.METRIC.EVAL_FORM.ENABLE_REPEAT_EVERY_DAY|translate"
|
T.F.METRIC.EVAL_FORM.DISABLE_REPEAT_EVERY_DAY | translate
|
||||||
[label]="T.F.METRIC.EVAL_FORM.IMPROVEMENTS_TOMORROW|translate"
|
"
|
||||||
[model]="metricForDay.improvementsTomorrow"
|
[additionalActionTooltip]="
|
||||||
[suggestions]="(improvementService.improvements$|async)"
|
T.F.METRIC.EVAL_FORM.ENABLE_REPEAT_EVERY_DAY | translate
|
||||||
[toggledItems]="improvementService.repeatedImprovementIds$|async"
|
"
|
||||||
additionalActionIcon="repeat"
|
[label]="T.F.METRIC.EVAL_FORM.IMPROVEMENTS_TOMORROW | translate"
|
||||||
></chip-list-input>
|
[model]="metricForDay.improvementsTomorrow"
|
||||||
</form>
|
[suggestions]="improvementService.improvements$ | async"
|
||||||
|
[toggledItems]="improvementService.repeatedImprovementIds$ | async"
|
||||||
|
additionalActionIcon="repeat"
|
||||||
|
></chip-list-input>
|
||||||
|
</form>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@if ((workContextService.isActiveWorkContextProject$|async)) {
|
@if (workContextService.isActiveWorkContextProject$ | async) {
|
||||||
<div style="text-align: center; margin-top: 8px; margin-bottom: 16px">
|
<div style="text-align: center; margin-top: 8px; margin-bottom: 16px">
|
||||||
<button
|
<button
|
||||||
(click)="addNote()"
|
(click)="addNote()"
|
||||||
mat-button
|
mat-button
|
||||||
>
|
>
|
||||||
<mat-icon>add</mat-icon>
|
<mat-icon>add</mat-icon>
|
||||||
{{T.F.METRIC.EVAL_FORM.ADD_NOTE_FOR_TOMORROW|translate}}
|
{{ T.F.METRIC.EVAL_FORM.ADD_NOTE_FOR_TOMORROW | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,29 +3,29 @@
|
||||||
class="improvements"
|
class="improvements"
|
||||||
>
|
>
|
||||||
@for (improvement of improvements; track trackById($index, improvement)) {
|
@for (improvement of improvements; track trackById($index, improvement)) {
|
||||||
<div
|
<div
|
||||||
class="improvement"
|
class="improvement"
|
||||||
mat-ripple
|
mat-ripple
|
||||||
>
|
|
||||||
<button
|
|
||||||
(click)="dismiss(improvement)"
|
|
||||||
[matTooltip]="T.G.DISMISS|translate"
|
|
||||||
class="dismiss"
|
|
||||||
disableRipple
|
|
||||||
mat-icon-button
|
|
||||||
>
|
>
|
||||||
<mat-icon>close</mat-icon>
|
<button
|
||||||
</button>
|
(click)="dismiss(improvement)"
|
||||||
<div class="title">{{improvement?.title}}</div>
|
[matTooltip]="T.G.DISMISS | translate"
|
||||||
<button
|
class="dismiss"
|
||||||
(click)="check(improvement)"
|
disableRipple
|
||||||
[matTooltip]="T.F.METRIC.BANNER.CHECK|translate"
|
mat-icon-button
|
||||||
class="check"
|
>
|
||||||
disableRipple
|
<mat-icon>close</mat-icon>
|
||||||
mat-icon-button
|
</button>
|
||||||
>
|
<div class="title">{{ improvement?.title }}</div>
|
||||||
<mat-icon>check</mat-icon>
|
<button
|
||||||
</button>
|
(click)="check(improvement)"
|
||||||
</div>
|
[matTooltip]="T.F.METRIC.BANNER.CHECK | translate"
|
||||||
|
class="check"
|
||||||
|
disableRipple
|
||||||
|
mat-icon-button
|
||||||
|
>
|
||||||
|
<mat-icon>check</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,156 +1,165 @@
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
@if (projectMetricsService.simpleMetrics$|async; as sm) {
|
@if (projectMetricsService.simpleMetrics$ | async; as sm) {
|
||||||
<section
|
<section
|
||||||
class="basic-stats"
|
class="basic-stats"
|
||||||
[@fade]
|
[@fade]
|
||||||
>
|
|
||||||
<h1
|
|
||||||
class="mat-h1"
|
|
||||||
style="text-align: center"
|
|
||||||
>
|
>
|
||||||
{{ T.PM.TITLE|translate }}
|
<h1
|
||||||
</h1>
|
class="mat-h1"
|
||||||
<!-- <h2>Basic Metrics</h2>-->
|
style="text-align: center"
|
||||||
<p><i>{{ sm.start }} – {{ sm.end }}</i></p>
|
>
|
||||||
<div class="material-table">
|
{{ T.PM.TITLE | translate }}
|
||||||
<table>
|
</h1>
|
||||||
<tr>
|
<!-- <h2>Basic Metrics</h2>-->
|
||||||
<th>{{ T.F.METRIC.CMP.TIME_SPENT|translate }}</th>
|
<p>
|
||||||
<td>{{ sm.timeSpent|msToString }}</td>
|
<i>{{ sm.start }} – {{ sm.end }}</i>
|
||||||
</tr>
|
</p>
|
||||||
<tr>
|
<div class="material-table">
|
||||||
<th>{{ T.F.METRIC.CMP.TIME_ESTIMATED|translate }}</th>
|
<table>
|
||||||
<td>{{ sm.timeEstimate|msToString }}</td>
|
<tr>
|
||||||
</tr>
|
<th>{{ T.F.METRIC.CMP.TIME_SPENT | translate }}</th>
|
||||||
<tr>
|
<td>{{ sm.timeSpent | msToString }}</td>
|
||||||
<th>{{ T.F.METRIC.CMP.TASKS_DONE_CREATED|translate }}</th>
|
</tr>
|
||||||
<td>{{ sm.nrOfCompletedTasks }} / {{ sm.nrOfAllTasks }}</td>
|
<tr>
|
||||||
</tr>
|
<th>{{ T.F.METRIC.CMP.TIME_ESTIMATED | translate }}</th>
|
||||||
<tr>
|
<td>{{ sm.timeEstimate | msToString }}</td>
|
||||||
<th>{{ T.F.METRIC.CMP.DAYS_WORKED|translate }}</th>
|
</tr>
|
||||||
<td>{{ sm.daysWorked }}</td>
|
<tr>
|
||||||
</tr>
|
<th>{{ T.F.METRIC.CMP.TASKS_DONE_CREATED | translate }}</th>
|
||||||
<tr>
|
<td>{{ sm.nrOfCompletedTasks }} / {{ sm.nrOfAllTasks }}</td>
|
||||||
<th>{{ T.F.METRIC.CMP.AVG_TASKS_PER_DAY_WORKED|translate }}</th>
|
</tr>
|
||||||
<td>{{ sm.avgTasksPerDay|number:'1.0-1' }}</td>
|
<tr>
|
||||||
</tr>
|
<th>{{ T.F.METRIC.CMP.DAYS_WORKED | translate }}</th>
|
||||||
<tr>
|
<td>{{ sm.daysWorked }}</td>
|
||||||
<th>{{ T.F.METRIC.CMP.AVG_BREAKS_PER_DAY|translate }}</th>
|
</tr>
|
||||||
<td>{{ sm.avgBreakNr|number:'1.0-1' }}</td>
|
<tr>
|
||||||
</tr>
|
<th>{{ T.F.METRIC.CMP.AVG_TASKS_PER_DAY_WORKED | translate }}</th>
|
||||||
<tr>
|
<td>{{ sm.avgTasksPerDay | number: '1.0-1' }}</td>
|
||||||
<th>{{ T.F.METRIC.CMP.AVG_TIME_SPENT_PER_DAY|translate }}</th>
|
</tr>
|
||||||
<td>{{ sm.avgTimeSpentOnDay|msToString }}</td>
|
<tr>
|
||||||
</tr>
|
<th>{{ T.F.METRIC.CMP.AVG_BREAKS_PER_DAY | translate }}</th>
|
||||||
<tr>
|
<td>{{ sm.avgBreakNr | number: '1.0-1' }}</td>
|
||||||
<th>{{ T.F.METRIC.CMP.AVG_TIME_SPENT_PER_TASK|translate }}</th>
|
</tr>
|
||||||
<td>{{ sm.avgTimeSpentOnTask|msToString }}</td>
|
<tr>
|
||||||
</tr>
|
<th>{{ T.F.METRIC.CMP.AVG_TIME_SPENT_PER_DAY | translate }}</th>
|
||||||
<tr>
|
<td>{{ sm.avgTimeSpentOnDay | msToString }}</td>
|
||||||
<th>
|
</tr>
|
||||||
{{ T.F.METRIC.CMP.AVG_TIME_SPENT_PER_TASK|translate }}
|
<tr>
|
||||||
<br />{{ T.F.METRIC.CMP.COUNTING_SUBTASKS|translate }}
|
<th>{{ T.F.METRIC.CMP.AVG_TIME_SPENT_PER_TASK | translate }}</th>
|
||||||
</th>
|
<td>{{ sm.avgTimeSpentOnTask | msToString }}</td>
|
||||||
<td>{{ sm.avgTimeSpentOnTaskIncludingSubTasks|msToString }}</td>
|
</tr>
|
||||||
</tr>
|
<tr>
|
||||||
<tr>
|
<th>
|
||||||
<th>{{ T.F.METRIC.CMP.AVG_TIME_SPENT_ON_BREAKS|translate }}</th>
|
{{ T.F.METRIC.CMP.AVG_TIME_SPENT_PER_TASK | translate }}
|
||||||
<td>{{ sm.avgBreakTime|msToString }}</td>
|
<br />{{ T.F.METRIC.CMP.COUNTING_SUBTASKS | translate }}
|
||||||
</tr>
|
</th>
|
||||||
</table>
|
<td>{{ sm.avgTimeSpentOnTaskIncludingSubTasks | msToString }}</td>
|
||||||
</div>
|
</tr>
|
||||||
</section>
|
<tr>
|
||||||
} @if (!(metricService.hasData$|async)) {
|
<th>{{ T.F.METRIC.CMP.AVG_TIME_SPENT_ON_BREAKS | translate }}</th>
|
||||||
<p style="margin-top: 32px">{{ T.F.METRIC.CMP.NO_ADDITIONAL_DATA_YET|translate }}</p>
|
<td>{{ sm.avgBreakTime | msToString }}</td>
|
||||||
} @if ((metricService.hasData$|async)) {
|
</tr>
|
||||||
<section class="metric-metrics">
|
</table>
|
||||||
<h1>{{ T.F.METRIC.CMP.GLOBAL_METRICS|translate }}</h1>
|
</div>
|
||||||
<section class="pie-charts">
|
|
||||||
@if ((metricService.improvementCountsPieChartData$|async); as improvementCounts) {
|
|
||||||
<section>
|
|
||||||
<h3>{{ T.F.METRIC.CMP.IMPROVEMENT_SELECTION_COUNT|translate }}</h3>
|
|
||||||
<canvas
|
|
||||||
[type]="pieChartType"
|
|
||||||
[data]="improvementCounts"
|
|
||||||
[legend]="(improvementCounts?.datasets[0].data.length < 12)"
|
|
||||||
[options]="pieChartOptions"
|
|
||||||
baseChart
|
|
||||||
>
|
|
||||||
</canvas>
|
|
||||||
</section>
|
|
||||||
} @if ((metricService.obstructionCountsPieChartData$|async); as obstructionCounts) {
|
|
||||||
<section>
|
|
||||||
<h3>{{ T.F.METRIC.CMP.OBSTRUCTION_SELECTION_COUNT|translate }}</h3>
|
|
||||||
<canvas
|
|
||||||
[type]="pieChartType"
|
|
||||||
[data]="obstructionCounts"
|
|
||||||
[legend]="(obstructionCounts?.datasets[0].data.length < 12)"
|
|
||||||
[options]="pieChartOptions"
|
|
||||||
baseChart
|
|
||||||
>
|
|
||||||
</canvas>
|
|
||||||
</section>
|
|
||||||
}
|
|
||||||
</section>
|
</section>
|
||||||
<section class="line-charts">
|
}
|
||||||
@if ((productivityHappiness$|async); as productivityHappiness) {
|
@if (!(metricService.hasData$ | async)) {
|
||||||
<section>
|
<p style="margin-top: 32px">
|
||||||
<h3>{{ T.F.METRIC.CMP.MOOD_PRODUCTIVITY_OVER_TIME|translate }}</h3>
|
{{ T.F.METRIC.CMP.NO_ADDITIONAL_DATA_YET | translate }}
|
||||||
<div class="chart-wrapper">
|
</p>
|
||||||
<div class="inner-chart-wrapper">
|
}
|
||||||
|
@if (metricService.hasData$ | async) {
|
||||||
|
<section class="metric-metrics">
|
||||||
|
<h1>{{ T.F.METRIC.CMP.GLOBAL_METRICS | translate }}</h1>
|
||||||
|
<section class="pie-charts">
|
||||||
|
@if (metricService.improvementCountsPieChartData$ | async; as improvementCounts) {
|
||||||
|
<section>
|
||||||
|
<h3>{{ T.F.METRIC.CMP.IMPROVEMENT_SELECTION_COUNT | translate }}</h3>
|
||||||
<canvas
|
<canvas
|
||||||
[type]="lineChartType"
|
[type]="pieChartType"
|
||||||
[data]="productivityHappiness"
|
[data]="improvementCounts"
|
||||||
[legend]="true"
|
[legend]="improvementCounts?.datasets[0].data.length < 12"
|
||||||
[options]="lineChartOptions"
|
[options]="pieChartOptions"
|
||||||
baseChart
|
|
||||||
></canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
}
|
|
||||||
</section>
|
|
||||||
</section>
|
|
||||||
} @if ((metricService.hasData$|async)) {
|
|
||||||
<section class="metric-metrics">
|
|
||||||
<h2>{{ T.F.METRIC.CMP.SIMPLE_COUNTERS|translate }}</h2>
|
|
||||||
<section class="line-charts">
|
|
||||||
@if ((simpleClickCounterData$|async); as simpleCounterClickData) {
|
|
||||||
<section>
|
|
||||||
<h3>{{ T.F.METRIC.CMP.SIMPLE_CLICK_COUNTERS_OVER_TIME|translate }}</h3>
|
|
||||||
<div class="chart-wrapper">
|
|
||||||
<div class="inner-chart-wrapper">
|
|
||||||
<canvas
|
|
||||||
[type]="lineChartType"
|
|
||||||
[data]="simpleCounterClickData"
|
|
||||||
[labels]="simpleCounterClickData.labels"
|
|
||||||
[options]="lineChartOptions"
|
|
||||||
[legend]="true"
|
|
||||||
baseChart
|
baseChart
|
||||||
>
|
>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</section>
|
||||||
</div>
|
}
|
||||||
</section>
|
@if (metricService.obstructionCountsPieChartData$ | async; as obstructionCounts) {
|
||||||
} @if ((simpleCounterStopWatchData$|async); as simpleCounterStopWatchData) {
|
<section>
|
||||||
<section>
|
<h3>{{ T.F.METRIC.CMP.OBSTRUCTION_SELECTION_COUNT | translate }}</h3>
|
||||||
<h3>{{ T.F.METRIC.CMP.SIMPLE_STOPWATCH_COUNTERS_OVER_TIME|translate }}</h3>
|
|
||||||
<div class="chart-wrapper">
|
|
||||||
<div class="inner-chart-wrapper">
|
|
||||||
<canvas
|
<canvas
|
||||||
[type]="lineChartType"
|
[type]="pieChartType"
|
||||||
[data]="simpleCounterStopWatchData"
|
[data]="obstructionCounts"
|
||||||
[labels]="simpleCounterStopWatchData.labels"
|
[legend]="obstructionCounts?.datasets[0].data.length < 12"
|
||||||
[options]="lineChartOptions"
|
[options]="pieChartOptions"
|
||||||
[legend]="true"
|
|
||||||
baseChart
|
baseChart
|
||||||
>
|
>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</section>
|
||||||
</div>
|
}
|
||||||
|
</section>
|
||||||
|
<section class="line-charts">
|
||||||
|
@if (productivityHappiness$ | async; as productivityHappiness) {
|
||||||
|
<section>
|
||||||
|
<h3>{{ T.F.METRIC.CMP.MOOD_PRODUCTIVITY_OVER_TIME | translate }}</h3>
|
||||||
|
<div class="chart-wrapper">
|
||||||
|
<div class="inner-chart-wrapper">
|
||||||
|
<canvas
|
||||||
|
[type]="lineChartType"
|
||||||
|
[data]="productivityHappiness"
|
||||||
|
[legend]="true"
|
||||||
|
[options]="lineChartOptions"
|
||||||
|
baseChart
|
||||||
|
></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
}
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
}
|
||||||
|
@if (metricService.hasData$ | async) {
|
||||||
|
<section class="metric-metrics">
|
||||||
|
<h2>{{ T.F.METRIC.CMP.SIMPLE_COUNTERS | translate }}</h2>
|
||||||
|
<section class="line-charts">
|
||||||
|
@if (simpleClickCounterData$ | async; as simpleCounterClickData) {
|
||||||
|
<section>
|
||||||
|
<h3>{{ T.F.METRIC.CMP.SIMPLE_CLICK_COUNTERS_OVER_TIME | translate }}</h3>
|
||||||
|
<div class="chart-wrapper">
|
||||||
|
<div class="inner-chart-wrapper">
|
||||||
|
<canvas
|
||||||
|
[type]="lineChartType"
|
||||||
|
[data]="simpleCounterClickData"
|
||||||
|
[labels]="simpleCounterClickData.labels"
|
||||||
|
[options]="lineChartOptions"
|
||||||
|
[legend]="true"
|
||||||
|
baseChart
|
||||||
|
>
|
||||||
|
</canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
}
|
||||||
|
@if (simpleCounterStopWatchData$ | async; as simpleCounterStopWatchData) {
|
||||||
|
<section>
|
||||||
|
<h3>{{ T.F.METRIC.CMP.SIMPLE_STOPWATCH_COUNTERS_OVER_TIME | translate }}</h3>
|
||||||
|
<div class="chart-wrapper">
|
||||||
|
<div class="inner-chart-wrapper">
|
||||||
|
<canvas
|
||||||
|
[type]="lineChartType"
|
||||||
|
[data]="simpleCounterStopWatchData"
|
||||||
|
[labels]="simpleCounterStopWatchData.labels"
|
||||||
|
[options]="lineChartOptions"
|
||||||
|
[legend]="true"
|
||||||
|
baseChart
|
||||||
|
>
|
||||||
|
</canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
}
|
||||||
</section>
|
</section>
|
||||||
}
|
|
||||||
</section>
|
</section>
|
||||||
</section>
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,55 +1,58 @@
|
||||||
@if (note) {
|
@if (note) {
|
||||||
<div
|
|
||||||
[class.isFocused]="isFocus()"
|
|
||||||
[class.isImg]="note.imgUrl"
|
|
||||||
class="note"
|
|
||||||
>
|
|
||||||
@if (note.imgUrl) {
|
|
||||||
<img
|
|
||||||
[enlargeImg]="note.imgUrl"
|
|
||||||
[src]="note.imgUrl"
|
|
||||||
(longPress)="editFullscreen($event)"
|
|
||||||
class="note-img"
|
|
||||||
/>
|
|
||||||
} @if (!note.imgUrl) {
|
|
||||||
<div class="content">
|
|
||||||
<div
|
|
||||||
(click)="editFullscreen($event)"
|
|
||||||
markdown
|
|
||||||
[data]="isLongNote ? shortenedNote : note.content"
|
|
||||||
class="markdown-preview markdown"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
<div
|
<div
|
||||||
class="bottom-controls handle-drag"
|
[class.isFocused]="isFocus()"
|
||||||
[class.isOver]="note.imgUrl"
|
[class.isImg]="note.imgUrl"
|
||||||
|
class="note"
|
||||||
>
|
>
|
||||||
@if (note.projectId) {
|
@if (note.imgUrl) {
|
||||||
<button
|
<img
|
||||||
mat-icon-button
|
[enlargeImg]="note.imgUrl"
|
||||||
(click)="togglePinToToday()"
|
[src]="note.imgUrl"
|
||||||
>
|
(longPress)="editFullscreen($event)"
|
||||||
@if (!note.isPinnedToToday) {
|
class="note-img"
|
||||||
<mat-icon>wb_sunny</mat-icon>
|
/>
|
||||||
} @if (note.isPinnedToToday) {
|
|
||||||
<mat-icon svgIcon="remove_today"></mat-icon>
|
|
||||||
}
|
|
||||||
</button>
|
|
||||||
} @if (projectTag$|async; as projectTag) {
|
|
||||||
<tag [tag]="projectTag"></tag>
|
|
||||||
}
|
}
|
||||||
<!-- <button mat-icon-button>-->
|
@if (!note.imgUrl) {
|
||||||
<!-- <mat-icon class="drag-handle-ico" svgIcon="drag_handle"></mat-icon>-->
|
<div class="content">
|
||||||
<!-- </button>-->
|
<div
|
||||||
<button
|
(click)="editFullscreen($event)"
|
||||||
[matMenuTriggerFor]="menu"
|
markdown
|
||||||
mat-icon-button
|
[data]="isLongNote ? shortenedNote : note.content"
|
||||||
|
class="markdown-preview markdown"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<div
|
||||||
|
class="bottom-controls handle-drag"
|
||||||
|
[class.isOver]="note.imgUrl"
|
||||||
>
|
>
|
||||||
<mat-icon>more_vert</mat-icon>
|
@if (note.projectId) {
|
||||||
</button>
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
(click)="togglePinToToday()"
|
||||||
|
>
|
||||||
|
@if (!note.isPinnedToToday) {
|
||||||
|
<mat-icon>wb_sunny</mat-icon>
|
||||||
|
}
|
||||||
|
@if (note.isPinnedToToday) {
|
||||||
|
<mat-icon svgIcon="remove_today"></mat-icon>
|
||||||
|
}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
@if (projectTag$ | async; as projectTag) {
|
||||||
|
<tag [tag]="projectTag"></tag>
|
||||||
|
}
|
||||||
|
<!-- <button mat-icon-button>-->
|
||||||
|
<!-- <mat-icon class="drag-handle-ico" svgIcon="drag_handle"></mat-icon>-->
|
||||||
|
<!-- </button>-->
|
||||||
|
<button
|
||||||
|
[matMenuTriggerFor]="menu"
|
||||||
|
mat-icon-button
|
||||||
|
>
|
||||||
|
<mat-icon>more_vert</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<mat-menu #menu="matMenu">
|
<mat-menu #menu="matMenu">
|
||||||
|
|
@ -59,22 +62,31 @@
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
>
|
>
|
||||||
<mat-icon>forward</mat-icon>
|
<mat-icon>forward</mat-icon>
|
||||||
{{(note.projectId ? T.F.TASK.CMP.MOVE_TO_OTHER_PROJECT :
|
{{
|
||||||
T.F.TASK.CMP.ADD_TO_PROJECT)|translate}}
|
(note.projectId
|
||||||
|
? T.F.TASK.CMP.MOVE_TO_OTHER_PROJECT
|
||||||
|
: T.F.TASK.CMP.ADD_TO_PROJECT
|
||||||
|
) | translate
|
||||||
|
}}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@if (!note.imgUrl) {
|
@if (!note.imgUrl) {
|
||||||
<button
|
<button
|
||||||
(click)="toggleLock()"
|
(click)="toggleLock()"
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
>
|
>
|
||||||
@if (note.isLock) {
|
@if (note.isLock) {
|
||||||
<mat-icon>lock</mat-icon>
|
<mat-icon>lock</mat-icon>
|
||||||
} @if (!note.isLock) {
|
}
|
||||||
<mat-icon>lock_open</mat-icon>
|
@if (!note.isLock) {
|
||||||
} {{note.isLock ? (T.F.NOTE.NOTE_CMP.ENABLE_PARSE|translate) :
|
<mat-icon>lock_open</mat-icon>
|
||||||
(T.F.NOTE.NOTE_CMP.DISABLE_PARSE|translate)}}
|
}
|
||||||
</button>
|
{{
|
||||||
|
note.isLock
|
||||||
|
? (T.F.NOTE.NOTE_CMP.ENABLE_PARSE | translate)
|
||||||
|
: (T.F.NOTE.NOTE_CMP.DISABLE_PARSE | translate)
|
||||||
|
}}
|
||||||
|
</button>
|
||||||
}
|
}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
@ -82,19 +94,21 @@
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
>
|
>
|
||||||
<mat-icon style="color: #e15d63">delete_forever</mat-icon>
|
<mat-icon style="color: #e15d63">delete_forever</mat-icon>
|
||||||
{{T.G.DELETE|translate}}
|
{{ T.G.DELETE | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<mat-menu #projectMenu="matMenu">
|
<mat-menu #projectMenu="matMenu">
|
||||||
<ng-template matMenuContent>
|
<ng-template matMenuContent>
|
||||||
@for (project of (moveToProjectList$|async); track trackByProjectId($index,
|
@for (
|
||||||
project)) {
|
project of moveToProjectList$ | async;
|
||||||
<button
|
track trackByProjectId($index, project)
|
||||||
(click)="moveNoteToProject(project.id)"
|
) {
|
||||||
mat-menu-item
|
<button
|
||||||
>
|
(click)="moveNoteToProject(project.id)"
|
||||||
{{project.title}}
|
mat-menu-item
|
||||||
</button>
|
>
|
||||||
|
{{ project.title }}
|
||||||
|
</button>
|
||||||
}
|
}
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
|
|
||||||
|
|
@ -6,22 +6,22 @@
|
||||||
mat-button
|
mat-button
|
||||||
>
|
>
|
||||||
<mat-icon>add</mat-icon>
|
<mat-icon>add</mat-icon>
|
||||||
{{ T.F.NOTE.NOTES_CMP.ADD_BTN|translate }}
|
{{ T.F.NOTE.NOTES_CMP.ADD_BTN | translate }}
|
||||||
</button>
|
</button>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@if (isDragOver) {
|
@if (isDragOver) {
|
||||||
<div
|
<div
|
||||||
@fade
|
@fade
|
||||||
class="bgc-accent drag-over-msg"
|
class="bgc-accent drag-over-msg"
|
||||||
>
|
>
|
||||||
<mat-icon>add</mat-icon>
|
<mat-icon>add</mat-icon>
|
||||||
{{ T.F.NOTE.NOTES_CMP.DROP_TO_ADD|translate }}
|
{{ T.F.NOTE.NOTES_CMP.DROP_TO_ADD | translate }}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<!---->
|
<!---->
|
||||||
@let notes = workContextService.notes$|async;
|
@let notes = workContextService.notes$ | async;
|
||||||
<div
|
<div
|
||||||
[@standardList]="notes?.length"
|
[@standardList]="notes?.length"
|
||||||
cdkDropList
|
cdkDropList
|
||||||
|
|
@ -30,16 +30,16 @@
|
||||||
class="notes"
|
class="notes"
|
||||||
>
|
>
|
||||||
<!---->
|
<!---->
|
||||||
@for( note of notes; track note.id) {
|
@for (note of notes; track note.id) {
|
||||||
<div cdkDrag>
|
<div cdkDrag>
|
||||||
<note
|
<note
|
||||||
[isFocus]="isElementWasAdded && $index===0"
|
[isFocus]="isElementWasAdded && $index === 0"
|
||||||
[note]="note"
|
[note]="note"
|
||||||
></note>
|
></note>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<!---->
|
<!---->
|
||||||
@if(notes?.length === 0) {
|
@if (notes?.length === 0) {
|
||||||
<div class="no-notes-info">{{ T.F.NOTE.NOTES_CMP.NO_NOTES|translate }}</div>
|
<div class="no-notes-info">{{ T.F.NOTE.NOTES_CMP.NO_NOTES | translate }}</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,20 @@
|
||||||
@if (!isShowAddTask) {
|
@if (!isShowAddTask) {
|
||||||
<div
|
<div
|
||||||
style="text-align: center"
|
style="text-align: center"
|
||||||
(click)="isShowAddTask = true"
|
(click)="isShowAddTask = true"
|
||||||
>
|
>
|
||||||
<button mat-button>
|
<button mat-button>
|
||||||
<mat-icon>add</mat-icon>
|
<mat-icon>add</mat-icon>
|
||||||
{{ T.G.ADD|translate }}
|
{{ T.G.ADD | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
} @if (isShowAddTask) {
|
}
|
||||||
<add-task-bar
|
@if (isShowAddTask) {
|
||||||
[isElevated]="true "
|
<add-task-bar
|
||||||
[isHideTagTitles]="true "
|
[isElevated]="true"
|
||||||
(blurred)="isShowAddTask = false"
|
[isHideTagTitles]="true"
|
||||||
(done)="isShowAddTask = false"
|
(blurred)="isShowAddTask = false"
|
||||||
[planForDay]="planForDay()"
|
(done)="isShowAddTask = false"
|
||||||
></add-task-bar>
|
[planForDay]="planForDay()"
|
||||||
|
></add-task-bar>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,22 +19,23 @@
|
||||||
* schedule tasks need to be indicated
|
* schedule tasks need to be indicated
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@if (filteredTasks$|async; as allTasks) {
|
@if (filteredTasks$ | async; as allTasks) {
|
||||||
<div
|
<div
|
||||||
class="tasks"
|
class="tasks"
|
||||||
cdkDropList
|
cdkDropList
|
||||||
cdkDropListSortingDisabled
|
cdkDropListSortingDisabled
|
||||||
[cdkDropListData]="ADD_TASK_PANEL "
|
[cdkDropListData]="ADD_TASK_PANEL"
|
||||||
(cdkDropListDropped)="drop($event)"
|
(cdkDropListDropped)="drop($event)"
|
||||||
>
|
>
|
||||||
@for (task of allTasks; track task.id) {
|
@for (task of allTasks; track task.id) {
|
||||||
<planner-task
|
<planner-task
|
||||||
cdkDrag
|
cdkDrag
|
||||||
[cdkDragData]="task"
|
[cdkDragData]="task"
|
||||||
[task]="task"
|
[task]="task"
|
||||||
></planner-task>
|
></planner-task>
|
||||||
} @if (allTasks.length === 0) {
|
}
|
||||||
<div class="empty">{{ T.F.PLANNER.NO_TASKS|translate }}</div>
|
@if (allTasks.length === 0) {
|
||||||
}
|
<div class="empty">{{ T.F.PLANNER.NO_TASKS | translate }}</div>
|
||||||
</div>
|
}
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,88 +2,98 @@
|
||||||
mat-dialog-title
|
mat-dialog-title
|
||||||
align="center"
|
align="center"
|
||||||
>
|
>
|
||||||
<span>{{ T.F.PLANNER.D.ADD_PLANNED.TITLE|translate }}</span>
|
<span>{{ T.F.PLANNER.D.ADD_PLANNED.TITLE | translate }}</span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
@if ((day$|async); as day) {
|
@if (day$ | async; as day) {
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
<header>
|
<header>
|
||||||
<!--<div class="day-estimate">{{ day.timeEstimate |roundDuration|msToString }}</div>-->
|
<!--<div class="day-estimate">{{ day.timeEstimate |roundDuration|msToString }}</div>-->
|
||||||
<div class="day-counts">
|
<div class="day-counts">
|
||||||
<span>{{ day.timeEstimate |roundDuration|msToString }}</span>
|
<span>{{ day.timeEstimate | roundDuration | msToString }}</span>
|
||||||
@if (day.itemsTotal > 5 ) {
|
@if (day.itemsTotal > 5) {
|
||||||
<mat-icon inline="true">task_alt</mat-icon>
|
<mat-icon inline="true">task_alt</mat-icon>
|
||||||
<span>{{ day.itemsTotal }}</span>
|
<span>{{ day.itemsTotal }}</span>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div class="normal-tasks">
|
<div class="normal-tasks">
|
||||||
<div class="normal-tasks-items">
|
<div class="normal-tasks-items">
|
||||||
@for (task of day.tasks; track task.id) {
|
@for (task of day.tasks; track task.id) {
|
||||||
<planner-task
|
<planner-task
|
||||||
[task]="task"
|
[task]="task"
|
||||||
[day]="day.dayDate"
|
[day]="day.dayDate"
|
||||||
></planner-task>
|
></planner-task>
|
||||||
}
|
|
||||||
<!-- -->
|
|
||||||
@for (repeatProjection of day.noStartTimeRepeatProjections; track
|
|
||||||
repeatProjection.id) {
|
|
||||||
<planner-repeat-projection
|
|
||||||
[repeatCfg]="repeatProjection.repeatCfg"
|
|
||||||
></planner-repeat-projection>
|
|
||||||
}
|
|
||||||
<!-- -->
|
|
||||||
@if (day.tasks.length === 0 && day.noStartTimeRepeatProjections.length === 0) {
|
|
||||||
<div class="empty">{{ T.F.PLANNER.NO_TASKS|translate }}</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<add-task-inline [planForDay]="day.dayDate"></add-task-inline>
|
|
||||||
</div>
|
|
||||||
<div class="scheduled">
|
|
||||||
<div class="section-title">
|
|
||||||
<mat-icon>alarm</mat-icon>
|
|
||||||
</div>
|
|
||||||
<div class="scheduled-items">
|
|
||||||
@for (scheduledItem of day.scheduledIItems; track scheduledItem.id) {
|
|
||||||
<div
|
|
||||||
class="scheduled-item"
|
|
||||||
[ngClass]="scheduledItem.type"
|
|
||||||
>
|
|
||||||
@if (scheduledItem.type === SCHEDULE_ITEM_TYPE.Task) {
|
|
||||||
<div
|
|
||||||
class="time"
|
|
||||||
(click)="editTaskReminderOrReScheduleIfPossible(scheduledItem.task)"
|
|
||||||
>
|
|
||||||
<span>{{ (scheduledItem.start|roundDuration|date:'HH:mm') }}</span>
|
|
||||||
<mat-icon>alarm</mat-icon>
|
|
||||||
</div>
|
|
||||||
} @else {
|
|
||||||
<div class="time">{{ (scheduledItem.start|roundDuration|date:'HH:mm') }}</div>
|
|
||||||
}
|
}
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@switch (scheduledItem.type) { @case (SCHEDULE_ITEM_TYPE.Task) {
|
@for (
|
||||||
<planner-task
|
repeatProjection of day.noStartTimeRepeatProjections;
|
||||||
[task]="scheduledItem.task"
|
track repeatProjection.id
|
||||||
[day]="day.dayDate"
|
) {
|
||||||
></planner-task>
|
<planner-repeat-projection
|
||||||
} @case (SCHEDULE_ITEM_TYPE.CalEvent) {
|
[repeatCfg]="repeatProjection.repeatCfg"
|
||||||
<planner-calendar-event
|
></planner-repeat-projection>
|
||||||
[calendarEvent]="scheduledItem.calendarEvent"
|
}
|
||||||
></planner-calendar-event>
|
<!-- -->
|
||||||
} @case (SCHEDULE_ITEM_TYPE.RepeatProjection) {
|
@if (day.tasks.length === 0 && day.noStartTimeRepeatProjections.length === 0) {
|
||||||
<planner-repeat-projection
|
<div class="empty">{{ T.F.PLANNER.NO_TASKS | translate }}</div>
|
||||||
[repeatCfg]="scheduledItem.repeatCfg"
|
}
|
||||||
></planner-repeat-projection>
|
|
||||||
} }
|
|
||||||
</div>
|
</div>
|
||||||
}
|
<add-task-inline [planForDay]="day.dayDate"></add-task-inline>
|
||||||
<!-- -->
|
|
||||||
@if (day.scheduledIItems.length === 0) {
|
|
||||||
<div class="empty">{{ T.F.PLANNER.PLAN_VIEW.NO_SCHEDULED_ITEMS|translate }}</div>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="scheduled">
|
||||||
</mat-dialog-content>
|
<div class="section-title">
|
||||||
|
<mat-icon>alarm</mat-icon>
|
||||||
|
</div>
|
||||||
|
<div class="scheduled-items">
|
||||||
|
@for (scheduledItem of day.scheduledIItems; track scheduledItem.id) {
|
||||||
|
<div
|
||||||
|
class="scheduled-item"
|
||||||
|
[ngClass]="scheduledItem.type"
|
||||||
|
>
|
||||||
|
@if (scheduledItem.type === SCHEDULE_ITEM_TYPE.Task) {
|
||||||
|
<div
|
||||||
|
class="time"
|
||||||
|
(click)="editTaskReminderOrReScheduleIfPossible(scheduledItem.task)"
|
||||||
|
>
|
||||||
|
<span>{{ scheduledItem.start | roundDuration | date: 'HH:mm' }}</span>
|
||||||
|
<mat-icon>alarm</mat-icon>
|
||||||
|
</div>
|
||||||
|
} @else {
|
||||||
|
<div class="time">
|
||||||
|
{{ scheduledItem.start | roundDuration | date: 'HH:mm' }}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<!-- -->
|
||||||
|
@switch (scheduledItem.type) {
|
||||||
|
@case (SCHEDULE_ITEM_TYPE.Task) {
|
||||||
|
<planner-task
|
||||||
|
[task]="scheduledItem.task"
|
||||||
|
[day]="day.dayDate"
|
||||||
|
></planner-task>
|
||||||
|
}
|
||||||
|
@case (SCHEDULE_ITEM_TYPE.CalEvent) {
|
||||||
|
<planner-calendar-event
|
||||||
|
[calendarEvent]="scheduledItem.calendarEvent"
|
||||||
|
></planner-calendar-event>
|
||||||
|
}
|
||||||
|
@case (SCHEDULE_ITEM_TYPE.RepeatProjection) {
|
||||||
|
<planner-repeat-projection
|
||||||
|
[repeatCfg]="scheduledItem.repeatCfg"
|
||||||
|
></planner-repeat-projection>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<!-- -->
|
||||||
|
@if (day.scheduledIItems.length === 0) {
|
||||||
|
<div class="empty">
|
||||||
|
{{ T.F.PLANNER.PLAN_VIEW.NO_SCHEDULED_ITEMS | translate }}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</mat-dialog-content>
|
||||||
}
|
}
|
||||||
|
|
||||||
<mat-dialog-actions align="end">
|
<mat-dialog-actions align="end">
|
||||||
|
|
@ -93,7 +103,7 @@
|
||||||
mat-button
|
mat-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
{{ T.G.DISMISS|translate }}
|
{{ T.G.DISMISS | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
@ -102,6 +112,6 @@
|
||||||
(click)="addTasksToToday()"
|
(click)="addTasksToToday()"
|
||||||
>
|
>
|
||||||
<mat-icon>wb_sunny</mat-icon>
|
<mat-icon>wb_sunny</mat-icon>
|
||||||
{{ T.F.PLANNER.D.ADD_PLANNED.ADD_TO_TODAY|translate }}
|
{{ T.F.PLANNER.D.ADD_PLANNED.ADD_TO_TODAY | translate }}
|
||||||
</button>
|
</button>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
|
|
|
||||||
|
|
@ -6,44 +6,44 @@
|
||||||
<!-- >-->
|
<!-- >-->
|
||||||
<!-- <mat-icon>history</mat-icon>-->
|
<!-- <mat-icon>history</mat-icon>-->
|
||||||
<!-- </button>-->
|
<!-- </button>-->
|
||||||
@if(isShowRemoveFromToday()){
|
@if (isShowRemoveFromToday()) {
|
||||||
<button
|
<button
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
(click)="quickAccessBtnClick(0)"
|
(click)="quickAccessBtnClick(0)"
|
||||||
[matTooltip]="(T.F.TASK.D_SCHEDULE_TASK.QA_REMOVE_TODAY|translate)"
|
[matTooltip]="T.F.TASK.D_SCHEDULE_TASK.QA_REMOVE_TODAY | translate"
|
||||||
>
|
>
|
||||||
<mat-icon svgIcon="remove_today"></mat-icon>
|
<mat-icon svgIcon="remove_today"></mat-icon>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@if(isShowAddToToday()){
|
@if (isShowAddToToday()) {
|
||||||
<button
|
<button
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
(click)="quickAccessBtnClick(1)"
|
(click)="quickAccessBtnClick(1)"
|
||||||
[matTooltip]="(T.F.TASK.D_SCHEDULE_TASK.QA_TODAY|translate)"
|
[matTooltip]="T.F.TASK.D_SCHEDULE_TASK.QA_TODAY | translate"
|
||||||
>
|
>
|
||||||
<mat-icon>wb_sunny</mat-icon>
|
<mat-icon>wb_sunny</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
(click)="quickAccessBtnClick(2)"
|
(click)="quickAccessBtnClick(2)"
|
||||||
[matTooltip]="(T.F.TASK.D_SCHEDULE_TASK.QA_TOMORROW|translate)"
|
[matTooltip]="T.F.TASK.D_SCHEDULE_TASK.QA_TOMORROW | translate"
|
||||||
>
|
>
|
||||||
<mat-icon svgIcon="tomorrow"></mat-icon>
|
<mat-icon svgIcon="tomorrow"></mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
(click)="quickAccessBtnClick(3)"
|
(click)="quickAccessBtnClick(3)"
|
||||||
[matTooltip]="(T.F.TASK.D_SCHEDULE_TASK.QA_NEXT_WEEK|translate)"
|
[matTooltip]="T.F.TASK.D_SCHEDULE_TASK.QA_NEXT_WEEK | translate"
|
||||||
>
|
>
|
||||||
<mat-icon svgIcon="next_week"></mat-icon>
|
<mat-icon svgIcon="next_week"></mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
(click)="quickAccessBtnClick(4)"
|
(click)="quickAccessBtnClick(4)"
|
||||||
[matTooltip]="(T.F.TASK.D_SCHEDULE_TASK.QA_NEXT_MONTH|translate)"
|
[matTooltip]="T.F.TASK.D_SCHEDULE_TASK.QA_NEXT_MONTH | translate"
|
||||||
>
|
>
|
||||||
<mat-icon>bedtime</mat-icon>
|
<mat-icon>bedtime</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -58,12 +58,12 @@
|
||||||
></mat-calendar>
|
></mat-calendar>
|
||||||
|
|
||||||
@if (isShowEnterMsg) {
|
@if (isShowEnterMsg) {
|
||||||
<div
|
<div
|
||||||
class="press-enter-msg"
|
class="press-enter-msg"
|
||||||
@fade
|
@fade
|
||||||
>
|
>
|
||||||
{{ T.DATETIME_SCHEDULE.PRESS_ENTER_AGAIN|translate }}
|
{{ T.DATETIME_SCHEDULE.PRESS_ENTER_AGAIN | translate }}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="form-ctrl-wrapper">
|
<div class="form-ctrl-wrapper">
|
||||||
|
|
@ -79,31 +79,31 @@
|
||||||
(keydown)="onTimeKeyDown($event)"
|
(keydown)="onTimeKeyDown($event)"
|
||||||
/>
|
/>
|
||||||
@if (selectedTime) {
|
@if (selectedTime) {
|
||||||
<mat-icon
|
<mat-icon
|
||||||
style="cursor: pointer"
|
style="cursor: pointer"
|
||||||
matSuffix
|
matSuffix
|
||||||
(click)="onTimeClear($event)"
|
(click)="onTimeClear($event)"
|
||||||
>close
|
>close
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
}
|
}
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
@if (selectedTime) {
|
@if (selectedTime) {
|
||||||
<mat-form-field [@expandFade]>
|
<mat-form-field [@expandFade]>
|
||||||
<mat-icon matPrefix>alarm</mat-icon>
|
<mat-icon matPrefix>alarm</mat-icon>
|
||||||
<mat-label>{{ (T.F.TASK.D_SCHEDULE_TASK.REMIND_AT|translate) }}</mat-label>
|
<mat-label>{{ T.F.TASK.D_SCHEDULE_TASK.REMIND_AT | translate }}</mat-label>
|
||||||
<mat-select
|
<mat-select
|
||||||
[(ngModel)]="selectedReminderCfgId"
|
[(ngModel)]="selectedReminderCfgId"
|
||||||
name="type"
|
name="type"
|
||||||
required="true"
|
required="true"
|
||||||
>
|
>
|
||||||
@for (remindOption of remindAvailableOptions; track remindOption.value) {
|
@for (remindOption of remindAvailableOptions; track remindOption.value) {
|
||||||
<mat-option [value]="remindOption.value">
|
<mat-option [value]="remindOption.value">
|
||||||
{{ (remindOption.label|translate) }}
|
{{ remindOption.label | translate }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
}
|
}
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -114,20 +114,21 @@
|
||||||
type="button"
|
type="button"
|
||||||
(click)="close()"
|
(click)="close()"
|
||||||
>
|
>
|
||||||
{{ T.G.CANCEL|translate }}
|
{{ T.G.CANCEL | translate }}
|
||||||
</button>
|
</button>
|
||||||
@if (data.task.plannedAt || (plannedDayForTask && plannedDayForTask !== todayStr)) {
|
@if (data.task.plannedAt || (plannedDayForTask && plannedDayForTask !== todayStr)) {
|
||||||
<button
|
<button
|
||||||
(click)="remove()"
|
(click)="remove()"
|
||||||
color="warn"
|
color="warn"
|
||||||
mat-stroked-button
|
mat-stroked-button
|
||||||
>
|
>
|
||||||
@if (selectedTime) {
|
@if (selectedTime) {
|
||||||
<mat-icon>alarm_off</mat-icon>
|
<mat-icon>alarm_off</mat-icon>
|
||||||
} @else {
|
} @else {
|
||||||
<mat-icon>event_busy</mat-icon>
|
<mat-icon>event_busy</mat-icon>
|
||||||
} {{ T.F.TASK.D_SCHEDULE_TASK.UNSCHEDULE|translate }}
|
}
|
||||||
</button>
|
{{ T.F.TASK.D_SCHEDULE_TASK.UNSCHEDULE | translate }}
|
||||||
|
</button>
|
||||||
}
|
}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
@ -136,9 +137,10 @@
|
||||||
(click)="submit()"
|
(click)="submit()"
|
||||||
>
|
>
|
||||||
@if (selectedTime) {
|
@if (selectedTime) {
|
||||||
<mat-icon>alarm</mat-icon>
|
<mat-icon>alarm</mat-icon>
|
||||||
} @else {
|
} @else {
|
||||||
<mat-icon>today</mat-icon>
|
<mat-icon>today</mat-icon>
|
||||||
} {{ T.F.TASK.D_SCHEDULE_TASK.SCHEDULE|translate }}
|
}
|
||||||
|
{{ T.F.TASK.D_SCHEDULE_TASK.SCHEDULE | translate }}
|
||||||
</button>
|
</button>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,6 @@
|
||||||
{{ calendarEvent().title }}
|
{{ calendarEvent().title }}
|
||||||
<!-- {{event.start|date:'HH:mm'}} – {{(event.start + event.duration)|date:'HH:mm'}}-->
|
<!-- {{event.start|date:'HH:mm'}} – {{(event.start + event.duration)|date:'HH:mm'}}-->
|
||||||
</div>
|
</div>
|
||||||
<div class="planner-time-remaining-shared">{{ calendarEvent().duration|msToString }}</div>
|
<div class="planner-time-remaining-shared">
|
||||||
|
{{ calendarEvent().duration | msToString }}
|
||||||
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,19 @@
|
||||||
<header>
|
<header>
|
||||||
<div class="day-title">
|
<div class="day-title">
|
||||||
@if (day.isToday) {
|
@if (day.isToday) {
|
||||||
<mat-icon inline="true">wb_sunny</mat-icon>
|
<mat-icon inline="true">wb_sunny</mat-icon>
|
||||||
} {{ day.dayDate|date:'EEE' }}
|
}
|
||||||
<span class="date">{{ day.dayDate|shortDate2 }}</span>
|
{{ day.dayDate | date: 'EEE' }}
|
||||||
|
<span class="date">{{ day.dayDate | shortDate2 }}</span>
|
||||||
</div>
|
</div>
|
||||||
<!--<div class="day-estimate">{{ day.timeEstimate |roundDuration|msToString }}</div>-->
|
<!--<div class="day-estimate">{{ day.timeEstimate |roundDuration|msToString }}</div>-->
|
||||||
|
|
||||||
<div class="day-counts">
|
<div class="day-counts">
|
||||||
<span>{{ day.timeEstimate |roundDuration|msToString }}</span>
|
<span>{{ day.timeEstimate | roundDuration | msToString }}</span>
|
||||||
|
|
||||||
@if (day.itemsTotal > 5 ) {
|
@if (day.itemsTotal > 5) {
|
||||||
<mat-icon inline="true">task_alt</mat-icon>
|
<mat-icon inline="true">task_alt</mat-icon>
|
||||||
<span>{{ day.itemsTotal }}</span>
|
<span>{{ day.itemsTotal }}</span>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
@ -25,25 +26,27 @@
|
||||||
(cdkDropListDropped)="drop('TODO', day.tasks, $event)"
|
(cdkDropListDropped)="drop('TODO', day.tasks, $event)"
|
||||||
>
|
>
|
||||||
@for (task of day.tasks; track task.id) {
|
@for (task of day.tasks; track task.id) {
|
||||||
<planner-task
|
<planner-task
|
||||||
cdkDrag
|
cdkDrag
|
||||||
[cdkDragData]="task"
|
[cdkDragData]="task"
|
||||||
[task]="task"
|
[task]="task"
|
||||||
[day]="day.dayDate"
|
[day]="day.dayDate"
|
||||||
></planner-task>
|
></planner-task>
|
||||||
}
|
}
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@for (repeatProjection of day.noStartTimeRepeatProjections; track repeatProjection.id)
|
@for (
|
||||||
{
|
repeatProjection of day.noStartTimeRepeatProjections;
|
||||||
<planner-repeat-projection
|
track repeatProjection.id
|
||||||
[repeatCfg]="repeatProjection.repeatCfg"
|
) {
|
||||||
></planner-repeat-projection>
|
<planner-repeat-projection
|
||||||
|
[repeatCfg]="repeatProjection.repeatCfg"
|
||||||
|
></planner-repeat-projection>
|
||||||
}
|
}
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@if (day.tasks.length === 0 && day.noStartTimeRepeatProjections.length === 0) {
|
@if (day.tasks.length === 0 && day.noStartTimeRepeatProjections.length === 0) {
|
||||||
<div class="empty">{{ T.F.PLANNER.NO_TASKS|translate }}</div>
|
<div class="empty">{{ T.F.PLANNER.NO_TASKS | translate }}</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -63,51 +66,55 @@
|
||||||
(cdkDropListDropped)="drop('SCHEDULED', day.scheduledIItems, $event)"
|
(cdkDropListDropped)="drop('SCHEDULED', day.scheduledIItems, $event)"
|
||||||
>
|
>
|
||||||
@for (scheduledItem of day.scheduledIItems; track scheduledItem.id) {
|
@for (scheduledItem of day.scheduledIItems; track scheduledItem.id) {
|
||||||
<div
|
|
||||||
class="scheduled-item"
|
|
||||||
[ngClass]="scheduledItem.type"
|
|
||||||
>
|
|
||||||
@if (scheduledItem.type === SCHEDULE_ITEM_TYPE.Task) {
|
|
||||||
<div
|
<div
|
||||||
class="time"
|
class="scheduled-item"
|
||||||
(click)="editTaskReminderOrReScheduleIfPossible(scheduledItem.task)"
|
[ngClass]="scheduledItem.type"
|
||||||
>
|
>
|
||||||
<span
|
@if (scheduledItem.type === SCHEDULE_ITEM_TYPE.Task) {
|
||||||
class="time-time"
|
<div
|
||||||
[innerHTML]="scheduledItem.start|roundDuration|shortTime2"
|
class="time"
|
||||||
></span>
|
(click)="editTaskReminderOrReScheduleIfPossible(scheduledItem.task)"
|
||||||
<mat-icon>alarm</mat-icon>
|
>
|
||||||
</div>
|
<span
|
||||||
} @else {
|
class="time-time"
|
||||||
<div
|
[innerHTML]="scheduledItem.start | roundDuration | shortTime2"
|
||||||
class="time time-time"
|
></span>
|
||||||
[innerHTML]="scheduledItem.start|roundDuration|shortTime2"
|
<mat-icon>alarm</mat-icon>
|
||||||
></div>
|
</div>
|
||||||
}
|
} @else {
|
||||||
|
<div
|
||||||
|
class="time time-time"
|
||||||
|
[innerHTML]="scheduledItem.start | roundDuration | shortTime2"
|
||||||
|
></div>
|
||||||
|
}
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@switch (scheduledItem.type) { @case (SCHEDULE_ITEM_TYPE.Task) {
|
@switch (scheduledItem.type) {
|
||||||
<planner-task
|
@case (SCHEDULE_ITEM_TYPE.Task) {
|
||||||
cdkDrag
|
<planner-task
|
||||||
[task]="scheduledItem.task"
|
cdkDrag
|
||||||
[day]="day.dayDate"
|
[task]="scheduledItem.task"
|
||||||
[cdkDragData]="scheduledItem.task"
|
[day]="day.dayDate"
|
||||||
></planner-task>
|
[cdkDragData]="scheduledItem.task"
|
||||||
} @case (SCHEDULE_ITEM_TYPE.CalEvent) {
|
></planner-task>
|
||||||
<planner-calendar-event
|
}
|
||||||
[calendarEvent]="scheduledItem.calendarEvent"
|
@case (SCHEDULE_ITEM_TYPE.CalEvent) {
|
||||||
></planner-calendar-event>
|
<planner-calendar-event
|
||||||
} @case (SCHEDULE_ITEM_TYPE.RepeatProjection) {
|
[calendarEvent]="scheduledItem.calendarEvent"
|
||||||
<planner-repeat-projection
|
></planner-calendar-event>
|
||||||
[repeatCfg]="scheduledItem.repeatCfg"
|
}
|
||||||
></planner-repeat-projection>
|
@case (SCHEDULE_ITEM_TYPE.RepeatProjection) {
|
||||||
} }
|
<planner-repeat-projection
|
||||||
</div>
|
[repeatCfg]="scheduledItem.repeatCfg"
|
||||||
|
></planner-repeat-projection>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@if (day.scheduledIItems.length === 0) {
|
@if (day.scheduledIItems.length === 0) {
|
||||||
<div class="empty">{{ T.F.PLANNER.PLAN_VIEW.NO_SCHEDULED_ITEMS|translate }}</div>
|
<div class="empty">{{ T.F.PLANNER.PLAN_VIEW.NO_SCHEDULED_ITEMS | translate }}</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="days">
|
<div class="days">
|
||||||
@for (day of days$|async; track day.dayDate) {
|
@for (day of days$ | async; track day.dayDate) {
|
||||||
<planner-day [day]="day"></planner-day>
|
<planner-day [day]="day"></planner-day>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
<div
|
<div
|
||||||
(click)="editTaskRepeatCfg()"
|
(click)="editTaskRepeatCfg()"
|
||||||
matTooltip="{{ T.F.PLANNER.EDIT_REPEATED_TASK|translate: {taskName: repeatCfg().title} }}"
|
matTooltip="{{
|
||||||
|
T.F.PLANNER.EDIT_REPEATED_TASK | translate: { taskName: repeatCfg().title }
|
||||||
|
}}"
|
||||||
>
|
>
|
||||||
<mat-icon svgIcon="repeat"></mat-icon>
|
<mat-icon svgIcon="repeat"></mat-icon>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
|
|
@ -8,11 +10,14 @@
|
||||||
<!-- {{event.start|date:'HH:mm'}} – {{(event.start + event.duration)|date:'HH:mm'}}-->
|
<!-- {{event.start|date:'HH:mm'}} – {{(event.start + event.duration)|date:'HH:mm'}}-->
|
||||||
</div>
|
</div>
|
||||||
<div class="planner-time-remaining-shared">
|
<div class="planner-time-remaining-shared">
|
||||||
@if (overWriteTimeEstimate() > 0) { {{ overWriteTimeEstimate()|msToString }} <br />
|
@if (overWriteTimeEstimate() > 0) {
|
||||||
<span class="original-time-remaining"
|
{{ overWriteTimeEstimate() | msToString }} <br />
|
||||||
>({{ repeatCfg().defaultEstimate|msToString }})</span
|
<span class="original-time-remaining"
|
||||||
>
|
>({{ repeatCfg().defaultEstimate | msToString }})</span
|
||||||
<!--- -->
|
>
|
||||||
} @else { {{ repeatCfg().defaultEstimate|msToString }} }
|
<!--- -->
|
||||||
|
} @else {
|
||||||
|
{{ repeatCfg().defaultEstimate | msToString }}
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -6,28 +6,30 @@
|
||||||
svgIcon="drag_handle"
|
svgIcon="drag_handle"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
@if (isCurrent) {
|
@if (isCurrent) {
|
||||||
<mat-icon class="play-icon-indicator">play_arrow </mat-icon>
|
<mat-icon class="play-icon-indicator">play_arrow </mat-icon>
|
||||||
}
|
}
|
||||||
<div class="type-ico-wrapper">
|
<div class="type-ico-wrapper">
|
||||||
@if (task.repeatCfgId) {
|
@if (task.repeatCfgId) {
|
||||||
<div>
|
<div>
|
||||||
@if (!isRepeatTaskCreatedToday) {
|
@if (!isRepeatTaskCreatedToday) {
|
||||||
<div class="repeat-date-badge">{{ task.created|shortDate2 }}</div>
|
<div class="repeat-date-badge">{{ task.created | shortDate2 }}</div>
|
||||||
} @if (task.repeatCfgId) {
|
}
|
||||||
<mat-icon
|
@if (task.repeatCfgId) {
|
||||||
[style.transform]="isCurrent ? 'scale(1.4)': ''"
|
<mat-icon
|
||||||
svgIcon="repeat"
|
[style.transform]="isCurrent ? 'scale(1.4)' : ''"
|
||||||
>
|
svgIcon="repeat"
|
||||||
</mat-icon>
|
>
|
||||||
}
|
</mat-icon>
|
||||||
</div>
|
}
|
||||||
} @if (task.issueId) {
|
</div>
|
||||||
<div>
|
}
|
||||||
@if (task.issuePoints) {
|
@if (task.issueId) {
|
||||||
<div class="mini-badge bgc-primary">{{ task.issuePoints }}</div>
|
<div>
|
||||||
}
|
@if (task.issuePoints) {
|
||||||
<mat-icon [svgIcon]="task.issueType|issueIcon"></mat-icon>
|
<div class="mini-badge bgc-primary">{{ task.issuePoints }}</div>
|
||||||
</div>
|
}
|
||||||
|
<mat-icon [svgIcon]="task.issueType | issueIcon"></mat-icon>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -40,7 +42,7 @@
|
||||||
>
|
>
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
@if (parentTitle) {
|
@if (parentTitle) {
|
||||||
<div class="parent-title">{{ parentTitle }}</div>
|
<div class="parent-title">{{ parentTitle }}</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="title">{{ task.title }}</div>
|
<div class="title">{{ task.title }}</div>
|
||||||
|
|
@ -60,15 +62,15 @@
|
||||||
class="planner-time-remaining-shared"
|
class="planner-time-remaining-shared"
|
||||||
>
|
>
|
||||||
@if (task.subTaskIds?.length) {
|
@if (task.subTaskIds?.length) {
|
||||||
<mat-icon
|
<mat-icon
|
||||||
svgIcon="estimate_remaining"
|
svgIcon="estimate_remaining"
|
||||||
inline="true"
|
inline="true"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
}
|
}
|
||||||
|
|
||||||
<inline-input
|
<inline-input
|
||||||
(changed)="updateTimeEstimate( $event)"
|
(changed)="updateTimeEstimate($event)"
|
||||||
[displayValue]="timeEstimate|msToString"
|
[displayValue]="timeEstimate | msToString"
|
||||||
[type]="'duration'"
|
[type]="'duration'"
|
||||||
[value]="timeEstimate"
|
[value]="timeEstimate"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -37,27 +37,27 @@
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container better-drawer-side>
|
<ng-container better-drawer-side>
|
||||||
<add-task-panel-planner (closePanel)="isPanelOpen=false"></add-task-panel-planner>
|
<add-task-panel-planner (closePanel)="isPanelOpen = false"></add-task-panel-planner>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</better-simple-drawer>
|
</better-simple-drawer>
|
||||||
|
|
||||||
@if (!isPanelOpen) {
|
@if (!isPanelOpen) {
|
||||||
<div class="fab-wrapper FAB-BTN">
|
<div class="fab-wrapper FAB-BTN">
|
||||||
<button
|
<button
|
||||||
mat-fab
|
mat-fab
|
||||||
class="show-xs-only"
|
class="show-xs-only"
|
||||||
color="primary"
|
color="primary"
|
||||||
(click)="layoutService.showAddTaskBar()"
|
(click)="layoutService.showAddTaskBar()"
|
||||||
>
|
>
|
||||||
<mat-icon>add</mat-icon>
|
<mat-icon>add</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
mat-fab
|
mat-fab
|
||||||
color="primary"
|
color="primary"
|
||||||
matTooltip="{{T.F.PLANNER.TASK_DRAWER|translate}}"
|
matTooltip="{{ T.F.PLANNER.TASK_DRAWER | translate }}"
|
||||||
(click)="isPanelOpen = true"
|
(click)="isPanelOpen = true"
|
||||||
>
|
>
|
||||||
<mat-icon>playlist_add</mat-icon>
|
<mat-icon>playlist_add</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,21 @@
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
@if (!(isManualPauseWork$|async)) {
|
@if (!(isManualPauseWork$ | async)) {
|
||||||
<div>
|
<div>
|
||||||
<p
|
<p
|
||||||
[innerHTML]="T.F.POMODORO.FINISH_SESSION_X|translate:{nr: (currentCycle$|async)}"
|
[innerHTML]="
|
||||||
></p>
|
T.F.POMODORO.FINISH_SESSION_X | translate: { nr: (currentCycle$ | async) }
|
||||||
<p>{{T.F.POMODORO.ENJOY_YOURSELF|translate}}</p>
|
"
|
||||||
</div>
|
></p>
|
||||||
} @if ((isManualPauseWork$|async)) {
|
<p>{{ T.F.POMODORO.ENJOY_YOURSELF | translate }}</p>
|
||||||
<div>
|
</div>
|
||||||
<p>{{T.F.POMODORO.BREAK_IS_DONE|translate}}</p>
|
}
|
||||||
</div>
|
@if (isManualPauseWork$ | async) {
|
||||||
|
<div>
|
||||||
|
<p>{{ T.F.POMODORO.BREAK_IS_DONE | translate }}</p>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="timer">{{currentTime$|async|msToMinuteClockString}}</div>
|
<div class="timer">{{ currentTime$ | async | msToMinuteClockString }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|
@ -24,35 +27,37 @@
|
||||||
color="primary"
|
color="primary"
|
||||||
mat-button
|
mat-button
|
||||||
>
|
>
|
||||||
{{T.G.CLOSE|translate}}
|
{{ T.G.CLOSE | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@if ((isManualPauseBreak$|async)) {
|
@if (isManualPauseBreak$ | async) {
|
||||||
<button
|
<button
|
||||||
(click)="startBreak()"
|
(click)="startBreak()"
|
||||||
color="primary"
|
color="primary"
|
||||||
mat-stroked-button
|
mat-stroked-button
|
||||||
>
|
>
|
||||||
<mat-icon>free_breakfast</mat-icon>
|
<mat-icon>free_breakfast</mat-icon>
|
||||||
<span>{{T.F.POMODORO.START_BREAK|translate}}</span>
|
<span>{{ T.F.POMODORO.START_BREAK | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
} @if (!(isManualPauseWork$|async)) {
|
}
|
||||||
<button
|
@if (!(isManualPauseWork$ | async)) {
|
||||||
(click)="nextSession(true)"
|
<button
|
||||||
color="primary"
|
(click)="nextSession(true)"
|
||||||
mat-stroked-button
|
color="primary"
|
||||||
>
|
mat-stroked-button
|
||||||
<mat-icon>skip_next</mat-icon>
|
>
|
||||||
<span>{{T.F.POMODORO.SKIP_BREAK|translate}}</span>
|
<mat-icon>skip_next</mat-icon>
|
||||||
</button>
|
<span>{{ T.F.POMODORO.SKIP_BREAK | translate }}</span>
|
||||||
} @if ((isManualPauseWork$|async)) {
|
</button>
|
||||||
<button
|
}
|
||||||
(click)="nextSession()"
|
@if (isManualPauseWork$ | async) {
|
||||||
color="primary"
|
<button
|
||||||
mat-stroked-button
|
(click)="nextSession()"
|
||||||
>
|
color="primary"
|
||||||
<mat-icon>play_arrow</mat-icon>
|
mat-stroked-button
|
||||||
{{T.F.POMODORO.BACK_TO_WORK|translate}}
|
>
|
||||||
</button>
|
<mat-icon>play_arrow</mat-icon>
|
||||||
|
{{ T.F.POMODORO.BACK_TO_WORK | translate }}
|
||||||
|
</button>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,41 @@
|
||||||
<div class="page-wrapper component-wrapper">
|
<div class="page-wrapper component-wrapper">
|
||||||
<h1 style="margin-top: 16px; text-align: center">
|
<h1 style="margin-top: 16px; text-align: center">
|
||||||
{{T.F.PROCRASTINATION.H1|translate}}
|
{{ T.F.PROCRASTINATION.H1 | translate }}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<mat-tab-group dynamicHeight>
|
<mat-tab-group dynamicHeight>
|
||||||
<mat-tab [label]="T.F.PROCRASTINATION.INTRO.TITLE|translate">
|
<mat-tab [label]="T.F.PROCRASTINATION.INTRO.TITLE | translate">
|
||||||
<section class="tab-inner">
|
<section class="tab-inner">
|
||||||
<p>{{T.F.PROCRASTINATION.P1|translate}}</p>
|
<p>{{ T.F.PROCRASTINATION.P1 | translate }}</p>
|
||||||
<p [innerHTML]="T.F.PROCRASTINATION.P2|translate"></p>
|
<p [innerHTML]="T.F.PROCRASTINATION.P2 | translate"></p>
|
||||||
|
|
||||||
<div class="procrastination-graph">
|
<div class="procrastination-graph">
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<div class="text-item">{{T.F.PROCRASTINATION.INTRO.FEAR|translate}}</div>
|
<div class="text-item">{{ T.F.PROCRASTINATION.INTRO.FEAR | translate }}</div>
|
||||||
<div class="text-item">{{T.F.PROCRASTINATION.INTRO.AVOIDING|translate}}</div>
|
<div class="text-item">
|
||||||
|
{{ T.F.PROCRASTINATION.INTRO.AVOIDING | translate }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<mat-icon>sync</mat-icon>
|
<mat-icon>sync</mat-icon>
|
||||||
<div class="text-item">{{T.F.PROCRASTINATION.INTRO.STRESSED|translate}}</div>
|
<div class="text-item">
|
||||||
|
{{ T.F.PROCRASTINATION.INTRO.STRESSED | translate }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
|
|
||||||
<mat-tab [label]="T.F.PROCRASTINATION.CUR.TITLE|translate">
|
<mat-tab [label]="T.F.PROCRASTINATION.CUR.TITLE | translate">
|
||||||
<section class="tab-inner">
|
<section class="tab-inner">
|
||||||
<p>{{T.F.PROCRASTINATION.CUR.INTRO|translate}}</p>
|
<p>{{ T.F.PROCRASTINATION.CUR.INTRO | translate }}</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>{{T.F.PROCRASTINATION.CUR.L1|translate}}</li>
|
<li>{{ T.F.PROCRASTINATION.CUR.L1 | translate }}</li>
|
||||||
<li>{{T.F.PROCRASTINATION.CUR.L2|translate}}</li>
|
<li>{{ T.F.PROCRASTINATION.CUR.L2 | translate }}</li>
|
||||||
<li>{{T.F.PROCRASTINATION.CUR.L3|translate}}</li>
|
<li>{{ T.F.PROCRASTINATION.CUR.L3 | translate }}</li>
|
||||||
<li>{{T.F.PROCRASTINATION.CUR.L4|translate}}</li>
|
<li>{{ T.F.PROCRASTINATION.CUR.L4 | translate }}</li>
|
||||||
<li>{{T.F.PROCRASTINATION.CUR.L5|translate}}</li>
|
<li>{{ T.F.PROCRASTINATION.CUR.L5 | translate }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3>{{T.F.PROCRASTINATION.CUR.PROCRASTINATION_TRIGGERS_TITLE|translate}}</h3>
|
<h3>{{ T.F.PROCRASTINATION.CUR.PROCRASTINATION_TRIGGERS_TITLE | translate }}</h3>
|
||||||
<p>{{T.F.PROCRASTINATION.CUR.PROCRASTINATION_TRIGGERS_TEXT|translate}}</p>
|
<p>{{ T.F.PROCRASTINATION.CUR.PROCRASTINATION_TRIGGERS_TEXT | translate }}</p>
|
||||||
|
|
||||||
<!-- <mat-form-field>-->
|
<!-- <mat-form-field>-->
|
||||||
<!-- <textarea matInput-->
|
<!-- <textarea matInput-->
|
||||||
|
|
@ -60,50 +64,50 @@
|
||||||
</section>
|
</section>
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
|
|
||||||
<mat-tab [label]="T.F.PROCRASTINATION.COMP.TITLE|translate">
|
<mat-tab [label]="T.F.PROCRASTINATION.COMP.TITLE | translate">
|
||||||
<section class="tab-inner">
|
<section class="tab-inner">
|
||||||
<p>{{T.F.PROCRASTINATION.COMP.INTRO|translate}}</p>
|
<p>{{ T.F.PROCRASTINATION.COMP.INTRO | translate }}</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>{{T.F.PROCRASTINATION.COMP.L1|translate}}</li>
|
<li>{{ T.F.PROCRASTINATION.COMP.L1 | translate }}</li>
|
||||||
<li>{{T.F.PROCRASTINATION.COMP.L2|translate}}</li>
|
<li>{{ T.F.PROCRASTINATION.COMP.L2 | translate }}</li>
|
||||||
<li>{{T.F.PROCRASTINATION.COMP.L3|translate}}</li>
|
<li>{{ T.F.PROCRASTINATION.COMP.L3 | translate }}</li>
|
||||||
<li>{{T.F.PROCRASTINATION.COMP.L4|translate}}</li>
|
<li>{{ T.F.PROCRASTINATION.COMP.L4 | translate }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p [innerHTML]="T.F.PROCRASTINATION.COMP.OUTRO|translate"></p>
|
<p [innerHTML]="T.F.PROCRASTINATION.COMP.OUTRO | translate"></p>
|
||||||
</section>
|
</section>
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
|
|
||||||
<mat-tab [label]="T.F.PROCRASTINATION.REFRAME.TITLE|translate">
|
<mat-tab [label]="T.F.PROCRASTINATION.REFRAME.TITLE | translate">
|
||||||
<section class="tab-inner">
|
<section class="tab-inner">
|
||||||
<p>{{T.F.PROCRASTINATION.REFRAME.INTRO|translate}}</p>
|
<p>{{ T.F.PROCRASTINATION.REFRAME.INTRO | translate }}</p>
|
||||||
|
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{T.F.PROCRASTINATION.REFRAME.TL1|translate}}</mat-label>
|
<mat-label>{{ T.F.PROCRASTINATION.REFRAME.TL1 | translate }}</mat-label>
|
||||||
<textarea matInput></textarea>
|
<textarea matInput></textarea>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{T.F.PROCRASTINATION.REFRAME.TL2|translate}}</mat-label>
|
<mat-label>{{ T.F.PROCRASTINATION.REFRAME.TL2 | translate }}</mat-label>
|
||||||
<textarea matInput></textarea>
|
<textarea matInput></textarea>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{T.F.PROCRASTINATION.REFRAME.TL3|translate}}</mat-label>
|
<mat-label>{{ T.F.PROCRASTINATION.REFRAME.TL3 | translate }}</mat-label>
|
||||||
<textarea matInput></textarea>
|
<textarea matInput></textarea>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</section>
|
</section>
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
|
|
||||||
@if ((taskService.currentTaskOrCurrentParent$|async); as currentTask) {
|
@if (taskService.currentTaskOrCurrentParent$ | async; as currentTask) {
|
||||||
<mat-tab [label]="T.F.PROCRASTINATION.SPLIT_UP.TITLE|translate">
|
<mat-tab [label]="T.F.PROCRASTINATION.SPLIT_UP.TITLE | translate">
|
||||||
<section class="tab-inner no-box">
|
<section class="tab-inner no-box">
|
||||||
<p>{{T.F.PROCRASTINATION.SPLIT_UP.INTRO|translate}}</p>
|
<p>{{ T.F.PROCRASTINATION.SPLIT_UP.INTRO | translate }}</p>
|
||||||
<task [task]="currentTask"></task>
|
<task [task]="currentTask"></task>
|
||||||
<p
|
<p
|
||||||
[innerHTML]="T.F.PROCRASTINATION.SPLIT_UP.OUTRO|translate"
|
[innerHTML]="T.F.PROCRASTINATION.SPLIT_UP.OUTRO | translate"
|
||||||
style="margin-top: 16px"
|
style="margin-top: 16px"
|
||||||
></p>
|
></p>
|
||||||
</section>
|
</section>
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
}
|
}
|
||||||
</mat-tab-group>
|
</mat-tab-group>
|
||||||
|
|
||||||
|
|
@ -113,7 +117,7 @@
|
||||||
mat-flat-button
|
mat-flat-button
|
||||||
(click)="backToWork()"
|
(click)="backToWork()"
|
||||||
>
|
>
|
||||||
{{T.F.PROCRASTINATION.BACK_TO_WORK|translate}}
|
{{ T.F.PROCRASTINATION.BACK_TO_WORK | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
<h1 mat-dialog-title>
|
<h1 mat-dialog-title>
|
||||||
@if (projectData.id) {
|
@if (projectData.id) {
|
||||||
<span>{{T.F.PROJECT.D_CREATE.EDIT|translate}}</span>
|
<span>{{ T.F.PROJECT.D_CREATE.EDIT | translate }}</span>
|
||||||
} @if (!projectData.id) {
|
}
|
||||||
<span>{{T.F.PROJECT.D_CREATE.CREATE|translate}}</span>
|
@if (!projectData.id) {
|
||||||
|
<span>{{ T.F.PROJECT.D_CREATE.CREATE | translate }}</span>
|
||||||
}
|
}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
|
|
@ -30,7 +31,7 @@
|
||||||
mat-button
|
mat-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
{{T.G.CANCEL|translate}}
|
{{ T.G.CANCEL | translate }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
[disabled]="!formBasic.valid"
|
[disabled]="!formBasic.valid"
|
||||||
|
|
@ -39,7 +40,7 @@
|
||||||
mat-stroked-button
|
mat-stroked-button
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
{{T.G.SAVE|translate}}
|
{{ T.G.SAVE | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
|
|
|
||||||
|
|
@ -1,70 +1,82 @@
|
||||||
<h1>{{ T.F.QUICK_HISTORY.PAGE_TITLE|translate }}</h1>
|
<h1>{{ T.F.QUICK_HISTORY.PAGE_TITLE | translate }}</h1>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
*ngIf="(worklogService.quickHistoryWeeks$|async) as weeks else spinner"
|
*ngIf="worklogService.quickHistoryWeeks$ | async as weeks; else spinner"
|
||||||
[@fadeInSlow]
|
[@fadeInSlow]
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="no-data"
|
class="no-data"
|
||||||
*ngIf="weeks?.length===0"
|
*ngIf="weeks?.length === 0"
|
||||||
>
|
>
|
||||||
{{ T.F.QUICK_HISTORY.NO_DATA|translate }}
|
{{ T.F.QUICK_HISTORY.NO_DATA | translate }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngFor="let week of weeks; let j = index;">
|
<div *ngFor="let week of weeks; let j = index">
|
||||||
<h2>
|
<h2>
|
||||||
{{ T.F.QUICK_HISTORY.WEEK_TITLE|translate:{ nr: week.weekNr, timeSpent:
|
{{
|
||||||
(week.timeSpent|msToString) } }}
|
T.F.QUICK_HISTORY.WEEK_TITLE
|
||||||
|
| translate: { nr: week.weekNr, timeSpent: (week.timeSpent | msToString) }
|
||||||
|
}}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div class="days">
|
<div class="days">
|
||||||
<div
|
<div
|
||||||
*ngFor="let day of week?.ent|keyvalue:sortDays trackBy: trackByDay; let i = index;"
|
*ngFor="
|
||||||
|
let day of week?.ent | keyvalue: sortDays;
|
||||||
|
trackBy: trackByDay;
|
||||||
|
let i = index
|
||||||
|
"
|
||||||
class="day"
|
class="day"
|
||||||
>
|
>
|
||||||
<div class="material-table">
|
<div class="material-table">
|
||||||
<div
|
<div
|
||||||
(click)="visibility[i+(j*100)]=!visibility[i+(j*100)];"
|
(click)="visibility[i + j * 100] = !visibility[i + j * 100]"
|
||||||
class="caption"
|
class="caption"
|
||||||
mat-ripple
|
mat-ripple
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<span
|
<span
|
||||||
*ngIf="visibility[i+(j*100)]"
|
*ngIf="visibility[i + j * 100]"
|
||||||
[@fade]
|
[@fade]
|
||||||
>{{ T.F.WORKLOG.WEEK.TITLE|translate }}</span
|
>{{ T.F.WORKLOG.WEEK.TITLE | translate }}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="center-box">
|
<div class="center-box">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<h3 class="mat-h3">{{ day.value.dayStr }}</h3>
|
<h3 class="mat-h3">{{ day.value.dayStr }}</h3>
|
||||||
<div
|
<div
|
||||||
*ngIf="!visibility[i+(j*100)]"
|
*ngIf="!visibility[i + j * 100]"
|
||||||
[@expandFade]
|
[@expandFade]
|
||||||
class="icon-indicator-bar"
|
class="icon-indicator-bar"
|
||||||
>
|
>
|
||||||
<strong>∑ {{ day.value.timeSpent|msToClockString }}</strong>
|
<strong>∑ {{ day.value.timeSpent | msToClockString }}</strong>
|
||||||
|
|
||||||
<mat-icon>list</mat-icon>
|
<mat-icon>list</mat-icon>
|
||||||
<strong>{{ day.value.logEntries.length }}</strong>
|
<strong>{{ day.value.logEntries.length }}</strong>
|
||||||
<em *ngIf="day.value.workStart"
|
<em *ngIf="day.value.workStart"
|
||||||
><span class="spacer"></span>{{
|
><span class="spacer"></span
|
||||||
day.value.workStart|momentFormat:'HH:mm' }} - {{
|
>{{ day.value.workStart | momentFormat: 'HH:mm' }} -
|
||||||
day.value.workEnd|momentFormat:'HH:mm' }}</em
|
{{ day.value.workEnd | momentFormat: 'HH:mm' }}</em
|
||||||
>
|
>
|
||||||
|
|
||||||
<div class="simple-counter-items">
|
<div class="simple-counter-items">
|
||||||
<div
|
<div
|
||||||
*ngFor="let sc of simpleCounterService.enabledSimpleCounters$|async"
|
*ngFor="
|
||||||
|
let sc of simpleCounterService.enabledSimpleCounters$ | async
|
||||||
|
"
|
||||||
class="simple-counter-item"
|
class="simple-counter-item"
|
||||||
>
|
>
|
||||||
<mat-icon inline="true">{{ sc.icon }}</mat-icon>
|
<mat-icon inline="true">{{ sc.icon }}</mat-icon>
|
||||||
@if(sc.type==='StopWatch') {
|
@if (sc.type === 'StopWatch') {
|
||||||
<div class="count">
|
<div class="count">
|
||||||
{{ sc.countOnDay[day.value.dateStr] || 0|msToMinuteClockString }}
|
{{
|
||||||
</div>
|
sc.countOnDay[day.value.dateStr] || 0 | msToMinuteClockString
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
} @else {
|
} @else {
|
||||||
<div class="count">{{ sc.countOnDay[day.value.dateStr] || 0 }}</div>
|
<div class="count">
|
||||||
|
{{ sc.countOnDay[day.value.dateStr] || 0 }}
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -73,7 +85,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="with-icon">
|
<div class="with-icon">
|
||||||
<mat-icon
|
<mat-icon
|
||||||
*ngIf="visibility[i+(j*100)]"
|
*ngIf="visibility[i + j * 100]"
|
||||||
[@fade]
|
[@fade]
|
||||||
>timer
|
>timer
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
|
|
@ -81,12 +93,15 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table
|
<table
|
||||||
*ngIf="visibility[i+(j*100)]"
|
*ngIf="visibility[i + j * 100]"
|
||||||
[@expandFade]
|
[@expandFade]
|
||||||
class="task-summary-table"
|
class="task-summary-table"
|
||||||
>
|
>
|
||||||
<tr
|
<tr
|
||||||
*ngFor="let logEntry of filterWorklogDataForDay(day.value.logEntries); trackBy: trackByLogEntry;"
|
*ngFor="
|
||||||
|
let logEntry of filterWorklogDataForDay(day.value.logEntries);
|
||||||
|
trackBy: trackByLogEntry
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
[class.isSubTask]="logEntry.task.parentId"
|
[class.isSubTask]="logEntry.task.parentId"
|
||||||
|
|
@ -97,14 +112,20 @@
|
||||||
</td>
|
</td>
|
||||||
<td class="worked">
|
<td class="worked">
|
||||||
<span
|
<span
|
||||||
*ngIf="logEntry.task.subTaskIds && logEntry.task.subTaskIds.length>0"
|
*ngIf="logEntry.task.subTaskIds && logEntry.task.subTaskIds.length > 0"
|
||||||
>∑ {{ logEntry.task.timeSpentOnDay[day.value.dateStr]|msToClockString
|
>∑
|
||||||
|
{{
|
||||||
|
logEntry.task.timeSpentOnDay[day.value.dateStr] | msToClockString
|
||||||
}}</span
|
}}</span
|
||||||
>
|
>
|
||||||
<inline-input
|
<inline-input
|
||||||
(changed)="updateTimeSpentTodayForTask(logEntry.task,day.value.dateStr, $event)"
|
(changed)="
|
||||||
|
updateTimeSpentTodayForTask(logEntry.task, day.value.dateStr, $event)
|
||||||
|
"
|
||||||
*ngIf="!logEntry.task.subTaskIds || !logEntry.task.subTaskIds.length"
|
*ngIf="!logEntry.task.subTaskIds || !logEntry.task.subTaskIds.length"
|
||||||
[displayValue]="logEntry.task.timeSpentOnDay[day.value.dateStr]|msToClockString"
|
[displayValue]="
|
||||||
|
logEntry.task.timeSpentOnDay[day.value.dateStr] | msToClockString
|
||||||
|
"
|
||||||
[type]="'duration'"
|
[type]="'duration'"
|
||||||
[value]="logEntry.task.timeSpentOnDay[day.value.dateStr]"
|
[value]="logEntry.task.timeSpentOnDay[day.value.dateStr]"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<better-drawer-container
|
<better-drawer-container
|
||||||
(wasClosed)="close()"
|
(wasClosed)="close()"
|
||||||
[isOpen]="isOpen$|async"
|
[isOpen]="isOpen$ | async"
|
||||||
[isOver]="isAlwaysOver() || (layoutService.isRightPanelOver$|async)"
|
[isOver]="isAlwaysOver() || (layoutService.isRightPanelOver$ | async)"
|
||||||
[sideWidth]="40"
|
[sideWidth]="40"
|
||||||
>
|
>
|
||||||
<ng-container better-drawer-content>
|
<ng-container better-drawer-content>
|
||||||
|
|
@ -9,19 +9,21 @@
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container better-drawer-side>
|
<ng-container better-drawer-side>
|
||||||
@let panelContent = panelContent$ |async;
|
@let panelContent = panelContent$ | async;
|
||||||
<div class="right-panel">
|
<div class="right-panel">
|
||||||
@if (panelContent === 'ADD_TASK_PANEL') {
|
@if (panelContent === 'ADD_TASK_PANEL') {
|
||||||
<issue-panel [@slideInFromRight]></issue-panel>
|
<issue-panel [@slideInFromRight]></issue-panel>
|
||||||
} @if (panelContent === 'NOTES') {
|
}
|
||||||
<notes [@slideInFromRight]></notes>
|
@if (panelContent === 'NOTES') {
|
||||||
} @if (selectedTaskWithDelayForNone$|async; as selectedTaskWithDelayForNone) {
|
<notes [@slideInFromRight]></notes>
|
||||||
<task-detail-panel
|
}
|
||||||
[isOver]="isAlwaysOver() || (layoutService.isRightPanelOver$|async)"
|
@if (selectedTaskWithDelayForNone$ | async; as selectedTaskWithDelayForNone) {
|
||||||
[@taskDetailPanelTaskChange]=" selectedTaskWithDelayForNone?.id"
|
<task-detail-panel
|
||||||
[@.disabled]="isDisableTaskPanelAni"
|
[isOver]="isAlwaysOver() || (layoutService.isRightPanelOver$ | async)"
|
||||||
[task]="selectedTaskWithDelayForNone"
|
[@taskDetailPanelTaskChange]="selectedTaskWithDelayForNone?.id"
|
||||||
></task-detail-panel>
|
[@.disabled]="isDisableTaskPanelAni"
|
||||||
|
[task]="selectedTaskWithDelayForNone"
|
||||||
|
></task-detail-panel>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
|
||||||
|
|
@ -3,21 +3,21 @@
|
||||||
(click)="isForDayMode.set(!isForDayMode())"
|
(click)="isForDayMode.set(!isForDayMode())"
|
||||||
>
|
>
|
||||||
@if (!isForDayMode()) {
|
@if (!isForDayMode()) {
|
||||||
<mat-icon>alarm</mat-icon>
|
<mat-icon>alarm</mat-icon>
|
||||||
<span [innerHTML]="plannedAt()|shortTime2"></span>
|
<span [innerHTML]="plannedAt() | shortTime2"></span>
|
||||||
<!---->
|
<!---->
|
||||||
} @else {
|
} @else {
|
||||||
<mat-icon>today</mat-icon>
|
<mat-icon>today</mat-icon>
|
||||||
<span>{{ date()|date:'shortDate' }} </span>
|
<span>{{ date() | date: 'shortDate' }} </span>
|
||||||
<!---->
|
<!---->
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (!isEditMode()) {
|
@if (!isEditMode()) {
|
||||||
<div class="msg">
|
<div class="msg">
|
||||||
<mat-icon>add</mat-icon>
|
<mat-icon>add</mat-icon>
|
||||||
click to create task
|
click to create task
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<textarea
|
<textarea
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,30 @@
|
||||||
<h1 mat-dialog-title>
|
<h1 mat-dialog-title>
|
||||||
<mat-icon>calendar_view_week</mat-icon>
|
<mat-icon>calendar_view_week</mat-icon>
|
||||||
<span style="margin-left: 8px">{{ T.F.SCHEDULE.D_INITIAL.TITLE|translate }}</span>
|
<span style="margin-left: 8px">{{ T.F.SCHEDULE.D_INITIAL.TITLE | translate }}</span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<form
|
<form
|
||||||
(submit)="$event.preventDefault();saveAndClose()"
|
(submit)="$event.preventDefault(); saveAndClose()"
|
||||||
[formGroup]="formGroup"
|
[formGroup]="formGroup"
|
||||||
>
|
>
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
@if (data?.isInfoShownInitially) {
|
@if (data?.isInfoShownInitially) {
|
||||||
<div
|
|
||||||
class="text"
|
|
||||||
[innerHTML]="T.F.SCHEDULE.D_INITIAL.TEXT|translate"
|
|
||||||
></div>
|
|
||||||
} @if (!data?.isInfoShownInitially) {
|
|
||||||
<help-section>
|
|
||||||
<div
|
<div
|
||||||
[innerHTML]="T.F.SCHEDULE.D_INITIAL.TEXT|translate"
|
class="text"
|
||||||
class="side-info"
|
[innerHTML]="T.F.SCHEDULE.D_INITIAL.TEXT | translate"
|
||||||
></div>
|
></div>
|
||||||
</help-section>
|
}
|
||||||
|
@if (!data?.isInfoShownInitially) {
|
||||||
|
<help-section>
|
||||||
|
<div
|
||||||
|
[innerHTML]="T.F.SCHEDULE.D_INITIAL.TEXT | translate"
|
||||||
|
class="side-info"
|
||||||
|
></div>
|
||||||
|
</help-section>
|
||||||
}
|
}
|
||||||
|
|
||||||
<formly-form
|
<formly-form
|
||||||
(modelChange)="timelineCfg=$event"
|
(modelChange)="timelineCfg = $event"
|
||||||
[fields]="formConfig"
|
[fields]="formConfig"
|
||||||
[form]="formGroup"
|
[form]="formGroup"
|
||||||
[model]="timelineCfg"
|
[model]="timelineCfg"
|
||||||
|
|
@ -38,7 +39,7 @@
|
||||||
mat-button
|
mat-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
{{T.G.CANCEL|translate}}
|
{{ T.G.CANCEL | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
@ -48,7 +49,7 @@
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
<mat-icon>save</mat-icon>
|
<mat-icon>save</mat-icon>
|
||||||
{{T.G.SAVE|translate}}
|
{{ T.G.SAVE | translate }}
|
||||||
</button>
|
</button>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -1,46 +1,52 @@
|
||||||
<div class="ico-wrapper">
|
<div class="ico-wrapper">
|
||||||
@switch (icoType) {
|
@switch (icoType) {
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@case ('REPEAT') {
|
@case ('REPEAT') {
|
||||||
<mat-icon
|
<mat-icon
|
||||||
svgIcon="repeat"
|
svgIcon="repeat"
|
||||||
class="ico"
|
class="ico"
|
||||||
inline="true"
|
inline="true"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
} @case ('PLANNED_FOR_DAY') {
|
}
|
||||||
<div class="day-of-month">{{ se.dayOfMonth }}</div>
|
@case ('PLANNED_FOR_DAY') {
|
||||||
} @case ('SCHEDULED_TASK') {
|
<div class="day-of-month">{{ se.dayOfMonth }}</div>
|
||||||
<mat-icon
|
}
|
||||||
class="ico"
|
@case ('SCHEDULED_TASK') {
|
||||||
inline="true"
|
<mat-icon
|
||||||
>alarm
|
class="ico"
|
||||||
</mat-icon>
|
inline="true"
|
||||||
} @case ('FLOW') {
|
>alarm
|
||||||
<!--<div class="fake-ico">~</div>-->
|
</mat-icon>
|
||||||
<mat-icon
|
}
|
||||||
class="ico"
|
@case ('FLOW') {
|
||||||
inline="true"
|
<!--<div class="fake-ico">~</div>-->
|
||||||
>wb_sunny
|
<mat-icon
|
||||||
</mat-icon>
|
class="ico"
|
||||||
} @case ('LUNCH_BREAK') {
|
inline="true"
|
||||||
<mat-icon
|
>wb_sunny
|
||||||
class="ico"
|
</mat-icon>
|
||||||
inline="true"
|
}
|
||||||
>restaurant
|
@case ('LUNCH_BREAK') {
|
||||||
</mat-icon>
|
<mat-icon
|
||||||
} @case ('CAL_PROJECTION') {
|
class="ico"
|
||||||
<mat-icon>{{ $any(se.data)?.icon || 'event' }}</mat-icon>
|
inline="true"
|
||||||
<mat-icon>add</mat-icon>
|
>restaurant
|
||||||
}
|
</mat-icon>
|
||||||
<!--- --->
|
}
|
||||||
@default { }
|
@case ('CAL_PROJECTION') {
|
||||||
<!--- --->
|
<mat-icon>{{ $any(se.data)?.icon || 'event' }}</mat-icon>
|
||||||
|
<mat-icon>add</mat-icon>
|
||||||
|
}
|
||||||
|
<!--- --->
|
||||||
|
@default {}
|
||||||
|
<!--- --->
|
||||||
}
|
}
|
||||||
<!--- -->
|
<!--- -->
|
||||||
|
|
||||||
@if (se.type === SVEType.ScheduledTask || se.type === SVEType.ScheduledRepeatProjection)
|
@if (
|
||||||
{
|
se.type === SVEType.ScheduledTask || se.type === SVEType.ScheduledRepeatProjection
|
||||||
<div class="time-badge">{{ scheduledClockStr }}</div>
|
) {
|
||||||
|
<div class="time-badge">{{ scheduledClockStr }}</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
|
|
@ -51,16 +57,22 @@
|
||||||
<!-- {{se.id}} __ {{se.data?.id}} __-->
|
<!-- {{se.id}} __ {{se.data?.id}} __-->
|
||||||
<!-- -->
|
<!-- -->
|
||||||
|
|
||||||
@if (se.type === SVEType.SplitTaskContinuedLast || se.type ===
|
@if (
|
||||||
SVEType.SplitTaskContinued || se.type === SVEType.RepeatProjectionSplitContinued ||
|
se.type === SVEType.SplitTaskContinuedLast ||
|
||||||
se.type === SVEType.RepeatProjectionSplitContinuedLast) { ...
|
se.type === SVEType.SplitTaskContinued ||
|
||||||
<!-- -->
|
se.type === SVEType.RepeatProjectionSplitContinued ||
|
||||||
} @else { {{ title }} }
|
se.type === SVEType.RepeatProjectionSplitContinuedLast
|
||||||
|
) {
|
||||||
|
...
|
||||||
|
<!-- -->
|
||||||
|
} @else {
|
||||||
|
{{ title }}
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (task) {
|
@if (task) {
|
||||||
<task-context-menu
|
<task-context-menu
|
||||||
#taskContextMenu
|
#taskContextMenu
|
||||||
[task]="task"
|
[task]="task"
|
||||||
></task-context-menu>
|
></task-context-menu>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,13 +38,13 @@
|
||||||
<div class="filler"><!--for time --></div>
|
<div class="filler"><!--for time --></div>
|
||||||
|
|
||||||
@for (day of daysToShow; track $index) {
|
@for (day of daysToShow; track $index) {
|
||||||
<div class="day">
|
<div class="day">
|
||||||
@if ($index === 0) {
|
@if ($index === 0) {
|
||||||
<mat-icon>wb_sunny</mat-icon>
|
<mat-icon>wb_sunny</mat-icon>
|
||||||
}
|
}
|
||||||
<div class="day-num">{{ day|date:'d' }}</div>
|
<div class="day-num">{{ day | date: 'd' }}</div>
|
||||||
<div class="day-day">{{ day|date:'EEE' }}</div>
|
<div class="day-day">{{ day | date: 'EEE' }}</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
@ -52,130 +52,141 @@
|
||||||
<!--<div class="outer-container">-->
|
<!--<div class="outer-container">-->
|
||||||
<div
|
<div
|
||||||
#gridContainer
|
#gridContainer
|
||||||
class="main-grid-container {{containerExtraClass}}"
|
class="main-grid-container {{ containerExtraClass }}"
|
||||||
[class.isCtrlKeyPressed]="shortcutService.isCtrlPressed$|async"
|
[class.isCtrlKeyPressed]="shortcutService.isCtrlPressed$ | async"
|
||||||
(click)="onGridClick($event)"
|
(click)="onGridClick($event)"
|
||||||
(mousemove)="onMoveOverGrid($event)"
|
(mousemove)="onMoveOverGrid($event)"
|
||||||
>
|
>
|
||||||
<!-- Time -->
|
<!-- Time -->
|
||||||
@for (time of times; track $index) {
|
@for (time of times; track $index) {
|
||||||
<div
|
<div
|
||||||
class="time"
|
class="time"
|
||||||
style="grid-row: {{ $index *FH + 1 }}"
|
style="grid-row: {{ $index * FH + 1 }}"
|
||||||
>
|
>
|
||||||
{{ time }}
|
{{ time }}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<!-- Grid Rows -->
|
<!-- Grid Rows -->
|
||||||
@for (row of rowsByNr; track $index) {
|
@for (row of rowsByNr; track $index) {
|
||||||
<div
|
<div
|
||||||
class="row"
|
class="row"
|
||||||
style="grid-row: {{ row + 1 }}"
|
style="grid-row: {{ row + 1 }}"
|
||||||
></div>
|
></div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<!-- Grid Cols -->
|
<!-- Grid Cols -->
|
||||||
@for (day of daysToShow; track $index) {
|
@for (day of daysToShow; track $index) {
|
||||||
<div
|
<div
|
||||||
class="col"
|
class="col"
|
||||||
[attr.data-day]="day"
|
[attr.data-day]="day"
|
||||||
style="grid-column: {{ $index + 2 }}; grid-row: 1 / span {{($index === 0 ? currentTimeRow :endOfDayColRowStart) -1}}"
|
style="grid-column: {{ $index + 2 }}; grid-row: 1 / span {{
|
||||||
>
|
($index === 0 ? currentTimeRow : endOfDayColRowStart) - 1
|
||||||
<div class="drop-label">{{ T.F.SCHEDULE.PLAN_START_DAY|translate }}</div>
|
}}"
|
||||||
</div>
|
>
|
||||||
<div
|
<div class="drop-label">{{ T.F.SCHEDULE.PLAN_START_DAY | translate }}</div>
|
||||||
class="col end-of-day"
|
</div>
|
||||||
[attr.data-day]="day"
|
<div
|
||||||
style="grid-column: {{ $index + 2 }}; grid-row: {{($index === 0 ? currentTimeRow :endOfDayColRowStart)}} / span {{totalRows - ($index === 0 ? currentTimeRow :endOfDayColRowStart)}}"
|
class="col end-of-day"
|
||||||
>
|
[attr.data-day]="day"
|
||||||
<div class="drop-label">{{ T.F.SCHEDULE.PLAN_END_DAY|translate }}</div>
|
style="grid-column: {{ $index + 2 }}; grid-row: {{
|
||||||
</div>
|
$index === 0 ? currentTimeRow : endOfDayColRowStart
|
||||||
|
}} / span {{ totalRows - ($index === 0 ? currentTimeRow : endOfDayColRowStart) }}"
|
||||||
|
>
|
||||||
|
<div class="drop-label">{{ T.F.SCHEDULE.PLAN_END_DAY | translate }}</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<!-- Work Start and End -->
|
<!-- Work Start and End -->
|
||||||
@if (workStartEnd) {
|
@if (workStartEnd) {
|
||||||
<div
|
<div
|
||||||
class="work-start"
|
class="work-start"
|
||||||
style="grid-row: {{workStartEnd.workStartRow}}"
|
style="grid-row: {{ workStartEnd.workStartRow }}"
|
||||||
>
|
>
|
||||||
<div>{{ T.F.SCHEDULE.START|translate }}</div>
|
<div>{{ T.F.SCHEDULE.START | translate }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="work-end"
|
class="work-end"
|
||||||
style="grid-row: {{workStartEnd.workEndRow}}"
|
style="grid-row: {{ workStartEnd.workEndRow }}"
|
||||||
>
|
>
|
||||||
<div>{{ T.F.SCHEDULE.END|translate }}</div>
|
<div>{{ T.F.SCHEDULE.END | translate }}</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<!-- Events -->
|
<!-- Events -->
|
||||||
@for (ev of (events$|async); track ev.id) {
|
@for (ev of events$ | async; track ev.id) {
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@if (ev.type === SVEType.Task || ev.type === SVEType.SplitTask || ev.type ===
|
@if (
|
||||||
SVEType.TaskPlannedForDay || ev.type === SVEType.SplitTaskPlannedForDay) {
|
ev.type === SVEType.Task ||
|
||||||
<schedule-event
|
ev.type === SVEType.SplitTask ||
|
||||||
class="draggable"
|
ev.type === SVEType.TaskPlannedForDay ||
|
||||||
cdkDrag
|
ev.type === SVEType.SplitTaskPlannedForDay
|
||||||
[cdkDragData]="ev"
|
) {
|
||||||
(cdkDragMoved)="dragMoved($event)"
|
<schedule-event
|
||||||
(cdkDragStarted)="dragStarted($event)"
|
class="draggable"
|
||||||
(cdkDragReleased)="dragReleased($event)"
|
cdkDrag
|
||||||
[cdkDragStartDelay]="IS_TOUCH_PRIMARY ? 75 : 0"
|
[cdkDragData]="ev"
|
||||||
[event]="ev"
|
(cdkDragMoved)="dragMoved($event)"
|
||||||
></schedule-event>
|
(cdkDragStarted)="dragStarted($event)"
|
||||||
} @else {
|
(cdkDragReleased)="dragReleased($event)"
|
||||||
<schedule-event [event]="ev"></schedule-event>
|
[cdkDragStartDelay]="IS_TOUCH_PRIMARY ? 75 : 0"
|
||||||
} }
|
[event]="ev"
|
||||||
|
></schedule-event>
|
||||||
|
} @else {
|
||||||
|
<schedule-event [event]="ev"></schedule-event>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
<!-- Excess tasks planned for day -->
|
<!-- Excess tasks planned for day -->
|
||||||
@for (beyondBudgetDay of (beyondBudget$|async); track i; let i = $index) {
|
@for (beyondBudgetDay of beyondBudget$ | async; track i; let i = $index) {
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@if (beyondBudgetDay.length > 0) {
|
@if (beyondBudgetDay.length > 0) {
|
||||||
<div
|
<div
|
||||||
class="excess-entries"
|
class="excess-entries"
|
||||||
style="grid-column: {{i + 2}}"
|
style="grid-column: {{ i + 2 }}"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="excess-entries-header"
|
class="excess-entries-header"
|
||||||
[matTooltipPosition]="'above'"
|
[matTooltipPosition]="'above'"
|
||||||
[matTooltip]="'Tasks planned for day, but that are beyond the available time budget'"
|
[matTooltip]="
|
||||||
>
|
'Tasks planned for day, but that are beyond the available time budget'
|
||||||
<mat-icon>hourglass_disabled</mat-icon>
|
"
|
||||||
{{ beyondBudgetDay.length }}
|
>
|
||||||
</div>
|
<mat-icon>hourglass_disabled</mat-icon>
|
||||||
@for (ev of beyondBudgetDay; track ev.id) {
|
{{ beyondBudgetDay.length }}
|
||||||
<schedule-event
|
</div>
|
||||||
[event]="ev"
|
@for (ev of beyondBudgetDay; track ev.id) {
|
||||||
class="draggable"
|
<schedule-event
|
||||||
cdkDrag
|
[event]="ev"
|
||||||
[cdkDragData]="ev"
|
class="draggable"
|
||||||
(cdkDragMoved)="dragMoved($event)"
|
cdkDrag
|
||||||
(cdkDragStarted)="dragStarted($event)"
|
[cdkDragData]="ev"
|
||||||
(cdkDragReleased)="dragReleased($event)"
|
(cdkDragMoved)="dragMoved($event)"
|
||||||
[cdkDragStartDelay]="IS_TOUCH_PRIMARY ? DRAG_DELAY_FOR_TOUCH : 0"
|
(cdkDragStarted)="dragStarted($event)"
|
||||||
></schedule-event>
|
(cdkDragReleased)="dragReleased($event)"
|
||||||
|
[cdkDragStartDelay]="IS_TOUCH_PRIMARY ? DRAG_DELAY_FOR_TOUCH : 0"
|
||||||
|
></schedule-event>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
<!-- -->
|
||||||
}
|
|
||||||
<!-- -->
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="current-time"
|
class="current-time"
|
||||||
style="grid-column: 2; grid-row: {{currentTimeRow}} / span 1"
|
style="grid-column: 2; grid-row: {{ currentTimeRow }} / span 1"
|
||||||
>
|
>
|
||||||
<div class="circle"></div>
|
<div class="circle"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (newTaskPlaceholder$|async; as newTaskPlaceholder) {
|
@if (newTaskPlaceholder$ | async; as newTaskPlaceholder) {
|
||||||
<create-task-placeholder
|
<create-task-placeholder
|
||||||
[isEditMode]="isCreateTaskActive"
|
[isEditMode]="isCreateTaskActive"
|
||||||
[time]="newTaskPlaceholder.time"
|
[time]="newTaskPlaceholder.time"
|
||||||
[date]="newTaskPlaceholder.date"
|
[date]="newTaskPlaceholder.date"
|
||||||
(editEnd)="isCreateTaskActive = false; this.newTaskPlaceholder$.next(null)"
|
(editEnd)="isCreateTaskActive = false; this.newTaskPlaceholder$.next(null)"
|
||||||
[style]="newTaskPlaceholder.style"
|
[style]="newTaskPlaceholder.style"
|
||||||
>
|
>
|
||||||
</create-task-placeholder>
|
</create-task-placeholder>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<!--</div>-->
|
<!--</div>-->
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@
|
||||||
class="search-form mat-elevation-z4"
|
class="search-form mat-elevation-z4"
|
||||||
>
|
>
|
||||||
<div class="input-wrapper">
|
<div class="input-wrapper">
|
||||||
@if ((isLoading$|async)) {
|
@if (isLoading$ | async) {
|
||||||
<div class="spinner">
|
<div class="spinner">
|
||||||
<mat-spinner diameter="50"></mat-spinner>
|
<mat-spinner diameter="50"></mat-spinner>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<mat-icon class="search-icon">search</mat-icon>
|
<mat-icon class="search-icon">search</mat-icon>
|
||||||
<input
|
<input
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
(blur)="onBlur($event)"
|
(blur)="onBlur($event)"
|
||||||
[formControl]="taskSuggestionsCtrl"
|
[formControl]="taskSuggestionsCtrl"
|
||||||
[matAutocomplete]="autoEl"
|
[matAutocomplete]="autoEl"
|
||||||
[placeholder]="(T.F.SEARCH_BAR.PLACEHOLDER|translate)"
|
[placeholder]="T.F.SEARCH_BAR.PLACEHOLDER | translate"
|
||||||
matInput
|
matInput
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
@ -33,8 +33,10 @@
|
||||||
|
|
||||||
<div class="info-bar">
|
<div class="info-bar">
|
||||||
<div class="info-text">
|
<div class="info-text">
|
||||||
{{ (!tooManyResults ? T.F.SEARCH_BAR.INFO :
|
{{
|
||||||
T.F.SEARCH_BAR.TOO_MANY_RESULTS)|translate }}
|
(!tooManyResults ? T.F.SEARCH_BAR.INFO : T.F.SEARCH_BAR.TOO_MANY_RESULTS)
|
||||||
|
| translate
|
||||||
|
}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -44,22 +46,23 @@
|
||||||
autoActiveFirstOption
|
autoActiveFirstOption
|
||||||
[displayWith]="getOptionText"
|
[displayWith]="getOptionText"
|
||||||
>
|
>
|
||||||
@for (item of (filteredIssueSuggestions$|async); track trackByFn($index, item)) {
|
@for (item of filteredIssueSuggestions$ | async; track trackByFn($index, item)) {
|
||||||
<mat-option
|
<mat-option
|
||||||
(click)="navigateToItem(item)"
|
(click)="navigateToItem(item)"
|
||||||
class="search-mat-option"
|
class="search-mat-option"
|
||||||
[value]="item"
|
[value]="item"
|
||||||
>
|
>
|
||||||
@if (item.ctx) {
|
@if (item.ctx) {
|
||||||
<tag [tag]="item.ctx"></tag>
|
<tag [tag]="item.ctx"></tag>
|
||||||
}
|
}
|
||||||
<span>{{ item?.titleHighlighted || item?.title }}</span>
|
<span>{{ item?.titleHighlighted || item?.title }}</span>
|
||||||
@if (item.issueType) {
|
@if (item.issueType) {
|
||||||
<mat-icon [svgIcon]="item.issueType|issueIcon"></mat-icon>
|
<mat-icon [svgIcon]="item.issueType | issueIcon"></mat-icon>
|
||||||
} @if (item.isArchiveTask) {
|
}
|
||||||
<mat-icon>archive</mat-icon>
|
@if (item.isArchiveTask) {
|
||||||
}
|
<mat-icon>archive</mat-icon>
|
||||||
</mat-option>
|
}
|
||||||
|
</mat-option>
|
||||||
}
|
}
|
||||||
</mat-autocomplete>
|
</mat-autocomplete>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -1,79 +1,84 @@
|
||||||
<form (submit)="$event.preventDefault();submit()">
|
<form (submit)="$event.preventDefault(); submit()">
|
||||||
<!-- <h1 mat-dialog-title>{{ T.F.SIMPLE_COUNTER.D_EDIT.TITLE|translate }}</h1>-->
|
<!-- <h1 mat-dialog-title>{{ T.F.SIMPLE_COUNTER.D_EDIT.TITLE|translate }}</h1>-->
|
||||||
<h1 mat-dialog-title>{{ data.simpleCounter.title }}</h1>
|
<h1 mat-dialog-title>{{ data.simpleCounter.title }}</h1>
|
||||||
|
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
<!---->
|
<!---->
|
||||||
@if (data.simpleCounter.isTrackStreaks) {
|
@if (data.simpleCounter.isTrackStreaks) {
|
||||||
<section style="text-align: center; margin-bottom: 16px">
|
<section style="text-align: center; margin-bottom: 16px">
|
||||||
<div>{{T.F.SIMPLE_COUNTER.D_EDIT.CURRENT_STREAK|translate}}</div>
|
<div>{{ T.F.SIMPLE_COUNTER.D_EDIT.CURRENT_STREAK | translate }}</div>
|
||||||
<div>
|
<div>
|
||||||
<strong
|
<strong
|
||||||
>{{ currentStreak() }} {{T.F.SIMPLE_COUNTER.D_EDIT.DAYS|translate}}</strong
|
>{{ currentStreak() }}
|
||||||
>
|
{{ T.F.SIMPLE_COUNTER.D_EDIT.DAYS | translate }}</strong
|
||||||
</div>
|
>
|
||||||
</section>
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section style="text-align: center; margin-bottom: 16px">
|
<section style="text-align: center; margin-bottom: 16px">
|
||||||
<div>{{T.F.SIMPLE_COUNTER.D_EDIT.DAILY_GOAL|translate}}</div>
|
<div>{{ T.F.SIMPLE_COUNTER.D_EDIT.DAILY_GOAL | translate }}</div>
|
||||||
<div>
|
<div>
|
||||||
<strong
|
<strong>
|
||||||
>@if (data.simpleCounter.type === SimpleCounterType.StopWatch) { {{
|
@if (data.simpleCounter.type === SimpleCounterType.StopWatch) {
|
||||||
data.simpleCounter.streakMinValue|msToString }}
|
{{ data.simpleCounter.streakMinValue | msToString }}
|
||||||
<!---->
|
<!---->
|
||||||
} @else { {{ data.simpleCounter.streakMinValue }} }</strong
|
} @else {
|
||||||
>
|
{{ data.simpleCounter.streakMinValue }}
|
||||||
</div>
|
}
|
||||||
</section>
|
</strong>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
}
|
}
|
||||||
<!---->
|
<!---->
|
||||||
|
|
||||||
@if (stats()) {
|
@if (stats()) {
|
||||||
<section style="margin-bottom: 32px">
|
<section style="margin-bottom: 32px">
|
||||||
<div class="chart-wrapper">
|
<div class="chart-wrapper">
|
||||||
<div class="inner-chart-wrapper">
|
<div class="inner-chart-wrapper">
|
||||||
<canvas
|
<canvas
|
||||||
[type]="'line'"
|
[type]="'line'"
|
||||||
[data]="stats()"
|
[data]="stats()"
|
||||||
[labels]="stats()?.labels"
|
[labels]="stats()?.labels"
|
||||||
[options]="lineChartOptions"
|
[options]="lineChartOptions"
|
||||||
[legend]="true"
|
[legend]="true"
|
||||||
baseChart
|
baseChart
|
||||||
>
|
>
|
||||||
</canvas>
|
</canvas>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
</section>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="form-wrapper">
|
<div class="form-wrapper">
|
||||||
@if (data.simpleCounter.type === SimpleCounterType.ClickCounter ||
|
@if (
|
||||||
data.simpleCounter.type === SimpleCounterType.RepeatedCountdownReminder) {
|
data.simpleCounter.type === SimpleCounterType.ClickCounter ||
|
||||||
<mat-form-field>
|
data.simpleCounter.type === SimpleCounterType.RepeatedCountdownReminder
|
||||||
<mat-label>{{ T.F.SIMPLE_COUNTER.D_EDIT.L_COUNTER|translate }}</mat-label>
|
) {
|
||||||
<input
|
<mat-form-field>
|
||||||
(ngModelChange)="onModelChange($event)"
|
<mat-label>{{ T.F.SIMPLE_COUNTER.D_EDIT.L_COUNTER | translate }}</mat-label>
|
||||||
[ngModel]="val"
|
<input
|
||||||
matInput
|
(ngModelChange)="onModelChange($event)"
|
||||||
name="count"
|
[ngModel]="val"
|
||||||
type="number"
|
matInput
|
||||||
/>
|
name="count"
|
||||||
</mat-form-field>
|
type="number"
|
||||||
|
/>
|
||||||
|
</mat-form-field>
|
||||||
}
|
}
|
||||||
<!---->
|
<!---->
|
||||||
@if (data.simpleCounter.type === SimpleCounterType.StopWatch) {
|
@if (data.simpleCounter.type === SimpleCounterType.StopWatch) {
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ T.F.SIMPLE_COUNTER.D_EDIT.L_COUNTER|translate }}</mat-label>
|
<mat-label>{{ T.F.SIMPLE_COUNTER.D_EDIT.L_COUNTER | translate }}</mat-label>
|
||||||
<input
|
<input
|
||||||
(ngModelChange)="onModelChange($event)"
|
(ngModelChange)="onModelChange($event)"
|
||||||
[ngModel]="val"
|
[ngModel]="val"
|
||||||
inputDuration="optional"
|
inputDuration="optional"
|
||||||
matInput
|
matInput
|
||||||
name="count"
|
name="count"
|
||||||
type="text"
|
type="text"
|
||||||
/>
|
/>
|
||||||
<mat-icon matPrefix>timer</mat-icon>
|
<mat-icon matPrefix>timer</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</mat-dialog-content>
|
</mat-dialog-content>
|
||||||
|
|
@ -87,7 +92,7 @@
|
||||||
mat-button
|
mat-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
{{ T.G.CANCEL|translate }}
|
{{ T.G.CANCEL | translate }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-primary submit-button"
|
class="btn btn-primary submit-button"
|
||||||
|
|
@ -96,7 +101,7 @@
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
<mat-icon>save</mat-icon>
|
<mat-icon>save</mat-icon>
|
||||||
{{ T.G.SAVE|translate }}
|
{{ T.G.SAVE | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
|
|
|
||||||
|
|
@ -1,60 +1,64 @@
|
||||||
@if (simpleCounter(); as sc) {
|
@if (simpleCounter(); as sc) {
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
@if (sc.type === SimpleCounterType.StopWatch) {
|
@if (sc.type === SimpleCounterType.StopWatch) {
|
||||||
<button
|
<button
|
||||||
(click)="toggleStopwatch()"
|
(click)="toggleStopwatch()"
|
||||||
(contextmenu)="edit($event)"
|
(contextmenu)="edit($event)"
|
||||||
(longPress)="edit()"
|
(longPress)="edit()"
|
||||||
[color]="sc.isOn? 'accent': ''"
|
[color]="sc.isOn ? 'accent' : ''"
|
||||||
class="main-btn stopwatch"
|
class="main-btn stopwatch"
|
||||||
mat-mini-fab
|
mat-mini-fab
|
||||||
>
|
>
|
||||||
<mat-icon>{{ sc.icon }}</mat-icon>
|
<mat-icon>{{ sc.icon }}</mat-icon>
|
||||||
@if (isSuccess()) {
|
@if (isSuccess()) {
|
||||||
<mat-icon class="check-ico">check</mat-icon>
|
<mat-icon class="check-ico">check</mat-icon>
|
||||||
|
}
|
||||||
|
</button>
|
||||||
|
@if (sc.countOnDay[todayStr()]) {
|
||||||
|
<div class="label">{{ sc.countOnDay[todayStr()] | msToMinuteClockString }}</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</button>
|
<!----->
|
||||||
@if (sc.countOnDay[todayStr()]) {
|
@if (sc.type === SimpleCounterType.ClickCounter) {
|
||||||
<div class="label">{{ sc.countOnDay[todayStr()]|msToMinuteClockString }}</div>
|
<button
|
||||||
} }
|
(click)="toggleCounter()"
|
||||||
<!----->
|
(contextmenu)="edit($event)"
|
||||||
@if (sc.type === SimpleCounterType.ClickCounter) {
|
(longPress)="edit()"
|
||||||
<button
|
class="main-btn"
|
||||||
(click)="toggleCounter()"
|
color=""
|
||||||
(contextmenu)="edit($event)"
|
mat-mini-fab
|
||||||
(longPress)="edit()"
|
>
|
||||||
class="main-btn"
|
<mat-icon>{{ sc.icon }}</mat-icon>
|
||||||
color=""
|
@if (isSuccess()) {
|
||||||
mat-mini-fab
|
<mat-icon class="check-ico">check</mat-icon>
|
||||||
>
|
}
|
||||||
<mat-icon>{{ sc.icon }}</mat-icon>
|
</button>
|
||||||
@if (isSuccess()) {
|
@if (sc.countOnDay[todayStr()]) {
|
||||||
<mat-icon class="check-ico">check</mat-icon>
|
<div class="label">{{ sc.countOnDay[todayStr()] }}</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</button>
|
<!----->
|
||||||
@if (sc.countOnDay[todayStr()]) {
|
@if (sc.type === SimpleCounterType.RepeatedCountdownReminder) {
|
||||||
<div class="label">{{ sc.countOnDay[todayStr()] }}</div>
|
<button
|
||||||
} }
|
(click)="isTimeUp() ? countUpAndNextRepeatCountdownSession() : toggleStopwatch()"
|
||||||
<!----->
|
(contextmenu)="edit($event)"
|
||||||
@if (sc.type === SimpleCounterType.RepeatedCountdownReminder) {
|
(longPress)="edit()"
|
||||||
<button
|
[color]="sc.isOn && !isTimeUp() ? 'accent' : ''"
|
||||||
(click)="isTimeUp() ? countUpAndNextRepeatCountdownSession() : toggleStopwatch()"
|
[class.isTimeUp]="isTimeUp()"
|
||||||
(contextmenu)="edit($event)"
|
class="main-btn repeated-countdown"
|
||||||
(longPress)="edit()"
|
mat-mini-fab
|
||||||
[color]="(sc.isOn && !isTimeUp())? 'accent': ''"
|
>
|
||||||
[class.isTimeUp]="isTimeUp()"
|
<mat-icon>{{ sc.icon }}</mat-icon>
|
||||||
class="main-btn repeated-countdown"
|
@if (isSuccess()) {
|
||||||
mat-mini-fab
|
<mat-icon class="check-ico">check</mat-icon>
|
||||||
>
|
}
|
||||||
<mat-icon>{{ sc.icon }}</mat-icon>
|
</button>
|
||||||
@if (isSuccess()) {
|
@if (sc.isOn && (countdownTime$ | async); as countdownTime) {
|
||||||
<mat-icon class="check-ico">check</mat-icon>
|
<div class="extra-label">{{ countdownTime | msToMinuteClockString }}</div>
|
||||||
|
}
|
||||||
|
@if (sc.countOnDay[todayStr()] || isTimeUp()) {
|
||||||
|
<div class="label">{{ isTimeUp() ? '+' : sc.countOnDay[todayStr()] }}</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</button>
|
</div>
|
||||||
@if (sc.isOn && (countdownTime$|async); as countdownTime) {
|
|
||||||
<div class="extra-label">{{ countdownTime|msToMinuteClockString }}</div>
|
|
||||||
} @if (sc.countOnDay[todayStr()] || isTimeUp()) {
|
|
||||||
<div class="label">{{ isTimeUp() ? "+" : sc.countOnDay[todayStr()] }}</div>
|
|
||||||
} }
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
<mat-icon>save</mat-icon>
|
<mat-icon>save</mat-icon>
|
||||||
{{T.G.SAVE|translate}}
|
{{ T.G.SAVE | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
<h1 mat-dialog-title>
|
<h1 mat-dialog-title>
|
||||||
{{isEdit ? (T.F.TAG.D_EDIT.EDIT|translate:{title: title}) :
|
{{
|
||||||
(T.F.TAG.D_EDIT.ADD|translate:{title: title})}}
|
isEdit
|
||||||
|
? (T.F.TAG.D_EDIT.EDIT | translate: { title: title })
|
||||||
|
: (T.F.TAG.D_EDIT.ADD | translate: { title: title })
|
||||||
|
}}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
|
|
@ -12,9 +15,9 @@
|
||||||
(addNewItem)="addNewTag($event)"
|
(addNewItem)="addNewTag($event)"
|
||||||
(removeItem)="removeTag($event)"
|
(removeItem)="removeTag($event)"
|
||||||
autoFocus
|
autoFocus
|
||||||
[label]="T.F.TAG.D_EDIT.LABEL|translate"
|
[label]="T.F.TAG.D_EDIT.LABEL | translate"
|
||||||
[model]="tagIds"
|
[model]="tagIds"
|
||||||
[suggestions]="(tagSuggestions$|async)"
|
[suggestions]="tagSuggestions$ | async"
|
||||||
(ctrlEnterSubmit)="close()"
|
(ctrlEnterSubmit)="close()"
|
||||||
></chip-list-input>
|
></chip-list-input>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -28,6 +31,6 @@
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
<mat-icon>close</mat-icon>
|
<mat-icon>close</mat-icon>
|
||||||
{{T.G.CLOSE|translate}}
|
{{ T.G.CLOSE | translate }}
|
||||||
</button>
|
</button>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
<mat-chip-grid #chipListElRef>
|
<mat-chip-grid #chipListElRef>
|
||||||
@for (modelItem of tagItems(); track modelItem.id) {
|
@for (modelItem of tagItems(); track modelItem.id) {
|
||||||
<mat-chip-row
|
<mat-chip-row
|
||||||
(removed)="remove(modelItem.id)"
|
(removed)="remove(modelItem.id)"
|
||||||
[removable]="true"
|
[removable]="true"
|
||||||
>
|
>
|
||||||
<tag [tag]="modelItem"></tag>
|
<tag [tag]="modelItem"></tag>
|
||||||
|
|
||||||
<mat-icon
|
<mat-icon
|
||||||
[title]="T.G.REMOVE|translate"
|
[title]="T.G.REMOVE | translate"
|
||||||
matChipRemove
|
matChipRemove
|
||||||
>cancel
|
>cancel
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
</mat-chip-row>
|
</mat-chip-row>
|
||||||
}
|
}
|
||||||
<input
|
<input
|
||||||
#inputElRef
|
#inputElRef
|
||||||
|
|
@ -30,6 +30,6 @@
|
||||||
(optionSelected)="selected($event)"
|
(optionSelected)="selected($event)"
|
||||||
>
|
>
|
||||||
@for (suggestion of filteredSuggestions(); track suggestion.id) {
|
@for (suggestion of filteredSuggestions(); track suggestion.id) {
|
||||||
<mat-option [value]="suggestion.id">{{ suggestion.title }}</mat-option>
|
<mat-option [value]="suggestion.id">{{ suggestion.title }}</mat-option>
|
||||||
}
|
}
|
||||||
</mat-autocomplete>
|
</mat-autocomplete>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
@if ((tags()?.length > 0)) {
|
@if (tags()?.length > 0) {
|
||||||
<div class="tags-container">
|
<div class="tags-container">
|
||||||
<div class="tags">
|
<div class="tags">
|
||||||
@for (tag of tags(); track tag.id) {
|
@for (tag of tags(); track tag.id) {
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<tag [tag]="tag"></tag>
|
<tag [tag]="tag"></tag>
|
||||||
}
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
<mat-icon
|
<mat-icon
|
||||||
[style.background]="color()"
|
[style.background]="color()"
|
||||||
class="tag-ico"
|
class="tag-ico"
|
||||||
>{{tag().icon}}</mat-icon
|
>{{ tag().icon }}</mat-icon
|
||||||
>
|
>
|
||||||
@if (!isHideTitle()) {
|
@if (!isHideTitle()) {
|
||||||
<span class="tag-title">{{ tag().title }}</span>
|
<span class="tag-title">{{ tag().title }}</span>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,27 @@
|
||||||
<form
|
<form
|
||||||
(submit)="$event.preventDefault();save()"
|
(submit)="$event.preventDefault(); save()"
|
||||||
class="dialog-help-wrapper"
|
class="dialog-help-wrapper"
|
||||||
>
|
>
|
||||||
<h1 mat-dialog-title>
|
<h1 mat-dialog-title>
|
||||||
{{isEdit ? (T.F.TASK_REPEAT.D_EDIT.EDIT|translate) :
|
{{
|
||||||
(T.F.TASK_REPEAT.D_EDIT.ADD|translate)}}
|
isEdit
|
||||||
|
? (T.F.TASK_REPEAT.D_EDIT.EDIT | translate)
|
||||||
|
: (T.F.TASK_REPEAT.D_EDIT.ADD | translate)
|
||||||
|
}}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
<!-- <h3 class="mat-h3">{{task.title}}</h3>-->
|
<!-- <h3 class="mat-h3">{{task.title}}</h3>-->
|
||||||
<help-section>
|
<help-section>
|
||||||
<p>{{T.F.TASK_REPEAT.D_EDIT.HELP1|translate}}</p>
|
<p>{{ T.F.TASK_REPEAT.D_EDIT.HELP1 | translate }}</p>
|
||||||
<p>{{T.F.TASK_REPEAT.D_EDIT.HELP2|translate}}</p>
|
<p>{{ T.F.TASK_REPEAT.D_EDIT.HELP2 | translate }}</p>
|
||||||
<p>{{T.F.TASK_REPEAT.D_EDIT.HELP3|translate}}</p>
|
<p>{{ T.F.TASK_REPEAT.D_EDIT.HELP3 | translate }}</p>
|
||||||
<p>{{T.F.TASK_REPEAT.D_EDIT.HELP4|translate}}</p>
|
<p>{{ T.F.TASK_REPEAT.D_EDIT.HELP4 | translate }}</p>
|
||||||
</help-section>
|
</help-section>
|
||||||
|
|
||||||
<div class="form-wrapper">
|
<div class="form-wrapper">
|
||||||
<formly-form
|
<formly-form
|
||||||
(modelChange)="repeatCfg=$event"
|
(modelChange)="repeatCfg = $event"
|
||||||
[form]="formGroup1"
|
[form]="formGroup1"
|
||||||
[fields]="TASK_REPEAT_CFG_FORM_CFG_BEFORE_TAGS"
|
[fields]="TASK_REPEAT_CFG_FORM_CFG_BEFORE_TAGS"
|
||||||
[model]="repeatCfg"
|
[model]="repeatCfg"
|
||||||
|
|
@ -27,14 +30,14 @@
|
||||||
(addItem)="addTag($event)"
|
(addItem)="addTag($event)"
|
||||||
(addNewItem)="addNewTag($event)"
|
(addNewItem)="addNewTag($event)"
|
||||||
(removeItem)="removeTag($event)"
|
(removeItem)="removeTag($event)"
|
||||||
[label]="T.F.TASK_REPEAT.D_EDIT.TAG_LABEL|translate"
|
[label]="T.F.TASK_REPEAT.D_EDIT.TAG_LABEL | translate"
|
||||||
[model]="repeatCfg.tagIds"
|
[model]="repeatCfg.tagIds"
|
||||||
[suggestions]="(tagSuggestions$|async)"
|
[suggestions]="tagSuggestions$ | async"
|
||||||
></chip-list-input>
|
></chip-list-input>
|
||||||
|
|
||||||
<!-- <collapsible [title]="T.F.TASK_REPEAT.D_EDIT.ADVANCED_CFG|translate">-->
|
<!-- <collapsible [title]="T.F.TASK_REPEAT.D_EDIT.ADVANCED_CFG|translate">-->
|
||||||
<formly-form
|
<formly-form
|
||||||
(modelChange)="repeatCfg=$event"
|
(modelChange)="repeatCfg = $event"
|
||||||
[form]="formGroup2"
|
[form]="formGroup2"
|
||||||
[fields]="TASK_REPEAT_CFG_ADVANCED_FORM_CFG"
|
[fields]="TASK_REPEAT_CFG_ADVANCED_FORM_CFG"
|
||||||
[model]="repeatCfg"
|
[model]="repeatCfg"
|
||||||
|
|
@ -50,19 +53,19 @@
|
||||||
mat-button
|
mat-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
{{T.G.CANCEL|translate}}
|
{{ T.G.CANCEL | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@if (isEdit) {
|
@if (isEdit) {
|
||||||
<button
|
<button
|
||||||
(click)="remove()"
|
(click)="remove()"
|
||||||
color="primary"
|
color="primary"
|
||||||
mat-stroked-button
|
mat-stroked-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<mat-icon>delete_forever</mat-icon>
|
<mat-icon>delete_forever</mat-icon>
|
||||||
{{T.G.REMOVE|translate}}
|
{{ T.G.REMOVE | translate }}
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
@ -72,7 +75,7 @@
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
<mat-icon>save</mat-icon>
|
<mat-icon>save</mat-icon>
|
||||||
{{T.G.SAVE|translate}}
|
{{ T.G.SAVE | translate }}
|
||||||
</button>
|
</button>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
@let shortSyntaxTags = (shortSyntaxTags$|async); @let activatedIssueTask =
|
@let shortSyntaxTags = shortSyntaxTags$ | async;
|
||||||
(activatedIssueTask$|async); @let inputVal = (inputVal$|async)||'';
|
@let activatedIssueTask = activatedIssueTask$ | async;
|
||||||
|
@let inputVal = (inputVal$ | async) || '';
|
||||||
|
|
||||||
<form
|
<form
|
||||||
(submit)="$event.preventDefault();addTask()"
|
(submit)="$event.preventDefault(); addTask()"
|
||||||
@blendInOut
|
@blendInOut
|
||||||
[class.isElevated]="isElevated()"
|
[class.isElevated]="isElevated()"
|
||||||
[class.mat-elevation-z3]="!isElevated()"
|
[class.mat-elevation-z3]="!isElevated()"
|
||||||
|
|
@ -12,10 +13,10 @@
|
||||||
#origin="matAutocompleteOrigin"
|
#origin="matAutocompleteOrigin"
|
||||||
>
|
>
|
||||||
<div class="input-wrapper">
|
<div class="input-wrapper">
|
||||||
@if ((isLoading())) {
|
@if (isLoading()) {
|
||||||
<div class="spinner">
|
<div class="spinner">
|
||||||
<mat-spinner diameter="50"></mat-spinner>
|
<mat-spinner diameter="50"></mat-spinner>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<input
|
<input
|
||||||
|
|
@ -25,108 +26,132 @@
|
||||||
[formControl]="taskSuggestionsCtrl"
|
[formControl]="taskSuggestionsCtrl"
|
||||||
[matAutocomplete]="autoEl"
|
[matAutocomplete]="autoEl"
|
||||||
[matAutocompleteConnectedTo]="origin"
|
[matAutocompleteConnectedTo]="origin"
|
||||||
[mentionConfig]="mentionConfig$|async"
|
[mentionConfig]="mentionConfig$ | async"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
[placeholder]="(doubleEnterCount() > 0)
|
[placeholder]="
|
||||||
? (T.F.TASK.ADD_TASK_BAR.START|translate)
|
doubleEnterCount() > 0
|
||||||
: isAddToBottom()
|
? (T.F.TASK.ADD_TASK_BAR.START | translate)
|
||||||
? isAddToBacklog()
|
: isAddToBottom()
|
||||||
? (T.F.TASK.ADD_TASK_BAR.ADD_TASK_TO_BOTTOM_OF_BACKLOG|translate)
|
? isAddToBacklog()
|
||||||
: (T.F.TASK.ADD_TASK_BAR.ADD_TASK_TO_BOTTOM_OF_TODAY|translate)
|
? (T.F.TASK.ADD_TASK_BAR.ADD_TASK_TO_BOTTOM_OF_BACKLOG | translate)
|
||||||
: isAddToBacklog()
|
: (T.F.TASK.ADD_TASK_BAR.ADD_TASK_TO_BOTTOM_OF_TODAY | translate)
|
||||||
? (T.F.TASK.ADD_TASK_BAR.ADD_TASK_TO_TOP_OF_BACKLOG|translate)
|
: isAddToBacklog()
|
||||||
: (T.F.TASK.ADD_TASK_BAR.ADD_TASK_TO_TOP_OF_TODAY|translate)"
|
? (T.F.TASK.ADD_TASK_BAR.ADD_TASK_TO_TOP_OF_BACKLOG | translate)
|
||||||
|
: (T.F.TASK.ADD_TASK_BAR.ADD_TASK_TO_TOP_OF_TODAY | translate)
|
||||||
|
"
|
||||||
matInput
|
matInput
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="button-controls">
|
<div class="button-controls">
|
||||||
@if (taskSuggestionsCtrl?.value?.length) {
|
@if (taskSuggestionsCtrl?.value?.length) {
|
||||||
<div class="separator-box">
|
<div class="separator-box">
|
||||||
<button
|
<button
|
||||||
class="switch-add-to-btn"
|
class="switch-add-to-btn"
|
||||||
(mousedown)="addTask()"
|
(mousedown)="addTask()"
|
||||||
type="submit"
|
type="submit"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
>
|
>
|
||||||
@if(activatedIssueTask){
|
@if (activatedIssueTask) {
|
||||||
<mat-icon>add_box</mat-icon>
|
<mat-icon>add_box</mat-icon>
|
||||||
}@else {
|
} @else {
|
||||||
<mat-icon>add</mat-icon>
|
<mat-icon>add</mat-icon>
|
||||||
}
|
}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
(click)="toggleIsAddToBottom()"
|
(click)="toggleIsAddToBottom()"
|
||||||
[matTooltip]="T.F.TASK.ADD_TASK_BAR.TOGGLE_ADD_TOP_OR_BOTTOM|translate"
|
[matTooltip]="T.F.TASK.ADD_TASK_BAR.TOGGLE_ADD_TOP_OR_BOTTOM | translate"
|
||||||
matTooltipPosition="above"
|
matTooltipPosition="above"
|
||||||
class="switch-add-to-bot-btn"
|
class="switch-add-to-bot-btn"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
@if(isAddToBottom()){
|
@if (isAddToBottom()) {
|
||||||
<mat-icon>vertical_align_bottom</mat-icon>
|
<mat-icon>vertical_align_bottom</mat-icon>
|
||||||
}@else {
|
} @else {
|
||||||
<mat-icon>vertical_align_top</mat-icon>
|
<mat-icon>vertical_align_top</mat-icon>
|
||||||
}
|
}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@if (isSearchIssueProvidersAvailable$|async) {
|
@if (isSearchIssueProvidersAvailable$ | async) {
|
||||||
<button
|
<button
|
||||||
(click)="isSearchIssueProviders.set(!isSearchIssueProviders())"
|
(click)="isSearchIssueProviders.set(!isSearchIssueProviders())"
|
||||||
[matTooltip]="'Toggle searching issue providers'"
|
[matTooltip]="'Toggle searching issue providers'"
|
||||||
matTooltipPosition="above"
|
matTooltipPosition="above"
|
||||||
class="switch-add-to-btn"
|
class="switch-add-to-btn"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
@if(isSearchIssueProviders()){
|
@if (isSearchIssueProviders()) {
|
||||||
<mat-icon>youtube_searched_for</mat-icon>
|
<mat-icon>youtube_searched_for</mat-icon>
|
||||||
}@else {
|
} @else {
|
||||||
<mat-icon>search_off</mat-icon>
|
<mat-icon>search_off</mat-icon>
|
||||||
}
|
}
|
||||||
</button>
|
</button>
|
||||||
} @if (isAddToBacklogAvailable$|async) {
|
}
|
||||||
<button
|
@if (isAddToBacklogAvailable$ | async) {
|
||||||
(click)="isAddToBacklog.set(!isAddToBacklog())"
|
<button
|
||||||
[matTooltip]="T.F.TASK.ADD_TASK_BAR.TOGGLE_ADD_TO_BACKLOG_TODAY|translate"
|
(click)="isAddToBacklog.set(!isAddToBacklog())"
|
||||||
matTooltipPosition="above"
|
[matTooltip]="T.F.TASK.ADD_TASK_BAR.TOGGLE_ADD_TO_BACKLOG_TODAY | translate"
|
||||||
class="switch-add-to-btn"
|
matTooltipPosition="above"
|
||||||
mat-icon-button
|
class="switch-add-to-btn"
|
||||||
type="button"
|
mat-icon-button
|
||||||
>
|
type="button"
|
||||||
@if(isAddToBacklog()){
|
>
|
||||||
<mat-icon>arrow_downward</mat-icon>
|
@if (isAddToBacklog()) {
|
||||||
}@else {
|
<mat-icon>arrow_downward</mat-icon>
|
||||||
<mat-icon>arrow_upward</mat-icon>
|
} @else {
|
||||||
}
|
<mat-icon>arrow_upward</mat-icon>
|
||||||
</button>
|
}
|
||||||
|
</button>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="info-bar">
|
<div class="info-bar">
|
||||||
@if (inputVal?.length > 0) { @if (!activatedIssueTask && !shortSyntaxTags?.length) {
|
@if (inputVal?.length > 0) {
|
||||||
<div class="info-text">{{ T.F.TASK.ADD_TASK_BAR.CREATE_TASK|translate }}</div>
|
@if (!activatedIssueTask && !shortSyntaxTags?.length) {
|
||||||
} @if (activatedIssueTask) { @if (activatedIssueTask?.issueType) {
|
<div class="info-text">{{ T.F.TASK.ADD_TASK_BAR.CREATE_TASK | translate }}</div>
|
||||||
<div class="info-text add-existing">
|
}
|
||||||
<mat-icon>playlist_add</mat-icon>
|
@if (activatedIssueTask) {
|
||||||
{{ T.F.TASK.ADD_TASK_BAR.ADD_ISSUE_TASK|translate:{ issueType:
|
@if (activatedIssueTask?.issueType) {
|
||||||
activatedIssueTask.issueType, issueNr: activatedIssueTask.taskIssueId ||
|
<div class="info-text add-existing">
|
||||||
activatedIssueTask.issueData?.id } }}
|
<mat-icon>playlist_add</mat-icon>
|
||||||
</div>
|
{{
|
||||||
} @if (activatedIssueTask.issueType=== undefined) {
|
T.F.TASK.ADD_TASK_BAR.ADD_ISSUE_TASK
|
||||||
<div class="info-text add-existing">
|
| translate
|
||||||
<mat-icon>playlist_add</mat-icon>
|
: {
|
||||||
{{ T.F.TASK.ADD_TASK_BAR.ADD_EXISTING_TASK|translate: { taskTitle:
|
issueType: activatedIssueTask.issueType,
|
||||||
activatedIssueTask.title } }}
|
issueNr:
|
||||||
</div>
|
activatedIssueTask.taskIssueId ||
|
||||||
} } @if (!activatedIssueTask && shortSyntaxTags?.length) { @for (shortSyntaxTag of
|
activatedIssueTask.issueData?.id,
|
||||||
(shortSyntaxTags); track shortSyntaxTag.title || shortSyntaxTag) {
|
}
|
||||||
<tag [tag]="shortSyntaxTag"></tag>
|
}}
|
||||||
} } } @if (inputVal.length === 0) {
|
</div>
|
||||||
<div class="info-text">{{ T.F.TASK.ADD_TASK_BAR.EXAMPLE|translate }}</div>
|
}
|
||||||
|
@if (activatedIssueTask.issueType === undefined) {
|
||||||
|
<div class="info-text add-existing">
|
||||||
|
<mat-icon>playlist_add</mat-icon>
|
||||||
|
{{
|
||||||
|
T.F.TASK.ADD_TASK_BAR.ADD_EXISTING_TASK
|
||||||
|
| translate: { taskTitle: activatedIssueTask.title }
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@if (!activatedIssueTask && shortSyntaxTags?.length) {
|
||||||
|
@for (
|
||||||
|
shortSyntaxTag of shortSyntaxTags;
|
||||||
|
track shortSyntaxTag.title || shortSyntaxTag
|
||||||
|
) {
|
||||||
|
<tag [tag]="shortSyntaxTag"></tag>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@if (inputVal.length === 0) {
|
||||||
|
<div class="info-text">{{ T.F.TASK.ADD_TASK_BAR.EXAMPLE | translate }}</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -138,21 +163,25 @@
|
||||||
(optionSelected)="addTask()"
|
(optionSelected)="addTask()"
|
||||||
[displayWith]="displayWith"
|
[displayWith]="displayWith"
|
||||||
>
|
>
|
||||||
@for (item of (filteredIssueSuggestions$|async); track item.taskId || (item.issueData
|
@for (
|
||||||
&& item.issueData.id)) {
|
item of filteredIssueSuggestions$ | async;
|
||||||
<mat-option [value]="item">
|
track item.taskId || (item.issueData && item.issueData.id)
|
||||||
@if (item.issueType) {
|
) {
|
||||||
<mat-icon [svgIcon]="item.issueType|issueIcon"></mat-icon>
|
<mat-option [value]="item">
|
||||||
} @if (!item.issueType && !item.ctx) {
|
@if (item.issueType) {
|
||||||
<mat-icon>library_books</mat-icon>
|
<mat-icon [svgIcon]="item.issueType | issueIcon"></mat-icon>
|
||||||
} @if (item.ctx) {
|
}
|
||||||
<tag
|
@if (!item.issueType && !item.ctx) {
|
||||||
[tag]="item.ctx"
|
<mat-icon>library_books</mat-icon>
|
||||||
[isHideTitle]="isHideTagTitles()"
|
}
|
||||||
></tag>
|
@if (item.ctx) {
|
||||||
}
|
<tag
|
||||||
<span [innerHTML]="item?.titleHighlighted||item?.title"></span>
|
[tag]="item.ctx"
|
||||||
</mat-option>
|
[isHideTitle]="isHideTagTitles()"
|
||||||
|
></tag>
|
||||||
|
}
|
||||||
|
<span [innerHTML]="item?.titleHighlighted || item?.title"></span>
|
||||||
|
</mat-option>
|
||||||
}
|
}
|
||||||
</mat-autocomplete>
|
</mat-autocomplete>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,26 @@
|
||||||
<div class="dialog-help-wrapper">
|
<div class="dialog-help-wrapper">
|
||||||
<h1 mat-dialog-title>{{T.F.TASK.D_TIME_FOR_DAY.TITLE|translate}}</h1>
|
<h1 mat-dialog-title>{{ T.F.TASK.D_TIME_FOR_DAY.TITLE | translate }}</h1>
|
||||||
|
|
||||||
<form
|
<form
|
||||||
(submit)="$event.preventDefault();submit()"
|
(submit)="$event.preventDefault(); submit()"
|
||||||
name="addForAnotherDayForm"
|
name="addForAnotherDayForm"
|
||||||
>
|
>
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
<help-section>
|
<help-section>
|
||||||
<div
|
<div
|
||||||
[innerHTML]="T.F.TASK.D_TIME_FOR_DAY.HELP|translate"
|
[innerHTML]="T.F.TASK.D_TIME_FOR_DAY.HELP | translate"
|
||||||
class="side-info"
|
class="side-info"
|
||||||
></div>
|
></div>
|
||||||
</help-section>
|
</help-section>
|
||||||
|
|
||||||
<h3 class="mat-caption">
|
<h3 class="mat-caption">
|
||||||
{{T.F.TASK.D_TIME_FOR_DAY.ADD_ENTRY_FOR|translate:{ date:
|
{{
|
||||||
(newEntry.date|date:'dd-MM-yyyy') || '' } }}
|
T.F.TASK.D_TIME_FOR_DAY.ADD_ENTRY_FOR
|
||||||
|
| translate: { date: (newEntry.date | date: 'dd-MM-yyyy') || '' }
|
||||||
|
}}
|
||||||
</h3>
|
</h3>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{T.F.TASK.D_TIME_FOR_DAY.DATE|translate}}</mat-label>
|
<mat-label>{{ T.F.TASK.D_TIME_FOR_DAY.DATE | translate }}</mat-label>
|
||||||
<input
|
<input
|
||||||
[(ngModel)]="newEntry.date"
|
[(ngModel)]="newEntry.date"
|
||||||
[matDatepicker]="myDatepicker"
|
[matDatepicker]="myDatepicker"
|
||||||
|
|
@ -27,7 +29,7 @@
|
||||||
required
|
required
|
||||||
type="text"
|
type="text"
|
||||||
/>
|
/>
|
||||||
<mat-error>{{T.V.E_DATETIME|translate}}</mat-error>
|
<mat-error>{{ T.V.E_DATETIME | translate }}</mat-error>
|
||||||
<mat-datepicker-toggle
|
<mat-datepicker-toggle
|
||||||
[for]="myDatepicker"
|
[for]="myDatepicker"
|
||||||
matPrefix
|
matPrefix
|
||||||
|
|
@ -38,7 +40,7 @@
|
||||||
<div class="wrap-time">
|
<div class="wrap-time">
|
||||||
<input-duration-slider
|
<input-duration-slider
|
||||||
[(model)]="newEntry.timeSpent"
|
[(model)]="newEntry.timeSpent"
|
||||||
[label]="T.F.TASK.D_TIME_FOR_DAY.TINE_SPENT|translate"
|
[label]="T.F.TASK.D_TIME_FOR_DAY.TINE_SPENT | translate"
|
||||||
>
|
>
|
||||||
</input-duration-slider>
|
</input-duration-slider>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -51,7 +53,7 @@
|
||||||
mat-button
|
mat-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
{{T.G.CANCEL|translate}}
|
{{ T.G.CANCEL | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
@ -60,7 +62,7 @@
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
<mat-icon>save</mat-icon>
|
<mat-icon>save</mat-icon>
|
||||||
{{T.G.SAVE|translate}}
|
{{ T.G.SAVE | translate }}
|
||||||
</button>
|
</button>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
<!-- <h1>XXX {{(task$|async)?.id}}</h1>-->
|
<!-- <h1>XXX {{(task$|async)?.id}}</h1>-->
|
||||||
@if (task$|async; as task) {
|
@if (task$ | async; as task) {
|
||||||
<task-detail-panel
|
<task-detail-panel
|
||||||
[task]="task"
|
[task]="task"
|
||||||
[isDialogMode]="true"
|
[isDialogMode]="true"
|
||||||
></task-detail-panel>
|
></task-detail-panel>
|
||||||
}
|
}
|
||||||
</mat-dialog-content>
|
</mat-dialog-content>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
<div class="dialog-help-wrapper">
|
<div class="dialog-help-wrapper">
|
||||||
<h1 mat-dialog-title>{{T.F.TASK.D_TIME.TITLE|translate}}</h1>
|
<h1 mat-dialog-title>{{ T.F.TASK.D_TIME.TITLE | translate }}</h1>
|
||||||
|
|
||||||
<form
|
<form
|
||||||
(submit)="$event.preventDefault();submit()"
|
(submit)="$event.preventDefault(); submit()"
|
||||||
class="mat-body"
|
class="mat-body"
|
||||||
name="time-estimate-form"
|
name="time-estimate-form"
|
||||||
>
|
>
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
<help-section>
|
<help-section>
|
||||||
<div
|
<div
|
||||||
[innerHTML]="T.F.TASK.D_TIME_FOR_DAY.HELP|translate"
|
[innerHTML]="T.F.TASK.D_TIME_FOR_DAY.HELP | translate"
|
||||||
class="side-info"
|
class="side-info"
|
||||||
></div>
|
></div>
|
||||||
</help-section>
|
</help-section>
|
||||||
|
|
@ -17,12 +17,12 @@
|
||||||
<div class="wrap-time">
|
<div class="wrap-time">
|
||||||
<input-duration-slider
|
<input-duration-slider
|
||||||
[(model)]="timeSpentOnDayCopy[todayStr]"
|
[(model)]="timeSpentOnDayCopy[todayStr]"
|
||||||
[label]="T.F.TASK.D_TIME.TIME_SPENT|translate"
|
[label]="T.F.TASK.D_TIME.TIME_SPENT | translate"
|
||||||
>
|
>
|
||||||
</input-duration-slider>
|
</input-duration-slider>
|
||||||
<input-duration-slider
|
<input-duration-slider
|
||||||
[(model)]="taskCopy.timeEstimate"
|
[(model)]="taskCopy.timeEstimate"
|
||||||
[label]="T.F.TASK.D_TIME.ESTIMATE|translate"
|
[label]="T.F.TASK.D_TIME.ESTIMATE | translate"
|
||||||
>
|
>
|
||||||
</input-duration-slider>
|
</input-duration-slider>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -36,35 +36,37 @@
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<mat-icon>add</mat-icon>
|
<mat-icon>add</mat-icon>
|
||||||
{{T.F.TASK.D_TIME.ADD_FOR_OTHER_DAY|translate}}
|
{{ T.F.TASK.D_TIME.ADD_FOR_OTHER_DAY | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@for (strDate of timeSpentOnDayCopy|keys:'reverse':todayStr; track
|
@for (
|
||||||
trackByIndex($index, strDate)) {
|
strDate of timeSpentOnDayCopy | keys: 'reverse' : todayStr;
|
||||||
<div class="other-day">
|
track trackByIndex($index, strDate)
|
||||||
<mat-form-field>
|
) {
|
||||||
<mat-label
|
<div class="other-day">
|
||||||
>{{T.F.TASK.D_TIME.TIME_SPENT_ON|translate:{date: strDate} }}</mat-label
|
<mat-form-field>
|
||||||
|
<mat-label>{{
|
||||||
|
T.F.TASK.D_TIME.TIME_SPENT_ON | translate: { date: strDate }
|
||||||
|
}}</mat-label>
|
||||||
|
<input
|
||||||
|
[(ngModel)]="timeSpentOnDayCopy[strDate]"
|
||||||
|
inputDuration="optional"
|
||||||
|
matInput
|
||||||
|
name="timeSpentOnDay{{ strDate }}"
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
<mat-icon matPrefix>timer</mat-icon>
|
||||||
|
</mat-form-field>
|
||||||
|
<button
|
||||||
|
(click)="deleteValue(strDate)"
|
||||||
|
[title]="T.F.TASK.D_TIME.DELETE_FOR | translate"
|
||||||
|
color="warn"
|
||||||
|
mat-icon-button
|
||||||
|
type="button"
|
||||||
>
|
>
|
||||||
<input
|
<mat-icon>delete_forever</mat-icon>
|
||||||
[(ngModel)]="timeSpentOnDayCopy[strDate]"
|
</button>
|
||||||
inputDuration="optional"
|
</div>
|
||||||
matInput
|
|
||||||
name="timeSpentOnDay{{strDate}}"
|
|
||||||
type="text"
|
|
||||||
/>
|
|
||||||
<mat-icon matPrefix>timer</mat-icon>
|
|
||||||
</mat-form-field>
|
|
||||||
<button
|
|
||||||
(click)="deleteValue(strDate)"
|
|
||||||
[title]="T.F.TASK.D_TIME.DELETE_FOR|translate"
|
|
||||||
color="warn"
|
|
||||||
mat-icon-button
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<mat-icon>delete_forever</mat-icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</mat-dialog-content>
|
</mat-dialog-content>
|
||||||
|
|
@ -76,7 +78,7 @@
|
||||||
mat-button
|
mat-button
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
{{T.G.CANCEL|translate}}
|
{{ T.G.CANCEL | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
@ -86,7 +88,7 @@
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
<mat-icon>save</mat-icon>
|
<mat-icon>save</mat-icon>
|
||||||
{{T.G.SAVE|translate}}
|
{{ T.G.SAVE | translate }}
|
||||||
</button>
|
</button>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -1,209 +1,223 @@
|
||||||
@if ((tasks$|async); as tasks) {
|
@if (tasks$ | async; as tasks) {
|
||||||
<h1 mat-dialog-title>
|
<h1 mat-dialog-title>
|
||||||
<mat-icon class="dialog-header-icon">alarm</mat-icon>
|
<mat-icon class="dialog-header-icon">alarm</mat-icon>
|
||||||
<span
|
<span>{{
|
||||||
>{{(isMultiple ? T.F.TASK.D_REMINDER_VIEW.DUE_TASKS :
|
(isMultiple
|
||||||
T.F.TASK.D_REMINDER_VIEW.DUE_TASK)|translate}}</span
|
? T.F.TASK.D_REMINDER_VIEW.DUE_TASKS
|
||||||
>
|
: T.F.TASK.D_REMINDER_VIEW.DUE_TASK
|
||||||
</h1>
|
) | translate
|
||||||
<mat-dialog-content>
|
}}</span>
|
||||||
<div
|
</h1>
|
||||||
[@standardList]="tasks.length"
|
<mat-dialog-content>
|
||||||
class="tasks"
|
<div
|
||||||
>
|
[@standardList]="tasks.length"
|
||||||
@for (task of tasks; track trackById($index, task)) {
|
class="tasks"
|
||||||
<div class="task">
|
>
|
||||||
<div class="title-wrapper">
|
@for (task of tasks; track trackById($index, task)) {
|
||||||
<div class="title">{{task.title}}</div>
|
<div class="task">
|
||||||
<tag-list
|
<div class="title-wrapper">
|
||||||
[isShowProjectTagAlways]="true"
|
<div class="title">{{ task.title }}</div>
|
||||||
[task]="task"
|
<tag-list
|
||||||
></tag-list>
|
[isShowProjectTagAlways]="true"
|
||||||
</div>
|
[task]="task"
|
||||||
@if (isMultiple) {
|
></tag-list>
|
||||||
<div class="actions">
|
</div>
|
||||||
|
@if (isMultiple) {
|
||||||
|
<div class="actions">
|
||||||
|
<button
|
||||||
|
[disabled]="!(task.projectId || task.parentId || task.tagIds.length > 0)"
|
||||||
|
(click)="dismiss(task)"
|
||||||
|
[title]="T.G.DISMISS | translate"
|
||||||
|
class="hide-xs"
|
||||||
|
color=""
|
||||||
|
mat-icon-button
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<mat-icon>alarm_off</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
(dblclick)="snooze(task, 10)"
|
||||||
|
[matMenuTriggerFor]="snoozeMenu"
|
||||||
|
[title]="T.F.TASK.D_REMINDER_VIEW.SNOOZE | translate"
|
||||||
|
color=""
|
||||||
|
mat-icon-button
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<mat-icon>snooze</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
(click)="addToToday(task)"
|
||||||
|
[title]="T.F.TASK.D_REMINDER_VIEW.ADD_TO_TODAY | translate"
|
||||||
|
color=""
|
||||||
|
mat-icon-button
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<mat-icon>wb_sunny</mat-icon>
|
||||||
|
</button>
|
||||||
|
<mat-menu #snoozeMenu="matMenu">
|
||||||
|
<button
|
||||||
|
(click)="snooze(task, 10)"
|
||||||
|
mat-menu-item
|
||||||
|
>
|
||||||
|
<mat-icon>snooze</mat-icon>
|
||||||
|
{{ T.G.MINUTES | translate: { m: 10 } }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
(click)="snooze(task, 30)"
|
||||||
|
mat-menu-item
|
||||||
|
>
|
||||||
|
<mat-icon>snooze</mat-icon>
|
||||||
|
{{ T.G.MINUTES | translate: { m: 30 } }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
(click)="snooze(task, 60)"
|
||||||
|
mat-menu-item
|
||||||
|
>
|
||||||
|
<mat-icon>snooze</mat-icon>
|
||||||
|
{{ T.G.MINUTES | translate: { m: 60 } }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
(click)="rescheduleUntilTomorrow(task)"
|
||||||
|
[disabled]="isDisableControls"
|
||||||
|
mat-menu-item
|
||||||
|
>
|
||||||
|
<mat-icon>schedule</mat-icon>
|
||||||
|
{{ T.F.TASK.D_REMINDER_VIEW.RESCHEDULE_UNTIL_TOMORROW | translate }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
[disabled]="
|
||||||
|
!(task.projectId || task.parentId || task.tagIds.length > 0)
|
||||||
|
"
|
||||||
|
(click)="dismiss(task)"
|
||||||
|
mat-menu-item
|
||||||
|
>
|
||||||
|
<mat-icon>alarm_off</mat-icon>
|
||||||
|
{{ T.G.DISMISS | translate }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
(click)="editReminder(task)"
|
||||||
|
mat-menu-item
|
||||||
|
>
|
||||||
|
<mat-icon>edit</mat-icon>
|
||||||
|
{{ T.G.EDIT | translate }}
|
||||||
|
</button>
|
||||||
|
</mat-menu>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</mat-dialog-content>
|
||||||
|
<mat-dialog-actions align="end">
|
||||||
|
<div class="wrap-buttons">
|
||||||
|
<button
|
||||||
|
(dblclick)="snoozeAll(10)"
|
||||||
|
[disabled]="isDisableControls"
|
||||||
|
[matMenuTriggerFor]="snoozeAllMenu"
|
||||||
|
color="primary"
|
||||||
|
mat-button
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<mat-icon>snooze</mat-icon>
|
||||||
|
{{
|
||||||
|
(isMultiple
|
||||||
|
? T.F.TASK.D_REMINDER_VIEW.SNOOZE_ALL
|
||||||
|
: T.F.TASK.D_REMINDER_VIEW.SNOOZE
|
||||||
|
) | translate
|
||||||
|
}}
|
||||||
|
</button>
|
||||||
|
@if (!isMultiple && (isSingleOnToday$ | async)) {
|
||||||
<button
|
<button
|
||||||
[disabled]="!(task.projectId || task.parentId || task.tagIds.length > 0)"
|
(click)="markAsDone()"
|
||||||
(click)="dismiss(task)"
|
[disabled]="isDisableControls"
|
||||||
[title]="T.G.DISMISS|translate"
|
color="primary"
|
||||||
class="hide-xs"
|
mat-stroked-button
|
||||||
color=""
|
|
||||||
mat-icon-button
|
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<mat-icon>alarm_off</mat-icon>
|
<mat-icon>check</mat-icon>
|
||||||
|
{{ T.F.TASK.D_REMINDER_VIEW.DONE | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
}
|
||||||
|
@if (!(isSingleOnToday$ | async)) {
|
||||||
<button
|
<button
|
||||||
(dblclick)="snooze(task,10)"
|
(click)="addAllToToday()"
|
||||||
[matMenuTriggerFor]="snoozeMenu"
|
[disabled]="isDisableControls"
|
||||||
[title]="T.F.TASK.D_REMINDER_VIEW.SNOOZE|translate"
|
color="primary"
|
||||||
color=""
|
mat-stroked-button
|
||||||
mat-icon-button
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<mat-icon>snooze</mat-icon>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
(click)="addToToday(task)"
|
|
||||||
[title]="T.F.TASK.D_REMINDER_VIEW.ADD_TO_TODAY|translate"
|
|
||||||
color=""
|
|
||||||
mat-icon-button
|
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<mat-icon>wb_sunny</mat-icon>
|
<mat-icon>wb_sunny</mat-icon>
|
||||||
|
{{
|
||||||
|
(isMultiple
|
||||||
|
? T.F.TASK.D_REMINDER_VIEW.ADD_ALL_TO_TODAY
|
||||||
|
: T.F.TASK.D_REMINDER_VIEW.ADD_TO_TODAY
|
||||||
|
) | translate
|
||||||
|
}}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
@if (!isMultiple || (isSingleOnToday$ | async)) {
|
||||||
|
<button
|
||||||
|
(click)="play()"
|
||||||
|
[disabled]="isDisableControls"
|
||||||
|
color="primary"
|
||||||
|
mat-stroked-button
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<mat-icon>play_arrow</mat-icon>
|
||||||
|
{{ T.F.TASK.D_REMINDER_VIEW.START | translate }}
|
||||||
</button>
|
</button>
|
||||||
<mat-menu #snoozeMenu="matMenu">
|
|
||||||
<button
|
|
||||||
(click)="snooze(task,10)"
|
|
||||||
mat-menu-item
|
|
||||||
>
|
|
||||||
<mat-icon>snooze</mat-icon>
|
|
||||||
{{T.G.MINUTES|translate:{m: 10} }}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
(click)="snooze(task,30)"
|
|
||||||
mat-menu-item
|
|
||||||
>
|
|
||||||
<mat-icon>snooze</mat-icon>
|
|
||||||
{{T.G.MINUTES|translate:{m: 30} }}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
(click)="snooze(task,60)"
|
|
||||||
mat-menu-item
|
|
||||||
>
|
|
||||||
<mat-icon>snooze</mat-icon>
|
|
||||||
{{T.G.MINUTES|translate:{m: 60} }}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
(click)="rescheduleUntilTomorrow(task)"
|
|
||||||
[disabled]="isDisableControls"
|
|
||||||
mat-menu-item
|
|
||||||
>
|
|
||||||
<mat-icon>schedule</mat-icon>
|
|
||||||
{{T.F.TASK.D_REMINDER_VIEW.RESCHEDULE_UNTIL_TOMORROW|translate}}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
[disabled]="!(task.projectId || task.parentId || task.tagIds.length > 0)"
|
|
||||||
(click)="dismiss(task)"
|
|
||||||
mat-menu-item
|
|
||||||
>
|
|
||||||
<mat-icon>alarm_off</mat-icon>
|
|
||||||
{{T.G.DISMISS|translate}}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
(click)="editReminder(task)"
|
|
||||||
mat-menu-item
|
|
||||||
>
|
|
||||||
<mat-icon>edit</mat-icon>
|
|
||||||
{{T.G.EDIT|translate}}
|
|
||||||
</button>
|
|
||||||
</mat-menu>
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
</mat-dialog-actions>
|
||||||
</div>
|
<mat-menu #snoozeAllMenu="matMenu">
|
||||||
</mat-dialog-content>
|
|
||||||
<mat-dialog-actions align="end">
|
|
||||||
<div class="wrap-buttons">
|
|
||||||
<button
|
<button
|
||||||
(dblclick)="snoozeAll(10)"
|
(click)="snoozeAll(10)"
|
||||||
[disabled]="isDisableControls"
|
[disabled]="isDisableControls"
|
||||||
[matMenuTriggerFor]="snoozeAllMenu"
|
mat-menu-item
|
||||||
color="primary"
|
|
||||||
mat-button
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<mat-icon>snooze</mat-icon>
|
<mat-icon>snooze</mat-icon>
|
||||||
{{(isMultiple ? T.F.TASK.D_REMINDER_VIEW.SNOOZE_ALL :
|
{{ T.G.MINUTES | translate: { m: 10 } }}
|
||||||
T.F.TASK.D_REMINDER_VIEW.SNOOZE)|translate }}
|
|
||||||
</button>
|
</button>
|
||||||
@if (!isMultiple && (isSingleOnToday$|async)) {
|
|
||||||
<button
|
<button
|
||||||
(click)="markAsDone()"
|
(click)="snoozeAll(30)"
|
||||||
[disabled]="isDisableControls"
|
[disabled]="isDisableControls"
|
||||||
color="primary"
|
mat-menu-item
|
||||||
mat-stroked-button
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<mat-icon>check</mat-icon>
|
<mat-icon>snooze</mat-icon>
|
||||||
{{T.F.TASK.D_REMINDER_VIEW.DONE|translate }}
|
{{ T.G.MINUTES | translate: { m: 30 } }}
|
||||||
</button>
|
</button>
|
||||||
} @if (!(isSingleOnToday$|async)) {
|
|
||||||
<button
|
<button
|
||||||
(click)="addAllToToday()"
|
(click)="snoozeAll(60)"
|
||||||
[disabled]="isDisableControls"
|
[disabled]="isDisableControls"
|
||||||
color="primary"
|
mat-menu-item
|
||||||
mat-stroked-button
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<mat-icon>wb_sunny</mat-icon>
|
<mat-icon>snooze</mat-icon>
|
||||||
{{(isMultiple ? T.F.TASK.D_REMINDER_VIEW.ADD_ALL_TO_TODAY :
|
{{ T.G.MINUTES | translate: { m: 60 } }}
|
||||||
T.F.TASK.D_REMINDER_VIEW.ADD_TO_TODAY)|translate }}
|
|
||||||
</button>
|
</button>
|
||||||
} @if (!isMultiple||(isSingleOnToday$|async)) {
|
|
||||||
<button
|
<button
|
||||||
(click)="play()"
|
(click)="rescheduleAllUntilTomorrow()"
|
||||||
[disabled]="isDisableControls"
|
[disabled]="isDisableControls"
|
||||||
color="primary"
|
mat-menu-item
|
||||||
mat-stroked-button
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<mat-icon>play_arrow</mat-icon>
|
<mat-icon>schedule</mat-icon>
|
||||||
{{(T.F.TASK.D_REMINDER_VIEW.START|translate)}}
|
{{ T.F.TASK.D_REMINDER_VIEW.RESCHEDULE_UNTIL_TOMORROW | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
@if (!isMultiple) {
|
||||||
|
<button
|
||||||
|
(click)="editReminder(tasks[0], true)"
|
||||||
|
mat-menu-item
|
||||||
|
>
|
||||||
|
<mat-icon>edit</mat-icon>
|
||||||
|
{{ T.F.TASK.D_REMINDER_VIEW.RESCHEDULE_EDIT | translate }}
|
||||||
|
</button>
|
||||||
}
|
}
|
||||||
</div>
|
<button
|
||||||
</mat-dialog-actions>
|
(click)="dismissAll()"
|
||||||
<mat-menu #snoozeAllMenu="matMenu">
|
[disabled]="isDisableControls"
|
||||||
<button
|
mat-menu-item
|
||||||
(click)="snoozeAll(10)"
|
>
|
||||||
[disabled]="isDisableControls"
|
<mat-icon>alarm_off</mat-icon>
|
||||||
mat-menu-item
|
{{ (isMultiple ? T.F.TASK.D_REMINDER_VIEW.DISMISS_ALL : T.G.DISMISS) | translate }}
|
||||||
>
|
</button>
|
||||||
<mat-icon>snooze</mat-icon>
|
</mat-menu>
|
||||||
{{T.G.MINUTES|translate:{m: 10} }}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
(click)="snoozeAll(30)"
|
|
||||||
[disabled]="isDisableControls"
|
|
||||||
mat-menu-item
|
|
||||||
>
|
|
||||||
<mat-icon>snooze</mat-icon>
|
|
||||||
{{T.G.MINUTES|translate:{m: 30} }}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
(click)="snoozeAll(60)"
|
|
||||||
[disabled]="isDisableControls"
|
|
||||||
mat-menu-item
|
|
||||||
>
|
|
||||||
<mat-icon>snooze</mat-icon>
|
|
||||||
{{T.G.MINUTES|translate:{m: 60} }}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
(click)="rescheduleAllUntilTomorrow()"
|
|
||||||
[disabled]="isDisableControls"
|
|
||||||
mat-menu-item
|
|
||||||
>
|
|
||||||
<mat-icon>schedule</mat-icon>
|
|
||||||
{{T.F.TASK.D_REMINDER_VIEW.RESCHEDULE_UNTIL_TOMORROW|translate}}
|
|
||||||
</button>
|
|
||||||
@if (!isMultiple) {
|
|
||||||
<button
|
|
||||||
(click)="editReminder(tasks[0], true)"
|
|
||||||
mat-menu-item
|
|
||||||
>
|
|
||||||
<mat-icon>edit</mat-icon>
|
|
||||||
{{T.F.TASK.D_REMINDER_VIEW.RESCHEDULE_EDIT|translate}}
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
<button
|
|
||||||
(click)="dismissAll()"
|
|
||||||
[disabled]="isDisableControls"
|
|
||||||
mat-menu-item
|
|
||||||
>
|
|
||||||
<mat-icon>alarm_off</mat-icon>
|
|
||||||
{{(isMultiple ? T.F.TASK.D_REMINDER_VIEW.DISMISS_ALL : T.G.DISMISS)|translate}}
|
|
||||||
</button>
|
|
||||||
</mat-menu>
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ T.F.TASK.SELECT_OR_CREATE|translate }}</mat-label>
|
<mat-label>{{ T.F.TASK.SELECT_OR_CREATE | translate }}</mat-label>
|
||||||
<input
|
<input
|
||||||
[formControl]="taskSelectCtrl"
|
[formControl]="taskSelectCtrl"
|
||||||
[matAutocomplete]="auto"
|
[matAutocomplete]="auto"
|
||||||
|
|
@ -9,9 +9,10 @@
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
@if (!isCreate) {
|
@if (!isCreate) {
|
||||||
<mat-icon matSuffix="">track_changes</mat-icon>
|
<mat-icon matSuffix="">track_changes</mat-icon>
|
||||||
} @if (isCreate) {
|
}
|
||||||
<mat-icon matSuffix="">add</mat-icon>
|
@if (isCreate) {
|
||||||
|
<mat-icon matSuffix="">add</mat-icon>
|
||||||
}
|
}
|
||||||
|
|
||||||
<mat-autocomplete
|
<mat-autocomplete
|
||||||
|
|
@ -20,25 +21,26 @@
|
||||||
[displayWith]="displayWith"
|
[displayWith]="displayWith"
|
||||||
>
|
>
|
||||||
@for (task of filteredTasks; track trackById($index, task)) {
|
@for (task of filteredTasks; track trackById($index, task)) {
|
||||||
<mat-option
|
<mat-option
|
||||||
[value]="task"
|
[value]="task"
|
||||||
[class.isDone]="task.isDone"
|
[class.isDone]="task.isDone"
|
||||||
>
|
>
|
||||||
@if (task.issueType) {
|
@if (task.issueType) {
|
||||||
<mat-icon [svgIcon]="task.issueType|issueIcon"></mat-icon>
|
<mat-icon [svgIcon]="task.issueType | issueIcon"></mat-icon>
|
||||||
}
|
}
|
||||||
<!---->
|
<!---->
|
||||||
@if (task.projectId) {
|
@if (task.projectId) {
|
||||||
<!---->
|
<!---->
|
||||||
@if (!task.issueType && !projectMap[task.projectId]) {
|
@if (!task.issueType && !projectMap[task.projectId]) {
|
||||||
<mat-icon>library_books</mat-icon>
|
<mat-icon>library_books</mat-icon>
|
||||||
} @if (projectMap[task.projectId]) {
|
}
|
||||||
<tag [tag]="projectMap[task.projectId]"></tag>
|
@if (projectMap[task.projectId]) {
|
||||||
}
|
<tag [tag]="projectMap[task.projectId]"></tag>
|
||||||
<!---->
|
}
|
||||||
}
|
<!---->
|
||||||
<span [innerHTML]="task.title"></span>
|
}
|
||||||
</mat-option>
|
<span [innerHTML]="task.title"></span>
|
||||||
|
</mat-option>
|
||||||
}
|
}
|
||||||
</mat-autocomplete>
|
</mat-autocomplete>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue