Skip to content

Commit

Permalink
(core) updates from grist-core
Browse files Browse the repository at this point in the history
  • Loading branch information
paulfitz committed Jun 3, 2024
2 parents c469a68 + 9c90da7 commit 5007754
Show file tree
Hide file tree
Showing 11 changed files with 350 additions and 68 deletions.
4 changes: 2 additions & 2 deletions app/client/ui/AdminPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,8 @@ Please log in as an administrator.`)),

private _buildAuthenticationNotice(owner: IDisposableOwner) {
return t('Grist allows different types of authentication to be configured, including SAML and OIDC. \
We recommend enabling one of these if Grist is accessible over the network or being made available \
to multiple people.');
We recommend enabling one of these if Grist is accessible over the network or being made available \
to multiple people.');
}

private _buildUpdates(owner: MultiHolder) {
Expand Down
6 changes: 3 additions & 3 deletions app/client/ui/AppHeader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export class AppHeader extends Disposable {
// Show 'Organization Settings' when on a home page of a valid org.
(!this._docPageModel && this._currentOrg && !this._currentOrg.owner ?
menuItem(() => manageTeamUsersApp({app: this._appModel}),
'Manage Team', testId('orgmenu-manage-team'),
t('Manage Team'), testId('orgmenu-manage-team'),
dom.cls('disabled', !roles.canEditAccess(this._currentOrg.access))) :
// Don't show on doc pages, or for personal orgs.
null),
Expand Down Expand Up @@ -153,12 +153,12 @@ export class AppHeader extends Disposable {
(isBillingManager
? menuItemLink(
urlState().setLinkUrl({billing: 'billing'}),
'Billing Account',
t('Billing Account'),
testId('orgmenu-billing'),
)
: menuItem(
() => null,
'Billing Account',
t('Billing Account'),
dom.cls('disabled', true),
testId('orgmenu-billing'),
)
Expand Down
55 changes: 38 additions & 17 deletions app/server/lib/MinIOExternalStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,39 @@ import {IncomingMessage} from 'http';
import * as fse from 'fs-extra';
import * as minio from 'minio';

// The minio typings appear to be quite stale. Extend them here to avoid
// lots of casts to any.
type MinIOClient = minio.Client & {
statObject(bucket: string, key: string, options: {versionId?: string}): Promise<MinIOBucketItemStat>;
getObject(bucket: string, key: string, options: {versionId?: string}): Promise<IncomingMessage>;
listObjects(bucket: string, key: string, recursive: boolean,
options: {IncludeVersion?: boolean}): minio.BucketStream<minio.BucketItem>;
removeObjects(bucket: string, versions: Array<{name: string, versionId: string}>): Promise<void>;
};

type MinIOBucketItemStat = minio.BucketItemStat & {
versionId?: string;
metaData?: Record<string, string>;
};
// The minio-js v8.0.0 typings are sometimes incorrect. Here are some workarounds.
interface MinIOClient extends
// Some of them are not directly extendable, must be omitted first and then redefined.
Omit<minio.Client, "listObjects" | "getBucketVersioning" | "removeObjects">
{
// The official typing returns `Promise<Readable>`, dropping some useful metadata.
getObject(bucket: string, key: string, options: {versionId?: string}): Promise<IncomingMessage>;
// The official typing dropped "options" in their .d.ts file, but it is present in the underlying impl.
listObjects(bucket: string, key: string, recursive: boolean,
options: {IncludeVersion?: boolean}): minio.BucketStream<minio.BucketItem>;
// The released v8.0.0 wrongly returns `Promise<void>`; borrowed from PR #1297
getBucketVersioning(bucketName: string): Promise<MinIOVersioningStatus>;
// The released v8.0.0 typing is outdated; copied over from commit 8633968.
removeObjects(bucketName: string, objectsList: RemoveObjectsParam): Promise<RemoveObjectsResponse[]>
}

type MinIOVersioningStatus = "" | {
Status: "Enabled" | "Suspended",
MFADelete?: string,
ExcludeFolders?: boolean,
ExcludedPrefixes?: {Prefix: string}[]
}

type RemoveObjectsParam = string[] | { name: string, versionId?: string }[]

type RemoveObjectsResponse = null | undefined | {
Error?: {
Code?: string
Message?: string
Key?: string
VersionId?: string
}
}

/**
* An external store implemented using the MinIO client, which
Expand All @@ -38,7 +57,7 @@ export class MinIOExternalStorage implements ExternalStorage {
region: string
},
private _batchSize?: number,
private _s3 = new minio.Client(options) as MinIOClient
private _s3 = new minio.Client(options) as unknown as MinIOClient
) {
}

Expand Down Expand Up @@ -70,7 +89,7 @@ export class MinIOExternalStorage implements ExternalStorage {
public async upload(key: string, fname: string, metadata?: ObjMetadata) {
const stream = fse.createReadStream(fname);
const result = await this._s3.putObject(
this.bucket, key, stream,
this.bucket, key, stream, undefined,
metadata ? {Metadata: toExternalMetadata(metadata)} : undefined
);
// Empirically VersionId is available in result for buckets with versioning enabled.
Expand Down Expand Up @@ -111,7 +130,9 @@ export class MinIOExternalStorage implements ExternalStorage {

public async hasVersioning(): Promise<Boolean> {
const versioning = await this._s3.getBucketVersioning(this.bucket);
return versioning && versioning.Status === 'Enabled';
// getBucketVersioning() may return an empty string when versioning has never been enabled.
// This situation is not addressed in minio-js v8.0.0, but included in our workaround.
return versioning !== '' && versioning?.Status === 'Enabled';
}

public async versions(key: string, options?: { includeDeleteMarkers?: boolean }) {
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@
"@types/lru-cache": "5.1.1",
"@types/marked": "4.0.8",
"@types/mime-types": "2.1.0",
"@types/minio": "7.0.15",
"@types/mocha": "10.0.1",
"@types/moment-timezone": "0.5.9",
"@types/mousetrap": "1.6.2",
Expand Down Expand Up @@ -167,7 +166,7 @@
"locale-currency": "0.0.2",
"lodash": "4.17.21",
"marked": "4.2.12",
"minio": "7.1.3",
"minio": "8.0.0",
"moment": "2.29.4",
"moment-timezone": "0.5.35",
"morgan": "1.9.1",
Expand Down
49 changes: 44 additions & 5 deletions static/locales/en.client.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@
"Legacy": "Legacy",
"Personal Site": "Personal Site",
"Team Site": "Team Site",
"Grist Templates": "Grist Templates"
"Grist Templates": "Grist Templates",
"Billing Account": "Billing Account",
"Manage Team": "Manage Team"
},
"AppModel": {
"This team site is suspended. Documents can be read, but not modified.": "This team site is suspended. Documents can be read, but not modified."
Expand Down Expand Up @@ -327,7 +329,17 @@
"Time Zone": "Time Zone",
"Try API calls from the browser": "Try API calls from the browser",
"python2 (legacy)": "python2 (legacy)",
"python3 (recommended)": "python3 (recommended)"
"python3 (recommended)": "python3 (recommended)",
"Cancel": "Cancel",
"Force reload the document while timing formulas, and show the result.": "Force reload the document while timing formulas, and show the result.",
"Formula timer": "Formula timer",
"Reload data engine": "Reload data engine",
"Reload data engine?": "Reload data engine?",
"Start timing": "Start timing",
"Stop timing...": "Stop timing...",
"Time reload": "Time reload",
"Timing is on": "Timing is on",
"You can make changes to the document, then stop timing to see the results.": "You can make changes to the document, then stop timing to see the results."
},
"DocumentUsage": {
"Attachments Size": "Size of Attachments",
Expand Down Expand Up @@ -525,7 +537,8 @@
"Trash": "Trash",
"Workspace will be moved to Trash.": "Workspace will be moved to Trash.",
"Workspaces": "Workspaces",
"Tutorial": "Tutorial"
"Tutorial": "Tutorial",
"Terms of service": "Terms of service"
},
"Importer": {
"Merge rows that match these fields:": "Merge rows that match these fields:",
Expand Down Expand Up @@ -1017,7 +1030,9 @@
"Add conditional style": "Add conditional style",
"Error in style rule": "Error in style rule",
"Row Style": "Row Style",
"Rule must return True or False": "Rule must return True or False"
"Rule must return True or False": "Rule must return True or False",
"Conditional Style": "Conditional Style",
"IF...": "IF..."
},
"CurrencyPicker": {
"Invalid currency": "Invalid currency"
Expand Down Expand Up @@ -1536,7 +1551,21 @@
"Security Settings": "Security Settings",
"Updates": "Updates",
"unconfigured": "unconfigured",
"unknown": "unknown"
"unknown": "unknown",
"Administrator Panel Unavailable": "Administrator Panel Unavailable",
"Authentication": "Authentication",
"Check failed.": "Check failed.",
"Check succeeded.": "Check succeeded.",
"Current authentication method": "Current authentication method",
"Details": "Details",
"Grist allows different types of authentication to be configured, including SAML and OIDC. We recommend enabling one of these if Grist is accessible over the network or being made available to multiple people.": "Grist allows different types of authentication to be configured, including SAML and OIDC. We recommend enabling one of these if Grist is accessible over the network or being made available to multiple people.",
"No fault detected.": "No fault detected.",
"Notes": "Notes",
"Or, as a fallback, you can set: {{bootKey}} in the environment and visit: {{url}}": "Or, as a fallback, you can set: {{bootKey}} in the environment and visit: {{url}}",
"Results": "Results",
"Self Checks": "Self Checks",
"You do not have access to the administrator panel.\nPlease log in as an administrator.": "You do not have access to the administrator panel.\nPlease log in as an administrator.",
"Grist allows different types of authentication to be configured, including SAML and OIDC. We recommend enabling one of these if Grist is accessible over the network or being made available to multiple people.": "Grist allows different types of authentication to be configured, including SAML and OIDC. We recommend enabling one of these if Grist is accessible over the network or being made available to multiple people."
},
"Columns": {
"Remove Column": "Remove Column"
Expand Down Expand Up @@ -1587,5 +1616,15 @@
"Custom": "Custom",
"Form": "Form",
"Table": "Table"
},
"TimingPage": {
"Average Time (s)": "Average Time (s)",
"Column ID": "Column ID",
"Formula timer": "Formula timer",
"Loading timing data. Don't close this tab.": "Loading timing data. Don't close this tab.",
"Max Time (s)": "Max Time (s)",
"Number of Calls": "Number of Calls",
"Table ID": "Table ID",
"Total Time (s)": "Total Time (s)"
}
}
8 changes: 6 additions & 2 deletions static/locales/es.client.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@
"Legacy": "Legado",
"Personal Site": "Sitio Personal",
"Team Site": "Sitio de Equipo",
"Grist Templates": "Plantillas Grist"
"Grist Templates": "Plantillas Grist",
"Manage Team": "Administrar equipo",
"Billing Account": "Cuenta de facturación"
},
"CellContextMenu": {
"Clear cell": "Borrar celda",
Expand Down Expand Up @@ -277,7 +279,9 @@
"python2 (legacy)": "python2 (legado)",
"Notify other services on doc changes": "Notificar a otros servicios los cambios de documentos",
"Python": "Python",
"python3 (recommended)": "python3 (recomendado)"
"python3 (recommended)": "python3 (recomendado)",
"Cancel": "Cancelar",
"Force reload the document while timing formulas, and show the result.": "Fuerza la recarga del documento mientras sincronizas las fórmulas y muestra el resultado."
},
"DuplicateTable": {
"Copy all data in addition to the table structure.": "Copiar todos los datos además de la estructura de la tabla.",
Expand Down
56 changes: 52 additions & 4 deletions static/locales/fr.client.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@
"Legacy": "Ancienne version",
"Personal Site": "Espace personnel",
"Team Site": "Espace d'équipe",
"Grist Templates": "Modèles Grist"
"Grist Templates": "Modèles Grist",
"Billing Account": "Compte de facturation",
"Manage Team": "Gestion de l'équipe"
},
"AppModel": {
"This team site is suspended. Documents can be read, but not modified.": "Le site de cette équipe est suspendu. Les documents peuvent être lus, mais pas modifiés."
Expand Down Expand Up @@ -311,7 +313,29 @@
"For currency columns": "Pour les colonnes de devises",
"Hard reset of data engine": "Réinitialisation du moteur de données",
"Locale": "Langue",
"For number and date formats": "Pour les colonnes de nombre et date"
"For number and date formats": "Pour les colonnes de nombre et date",
"Base doc URL: {{docApiUrl}}": "URL de base pour ce document : {{docApiUrl}}",
"Document ID to use whenever the REST API calls for {{docId}}. See {{apiURL}}": "ID du document à utiliser lorsque l'API REST fait appel à {{docId}}. Voir {{apiURL}}",
"Python version used": "Version de Python utilisée",
"Notify other services on doc changes": "Informer d'autres services des changements du documents",
"Manage webhooks": "Gérer les points d'ancrage Web",
"ID for API use": "ID pour l'utilisation de l'API",
"Find slow formulas": "Trouver les formules lentes",
"python2 (legacy)": "python2 (encien)",
"Try API calls from the browser": "Essayer les appels API à partir du navigateur",
"Time Zone": "Fuseau horaire",
"python3 (recommended)": "python3 (recommandé)",
"Start timing": "Début du chrono",
"Time reload": "Durée du rechargement",
"Stop timing...": "Arrêter le chrono...",
"Cancel": "Annuler",
"Reload data engine": "Recharger le moteur de données",
"Reload data engine?": "Recharger le moteur de données ?",
"Force reload the document while timing formulas, and show the result.": "Forcer le rechargement du document pendant le chronométrage des formules et afficher le résultat.",
"Formula timer": "Chronomètre de formule",
"Timing is on": "Le chronomètre tourne",
"You can make changes to the document, then stop timing to see the results.": "Vous pouvez apporter des modifications au document, puis arrêter le chronométrage pour voir les résultats.",
"Formula times": "Minuteur de formule"
},
"DocumentUsage": {
"Usage statistics are only available to users with full access to the document data.": "Les statistiques d'utilisation ne sont disponibles qu'aux utilisateurs ayant un accès complet aux données du document.",
Expand Down Expand Up @@ -1053,7 +1077,9 @@
"Add another rule": "Ajouter une autre règle",
"Error in style rule": "Erreur dans la règle de style",
"Row Style": "Style de ligne",
"Rule must return True or False": "La règle doit retourner Vrai ou Faux"
"Rule must return True or False": "La règle doit retourner Vrai ou Faux",
"Conditional Style": "Style conditionnel",
"IF...": "SI..."
},
"CurrencyPicker": {
"Invalid currency": "Devise invalide"
Expand Down Expand Up @@ -1509,7 +1535,19 @@
"Updates": "Mises à jour",
"unconfigured": "non configuré",
"unknown": "inconnu",
"Auto-check when this page loads": "Vérification automatique au chargement de cette page"
"Auto-check when this page loads": "Vérification automatique au chargement de cette page",
"Sandbox settings for data engine": "Paramètres de la Sandbox pour le moteur de données",
"Check failed.": "La vérification a échoué.",
"Check succeeded.": "Vérification réussie.",
"No fault detected.": "Aucun défaut n'a été détecté.",
"Notes": "Notes",
"Authentication": "Authentification",
"Administrator Panel Unavailable": "Panneau d'administration indisponible",
"Current authentication method": "Méthode actuelle d'authentification",
"Details": "Détails",
"Grist allows different types of authentication to be configured, including SAML and OIDC. We recommend enabling one of these if Grist is accessible over the network or being made available to multiple people.": "Grist permet de configurer différents types d'authentification, notamment SAML et OIDC. Nous recommandons d'activer l'un de ces types d'authentification si Grist est accessible via le réseau ou s'il est mis à la disposition de plusieurs personnes.",
"You do not have access to the administrator panel.\nPlease log in as an administrator.": "Vous n'avez pas accès au panneau d'administrateur.\nVeuillez vous connecter en tant qu'administrateur.",
"Results": "Résultats"
},
"Field": {
"No choices configured": "Aucun choix configuré",
Expand Down Expand Up @@ -1574,5 +1612,15 @@
"Card List": "Liste de fiches",
"Card": "Fiche",
"Calendar": "Calendrier"
},
"TimingPage": {
"Max Time (s)": "Temps maximum (s)",
"Average Time (s)": "Temps moyen (s)",
"Column ID": "ID de la colonne",
"Loading timing data. Don't close this tab.": "Chargement des données de chronométrage. Ne pas fermer cet onglet.",
"Formula timer": "Chronomètre de formule",
"Number of Calls": "Nombre d'appels",
"Table ID": "ID de la table",
"Total Time (s)": "Temps total"
}
}
15 changes: 13 additions & 2 deletions static/locales/ro.client.json
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,9 @@
"SELECTOR FOR": "SELECTOR PENTRU",
"Sort & Filter": "Sortare și filtrare",
"Widget": "Widget",
"Reset form": "Resetare formular"
"Reset form": "Resetare formular",
"Enter text": "Introdu text",
"Configuration": "Configurare"
},
"FloatingPopup": {
"Maximize": "Maximizați",
Expand Down Expand Up @@ -884,7 +886,8 @@
"Help Center": "Centru de ajutor",
"Opted In": "A optat pentru a participa",
"Contribute": "Contribuie",
"Support Grist page": "Pagina Susține Grist"
"Support Grist page": "Pagina Susține Grist",
"Admin Panel": "Panou administrator"
},
"ValidationPanel": {
"Update formula (Shift+Enter)": "Actualizați formula (Shift+Enter)",
Expand Down Expand Up @@ -1292,5 +1295,13 @@
},
"HiddenQuestionConfig": {
"Hidden fields": "Câmpuri ascunse"
},
"AdminPanel": {
"Support Grist Labs on GitHub": "Sponsor Grist Labs pe GitHub",
"Telemetry": "Telemetry",
"Admin Panel": "Panou administrator",
"Home": "Acasă",
"Sponsor": "Sponsor",
"Support Grist": "Sponsor Grist"
}
}
Loading

0 comments on commit 5007754

Please sign in to comment.