18.9.3 • Published 8 months ago

pro-web v18.9.3

Weekly downloads
-
License
-
Repository
-
Last release
8 months ago

Pro Web

A modern web-based version of ITrack Pro.

Moved from SVN to GitHub at SVN revision 32416

Getting started for development

  • clone repo
  • make sure you have node version 20+ installed
  • make sure you are logged into an npm account(npm login) that has access to the @isoftdata npm organization. If you don't have access, ask another ISoft developer for an invite.
  • Run npm i in the cloned pro-web directory
  • create a config.json file (see config.template.json)
  • build the server with npm run build-server-watch
  • start the server for dev by running npm run startdev. This will also build and serve the client.
    • By default, this will look for a config.json file. If you want to user another file, run npm run startdev <theFileName>
  • open your browser to localhost on the port specified in the config.json file's webport property.

Instead of running build-server-watch and startdev manually, you can run the "Server: Dev" debug configuration

Yup Schema Validation

Yup is used for schema validation, custom methods have been added to make handling dates and other data types easier. To access these on the server, you should require tools/yup-helper instead of yup. This will give you access to all the features of yup, plus the added custom methods, which are detailed below.

yup.mixed().dateNowOnInsert(primaryKeyName)

If the named primary key is truthy (i.e., when inserting a new row), it will strip off this property. Otherwise (i.e. updating an existing row), it will replace the property's value with the current date and time according to the database. This will also work fine if you already pass db.NOW on the property, since it matches the shape enforced by this function.

yup.mixed().dateNow()

Replaces the current value with the current date and time according to the database.

yup.boolean().enumBool()

Coerces a string ('True' or 'False'), native JS boolean, or other value(truthyness test) to a string with the value of either "True" or "False".

yup.number().precision(integer)

Evaluates whether the current value has at most the specified number of digits.

yup.string().ensureValidIsoDate()

Evaluates whether the current value is a valid string representation of an ISO date

yup.string().isValidJSON()

Evaluates whether the current value is valid JSON by parsing it.

printValueAndType

Prints the value and type of the current value without mutating it. Used for debugging.

Error logging and handling

Logging errors in mediator requests

Whenever you make a mediator request to emitToServer or noAuthEmitToServer, any errors thrown by the server will implicitly be caught, logged, and an alert will be shown to the user. If you want to override the default behavior, you can optionally pass a third parameter in your mediator request, an object with the properties shown below.

logOptions properties

PropertyTypeDescriptionDefault
messagestringThe message that will be shown to the user. If truthy, is used instead of the default, unless the error is a Yup ValidationErrorDepends on the error
contextanyAnything you want logged alongside the error to give more context, such as a state or endpoint name.''
doNotAlertbooleanIf truthy, the user will not be alerted to the error, but it will still be logged. Useful for if you show errors to the user some other way.false

Example

const auth = await mediator.call('noAuthEmitToServer', 'authenticate', {
	userName,
	passphrase,
	storeId,
}, { doNotAlert: true, message: '', context: 'login' })

Logging errors elsewhere in client code

If you want to log errors outside of mediator requests, you can do so with the logAndAlert function, which is included in the context object passed to every state.

Function arguments

ArgumentTypeDescriptionDefault
errErrorA JS error. If absent, nothing will be logged or alerted.undefined
mediatorObjectThe mediator. Used to call showMessage to show alerts. If absent, uses vanilla JS alerts.undefined
messagestringThe message that will be shown to the user and logged with the error. If truthy, is used instead of the default, unless the error is a Yup ValidationErrorDepends on the error
contextanyAnything you want logged alongside the error to give more context, such as a state or endpoint name.''
showMessageOptionsObjectAny options you want to pass to showMessage. If this is explicitly false, the alert will not be shown.{}

Example

try {
	// Something that can throw an error
} catch (err) {
	logAndAlert(
	err,
	mediator,
	'This will be shown to the user and logged with the error. It should be a string',
	'This will be logged alongside the error. It can be of any type.',
	{
		type: 'danger', // Bootstrap alert class
		time: 3000, // Milliseconds before the alert dismisses itself
		dismissable: true // Whether to allow the user to dismiss the alert
	})
}

Retrieving the error log

The error log is stored in the localStorage variable errorLog. You can view it from the web browser's console. At the top level, it is an object whose keys are the userAccountId of the logged in user when the error was logged. Each of these properties is an array of objects, representing any errors that were logged, sorted by age, newest first. Only 100 logs will be stored per user, then the oldest will be removed whenever a new error is inserted.

There is also a function, getErrorLog, that retrieves this object from localStorage.

Reporting/Charting

Pro web has a set of three database tables and views where reports, charts, and their associations are defined: wa_dashboard_report, wa_dashboard_chart, and wa_dashboard_report_chart. Reports are a collection of various charts. Reports have parameters and charts can use said parameters. Currently Charts are rendered using Google Charts.

Defining a Report

Inside of Pro web, reports can be created on the Configuration > Dashboard screen. This includes the report name, the charts contained within it, who it is shared with, and the default value of any parameters. Currently it is not possible to add or remove parameters for reports within Pro web, because all charts require the date range parameter, and support no others.

