Salta al contenuto
KAMOUniverse

Changelog

Cosa c'è di nuovo.

Ogni miglioramento alla piattaforma, come si spedisce.

  1. · kamo-shared-library

    Un dominio viene rivendicato dimostrandolo, non digitandolo

    Tre regole, e hanno solo senso insieme. **Notare un dominio non dice nulla. Un FQDN è stato unico a livello globale qui, quindi il la prima organizzazione ad entrare "acme.com" ha chiuso ogni altro — compreso l'azienda che possiede in realtà acme.com, che poi non aveva affatto modo di entrare. Qualcuno che non ha provato nulla non deve essere in grado di negare un dominio a qualcuno che Può. Le righe duplicate tra le organizzazioni sono ora legali; una ripetizione all'interno di UN l'organizzazione è ancora rifiutata, perché questo è un errore senza significato che un reclamo in competizione. **Solo un dominio verificato percorsi.** findByDomain ora richiede proprietà verified sulla riga di alto livello, quindi un host va all'organizzazione che ha dimostrato il controllo di il suo DNS piuttosto che a chiunque l'abbia digitato prima. Senza questo abbinamento il primo regola sarebbe una porta aperta: rivendicare somebank.com e aspettare. Un alias eredita la sua verifica del genitore — la sfida TXT è emessa solo per l'apice — e che si legge il genitore esplicito si uniscono, mai come d.parent.ownershipVerified, che Hibernate emette come un'unione interiore su tutta la query e cadrebbe ogni fila di apex. **Verifying toglie il dominio da tutti gli altri.** set lo stesso FQDN dov'è tenuto, quindi c'è alla maggior parte di un titolare ad un tempo. Questa non è una cortesia: due righe verificate sono entrambi routable, e il risolutore avrebbe consegnato il traffico a qualsiasi il database restituito prima. An organizzazione che ha verificato un dominio lo scorso anno e ha da allora lasciato che lasso di tempo sarebbe Continua a ricevere la posta di chi lo possiede ora. La verifica DNS del perdente va con esso, perché descrive un nome host che non indica più a loro. Permettere duplicati poi rompe ogni ricerca che ha assunto una riga, e uno di quelli non erano un crash ma un dirottatore: upsertDomain abbinato al dominio NAME e poi riassegnato tutto quello che ha trovato all'organizzazione di chiamata, quindi un upsert avrebbe tranquillamente tolto il dominio di un'altra organizzazione. È organizzazione ora. Il resto — findByDomain, updateSslInfoByDomain, transferDomainOwnership — ha attraversato un unico titolareOf(), che preferisce il riga verificata e altrimenti prende il minimo id, quindi il proprietario di un dominio non può cambiamento tra due richieste. Sinistra come binding facoltativo avrebbero lanciato I dati che lo schema ora permette.

  2. · SecurityService

    Effettuare i default dello schermo a casa per-membro

    Leggi su POST/PUT /security-models e PUT /master-model, emessi da Impostazioni /applied-model in modo che la shell possa decidere dove un membro atterra su "/". Una domanda separataHomeScreenDefaults chiama piuttosto che altri tre posizionali argomenti su un metodo di servizio che già richiede quindici. Le chiavi assurde sono rimaste da solo piuttosto che resettare, quindi un client che pubblica un modello di sicurezza senza sapere su questo campo non può tranquillamente consegnare ogni membro del modello il loro launchpad indietro — o portarlo via. /applied-model normalizza sulla via d'uscita così come in. REQUIRES CHILD ORG OWNERSHIP tiene una schermata iniziale, quindi una colonna nulla su una riga scritta prima di questo spedito, o qualsiasi cosa non riconosciuta, legge come il launchpad. Il cliente è proprio fallback è lo stesso valore, quindi i due non possono essere d'accordo.

  3. · kamo-shared-library

    Un modello di sicurezza dice dove ogni tipo di membro atterra su "/"

    Tre colonne su ChildOrgSecurityModel — DEFAULT MEMBER HOME SCREEN, Non e' vero. DEFAULT ORG OWNER HOME SCREEN. Ciascuna detiene HOME SCREEN DEFAULT o REQUIRES CHILD ORG OWNERSHIP; il secondo blocca il launchpad fino a che il membro possiede un'organizzazione propria. Tre piuttosto che uno perché i tre tipi membri sono tre diversi posti di lavoro: lo stesso modello vuole regolarmente un membro normale spinto a creare il proprio organizzazione mentre i suoi membri del team e proprietari vanno direttamente al lavoro. La scissione specchi APPLIES TO MEMBERS / TEAM MEMBERS / OWNERS esattamente. VARCHAR, non un enum ordinale — un rilabel ordinale ogni riga memorizzata il giorno un terza opzione è inserita ovunque ma la fine. setHomeScreenDefaults è un setter mirato a forma di setAllowRootSubdomains piuttosto che altri tre parametri posizionali su updateModel, che già prende 15. Null significa "lasciare questo solo", quindi un chiamante che sa di uno di i tre non possono ripristinare silenziosamente gli altri. normalzeHomeScreenDefault non riesce OPEN ed è testato per esso: solo la stringa esatta accende il requisito, perché l'alternativa prende la schermata iniziale di un membro e un tipo o un cliente stante non deve mai essere in grado di farlo per caso.

  4. · InitializerService

    Le tre colonne home-screen di tipo per membro su un modello di sicurezza

    CHILD ORG SECURITY MODELS guadagna DEFAULT MEMBER HOME SCREEN, DEFAULT TEAM MEMBER HOME SCREEN e DEFAULT ORG OWNER HOME SCREEN. Ciascuna detiene HOME SCREEN DEFAULT (la scheda di lancio) o REQUIRES CHILD ORG OWNERSHIP, che lo tiene fino a quando quel membro possiede un'organizzazione propria. La clausola DEFAULT è la parte portante, non la ADD COLUMN. Le colonne sono NON NULL e la tenuta non è vuota, quindi il default è quello che si ricarica ogni il modello di sicurezza esistente nella stessa dichiarazione — ed è deliberatamente il valore permissivo, perché inadempienza l'altro modo porterebbe via il launchpad da ogni membro di ogni modello il momento in cui questo ha funzionato. Ordine(0) per la ragione abituale: l'entità condivisa-libraria che trasporta questi campi è caricato da ogni servizio Java, quindi un corridore precedente sarebbe morto su "colonna non esistere" prima che una migrazione tardiva fosse mai raggiunta. Le dichiarazioni SET NON NULL riparano il caso in cui il ddl-auto di Hibernate ha creato le colonne prima, dalla colonna dell'entitàDefinizione, senza il vincolo. Ognuno è preceduto dal proprio UPDATE null-clearing, perché SET NON NULL è rifiutato mentre qualsiasi riga detiene ancora un null — i perni di prova che ordinano.

  5. · kamo-internal

    Una lista di ciò che la scansione ha trovato, accanto a quello che si sta utilizzando

    La sezione di marca di /network/create diventa tre bande con la stessa forma: quello che il tuo sito ha a sinistra, quello che la tua organizzazione sta usando a destra. Logos. C'era una volta per essere TWO rails sopra gli stessi candidati, uno per slot, classificato in modo diverso — quindi una società con quattro loghi sembrava avere otto, e la domanda è stata messa nella direzione sbagliata. Un membro non guarda una rotaia e chiede "che di questi è il mio logo completo"; essi guardano il loro marchio e dicono "che uno è quello pieno». Quindi è una lista dei loghi del sito, ogni riga che trasporta entrambi destinazioni — Impostare come pieno, Impostare come semplice — e ogni riga contrassegnata vettore o immagine, perché questa è l'unica cosa di un file di logo che non si può vedere guardandolo e l'unica cosa che la semplice slot si preoccupa. Marcato, mai filtrato: nascondersi rasters dal semplice slot ha nascosto il proprio logo dell'azienda su esattamente i siti La scansione ha funzionato meglio. La lista si avvia con frecce su / giù e dice quanti ci sono, quindi "è il mio logo qui" è rispondebile guardando. I retroterra. La procedura guidata di dodici fasi ha raccolto carte da parati firma e la riscrittura di una pagina li ha lasciati; la scansione era già trovare l'eroe di una società immagini e poi offrendo da nessuna parte per metterlo. Stessa banda: immagini scansionate sulla sinistra, carica e l'ordine in esecuzione a destra, con la scelta del watermark qui sotto una volta c'è qualcosa da timbrare. I colori sono adottati piuttosto che offerti. Una scansione finita imposta la coppia trovata, e i raccoglitori rimangono in diretta. Le guardie sono tutto il rischio, quindi sono pure e testato in scanAutoApply.ts: una volta per risultato di scansione, e mai sopra un colore creatore ha toccato — compreso per una successiva scansione di un sito diverso. Anche qui: - "Chi è per" è completamente assente, voce inclusa, fino a quando non c'è qualcosa per rispondere. Stava rendendo una carta vuota prima che un tipo fosse scelto, e di nuovo per i modelli che regolano ogni domanda di conformità stessi. - L'anteprima dal vivo mostra il logo FULL, in alto a sinistra dell'area contenuti sopra la mock text, dove uno schermo di accesso lo mette. La barra sopra è la navigazione bar e mostra il segno — e le due slot sono facili da mescolare, quindi l'anteprima è l'unico posto in cui un creatore può dire quale hanno riempito. - "Il logo Compatto" è "il logo semplice" ovunque si legga, qui e nel Ottenere Ho iniziato il mago. Gli identificatori interni sono lasciati soli. - "Nome breve" è "Nome di organizzazione (versione breve)". - Il sito dice chiaramente che non ne hai bisogno, piuttosto che lasciare l'assenza di un asterisco rosso per portare il messaggio.

  6. · kamo-internal

    Una schermata iniziale predefinita di tipo per membro

    Un modello di sicurezza ora dice dove ciascuno dei suoi tre tipi membri atterra quando essi aperto "/". Due valori: HOME SCREEN DEFAULT è il launchpad che tutti hanno sempre aveva, e REQUIRES CHILD ORG OWNERSHIP lo trattengo finché quel membro non possiede un organizzazione del proprio — "/" va a /network/creare invece, e organizzazione-network link lascia la barra superiore fino a quando non hanno uno. Tre colonne piuttosto che una, specchiando APPLIES TO MEMBERS / TEAM MEMBERS / OWNERS, perché lo stesso modello vuole di routine un membro normale spinto in creare la propria organizzazione mentre i suoi membri del team e proprietari vanno al lavoro. La regola è pura e testata in app/lib/homeScreenGate.ts: quale colonna si applica, e cosa conta come possedere un'organizzazione (un proprietario dell'org sono già dentro non ha creato uno — la stessa esclusione FirstOrgCta fa). fallisce. OPEN ad ogni passo. Solo la stringa esatta chiude il cancello; una colonna nulla, una valore non riconosciuto, un fetch modello applicato fallito e una mynetworks non raggiungibile tutti leggono come "no", perché portare via lo schermo di casa di qualcuno sulla forza di una richiesta che non ha risposto non è qualcosa da fare. Un contesto, montato sopra i nav e la pagina, piuttosto che il gancio in entrambi luoghi: NavTop e il launchpad hanno bisogno della stessa risposta su ogni carico di pagina, e due copie costerebbe due viaggi rotondi e potrebbe non essere d'accordo per la lunghezza di uno. Il launchpad deliberatamente non aspetta su di esso — tenendo la casa di ogni membro pagina dietro un /applied-model fetch per risparmiare una manciata di loro un breve flash è il commercio sbagliato.

  7. · kamo-internal

    Crea il mio gratis Org diventa un widget di tre fasi

    Il widget ha incorporato l'intero di CreateOrgForm — cinque sezioni, il marchio anteprima, il misuratore di disponibilità — che è circa 1400px all'interno di un riquadro di circa Le righe di HomeGrid sono minmax (unità, auto), e che `auto` è una valvola di sicurezza piuttosto che un soffitto, quindi un pannello il cui contenuto non può ridurre la fila: il "widget" reso come una forma lunga giù la pagina. Ora è il percorso veloce che è stato sempre descritto come. Tre passi — tipo, nome e indirizzo, recensione — chiedendo solo i campi che bloccano effettivamente una creazione e l'invio tutto il resto esattamente come aWizardFormData ha sempre mandato per un creatore che Ho saltato quei passi. Branding, app e conformità sono completati in seguito Il nuovo org sta iniziando il mago. /network/create è invariata e chiede ancora tutto davanti. Il passaggio tipo è una RICERCA, non una griglia di carta. Nel layout denso del widget la griglia è una carta per fila, quindi un inquilino con trenta tipi di ramo è diciottocento pixel di carte — il tratto, di nuovo, e peggiora quando la piattaforma cresce. La ricerca rende il passo un'altezza fissa a quattro tipi o trecento. Anche qui: - WidgetFrame prende un maxHeightPx opzionale, e questo widget passa il proprio riquadroHeightPx(halfRows), quindi il pannello è la dimensione che il membro ha dato e rotazioni piuttosto che crescere. Opzionale, quindi nessun altro widget cambia comportamento. WidgetComponentProps guadagna metàRows per rendere possibile. - L'anteprima alias ora legge KamoCRM.com/o/hyalias> su entrambe le superfici che mostrano esso, attraverso un aiutante invece di ogni edificio la stringa stessa. DISPLAY SOLO — il routing è da hostname e non c'è /o/ route, quindi workspaceUrl e /api/org/current sono deliberatamente intatti e un lancio continua interno. Un dominio personalizzato mostra ancora come se stesso. - Il /branch-types/creatable fetch e la sua parsing si spostano in un modulo condiviso e gancio, poiché entrambi i tipi-pickers ne hanno bisogno e porta anche il genitore contesto sottodominio-branch. Che stabilisce una duplicazione live: OrgTypePicker costruito BranchTypeData due volte e le due copie erano già alla deriva su array coercion. - workspaceUrl si allontana da CreateOrgForm in modo che il widget possa costruire uno spazio di lavoro link senza importare l'intero modulo di pagina. - successivo/link per il salto "apri la pagina completa". check-client-navigation ha mancato il ancoraggio crudo perché il suo regex ha bisogno di <a e href su una linea. Guardie, tsc e 4.039 test verdi; chiavi del dizionario spinta prima.

  8. · kamo-internal

    Avviare la scheda sulla pagina di atterraggio Impostazioni

    Aggiunge una scheda di gruppo essenziale che collega a /settings/wizard, corrispondente al makeCard idiom utilizzato dai suoi fratelli. Tasti dizionario già spinto E' il momento giusto

  9. · kamo-internal

    A SEND TO AI accendere il modulo di relazione

    Allineato a destra sulla riga "Cosa stai segnalando?", ogni volta che la finestra si apre — inizia una sessione su una macchina che tiene le credenziali del cluster e interruttore che ha ricordato la sua ultima posizione avrebbe eventualmente inviare qualcosa nessuno Volevo mandare. Inviare con esso su mani il rapporto direttamente sopra: In progresso, e letto dall'operatore che l'ha mandato. Disegnato solo per un titolare di MANAGE SYSTEM BUGS, letto dal server-risolto PlatformRightsContext — checkRight è la spina dorsale dei diritti TENANT e non può rispondere per una piattaforma proprio a tutti, quindi chiedere che avrebbe nascosto l'interruttore da ogni amministratore della piattaforma. Questo è cromo in entrambi i modi: SecurityService siede sotto un livello di classe @RequirePlatformRight e rifiuta chiunque altro con un 403. La richiesta porta un bug id e NOTHING ELSE. Il modulo non ha una casella di richiesta, no modello picker e nessun raccoglitore di screenshot, quindi il server li sceglie tutti; assemblare un payload qui avrebbe messo quelle scelte nel browser, dove membro che tiene il diritto potrebbe modificarli. La consegna viene eseguita dopo gli upload, non accanto a loro — la spedizione legge qualsiasi cosa sia attaccata al momento della sua esecuzione, e una sessione iniziata presto sarebbe lavorando da mezzo rapporto. Una spedizione che non si applica ancora il suo stato, quindi il rapporto è In Progress quando il pulsante viene premuto di nuovo e un reporter può solo modificare uno che è ancora Nuovo: la finestra ricorda quello che ha scritto e salta la riscoperta ridondante, o la riprovazione riferirebbe che un rapporto salvato potrebbe non essere salvato e non riattribuire mai la cosa che effettivamente fallito.

  10. · SecurityService

    Invia a AI direttamente dal modulo di rapporto

    Un titolare di MANAGE SYSTEM BUGS ottiene un SEND TO AI accendere il Report Bug finestra, e presentare con esso sulle mani il rapporto a una sessione senza finestra di dialogo tra. Il nuovo endpoint non prende nessuno e questo è il punto. Il modulo non ha alcun prompt scatola, nessun picker modello e nessun raccoglitore di screenshot, quindi l'istruzione, il modello, lo sforzo, gli screenshot e lo stato sono ognuno di loro scelto qui — un chiamante oltre il cancello non può esprimere nulla il dialogo non poteva, che fa l'interruttore strettamente più stretto della superficie in cui si trova. Poi va attraverso la spedizione() invariata, quindi l'acceleratore, la riga di audit scritta prima chiamata di rete, e il controllo di proprietà dello screenshot sono gli stessi, non un secondo copia per tenere in passo. Guardiata dal livello di classe. la finestra di dialogo già seduto. La console nasconde l'interruttore da tutti gli altri, ma che è cromo: un rapporto presentato con la bandiera da un membro senza la destra è rifiutato con un 403 qui e non raggiunge sessione. "Already visto" è un fatto per membro e non può essere scritto per tutti — PlatformRightsResolver risponde "questo membro lo tiene", mai "chi lo tiene". Così la lettura è registrata per l'operatore che ha chiesto la spedizione, prima del chiamata di rete piuttosto che dopo di esso (può richiedere due minuti e può fallire), e IN PROGRESS è ciò che toglie il rapporto dal nuovo badge di ogni altro manager.

  11. · kamo-internal

    Avviare la procedura guidata di configurazione a /settings/wizard

    Trasforma i nove passi della procedura guidata spostati in un editor sopra l'organizzazione il membro è già firmato. Ogni passo ora semi il suo valore da live org dati (usoOrgContext, GET /api/security/org/{id}, /api/security/feature, o useAppliedModel come appropriato) e salva al punto finale che già possiede che l'impostazione su "Salva e continua"; "Skip this step" registra progressi senza scrittura. - orgSettingsSave.ts: tipi di payload per passo (StepSavePayloads) e un generico saveStep (chiave, orgId, valore) invio, digitato senza `never`/`any`. - orgDetails.ts: fetch condiviso per i campi di org il thin theming La classe organizzativa non porta (contatto, etichette, descrizione, ecc). - wizardSteps.tsx / StepRail.tsx / page.tsx: il tavolo passo, il sempre- guida cliccabile, e la shell (BrandScanProvider, inerte durante i risparmi). - IdentityStep gocce E' il momento giusto. controlli — quelli sono Impostazioni — > Domains/Behavior & Etichettatura territorio ora. - BackgroundsStep tracce esistenti + nuove slot insieme, dal /backgrounds/commit sostituisce l'intero ordinamento e commette solo nuovi i file avrebbero cancellato lo slideshow esistente di un'organizzazione. - complianceWizard.ts: amplia il parametro ComplianceStepUi al cinque campi in realtà legge, così la fase di Compliance può chiamarlo con useAppliedModel impostazioni invece di un cre-time BranchTypeData. - api.ts: buildCustomLabels esportato per il riutilizzo da parte del risparmiatore di etichette.

  12. · kamo-internal

    L'eroe /copilota ed entrambi i codici di scansione portano anche il segno di camaleonte

    erano gli ultimi due siti, e non poteva semplicemente prendere il nuovo src invariato, perché l'opera è una silhouette trasparente 127x102 dove il raster era un quadrato opaco. CopilotHero. `objectFit: coprire` ritaglierebbe il muso da entrambi i lati del quadrato piastrelle, quindi il segno è `contenuto`ed all'interno di un involucro di inset — `fill` si risolve contro la scatola di imbottitura, così l'inset non può vivere sulla piastra stessa. La piastra anche guadagna un riempimento traslucido: usato per essere l'icona, e uno non riempito lascia il confine e l'ombra di goccia che non delinea nulla. QrFrame, entrambi i codici. Due correzioni: - Il marchio è bianco, e un codice QR è stampato su bianco. Come spedito era un logo invisibile seduto in un buco tirato fuori dal codice. `Brightness(0)` sul emesso <image> lo spinge a nero e lascia i busti trasparenti. Ha per essere CSS — immagineImpostazioni rende un <image href> e un SVG esterno richiamato questo modo è un documento isolato che non eredita colore. - 48x39, non 48x48. elemento, così la scatola è il rapporto di aspetto e un quadrato ha schiacciato il segno. The scatola più stretta inoltre riduce il foro scavato a ~ 2,9% del codice, sotto il 3,5% era prima e lontano dentro che livello M può perdere e ancora la scansione. Verificato rendendo QRCodeSVG con questi oggetti esatti e rasterizzandolo: il marchio legge chiaramente al centro e lo scavo non sgombera nessun modello di ricercatore. Entrambi i codici, non solo Installare — sono una cornice condivisa su una piastra bianca condivisa, e i propri documenti di QrFrame dicono di resistere allo styling o call site individualmente.

  13. · kamo-internal

    Scambiare il marchio mobile-app per il camaleonte SVG nella rotaia e sulla casa

    raster. Entrambi ora disegnano l'opera KamoMobileApp come vettore. Controllato come SVG perché questo è ciò che il marchio è: una singola silhouette bianca con Tossiture trasparenti. Passato attraverso svgo a 2-decimale precisione prima, che è senza perdite per la geometria di questa traccia ma prende il file da 675 KB a 106 KB (~23 KB sopra il filo una volta compresso) — l'esportazione ha trasportato sei decimali su ciascuno di - 5k segmenti di traccia. Due cose NON portano indietro dal raster: - La scatola. Il viewBox è 127x102, quindi una larghezza/altezza quadrata lo schiaccia. Ciascuno di i tre siti di chiamata ottiene una scatola di 127:102 dimensioni per mantenere l'altezza ottica del glifo dove era il PNG imbottito. - ottimizzazione successiva/immagine. `unoptimized` su tutti e tre: / next/image non può rivenditample vettoriale, quindi senza di essa la richiesta è un viaggio rotondo che consegna gli stessi byte. CopilotHero e il centro QR utilizzano ancora icon.png alle loro dimensioni; il raster rimane.

  14. · kamo-internal

    Crea il widget My Free Org

    Nave lo stesso CreateOrgForm la pagina /network/create renders, nella sua layout widget, come widget home-launchpad (org.create) gated on CREATE FREE ORG WIDGET. Registrato ultimo: è un invito in piedi, non un riquadro temporale-critico. Nessun cancello — creare un'organizzazione non è una app, e i cinque diritti sono l'intera decisione. Specchi anche CREATE FREE ORG WIDGET e i suoi quattro bambini politici in la gerarchia dei diritti TS mantenuti a mano (205 -> 210 bordi), che widgetPolicy.test.ts's cinque-destra-shape affermazioni richiedono per ogni widget registrato.

  15. · KlusterServices

    Apri Invia a AI in una scheda di sessione del codice VS, non una finestra di Konsole

    Una spedizione ora inizia una sessione BACKGROUND e le mani Codice VS sua sessione id, invece di eseguire il CLI in una finestra terminale: Passare il prompt all'URI invece è una trappola: l'estensione chiama setInputText e mai invia, e la sintesi di un Ritorno è impossibile mentre il L'armadietto KDE tiene la sua presa X. Una sessione che è ALREADY RUNNING non ha più nulla presentare, che è ciò che rende il handoff lavorare con nessuno alla macchina. Quattro cose misurate piuttosto che ragionate su: - cwd deve essere realpath(workspaceFolders[0]), NON il genitore comune che questo usato prima. Il pannello ospitante si radica alla prima cartella e elenca solo le sessioni che trova lì, così una sessione iniziata in qualsiasi altro luogo è invisibile la finestra è destinata ad aprire in — il handoff apre una scheda vuota. L'altro i repository rimangono raggiungibili tramite --add-dir invece. --add-dir è VARIADIC e stava mangiando il prompt, così le sessioni sono arrivate con un compositore vuoto. La lista di directory ora va prima, chiusa dalle bandiere dopo di esso. - Un lancio può stampare nessuna maniglia, o uno contrassegnato "(idiota — inviare un prompt per iniziare)". Entrambi significano che il messaggio non è mai arrivato, quindi entrambi sono fermati e rimessi piuttosto che aperto davanti all'operatore come scheda vuota. - Il pannello non può possedere un agente di fondo, e uno finito rimane residente, quindi un guardiano lo ferma una volta che il lavoro è fatto. Riaprire la scheda quindi riprendere il sessione normalmente, intera conversazione intatta. La conferma è ora la trascrizione affrontata da id sessione, che rimuove il JSON-escaped-needle ricerca che ha riferito spedito spedizioni come guasti.

  16. · kamo-internal

    /network/create è una pagina; i dodici passi si spostano a /settings/wizard

    CreateOrgForm.tsx è un componente con due layout (pagina/widget), costruito da Task 7/8 CreareOrgFields modello, gruppi di campo e OrgBrandPreview. page.tsx è ora solo Conchiglia di larghezza piena intorno a esso. Il vecchio mago di nove file passo più Stepper/stepIcons spostare a app/settings/wizard, dove Task 12 li ricollega alla configurazione Iniziata Wizard; BranchTypeStep, MemberInfoStep, ReviewStep, StepNavigation, CancelModal e sessionStorage-backed useWizardForm gancio sono in pensione outright, dal momento che un creato di una pagina ha nessun passo per navigare tra e nulla lasciato per salvare una bozza di. Ogni importazione relativa nei file spostati che hanno indicato ../ui/*, ../brandscan/*, .././types, .././validazione, ../././appSelezioni, .././complianceWizard o .././hooks/* è riscritta l'assoluta @/app/network/create/... form, poiché componenti/ui e componenti/brand possono rimanere put (i componenti del campo sopravvissuti ancora li usano) e risolvere solo una directory in su vecchia posizione. hooks/useWizardForm.ts è tagliata piuttosto che eliminata: tests /submitWizard.test.ts importazioni frescoWizardData da esso e deve rimanere verde e unedited, quindi il file mantiene che una esportazione (e il DATI INIZIALI ha bisogno) e cade tutto il resto che non ha più un chiamante. Due correzioni di correttezza trovate in recensione prima di collegare i componenti del campo: - CreateOrgForm's onChange è ora fondamentalmente stabile tra i renders (requestScan read through a ref invece di un usoCallback dipendenza) — OrgTypePicker e IdentityFields ogni elenco suChange in un usoEffect Dependency array, e richiedi modifiche di identità di Scan su ogni marchio completato scansione, che avrebbe re-fire entrambi gli effetti su ogni scansione piuttosto che solo su reali cambiamenti di input. - DropZone prende un vero e proprio prop disabile (tabIndex=-1, gestori custoditi, nativo disabilitato sul suo file pulsante input e fallback) invece di affidarsi solo a un antenato puntatore-events-none, che non fa nulla per l'attivazione della tastiera; cablato attraverso le slot del logo di BrandFields in modo da una forma bloccata in realtà blocca anche gli utenti della tastiera. /network/create?fresh=1 diventa normale /network/creare in FirstOrgCta.tsx e network/page.tsx: il modulo di una pagina inizia da inizialeCreateOrgFields() su ogni supporto piuttosto che ripristinare un sessionStorage Draft, quindi il param non ha più niente da fare.

  17. · kamo-internal

    Gruppi di campo riutilizzabili e l'anteprima live del marchio

    Estrae gli input da BranchTypeStep, BasicsStep, LogoStep, ColorsStep, AppsStep e AgeRestrictionsStep in cinque componenti di campo controllati (OrgTypePicker, IdentityFields, BrandFields, AppSwitches, ComplianceFields) che sia /network/create-as-one-page e il widget di launchpad può rendere, lasciando il passo di inquadratura (intestazione, saltare pulsante, navigazione) dietro. Aggiunti OrgBrandPreview, un marchio live in miniatura guidato da anteprimaPalette(), che schema-controlla qualsiasi colore autorizzato dal creatore prima di raggiungere uno stile attributo e ricade sulle variabili CSS della piattaforma. IdentityFields e OrgTypePicker sono stati regolati mid-task per il ****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** parallelo: OrgTypePicker ora cattura il subdominio-branch del genitore org contesto accanto al tipo di ramo, e IdentityFields consulta webAliasPossible() invece di ri-deriving esso, offrendo il percorso web-alias solo quando è veramente disponibile. Il compito 8 della missione e'... Piano.

  18. · kamo-internal

    Avviare il pulsante Configurazione guidata con un bordo di attenzione

    Aggiunge il punto di ingresso del launchpad nella procedura guidata di configurazione: un proprietario-solo, diritti-gated pillola che legge "Getting Started Configuration Wizard (x/9 step complete)", posto prima nella fila delle pillole davanti ai miei Widget. Responsabili nulli fino al titolare + diritto + caricato-sommario + cancello non finito si risolve, quindi non lampeggia mai per un proprietario il cui organizzazione già finito la configurazione. Il confine porta un continuo conico-gradiente sheen più un box-shadow respiratorio nel proprio --colore-primario, e smette di animare (mentre rimanendo visibilmente due toni) sotto la preferenza-ridotta-mozione.

  19. · kamo-internal

    Avviare mago passo modello e client

    Aggiunge il modello passo lato client (app/lib/orgSetupWizard.ts), una API sottile client per GET/PUT/DELETE /api/security/org-setup-wizard (app/lib/orgSetupWizardApi.ts), e l'usoOrgSetupWizard gancio che il la pagina guidata e il pulsante di avvio si costruiranno entrambi. Una logica pura in app/lib piuttosto che accanto alla pagina perché app/settings/** e app/hooks/** non sono in vitest incluso consentlist. èWizardFinished è deciso esclusivamente dal server completatoA latch, non contando i passaggi completati, quindi il pulsante di avvio rimane andato per un organizzazione che già finito anche dopo la lista passo cresce. normalzeSummary è totale sopra input sconosciuto e gocce passo chiavi il il cliente non riconosce. useOrgSetupWizard mantiene `caricato` separato da `summary` in modo che il pulsante di avvio non renda nulla fino alla risposta reale è conosciuto.

  20. · SecurityService

    Aggiungi servizio di avanzamento e endpoint dietro la procedura guidata

    GET/PUT/DELETE in /api/security/org-setup-wizard traccia che dei nove Iniziare i passi che un'organizzazione ha completato. Una lettura non crea mai una fila, e completatoAt è un set di chiavistello memorizzato una volta quando l'ultimo passo eccezionale atterra - sopravvive sia incompleto un passo e la lista dei passi in crescita più tardi, quindi un'organizzazione finita pulsante launchpad non riappare mai.

  21. · kamo-internal

    Il pannello massimizzato zoom nella conversazione che hai scelto

    Cambiare le conversazioni nella vista massimizzata era un nudge 8px e una dissolvenza di 180ms — abbastanza vicino a nulla che il pannello sembrava semplicemente riverniciato. Ora legge come arrivare da qualche parte: la conversazione in arrivo arriva dal 6% sotto le dimensioni con un breve aumento e atterra nel pannello, opaco presto quindi è leggibile mentre è ancora in movimento, su una curva che passa la maggior parte del suo viaggio avanti e poi si stabilisce. La forma è dettata dalla z-stack piuttosto che scelta. Fare clic su una riga navigatore si concentra la nuova finestra, quindi l'ingresso è dipinto sopra l'uscita, e che decide entrambi: - L'incoming può crescere nel pannello, ma non superarlo mai. Il guscio massimizzato è un elemento fisso la dimensione del viewport e niente qui pins il documento's overflow, quindi un arrivo che supera 1 vernici al di fuori del viewport. - L'outgoing ha una dimensione piena e svanisce. Mentre l'ingresso è ancora sotto scala non copre il pannello e l'uscita è l'unica cosa dietro esso, così restringendo che troppo aprirebbe un cerchio di sfondo intorno a una finestra MAXIMIZED — un flicker, non profondità. È libero di svanire perché l'ingresso è opaco sopra di esso molto prima che se ne vada. Quella regola di copertura è aritmetica, non gusto, quindi è un test: la dissolvenza in uscita deve fuori dall'ingresso. Altri due pin i vincoli che sono invisibili fino a quando non sono pausa — l'arrivo non scala mai oltre 1, e finisce all'interno della fase di swap, che ritira il ruolo e altrimenti lo ritarda a metà volo. Il movimento ridotto mantiene il semplice crossfade. Per inciso corregge una cosa più piccola: l'arrivo era di 200m all'interno di una fase di 180ms, così è stato consegnato l'obiettivo di sistema 20ms prima che finisse.

  22. · kamo-internal

    Widget a tre colonne e dimensioni minime per-widget

    Widens WidgetWidth a 1 | 2 | 3 | 'full' e permette un WidgetDefinition dichiarare minWidth/minHeight. widgetMinSize(definizione) converte che in un pavimento PaneSize (o null quando nulla è dichiarato), dando entrambi asce un pavimento anche quando solo uno è dichiarato — l'asse non dichiarato pavimenti a proprio formato predefinito. Filetti che il pavimento dal registro attraverso ogni consumatore che dimensioni o ridimensiona un pannello: utilizzareHomePanes' SizeOf/setSize, trascinamento di PaneChrome tastiera ridimensionare i percorsi (tutte e tre le chiamate), SortableCard, la casa il sito di rendering dei widget selezionabili della pagina, e il layout delle impostazioni-pagina Anteprima. La banda a catena in una pagina. tsx è intoccato di proposito — rende sempre a widgetDefaultSize e non legge mai memorizzati preferenze, quindi un default dichiarato soddisfa già il proprio piano. Nessun widget del Registro di sistema dichiara la larghezza 3 o un minimo ancora; cioè poi lavoro. Questo amplia solo il vocabolario e collega il macchinario.

  23. · kamo-internal

    Toccare un logo tracciato a mano e scaricare il file convertito

    Quattro cose sul convertitore raster-to-vector e la semplice slot logo. **La barra di scorrimento sulle opzioni raster è tre volte più ampia.** 4px è stato un bersaglio difficile per terra su, e le regole erano solo webkit, quindi Firefox non aveva mai avuto una barra stilizzata a tutti — scrollbarWidth/scrollbarColore ora portano lo stesso intento lì. **Una fonte che ha già uno sfondo trasparente è lasciata sola.** L'oculare usato per restituire felicemente un colore per un pixel trasparente: una tela memorizza alfa premultipato, quindi ognuno di loro legge come (0, 0, 0), e raccogliendo uno ha detto al condotto lo sfondo era nero. Poi è andato e cancellato le parti scure del logo. Fare clic sulla trasparenza ora lo dice invece di scegliere. La correzione lato server corrispondente è in vettoriale. **Una bacchetta e un pennello, ciascuno in grado di aggiungere o rimuovere.** La rimozione automatica ottiene due cose sbagliate spesso abbastanza per avere bisogno di discutere con: uno sfondo che perde in una parte racchiusa del design, e un pezzo del design che condivide il colore dello sfondo e lo accompagna. The bacchetta prende una regione contigua intera in un clic; il pennello prende tutto ciò che è trascinato sopra. Ogni operazione si risolve contro il raccolto ORIGINALE, mai il taglio attuale. Questo è ciò rende possibile "+" a tutti — una volta che la rimozione ha annullato l'alfa di una regione non vi è alcuna regione sinistra per trovare, ma l'originale ha ancora il colore. Rende anche le operazioni riproducibili, quindi nudging a setting in seguito re-runs rimozione senza scartare le correzioni. Modifica della vernice localmente per feedback istantaneo; solo il risultato stabilito attraversa il filo, e solo l'alfa maschera, come un PNG di scala a 8 bit di poche centinaia di byte. **Un pulsante di download accanto al semplice logo**, così il membro può mantenere il convertitore SVG prodotto — spesso l'unica copia vettoriale del loro logo chiunque ha, e altrimenti raggiungibile solo da un secchio non possono navigare. L'estensione viene da annusare i byte, non il nome memorizzato: che lo slot scrive ogni upload a un logo fisso. chiave svg indipendentemente dal tipo, quindi Tema.kamocrm.com serve byte PNG da un nome .svg per qualsiasi org che ha impostato un logo prima di questo il convertitore esisteva. Preso in un blob piuttosto che collegato, perché un cross-origin `♥a download>` viene ignorato e aprirebbe il file invece di salvarlo.

  24. · kamo-internal

    Set di campo di una pagina e le impostazioni predefinite che sostituiscono i passaggi caduti

    CreateOrgFields è ciò che la nuova forma single-page /network/create chiede per: un tipo di ramo, nome, alias, l'app switch, e una manciata di optional campi. toWizardFormData riempie in tutto il mago a dodici passi utilizzato per raccogliere ma questa pagina non mostra mai, utilizzando esattamente ciò che salta ognuno di questi passi utilizzati per inviare (bindPhone/bindEmail true, contatto vuoto/labels, watermark FULL, fonti di marca COMPANY) così un org creato qui è indistinguibile da uno ha fatto il vecchio modo da qualcuno che ha riempito solo ciò che era richiesto. conBranchType mantiene anche genitoreAliasId indicato in un'opzione il selezionato modello offre in realtà (ROOT prima quando consentito, altrimenti il primo personalizzato del modello alias) — la procedura guidata di dodici fasi ha fatto questo in un effetto BasicsStep il creatore mai visto il fuoco, e senza un equivalente qui creareOrgReadiness blocchi per sempre su un campo questa pagina non chiede mai per qualsiasi tipo di ramo il cui unico l'opzione genitoriale è ROOT.

  25. · kamo-shared-library

    Creare i diritti dei widget di My Free Org e Avviare il progresso della procedura guidata

    Aggiunge RoleRightType 288-292 (CREATE FREE ORG WIDGET e i suoi quattro ADDED/OPTIONAL/ CREATE CHILD ORG (131). Aggiunti OrgSetupWizardStep, il supporto enum di nove fasi della configurazione Iniziata Wizard, e... tabella org setup wizard progress da Task 2. Aggiornamenti anche RoleRightHierarchyTest forma tassonomia pinned (278/205/35/38 -> 283/210/36/37): CREATE CHILD ORG era una radice indipendente e ne guadagna il primo bambino qui, spostandolo nelle radiciCon secchio bambini, corrispondente a questo file propria convenzione consolidata di registrazione ogni spedizione widget in quel test.

  26. · kamo-internal

    Per-pane dimensione minima, applicato su lettura e su trascinamento

    Filetta un `min opzionale?: PaneSize | null` tramite morsettoPaneSize, i due helper resize-delta, e le due funzioni di lettura/scrittura preferenze nella modello di pannello lavagna puro. Supporti compatibili: ogni chiamante esistente omette l'argomento e mantiene il comportamento di oggi, dal momento che morsettoPaneSize cade E' il momento in cui... per-pane minimo è fornito. Il pavimento è applicato sul valore STORED di risolverePaneSize, non solo nel trascinatori, quindi la preferenza di un membro registrato prima che un pannello avesse un minimo (o prima che sia stato alzato) viene tirato indietro sul letto.

  27. · SecurityService

    Metti un bilancio in tempo reale sulla rettifica

    Il punto finale non aveva limiti di alcun tipo. *** lo schermo del registro richiesto prima di abilitare il suo pulsante di ricerca non è mai stato letto qui — il richiesta corpo è tre campi di JSON e nulla sul server cercato un payload — così il controllo ha cantato un pulsante, non la richiesta, e uno script inviare direttamente a questo URL era già illimitato. VerificationResendRateLimiter lo sostituisce con un budget che il server possiede: a 60s cooldown preso come un singolo SET NX così le repliche da corsa non possono entrambi vincere, 5/ora e 15/giorno per indirizzo, e 20/ora per IP pubblico. Checked PRIMA dell'org e della ricerca degli utenti e cliccato sull'indirizzo SUBMITTED, quindi un la sonda costi di bilancio se esiste o meno il conto e il 429 non diventare l'oracolo dell'esistenza del conto che il punto finale è attento "se questo esiste una risposta" per evitare. La finestra IP è saltata per un indirizzo non pubblico: non determinato collassare in una chiave condivisa per ogni registrante. Redis-backed perché questo servizio esegue repliche, e non si apre su un outage Redis. Un rifiuto risponde 429 con Retry-After e retryAfterSeconds, così il schermo può contare giù contro questo orologio piuttosto che indovinare da solo.

  28. · InitializerService

    Crea org setup wizard progress per la procedura guidata

  29. · kamo-internal

    L'anno stabilito dell'org è facoltativo, e renders non impostati come assenti

    Nulla sul server mai richiesto — la colonna è nullable, la creazione parser mappa un valore vuoto a null, e patchOrganization applica solo le chiavi un corpo PUT menziona, quindi "yearEst": null è un deliberato chiaro. L'unica porta era questo wizard's validateBasics, che ha bloccato l'intero passo di base fino a un anno E' stato scelto. Un sacco di clienti reali non hanno risposta (una nuova LLC, una divisione spun fuori metà anno, chiunque semplicemente non conosce), così il cancello appena insegnato loro a inventarne uno. Gettala; il campo mantiene la sua etichetta senza asterisco e ottiene lo stesso "Opzionale". FieldHint ogni altro campo opzionale sul passaggio già ha. Fissa il motivo per cui nessuno ha notato che il campo era già fine nullable: il DTO parsed yearEst con un nudo la coercizione corre BEFORE optionality, quindi Number(null) === 0 e ogni org senza un anno arrivato come fondato nell'anno zero. È rimasto invisibile perché display siti di guardia sulla veridicità e 0 è falsy — avrebbe superficiale come "Est. 0" a il primo sito che ha controllato `!= null` invece. Preprocess null e "" torna a non definita, normalizzare lo stesso modo in Organizzazione. daJSON, e allargare il rete / tema DTO per ammettere il null che effettivamente arriva. I due siti di visualizzazione che hanno utilizzato `{org.yearEst && <Fact/>} diventano ternari: a falsy-and render è ciò che avrebbe dipinto un nudo 0 nel cassetto. The le impostazioni formano ora percorsi il salvataggio attraverso parseYearEst, quindi una scatola vuota cancella il valore di proposito piuttosto che per via di JSON.stringify trasformando NaN in nullo.

  30. · kamo-internal

    Mostra un membro solo le schede che sono loro da vedere

    Le tre superfici dei componenti erano aperte alle persone che non possono significare nulla per. Ogni cancello è sul MEMBER TYPE o le app di org, mai su checkRight — checkRight restituisce vero per ogni destra sotto la modalità dio attivo, e la pagina è puòViewAltherMemberAccount ORs in diritti che non hanno nulla a che fare con E' una cosa che non va. ottenereMemberType() di default a 'MEMBER', così ognuno di loro non riesce chiuso su una sessione il cui tipo non ha ancora risolto. Plans & Billing: membri del team. Il piano, gli abbonamenti, le fatture, i metodi di pagamento e la sede tutti appartengono al business; un membro normale Non contiene nessuno di loro, quindi la scheda mostrava loro i soldi della compagnia. Gatted su il VIEWER, quindi un proprietario che apre la pagina di qualcun altro mantiene l'amministrazione Percorso. La carta /settings è gated lo stesso modo — una carta che apre una scheda che non renderà peggiore di nessuna carta, esattamente come le Commissioni accanto a esso. Suoni e avvisi: gated alla stessa condizione dell'icona del telefono di NavTop, che è ora una funzione (hasPhoneAccess) piuttosto che due copie della stessa &&&. Il sottotab non è altro che la configurazione del telefono che l'icona apre — quale suoneria, quale dispositivo, quanto forte — quindi un membro senza telefono era controlli consegnati che non possono cambiare nulla che sentiranno mai. Audio, Video e Event Suoni sono intatti: questi sono i dispositivi di riunione e l'app suoni di notifica, che ogni membro ha. Legal & Compliance: membri del team, e un org con le applicazioni Docs e HR. Piuttosto che inline le nuove condizioni, si piegano in legaleBadgeAppliesTo, che il pulsante di firma di NavTop e il fornitore di conteggio dietro il suo distintivo già Condividi. Quel pulsante è un link dritto a questa scheda, quindi una quarta copia della condizione avrebbe permesso di vivere la propria destinazione e lasciare il membro sul loro profilo senza spiegazione; il fornitore va tranquillo sulla stessa condizione invece di tenere un abbonamento STOMP e un sondaggio di 60 secondi per un conteggio che è 0 per costruzione.

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