Salta al contenuto
KAMOUniverse

Changelog

Cosa c'è di nuovo.

Ogni miglioramento alla piattaforma, come si spedisce.

  1. · kamo-shared-library

    Mostra cosa spegnere fail-open costerebbe

    kamo.entitlement.fail-open concede qualsiasi applicazione il piano matrix non menziona mai. È documentato come una valvola temporanea per il backfill del catalogo — spegnerlo una volta che la matrice è seme — ma nulla può rispondere alla domanda che decide se spegnerlo è sicuro: che gli inquilini tengono che le applicazioni solo a causa di esso. Flipping it blind avrebbe portato le applicazioni lontano da organizzazioni dal vivo, con il primo biglietto di supporto come la notifica. failOpenGrants risolve ogni organizzazione due volte, una volta che rilascia applicazioni non citate e una volta negandoli, e riporta la differenza. Non legge il vivo bandiera, così dà la stessa risposta prima e dopo il capo. La ri-risoluzione passa attraverso risolvePlan piuttosto che il piano id direttamente, rispecchiare la caduta del vero sentiero ad un pianoRicerca di Code — altrimenti una sovvenzione che sarebbe infatti sopravvivere viene segnalato come una perdita.

  2. · kamo-internal

    Mostra se c'è qualcuno e la loro estensione

    Ogni riga ora porta un punto di presenza e una parola accanto al nome, e la sua estensione nella linea di dettaglio — quindi scegliere una persona non significa più scegliere un nome e sperando. Questa è la persona che sceglie nell'app, quindi atterra sul Manager campo, firmatori di e-sign, aggiungendo persone a una chat e assegnando supporto allo stesso modo. L'offline batte tutto ciò che è stato dichiarato. disponibilità status si muove solo sul sign-in, segnale-out e una manovra manuale, quindi qualcuno che non si firma legge a tempo indeterminato — mostrando che come un punto verde sarebbe fiducioso e sbagliato circa una cosa per cui il punto e'. Disegni non collegati come un anello di profilo piuttosto che un punto riempito, quindi si legge come assenza invece di come un altro colore di stato. Una directory che non ha mai portato presenza — una fonte in-memoria dietro `fetcher` — non mostra alcun indicatore affatto. L'assenso è sconosciuto, e sconosciuto non dovrebbe dire nulla piuttosto che affermare che tutti sono offline.

  3. · SecurityService

    Porta disponibilità, presenza e estensione su una riga di directory

    Scegliere una persona è più facile quando la riga dice se sono lì e come raggiungerli, così ognuno ora porta quello che hanno dichiarato, se qualcosa di loro è in realtà collegato, e la loro estensione di lavoro quando ne hanno uno. Disponibilità e presenza sono entrambi qui perché sia da soli errori: disponibilità status si muove solo su sign-in, sign-out e una pratica manuale, quindi un membro che non si firma legge indefinitamente. La presenza viene letta dal PRESENCE: chiave MediaService scrive — un cross-service leggi la pena di nominare. Le alternative erano un viaggio rotondo HTTP a MediaService su ogni tasto di una ricerca, o la presenza di lettura nel browser, e il browser non può: ToolProviders rende lo strumento dock come un fratello del albero che tiene i fornitori di presenza, quindi un raccoglitore aperto all'interno di un biglietto di supporto finestra riferirebbe ogni collega offline. Entrambi i servizi condividono l'host Redis e database. Una ricerca fallita legge come offline, piuttosto che fallire la ricerca.

  4. · BillingService

    Acquistare un blocco quando un org opted-in esaurisce la stanza

    Corre poco dopo lo spazzamento istantanee notturno, perché questo è ciò che produce figura di utilizzo su cui decide — l'espansione contro il numero di ieri comprerebbe un bloccare un giorno in ritardo ogni volta. Un blocco per corsa, mai un colpo di catch-up, e si ferma al soffitto del proprietario. Se un'organizzazione è ben oltre quel soffitto l'esito giusto è che scrive ferma e qualcuno lo guarda, non che la piattaforma tranquillamente compra la sua via d'uscita al loro spese. Auto-expand on senza soffitto legge come disabilitato piuttosto che illimitato, perché un limite assente è molto più probabile che sia una supervisione che un'intenzione.

  5. · InitializerService

    Aggiungere le colonne auto-espand

  6. · kamo-shared-library

    Opt-in auto-espand con un soffitto

    Due colonne sull'abbonamento che contiene i blocchi: se acquistare un'altra uno automaticamente quando l'organizzazione esce dalla stanza, e il massimo può mai comprare. Di default di proposito — silenziosamente aumentare il disegno di legge di qualcuno è peggiore di un upload che non riesce con una spiegazione, quindi accenderlo è il proprietario che commercia poco denaro per non dover mai pensarci, e questo è solo il loro commercio a make. Un soffitto è richiesto piuttosto che facoltativo: un acquisto automatico senza bound è un impegno aperto a un processo che nessuno sta guardando.

  7. · BillingService

    Lascia un cambio di prezzo di catalogo in realtà raggiungere Stripe

    Stripe I prezzi sono immutabili e la mappatura contiene una riga per (org, tipo, codice, ciclo) dietro una chiave unica, quindi una volta che un prezzo esisteva non poteva cambiare. A l'editing dei prezzi era una no-op permanente sulle entrate, e nulla lo ha segnalato. StripePriceReconciler confronta ogni prezzo mappato contro quello che il catalogo ora dice e, quando viene chiesto, indica la mappatura a un fresco Stripe Price con il vecchio un archivio — archiviato piuttosto che cancellato, perché Stripe continua a fatturare un prezzo archiviato per abbonamenti già su di esso e lo rifiuta per quelli nuovi, che è esattamente il comportamento desiderato. Il metro viene trasportato attraverso, quindi un metro prezzo non può tornare non misurato e silenziosamente smettere di fatturazione uso. Non muove deliberatamente gli abbonati esistenti sul nuovo prezzo. Silenziosamente riprendere un cliente dal vivo perché qualcuno ha modificato una riga di catalogo è un addebito nessuno autorizzato; se a nonno loro è una decisione commerciale, e il fatto che non è mai stata una decisione è ciò che mancava. Il conteggio ancora sul il vecchio prezzo viene segnalato invece. Esposta solo per impostazione predefinita al GET************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************ repoint dietro un POST esplicito.

  8. · InitializerService

    Aggiungere le colonne che rendono rilevabile una variazione di prezzo

    Ordine(0), nullable, no backfill — un importo null si legge come "non sappiamo cosa questo prezzo è stato creato con" e il conciliare lo tratta come sconosciuto piuttosto che come la deriva.

  9. · kamo-shared-library

    Registrare ciò che ogni prezzo Stripe è stato creato con

    La mappatura memorizzata solo quale prezzo id da utilizzare, in modo che un cambiamento di prezzo di catalogo potrebbe nemmeno essere notato. garantirePlanPrices cortocircuitato sull'esistenza della riga e la chiave unica perbade un secondo, che significava alzare un piano da $72 a $79 aggiornato la pagina di marketing, il preventivo in-app e il piano DTO e cambiato nulla di ciò che qualcuno è stato accusato — con nulla che segnala la divergenza. unit amount cents e valuta danno al conciliare qualcosa da confrontare. Sia nullable che ha lasciato NULL per le righe esistenti: null significa "non noto", che è vero di ogni riga che predating la colonna, e il trattamento sconosciuto come errato sarebbe ricreare ogni prezzo nella tenuta a prima corsa.

  10. · kamo-internal

    Digitare la capacità di archiviazione il riepilogo ora restituisce

    Mantiene il contratto cliente in fase con BillingService, che ora segnala cosa il piano comprende, quali blocchi sono stati acquistati, il soffitto combinato e frazione utilizzata accanto ai byte memorizzati. Il pannello che lo rende ha bisogno di nuova copia, e kamo-traduzione-dizionario è mid-edit da un'altra sessione, quindi l'UI atterra separatamente piuttosto che spazzare su Il lavoro in volo in quel repo.

  11. · BillingService

    Capacità di report accanto all'utilizzo

    Il pannello di stoccaggio riportato dates immagazzinato contro nulla — nessuna indennità, nessuna percentuale, nessun denaro — quindi un proprietario che guarda 400 GB non aveva modo di dire che fosse comodo o che si fermasse i loro upload. Il primo la conoscenza di un problema sarebbe stato un caricamento fallito. Il riassunto ora porta ciò che il piano include, quali blocchi sono stati acquistati, il soffitto combinato e la frazione utilizzata, più la dimensione del blocco e il prezzo così un superficie può dire che cosa un altro blocco darebbe e costo senza hardcoding esso. Tutto viene dalle stesse righe di catalogo la carica è a prezzo.

  12. · kamo-shared-library

    Dà un effetto all'indennità di deposito

    Lo stoccaggio è stato misurato in diciannove domini, di notte, con un processo di costruzione prova di copertura — e nulla ovunque calcolato un'indennità o rifiutato un byte. La figura di archiviazione del piano era dati che nessuno leggeva, e la conservazione aggiuntiva add-on non ha avuto alcun effetto prodotto affatto: pagare non ha cambiato nulla e non pagare il costo Niente. StorageQuotaService risolve ciò che un'organizzazione può contenere — il piano per utente indennità immatricolata attraverso i suoi sedili, più i blocchi che ha acquistato — e ImageService rifiuta il contenuto che lo supererebbe. L'assegno siede dopo il dedup lookup, in modo da re-attaccare un file la piattaforma già detiene non è mai rifiutato per lo spazio; solo i nuovi byte contano. Vive qui piuttosto che in BillingService perché i servizi che scrivono bytes non può ogni chiamata API fatturazione sul loro percorso di upload, e viene iniettato da campo piuttosto che attraverso il costruttore perché ImageService è assemblato da mano in diversi luoghi — un argomento costruttore è l'unica modifica che compila ovunque tranne i test e poi fallisce la costruzione dell'immagine. Due modi deliberati di sbagliare. "GB" è letto come un gibibyte, che è quello che un file manager significa quando stampa GB e la lettura più generosa. E... organizzazione senza abbonamento in diretta, o un servizio senza contingente bancario, negozi esattamente come prima: questo cancello esiste per tenere un cliente pagante a che cosa hanno comprato, per non trasformare un gap di fatturazione in perdita di dati. Le letture non sono mai cancellate — riempire il vostro deposito smette di aggiungere di più, non toglie mai ciò che avete.

  13. · kamo-internal

    Dite al richiedente se il loro agente è lì

    Un filo silenzioso non distingue "nessuno ha guardato questo" da "il mio agente e la persona che aspetta non può dire quale. Il bando di gara conversazione dice quale, e quando la risposta è "non ora" dice che cosa succede il prossimo — il messaggio è ricevuto e verrà risposto quando torneranno — piuttosto che lasciare qualcuno per chiedersi se è atterrato affatto. Posizionato sotto la chat piuttosto che nell'intestazione perché risponde "è chiunque ", che è la domanda che viene chiesto durante la digitazione, non durante la scansione I metadati del biglietto. Server-risposta, non leggere dalla mappa di presenza del richiedente: la presenza è trasmissione per organizzazione, quindi un membro di customer-org è aiutato dal fornitore org vedrebbe il loro agente in modo permanente offline. "Si sbagliano con fiducia" "è peggio di nessun preavviso. Per lo stesso motivo un sondaggio fallito mantiene l'ultimo risposta nota invece di ribaltare l'avviso. Polled a 30s e solo mentre la scheda è visibile. La disponibilità è un comfort segnale, non una correttezza, e una scheda di sfondo non è nessuno guardare.

  14. · MediaService

    Il ritiro raggiunge il nuovo agente, e il richiedente viene detto chi c'è

    Le dimissioni non hanno raggiunto nessuno. incaricoOpenedAt registra che un cliente ha messo la conversazione sullo schermo, ed è ciò che solleva un biglietto all'ingresso — ma è ancora tenuto il francobollo dell'agente PREVIOUS, quindi il nuovo ha ottenuto la spinta dal vivo solo se sono capitati di essere on-line quel secondo, e nulla se fossero firmato. applichiAssignment ora lo cancella ogni volta che l'aggiudicatario realmente cambia, che rende la consegna durevole per chiunque lo possiede ora. E' il momento giusto. dice la persona che ha chiesto aiuto se la persona che li aiuta è raggiungibile. Risponso lato server di proposito: presenza è trasmesso per organizzazione, quindi un richiedente di customer-org non può vedere un agente in il provider org a tutti e lo stato leggerebbe "offline" per ogni singolo conversazione cross-org. Scoperto alle persone già nella conversazione — un ticket id è un UUID, non un segreto, e "è questa persona alla loro scrivania" non dovrebbe Rispondi a un'ipotesi.

  15. · kamo-internal

    Assegna una richiesta di chat e assegna dall'elenco dei biglietti

    Due lacune, stessa causa — l'assegnazione è stata trattata come qualcosa che accade ad un biglietto piuttosto che a un pezzo di lavoro. Il pulsante di assegnazione è stato nascosto per pre-tickets outright, quindi una richiesta di chat dal vivo, il caso in cui arrivare alla persona giusta conta di più, non aveva modo di essere consegnato a tutti. Tale esclusione è data da quando una richiesta di chat non era ancora "a biglietto reale" e l'assegnazione è avvenuta solo sulla conversione. Ora è assegnabile, e lo stato sopravvive, in modo che possa ancora essere convertito in seguito. E assegnare necessario aprire prima la conversazione, che è la forma sbagliata per triaging una coda — la persona che lavora in coda non è spesso la persona che dovrebbe rispondere. La cella Assegnata nella lista dei biglietti è ora il controllo: hovering mostra assegnare o riassegnare, facendo clic apre lo stesso picker il biglietto usa la finestra. Il clic di riga apre ancora la conversazione. La risposta patch la propria riga piuttosto che ricaricare, quindi assegnare non spostare il posto dell'operatore in una coda filtrata, ordinata e a pagina.

  16. · kamo-internal

    Motore citazione per il picker piano, corrispondente a ciò che Stripe fattura

    L'aritmetica dietro un totale live running, tenuto a parte qualsiasi componente in modo che il i numeri possono essere testati direttamente. Specchio. esattamente: per-seat add-ons scala con testata, quelli piatti fattura per unità acquistate tuttavia molte persone sono sul piano, e quelli misurati sono chiamati piuttosto che indovinato. Quella corrispondenza è il punto. Entrambi i posti della piattaforma precedentemente citato un prezzo non concordato con l'addebito — la procedura guidata in-app ha aggiunto ogni componente aggiuntivo una volta indipendentemente dai sedili, e la pagina pubblica ha fatturato un pool di archiviazione a livello organizzativo per utente.

  17. · BillingService

    Fai un primo piano acquistabile, e restituire i prezzi reali del piano

    Due cose hanno fermato un'organizzazione a comprare un primo abbonamento. Le liste dei piani sono raggiungibili solo tramite il submarketId su un abbonamento già tenuto, quindi un org con nessuno non poteva vedere un piano ovunque nel prodotto. GET /api/billing/markets/for-org risolve il mercato dal caller radice di diritto — lo stesso org il cui piano libero già fornisce la loro linea di base, così i piani e i diritti non possono venire da diversi cataloghi. E il piano dell'OMC ha letto che non c'e' niente. mai popolati: sono NULL per ogni piano KamoCRM, perché il seminatore scrive I prezzi sono in aumento. Una superficie di acquisto quindi mostrato nessun prezzo, e il conto ha registrato una carica nulla. Ora legge il prezzo righe, con le colonne del piano come un fallback per i cataloghi che li portano. Inoltre espone la dimensione dell'unità add-on in modo che una superficie di acquisto può dire "per 10 GB" senza indugio.

  18. · kamo-internal

    Gate ha pagato le azioni su un sedile autorizzato, al punto

    Quasi ogni azione gateable nel prodotto — comporre un'estensione, e-mail un membro, aprire l'assistente AI, suonare una registrazione, avviare una conversazione sociale — è un nudo E il registro degli attrezzi non aveva alcun cancello. Raccogliere quei siti di chiamata uno alla volta non potrebbe mai essere completo: un mittente aggiunto più tardi, o semplicemente perso, percorsi direttamente intorno a esso. L'assegno ora vive ToolWindowsContext unico strumento: aperto handler, così ogni chiamante è coperto. Azioni che non passano mai attraverso una finestra degli strumenti sono gated dove vivono: allegati (compreso drag-drop e pasta, che sono la stessa capacità da un altro percorso), crescendo una chat in un gruppo, e i punti di ingresso meeting. Questo stabilisce anche tre incongruenze dell'audit trovato. Due dei tre "invita a incontrare" punti di ingresso controllati organizzazione. èMeet e il terzo ha fatto no; due dei tre punti di ingresso email controllati ACCESS MAIL e il terzo ha fatto no; e il dialling di un membro di estensione dal roster non aveva controllo VOIP di qualsiasi gentile. Tutti sono d'accordo. Capacità di default a bloccato — mentre il primo carico è in volo, se la chiamata fallisce, e se un vecchio backend omette il campo. Indovinare "consentito" avrebbe dato fuori le caratteristiche pagate, che è l'errore il percorso di diritto già fatto una volta con il suo default non aperto.

  19. · SecurityService

    Risolvere ciò che un membro può fare, non solo ciò che il loro piano include

    Le borse di studio descrivono un piano. Non hanno mai descritto questo membro, perché console gates navigazione su org-level org.features — quindi un membro senza licenza a tutti hanno visto ogni app a cui l'organizzazione aveva diritto, e le licenze che già esistevano nel database non avevano alcun effetto su nulla. MemberCapabilities è quella risposta mancante, risolta una volta sul server. Un membro senza sede mantiene un piano deliberato: conversazione di testo con i compagni di squadra, il sostegno, il proprio profilo, la loro fatturazione — abbastanza per raggiungere un umano e per Ricompra un posto. La traduzione del messaggio in arrivo rimane anche su, perché la lettura che cosa Sei stato mandato non sta spendendo. Tutto quello che costa soldi per scappare è spento. Un org attivo licenza di prova tutti in org piuttosto che solo il sedile titolare. Un org di prova è seme con il sedile singolo del piano libero, quindi gating il prova su licenze avrebbe significato il proprietario da solo potrebbe valutare il prodotto mentre la squadra che hanno invitato a valutarlo non ha visto nulla. Login è intatto: l'autenticazione non ha mai consultato lo stato di fatturazione e ancora No. Perdere un sedile costa funzionalità, non accedere mai.

  20. · BillingService

    Bill per-unit add-ons da unità acquistate, non da headcount

    Filetta la nuova quantità di add-on tramite creare e aggiornare: un componente aggiuntivo FLAT prende la sua quantità Stripe da quello che l'abbonamento effettivamente comprato, quindi quattro 10 GB blocchi di stoccaggio fattura come quattro blocchi piuttosto che una volta per posto. Le quantità sono filtrate contro i codici aggiuntivi risolti sulla strada in, quindi un corpo stale o ostile non può parcheggiare una quantità contro un codice che non aveva diritto per comprare.

  21. · InitializerService

    Riprezzo Deposito supplementare come $2.50 per 10 GB, org-wide

    L'add-on ha descritto una piscina condivisa a livello organizzativo ed è stato quindi valutato USAGE BASED a $4 con "25 GB" dichiarato solo in prosa. Niente mai presentato evento del contatore di stoccaggio, così non ha fatturato nulla; ed era stato attaccato, Stripe respinge una quantità su un prezzo misurato, quindi la creazione di abbonamento avrebbe gettato. Nel frattempo la pagina pubblica lo ha reso "+$4 /user/mese". È ora FLAT con unit size 10 a $2.50 — blocchi il proprietario compra, prezzo stesso tuttavia molte persone sono sul piano. AddOnQuantityMigration aggiunge i due colonne nullable a Order(0), prima che qualsiasi corridore possa caricare un'entità che mappa loro.

  22. · kamo-shared-library

    Dare componenti aggiuntivi una dimensione dell'unità e una quantità acquistabile

    Un'unità aggiuntiva esisteva solo come prosa all'interno della sua descrizione ("Ogni unità aggiunge 25 GB") e come costante codificata nel sito di marketing, in modo che nulla potrebbe Il conto contro di esso. AbbonamentoAddOn guadagni unit size, e AccountSubscription guadagni addon quantities — quante unità di ogni componente aggiuntivo all'abbonamento acquistato. active addon codes rimane la fonte di diritto della verità, così nulla che solo chiede "è questa app concessa" deve sapere che esiste la mappa della quantità. Corregge anche il preventivo della procedura guidata, che ha aggiunto ogni componente aggiuntivo una volta senza sedili fattore anche se la maggior parte sono PER SEAT: un ordine di 25 posti con quattro moduli è stato citato $31 contro il $775 Stripe avrebbe fattura. La citazione ora segue la stessa modello di prezzi che l'accusa fa, e omits metroed add-ons piuttosto che indovinare.

  23. · kamo-internal

    Scegli l'agente per riassegnare un biglietto, invece di digitare il loro ID

    Assegnare e riassegnare ha aperto una casella di testo che ha digitato un membro grezzo in — che significava già conoscere l'id della persona che volevi, per un'azione il cui tutto lo scopo è trovare quello giusto. Ora utilizza MemberPickerDialog, lo stesso raccoglitore dietro il campo Manager su un profilo del membro e quello che la gente sceglie in questa app. La ricerca della directory lato server e corrisponde a nome, alias, email di lavoro e account, titolo di lavoro e dipartimento, quindi "un prestito" trova l'Ana in prestito; ogni riga porta abbastanza a dire a due persone dello stesso nome a parte. L'assegno corrente è bloccato sopra il risultati in modo che non è perso mid-search. Gli ids membri superano l'esatta gamma di integer di JavaScript, quindi il id rimane una stringa da la directory al filo.

  24. · MediaService

    Endpoints per la consegna auto-aperto firmata

    GET /sessions/chat/auto-open restituisce le conversazioni di chat del cliente di questo membro dovrebbe aumentare; POST /sessions/{guid}/auto-opened record che ha fatto. Il durevole controparte del sostegno, e per lo stesso motivo: la decisione appartiene alla piattaforma, non a una scheda del browser sessioneStorage. La scrittura è indirizzata alla riga di appartenenza del chiamante, quindi il cliente di un membro non può mai ritirare il tempo di un altro, e timbri del server piuttosto che un client-fornito valore — il confronto è contro i timestamp del messaggio scritti da questo stesso orologio, e un browser skewed altrimenti o sopprimere una conversazione per sempre o ri-riprenderlo senza fine. ChatAutoOpenHqlTest parses la query contro il modello di entità reale e pins il tre predicati per cui esiste. I dati di primavera convalidano solo @Query al contesto boot, in modo che un typo altrimenti supererebbe come una startup fallita o un 500 su un percorso ogni membro colpisce al sign-in; il test legge la query fuori l'annotazione da riflesso quindi non può passare contro una copia stante.

  25. · kamo-shared-library

    Registrazione durevole di una conversazione che il cliente ha sollevato da solo

    MediaSessionMember guadagna AUTO OPENED AT, accanto a msgIdLastViewed perché è il lo stesso grano — un fatto circa il rapporto di un membro con una sessione. Quella risposte "quanto hanno letto"; questo risponde "hanno già mostrato questo, senza scrupoli". Sostituisce una sessione per-tabbandiera, che non era un record di nulla: un secondo dispositivo riaperto ogni conversazione che il primo aveva già saltato, e Sgomberare lo stoccaggio ha perso completamente il fatto. findChatSessionsToAutoOpen restituisce le sessioni tenendo qualcosa che il membro ha non leggere dove qualcosa è arrivato dall'ultimo rilancio — quindi una conversazione deliberatamente lasciato non letto smette di riaprire su ogni carico ma torna quando un un messaggio veramente nuovo atterra. Solo sessioni di chat; i biglietti di supporto hanno i propri Consegna. I propri messaggi del membro sono esclusi, e un abbagliante msgIdLastViewed puntatore conta come non letto, piuttosto che come catturato, perché una sottoqueria scalare sopra una riga svanita produce NULL e leggerebbe come permanentemente letto.

  26. · kamo-internal

    Respirare il pannello delle preferenze

    Quattro cadute e un interruttore su un pannello lavato superiore a fondo in inquilino colore a piena forza, così ogni controllo ha combattuto il proprio sfondo. Ogni selezionare nascosto tre o quattro opzioni dietro un clic e ripetuto lo stesso dodici linee di stile di confine. Il pannello è una superficie ora, e il colore appartiene a tutto ciò che è selezionato. - Ogni opzione è sullo schermo. Queste sono quattro impostazioni con tre a cinque valori brevi ciascuno; mostrarli è più veloce da usare che aprire un menu, e un componente Scelta sostituisce quattro blocchi di stile duplicato. - Tempo e metodo del mittente condividono una carta, perché non significa niente senza l'altro. Gli offset del reminder sono mono, corrispondenti al resto del il trattamento del calendario del tempo. - Il calendario predefinito mostra il suo colore, quindi è riconosciuto allo stesso modo è nella barra laterale e la finestra di dialogo evento piuttosto che per nome da solo. - L'intestazione rimane messa mentre il corpo scorre — con quattro sezioni il titolo altrimenti scorre via. Queste impostazioni salvano sul cambiamento senza pulsante per premere, e precedentemente detto così con un spinner nudo. C'è ora un esplicito "Saved", che svanisce dopo un paio di secondi perché è una ricevuta per il cambiamento appena fatto, non un stato permanente del pannello. Sezioni incinte e le molle di conferma; entrambi sono soppressi sotto Preferisce-ridotta-mozione. Ogni stringa è una chiave esistente. Verificato con una costruzione di produzione in un pezzo staccato.

  27. · kamo-internal

    Sostituire i giranti della cassetta postale con uno scheletro che si assembla

    Ogni stato di carico su /messages era un Loader2 su un pannello altrimenti vuoto — il boot, l'elenco dei messaggi, l'albero della cartella, il corpo del messaggio e la pagina successiva sculacciata e non ha detto al lettore nulla di quello che stava arrivando. Ora disegnano la cosa che sta caricando. Ogni segnaposto copia la geometria della il componente in cui si trova, fino al 40px avatar, il indent della cartella e la riga di messaggi 104/120px misurata dal markup reale, quindi il layout non muoversi quando i dati atterrano. Un'idea porta il moto: una banda di luci attraversa ogni segnaposto da sinistra a destra e inizia un battito più tardi su ogni riga sottostante, quindi l'evidenziatore scende lo stack come un singolo passaggio diagonale piuttosto che ogni riga lampeggiando sul proprio orologio. Le righe si alzano nello stesso ordine. La luce è mescolata da --accent-comms, l'accento familiare del modulo messaggi, così si legge come questo prodotto piuttosto che una lucentezza generica. preferisce-ridotto-mozione appiattisce l'intera cosa alle barrette. Nessun nuovo messaggio chiavi: i segnaposto si annunciano ai lettori dello schermo attraverso le tre corde di carico che erano già lì.

  28. · kamo-internal

    Aggiungere e rimuovere gli ospiti dalla finestra di dialogo evento

    L'ultima cosa che il dialogo non poteva fare. Potrebbe mostrare chi era già su un evento, ma non c'era modo di mettere qualcuno lì — l'unico controllo degli ospiti era "aggiornamento e notifica", che ri-mail persone che erano già invitati. Gli ospiti vengono aggiunti via e-mail, elencati con il loro RSVP come punto colorato intitolato con lo stato, e rimosso su hover. Inserisci aggiunge un ospite piuttosto che presentando la finestra di dialogo, perché sei mid-list piuttosto che finito. The organizzatore è segnato e non può essere scambiato per un ospite ordinario. La convalida e-mail è volutamente permissiva: il vero test è se la posta a esso rimbalza, e un modello più rigoroso rifiuta indirizzi che sono perfettamente valido. Prende un tipo ovvio, niente di più. Lo stato vuoto invita piuttosto che scusarsi. Strings spedito avanti a questo in kamo-translation-dictionary — prossimo-intl getta su una chiave mancante da en.json e cloni CI di kamo-internal che repo al momento della costruzione, quindi sbarcare questo primo avrebbe spedito una pagina del calendario che si schianta. Verificato con una produzione costruita in un pezzo staccato; un'altra sessione tiene la serratura dell'albero.

  29. · EmailService

    Gestire la lista degli ospiti di un evento

    La finestra di dialogo potrebbe mostrare chi era già su un evento ma mai aggiungere o rimuovere chiunque; l'unica operazione ospite è stata rinotificare le persone che erano in qualche modo già lì. Gli eventi ora accettano una lista degli ospiti, sostituito all'ingrosso su salvare. Sostituire piuttosto che unire, perché la finestra di dialogo possiede l'elenco — un ospite rimosso là deve sparisci qui. Una lista null significa "non fornita" e lascia gli ospiti da solo, che è ciò che un cliente modifica solo un titolo invia. Due cose che un cliente non può affermare, quindi né è letto via richiesta: la RSVP, che è l'ospite da dare, e la bandiera dell'organizzatore, che registra chi ha chiamato l'incontro. Entrambi sopravvivono a una modifica — ricreazione righe invece di aggiornarle resetterebbero ogni risposta e striscerebbero quella persona autorizzata a cancellare l'evento. Gli ospiti tornano in batch. Una vista mese restituisce un centinaio di eventi, e chiedendo per evento è una query per fila. Cancellare un evento ora rimuove i suoi ospiti prima. Portano un nonno chiave straniera di nuovo ad esso, in modo che l'eliminazione o orfano loro o fallito una volta il database ha applicato il riferimento.

  30. · kamo-shared-library

    Ricerca ospite pirata, e delete-by-event

    La finestra di dialogo eventi mostra con chi è un evento, e l'elenco endpoint restituisce un mese di eventi alla volta. Chiedere per gli ospiti per evento è una query per fila; trovareByEventIdIn chiede una volta. deleteByEventId è la prima metà di sostituire una lista degli ospiti all'ingrosso, e di rimuovere un evento senza fila orfano che portano un non-null straniero chiave di nuovo.

Il tuo universo ti sta aspettando.

Aggiungi i prodotti quando sei pronto: nessuna migrazione, nessun nuovo login, nessuna richiesta di pagamento.

Gratis per sempre — nessuna carta di credito richiesta