Consolidated commit message to v22 signals

This commit is contained in:
2026-08-25 14:45:09 +00:00
parent 6403d25d3e
commit df289b20b8
443 changed files with 16058 additions and 17332 deletions
+126 -121
View File
@@ -1,22 +1,27 @@
<h2 class="row-container space-between">
<span>Journal</span>
<mat-icon matSuffix (click)="voucher.isStarred = !voucher.isStarred" class="pointer" [class.gold]="voucher.isStarred">
{{ voucher.isStarred ? 'star' : 'star_border' }}
<mat-icon
matSuffix
(click)="form.isStarred().value.set(!form.isStarred())"
class="pointer"
[class.gold]="form.isStarred()"
>
{{ form.isStarred() ? 'star' : 'star_border' }}
</mat-icon>
</h2>
<form [formGroup]="form" class="flex-col">
<form [formRoot]="form" class="flex-col">
<div class="row-container">
<mat-form-field class="flex-auto">
<mat-label>Date</mat-label>
<input matInput [matDatepicker]="date" formControlName="date" autocomplete="off" #dateElement />
<input matInput [matDatepicker]="date" [formField]="form.date" autocomplete="off" #dateElement />
<mat-datepicker-toggle matSuffix [for]="date"></mat-datepicker-toggle>
<mat-datepicker #date></mat-datepicker>
</mat-form-field>
</div>
<div formGroupName="addRow" class="row-container">
<div class="row-container">
<mat-form-field class="flex-auto basis-1-6">
<mat-select formControlName="debit">
<mat-select [formField]="form.addRow.debit">
<mat-option [value]="1">Dr</mat-option>
<mat-option [value]="-1">Cr</mat-option>
</mat-select>
@@ -28,149 +33,149 @@
matInput
#accountElement
[matAutocomplete]="auto"
formControlName="account"
[formField]="form.addRow.account"
autocomplete="off"
/>
@if (accBal) {
@if (accBal()) {
<mat-hint>
Balance as on Date: <strong>{{ accBal.date | currency: 'INR' | accounting }}</strong> / Final balance:
<strong>{{ accBal.total | currency: 'INR' | accounting }}</strong>
Balance as on Date: <strong>{{ accBal()?.date | currency: 'INR' | accounting }}</strong> / Final balance:
<strong>{{ accBal()?.total | currency: 'INR' | accounting }}</strong>
</mat-hint>
}
<mat-autocomplete #auto="matAutocomplete" autoActiveFirstOption [displayWith]="displayFn">
@for (account of accounts(); track account) {
<mat-option [value]="account">{{ account.name }}</mat-option>
}
</mat-autocomplete>
</mat-form-field>
<mat-autocomplete
#auto="matAutocomplete"
autoActiveFirstOption
[displayWith]="displayFn"
(optionSelected)="accountSelected($event)"
>
@for (account of accounts | async; track account) {
<mat-option [value]="account">{{ account.name }}</mat-option>
}
</mat-autocomplete>
<mat-form-field class="flex-auto basis-1-6">
<mat-label>Amount</mat-label>
<input type="text" matInput formControlName="amount" autocomplete="off" />
<input type="text" matInput [formField]="form.addRow.amount" autocomplete="off" />
<span matTextPrefix>&nbsp;</span>
</mat-form-field>
<button mat-raised-button color="primary" (click)="addRow()" class="flex-auto basis-1-6">Add</button>
</div>
<mat-table #table [dataSource]="dataSource" matSort aria-label="Elements">
<!-- Debit Column -->
<ng-container matColumnDef="debit">
<mat-header-cell *matHeaderCellDef>Debit</mat-header-cell>
<mat-cell *matCellDef="let row">{{ row.debit === 1 ? 'Dr' : 'Cr' }}</mat-cell>
</ng-container>
@if (itemResource.isLoading()) {
<app-skeleton-loader type="table" [count]="1" />
} @else if (itemResource.error()) {
<app-error-state [message]="'Failed to load data.'" (retryAction)="itemResource.reload()" />
} @else {
<mat-table #table [dataSource]="form.journals().value() ?? []" matSort (matSortChange)="sortData($event)">
<!-- Debit Column -->
<ng-container matColumnDef="debit">
<mat-header-cell *matHeaderCellDef>Debit</mat-header-cell>
<mat-cell *matCellDef="let row">{{ row.debit === 1 ? 'Dr' : 'Cr' }}</mat-cell>
</ng-container>
<!-- Account Column -->
<ng-container matColumnDef="account">
<mat-header-cell *matHeaderCellDef>Account</mat-header-cell>
<mat-cell *matCellDef="let row">{{ row.account.name }}</mat-cell>
</ng-container>
<!-- Account Column -->
<ng-container matColumnDef="account">
<mat-header-cell *matHeaderCellDef>Account</mat-header-cell>
<mat-cell *matCellDef="let row">{{ row.account.name }}</mat-cell>
</ng-container>
<!-- Amount Column -->
<ng-container matColumnDef="amount">
<mat-header-cell *matHeaderCellDef class="right">Amount</mat-header-cell>
<mat-cell *matCellDef="let row" class="right">{{ row.amount | currency: 'INR' }}</mat-cell>
</ng-container>
<!-- Amount Column -->
<ng-container matColumnDef="amount">
<mat-header-cell *matHeaderCellDef class="right">Amount</mat-header-cell>
<mat-cell *matCellDef="let row" class="right">{{ row.amount | currency: 'INR' }}</mat-cell>
</ng-container>
<!-- Action Column -->
<ng-container matColumnDef="action">
<mat-header-cell *matHeaderCellDef class="center">Action</mat-header-cell>
<mat-cell *matCellDef="let row" class="center">
<button mat-icon-button tabindex="-1" (click)="editRow(row)">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button tabindex="-1" color="warn" (click)="deleteRow(row)">
<mat-icon>delete</mat-icon>
</button>
</mat-cell>
</ng-container>
<!-- Action Column -->
<ng-container matColumnDef="action">
<mat-header-cell *matHeaderCellDef class="center">Action</mat-header-cell>
<mat-cell *matCellDef="let row" class="center">
<button mat-icon-button tabindex="-1" (click)="editRow(row)">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button tabindex="-1" color="warn" (click)="deleteRow(row)">
<mat-icon>delete</mat-icon>
</button>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
</mat-table>
<div class="row-container">
<mat-form-field class="flex-auto">
<mat-label>Narration</mat-label>
<textarea matInput matAutosizeMinRows="5" formControlName="narration"></textarea>
</mat-form-field>
</div>
<div class="row-container">
<mat-form-field class="flex-auto">
<mat-label>Tags</mat-label>
<mat-chip-grid #chipGrid aria-label="Tag selection">
@for (tag of voucher.tags; track tag) {
<mat-chip-row (removed)="removeTag(tag)">
{{ tag.name }}
<button matChipRemove [attr.aria-label]="'remove ' + tag.name">
<mat-icon>cancel</mat-icon>
</button>
</mat-chip-row>
}
</mat-chip-grid>
<input
placeholder="New Tag..."
#tagInput
formControlName="tags"
[matChipInputFor]="chipGrid"
[matAutocomplete]="autoTag"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
(matChipInputTokenEnd)="addTag($event)"
/>
<mat-autocomplete #autoTag="matAutocomplete" (optionSelected)="selectedTag($event)">
@for (tag of tags | async; track tag) {
<mat-option [value]="tag">{{ tag.name }}</mat-option>
}
</mat-autocomplete>
</mat-form-field>
</div>
<div class="row-container">
@for (item of voucher.files; track item) {
<div class="img-container" class="flex-auto basis-1-5">
<img [src]="item.thumbnail" alt="img" (click)="zoomImage(item)" (keyup.enter)="zoomImage(item)" tabindex="0" />
<button mat-icon-button class="overlay" (click)="deleteImage(item)">
<mat-icon>delete</mat-icon>
</button>
</div>
}
<div class="img-container" class="flex flex-auto basis-1-5">
<label ng-href for="fileUp">
<img
alt="add"
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTUwIj48cmVjdCB3aWR0aD0iMTAwIiBoZWlnaHQ9IjE1MCIgZmlsbD0iI2VlZSIvPjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjUwIiB5PSI3NSIgc3R5bGU9ImZpbGw6I2FhYTtmb250LXdlaWdodDpib2xkO2ZvbnQtc2l6ZToxMDBweDtmb250LWZhbWlseTpBcmlhbCxIZWx2ZXRpY2Esc2Fucy1zZXJpZjtkb21pbmFudC1iYXNlbGluZTpjZW50cmFsIj4rPC90ZXh0Pjwvc3ZnPg=="
/>
</label>
<input
type="file"
id="fileUp"
multiple
accept="image/*"
style="display: none"
(change)="image.detectFiles($event, voucher)"
/>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
</mat-table>
<div class="row-container">
<mat-form-field class="flex-auto">
<mat-label>Narration</mat-label>
<textarea matInput matAutosizeMinRows="5" [formField]="form.narration"></textarea>
</mat-form-field>
</div>
</div>
<div class="row-container">
<mat-form-field class="flex-auto">
<mat-label>Tags</mat-label>
<mat-chip-grid #chipGrid aria-label="Tag selection">
@for (tag of form.tagList().value(); track tag) {
<mat-chip-row (removed)="removeTag(tag)">
{{ tag.name }}
<button matChipRemove [attr.aria-label]="'remove ' + tag.name">
<mat-icon>cancel</mat-icon>
</button>
</mat-chip-row>
}
</mat-chip-grid>
<input
placeholder="New Tag..."
#tagInput
[formField]="form.tagInput"
[matChipInputFor]="chipGrid"
[matAutocomplete]="autoTag"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
(matChipInputTokenEnd)="addTag()"
/>
<mat-autocomplete #autoTag="matAutocomplete" (optionSelected)="selectedTag($event)">
@for (tag of tags(); track tag) {
<mat-option [value]="tag">{{ tag.name }}</mat-option>
}
</mat-autocomplete>
</mat-form-field>
</div>
<div class="row-container">
@for (item of form.files().value(); track item) {
<div class="img-container" class="flex-auto basis-1-5">
<img
[src]="item.thumbnail"
alt="img"
(click)="zoomImage(item)"
(keyup.enter)="zoomImage(item)"
tabindex="0"
/>
<button mat-icon-button class="overlay" (click)="deleteImage(item)">
<mat-icon>delete</mat-icon>
</button>
</div>
}
<div class="img-container" class="flex flex-auto basis-1-5">
<label ng-href for="fileUp">
<img
alt="add"
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTUwIj48cmVjdCB3aWR0aD0iMTAwIiBoZWlnaHQ9IjE1MCIgZmlsbD0iI2VlZSIvPjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjUwIiB5PSI3NSIgc3R5bGU9ImZpbGw6I2FhYTtmb250LXdlaWdodDpib2xkO2ZvbnQtc2l6ZToxMDBweDtmb250LWZhbWlseTpBcmlhbCxIZWx2ZXRpY2Esc2Fucy1zZXJpZjtkb21pbmFudC1iYXNlbGluZTpjZW50cmFsIj4rPC90ZXh0Pjwvc3ZnPg=="
/>
</label>
<input type="file" id="fileUp" multiple accept="image/*" style="display: none" (change)="detectFiles($event)" />
</div>
</div>
}
</form>
<div class="row-container">
<button mat-raised-button color="primary" (click)="save()" [disabled]="!canSave()" class="">
{{ voucher.id ? 'Update' : 'Save' }}
{{ id() ? 'Update' : 'Save' }}
</button>
@if (voucher.id) {
<button mat-raised-button (click)="post()" [disabled]="voucher.posted || !auth.allowed('post-vouchers')" class="">
{{ voucher.posted ? 'Posted' : 'Post' }}
@if (id()) {
<button mat-raised-button (click)="post()" [disabled]="form.posted().controlValue()" class="">
{{ form.posted().controlValue() ? 'Posted' : 'Post' }}
</button>
<button mat-raised-button color="warn" (click)="confirmDelete()" [disabled]="!canSave()">Delete</button>
}
<span class="spacer"></span>
@if (voucher.id) {
@if (id()) {
<span class="flex">
Created on&nbsp;<strong>{{ voucher.creationDate | localTime }}</strong
>&nbsp;and Last Edited on&nbsp; <strong>{{ voucher.lastEditDate | localTime }}</strong
>&nbsp;by&nbsp; <strong>{{ voucher.user.name }}</strong
>. {{ voucher.poster ? 'Posted by ' + voucher.poster : '' }}
Created on&nbsp;<strong>{{ form.creationDate().value() | localTime }}</strong
>&nbsp;and Last Edited on&nbsp; <strong>{{ form.lastEditDate().value() | localTime }}</strong
>&nbsp;by&nbsp; <strong>{{ form.userName() }}</strong
>. {{ form.posted() ? 'Posted by ' + form.poster() : '' }}
</span>
}
</div>