Report Database Row - wa_dashboard_report

PropertyTypeDescription
dashboard_report_idUnsigned integerRequired - Primary key. Auto incremented.
report_nameStringRequired - a unique name for the report.
report_titleStringWhen rendered, this title will be displayed at the top of the card. If omitted, name will be used.
jsonTextParsed into JSON on the server, this field contains JSON for an array of parameter objects, the format of which is detailed below.
share_typeEnumControls access to reports within Pro web. Possible values include: everyone, group, store, and user. Defaults to everyone.
share_idUnsigned integerUsed in conjunction with share_type to control access to reports. When share_type is 'everyone', this field is null. Otherwise, it contains the id of the user, group, or store to share the report with. Defaults to NULL.
owner_idUnsigned integerThe user_account_id of the user who created the report within Pro web. This user will always have access to the given report, regardless of its sharing settings, and will be shown as the report owner on the configuration screen. Defaults to NULL, which designates it as a default report.

Parameter Object

PropertyTypeDescription
nameStringRequired - a unique name for the parameter. This name is also used to reference param in a query.
titleStringThis is used to label the parameter for the user.
typeStringCan be one of dateRange, date, or selection. See the tables below for parameter-type-specific properties
dateRange Type Properties

In the UI, the user will see a dropdown with the possible date range values(see default description below).

PropertyTypeDescription
defaultStringOne of the following values: 'Today', 'Yesterday', 'Last 7 Days', 'Last 30 Days', 'Last 90 Days', 'Last 365 Days', 'This Week', 'This Month', 'This Quarter', 'This Year', 'Previous Week', 'Previous Month', 'Previous Quarter', or 'Previous Year'. If the default property is omitted or falsy, 'Last 30 Days' will be used.
date Type Properties

In the UI, the user will see a dropdown with a date picker.

PropertyTypeDescription
defaultStringCan be an ISO 8601 date string(eg. '2021-01-13'). If the default property is omitted or falsy, the today's date will be used.
selection Type properties

In the UI, the user will see a dropdown with the optionList values(if any) and the values returned from the optionListQuery(if any).

PropertyTypeDescription
defaultStringThe id of the option you'd like to be selected by default
optionListObjectEach object should have an id, and name. id is the value that will be given to you at query time and name is what will be displayed in the dropdown to the user.
optionListQueryStringA query that selects 2 columns id and name. The results of this query will be merged with optionList and put in the dropdown for the user.

Example

'dashboard_report_id''report_name''report_title''json''share_type''share_id''owner_id'
1report_overviewOverview{"parameters": [{"name": "date_range", "type": "dateRange", "title": "Date Range", "default": "This Year"}]}everyoneNULLNULL
2shared_reportShared Report{"parameters":[{"name":"date_range","type":"dateRange","title":"Date Range","default":"This Month"}]}user12

Defining a Chart

Currently, charts cannot be defined within Pro web, and must be created in the database view wa_dashboard_chart. Currently, 19 charts are defined, but some are set to not show as options in the user interface.

Chart Database Row - wa_dashboard_chart

PropertyTypeDescription
chart_idUnsigned integerRequired - primary key. Auto incremented.
chart_nameStringRequired - a unique name for the chart
chart_titleStringWhen rendered, this title will be displayed at the top of the card. If omitted, name will be used.
supertypeEnumRequired - designates how the chart should be loaded. Options include google, table, and embed. Defaults to google.
jsonTextParsed to JSON on the server. Contains several properties: query (string, required), chartWrapper (object, required for Google charts), multiSeries (object, required for multi-series charts), formatting (object).
show_chartBitRequired - whether or not to show a chart in the UI. Defaults to 1.

MultiSeries Object

PropertyTypeDescription
groupXAxisByStringRequired - The name of the query column that determines the X axis of the chart.
seriesStringRequired - The name of the query column that determines which series a query row corresponds to.
valueStringRequired - The namem of the query column that contains the value for that data point.
tooltipStringThe name of the (optional) query column that contains a custom plaintext tooltip, which replaces the default Google Charts tooltip. Does not work for Tree Map type charts, which have special tooltip requirements.

Formatting Object

An object whose property names are the columns in the query to be formatted. Currently only currency formatting is supported.

PropertyTypeDescription
typeStringThe name of a Google Charts Formatter.
formatStringThe name of a formatter template, defined in charts.json.

JSON Example

