Merge branch 'master' into upgrade-ra

This commit is contained in:
dklimpel 2023-10-14 21:45:12 +02:00
commit f21764e382
12 changed files with 1063 additions and 204 deletions

View File

@ -10,11 +10,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: 16
node-version: "18"
- name: Install dependencies
run: yarn --frozen-lockfile
- name: Run tests

View File

@ -17,7 +17,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
@ -43,7 +43,7 @@ jobs:
esac
echo "::set-output name=tag::$tag"
- name: Build and Push Tag
uses: docker/build-push-action@v3
uses: docker/build-push-action@v4
with:
context: .
push: true

View File

@ -10,17 +10,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v3
uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: "16"
node-version: "18"
- name: Install and Build 🔧
run: |
yarn install
yarn build
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@v4.4.1
uses: JamesIves/github-pages-deploy-action@v4.4.3
with:
branch: gh-pages
folder: build

View File

@ -13,10 +13,10 @@ jobs:
packages: write
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: "16"
node-version: "18"
- run: yarn install
- run: yarn build
- run: |

View File

@ -17,7 +17,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
@ -43,7 +43,7 @@ jobs:
esac
echo "::set-output name=tag::$tag"
- name: Build and Push Tag
uses: docker/build-push-action@v3
uses: docker/build-push-action@v4
with:
context: .
push: false

View File

@ -1,6 +1,6 @@
dist: focal
language: node_js
node_js:
- 17
- 18
cache: yarn

View File

