mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) updates from grist-core
This commit is contained in:
@@ -504,6 +504,11 @@ export class RightPanel extends Disposable {
|
||||
const srcSec = use(tgtSec.linkSrcSection); //might be the empty section
|
||||
const srcCol = use(tgtSec.linkSrcCol);
|
||||
const srcColId = use(use(tgtSec.linkSrcCol).colId); // if srcCol is the empty col, colId will be undefined
|
||||
|
||||
if (srcSec.isDisposed()) { // can happen when deleting srcSection with rightpanel open
|
||||
return cssLinkInfoPanel("");
|
||||
}
|
||||
|
||||
//const tgtColId = use(use(tgtSec.linkTargetCol).colId);
|
||||
const srcTable = use(srcSec.table);
|
||||
const tgtTable = use(tgtSec.table);
|
||||
@@ -616,6 +621,11 @@ export class RightPanel extends Disposable {
|
||||
// but the fact that it's all observables makes that trickier to do correctly, so let's leave it here
|
||||
const srcSec = use(activeSection.linkSrcSection); //might be the empty section
|
||||
const tgtSec = activeSection;
|
||||
|
||||
if (srcSec.isDisposed()) { // can happen when deleting srcSection with rightpanel open
|
||||
return cssRow("");
|
||||
}
|
||||
|
||||
const srcCol = use(activeSection.linkSrcCol); // might be the empty column
|
||||
const tgtCol = use(activeSection.linkTargetCol);
|
||||
// columns might be the empty column
|
||||
|
||||
@@ -1046,6 +1046,11 @@ export function buildTelemetryEventChecker(telemetryLevel: TelemetryLevel) {
|
||||
`but received a value of type ${typeof value}`
|
||||
);
|
||||
}
|
||||
if (typeof value === 'string' && !hasTimezone(value)) {
|
||||
throw new Error(
|
||||
`Telemetry metadata ${key} of event ${event} has an ambiguous date string`
|
||||
);
|
||||
}
|
||||
} else if (dataType !== typeof value) {
|
||||
throw new Error(
|
||||
`Telemetry metadata ${key} of event ${event} expected a value of type ${dataType} ` +
|
||||
@@ -1056,4 +1061,11 @@ export function buildTelemetryEventChecker(telemetryLevel: TelemetryLevel) {
|
||||
};
|
||||
}
|
||||
|
||||
// Check that datetime looks like it has a timezone in it. If not,
|
||||
// that could be a problem for whatever ingests the data.
|
||||
function hasTimezone(isoDateString: string) {
|
||||
// Use a regular expression to check for a timezone offset or 'Z'
|
||||
return /([+-]\d{2}:\d{2}|Z)$/.test(isoDateString);
|
||||
}
|
||||
|
||||
export type TelemetryEventChecker = (event: TelemetryEvent, metadata?: TelemetryMetadata) => void;
|
||||
|
||||
@@ -13,6 +13,7 @@ import log from 'app/server/lib/log';
|
||||
import { IPermitStore } from 'app/server/lib/Permit';
|
||||
import { optStringParam, stringParam } from 'app/server/lib/requestUtils';
|
||||
import * as express from 'express';
|
||||
import moment from 'moment';
|
||||
import fetch from 'node-fetch';
|
||||
import * as Fetch from 'node-fetch';
|
||||
import { EntityManager } from 'typeorm';
|
||||
@@ -185,8 +186,8 @@ export class Housekeeper {
|
||||
numDocs: Number(summary.num_docs),
|
||||
numWorkspaces: Number(summary.num_workspaces),
|
||||
numMembers: Number(summary.num_members),
|
||||
lastActivity: summary.last_activity,
|
||||
earliestDocCreatedAt: summary.earliest_doc_created_at,
|
||||
lastActivity: normalizedDateTimeString(summary.last_activity),
|
||||
earliestDocCreatedAt: normalizedDateTimeString(summary.earliest_doc_created_at),
|
||||
},
|
||||
full: {
|
||||
stripePlanId: summary.stripe_plan_id,
|
||||
@@ -398,3 +399,29 @@ export class Housekeeper {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output an ISO8601 format datetime string, with timezone.
|
||||
* Any string fed in without timezone is expected to be in UTC.
|
||||
*
|
||||
* When connected to postgres, dates will be extracted as Date objects,
|
||||
* with timezone information. The normalization done here is not
|
||||
* really needed in this case.
|
||||
*
|
||||
* Timestamps in SQLite are stored as UTC, and read as strings
|
||||
* (without timezone information). The normalization here is
|
||||
* pretty important in this case.
|
||||
*/
|
||||
function normalizedDateTimeString(dateTime: any): string {
|
||||
if (!dateTime) { return dateTime; }
|
||||
if (dateTime instanceof Date) {
|
||||
return moment(dateTime).toISOString();
|
||||
}
|
||||
if (typeof dateTime === 'string') {
|
||||
// When SQLite returns a string, it will be in UTC.
|
||||
// Need to make sure it actually have timezone info in it
|
||||
// (will not by default).
|
||||
return moment.utc(dateTime).toISOString();
|
||||
}
|
||||
throw new Error(`normalizedDateTimeString cannot handle ${dateTime}`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user