mirror of
https://github.com/frappe/books.git
synced 2024-12-22 10:58:59 +00:00
fix: PrintTemplate list view
- type ListCell - improve ListViewConfig types, update where required
This commit is contained in:
parent
f9fbefad0e
commit
dabcbcd2ce
@ -13,7 +13,7 @@ import { TelemetryManager } from './telemetry/telemetry';
|
||||
import {
|
||||
DEFAULT_CURRENCY,
|
||||
DEFAULT_DISPLAY_PRECISION,
|
||||
DEFAULT_INTERNAL_PRECISION
|
||||
DEFAULT_INTERNAL_PRECISION,
|
||||
} from './utils/consts';
|
||||
import * as errors from './utils/errors';
|
||||
import { format } from './utils/format';
|
||||
@ -88,7 +88,7 @@ export class Fyo {
|
||||
return this.db.fieldMap;
|
||||
}
|
||||
|
||||
format(value: DocValue, field: string | Field, doc?: Doc) {
|
||||
format(value: unknown, field: string | Field, doc?: Doc) {
|
||||
return format(value, field, doc ?? null, this);
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { Fyo } from 'fyo';
|
||||
import { DocValue, DocValueMap } from 'fyo/core/types';
|
||||
import SystemSettings from 'fyo/models/SystemSettings';
|
||||
import { FieldType, Schema, SelectOption } from 'schemas/types';
|
||||
@ -76,13 +77,12 @@ export interface RenderData {
|
||||
[key: string]: DocValue | Schema
|
||||
}
|
||||
|
||||
export interface ColumnConfig {
|
||||
export type ColumnConfig = {
|
||||
label: string;
|
||||
fieldtype: FieldType;
|
||||
fieldname?: string;
|
||||
size?: string;
|
||||
fieldname: string;
|
||||
render?: (doc: RenderData) => { template: string };
|
||||
getValue?: (doc: Doc) => string;
|
||||
display?: (value: unknown, fyo: Fyo) => string;
|
||||
}
|
||||
|
||||
export type ListViewColumn = string | ColumnConfig;
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { Fyo } from 'fyo';
|
||||
import { DocValue } from 'fyo/core/types';
|
||||
import { Doc } from 'fyo/model/doc';
|
||||
import { DateTime } from 'luxon';
|
||||
import { Money } from 'pesa';
|
||||
import { Field, FieldType, FieldTypeEnum } from 'schemas/types';
|
||||
import { getIsNullOrUndef, safeParseFloat } from 'utils';
|
||||
import { getIsNullOrUndef, safeParseFloat, titleCase } from 'utils';
|
||||
import {
|
||||
DEFAULT_CURRENCY,
|
||||
DEFAULT_DATE_FORMAT,
|
||||
@ -13,7 +12,7 @@ import {
|
||||
} from './consts';
|
||||
|
||||
export function format(
|
||||
value: DocValue,
|
||||
value: unknown,
|
||||
df: string | Field | null,
|
||||
doc: Doc | null,
|
||||
fyo: Fyo
|
||||
@ -45,7 +44,7 @@ export function format(
|
||||
}
|
||||
|
||||
if (field.fieldtype === FieldTypeEnum.Check) {
|
||||
return Boolean(value).toString();
|
||||
return titleCase(Boolean(value).toString());
|
||||
}
|
||||
|
||||
if (getIsNullOrUndef(value)) {
|
||||
@ -55,26 +54,31 @@ export function format(
|
||||
return String(value);
|
||||
}
|
||||
|
||||
function toDatetime(value: DocValue) {
|
||||
function toDatetime(value: unknown): DateTime | null {
|
||||
if (typeof value === 'string') {
|
||||
return DateTime.fromISO(value);
|
||||
} else if (value instanceof Date) {
|
||||
return DateTime.fromJSDate(value);
|
||||
} else {
|
||||
} else if (typeof value === 'number') {
|
||||
return DateTime.fromSeconds(value as number);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function formatDatetime(value: DocValue, fyo: Fyo): string {
|
||||
function formatDatetime(value: unknown, fyo: Fyo): string {
|
||||
if (value == null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const dateFormat =
|
||||
(fyo.singles.SystemSettings?.dateFormat as string) ?? DEFAULT_DATE_FORMAT;
|
||||
const formattedDatetime = toDatetime(value).toFormat(
|
||||
`${dateFormat} HH:mm:ss`
|
||||
);
|
||||
const dateTime = toDatetime(value);
|
||||
if (!dateTime) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const formattedDatetime = dateTime.toFormat(`${dateFormat} HH:mm:ss`);
|
||||
|
||||
if (value === 'Invalid DateTime') {
|
||||
return '';
|
||||
@ -83,7 +87,7 @@ function formatDatetime(value: DocValue, fyo: Fyo): string {
|
||||
return formattedDatetime;
|
||||
}
|
||||
|
||||
function formatDate(value: DocValue, fyo: Fyo): string {
|
||||
function formatDate(value: unknown, fyo: Fyo): string {
|
||||
if (value == null) {
|
||||
return '';
|
||||
}
|
||||
@ -91,9 +95,12 @@ function formatDate(value: DocValue, fyo: Fyo): string {
|
||||
const dateFormat =
|
||||
(fyo.singles.SystemSettings?.dateFormat as string) ?? DEFAULT_DATE_FORMAT;
|
||||
|
||||
const dateValue: DateTime = toDatetime(value);
|
||||
const dateTime = toDatetime(value);
|
||||
if (!dateTime) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const formattedDate = dateValue.toFormat(dateFormat);
|
||||
const formattedDate = dateTime.toFormat(dateFormat);
|
||||
if (value === 'Invalid DateTime') {
|
||||
return '';
|
||||
}
|
||||
@ -102,7 +109,7 @@ function formatDate(value: DocValue, fyo: Fyo): string {
|
||||
}
|
||||
|
||||
function formatCurrency(
|
||||
value: DocValue,
|
||||
value: unknown,
|
||||
field: Field,
|
||||
doc: Doc | null,
|
||||
fyo: Fyo
|
||||
@ -125,7 +132,7 @@ function formatCurrency(
|
||||
return valueString;
|
||||
}
|
||||
|
||||
function formatNumber(value: DocValue, fyo: Fyo): string {
|
||||
function formatNumber(value: unknown, fyo: Fyo): string {
|
||||
const numberFormatter = getNumberFormatter(fyo);
|
||||
if (typeof value === 'number') {
|
||||
value = fyo.pesa(value.toFixed(20));
|
||||
|
@ -70,8 +70,8 @@ export class JournalEntry extends Transactional {
|
||||
'name',
|
||||
{
|
||||
label: t`Status`,
|
||||
fieldname: 'status',
|
||||
fieldtype: 'Select',
|
||||
size: 'small',
|
||||
render(doc) {
|
||||
const status = getDocStatus(doc);
|
||||
const color = statusColor[status] ?? 'gray';
|
||||
|
@ -2,6 +2,7 @@ import { Doc } from 'fyo/model/doc';
|
||||
import { SchemaMap } from 'schemas/types';
|
||||
import { ListsMap, ListViewSettings, ReadOnlyMap } from 'fyo/model/types';
|
||||
import { ModelNameEnum } from 'models/types';
|
||||
import { Fyo } from 'fyo';
|
||||
|
||||
export class PrintTemplate extends Doc {
|
||||
name?: string;
|
||||
@ -17,10 +18,21 @@ export class PrintTemplate extends Doc {
|
||||
return super.canDelete;
|
||||
}
|
||||
|
||||
static getListViewSettings(): ListViewSettings {
|
||||
static getListViewSettings(fyo: Fyo): ListViewSettings {
|
||||
return {
|
||||
formRoute: (name) => `/template-builder/${name}`,
|
||||
columns: ['name', 'type', 'isCustom'],
|
||||
columns: [
|
||||
'name',
|
||||
{
|
||||
label: fyo.t`Type`,
|
||||
fieldtype: 'AutoComplete',
|
||||
fieldname: 'type',
|
||||
display(value) {
|
||||
return fyo.schemaMap[value as string]?.label ?? '';
|
||||
},
|
||||
},
|
||||
'isCustom',
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -311,7 +311,6 @@ export function getDocStatusListColumn(): ColumnConfig {
|
||||
label: t`Status`,
|
||||
fieldname: 'status',
|
||||
fieldtype: 'Select',
|
||||
size: 'small',
|
||||
render(doc) {
|
||||
const status = getDocStatus(doc);
|
||||
const color = statusColor[status] ?? 'gray';
|
||||
|
@ -80,6 +80,13 @@ export class StockMovement extends Transfer {
|
||||
};
|
||||
|
||||
static getListViewSettings(fyo: Fyo): ListViewSettings {
|
||||
const movementTypeMap = {
|
||||
[MovementType.MaterialIssue]: fyo.t`Material Issue`,
|
||||
[MovementType.MaterialReceipt]: fyo.t`Material Receipt`,
|
||||
[MovementType.MaterialTransfer]: fyo.t`Material Transfer`,
|
||||
[MovementType.Manufacture]: fyo.t`Manufacture`,
|
||||
};
|
||||
|
||||
return {
|
||||
formRoute: (name) => `/edit/StockMovement/${name}`,
|
||||
columns: [
|
||||
@ -90,20 +97,8 @@ export class StockMovement extends Transfer {
|
||||
label: fyo.t`Movement Type`,
|
||||
fieldname: 'movementType',
|
||||
fieldtype: 'Select',
|
||||
size: 'small',
|
||||
render(doc) {
|
||||
const movementType = doc.movementType as MovementType;
|
||||
const label =
|
||||
{
|
||||
[MovementType.MaterialIssue]: fyo.t`Material Issue`,
|
||||
[MovementType.MaterialReceipt]: fyo.t`Material Receipt`,
|
||||
[MovementType.MaterialTransfer]: fyo.t`Material Transfer`,
|
||||
[MovementType.Manufacture]: fyo.t`Manufacture`,
|
||||
}[movementType] ?? '';
|
||||
|
||||
return {
|
||||
template: `<span>${label}</span>`,
|
||||
};
|
||||
display(value): string {
|
||||
return movementTypeMap[value as MovementType] ?? '';
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -37,7 +37,7 @@
|
||||
|
||||
<!-- Data Rows -->
|
||||
<div class="overflow-y-auto custom-scroll" v-if="dataSlice.length !== 0">
|
||||
<div v-for="(doc, i) in dataSlice" :key="doc.name">
|
||||
<div v-for="(row, i) in dataSlice" :key="row.name">
|
||||
<!-- Row Content -->
|
||||
<div class="flex hover:bg-gray-50 items-center">
|
||||
<p class="w-8 text-end me-4 text-gray-900">
|
||||
@ -46,7 +46,7 @@
|
||||
<Row
|
||||
gap="1rem"
|
||||
class="cursor-pointer text-gray-900 flex-1 h-row-mid"
|
||||
@click="$emit('openDoc', doc.name)"
|
||||
@click="$emit('openDoc', row.name)"
|
||||
:columnCount="columns.length"
|
||||
>
|
||||
<ListCell
|
||||
@ -56,7 +56,7 @@
|
||||
'text-end': isNumeric(column.fieldtype),
|
||||
'pe-4': c === columns.length - 1,
|
||||
}"
|
||||
:doc="doc"
|
||||
:row="row"
|
||||
:column="column"
|
||||
/>
|
||||
</Row>
|
||||
@ -95,7 +95,6 @@ import Paginator from 'src/components/Paginator.vue';
|
||||
import Row from 'src/components/Row';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { isNumeric } from 'src/utils';
|
||||
import { openQuickEdit, routeTo } from 'src/utils/ui';
|
||||
import { objectForEach } from 'utils/index';
|
||||
import { defineComponent, toRaw } from 'vue';
|
||||
import ListCell from './ListCell';
|
||||
|
@ -4,26 +4,52 @@
|
||||
<component v-else :is="customRenderer" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { ColumnConfig, RenderData } from 'fyo/model/types';
|
||||
import { Field } from 'schemas/types';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { isNumeric } from 'src/utils';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
|
||||
export default {
|
||||
type Column = ColumnConfig | Field;
|
||||
|
||||
function isField(column: ColumnConfig | Field): column is Field {
|
||||
if ((column as ColumnConfig).display || (column as ColumnConfig).render) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ListCell',
|
||||
props: ['doc', 'column'],
|
||||
props: {
|
||||
row: { type: Object as PropType<RenderData>, required: true },
|
||||
column: { type: Object as PropType<Column>, required: true },
|
||||
},
|
||||
computed: {
|
||||
columnValue() {
|
||||
let { column, doc } = this;
|
||||
let value = doc[column.fieldname];
|
||||
return fyo.format(value, column, doc);
|
||||
columnValue(): string {
|
||||
const column = this.column;
|
||||
const value = this.row[this.column.fieldname];
|
||||
|
||||
if (isField(column)) {
|
||||
return fyo.format(value, column);
|
||||
}
|
||||
|
||||
return column.display?.(value, fyo) ?? '';
|
||||
},
|
||||
customRenderer() {
|
||||
if (!this.column.render) return;
|
||||
return this.column.render(this.doc);
|
||||
const { render } = this.column as ColumnConfig;
|
||||
|
||||
if (!render) {
|
||||
return;
|
||||
}
|
||||
|
||||
return render(this.row);
|
||||
},
|
||||
cellClass() {
|
||||
return isNumeric(this.column.fieldtype) ? 'justify-end' : '';
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
@ -344,36 +344,6 @@ async function openEdit({ name, schemaName }: Doc) {
|
||||
|
||||
const route = getFormRoute(schemaName, name);
|
||||
return await routeTo(route);
|
||||
|
||||
/*
|
||||
const listConfig = fyo.models[doc.schemaName]?.getListViewSettings?.(fyo);
|
||||
const formRoute = listConfig?.formRoute;
|
||||
if (!doc.name) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (formRoute) {
|
||||
const route = formRoute(doc.name);
|
||||
return await routeTo(route);
|
||||
}
|
||||
|
||||
const isFormEdit = [
|
||||
ModelNameEnum.SalesInvoice,
|
||||
ModelNameEnum.PurchaseInvoice,
|
||||
ModelNameEnum.JournalEntry,
|
||||
ModelNameEnum.Shipment,
|
||||
ModelNameEnum.PurchaseReceipt,
|
||||
ModelNameEnum.StockMovement,
|
||||
ModelNameEnum.Payment,
|
||||
ModelNameEnum.Item,
|
||||
].includes(doc.schemaName as ModelNameEnum);
|
||||
|
||||
if (isFormEdit) {
|
||||
return await routeTo(`/edit/${doc.schemaName}/${doc.name}`);
|
||||
}
|
||||
|
||||
await openQuickEdit({ schemaName: doc.schemaName, name: doc.name });
|
||||
*/
|
||||
}
|
||||
|
||||
function getDuplicateAction(doc: Doc): Action {
|
||||
|
Loading…
Reference in New Issue
Block a user