@ -11,25 +11,26 @@
},
"devDependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^11.2.6",
"@testing-library/react": "^12.1.5",
"@testing-library/user-event": "^14.4.3",
"eslint": "^8.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint": "^8.48.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-prettier": "^4.2.1",
"jest-fetch-mock": "^3.0.3",
"prettier": "^2.2.0"
},
"dependencies": {
"@emotion/react": "^11.7.1",
"@emotion/styled": "^11.6.0",
"@mui/icons-material": "^5.3.1",
"@mui/material": "^5.11.7",
"papaparse": "^5.2.0",
"prop-types": "^15.7.2",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.10.6",
"@mui/icons-material": "^5.14.8",
"@mui/material": "^5.14.8",
"papaparse": "^5.4.1",
"prop-types": "^15.8.1",
"ra-language-chinese": "^2.0.10",
"ra-language-french": "^4.2.0",
"ra-language-french": "^4.13.3",
"ra-language-german": "^3.13.4",
"ra-language-italian": "^3.13.1",
"react": "^17.0.0",
"react-admin": "^4.7.3",
"react-dom": "^17.0.2",

View File

@ -33,12 +33,14 @@ import germanMessages from "./i18n/de";
import englishMessages from "./i18n/en";
import frenchMessages from "./i18n/fr";
import chineseMessages from "./i18n/zh";
import italianMessages from "./i18n/it";
// TODO: Can we use lazy loading together with browser locale?
const messages = {
de: germanMessages,
en: englishMessages,
fr: frenchMessages,
it: italianMessages,
zh: chineseMessages,
};
const i18nProvider = polyglotI18nProvider(

View File

@ -79,6 +79,7 @@ export const ReportShow = () => {
<ReferenceField source="sender" reference="users">
<TextField source="id" />
</ReferenceField>
<TextField source="sender" label="Sender (raw user ID)" />
<TextField source="event_id" />
<TextField source="event_json.origin" />
<TextField source="event_json.type" />

View File

@ -215,7 +215,9 @@ const LoginPage = () => {
_ => {
if (
!formData.base_url ||
!formData.base_url.match(/^(http|https):\/\/[a-zA-Z0-9\-.]+$/)
!formData.base_url.match(
/^(http|https):\/\/[a-zA-Z0-9\-.]+(:\d{1,5})?$/
)
)
return;
const versionUrl = `${formData.base_url}/_synapse/admin/v1/server_version`;
@ -324,6 +326,7 @@ const LoginPage = () => {
<MenuItem value="de">Deutsch</MenuItem>
<MenuItem value="en">English</MenuItem>
<MenuItem value="fr">Français</MenuItem>
<MenuItem value="it">Italiano</MenuItem>
<MenuItem value="zh">简体中文</MenuItem>
</Select>
<FormDataConsumer>

385
src/i18n/it.js Normal file
View File

@ -0,0 +1,385 @@
import italianMessages from "ra-language-italian";
const it = {
...italianMessages,
synapseadmin: {
auth: {
base_url: "URL dell'homeserver",
welcome: "Benvenuto in Synapse-admin",
server_version: "Versione di Synapse",
username_error:
"Per favore inserisci un ID utente completo: '@utente:dominio'",
protocol_error: "L'URL deve iniziare per 'http://' o 'https://'",
url_error: "URL del server Matrix non valido",
sso_sign_in: "Accedi con SSO",
},
users: {
invalid_user_id: "ID utente non valido su questo homeserver.",
tabs: { sso: "SSO" },
},
rooms: {
tabs: {
basic: "Semplice",
members: "Membro",
detail: "Dettagli",
permission: "Permessi",
},
},
reports: { tabs: { basic: "Semplice", detail: "Dettagli" } },
},
import_users: {
error: {
at_entry: "Alla voce %{entry}: %{message}",
error: "Errore",
required_field: "Il campo '%{field}' non è presente",
invalid_value:
"Valore non valido alla riga %{row}. '%{field}' Il campo può essere solo 'true' o 'false'",
unreasonably_big:
"Impossibile caricare un file così grosso (%{size} megabyte)",
already_in_progress: "Un import è attualmente già in caricamento",
id_exits: "L'ID %{id} è già presente",
},
title: "Importa utenti tramite file CSV",
goToPdf: "Vai al PDF",
cards: {
importstats: {
header: "Importa utenti",
users_total:
"%{smart_count} utente nel file CSV |||| %{smart_count} utenti nel file CSV",
guest_count: "%{smart_count} ospite |||| %{smart_count} ospiti",
admin_count:
"%{smart_count} amministratore |||| %{smart_count} amministratori",
},
conflicts: {
header: "Strategia di conflitto",
mode: {
stop: "Stoppa al conflitto",
skip: "Mostra l'errore e ignora il conflitto",
},
},
ids: {
header: "ID",
all_ids_present: "ID presenti in ogni voce",
count_ids_present:
"%{smart_count} voce con ID |||| %{smart_count} voci con ID",
mode: {
ignore: "Ignora gli ID nel file CSV e creane di nuovi",
update: "Aggiorna le voci esistenti",
},
},
passwords: {
header: "Passwords",
all_passwords_present: "Password presenti in ogni voce",
count_passwords_present:
"%{smart_count} voce con password |||| %{smart_count} voci con password",
use_passwords: "Usa le password dal file CSV",
},
upload: {
header: "Input file CSV",
explanation:
"Qui puoi caricare un file con valori separati da virgole che verrà poi utilizzato per creare o aggiornare gli utenti. Il file deve includere i campi 'id' and 'displayname'. Puoi scaricare un file di esempio per adattarlo: ",
},
startImport: {
simulate_only: "Solo simulazione",
run_import: "Importa",
},
results: {
header: "Importa i risultati",
total:
"%{smart_count} voce in totale |||| %{smart_count} voci in totale",
successful: "%{smart_count} voci importate con successo",
skipped: "%{smart_count} voci ignorate",
download_skipped: "Scarica le voci ignorate",
with_error:
"%{smart_count} voce con errori ||| %{smart_count} voci con errori",
simulated_only: "Il processo era stato solamente simulato",
},
},
},
resources: {
users: {
name: "Utente |||| Utenti",
email: "Email",
msisdn: "Telefono",
threepid: "Email / Telefono",
fields: {
avatar: "Avatar",
id: "ID utente",
name: "Nome",
is_guest: "Ospite",
admin: "Amministratore",
deactivated: "Disattivato",
guests: "Mostra gli ospiti",
show_deactivated: "Mostra gli utenti disattivati",
user_id: "Cerca utente",
displayname: "Nickname",
password: "Password",
avatar_url: "URL dell'avatar",
avatar_src: "Avatar",
medium: "Medium",
threepids: "3PID",
address: "Indirizzo",
creation_ts_ms: "Creazione del timestamp",
consent_version: "Versione minima richiesta",
auth_provider: "Provider",
user_type: "Tipo d'utente",
},
helper: {
password:
"Cambiando la password l'utente verrà disconnesso da tutte le sessioni attive.",
deactivate: "Devi fornire una password per riattivare l'account.",
erase: "Constrassegna l'utente come cancellato dal GDPR",
},
action: {
erase: "Cancella i dati dell'utente",
},
},
rooms: {
name: "Stanza |||| Stanze",
fields: {
room_id: "ID della stanza",
name: "Nome",
canonical_alias: "Alias",
joined_members: "Membri",
joined_local_members: "Membri locali",
joined_local_devices: "Dispositivi locali",
state_events: "Eventi di stato / Complessità",
version: "Versione",
is_encrypted: "Criptato",
encryption: "Crittografia",
federatable: "Federabile",
public: "Visibile nella cartella della stanza",
creator: "Creatore",
join_rules: "Regole per entrare",
guest_access: "Entra come ospite",
history_visibility: "Visibilità temporale",
topic: "Topic",
avatar: "Avatar",
},
helper: {
/* forward_extremities:
"Forward extremities are the leaf events at the end of a Directed acyclic graph (DAG) in a room, aka events that have no children. The more exist in a room, the more state resolution that Synapse needs to perform (hint: it's an expensive operation). While Synapse has code to prevent too many of these existing at one time in a room, bugs can sometimes make them crop up again. If a room has >10 forward extremities, it's worth checking which room is the culprit and potentially removing them using the SQL queries mentioned in #1760.", */
},
enums: {
join_rules: {
public: "Pubblica",
knock: "Bussa",
invite: "Invita",
private: "Privata",
},
guest_access: {
can_join: "Gli utenti ospiti possono entrare",
forbidden: "Gli utenti ospiti non possono entrare",
},
history_visibility: {
invited: "Dall'invito",
joined: "Dall'entrata",
shared: "Dalla condivisione",
world_readable: "Chiunque",
},
unencrypted: "Non criptata",
},
action: {
erase: {
title: "Cancella stanza",
content:
"Sei sicuro di voler eliminare questa stanza? Questa azione è definitiva. Tutti i messaggi e i media condivisi in questa stanza verranno eliminati dal server!",
},
},
},
reports: {
name: "Evento segnalato |||| Eventi segnalati",
fields: {
id: "ID",
received_ts: "Orario del report",
user_id: "richiedente",
name: "nome della stanza",
score: "punteggio",
reason: "ragione",
event_id: "ID dell'evento",
event_json: {
origin: "server di origine",
origin_server_ts: "ora dell'invio",
type: "tipo di evento",
content: {
msgtype: "tipo di contenuto",
body: "contenuto",
format: "formato",
formatted_body: "contenuto formattato",
algorithm: "algoritmo",
},
},
},
},
connections: {
name: "Connessioni",
fields: {
last_seen: "Data",
ip: "Indirizzo IP",
user_agent: "agente utente",
},
},
devices: {
name: "Dispositivo |||| Dispositivi",
fields: {
device_id: "ID del dispositivo",
display_name: "Nome del dispositivo",
last_seen_ts: "Timestamp",
last_seen_ip: "Indirizzo IP",
},
action: {
erase: {
title: "Rimozione del dispositivo %{id}",
content: 'Sei sicuro di voler rimuovere il dispositivo "%{name}"?',
success: "Dispositivo rimosso con successo.",
failure: "C'è stato un errore.",
},
},
},
users_media: {
name: "Media",
fields: {
media_id: "ID del media",
media_length: "Peso del file (in Byte)",
media_type: "Tipo",
upload_name: "Nome del file",
quarantined_by: "In quarantena da",
safe_from_quarantine: "Protetto dalla quarantena",
created_ts: "Creato",
last_access_ts: "Ultimo accesso",
},
},
delete_media: {
name: "Media",
fields: {
before_ts: "ultimo accesso effettuato prima",
size_gt: "Più grande di (in byte)",
keep_profiles: "Mantieni le immagini del profilo",
},
action: {
send: "Cancella media",
send_success: "Richiesta inviata con successo.",
send_failure: "C'è stato un errore.",
},
helper: {
send: "Questa API cancella i media locali dal disco del tuo server. Questo include anche ogni miniatura e copia del media scaricato. Questa API non inciderà sui media che sono stati caricati nei repository esterni.",
},
},
protect_media: {
action: {
create: "Non protetto, proteggi",
delete: "Protetto, rimuovi protezione",
none: "In quarantena",
send_success: "Stato della protezione cambiato con successo.",
send_failure: "C'è stato un errore.",
},
},
quarantine_media: {
action: {
name: "Quarantina",
create: "Aggiungi alla quarantena",
delete: "In quarantena, rimuovi dalla quarantena",
none: "Protetto dalla quarantena",
send_success: "Stato della quarantena cambiato con successo.",
send_failure: "C'è stato un errore.",
},
},
pushers: {
name: "Pusher |||| Pusher",
fields: {
app: "App",
app_display_name: "Nome dell'app",
app_id: "ID dell'app",
device_display_name: "Nome del dispositivo",
kind: "Tipo",
lang: "Lingua",
profile_tag: "Tag del profilo",
pushkey: "Pushkey",
data: { url: "URL" },
},
},
servernotices: {
name: "Avvisi del server",
send: "Invia avvisi",
fields: {
body: "Messaggio",
},
action: {
send: "Invia nota",
send_success: "Avviso inviato con successo.",
send_failure: "C'è stato un errore.",
},
helper: {
send: 'Invia un avviso dal server agli utenti selezionati. La feature "Avvisi del server" è stata attivata sul server.',
},
},
user_media_statistics: {
name: "Media degli utenti",
fields: {
media_count: "Numero media",
media_length: "Lunghezza media",
},
},
forward_extremities: {
name: "Invia estremità",
fields: {
id: "Event ID",
received_ts: "Timestamp",
depth: "Profondità",
state_group: "State group",
},
},
room_state: {
name: "Eventi di stato",
fields: {
type: "Tipo",
content: "Contenuto",
origin_server_ts: "Ora dell'invio",
sender: "Mittente",
},
},
room_directory: {
name: "Elenco delle stanze",
fields: {
world_readable: "gli utenti ospite possono vedere senza entrare",
guest_can_join: "gli utenti ospite possono entrare",
},
action: {
title:
"Cancella stanza dall'elenco |||| Cancella %{smart_count} stanze dall'elenco",
content:
"Sei sicuro di voler rimuovere questa stanza dall'elenco? |||| Sei sicuro di voler rimuovere %{smart_count} stanze dall'elenco?",
erase: "Rimuovi dall'elenco",
create: "Crea",
send_success: "Stanza creata con successo.",
send_failure: "C'è stato un errore.",
},
},
destinations: {
name: "Federazione",
fields: {
destination: "Destinazione",
failure_ts: "Timestamp dell'errore",
retry_last_ts: "Tentativo ultimo timestamp",
retry_interval: "Intervallo dei tentativi",
last_successful_stream_ordering: "Ultimo flusso riuscito con successo",
stream_ordering: "Flusso",
},
action: { reconnect: "Riconnetti" },
},
},
registration_tokens: {
name: "Token di registrazione",
fields: {
token: "Token",
valid: "Token valido",
uses_allowed: "Usi permessi",
pending: "In attesa",
completed: "Completato",
expiry_time: "Data della scadenza",
length: "Lunghezza",
},
helper: { length: "Lunghezza del token se non viene dato alcun token." },
},
};
export default it;

829
yarn.lock

File diff suppressed because it is too large Load Diff