{
	"chartWrapper": {
		"chartType": "AreaChart",
		"options": {
			"isStacked": true,
			"width": 1000,
			"height": 1000
		}
	},
	"multiSeries": {
		"groupXAxisBy": "Date",
		"series": "Part Type",
		"value": "Sales",
		"tooltip": "Tooltip"
	},
	"formatting": {
		"Sales": {
			"type": "NumberFormat",
			"format": "CURRENCY"
		}
	},
	"query": "SELECT t.date AS `Date`,\r\n       IFNULL (t.part_type, 'Misc. Lineitems') AS `Part Type`,\r\n       ROUND(@running_total:=@running_total + t.sales, 2) AS `Sales`\r\nFROM\r\n(SELECT \r\n`wa_sale`.`document_date` AS `Date`,\r\nIF(wa_sale_line.part_type = '', 'Misc. Lineitems', wa_sale_line.part_type) AS `part_type`,\r\nFORMAT(SUM(wa_sale_line.quantity * `wa_sale_line`.`price`), 2) AS `sales`\r\nFROM \r\n`wa_sale_line`\r\nINNER JOIN `wa_sale` USING(`sale_id`)\r\nWHERE\r\n`wa_sale`.`status` = 'Invoice' AND wa_sale.document_date IS NOT NULL\r\n GROUP BY \r\n `wa_sale`.`document_date`, `wa_sale_line`.`part_type`) t\r\n JOIN (SELECT @running_total:=0) r\r\n ORDER BY t.Date;"
}

Adding charts to reports

Adding charts to reports is handled entirely in the interface of Pro web, on the Configuration > Dashboard screen. Each row in the database view wa_dashboard_report_chart defines the association of one chart to one report, the rank of the chart within the report, and any JSON to apply to the chart when displayed in that report.

Report Chart Database Row - wa_dashboard_report_chart

PropertyTypeDescription
report_chart_idUnsigned integerRequired - Primary key. Auto incremented.
dashboard_report_idUnsigned integerRequired - Foreign key constraint with wa_dashboard_report.dashboard_report_id.
chart_idUnsigned integerRequired - Foreign key constraint with wa_dashboard_chart.dashboad_chart_id. chart_id and dashboard_report_id must be a unique pair.
rankUnsigned integerThe order to display the chart in on the report. Defaults to 1.
json_overrideTextParsed as JSON on the server. Contains any JSON properties to be applied to the chart for the given report, overriding any of the same property on the base chart. Primarily used for chartWarpper options. Default NULL.
@isoftdata/address-card@isoftdata/alert@isoftdata/attachment@isoftdata/autocomplete@isoftdata/button@isoftdata/carousel@isoftdata/carousel-item@isoftdata/checkbox@isoftdata/checkbox-button@isoftdata/currency-input@isoftdata/dashboard-big-query-connector@isoftdata/date-range@isoftdata/file-service@isoftdata/focused-element-is-input@isoftdata/image-thumbnail-viewer@isoftdata/image-viewer-modal@isoftdata/input@isoftdata/isoft-authentication@isoftdata/json-to-csv@isoftdata/label@isoftdata/list@isoftdata/load-item-modal@isoftdata/login-component@isoftdata/map-button@isoftdata/modal@isoftdata/mysql-full-text-require-all-words@isoftdata/nav-tab-bar-component@isoftdata/quickbooks-online@isoftdata/ractive-method-upsert@isoftdata/ractive-svelte-state-renderer-wrapper@isoftdata/report-viewer@isoftdata/scanner-support@isoftdata/select@isoftdata/sidebar-component@isoftdata/split-button@isoftdata/stepper-buttons@isoftdata/svelte-alert@isoftdata/svelte-attachments@isoftdata/svelte-autocomplete@isoftdata/svelte-button@isoftdata/svelte-checkbox@isoftdata/svelte-currency-input@isoftdata/svelte-date-range@isoftdata/svelte-icon@isoftdata/svelte-input@isoftdata/svelte-load-item-modal@isoftdata/svelte-modal@isoftdata/svelte-nav-tab-bar@isoftdata/svelte-report-job-modal@isoftdata/svelte-report-viewer@isoftdata/svelte-scanner-configuration@isoftdata/svelte-select@isoftdata/svelte-table@isoftdata/svelte-textarea@isoftdata/table@isoftdata/table-card-footer@isoftdata/td@isoftdata/textarea@isoftdata/toggle-selection-component@isoftdata/user-avatar-component@isoftdata/utility-array@isoftdata/utility-boolean@isoftdata/utility-bootstrap@isoftdata/utility-currency@isoftdata/utility-dashboard-backend@isoftdata/utility-date-time@isoftdata/utility-db@isoftdata/utility-financial-subset-sum@isoftdata/utility-object@isoftdata/utility-string@isoftdata/utility-url@isoftdata/web-dashboard@isoftdata/year-input@isoftdata/yes-no-modal@lukeed/uuid@yaireo/tagifyabstract-state-routerasr-active-state-watcherasr-fsm-navigationcamelcasecamelcase-keyschalkcommand-line-configdate-fnsdequaldom-valueexpressfinancial-numberfuzzysortgotintuit-oauthjust-kebab-casejust-splitkeyboardjsklonalog-timestampmannishmd5mimermultermysqlnodemailerp-mapp-propsp-seriesp-throttlep-waterfallpromise-file-readerractive-drag-and-drop-filesractive-select-on-focusractive-transitions-faderactive-transitions-flyractive-transitions-slidesecure-random-passwordsharpsnakeizesocket.iosql-concatto-snake-caseto-title-casevinidatorvite-expressyup
18.9.3

8 months ago