mirror of
https://github.com/strapi/strapi.git
synced 2025-09-22 14:59:07 +00:00
Merge branch 'master' into Validate-boolean-is-not-null-when-required
This commit is contained in:
commit
47e9da89e5
@ -1,6 +1,6 @@
|
||||
{
|
||||
"Analytics": "Analytics",
|
||||
"Auth.advanced.allow_register": "Registrazione compiuta",
|
||||
"Auth.advanced.allow_register": "Permetti registrazione",
|
||||
"Auth.components.Oops.text": "Il tuo account è stato sospeso",
|
||||
"Auth.form.button.forgot-password": "Invia email",
|
||||
"Auth.form.button.go-home": "TORNA ALLA HOME",
|
||||
@ -12,13 +12,13 @@
|
||||
"Auth.form.email.placeholder": "kai@doe.com",
|
||||
"Auth.form.error.blocked": "Il tuo account è stato bloccato dall'amministratore.",
|
||||
"Auth.form.error.code.provide": "Codice fornito non corretto.",
|
||||
"Auth.form.error.confirmed": "La mail del tuo account non è stata confermata.",
|
||||
"Auth.form.error.confirmed": "L'email del tuo account non è stata confermata.",
|
||||
"Auth.form.error.email.invalid": "Questa email non è valida.",
|
||||
"Auth.form.error.email.provide": "Per favore fornisci il tuo Nome utente o la tua mail",
|
||||
"Auth.form.error.email.taken": "Email già utilizzata",
|
||||
"Auth.form.error.email.provide": "Per favore inserisci il tuo nome utente o la tua email.",
|
||||
"Auth.form.error.email.taken": "Email già utilizzata.",
|
||||
"Auth.form.error.invalid": "Identificatore o password non valida.",
|
||||
"Auth.form.error.params.provide": "I parametri forniti non sono corretti.",
|
||||
"Auth.form.error.password.format": "La tua password non può contenere il simbolo $ per più di tre volte.",
|
||||
"Auth.form.error.password.format": "La tua password non può contenere il simbolo `$` per più di tre volte.",
|
||||
"Auth.form.error.password.local": "Questo utente non ha mai impostato una password locale, accedi gentilmente tramite il provider usato durante la creazione dell'account",
|
||||
"Auth.form.error.password.matching": "La password non corrisponde.",
|
||||
"Auth.form.error.password.provide": "Per favore fornisci la tua password",
|
||||
@ -32,7 +32,7 @@
|
||||
"Auth.form.lastname.label": "Cognome",
|
||||
"Auth.form.lastname.placeholder": "Doe",
|
||||
"Auth.form.password.label": "Password",
|
||||
"Auth.form.register.news.label": "Tienimi aggiornata in merito a nuove funzionalità e futuri sviluppi (così facendo accetti {terms} e {policy}).",
|
||||
"Auth.form.register.news.label": "Tienimi aggiornato in merito a nuove funzionalità e futuri sviluppi (così facendo accetti {terms} e {policy}).",
|
||||
"Auth.form.rememberMe.label": "Ricordami",
|
||||
"Auth.form.username.label": "Nome utente",
|
||||
"Auth.form.username.placeholder": "Kai Doe",
|
||||
@ -53,7 +53,7 @@
|
||||
"HomePage.roadmap": "Guarda la nostra roadmap",
|
||||
"HomePage.welcome.congrats": "Congratulazioni!",
|
||||
"HomePage.welcome.congrats.content": "Ti sei loggato come primo amministratore. Per scoprire le funzionalità di Strapi,",
|
||||
"HomePage.welcome.congrats.content.bold": "Adesso puoi creare la tua prima lista",
|
||||
"HomePage.welcome.congrats.content.bold": "ti consigliamo di creare la tua prima Collezione.",
|
||||
"Media Library": "Libreria media",
|
||||
"New entry": "Nuovo elemento",
|
||||
"Password": "Password",
|
||||
@ -66,11 +66,19 @@
|
||||
"Roles.RoleRow.user-count.plural": "{number} utenti",
|
||||
"Roles.RoleRow.user-count.singular": "{number} utente",
|
||||
"Roles.components.List.empty.withSearch": "Nessun ruolo corrisponde alla ricerca ({search})...",
|
||||
"Settings.application.title": "Applicazione",
|
||||
"Settings.application.description": "Vedi i dettagli del tuo progetto",
|
||||
"Settings.application.link-pricing": "Vedi tutti i prezzi",
|
||||
"Settings.application.link-upgrade": "Aggiorna il tuo progetto",
|
||||
"Settings.application.strapi-version": "VERSIONE STRAPI",
|
||||
"Settings.application.node-version": "VERSIONE NODE",
|
||||
"Settings.application.edition-title": "PIANO ATTUALE",
|
||||
"Settings.PageTitle": "Impostazioni - {name}",
|
||||
"Settings.error": "Errore",
|
||||
"Settings.global": "Impostazioni Globali",
|
||||
"Settings.permissions": "Pannello di amministazione",
|
||||
"Settings.permissions.category": "Impostazioni permessi per la categoria {category}",
|
||||
"Settings.permissions.category.plugins": "Permissions settings for the {category} plugin",
|
||||
"Settings.permissions.conditions.anytime": "In ogni momento",
|
||||
"Settings.permissions.conditions.apply": "Applica",
|
||||
"Settings.permissions.conditions.can": "Può",
|
||||
@ -108,7 +116,7 @@
|
||||
"Settings.roles.form.permissions.update": "Aggiorna",
|
||||
"Settings.roles.form.title": "Dettagli",
|
||||
"Settings.roles.list.button.add": "Aggiungi nuovo ruolo",
|
||||
"Settings.roles.list.description": "Listi dei ruoli",
|
||||
"Settings.roles.list.description": "Lista dei ruoli",
|
||||
"Settings.roles.list.title.plural": "{number} ruoli",
|
||||
"Settings.roles.list.title.singular": "{number} ruolo",
|
||||
"Settings.roles.title": "Ruoli",
|
||||
@ -262,13 +270,13 @@
|
||||
"components.AutoReloadBlocker.description": "Avvia Strapi con uno dei seguenti comandi:",
|
||||
"components.AutoReloadBlocker.header": "Ricarica funzionalità è richiesto per questo plugin.",
|
||||
"components.ErrorBoundary.title": "Qualcosa è andato storto...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "si",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "è",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "contiene",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "contiene (maiuscole e minuscole)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "è maggiore di",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "è maggiore o uguale a",
|
||||
"components.FilterOptions.FILTER_TYPES._in": "contiene uno dei valori nell'array",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "è inferiore",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "è inferiore di",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "è inferiore o uguale a",
|
||||
"components.FilterOptions.FILTER_TYPES._ncontains": "non contiene",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "non è",
|
||||
@ -295,8 +303,8 @@
|
||||
"components.InputSelect.option.placeholder": "Seleziona",
|
||||
"components.ListRow.empty": "Non ci sono dati da mostrare.",
|
||||
"components.OverlayBlocker.description": "Stai utilizzando una funzionalità che necessita del riavvio del server. Per favore, attendi che il server ritorni attivo.",
|
||||
"components.OverlayBlocker.description.serverError": "Il server deve essere riavvito, per favore controlla i tuoi log nel terminale.",
|
||||
"components.OverlayBlocker.title": "Attendendo il riavvio...",
|
||||
"components.OverlayBlocker.description.serverError": "Il server deve essere riavviato, per favore controlla i tuoi log nel terminale.",
|
||||
"components.OverlayBlocker.title": "Attendo il riavvio...",
|
||||
"components.OverlayBlocker.title.serverError": "Il riavvio sta impiegando più del previsto",
|
||||
"components.PageFooter.select": "elementi per pagina",
|
||||
"components.ProductionBlocker.description": "Per ragioni di sicurezza dobbiamo disabilitare questo plugin in altri ambienti.",
|
||||
@ -312,26 +320,28 @@
|
||||
"components.Wysiwyg.selectOptions.H5": "Titolo H5",
|
||||
"components.Wysiwyg.selectOptions.H6": "Titolo H6",
|
||||
"components.Wysiwyg.selectOptions.title": "Aggiungi un titolo",
|
||||
"components.WysiwygBottomControls.charactersIndicators": "lettere",
|
||||
"components.WysiwygBottomControls.charactersIndicators": "caratteri",
|
||||
"components.WysiwygBottomControls.fullscreen": "Espandi",
|
||||
"components.WysiwygBottomControls.uploadFiles": "Trascina file, incolla dagli appunti o {browse}.",
|
||||
"components.WysiwygBottomControls.uploadFiles": "Trascina & rilascia file, incolla dagli appunti o {browse}.",
|
||||
"components.WysiwygBottomControls.uploadFiles.browse": "selezionali",
|
||||
"components.popUpWarning.button.cancel": "No, annulla",
|
||||
"components.popUpWarning.button.confirm": "Sì, conferma",
|
||||
"components.popUpWarning.message": "Sei sicuro di volerlo cancellare?",
|
||||
"components.popUpWarning.title": "Richiesta conferma",
|
||||
"components.popUpWarning.title": "Conferma richiesta",
|
||||
"form.button.continue": "Continua",
|
||||
"form.button.done": "Fatto",
|
||||
"form.button.finish": "Completa",
|
||||
"global.prompt.unsaved": "Sei sicuro di voler lasciare questa pagina? Tutte le modifiche effettuate verranno perse.",
|
||||
"notification.contentType.relations.conflict": "Content type ha relazioni in conflitto",
|
||||
"notification.contentType.relations.conflict": "Questo Tipo di Contenuto ha delle relazioni in conflitto",
|
||||
"notification.error": "Si è verificato un errore",
|
||||
"notification.error.layout": "Non è stato possibile recuperare il layout",
|
||||
"notification.form.error.fields": "Ci sono errori nel form",
|
||||
"notification.form.error.fields": "Il form contiene degli errori",
|
||||
"notification.form.success.fields": "Modifiche salvate",
|
||||
"notification.link-copied": "Link copiato",
|
||||
"notification.permission.not-allowed-read": "Non sei abilitato a visualizzare il documento",
|
||||
"notification.success.delete": "Elemento cancellato",
|
||||
"notification.link-copied": "Link copiato negli appunti",
|
||||
"notification.permission.not-allowed-read": "Non sei abilitato a visualizzare questo documento",
|
||||
"notification.success.delete": "L'elemento è stato eliminato",
|
||||
"notification.success.saved": "Salvato",
|
||||
"notification.version.update.message": "Una nuova versione di Strapi è disponibile!",
|
||||
"notification.version.update.link": "Scopri di più",
|
||||
"request.error.model.unknown": "Modello inesistente"
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const { each, prop, reject, isEmpty } = require('lodash/fp');
|
||||
const { each, prop, isEmpty } = require('lodash/fp');
|
||||
const { singular } = require('pluralize');
|
||||
const { toQueries, runPopulateQueries } = require('./utils/populate-queries');
|
||||
|
||||
@ -14,15 +14,21 @@ const BOOLEAN_OPERATORS = ['or'];
|
||||
* @param {Object} options.filters - Filters params (start, limit, sort, where)
|
||||
*/
|
||||
const buildQuery = ({ model, filters }) => qb => {
|
||||
const joinsTree = buildJoinsAndFilter(qb, model, filters);
|
||||
|
||||
if (_.has(filters, 'where') && Array.isArray(filters.where) && filters.where.length > 0) {
|
||||
qb.distinct();
|
||||
}
|
||||
|
||||
const joinsTree = buildJoinsAndFilter(qb, model, filters);
|
||||
|
||||
if (_.has(filters, 'sort')) {
|
||||
const clauses = filters.sort.map(buildSortClauseFromTree(joinsTree));
|
||||
qb.orderBy(reject(isEmpty, clauses));
|
||||
const clauses = filters.sort.map(buildSortClauseFromTree(joinsTree)).filter(c => !isEmpty(c));
|
||||
const orderBy = clauses.map(({ order, alias }) => ({ order, column: alias }));
|
||||
const orderColumns = clauses.map(({ alias, column }) => ({ [alias]: column }));
|
||||
const columns = [`${joinsTree.alias}.*`, ...orderColumns];
|
||||
|
||||
qb.distinct()
|
||||
.column(columns)
|
||||
.orderBy(orderBy);
|
||||
}
|
||||
|
||||
if (_.has(filters, 'start')) {
|
||||
@ -47,13 +53,21 @@ const buildQuery = ({ model, filters }) => qb => {
|
||||
*/
|
||||
const buildSortClauseFromTree = tree => ({ field, order }) => {
|
||||
if (!field.includes('.')) {
|
||||
return { column: field, order };
|
||||
return {
|
||||
column: `${tree.alias}.${field}`,
|
||||
order,
|
||||
alias: `_strapi_tmp_${tree.alias}_${field}`,
|
||||
};
|
||||
}
|
||||
|
||||
const [relation, attribute] = field.split('.');
|
||||
for (const { alias, assoc } of Object.values(tree.joins)) {
|
||||
if (relation === assoc.alias) {
|
||||
return { column: `${alias}.${attribute}`, order };
|
||||
return {
|
||||
column: `${alias}.${attribute}`,
|
||||
order,
|
||||
alias: `_strapi_tmp_${alias}_${attribute}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -610,6 +610,10 @@ module.exports = async ({ models, target }, ctx, { selfFinalize = false } = {})
|
||||
const formatValue = createFormatter(definition.client);
|
||||
function formatEntry(entry) {
|
||||
Object.keys(entry.attributes).forEach(key => {
|
||||
if (key.startsWith('_strapi_tmp_')) {
|
||||
delete entry.attributes[key];
|
||||
return;
|
||||
}
|
||||
const attr = definition.attributes[key] || {};
|
||||
entry.attributes[key] = formatValue(attr, entry.attributes[key]);
|
||||
});
|
||||
|
@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
const _ = require('lodash');
|
||||
const { prop } = require('lodash/fp');
|
||||
const { prop, omit } = require('lodash/fp');
|
||||
const { convertRestQueryParams, buildQuery } = require('strapi-utils');
|
||||
const { contentTypes: contentTypesUtils } = require('strapi-utils');
|
||||
const mongoose = require('mongoose');
|
||||
@ -417,12 +417,10 @@ module.exports = ({ model, strapi }) => {
|
||||
}
|
||||
|
||||
function count(params) {
|
||||
const filters = convertRestQueryParams(params);
|
||||
const countParams = omit(['_sort', '_limit', '_start'], params);
|
||||
const filters = convertRestQueryParams(countParams);
|
||||
|
||||
return buildQuery({
|
||||
model,
|
||||
filters: { where: filters.where },
|
||||
}).count();
|
||||
return buildQuery({ model, filters }).count();
|
||||
}
|
||||
|
||||
async function create(values) {
|
||||
@ -515,11 +513,12 @@ module.exports = ({ model, strapi }) => {
|
||||
}
|
||||
|
||||
function countSearch(params) {
|
||||
const { where } = convertRestQueryParams(_.omit(params, '_q'));
|
||||
const countParams = omit(['_sort', '_limit', '_start', '_q'], params);
|
||||
const filters = convertRestQueryParams(countParams);
|
||||
|
||||
return buildQuery({
|
||||
model,
|
||||
filters: { where },
|
||||
filters,
|
||||
searchParam: params._q,
|
||||
}).count();
|
||||
}
|
||||
|
@ -30,9 +30,9 @@
|
||||
"components.TableDelete.deleteSelected": "Delete selected",
|
||||
"components.TableDelete.entries.plural": "{number} entries selected",
|
||||
"components.TableDelete.entries.singular": "{number} entry selected",
|
||||
"components.TableEmpty.withFilters": "There is no {contentType} with the applied filters...",
|
||||
"components.TableEmpty.withSearch": "There is no {contentType} corresponding to the search ({search})...",
|
||||
"components.TableEmpty.withoutFilter": "There is no {contentType}...",
|
||||
"components.TableEmpty.withFilters": "There are no {contentType} with the applied filters...",
|
||||
"components.TableEmpty.withSearch": "There are no {contentType} corresponding to the search ({search})...",
|
||||
"components.TableEmpty.withoutFilter": "There are no {contentType}...",
|
||||
"components.empty-repeatable": "No entry yet. Click on the button below to add one.",
|
||||
"components.repeatable.reorder.error": "An error occurred while reordering your component's field, please try again",
|
||||
"components.notification.info.maximum-requirement": "You have already reached the maximum number of fields",
|
||||
|
@ -1,61 +1,124 @@
|
||||
{
|
||||
"EditRelations.title": "Dati relazionali",
|
||||
"api.id": "API ID",
|
||||
"components.AddFilterCTA.add": "Filtri",
|
||||
"components.AddFilterCTA.hide": "Filtri",
|
||||
"components.DraggableAttr.edit": "Clicca per modificare",
|
||||
"components.DynamicZone.add-compo": "Aggiungi a {componentName}",
|
||||
"components.DynamicZone.missing.plural": "Ci sono {count} componenti mancanti",
|
||||
"components.DynamicZone.missing.singular": "C'è {count} componente mancante",
|
||||
"components.DynamicZone.pick-compo": "Scegli un componente",
|
||||
"components.DynamicZone.required": "Componente richiesto",
|
||||
"components.EmptyAttributesBlock.button": "Vai alla pagina delle impostazioni",
|
||||
"components.EmptyAttributesBlock.description": "Puoi cambiare le tue impostazioni",
|
||||
"components.FieldItem.linkToComponentLayout": "Modifica impaginazione componente",
|
||||
"components.FilterOptions.button.apply": "Applica",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "Applica",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "Cancella tutto",
|
||||
"components.FiltersPickWrapper.PluginHeader.description": "Impostare le condizioni da applicare per filtrare le voci",
|
||||
"components.FiltersPickWrapper.PluginHeader.description": "Imposta le condizioni da applicare per filtrare gli elementi",
|
||||
"components.FiltersPickWrapper.PluginHeader.title.filter": "Filtri",
|
||||
"components.FiltersPickWrapper.hide": "Nascondi",
|
||||
"components.LimitSelect.itemsPerPage": "Elementi per pagina",
|
||||
"components.Search.placeholder": "Ricerca di una voce...",
|
||||
"components.TableDelete.delete": "Eliminare tutti",
|
||||
"components.NotAllowedInput.text": "Non hai il permesso di vedere questo campo",
|
||||
"components.Search.placeholder": "Ricerca elementi...",
|
||||
"components.Select.draft-info-title": "Stato: Bozza",
|
||||
"components.Select.publish-info-title": "Stato: Pubblicato",
|
||||
"components.SettingsViewWrapper.pluginHeader.description.edit-settings": "Personalizza l'aspetto della schermata di modifica.",
|
||||
"components.SettingsViewWrapper.pluginHeader.description.list-settings": "Definisci le impostazioni delle liste di elementi.",
|
||||
"components.SettingsViewWrapper.pluginHeader.title": "Configura la vista - {name}",
|
||||
"components.TableDelete.delete": "Elimina tutti",
|
||||
"components.TableDelete.deleteSelected": "Elimina selezionato",
|
||||
"components.TableDelete.entries.plural": "{number} voci selezionate",
|
||||
"components.TableDelete.entries.singular": "{number} voce selezionata",
|
||||
"components.TableEmpty.withFilters": "Non vi è alcun {contentType} con l'applicazione di filtri...",
|
||||
"components.TableEmpty.withSearch": "Non vi è alcun {contentType} corrispondente alla ricerca ({search})...",
|
||||
"components.TableEmpty.withoutFilter": "Non vi è alcun {contentType}...",
|
||||
"components.TableDelete.entries.plural": "{number} elementi selezionati",
|
||||
"components.TableDelete.entries.singular": "{number} elemento selezionato",
|
||||
"components.TableEmpty.withFilters": "Nessun {contentType} con questi filtri...",
|
||||
"components.TableEmpty.withSearch": "Nessun {contentType} corrispondente alla ricerca ({search})...",
|
||||
"components.TableEmpty.withoutFilter": "Non ci sono {contentType}...",
|
||||
"components.empty-repeatable": "Ancora nessun elemento. Clicca il pulsante sottostante per aggiungerne uno.",
|
||||
"components.repeatable.reorder.error": "Si è verificato un errore durante il riordinamento del campo del componente",
|
||||
"components.notification.info.maximum-requirement": "Hai già raggiunto il massimo numero di campi",
|
||||
"components.notification.info.minimum-requirement": "È stato aggiunto un campo per soddisfare il requisito minimo",
|
||||
"components.reset-entry": "Azzera elemento",
|
||||
"components.uid.apply": "applica",
|
||||
"components.uid.available": "disponibile",
|
||||
"components.uid.regenerate": "rigenera",
|
||||
"components.uid.suggested": "suggerito",
|
||||
"components.uid.unavailable": "non disponibile",
|
||||
"containers.Edit.Link.Fields": "Modifica i campi",
|
||||
"containers.Edit.Link.Layout": "Configura impaginazione",
|
||||
"containers.Edit.Link.Model": "Modifica la Collezione",
|
||||
"containers.Edit.addAnItem": "Aggiungi un elemento...",
|
||||
"containers.Edit.clickToJump": "Clicca per andare alla riga",
|
||||
"containers.Edit.clickToJump": "Clicca per andare all'elemento",
|
||||
"containers.Edit.delete": "Elimina",
|
||||
"containers.Edit.editing": "Modificando...",
|
||||
"containers.Edit.reset": "Resetta",
|
||||
"containers.Edit.returnList": "Tornare alla lista",
|
||||
"containers.Edit.delete-entry": "Elimina questo elemento",
|
||||
"containers.Edit.editing": "Modifica in corso...",
|
||||
"containers.Edit.information": "Informazioni",
|
||||
"containers.Edit.information.by": "Da",
|
||||
"containers.Edit.information.draftVersion": "versione bozza",
|
||||
"containers.Edit.information.editing": "Modifica",
|
||||
"containers.Edit.information.lastUpdate": "Aggiornato",
|
||||
"containers.Edit.information.publishedVersion": "versione pubblicata",
|
||||
"containers.Edit.pluginHeader.title.new": "Crea un elemento",
|
||||
"containers.Edit.reset": "Azzera",
|
||||
"containers.Edit.returnList": "Torna alla lista",
|
||||
"containers.Edit.seeDetails": "Dettagli",
|
||||
"containers.Edit.submit": "Salva",
|
||||
"containers.Home.introduction": "Per modificare le voci, visitare il link nel menu di sinistra. Questo plugin non ha un suo modo corretto di modificare le impostazioni ed è ancora in fase di sviluppo attivo.",
|
||||
"containers.Home.pluginHeaderDescription": "Gestire le voci attraverso un potente e bella interfaccia.",
|
||||
"containers.Home.pluginHeaderTitle": "Content Manager",
|
||||
"containers.List.addAnEntry": "Aggiungi un Nuovo {entity}",
|
||||
"containers.EditSettingsView.modal-form.edit-field": "Modifica campo",
|
||||
"containers.EditView.add.new": "AGGIUNGI ELEMENTO",
|
||||
"containers.EditView.components.missing.plural": "Ci sono {count} componenti mancanti",
|
||||
"containers.EditView.components.missing.singular": "C'è {count} componente mancante",
|
||||
"containers.EditView.notification.errors": "Il form contiene degli errori",
|
||||
"containers.Home.introduction": "Per modificare le voci, visitare il link nel menu di sinistra. Questo plugin non ha un modo per modificare le impostazioni ed è ancora in fase di sviluppo attivo.",
|
||||
"containers.Home.pluginHeaderDescription": "Gestisci i tuoi dati attraverso un'interfaccia bella e potente.",
|
||||
"containers.Home.pluginHeaderTitle": "Gestore Contenuti",
|
||||
"containers.List.addAnEntry": "Aggiungi Nuovo {entity}",
|
||||
"containers.List.draft": "Bozza",
|
||||
"containers.List.errorFetchRecords": "Errore",
|
||||
"containers.List.pluginHeaderDescription": "{label} voci non trovato",
|
||||
"containers.List.pluginHeaderDescription.singular": "{label} voce trovati",
|
||||
"containers.List.pluginHeaderDescription": "{label} elementi trovati",
|
||||
"containers.List.pluginHeaderDescription.singular": "{label} elemento trovato",
|
||||
"containers.List.published": "Pubblicato",
|
||||
"containers.ListPage.displayedFields": "Campi visualizzati",
|
||||
"containers.ListPage.items.plural": "elementi",
|
||||
"containers.ListPage.items.singular": "elemento",
|
||||
"containers.ListPage.table-headers.published_at": "Stato",
|
||||
"containers.ListSettingsView.modal-form.edit-label": "Modifica etichetta",
|
||||
"containers.SettingPage.add.field": "Inserisci nuovo campo",
|
||||
"containers.SettingPage.add.relational-field": "Inserisci nuovo campo relazione",
|
||||
"containers.SettingPage.attributes": "Attributi",
|
||||
"containers.SettingPage.attributes.description": "Definisci l'ordine degli attributi",
|
||||
"containers.SettingPage.editSettings.description": "Sposta il campo per costruire il layout",
|
||||
"containers.SettingPage.editSettings.description": "Sposta i campi per costruire il layout",
|
||||
"containers.SettingPage.editSettings.entry.title": "Titolo elemento",
|
||||
"containers.SettingPage.editSettings.entry.title.description": "Scegli quale campo mostrare dell'elemento",
|
||||
"containers.SettingPage.editSettings.relation-field.description": "Scegli il campo da mostrare nelle liste e durante la modifica",
|
||||
"containers.SettingPage.editSettings.title": "Modifica (impostazioni)",
|
||||
"containers.SettingPage.layout": "Layout",
|
||||
"containers.SettingPage.listSettings.description": "Scegli le opzioni per questa Collezione",
|
||||
"containers.SettingPage.listSettings.title": "Lista (impostazioni)",
|
||||
"containers.SettingPage.pluginHeaderDescription": "Configura le impostazioni specifiche per questa Collezione",
|
||||
"containers.SettingPage.relations": "Campi relazionali",
|
||||
"containers.SettingPage.settings": "Impostazioni",
|
||||
"containers.SettingPage.view": "Vista",
|
||||
"containers.SettingViewModel.pluginHeader.title": "Gestore Contenuti - {name}",
|
||||
"containers.SettingsPage.Block.contentType.description": "Configura le impostazioni specifiche",
|
||||
"containers.SettingsPage.Block.contentType.title": "Tipi Collezione",
|
||||
"containers.SettingsPage.Block.generalSettings.description": "Configura le impostazioni di default per le tue Collezioni",
|
||||
"containers.SettingsPage.Block.generalSettings.title": "Generali",
|
||||
"emptyAttributes.title": "Non ci sono ancora campi",
|
||||
"containers.SettingsPage.pluginHeaderDescription": "Configura le impostazioni per tutti i Tipi Collezione e i Gruppi",
|
||||
"containers.SettingsView.list.subtitle": "Configura il layout e la vista per i tuoi tipi Collezione e i gruppi",
|
||||
"containers.SettingsView.list.title": "Configurazioni vista",
|
||||
"emptyAttributes.button": "Vai al costruttore di collezioni",
|
||||
"emptyAttributes.description": "Aggiungi il primo campo al tuo Tipo Collezione",
|
||||
"emptyAttributes.title": "Nessun campo presente",
|
||||
"error.attribute.key.taken": "Questo valore esiste già",
|
||||
"error.attribute.sameKeyAndName": "Non può essere uguale",
|
||||
"error.attribute.taken": "Questo campo nome esiste già",
|
||||
"error.attribute.sameKeyAndName": "Non possono essere uguali",
|
||||
"error.attribute.taken": "Esiste già un campo con questo nome",
|
||||
"error.contentTypeName.taken": "Questo nome esiste già",
|
||||
"error.model.fetch": "Si è verificato un errore durante il caricamento dei modelli di configurazione.",
|
||||
"error.record.create": "Si è verificato un errore durante la creazione del record.",
|
||||
"error.record.delete": "Si è verificato un errore durante la cancellazione del record.",
|
||||
"error.record.fetch": "Si è verificato un errore durante la registrazione.",
|
||||
"error.record.update": "Si è verificato un errore durante l'aggiornamento del record.",
|
||||
"error.records.count": "Si è verificato un errore durante il conteggio dei record.",
|
||||
"error.records.fetch": "Si è verificato un errore durante il caricamento dei record.",
|
||||
"error.record.create": "Si è verificato un errore durante la creazione dell'elemento.",
|
||||
"error.record.delete": "Si è verificato un errore durante la cancellazione dell'elemento.",
|
||||
"error.record.fetch": "Si è verificato un errore durante il caricamento dell'elemento.",
|
||||
"error.record.update": "Si è verificato un errore durante l'aggiornamento dell'elemento.",
|
||||
"error.records.count": "Si è verificato un errore durante il conteggio degli elementi.",
|
||||
"error.records.fetch": "Si è verificato un errore durante il caricamento degli elementi.",
|
||||
"error.schema.generation": "Si è verificato un errore durante la generazione dello schema.",
|
||||
"error.validation.json": "Non è un JSON",
|
||||
"error.validation.max": "Il valore è troppo alto.",
|
||||
@ -63,32 +126,52 @@
|
||||
"error.validation.min": "Il valore è troppo basso.",
|
||||
"error.validation.minLength": "Il valore è troppo breve.",
|
||||
"error.validation.minSupMax": "Non può essere superiore",
|
||||
"error.validation.regex": "Il valore non corrisponde alla regex.",
|
||||
"error.validation.regex": "Il valore non corrisponde alla RegEx.",
|
||||
"error.validation.required": "Questo valore è richiesto.",
|
||||
"form.Input.bulkActions": "Abilita caricamento",
|
||||
"form.Input.bulkActions": "Abilita azioni in blocco",
|
||||
"form.Input.defaultSort": "Attributo di ordinamento di default",
|
||||
"form.Input.description": "Description",
|
||||
"form.Input.description.placeholder": "Display name in the profile",
|
||||
"form.Input.editable": "Editable field",
|
||||
"form.Input.description": "Descrizione",
|
||||
"form.Input.description.placeholder": "Mostra nome nel profilo",
|
||||
"form.Input.editable": "Campo modificabile",
|
||||
"form.Input.filters": "Abilita filtri",
|
||||
"form.Input.label": "Etichetta",
|
||||
"form.Input.label.inputDescription": "Questo valore sovrascrive l'etichetta mostrata nell'intestazione della tabella",
|
||||
"form.Input.pageEntries": "Righe per pagina",
|
||||
"form.Input.pageEntries.inputDescription": "Nota: Puoi sovrascrivere questo valore nella pagina delle impostazioni del Tipo Collezione.",
|
||||
"form.Input.placeholder": "Segnaposto",
|
||||
"form.Input.placeholder.placeholder": "Il mio fantastico valore",
|
||||
"form.Input.search": "Abilita ricerca",
|
||||
"form.Input.search.field": "Abilita la ricerca su questo campo",
|
||||
"form.Input.search.field": "Abilita ricerca su questo campo",
|
||||
"form.Input.sort.field": "Abilita ordinamento su questo campo",
|
||||
"notification.error.displayedFields": "E' necessario almeno un campo visualizzato",
|
||||
"notification.error.relationship.fetch": "Si è verificato un errore durante il rapporto di recupero.",
|
||||
"notification.info.SettingPage.disableSort": "E' necessario un attributo con l'ordinamento abilitato",
|
||||
"form.Input.wysiwyg": "Mostra come WYSIWYG",
|
||||
"global.displayedFields": "Campi visualizzati",
|
||||
"groups": "Gruppi",
|
||||
"groups.numbered": "Gruppi ({number})",
|
||||
"models": "Tipi Collezione",
|
||||
"models.numbered": "Tipi Collezione ({number})",
|
||||
"notification.error.displayedFields": "Devi avere almeno un campo visualizzato",
|
||||
"notification.error.relationship.fetch": "Si è verificato un errore durante il caricamento della relazione.",
|
||||
"notification.info.SettingPage.disableSort": "Devi avere almeno un attributo con ordinamento abilitato",
|
||||
"notification.info.minimumFields": "Devi avere almeno un campo visualizzato",
|
||||
"notification.upload.error": "Si è verificato un errore durante il caricamento dei file",
|
||||
"pageNotFound": "Pagina non trovata",
|
||||
"plugin.description.long": "Veloce modo di vedere, modificare e cancellare i dati presenti nel database.",
|
||||
"plugin.description.short": "Veloce modo di vedere, modificare e cancellare i dati presenti nel database.",
|
||||
"popUpWarning.bodyMessage.contentType.delete": "Sei sicuro di voler cancellare questa voce?",
|
||||
"popUpWarning.bodyMessage.contentType.delete.all": "Sei sicuro di voler eliminare queste voci?",
|
||||
"popUpWarning.warning.cancelAllSettings": "Sei sicuro di voler cancellare le tue modifiche?",
|
||||
"permissions.not-allowed.create": "Non sei autorizzato a creare documenti",
|
||||
"permissions.not-allowed.update": "Non sei autorizzato a vedere questo documento",
|
||||
"plugin.description.long": "Permette di vedere, modificare e cancellare i dati presenti nel database in modo veloce.",
|
||||
"plugin.description.short": "Permette di vedere, modificare e cancellare i dati presenti nel database in modo veloce.",
|
||||
"popUpWarning.bodyMessage.contentType.delete": "Sei sicuro di voler eliminare questo elemento?",
|
||||
"popUpWarning.bodyMessage.contentType.delete.all": "Sei sicuro di voler eliminare questi elementi?",
|
||||
"popUpWarning.warning.cancelAllSettings": "Sei sicuro di voler annullare le tue modifiche?",
|
||||
"popUpWarning.warning.publish-question": "Vuoi ancora pubblicarlo?",
|
||||
"popUpWarning.warning.unpublish": "Annullando la pubblicazione<br></br>cambierai lo stato a Bozza.",
|
||||
"popUpWarning.warning.unpublish-question": "Vuoi annullare la pubblicazione?",
|
||||
"popUpWarning.warning.updateAllSettings": "Questa operazione modificherà tutte le tue impostazioni",
|
||||
"popUpwarning.warning.has-draft-relations.button-confirm": "Sì, pubblica",
|
||||
"popUpwarning.warning.has-draft-relations.message.plural": "<b>{count} delle relazioni collegate sono</b> non ancora pubblicate.<br></br>Questo può produrre collegamenti non validi ed errori nel tuo progetto.",
|
||||
"popUpwarning.warning.has-draft-relations.message.singular": "<b>{count} relazione collegata è</b> non ancora pubblicata.<br></br>Questo può produrre collegamenti non validi ed errori nel tuo progetto.",
|
||||
"popUpwarning.warning.has-draft-relations.second-message": "Questo può produrre collegamenti non validi ed errori nel tuo progetto.",
|
||||
"success.record.delete": "Eliminato",
|
||||
"success.record.save": "Salvato"
|
||||
"success.record.publish": "Pubblicato",
|
||||
"success.record.save": "Salvato",
|
||||
"success.record.unpublish": "Non pubblicato"
|
||||
}
|
||||
|
@ -1,171 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const { createAuthRequest } = require('../../../../test/helpers/request');
|
||||
const { createStrapiInstance } = require('../../../../test/helpers/strapi');
|
||||
const { createTestBuilder } = require('../../../../test/helpers/builder');
|
||||
|
||||
let strapi;
|
||||
let rq;
|
||||
const builder = createTestBuilder();
|
||||
|
||||
let data = {
|
||||
stamps: [],
|
||||
collectors: [],
|
||||
};
|
||||
|
||||
const stamp = {
|
||||
name: 'stamp',
|
||||
kind: 'collectionType',
|
||||
attributes: {
|
||||
name: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const collector = {
|
||||
name: 'collector',
|
||||
kind: 'collectionType',
|
||||
attributes: {
|
||||
name: {
|
||||
type: 'string',
|
||||
},
|
||||
age: {
|
||||
type: 'integer',
|
||||
},
|
||||
stamps: {
|
||||
nature: 'manyWay',
|
||||
target: 'application::stamp.stamp',
|
||||
unique: false,
|
||||
},
|
||||
stamps_m2m: {
|
||||
nature: 'manyToMany',
|
||||
targetAttribute: 'collectors',
|
||||
target: 'application::stamp.stamp',
|
||||
unique: false,
|
||||
dominant: true,
|
||||
},
|
||||
stamps_one_many: {
|
||||
nature: 'oneToMany',
|
||||
targetAttribute: 'collector',
|
||||
target: 'application::stamp.stamp',
|
||||
unique: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const stampFixtures = [
|
||||
{
|
||||
name: '1946',
|
||||
},
|
||||
{
|
||||
name: '1947',
|
||||
},
|
||||
{
|
||||
name: '1948',
|
||||
},
|
||||
];
|
||||
|
||||
const collectorFixtures = ({ stamp }) => [
|
||||
{
|
||||
name: 'Bernard',
|
||||
age: 25,
|
||||
stamps: [stamp[0].id, stamp[1].id],
|
||||
stamps_m2m: [stamp[0].id],
|
||||
stamps_one_many: [],
|
||||
},
|
||||
{
|
||||
name: 'Isabelle',
|
||||
age: 55,
|
||||
stamps: [stamp[0].id],
|
||||
stamps_m2m: [],
|
||||
stamps_one_many: [stamp[1].id, stamp[2].id],
|
||||
},
|
||||
{
|
||||
name: 'Emma',
|
||||
age: 23,
|
||||
stamps: [],
|
||||
stamps_m2m: [stamp[0].id, stamp[1].id],
|
||||
stamps_one_many: [stamp[0].id],
|
||||
},
|
||||
];
|
||||
|
||||
const getCollectorByName = (collectors, name) => collectors.find(c => c.name === name);
|
||||
const getStampByName = (stamps, name) => stamps.find(s => s.name === name);
|
||||
|
||||
describe('CM API - Count relations', () => {
|
||||
beforeAll(async () => {
|
||||
await builder
|
||||
.addContentTypes([stamp, collector])
|
||||
.addFixtures(stamp.name, stampFixtures)
|
||||
.addFixtures(collector.name, collectorFixtures)
|
||||
.build();
|
||||
|
||||
strapi = await createStrapiInstance();
|
||||
rq = await createAuthRequest({ strapi });
|
||||
|
||||
data.collectors = builder.sanitizedFixturesFor(collector.name, strapi);
|
||||
data.stamps = builder.sanitizedFixturesFor(stamp.name, strapi);
|
||||
}, 60000);
|
||||
|
||||
afterAll(async () => {
|
||||
await strapi.destroy();
|
||||
await builder.cleanup();
|
||||
}, 60000);
|
||||
|
||||
test('many-way', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::collector.collector',
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(3);
|
||||
expect(getCollectorByName(res.body.results, 'Bernard').stamps.count).toBe(2);
|
||||
expect(getCollectorByName(res.body.results, 'Isabelle').stamps.count).toBe(1);
|
||||
expect(getCollectorByName(res.body.results, 'Emma').stamps.count).toBe(0);
|
||||
});
|
||||
|
||||
test('many-to-many (collector -> stamps)', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::collector.collector',
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(3);
|
||||
expect(getCollectorByName(res.body.results, 'Bernard').stamps_m2m.count).toBe(1);
|
||||
expect(getCollectorByName(res.body.results, 'Isabelle').stamps_m2m.count).toBe(0);
|
||||
expect(getCollectorByName(res.body.results, 'Emma').stamps_m2m.count).toBe(2);
|
||||
});
|
||||
|
||||
test('many-to-many (stamp -> collectors)', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::stamp.stamp',
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(3);
|
||||
expect(getStampByName(res.body.results, '1946').collectors.count).toBe(2);
|
||||
expect(getStampByName(res.body.results, '1947').collectors.count).toBe(1);
|
||||
expect(getStampByName(res.body.results, '1948').collectors.count).toBe(0);
|
||||
});
|
||||
|
||||
test('one-to-many', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::collector.collector',
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(3);
|
||||
expect(getCollectorByName(res.body.results, 'Bernard').stamps_one_many.count).toBe(0);
|
||||
expect(getCollectorByName(res.body.results, 'Isabelle').stamps_one_many.count).toBe(2);
|
||||
expect(getCollectorByName(res.body.results, 'Emma').stamps_one_many.count).toBe(1);
|
||||
});
|
||||
});
|
@ -0,0 +1,404 @@
|
||||
'use strict';
|
||||
|
||||
const { createAuthRequest } = require('../../../../test/helpers/request');
|
||||
const { createStrapiInstance } = require('../../../../test/helpers/strapi');
|
||||
const { createTestBuilder } = require('../../../../test/helpers/builder');
|
||||
|
||||
let strapi;
|
||||
let rq;
|
||||
const builder = createTestBuilder();
|
||||
|
||||
let data = {
|
||||
stamps: [],
|
||||
collectors: [],
|
||||
};
|
||||
|
||||
const stamp = {
|
||||
name: 'stamp',
|
||||
kind: 'collectionType',
|
||||
attributes: {
|
||||
name: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const collector = {
|
||||
name: 'collector',
|
||||
kind: 'collectionType',
|
||||
attributes: {
|
||||
name: {
|
||||
type: 'string',
|
||||
},
|
||||
age: {
|
||||
type: 'integer',
|
||||
},
|
||||
stamps: {
|
||||
nature: 'manyWay',
|
||||
target: 'application::stamp.stamp',
|
||||
unique: false,
|
||||
},
|
||||
stamps_one_way: {
|
||||
nature: 'oneWay',
|
||||
target: 'application::stamp.stamp',
|
||||
unique: false,
|
||||
},
|
||||
stamps_m2m: {
|
||||
nature: 'manyToMany',
|
||||
targetAttribute: 'collectors',
|
||||
target: 'application::stamp.stamp',
|
||||
unique: false,
|
||||
dominant: true,
|
||||
},
|
||||
stamps_one_many: {
|
||||
nature: 'oneToMany',
|
||||
targetAttribute: 'collector',
|
||||
target: 'application::stamp.stamp',
|
||||
unique: false,
|
||||
},
|
||||
stamps_one_one: {
|
||||
nature: 'oneToOne',
|
||||
targetAttribute: 'collector_one_one',
|
||||
target: 'application::stamp.stamp',
|
||||
unique: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const stampFixtures = [
|
||||
{
|
||||
name: '1946',
|
||||
},
|
||||
{
|
||||
name: '1947',
|
||||
},
|
||||
{
|
||||
name: '1948',
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
|
||||
|
||||
const collectorFixtures = ({ stamp }) => [
|
||||
{
|
||||
name: 'Bernard',
|
||||
age: 25,
|
||||
stamps: [stamp[0].id, stamp[1].id],
|
||||
stamps_m2m: [stamp[0].id],
|
||||
stamps_one_many: [],
|
||||
stamps_one_way: stamp[0].id,
|
||||
stamps_one_one: stamp[0].id,
|
||||
},
|
||||
{
|
||||
name: 'Isabelle',
|
||||
age: 55,
|
||||
stamps: [stamp[0].id],
|
||||
stamps_m2m: [],
|
||||
stamps_one_many: [stamp[1].id, stamp[2].id],
|
||||
stamps_one_way: stamp[1].id,
|
||||
stamps_one_one: stamp[1].id,
|
||||
},
|
||||
{
|
||||
name: 'Emma',
|
||||
age: 23,
|
||||
stamps: [],
|
||||
stamps_m2m: [stamp[0].id, stamp[1].id],
|
||||
stamps_one_many: [stamp[0].id],
|
||||
stamps_one_way: stamp[2].id,
|
||||
stamps_one_one: stamp[2].id,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
const getCollectorByName = (collectors, name) => collectors.find(c => c.name === name);
|
||||
const getStampByName = (stamps, name) => stamps.find(s => s.name === name);
|
||||
|
||||
describe('CM API', () => {
|
||||
beforeAll(async () => {
|
||||
await builder
|
||||
.addContentTypes([stamp, collector])
|
||||
.addFixtures(stamp.name, stampFixtures)
|
||||
.addFixtures(collector.name, collectorFixtures)
|
||||
.build();
|
||||
|
||||
|
||||
strapi = await createStrapiInstance();
|
||||
rq = await createAuthRequest({ strapi });
|
||||
|
||||
data.collectors = builder.sanitizedFixturesFor(collector.name, strapi);
|
||||
data.stamps = builder.sanitizedFixturesFor(stamp.name, strapi);
|
||||
}, 60000);
|
||||
|
||||
afterAll(async () => {
|
||||
await strapi.destroy();
|
||||
await builder.cleanup();
|
||||
}, 60000);
|
||||
|
||||
describe('Count relations', () => {
|
||||
test('many-way', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::collector.collector',
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(3);
|
||||
expect(getCollectorByName(res.body.results, 'Bernard').stamps.count).toBe(2);
|
||||
expect(getCollectorByName(res.body.results, 'Isabelle').stamps.count).toBe(1);
|
||||
expect(getCollectorByName(res.body.results, 'Emma').stamps.count).toBe(0);
|
||||
});
|
||||
|
||||
test('many-to-many (collector -> stamps)', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::collector.collector',
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(3);
|
||||
expect(getCollectorByName(res.body.results, 'Bernard').stamps_m2m.count).toBe(1);
|
||||
expect(getCollectorByName(res.body.results, 'Isabelle').stamps_m2m.count).toBe(0);
|
||||
expect(getCollectorByName(res.body.results, 'Emma').stamps_m2m.count).toBe(2);
|
||||
});
|
||||
|
||||
test('many-to-many (stamp -> collectors)', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::stamp.stamp',
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(3);
|
||||
expect(getStampByName(res.body.results, '1946').collectors.count).toBe(2);
|
||||
expect(getStampByName(res.body.results, '1947').collectors.count).toBe(1);
|
||||
expect(getStampByName(res.body.results, '1948').collectors.count).toBe(0);
|
||||
});
|
||||
|
||||
test('one-to-many', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::collector.collector',
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(3);
|
||||
expect(getCollectorByName(res.body.results, 'Bernard').stamps_one_many.count).toBe(0);
|
||||
expect(getCollectorByName(res.body.results, 'Isabelle').stamps_one_many.count).toBe(2);
|
||||
expect(getCollectorByName(res.body.results, 'Emma').stamps_one_many.count).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Filter relations', () => {
|
||||
test('many-way', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::collector.collector',
|
||||
qs: {
|
||||
_where: { 'stamps.name': '1946' },
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(2);
|
||||
expect(res.body.results[0].name).toBe('Bernard');
|
||||
expect(res.body.results[1].name).toBe('Isabelle');
|
||||
});
|
||||
|
||||
test('many-to-many (collector -> stamps)', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::collector.collector',
|
||||
qs: {
|
||||
_where: { 'stamps_m2m.name': '1946' },
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(2);
|
||||
expect(getCollectorByName(res.body.results, 'Bernard')).toBeDefined();
|
||||
expect(getCollectorByName(res.body.results, 'Emma')).toBeDefined();
|
||||
});
|
||||
|
||||
test('many-to-many (stamp -> collectors)', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::stamp.stamp',
|
||||
qs: {
|
||||
_where: { 'collectors.name': 'Emma' },
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(2);
|
||||
expect(getStampByName(res.body.results, '1946')).toBeDefined();
|
||||
expect(getStampByName(res.body.results, '1947')).toBeDefined();
|
||||
});
|
||||
|
||||
test('one-to-many', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::collector.collector',
|
||||
qs: {
|
||||
_where: { 'stamps_one_many.name': '1947' },
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(1);
|
||||
expect(res.body.results[0].name).toBe('Isabelle');
|
||||
});
|
||||
|
||||
test('many-to-one', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::stamp.stamp',
|
||||
qs: {
|
||||
_where: { 'collector.name': 'Isabelle' },
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(2);
|
||||
expect(getStampByName(res.body.results, '1947')).toBeDefined();
|
||||
expect(getStampByName(res.body.results, '1948')).toBeDefined();
|
||||
});
|
||||
|
||||
test('one-way', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::collector.collector',
|
||||
qs: {
|
||||
_where: { 'stamps_one_way.name': '1947' },
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(1);
|
||||
expect(getCollectorByName(res.body.results, 'Isabelle')).toBeDefined();
|
||||
});
|
||||
|
||||
test('one-one', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::collector.collector',
|
||||
qs: {
|
||||
_where: { 'stamps_one_one.name': '1947' },
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(1);
|
||||
expect(getCollectorByName(res.body.results, 'Isabelle')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Sort relations', () => {
|
||||
test('many-to-one', async () => {
|
||||
let res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::stamp.stamp',
|
||||
qs: {
|
||||
_sort: 'collector.name:ASC',
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(3);
|
||||
expect(res.body.results[0].collector.name).toBe('Emma');
|
||||
expect(res.body.results[1].collector.name).toBe('Isabelle');
|
||||
expect(res.body.results[2].collector.name).toBe('Isabelle');
|
||||
|
||||
res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::stamp.stamp',
|
||||
qs: {
|
||||
_sort: 'collector.name:DESC',
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(3);
|
||||
expect(res.body.results[0].collector.name).toBe('Isabelle');
|
||||
expect(res.body.results[1].collector.name).toBe('Isabelle');
|
||||
expect(res.body.results[2].collector.name).toBe('Emma');
|
||||
});
|
||||
|
||||
test('one-way', async () => {
|
||||
let res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::collector.collector',
|
||||
qs: {
|
||||
_sort: 'stamps_one_way.name:ASC',
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(3);
|
||||
expect(res.body.results[0].stamps_one_way.name).toBe('1946');
|
||||
expect(res.body.results[1].stamps_one_way.name).toBe('1947');
|
||||
expect(res.body.results[2].stamps_one_way.name).toBe('1948');
|
||||
|
||||
res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::collector.collector',
|
||||
qs: {
|
||||
_sort: 'stamps_one_way.name:DESC',
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(3);
|
||||
expect(res.body.results[0].stamps_one_way.name).toBe('1948');
|
||||
expect(res.body.results[1].stamps_one_way.name).toBe('1947');
|
||||
expect(res.body.results[2].stamps_one_way.name).toBe('1946');
|
||||
});
|
||||
|
||||
test('one-one', async () => {
|
||||
let res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::collector.collector',
|
||||
qs: {
|
||||
_sort: 'stamps_one_one.name:ASC',
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(3);
|
||||
expect(res.body.results[0].stamps_one_one.name).toBe('1946');
|
||||
expect(res.body.results[1].stamps_one_one.name).toBe('1947');
|
||||
expect(res.body.results[2].stamps_one_one.name).toBe('1948');
|
||||
|
||||
res = await rq({
|
||||
method: 'GET',
|
||||
url: '/content-manager/collection-types/application::collector.collector',
|
||||
qs: {
|
||||
_sort: 'stamps_one_one.name:DESC',
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(Array.isArray(res.body.results)).toBe(true);
|
||||
expect(res.body.results).toHaveLength(3);
|
||||
expect(res.body.results[0].stamps_one_one.name).toBe('1948');
|
||||
expect(res.body.results[1].stamps_one_one.name).toBe('1947');
|
||||
expect(res.body.results[2].stamps_one_one.name).toBe('1946');
|
||||
});
|
||||
});
|
||||
});
|
@ -1,51 +1,187 @@
|
||||
{
|
||||
"attribute.boolean": "Boolean",
|
||||
"attribute.boolean": "Booleano",
|
||||
"attribute.boolean.description": "Sì o no, 1 o 0, vero o falso",
|
||||
"attribute.component": "Componente",
|
||||
"attribute.component.description": "Gruppo di campi che puoi ripetere o riutilizzare",
|
||||
"attribute.date": "Data",
|
||||
"attribute.date.description": "Un selettore di date con ore, minuti e secondi",
|
||||
"attribute.datetime": "Data e Ora",
|
||||
"attribute.dynamiczone": "Zona dinamica",
|
||||
"attribute.dynamiczone.description": "Scegli un componente dinamicamente durante la modifica del contenuto ",
|
||||
"attribute.email": "Email",
|
||||
"attribute.email.description": "Un campo Email con validazione del formato",
|
||||
"attribute.enumeration": "Enumerazione",
|
||||
"attribute.enumeration.description": "Scegli il valore da una lista precompilata",
|
||||
"attribute.json": "JSON",
|
||||
"attribute.json.description": "Dati in formato JSON",
|
||||
"attribute.media": "Media",
|
||||
"attribute.media.description": "File come immagini, video, ecc.",
|
||||
"attribute.null": " ",
|
||||
"attribute.number": "Numero",
|
||||
"attribute.number.description": "Numeri (interi, float, decimali)",
|
||||
"attribute.password": "Password",
|
||||
"attribute.password.description": "Campo Password crittografato",
|
||||
"attribute.relation": "Relazione",
|
||||
"attribute.relation.description": "Per collegare una Collezione",
|
||||
"attribute.richtext": "Testo formattato",
|
||||
"attribute.richtext.description": "Un editor di testo con comandi per la formattazione",
|
||||
"attribute.text": "Testo",
|
||||
"form.attribute.item.customColumnName": "Nomi di colonna personalizzata",
|
||||
"form.attribute.item.customColumnName.description": "Questo è utile per rinominare il database di nomi di colonna in un più ampio formato per le API risposte",
|
||||
"attribute.text.description": "Testo semplice come titolo o descrizione",
|
||||
"attribute.time": "Orario",
|
||||
"attribute.timestamp": "Timestamp",
|
||||
"attribute.uid": "UID",
|
||||
"attribute.uid.description": "Identificatore univoco",
|
||||
"button.attributes.add.another": "Aggiungi altro campo",
|
||||
"button.component.add": "Aggiungi componente",
|
||||
"button.component.create": "Crea nuovo componente",
|
||||
"button.model.create": "Crea nuova Collezione",
|
||||
"button.single-types.create": "Crea nuova Entità singola",
|
||||
"component.repeatable": "(ripetibile)",
|
||||
"components.componentSelect.no-component-available": "Hai già aggiunto tutti i componenti",
|
||||
"components.componentSelect.no-component-available.with-search": "Nessun componente con questa chiave di ricerca",
|
||||
"components.componentSelect.value-component": "{number} componenti selezionati (digita per cercare un componente)",
|
||||
"components.componentSelect.value-components": "{number} componenti selezionati",
|
||||
"configurations": "configurazioni",
|
||||
"contentType.UID.description": "Lo UID viene usato per generare le routes API e le tabelle del database",
|
||||
"contentType.collectionName.description": "Utile quando il nome della Collezione differisce dal nome della tabella del DB",
|
||||
"contentType.collectionName.label": "Nome della Collezione",
|
||||
"contentType.displayName.label": "Nome visualizzato",
|
||||
"contentType.draftAndPublish.description": "Scrivi una bozza dell'elemento prima di pubblicarlo",
|
||||
"contentType.draftAndPublish.label": "Sistema Bozza/pubblicato",
|
||||
"contentType.kind.change.warning": "Hai cambiato il genere di questo Tipo di Contenuto. Le API verranno ripristinate (route, controller e services verranno sovrascritti).",
|
||||
"error.attributeName.reserved-name": "Questo nome non può essere utilizzato nel tuo Tipo di Contenuto perché potrebbe danneggiare altre funzionalità",
|
||||
"error.contentTypeName.reserved-name": "Questo nome non può essere utilizzato nel tuo progetto perché potrebbe danneggiare altre funzionalità",
|
||||
"error.validation.enum-duplicate": "Valori duplicati non ammessi",
|
||||
"error.validation.minSupMax": "Non può essere maggiore",
|
||||
"error.validation.regex": "Regex non valida",
|
||||
"error.validation.relation.targetAttribute-taken": "Questo nome già esiste nella destinazione",
|
||||
"form.attribute.component.option.add": "Aggiungi componente",
|
||||
"form.attribute.component.option.create": "Crea nuovo componente",
|
||||
"form.attribute.component.option.create.description": "I componenti sono condivisi tra Tipi e componenti, sono disponibili e accessibili da ovunque.",
|
||||
"form.attribute.component.option.repeatable": "Componente ripetibile",
|
||||
"form.attribute.component.option.repeatable.description": "Utile per istanze multiple (liste) come ingredienti, meta tag, ecc...",
|
||||
"form.attribute.component.option.reuse-existing": "Usa componente esistente",
|
||||
"form.attribute.component.option.reuse-existing.description": "Riutilizza un componente già creato per mantenere i dati consistenti tra i vari Tipi di Contenuto",
|
||||
"form.attribute.component.option.single": "Componente singolo",
|
||||
"form.attribute.component.option.single.description": "Utile per raggruppare campi correlati come quelli di un indirizzo",
|
||||
"form.attribute.item.customColumnName": "Nome della colonna personalizzato",
|
||||
"form.attribute.item.customColumnName.description": "Utile per rinominare le colonne del database e mantenere consistente il formato delle risposte API",
|
||||
"form.attribute.item.date.type.date": "data",
|
||||
"form.attribute.item.date.type.datetime": "data e ora",
|
||||
"form.attribute.item.date.type.time": "orario",
|
||||
"form.attribute.item.defineRelation.fieldName": "Nome del campo",
|
||||
"form.attribute.item.enumeration.graphql": "Nome override per GraphQL",
|
||||
"form.attribute.item.enumeration.graphql.description": "Consente di ignorare l'impostazione predefinita generata nome per GraphQL",
|
||||
"form.attribute.item.enumeration.placeholder": "Ex:\nmattina\nmezzogiorno\nsera",
|
||||
"form.attribute.item.enumeration.rules": "Values (one line per value)",
|
||||
"form.attribute.item.enumeration.graphql": "Override del nome GraphQL",
|
||||
"form.attribute.item.enumeration.graphql.description": "Consente di ignorare l'impostazione predefinita del nome generato per GraphQL",
|
||||
"form.attribute.item.enumeration.placeholder": "Es:\nmattina\nmezzogiorno\nsera",
|
||||
"form.attribute.item.enumeration.rules": "Valori (un valore per riga)",
|
||||
"form.attribute.item.maximum": "Valore massimo",
|
||||
"form.attribute.item.maximumLength": "Lunghezza massima",
|
||||
"form.attribute.item.minimum": "Valore minimo",
|
||||
"form.attribute.item.minimumLength": "Lunghezza minima",
|
||||
"form.attribute.item.number.type": "Il formato del numero di",
|
||||
"form.attribute.item.number.type": "Formato del numero",
|
||||
"form.attribute.item.number.type.biginteger": "intero grande (es: 123456789)",
|
||||
"form.attribute.item.number.type.decimal": "decimale (es: 2.22)",
|
||||
"form.attribute.item.number.type.float": "float (ex: 3.33333333)",
|
||||
"form.attribute.item.number.type.float": "float (es: 3.33333333)",
|
||||
"form.attribute.item.number.type.integer": "intero (es: 10)",
|
||||
"form.attribute.item.privateField": "Campo privato",
|
||||
"form.attribute.item.privateField.description": "Questo campo non sarà presente nelle risposte API",
|
||||
"form.attribute.item.requiredField": "Campo obbligatorio",
|
||||
"form.attribute.item.requiredField.description": "Non sarà in grado di creare una voce se questo campo è vuoto",
|
||||
"form.attribute.item.requiredField.description": "Non sarai in grado di creare una voce se questo campo è vuoto",
|
||||
"form.attribute.item.settings.name": "Impostazioni",
|
||||
"form.attribute.item.uniqueField": "Unico campo",
|
||||
"form.attribute.item.uniqueField.description": "Non sarà in grado di creare una voce, se c'è una voce esistente con contenuti identici",
|
||||
"form.attribute.item.text.regex": "Schema RegExp",
|
||||
"form.attribute.item.text.regex.description": "Il testo di una Espressione Regolare",
|
||||
"form.attribute.item.uniqueField": "Campo univoco",
|
||||
"form.attribute.item.uniqueField.description": "Non sarai in grado di creare una voce, se c'è una voce esistente con valore identico",
|
||||
"form.attribute.media.allowed-types": "Seleziona i tipi di media permessi",
|
||||
"form.attribute.media.allowed-types.none": "Nessuno",
|
||||
"form.attribute.media.allowed-types.option-files": "File",
|
||||
"form.attribute.media.allowed-types.option-images": "Immagini",
|
||||
"form.attribute.media.allowed-types.option-videos": "Video",
|
||||
"form.attribute.media.option.multiple": "Media multipli",
|
||||
"form.attribute.media.option.multiple.description": "Utile per slider, caroselli o download multipli",
|
||||
"form.attribute.media.option.single": "Media singolo",
|
||||
"form.attribute.media.option.single.description": "Utile per avatar, foto profilo o copertina",
|
||||
"form.attribute.settings.default": "Valore di Default",
|
||||
"form.attribute.text.option.long-text": "Testo lungo",
|
||||
"form.attribute.text.option.long-text.description": "Utile per descrizioni o biografie. La ricerca esatta è disabilitata.",
|
||||
"form.attribute.text.option.short-text": "Testo breve",
|
||||
"form.attribute.text.option.short-text.description": "Utile per titoli, nomi, link (URL). Potrai eseguire una ricerca esatta sul campo.",
|
||||
"form.button.add-components-to-dynamiczone": "Aggiungi componenti alla zona",
|
||||
"form.button.add-field": "Aggiungi altro campo",
|
||||
"form.button.add-first-field-to-created-component": "Aggiungi un primo campo al componente",
|
||||
"form.button.add.field.to.collectionType": "Aggiungi un altro campo a questa Collezione",
|
||||
"form.button.add.field.to.component": "Aggiungi un altro campo a questo componente",
|
||||
"form.button.add.field.to.contentType ": "Aggiungi un altro campo a questo Tipo di Contenuto",
|
||||
"form.button.add.field.to.singleType": "Aggiungi un altro campo a questa Entità singola",
|
||||
"form.button.cancel": "Annulla",
|
||||
"form.button.collection-type.description": "Utile per istanze multiple come articoli, prodotti, commenti, ecc...",
|
||||
"form.button.configure-component": "Configura componente",
|
||||
"form.button.configure-view": "Configura vista",
|
||||
"form.button.continue": "Continua",
|
||||
"form.button.delete": "Elimina",
|
||||
"form.button.finish": "Fatto",
|
||||
"form.button.save": "Salva",
|
||||
"form.button.select-component": "Seleziona un componente",
|
||||
"form.button.single-type.description": "Indicato per entità uniche come home page, chi siamo, ecc...",
|
||||
"form.contentType.divider.draft-publish": "DRAFT/PUBLISH",
|
||||
"from": "da",
|
||||
"menu.section.models.name.plural": "I Tipi Di Contenuto",
|
||||
"menu.section.models.name.singular": "Tipo Di Contenuto",
|
||||
"injected-components.content-manager.edit-settings-view.link.components": "Modifica componente",
|
||||
"injected-components.content-manager.edit-settings-view.link.content-types": "Modifica Tipo di Contenuto",
|
||||
"menu.section.components.name.plural": "Componenti",
|
||||
"menu.section.components.name.singular": "Componente",
|
||||
"menu.section.models.name.plural": "Collezioni",
|
||||
"menu.section.models.name.singular": "Collezione",
|
||||
"menu.section.single-types.name.plural": "Entità singole",
|
||||
"menu.section.single-types.name.singular": "Entità singola",
|
||||
"modalForm.attribute.form.base.name": "Nome",
|
||||
"modalForm.attribute.form.base.name.description": "Spazi non ammessi per il nome dell'attributo",
|
||||
"modalForm.attribute.form.base.name.placeholder": "Es: Slug, URL SEO, URL Canonico",
|
||||
"modalForm.attribute.target-field": "Campo collegato",
|
||||
"modalForm.attribute.text.type-selection": "Tipo",
|
||||
"modalForm.attributes.select-component": "Seleziona un componente",
|
||||
"modalForm.attributes.select-components": "Seleziona i componenti",
|
||||
"modalForm.component.header-create": "Crea un componente",
|
||||
"modalForm.components.create-component.category.label": "Seleziona una categoria o inserisci un nome per crearne una nuova",
|
||||
"modalForm.components.icon.label": "Icona",
|
||||
"modalForm.contentType.header-create": "Crea una Collezione",
|
||||
"modalForm.editCategory.base.name.description": "Spazi non ammessi per il nome della categoria",
|
||||
"modalForm.header-edit": "Modifica {name}",
|
||||
"modalForm.header.categories": "Categorie",
|
||||
"modalForm.singleType.header-create": "Crea una Entità singola",
|
||||
"modalForm.sub-header.addComponentToDynamicZone": "Aggiungi nuovo componente alla zona dinamica",
|
||||
"modalForm.sub-header.attribute.create": "Aggiungi nuovo campo {type}",
|
||||
"modalForm.sub-header.attribute.create.step": "Aggiungi nuovo componente ({step}/2)",
|
||||
"modalForm.sub-header.attribute.edit": "Modifica {name}",
|
||||
"modalForm.sub-header.chooseAttribute.collectionType": "Seleziona un campo per la tua Collezione",
|
||||
"modalForm.sub-header.chooseAttribute.component": "Seleziona un campo per il tuo componente",
|
||||
"modalForm.sub-header.chooseAttribute.singleType": "Seleziona un campo per la tua Entità singola",
|
||||
"modelPage.attribute.relation-polymorphic": "Relazione (polimorfica)",
|
||||
"modelPage.attribute.relationWith": "Relazione con",
|
||||
"modelPage.contentHeader.emptyDescription.description": "Non vi è alcuna descrizione per questo Tipo di Contenuto",
|
||||
"plugin.description.long": "Modellizzare la struttura dei dati dell'API. Creare nuovi campi e le relazioni che in un solo minuto. I file vengono automaticamente creati e aggiornati nel tuo progetto.",
|
||||
"plugin.description.short": "Modellizzare la struttura dei dati dell'API.",
|
||||
"modelPage.contentHeader.emptyDescription.description": "Nessuna descrizione",
|
||||
"none": "Nessuno",
|
||||
"notification.info.autoreaload-disable": "La funzionalità autoReload è richiesta per usare questo plugin. Avvia il tuo server con `strapi develop`",
|
||||
"notification.info.creating.notSaved": "Per favore, salva il tuo lavoro prima di creare nuovi Tipi di Contenuto o componenti",
|
||||
"plugin.description.long": "Modella la struttura dei dati delle tue API. Crea nuovi campi e relazioni in maniera visuale. I file vengono automaticamente creati e aggiornati nel tuo progetto.",
|
||||
"plugin.description.short": "Modella la struttura dei dati delle tue API.",
|
||||
"plugin.name": "Content-Types Builder",
|
||||
"popUpForm.navContainer.advanced": "Impostazioni avanzate",
|
||||
"popUpForm.navContainer.base": "Le impostazioni di Base",
|
||||
"popUpWarning.bodyMessage.contentType.delete": "Sei sicuro di voler eliminare questo Tipo di Contenuto?",
|
||||
"relation.attributeName.placeholder": "Ex: autore, categoria, tag",
|
||||
"relation.manyToMany": "e appartiene a molti",
|
||||
"popUpForm.navContainer.base": "Impostazioni di base",
|
||||
"popUpWarning.bodyMessage.cancel-modifications": "Sei sicuro di voler annullare le tue modifiche?",
|
||||
"popUpWarning.bodyMessage.cancel-modifications.with-components": "Sei sicuro di voler annullare le tue modifiche? Alcuni componenti sono stati creati o modificati...",
|
||||
"popUpWarning.bodyMessage.category.delete": "Sei sicuro di voler eliminare questa categoria? Verranno cancellati anche tutti i suoi componenti.",
|
||||
"popUpWarning.bodyMessage.component.delete": "Sei sicuro di voler eliminare questo componente?",
|
||||
"popUpWarning.bodyMessage.contentType.delete": "Sei sicuro di voler eliminare questa Collezione?",
|
||||
"popUpWarning.draft-publish.button.confirm": "Sì, disabilita",
|
||||
"popUpWarning.draft-publish.message": "Se disabiliti il sistema Bozza/pubblicato, le tue bozze verranno eliminate.",
|
||||
"popUpWarning.draft-publish.second-message": "Sei sicuro di volerlo disabilitare?",
|
||||
"prompt.unsaved": "Sei sicuro di voler uscire? Tutte le modifiche verranno perdute.",
|
||||
"relation.attributeName.placeholder": "Es: autore, categoria, tag",
|
||||
"relation.manyToMany": "ha e appartiene a molti",
|
||||
"relation.manyToOne": "ha molti",
|
||||
"relation.manyWay": "ha molti",
|
||||
"relation.oneToMany": "appartiene a molti",
|
||||
"relation.oneToOne": "e appartiene a uno",
|
||||
"relation.oneWay": "ha una"
|
||||
"relation.oneToOne": "ha e appartiene a un",
|
||||
"relation.oneWay": "ha un",
|
||||
"table.attributes.title.plural": "{number} campi",
|
||||
"table.attributes.title.singular": "{number} campo"
|
||||
}
|
||||
|
@ -1,24 +1,29 @@
|
||||
{
|
||||
"components.Row.generatedDate": "Last generation",
|
||||
"components.Row.open": "Open",
|
||||
"components.Row.regenerate": "Regenerate",
|
||||
"containers.HomePage.Block.title": "Versions",
|
||||
"containers.HomePage.Button.open": "Open the documentation",
|
||||
"containers.HomePage.Button.update": "Update",
|
||||
"containers.HomePage.PluginHeader.description": "Configure the documentation plugin",
|
||||
"containers.HomePage.PluginHeader.title": "Documentation - Settings",
|
||||
"containers.HomePage.PopUpWarning.confirm": "I understand",
|
||||
"containers.HomePage.PopUpWarning.message": "Are you sure you want to delete this version?",
|
||||
"components.Row.generatedDate": "Ultima generazione",
|
||||
"components.Row.open": "Apri",
|
||||
"components.Row.regenerate": "Rigenera",
|
||||
"containers.HomePage.Block.title": "Versioni",
|
||||
"containers.HomePage.Button.open": "Apri la documentazione",
|
||||
"containers.HomePage.Button.update": "Aggiorna",
|
||||
"containers.HomePage.PluginHeader.description": "Configura il plugin Documentazione",
|
||||
"containers.HomePage.PluginHeader.title": "Documentazione - Impostazioni",
|
||||
"containers.HomePage.PopUpWarning.confirm": "Ho capito",
|
||||
"containers.HomePage.PopUpWarning.message": "Sei sicuro di voler eliminare questa versione?",
|
||||
"containers.HomePage.copied": "Token copiato negli appunti",
|
||||
"containers.HomePage.form.jwtToken": "Recupera il tuo token jwt",
|
||||
"containers.HomePage.form.jwtToken.description": "Copia questo token e usalo in swagger per fare richieste",
|
||||
"containers.HomePage.form.password": "Password",
|
||||
"containers.HomePage.form.password.inputDescription": "Set the password to access the documentation",
|
||||
"containers.HomePage.form.restrictedAccess": "Restricted access",
|
||||
"containers.HomePage.form.restrictedAccess.inputDescription": "Make the documentation endpoint private. By default, the access is public",
|
||||
"containers.HomePage.form.showGeneratedFiles": "Show generated files",
|
||||
"containers.HomePage.form.showGeneratedFiles.inputDescription": "Useful when you want to override the generated documentation. \nThe plugin will generate files split by model and plugin. \nBy enabling this option it will be easier to customize your documentation",
|
||||
"error.deleteDoc.versionMissing": "The version you are trying to delete does not exist.",
|
||||
"error.noVersion": "A version is required",
|
||||
"error.regenerateDoc": "An error occurred while regenerating the doc",
|
||||
"error.regenerateDoc.versionMissing": "The version you are trying to generate doesn't exist",
|
||||
"notification.update.success": "Settings updated successfully",
|
||||
"containers.HomePage.form.password.inputDescription": "Imposta una password per accedere alla documentazione",
|
||||
"containers.HomePage.form.restrictedAccess": "Accesso limitato",
|
||||
"containers.HomePage.form.restrictedAccess.inputDescription": "Rendi l'endpoint della documentazione privato. Di default l'accesso è pubblico",
|
||||
"containers.HomePage.form.showGeneratedFiles": "Mostra file generati",
|
||||
"containers.HomePage.form.showGeneratedFiles.inputDescription": "Utile quando vuoi sovrascrivere la documentazione generata. \nIl plugin genera file suddivisi per modello e per plugin. \nAbilitando questa opzione sarà più semplice personalizzare la tua documentazione.",
|
||||
"error.deleteDoc.versionMissing": "La versione che stai tentando di cancellare non esiste.",
|
||||
"error.noVersion": "Una versione è richiesta",
|
||||
"error.regenerateDoc": "Si è verificato un errore durante la rigenerazione della documentazione",
|
||||
"error.regenerateDoc.versionMissing": "La versione che stai tentando di generare non esiste",
|
||||
"notification.update.success": "Impostazioni aggiornate con successo",
|
||||
"notification.delete.success": "Doc eliminata",
|
||||
"notification.generate.success": "Doc generata",
|
||||
"plugin.name": "Documentazione"
|
||||
}
|
82
packages/strapi-plugin-upload/admin/src/translations/it.json
Normal file
82
packages/strapi-plugin-upload/admin/src/translations/it.json
Normal file
@ -0,0 +1,82 @@
|
||||
{
|
||||
"button.next": "Prossimo",
|
||||
"checkControl.crop-duplicate": "Copia file prima del ritaglio",
|
||||
"checkControl.crop-original": "Ritaglia il file originale",
|
||||
"control-card.add": "Aggiungi",
|
||||
"control-card.cancel": "Annulla",
|
||||
"control-card.copy-link": "Copia link",
|
||||
"control-card.crop": "Ritaglia",
|
||||
"control-card.delete": "Elimina",
|
||||
"control-card.download": "Download",
|
||||
"control-card.edit": "Modifica",
|
||||
"control-card.replace-media": "Rimpiazza Media",
|
||||
"control-card.save": "Salva",
|
||||
"filter.add": "Aggiungi filtro",
|
||||
"form.button.replace-media": "Rimpiazza media",
|
||||
"form.input.decription.file-alt": "Questo testo viene mostrato quando la risorsa non può essere visualizzata.",
|
||||
"form.input.label.file-alt": "Testo alternativo",
|
||||
"form.input.label.file-caption": "Didascalia",
|
||||
"form.input.label.file-name": "Nome file",
|
||||
"form.upload-url.error.url.invalid": "Un URL non è valido",
|
||||
"form.upload-url.error.url.invalids": "{number} URL non sono validi",
|
||||
"header.actions.upload-assets": "Carica risorse",
|
||||
"header.content.assets-empty": "Nessuna risorsa",
|
||||
"header.content.assets-multiple": "{number} risorse",
|
||||
"header.content.assets-single": "1 risorsa",
|
||||
"input.button.label": "Sfoglia file",
|
||||
"input.label-bold": "Trascina & rilascia",
|
||||
"input.label-normal": "per caricare oppure",
|
||||
"input.placeholder": "Clicca per selezionare una risorsa o rilascia un file in quest'area",
|
||||
"input.url.description": "Separa i tuoi URL con un ritorno a capo.",
|
||||
"input.url.label": "URL",
|
||||
"list.assets-empty.subtitle": "Aggiungi uno alla lista.",
|
||||
"list.assets-empty.title": "Ancora nessuna risorsa",
|
||||
"list.assets-empty.title-withSearch": "Nessuna risorsa con i filtri selezionati",
|
||||
"list.assets.selected.plural": "{number} risorse selezionate",
|
||||
"list.assets.selected.singular": "{number} risorsa selezionata",
|
||||
"list.assets.type-not-allowed": "Questo tipo di file non è consentito.",
|
||||
"modal.file-details.date": "Data",
|
||||
"modal.file-details.dimensions": "Dimensioni",
|
||||
"modal.file-details.extension": "Estensione",
|
||||
"modal.file-details.size": "Dimensione",
|
||||
"modal.header.browse": "Carica risorsa",
|
||||
"modal.header.file-detail": "Dettagli",
|
||||
"modal.header.pending-assets": "Risorse rimanenti",
|
||||
"modal.header.select-files": "File selezionati",
|
||||
"modal.nav.browse": "sfoglia",
|
||||
"modal.nav.computer": "dal computer",
|
||||
"modal.nav.selected": "selezionato",
|
||||
"modal.nav.url": "da url",
|
||||
"modal.selected-list.sub-header-subtitle": "Trascina & rilascia per riordinare le risorse nel campo",
|
||||
"modal.upload-list.footer.button.plural": "Carica {number} risorse nella libreria",
|
||||
"modal.upload-list.footer.button.singular": "Carica {number} risorsa nella libreria",
|
||||
"modal.upload-list.sub-header-subtitle": "Gestisci le risorse prima di aggiungerle alla Libreria Media",
|
||||
"modal.upload-list.sub-header-title.plural": "{number} risorse selezionate",
|
||||
"modal.upload-list.sub-header-title.singular": "{number} risorsa selezionata",
|
||||
"modal.upload-list.sub-header.button": "Aggiungi più risorse",
|
||||
"plugin.description.long": "Gestione di file Media.",
|
||||
"plugin.description.short": "Gestione di file Media.",
|
||||
"plugin.name": "Libreria Media",
|
||||
"search.placeholder": "Ricerca risorse...",
|
||||
"settings.form.autoOrientation.description": "Ruota automaticamente l'immagine secondo il tag EXIF di orientamento",
|
||||
"settings.form.autoOrientation.label": "Abilita rotazione automatica",
|
||||
"settings.form.responsiveDimensions.description": "Genera automaticamente formati multipli (large, medium, small) delle risorse caricate",
|
||||
"settings.form.responsiveDimensions.label": "Abilita caricamenti responsive-friendly",
|
||||
"settings.form.sizeOptimization.label": "Abilita ottimizzazioni di qualità (senza perdita di qualità)",
|
||||
"settings.form.videoPreview.description": "Genera una anteprima del video di 6 secondi (GIF)",
|
||||
"settings.form.videoPreview.label": "Anteprima",
|
||||
"settings.header.label": "Libreria Media - Impostazioni",
|
||||
"settings.section.image.label": "IMMAGINE",
|
||||
"settings.section.video.label": "VIDEO",
|
||||
"settings.sub-header.label": "Configura le impostazioni della Libreria Media",
|
||||
"sort.created_at_asc": "Upload più vecchi",
|
||||
"sort.created_at_desc": "Upload recenti",
|
||||
"sort.label": "Ordina per",
|
||||
"sort.name_asc": "Ordine alfabetico (da A a Z)",
|
||||
"sort.name_desc": "Ordine alfabetico inverso (da Z ad A)",
|
||||
"sort.updated_at_asc": "Aggiornamenti più vecchi",
|
||||
"sort.updated_at_desc": "Aggiornamenti recenti",
|
||||
"window.confirm.close-modal.file": "Sei sicuro? I tuoi cambiamenti verranno perduti.",
|
||||
"window.confirm.close-modal.files": "Sei sicuro? Ci sono dei file che non sono stati ancora caricati."
|
||||
}
|
||||
|
@ -1,47 +1,68 @@
|
||||
{
|
||||
"BoundRoute.title": "Percorso vincolato a",
|
||||
"EditForm.inputSelect.description.role": "Questa operazione associerà i nuovi utenti autenticati al ruolo selezionato.",
|
||||
"EditForm.inputSelect.label.role": "Ruolo di default per gli utenti autenticati",
|
||||
"EditForm.inputToggle.description.email": "Non consentire all'utente di creare account multipli usando lo stesso indirizzo email con fornitori di autenticazione diversi.",
|
||||
"EditForm.inputToggle.description.sign-up": "Quando disabilitata (OFF), il processo di registrazione è proibito. Nessuno può iscriversi indipendentemente dal fornitore utilizzato.",
|
||||
"EditForm.inputToggle.label.email": "Un account per indirizzo email",
|
||||
"EditForm.inputToggle.label.sign-up": "Abilita iscrizioni",
|
||||
"BoundRoute.title": "Vincola route a",
|
||||
"EditForm.inputSelect.description.role": "Questa operazione assocerà i nuovi utenti autenticati al ruolo selezionato.",
|
||||
"EditForm.inputSelect.label.role": "Ruolo di default per gli utenti registrati",
|
||||
"EditForm.inputToggle.description.email": "Non consentire all'utente di creare account multipli usando lo stesso indirizzo email con provider di autenticazione diversi.",
|
||||
"EditForm.inputToggle.description.email-confirmation": "Quando abilitato (ON), i nuovi utenti registrati riceveranno una richiesta di conferma via email.",
|
||||
"EditForm.inputToggle.description.email-confirmation-redirection": "Scegli dove redirigere gli utenti che completano la conferma dell'indirizzo email.",
|
||||
"EditForm.inputToggle.description.email-reset-password": "URL della pagina per il reset della password della tua applicazione",
|
||||
"EditForm.inputToggle.description.sign-up": "Quando disabilitata (OFF), il processo di registrazione è proibito. Nessuno può iscriversi indipendentemente dal provider utilizzato.",
|
||||
"EditForm.inputToggle.label.email": "Un solo account per indirizzo email",
|
||||
"EditForm.inputToggle.label.email-confirmation": "Abilita conferma email",
|
||||
"EditForm.inputToggle.label.email-confirmation-redirection": "URL di reindirizzamento",
|
||||
"EditForm.inputToggle.label.email-reset-password": "Pagina reset password",
|
||||
"EditForm.inputToggle.label.sign-up": "Abilita registrazione",
|
||||
"Email.template.email_confirmation": "Conferma dell'indirizzo Email",
|
||||
"Email.template.reset_password": "Reset password",
|
||||
"HeaderNav.link.advancedSettings": "Impostazioni avanzate",
|
||||
"HeaderNav.link.emailTemplates": "Template delle Email",
|
||||
"HeaderNav.link.providers": "Providers",
|
||||
"HeaderNav.link.roles": "Ruoli e permessi",
|
||||
"HeaderNav.link.providers": "Provider",
|
||||
"HeaderNav.link.roles": "Utenti & Permessi",
|
||||
"List.title.emailTemplates.plural": "{number} template per le email disponibili",
|
||||
"List.title.emailTemplates.singular": "{number} template per le email disponibile",
|
||||
"List.title.providers.disabled.plural": "{number} sono disabilitati",
|
||||
"List.title.providers.disabled.singular": "{number} disabilitato",
|
||||
"List.title.providers.disabled.singular": "{number} è disabilitato",
|
||||
"List.title.providers.enabled.plural": "{number} providers sono disponibili e",
|
||||
"List.title.providers.enabled.singular": "{number} provider è abilitato e",
|
||||
"Plugin.permissions.plugins.description": "Definire tutte le azioni consentite per il plugin {name}.",
|
||||
"Plugins.header.description": "Solo le azioni guidate da un percorso sono elencate sotto.",
|
||||
"Plugin.permissions.plugins.description": "Definisce tutte le azioni consentite per il plugin {name}.",
|
||||
"Plugins.header.description": "Di seguito sono elencate solo le azioni vincolate da una route.",
|
||||
"Plugins.header.title": "Permessi",
|
||||
"Policies.InputSelect.empty": "Nessuno",
|
||||
"Policies.InputSelect.label": "Consenti di eseguire questa azione per:",
|
||||
"Policies.header.hint": "Seleziona le azioni dell'applicazione o del plugin e clicca sull'icona cog per mostrare il percorso corrispondente",
|
||||
"Policies.header.hint": "Seleziona le azioni dell'applicazione o del plugin e clicca sull'ingranaggio per mostrare il percorso corrispondente",
|
||||
"Policies.header.title": "Impostazioni avanzate",
|
||||
"PopUpForm.Email.email_templates.inputDescription": "Se non sai bene come usare le variabili, {link}",
|
||||
"PopUpForm.Email.link.documentation": "controlla la nostra documentazione.",
|
||||
"PopUpForm.Email.options.from.email.label": "Email del mittente",
|
||||
"PopUpForm.Email.options.from.email.placeholder": "kai@doe.com",
|
||||
"PopUpForm.Email.options.from.name.label": "Nome del mittente",
|
||||
"PopUpForm.Email.options.from.name.placeholder": "Kai Doe",
|
||||
"PopUpForm.Email.options.message.label": "Messaggio",
|
||||
"PopUpForm.Email.options.object.label": "Soggetto",
|
||||
"PopUpForm.Email.options.object.label": "Oggetto",
|
||||
"PopUpForm.Email.options.object.placeholder": "Conferma il tuo indirizzo email per %APP_NAME%",
|
||||
"PopUpForm.Email.options.response_email.label": "Email di risposta",
|
||||
"PopUpForm.Email.options.response_email.placeholder": "kai@doe.com",
|
||||
"PopUpForm.Providers.enabled.description": "Se disabilitato, gli utenti non potranno usare questo provider.",
|
||||
"PopUpForm.Providers.enabled.label": "Abilita",
|
||||
"PopUpForm.Providers.key.label": "Client ID",
|
||||
"PopUpForm.Providers.key.placeholder": "TEXT",
|
||||
"PopUpForm.Providers.redirectURL.front-end.label": "L'URL di redirect per la tua app di front-end",
|
||||
"PopUpForm.Providers.redirectURL.front-end.label": "L'URL di reindirizzamento per la tua app di front-end",
|
||||
"PopUpForm.Providers.redirectURL.label": "L'URL di reindirizzamento da aggiungere nelle impostazioni dell'applicazione di {provider}",
|
||||
"PopUpForm.Providers.secret.label": "Client Secret",
|
||||
"PopUpForm.Providers.secret.placeholder": "TEXT",
|
||||
"PopUpForm.header.edit.email-templates": "Modifica il template delle Email",
|
||||
"PopUpForm.Providers.subdomain.label": "Host URI (Subdomain)",
|
||||
"PopUpForm.header.edit.email-templates": "Modifica i Template Email",
|
||||
"PopUpForm.header.edit.providers": "Modifica Provider",
|
||||
"PopUpForm.Providers.subdomain.label": "Host URI (Sottodominio)",
|
||||
"PopUpForm.Providers.subdomain.placeholder": "my.subdomain.com",
|
||||
"Settings.roles.deleted": "Ruolo eliminato",
|
||||
"Settings.roles.edited": "Ruolo modificato",
|
||||
"Settings.section-label": "Plugin Utenti & Permessi",
|
||||
"notification.success.submit": "Impostazioni aggiornate",
|
||||
"plugin.description.long": "Proteggi le tue API con un processo completo di autenticazione basato su JWT. Questo plugin è implementato con una strategia ACL che ti consente di gestire i permessi tra i gruppi di utenti.",
|
||||
"plugin.description.short": "Proteggi le tue API con un processo completo di autenticazione basato su JWT",
|
||||
"plugin.name": "Ruoli e Permessi"
|
||||
"plugin.description.long": "Proteggi le tue API con un processo di autenticazione completo basato su JWT. Questo plugin è implementato con una strategia ACL che ti consente di gestire i permessi tra i gruppi di utenti.",
|
||||
"plugin.description.short": "Proteggi le tue API con un processo di autenticazione completo basato su JWT",
|
||||
"plugin.name": "Plugin Utenti & Permessi",
|
||||
"popUpWarning.button.cancel": "Annulla",
|
||||
"popUpWarning.button.confirm": "Conferma",
|
||||
"popUpWarning.title": "Si prega di confermare",
|
||||
"popUpWarning.warning.cancel": "Sei sicuro di voler annullare le tue modifiche?"
|
||||
}
|
||||
|
@ -146,9 +146,17 @@ const normalizeSortClauses = (clauses, { model }) => {
|
||||
}));
|
||||
|
||||
normalizedClauses.forEach(({ field }) => {
|
||||
if (field.includes('.')) {
|
||||
const fieldDepth = field.split('.').length - 1;
|
||||
if (fieldDepth === 1) {
|
||||
// Check if the relational field exists
|
||||
getAssociationFromFieldKey({ model, field });
|
||||
} else if (fieldDepth > 1) {
|
||||
const err = new Error(
|
||||
`Sorting on ${field} is not possible: you cannot sort at a depth greater than 1`
|
||||
);
|
||||
|
||||
err.status = 400;
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -92,7 +92,7 @@ const getPrivateAttributes = (model = {}) => {
|
||||
};
|
||||
|
||||
const isPrivateAttribute = (model = {}, attributeName) => {
|
||||
return model.privateAttributes.includes(attributeName);
|
||||
return model && model.privateAttributes && model.privateAttributes.includes(attributeName);
|
||||
};
|
||||
|
||||
const isScalarAttribute = attribute => {
|
||||
|
@ -1,6 +1,26 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const createService = require('../service');
|
||||
|
||||
const maxLimit = 50;
|
||||
const defaultLimit = 20;
|
||||
|
||||
// init global strapi
|
||||
global.strapi = {
|
||||
config: {
|
||||
get(path, defaultValue) {
|
||||
return _.get(this, path, defaultValue);
|
||||
},
|
||||
api: {
|
||||
rest: {
|
||||
defaultLimit,
|
||||
maxLimit,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
describe('Default Service', () => {
|
||||
describe('Collection Type', () => {
|
||||
test('Creates default actions', () => {
|
||||
@ -62,7 +82,7 @@ describe('Default Service', () => {
|
||||
await service.createOrUpdate(input);
|
||||
|
||||
expect(strapi.entityService.find).toHaveBeenCalledWith(
|
||||
{ populate: undefined, params: { _publicationState: 'live' } },
|
||||
{ populate: undefined, params: { _publicationState: 'live', _limit: defaultLimit } },
|
||||
{
|
||||
model: 'testModel',
|
||||
}
|
||||
@ -95,7 +115,7 @@ describe('Default Service', () => {
|
||||
await service.createOrUpdate(input);
|
||||
|
||||
expect(strapi.entityService.find).toHaveBeenCalledWith(
|
||||
{ populate: undefined, params: { _publicationState: 'live' } },
|
||||
{ populate: undefined, params: { _publicationState: 'live', _limit: defaultLimit } },
|
||||
{
|
||||
model: 'testModel',
|
||||
}
|
||||
@ -130,7 +150,7 @@ describe('Default Service', () => {
|
||||
await service.delete();
|
||||
|
||||
expect(strapi.entityService.find).toHaveBeenCalledWith(
|
||||
{ populate: undefined, params: { _publicationState: 'live' } },
|
||||
{ populate: undefined, params: { _publicationState: 'live', _limit: defaultLimit } },
|
||||
{
|
||||
model: 'testModel',
|
||||
}
|
||||
@ -148,3 +168,22 @@ describe('Default Service', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getFetchParams', () => {
|
||||
test.each([
|
||||
[`0 if _limit is '0'`, { _limit: '0', maxLimit }, 0],
|
||||
['0 if _limit is 0', { _limit: 0, maxLimit }, 0],
|
||||
[`0 if _limit is ''`, { _limit: '', maxLimit }, 0],
|
||||
[`1 if _limit is '1'`, { _limit: '1', maxLimit }, 1],
|
||||
[`${maxLimit} if _limit(500) exceeds max allowed limit (${maxLimit})`, { _limit: '500', maxLimit }, maxLimit],
|
||||
[`${maxLimit} if _limit is set to -1 and max allowed limit is set (${maxLimit})`, { _limit: '-1', maxLimit }, maxLimit],
|
||||
[`${defaultLimit} (default) if no _limit is provided`, { maxLimit }, defaultLimit],
|
||||
[`${defaultLimit} (default) if _limit is undefined`, { _limit: undefined, maxLimit }, defaultLimit],
|
||||
['1000 if _limit=1000 and no max allowed limit is set', { _limit: 1000 }, 1000],
|
||||
])('Sets _limit parameter to %s', (description, input, expected) => {
|
||||
strapi.config.api.rest.maxLimit = input.maxLimit;
|
||||
expect(createService.getFetchParams({ _limit: input._limit })).toMatchObject({
|
||||
_limit: expected,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -9,14 +9,42 @@ const {
|
||||
},
|
||||
} = require('strapi-utils');
|
||||
|
||||
const getFetchParams = params => {
|
||||
/**
|
||||
* Default limit values from config
|
||||
* @return {{maxLimit: number, defaultLimit: number}}
|
||||
*/
|
||||
const getLimitConfigDefaults = () => ({
|
||||
defaultLimit: _.toNumber(strapi.config.get('api.rest.defaultLimit', 100)),
|
||||
maxLimit: _.toNumber(strapi.config.get('api.rest.maxLimit')) || null,
|
||||
});
|
||||
|
||||
const getLimitParam = params => {
|
||||
const { defaultLimit, maxLimit } = getLimitConfigDefaults();
|
||||
if (params._limit === undefined) {
|
||||
return defaultLimit;
|
||||
}
|
||||
|
||||
const limit = _.toNumber(params._limit);
|
||||
// if there is max limit set and params._limit exceeds this number, return configured max limit
|
||||
if (maxLimit && (limit === -1 || limit > maxLimit)) {
|
||||
return maxLimit;
|
||||
}
|
||||
|
||||
return limit;
|
||||
};
|
||||
|
||||
const getFetchParams = (params = {}) => {
|
||||
const defaultParams = {};
|
||||
|
||||
Object.assign(defaultParams, {
|
||||
_publicationState: DP_PUB_STATE_LIVE,
|
||||
});
|
||||
|
||||
return { ...defaultParams, ...params };
|
||||
return {
|
||||
...defaultParams,
|
||||
...params,
|
||||
_limit: getLimitParam(params),
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@ -212,3 +240,5 @@ const createCollectionTypeService = ({ model, strapi }) => {
|
||||
};
|
||||
|
||||
module.exports = createCoreService;
|
||||
|
||||
module.exports.getFetchParams = getFetchParams;
|
||||
|
@ -26,7 +26,7 @@ module.exports = ({ db, eventHub, entityValidator }) => ({
|
||||
|
||||
// return first element and ignore filters
|
||||
if (kind === 'singleType') {
|
||||
const results = await db.query(model).find({ _limit: 1, ...params }, populate);
|
||||
const results = await db.query(model).find({ ...params, _limit: 1 }, populate);
|
||||
return _.first(results) || null;
|
||||
}
|
||||
|
||||
|
@ -165,12 +165,22 @@ describe('Publication State', () => {
|
||||
}, 60000);
|
||||
|
||||
describe.each(['default', 'live', 'preview'])('Mode: "%s"', mode => {
|
||||
test.each(['country', 'category', 'product'])('For %s', async modelName => {
|
||||
const url = `/${pluralizedModels[modelName]}${getQueryFromMode(mode)}`;
|
||||
const res = await rq({ method: 'GET', url });
|
||||
describe.each(['country', 'category', 'product'])('For %s', modelName => {
|
||||
const baseUrl = `/${pluralizedModels[modelName]}`;
|
||||
const query = getQueryFromMode(mode);
|
||||
|
||||
test('Can get entries', async () => {
|
||||
const res = await rq({ method: 'GET', url: `${baseUrl}${query}` });
|
||||
|
||||
expect(res.body).toHaveLength(lengthFor(modelName, { mode }));
|
||||
});
|
||||
|
||||
test('Can count entries', async () => {
|
||||
const res = await rq({ method: 'GET', url: `${baseUrl}/count${query}` });
|
||||
|
||||
expect(res.body).toBe(lengthFor(modelName, { mode }));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Advanced checks', () => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user