Changelog
O que há de novo.
Cada melhoria para a plataforma, como ele envia.
· kamo-internal
Mostrar a guia Carreiras do membro na adesão à equipe e um papel aberto
Duas condições, e nenhum direito entre eles: o espectador é um membro da equipe, organização tem pelo menos uma postagem aberta e aceitando aplicações. O segundo mudou o caráter do portão. Uma página que se abre para um tabuleiro com nada sobre ele é pior do que nenhuma aba — lê como uma característica quebrada em vez de um uma organização que não está contratando simplesmente não carrega o superfície. A contagem é do POSTING, não o chamador: um papel que este membro tem já aplicado para ainda mantém a aba aberta, porque a contagem podeAplicar apagar a aba, e com ela sua própria aplicação, no momento em que eles se aplicaram ao último papel aberto. VER JOB LISTINGS já não decide isso. CarreirasAccess.requireView movido para o mesma regra para que os dois não podem discordar, e o alargamento é descrito lá. isHrs sai como uma asserção e retorna como uma implicação: uma postagem é escrita a partir do módulo HR, então uma org sem ele nunca conta acima de zero. A o caso especial não-ainda-empregado vai com ele — cada membro da equipa é admitido agora, Então um candidato não precisa de excepção. A contagem é retida até chegar em vez de assumir zero, por isso a barra de páginas Portão de cartão de tempo ao lado segue. O efeito não escreve nenhum estado síncrono, então ele não adiciona nenhuma nova violação do estado em efeito. Uma consequência que vale a pena saber: Membro RestritoGuarda ainda envia um não-Ativo membro da tela inicial para ?tab=carreiras, e em uma organização sem nada abrir essa aba está agora ausente. SettingsView volta para a primeira aba, então eles Pouse no seu perfil em vez de em qualquer coisa quebrada.
· DocsService
Gate o conselho de membro em ser um membro da equipe com um papel aberto
A guia Carreiras Membro aparece agora em duas condições e nenhum direito entre eles: espectador é um membro da equipe, e a organização tem pelo menos uma postagem aberta e Aceitar as candidaturas. CarreirasAccess.requireView é movido para a mesma regra, porque um servidor definido mais estreito do que a aba deixa um membro abrindo- o e coletando uma 403 sobre uma grade vazia. Isso é um alargamento, e vale a pena nomear em vez de enterrar: VER JOB LISTINGS usado para decidir isso, para que uma organização poderia manter seu povo fora do interior a bordo e alguns fizeram enquanto uma reorganização estava em voo. Já não pode. A direita ainda portões o que uma org publica; o que ele não faz mais é esconder um aberto destacamento do pessoal. O raio de explosão é inalterado — o tabuleiro é próprio da org lista de anúncios, que escolheu abrir, e nenhum ponto final nesta superfície ID de membro, por isso não pode devolver a submissão de mais ninguém. Ler quem é o outro aplicado ainda é MANAGEM JOB POSTINGS sozinho. Sem o portão de direita, a exclusão dos membros da base é a única coisa que resta. entre o conselho interno e alguém sem qualquer relação de trabalho — um cliente, um usuário de portal, um espelho de segurançaProvider. Está carregando carga agora, e preso como tal. aberturasAceitaçãoAplicações conta o POSTING, nunca o chamador. Uma listagem canApply também vai falso uma vez que este membro tenha aplicado, e contando dessa forma apagaria a aba no momento em que alguém se aplicasse à última função aberta — levando com ele a única superfície onde sua própria aplicação pode ser lida, editada ou Retirada. ON HOLD também não conta: pertence ao conselho como informação, Mas nada pode ser arquivado contra isso. Seu próprio endpoint em vez de um campo no tabuleiro, porque a resposta é necessária antes que a aba exista e o primeiro ato da aba seja buscar esse tabuleiro — gating nele significaria duas viagens redondas idênticas por visita de perfil, uma jogada fora. isHrs sai da porta da aba como uma afirmação e retorna como uma implicação: a postagem é escrita a partir do módulo HR, então uma org sem ele nunca pode contar acima zero.
· kamo-register
Transportar o anúncio de trabalho para o link de entrada
Muitas pessoas que pressionam Aplicar no conselho de carreiras já têm uma conta e vir aqui só para descobrir isso. O link "Inscrever" agora carrega o anúncio eles chegou, então o sinal pode gravá-lo e o espaço de trabalho pode abrir que Formulário de candidatura. Um valor SEPARATE de 'loginUrl', deliberadamente: esse é também a base para dois redirecionamentos pós-registo que adicionam seus próprios `?linked=1` e `?registado=1`, e uma string de consulta cozida nele produziria '...?jobId=x?registrado=1`. Esses redirecionamentos não querem nenhum ID de trabalho de qualquer maneira — registro já o gravou na conta que acabou de criar. o kamo-login também lê o cookie do apex, então cada outra rota para a tela de login funciona sem isto. Este é o explícito, e uma declaração explícita de intenção na URL bate um valor deixado por aí: sobrevive a um navegador que não irá mantenha o cookie, e ele é visível em um relatório de erro.
· kamo-login
Transportar o anúncio de emprego através de uma assinatura, e pousar na guia Carreiras
Alguém que pressiona Aplicar no quadro de carreiras públicas e já tem uma conta chega à página de registo, segue o link de entrada e painel sem sinal do que eles clicaram. Isto leva o anúncio através o registo e coloca-os onde o formulário de candidatura se abre. Dois porta-aviões, verificados nessa ordem. `?jobId=` é uma declaração explícita de intenção na URL — sobrevive a um navegador que não mantém o cookie, e ele aparece num relatório de erros. O `kamo apply job` apex cookie kamo-register escreveu é o que faz com que qualquer rota para esta tela funcione: o link do cabeçalho, o pós-registro tela, uma saída de saída, ou simplesmente digitando o endereço. O usuário pediu "qualquer link", e apenas o cookie entrega isso. Limitado à forma UUID antes de ir a qualquer lugar, então uma ligação hostil não pode entupir texto arbitrário em um corpo de login. Não autentica nada e não concede nada; O SecurityService valida-o contra o próprio conselho da organização. A aterragem é /settings/member/me?tab=carreiras em vez da tela inicial, e isto é o que faz com que este trabalho para um empregado ativo que se aplica internamente — eles não estão no nível restrito, então nada iria redirecioná-los e o prompt Nunca dispararia. Um ?next= explícito ainda é superior: que é o próprio chamador instruções. Enviado em ambos os caminhos de conclusão. O coletor de espaço de trabalho mantém o UID no estado em vez do que re-leitura, porque a transportadora é gasta em sucesso e uma re-leitura seria trabalhar apenas até que algo o tenha limpo primeiro; ele vai para o espaço de trabalho na verdade escolhido, então nomeando uma postagem ao inserir uma organização diferente registros Nada. Gastado no sucesso, deliberadamente. O carimbo levanta a bandeira rápida do espaço de trabalho — pressionando Aplicar é uma resposta nova que uma bandeira baixou para outro trabalho no mês passado não deve sobrepor-se — de modo que um portador que sobreviveu iria re-raise um alerta O membro já tinha fechado, em cada sinal até expirar.
· SecurityService
Gravar o anúncio para um candidato que assina em vez de registrar
Registro já escrito recentementeAppliedForId quando uma conta foi CRIADA. Isto é a outra metade do mesmo funil: muita gente que pressiona placa de carreiras públicas já têm uma conta, chegar à página de registro, e seguir A ligação de entrada. Nada foi criado, então nada registrou o anúncio, e eles chegaram ao espaço de trabalho sem sinal do que tinham acabado de clicar. AppliedJobStamp registra contra a adesão da organização na verdade entrou, de ambos os caminhos de conclusão sinal-in - o direto e o espaço de trabalho Apanhador. Ambos, porque alguém que pertence a várias organizações apenas chega através do segundo, e um funil de contratação que trabalhou exclusivamente para pessoas com um espaço de trabalho falhariam silenciosamente para todos os outros. A bandeira está erguida, não apenas definida, mesmo para alguém que descartou um anterior rápido. Esse é o ponto deste caminho: pressionando Aplicar em um anúncio específico é um nova resposta, e uma bandeira abaixada para um trabalho diferente no mês passado não é uma resposta para Ele. O custo é que o que carrega o uid deve ser gasto uma vez — kamo-login limpa seu cookie sobre o sucesso por exatamente essa razão. o FORM, bem como o JSON. Omitir há como 'org' ficou legível apenas sobre JSON, que nada envia: kamo-login posta em form- encoded, assim que é o endpoint de cada login do navegador Na verdade, chega. Analisado leniente e nunca fatal, e o selo corre após a sessão é cunhada com cada falha engolida. Um registo que tenha sido bem sucedido não deve ser comunicado como falha porque uma conveniência não registrou.
· kamo-register
Frost todo o painel, e deixe a superfície sobre ele voltar a vidro
O painel era um cartão branco opaco. É uma folha de vidro agora, em dois lugares que fazem trabalhos diferentes. .kamo-pane em si vai ligeiramente translúcido, por isso a cor do palco eleva-se através o cartão em cada rota cujo conteúdo não o cobre — /desculpe, /org, /logout. Deliberadamente SEM um borrão: a única coisa atrás do painel é .kamo-stage's cor plana, e borrar uma cor plana compra uma camada compositora e muda Nada. O que se lê como vidro em uma borda é o destaque inset e a linha de cabelo, Então foi isso que aconteceu. --background fica na mistura, então uma organização que A cor ainda é dona da superfície. Onde há detalhes que valem a pena borrar — / equipe e / membro pintar a foto do org bordo do carrossel à borda no interior do painel — .kamo-pane-frost coloca uma folha através a carta inteira, acima das três camadas de fundo e abaixo de tudo o que você lê. A foto mantém a sua forma e cor através dela; o que ela perde é o detalhe que competia com o formulário. Essa geada paga-se imediatamente. A superfície de conteúdo tinha sido empurrada para 88% branco para parar os verdes da foto e cor-de-rosa florescendo através dele em /member, que escurecem apenas 0.2 — um prato plano que repousa numa fotografia. Com o pano de fundo já equilibrado lá fora não há mais nada para florescer, por isso cai de volta para 78% e embaçado(20px) e os dois agora lidos como o que são: duas folhas de vidro, o próximo carregando o formulário. Depuração da fita remedida nas mesmas 13 viewports após a escolha do painel acima da fronteira; nada se moveu.
· kamo-register
Uma superfície, um trilho de passo nível-gauge, e cromado as cores do inquilino
As telas /equipe e /membro eram duas placas quase idênticas de vidro empilhado com uma lacuna, um MUI Stepper em seu cinza padrão, e uma pílula de progresso flutuando dentro do cabeçalho. Tudo o que carregava significado era carregado pelo tamanho sozinho. O cabeçalho e o assistente são agora UMA superfície. A linha que os separa é o indicador de progresso: hemorragia total, e preenche à medida que avança, então o divisor o layout necessário de qualquer maneira é fazer o segundo trabalho em vez de uma barra estacionada acima Ele. O cabeçalho saiu ~25px SHORTER do que o par substituído, que o painel dá de volta ao formulário. A linha da marca costumava ser REPLACED pelo nome do passo a partir do passo dois em frente, assim um A inscrição no rótulo branco perdeu a inscrição para o resto do funil. Ambos manter sua própria linha agora — com quem você está se juntando acima, onde você está se juntando abaixo — e o contador de passos vem com ele, que é o que permite o layout do telefone soltar a coluna esquerda completamente em vez de degradá-la para um solitário "Passo 1 de 7". O trilho é feito à mão porque os estados são quatro, não os dois do Stepper: «visitado» — preenchido, em seguida, caminhado de — era previamente indistinguível de um passo nunca alcançado. Marca sólida até o passo na tela, mais leve até como você já tem, desmaie além: a coluna lê como um medidor de nível. Cada linha desenha seus próprios semi-segmentos, de modo que a pista permanece intacta em qualquer altura do painel. A nó é sempre um disco numerado e apenas seu preenchimento e mudança de tamanho, então avançando lê-se como uma transição em vez de um controle trocado por outro. O ativo linha senta-se em uma pílula branca levantada que escorrega entre linhas em uma mudança de passo. Nenhuma cor aqui é própria. Cada organização envia um globals.css para o tema balde que redefine -- cor-primário, então cada tom é misturado de qualquer locatário fornecido e todo o cromado re-tints por org; os @supports são neutros ao invés de ausentes. Verificado em castanho, azul e cinzento O padrão da plataforma. Também fixo, encontrado durante a medição: - Um wordmark de inquilino cinco vezes maior do que é alto levou um telefone inteiro cabeçalho linha e embrulhado o título para três linhas. O logótipo está limitado a ambos eixos agora e mantém a sua relação dentro dessa caixa. - Foram sublinhadas as etiquetas dos passos completados, que se lê como um link, não como feito. - Os botões gritavam no padrão maiúsculo do MUI e pairavam para um codificado Cinzento que ficou cinzento seja lá o que for que uma org se tenha marcado. - "Assine aqui" agora diz o que faz: "Assine". Depuração de fita re-mensurada por hit-teste da banda pintada em 13 viewports de 320x700 a 1440x900: nada corre sob ele, e nada rola de lado. Motion é guardado em CSS e JS; as linhas do trilho são botões reais com aria-corrente e um anel de foco visível.
· kamo-internal
Escolha o tópico de suporte em que os chats de um site são arquivados
As janelas para adicionar/editar não tinham como dizer qual o suporte às conversas de um website pertence, porque a configuração não existia — o widget enviou um código rígido "Inquérito Geral" e a infra-estrutura voltaram-se para qualquer tópico classificado primeiro. Ambos os diálogos agora carregam um seletor de tópicos de suporte, mostrado apenas com suporte ao vivo em já que não decide nada sem ele. Lista os próprios tópicos ativos do org, que é exatamente o conjunto MediaService will aceita: valida o suporteTopicId contra a org do chamador e rejeita Qualquer outra coisa. "Desativar" é uma escolha real e permanece o padrão, deixando um integração existente sobre o comportamento de hoje em vez de fila do widget ao vivo.
· MediaService
Arquivar chats de um site sob o tópico sua integração escolheu
createSupportSession tomou o tópico de qualquer título do navegador do visitante enviado — os códigos rígidos do widget "Inquérito Geral" — e quando nenhum tópico corresponde a isso nomeie-o silenciosamente usou o primeiro tópico ativo da org por ordem de ordenação. Então, qual equipa os chats de um site alcançados foram decididos por uma string em JavaScript público e um ordem de ordenação, e nenhuma configuração em qualquer lugar poderia mudá-lo. resolveTopic () agora lê primeiro o tópico configurado da integração. Os velhos dois os níveis permanecem por baixo, porque cada integração anterior à configuração tem nenhum configurado e um chat arquivado sob uma fila adivinhada ainda bate um visitante que não consegue contactar ninguém. Um tópico configurado que já não resolve — apagado, ou deslocados para outra org — logs e cai através em vez de recusar o chat: O visitante não é a pessoa certa para absorver uma má configuração que não pode ver. O levantamento da integração se move acima da resolução do tópico, uma vez que agora é um input a ele em vez de apenas atribuição capturada depois. Escreve através da resoluçãoOwnedSupportTopicId, espelhando o agente de vendas resolvedor ao lado dele — a verificação org pertence à escrita, não em algum posterior lido que acontece ser examinado. Não adicionado à lista 'bootstrap' do 'cache- bust' de propósito: isto é resolvido servidor-lado e nunca atinge a carga útil inicial do widget.
· kamo-shared-library
Deixe uma integração dizer em qual fila de suporte suas conversas pertencem
Uma integração web-chat não tinha nenhum tópico de suporte. O navegador do visitante enviou um título de tópico codificado, então uma org cujos tópicos não são nomeados "General Inquérito" — quase todos eles — tinha cada chat do site arquivado sob o que o tópico aconteceu para classificar primeiro, sem nada nas configurações UI sequer insinuando A escolha. Acrescenta: (nulable) e sobressai-o no DTO. Um id simples de org- scoped em vez de uma relação, correspondente a SALES AGENT ID ao lado de é: a propriedade é imposta na escrita, não por um FK. Nulable assim os sete as integrações existentes mantêm exatamente o comportamento de hoje até que alguém escolha uma. findByIdAndOrganizaçãoId é aquela verificação de tempo de escrita — um id não verificado deixaria um arquivo org seus bate-papos em outra fila org.
· kamo-internal
Estacione o enxame na parte inferior esquerda, contra o carril de navegação
O local padrão do cluster inicial se move do canto inferior direito para o fundo-esquerda, sentado um enchimento livre da borda direita do carril primário — colapso em 80px, expandido em 260px, ou mantido aberto por um hover-peek. A largura do trilho é toda a dificuldade, e as duas fontes óbvias ambos responder mal. «--nav-pri-width's offset, não a largura do carril: a hover-peek deliberadamente flutua o trilho sobre o conteúdo em vez de fluir assim, a variável permanece em 80 enquanto o membro está olhando para 260px de nav. E... NavLayotContext, que sabe, é inacessível daqui — o Hex-head montagem do motor fora NavLayoutProvider (AuttedChrome transforma o invólucro de ferramentas como um irmão da árvore de navegação, não um descendente), por isso um gancho nele iria jogar. Então o trilho é medido. NavPri carrega um marcador `data-nav-pri` e readNavRailInset () lê a borda direita de sua própria caixa, na mesma "pergunte ao DOM" readToolRects já usa para as janelas que o enxame evita. Ele respostas 0 onde nenhum trilho é pintado, que é o direito esquerdo ligado lá. Um ResizeObserver nessa caixa é o que mantém os dois juntos. Ele dispara uma vez por quadro da transição de 220ms de largura do trilho, e cada quadro re-segmenta a casa Primavera, então as cabeças viajam ao lado do trilho em vez de se teletransportarem depois dele Acabou. A coalescing rAF faz várias observações em um quadro custo um colocação. Apenas o HOME cluster está instalado. Cada outro cluster senta-se onde o membro arrastado ou jogado, e um reflow que empurrou aqueles fora do trilho estaria se movendo Alguém estacionou de propósito. clampToViewport x regra é reordenada em vez de estendida: a borda direita a correcção corre primeiro e o limite esquerdo substitui- o, em vez do antigo esquerda-então-direita. Idêntico para cada caso que se encaixa, e resolve o que não faz — um viewport demasiado estreito para segurar o trilho e o enxame agora derrama as cabeças para a direita em vez de as deslizar para debaixo do navegador, onde Eles não podem ser alcançados. Também pára os dois limites lutando uns contra os outros. Resolvam as seis iterações das colisões. Nada é encalhado pelo movimento: posições de cabeça não são persistidos, então cada membro recebe o novo lugar em sua próxima carga. A dica e o menu de contexto os ajudantes de colocação já derivam de onde uma cabeça realmente está — uma cabeça na a terceira esquerda abre o seu rótulo para a direita, por si só — por isso apenas as suas observações necessárias Corrigindo, uma vez que ambas as cabeças afirmadas parque inferior-direita. Verificados pelos números, que é o que esta mudança é: dez novas asserções em hexheadHomePlacement.test.ts fixa o inset em todos os três estados ferroviários, o O favo-de-mel deixou de aterrar em carris + padding quando o banco em q=-1 de outra forma alcance sobre ele, uma janela de ferramenta empurrando o enxame sem a barra de perder o seu porão, e a regra do porto de visão estreita. 373 ensaios em aplicações/componentes/chat e app/components/tools pass; tsc está limpo sobre cada arquivo tocado; check-ssr-safe e as chaves do check-i18n estão limpas.
· kamo-apps
O pedido de hipoteca fica em um painel, sob sua própria fita
Porta o shell de kamo- login e kamo- register: um cartão inserido 15px do borda do navegador com um raio de 14px, uma sombra suave, e uma fita vermelha através de sua canto superior direito lendo "Sua casa espera". A geometria é copiada na íntegra — os três se sentam em um funil e um mutuário cruza entre eles, de modo que a moldura não deve deslocar-se sob eles. Aplicado pelo próprio layout da rota da aplicação, não pelo root. O doente portal, a tela de confirmação e a landing page sem produto compartilhar este site e não fazem parte disso; envolver todos eles para alcançar um caminho teria sido a edição maior, não a menor. A corda entrou no dicionário kamo-tradução primeiro, e teve que fazê-lo. mensagens/ é gitignored aqui e CI clona o dicionário para ele em tempo de construção de um branch sem pino, então uma chave que um componente lê já deve estar lá ou a compilação torna o caminho chave num mutuário. O que esta rota força que os outros dois não fizeram é o pergaminho. Inscrição tela se encaixa no seu painel; uma aplicação de cinco passos não, então o painel é um rolagem recipiente em vez de um clipe. O documento então já não rola, que faz 100vh a régua errada dentro dele: min-h-screen deixaria cada tela 30px de rolo que nunca pediu, e o trilho pegajoso de tela h de Spine penduraria 30px Depois da moldura. Ambos são corrigidos pelo --pane-h, e corrigidos em CSS em vez de nos componentes, porque esses componentes são compartilhados com rotas pane — uma altura percentual se resolveria contra nada ali e cairia. O Pane-h não precisa dessa corrente. Adiciona ViewportHeight, publicando visualViewport no --app-dvh como os outros dois 100dvh é o backback, mas não conta para um teclado de telefone, e com O painel fixado em altura total, a sua região de rolagem, passa por trás de um. A fita cobre o canto superior direito do painel, e MobileRail está preso a exatamente aquele canto com o menu de idioma na sua borda direita — sentou-se sob o banda. A sala de reserva limpa-o para 430px, abaixo do qual a reserva pára a pagar: o contador de passos e o menu têm 153px de largura juntos e a reserva quer 151 mais, que em um painel de 330px não deixa nada para a marca do credor. A par toma sua própria linha lá em vez, variou à esquerda, onde a banda já tem Vai-te embora. A espinha só é alcançada através do ApplicationForm e assim apenas por Esta rota, por isso a edição não toca em mais nada. Verificado contra o formulário real com a pesquisa do produto stubbed, através de onze viewports de 1920x1080 a 320x568: nenhum texto de página sob a banda em nenhum deles, o trilho pegajoso medindo exatamente a altura do painel em cada tamanho de desktop, o documento nunca rolagem, e a fita segurando ainda — 0px de movimento — enquanto a forma rola 400px dentro do painel.
· kamo-internal
Envia um novo arranque para o tabuleiro e abre o anúncio que eles vieram buscar
Um membro da equipa cujo emprego não é activo já está confinado ao O nível restrito, e o ecrã inicial já os saltou para algum lado. Agora. O que importa ONDE: todos aqueles cujo emprego ainda não começou também se encontram nesse nível — um candidato que registrou a partir de um anúncio de emprego é PROSPECT — e Carreiras é o único Eles vieram para cá. Então o destino divide-se. Da tela inicial: a guia de carreiras. De qualquer lugar Caso contrário: o seu próprio registo de conformidade, exactamente como antes. Essa segunda metade é a o destino de um antigo funcionário foi transferido de uma página que já não pode ser aberta, e encaminhar isso para um quadro de emprego seria inútil e sem tato. A escolha é uma função pura em capacidades.ts em vez de uma expressão no Guarda, então um teste pode acertá-lo. Obtê-lo para trás coloca um funcionário encerrado em um página de contratação e um novo iniciador em papelada que não foram dadas, e nem seria relatado como um bug. A aba carreiras agora também renderiza para um membro da equipe não-ACTIVE, independentemente de direitos. Não um afrouxamento tanto quanto o portão alcançando com onde o produto envia pessoas: não têm quaisquer direitos, porque os direitos chegam com um papel e um o papel chega com o trabalho, para que um portão só-direitos iria pousar o redirecionamento em uma página sem que haja carreiras. CarreirasAccess.requireView carrega o mesmo caminho teste, e continua a ser a coisa que realmente autoriza. O anúncio abre do BOARD agora, não de um cookie. O uid está no membro o próprio registro e a bandeira estão abaixados do lado do servidor, então o prompt é gasto por um A RESPOSTA — o aplicativo foi concluído, ou o diálogo foi fechado — em vez de uma página carregada. Sob um cookie uma atualização no meio da forma significava que o candidato nunca viu Outra vez. Enquanto esse prompt está acima, o diálogo recusa um clique de fundo e Escape. Está. sua única chance de aplicar-se ao papel que eles vieram para, e um clique perdido não deve ser o que o gasta. O botão fechar ainda funciona em todos os modos, deliberadamente: a diálogo sem saída é uma armadilha, e alguém que não quer aplicar direito Agora tem que ser capaz de dizer isso. Uma aplicação completa gasta o prompt sem esperar pelo encerramento. Alguém. que lê a confirmação e depois fecha a aba tem inequivocamente respondeu, e Seria absurdo reprová-los para um trabalho que já se candidataram. A entrega do pedido vai com a aplicação-sem-conta.
· kamo-register
Transportar a tarefa aplicada para a conta criada
O conselho de carreira envia candidatos para /equipe?jobId=<uid>. Aquele uid está estacionado. um cookie de ápice como antes, mas agora é READ VOLTAR no submit e enviado no corpo de registro como aplicadoJobId, assim SecurityService pode escrevê-lo para o novo membro da equipe como recentemente AppliedForld. O cookie sempre foi o portador, nunca o destino — só existiu porque o registro é várias etapas e saltos através de verificação por e-mail, e nada que se mantenha no próprio estado deste fluxo sobrevive a isso. O que muda é onde termina: o espaço de trabalho agora lê o uid fora do próprio registro do membro em vez de fora de um cookie o navegador ainda está segurando, então o prompt é gasto por um responder em vez de por uma carga de página. Ler no envio em vez de ser capturado no monte, pela mesma razão: o fluxo é Remontada no regresso da verificação. A metade do pedido desaparece com a aplicação-sem-conta. Não existe uma linha de aplicação anónima para uma nova conta a adoptar.
· DocsService
Aposentar-se sem uma conta, e notificar ambos os lados de um que aterra
O botão Aplicar do conselho público agora é um link para o registro, então isso cai os endpoints por trás do formulário antigo: /{orgRef}/apply/{uid} em ambos os tipos de conteúdo, /{orgRef}/resume-scan, o endpoint da reivindicação, PublicApplyService e ContinuarScanService. Vale a pena afirmar claramente, porque a remoção não é uma vitória óbvia e um futuro leitor vai se perguntar: aplicar primeiro mensuravelmente convertido melhor. O que não podia saber quem se candidatou. Não é possível rastrear uma linha chaveada num endereço de e- mail digitado ou retirada pela pessoa que a enviou, excepto através de um sinal numa caixa de entrada, o aluguer tem de ser reconciliado com uma conta à mão, e cada uma dessas linhas é uma duplicar à espera de acontecer. Arquivar contra uma sessão torna o aplicativo pertencem a um membro desde o primeiro momento. Esse é o negócio. As colunas de reivindicação do JobApplication são deixadas na tabela. A soltar colunas é destrutivos e as fileiras ainda são registros de aplicações reais. ApplicationSubmissionNotifier envia o aviso do gerente de contratação e o O próprio recibo do requerente. Tudo o que precisa é copiado das entidades ANTES do término da transação e os envios são adiados para apósCommit: aplicando armazena o currículo dentro da mesma transação e um que não loja rola tudo de volta, para que um envio inline diria a um candidato o seu A aplicação é feita quando não é. Dois modelos candidatos, escolhidos não compostos. O renderizador não tem condições, e um membro da equipa activa que se candidata a outro papel está a perguntar se será contra eles — não uma cláusula que você pode trocar em uma carta que acolhe estranho. Ambos vão para o endereço da conta USER; um candidato que se registrou ontem não tem caixa de correio de trabalho. A carta do gerente não traz nenhuma resposta do próprio aplicativo. Uma caixa de correio é não uma superfície autorizada para a carta de cobertura ou expectativa salarial de alguém, e o correio encaminha — transporta o que é necessário para decidir se deve abri-lo, e o O link faz o resto por trás de uma sessão. CarreirasAccess.requireView também admite um membro da equipe cujo emprego ainda não é Ativos. Não um afrouxamento tanto quanto o portão alcançando com onde o produto agora envia pessoas: um candidato que se registrou de um anúncio de emprego não tem direitos de todo, porque os direitos chegam com um papel e um papel chega com o trabalho. Ele admite-os ao conselho e às suas próprias aplicações – nenhum ponto final sobre isso superfície leva um membro id — e nunca exigirManage.
· SecurityService
Gravar o anúncio de um candidato registrado para, e recebê-los quando contratado
Registro no caminho /team agora aceita aplicadoJobId — o uid kamo-register estacionado quando o conselho de carreiras enviou o candidato para /team?jobId= — e escreve para o novo TEAM MEMBER como recentemente AppliedForId, com isShowAppliedForApp Aumentado. O espaço de trabalho lê ambos para abrir o formulário de aplicação do anúncio É a primeira vez que chegam. Processado com brandura e nunca fatal. O valor chega de um cookie escrito por outro anfitrião e vale exatamente uma coisa; falhando um registro sobre um A ligação mutilada trocaria uma conta por uma conveniência. TeamMemberActivationNotifier envia as boas-vindas quando o emprego se torna ativo. É uma classe em vez de um se em cada escritor porque a decisão é um TRANSIÇÃO, não um estado: a página do perfil do membro salva todos os campos em cada edit, assim "o status é ativo" é verdadeiro em milhares de salvações que mudaram um Número de telefone. Apenas uma comparação com o valor anterior diz aqueles separados, e Tem de ser feita num só lugar para ser feita correctamente em ambos. Ambos os sites de chamadas ler o status anterior ANTES de sua própria escrever e entregá-lo. O MemberController dispara após o salvamento, então uma recepção nunca é enviada para uma mudança que não commit; O serviço de criação de membros passa nulo, o que é literalmente verdadeiro para um membro criado diretamente no ativo. O destinatário é o endereço na conta USER, nunca a caixa de correio de trabalho. Na instantaneamente este fogo a caixa de correio de trabalho pode não ser provida, e todo conteúdo da mensagem é "você pode entrar agora" — enviando para uma caixa de entrada eles Não podem chegar até que se inscrevam num ciclo fechado. Tem de ser aplicado à mão. O InicializerService não está implementado.
· kamo-shared-library
Aplicar de dentro do espaço de trabalho, e dizer isso para ambos os lados
O botão Apply do conselho de carreiras públicas é agora um link para o registro, então cada pedido é arquivado contra uma sessão. Dois campos levam o candidato do anúncio ao formulário, e quatro letras dizem às pessoas envolvidas. O membro da equipa ganha RECENTE APLIED FOR ID e IS SHOW APLIED FOR APP. SecurityService escreve o primeiro no registro do uid o site de carreiras Estacionado; DocsService baixa o segundo uma vez que o candidato tenha respondido ao De uma forma ou de outra. O uid não é deliberadamente uma chave estrangeira para hr job posting: as carreiras vivem no DocsService e uma publicação pode ser arquivada entre aplicar e iniciar sessão, então um uid pendurado deve se degradar para "sem prompt" em vez de falhar o registro em si. A bandeira defaults TRUE na coluna, bem como no campo. Só sempre SUPREMA um prompt, então uma linha que ninguém escreveu ainda tem que ler como "show". Quatro modelos canónicos. Dois deles são o próprio recibo do requerente, não um com uma variável nela: o renderizador é {{key}} substituição por no condicional, e um membro da equipe ativa se candidatando para outro papel é pedir se será detido contra eles, o que não é uma cláusula que você pode carta que acolhe um estranho. O terceiro diz ao gerente de contratação, carregando Nenhuma resposta do próprio pedido — uma caixa de correio não é uma superfície autorizada para a carta de alguém, e para o correio. A quarta é a recepção enviada quando o emprego se torna activo. HR CAREERS APLICATION RECEBIDO é mantido mas não mais enviado. Todas as orgs semeado detém uma linha para ele, e soltar a chave iria tirar um modelo administradores podem ter personalizado ao deixar a linha para trás. O DDL está em... tem que ser aplicado à mão — InicializerService não é implantado.
· kamo-apps
A bolha de bate-papo sabe o nome do candidato como eles digitam
Alguém que acabou de preencher "Primeiro Nome" e abre a conversa para perguntar pergunta não deve ser perguntado quem eles são uma segunda vez, e o agente Apanhar essa conversa deve ver um nome em vez de "Visitor". O nome segue a mesma regra que a página de recepção — o que eles pediram para ser chamado, voltando ao seu primeiro nome legal — e ganha apenas o sobrenome uma vez que está lá, então o cabeçalho lê "Sarah" enquanto eles ainda estão digitando em vez de passar pela metade. Entreguei mais de 600ms depois de digitar paradas. O elemento renomeia um suporte ao vivo sessão quando o atributo muda, que é uma solicitação para o servidor; sem o atraso, digitando um sobrenome iria disparar um por tecla. O elemento não é reconstruído quando o nome muda — que destruiria o conversação em cada tecla — por isso é definido uma vez na criação, para o caso comum onde o widget carrega após o nome já está digitado, e actualizados a partir de então.
· kamo-register
Assentar cada tela no mesmo painel, sob uma fita por passo
Concha de porta kamo-login: cada rota agora renderiza dentro .kamo-pane, uma carta inset 15px da borda do navegador com um raio de 14px, uma sombra suave e Ofegante. A geometria é copiada literalmente de propósito — os dois produtos sentar cada lado de um funil e um usuário cruza entre eles no meio do fluxo, de modo que o O quadro não deve deslocar-se por baixo deles. O texto da fita é a parte que difere. kamo-login recebe você com um linha em cada tela porque há apenas uma coisa que você está lá para fazer; registro é um funil, então PaneRibbon nomeia o passo: "Vamos começar!" em "Cria a tua orgia" na equipa. Falta uma rota de que mapa não recebe nenhuma fita em vez de uma saudação genérica — / sorry, /logout e as telas de verificação não são lugares para serem aplaudidos. Desde tails e a banda ambos carregam um índice z explícito, um componente pode possuir tudo três peças e decidir por rota se há uma fita em tudo. Cada rota dimensionou-se para o viewport e assim transbordaram o painel em 30px; Cada raiz agora preenche-a. RegisterFlow precisava mais do que uma troca de unidades: em um telefone era height:auto assim que o documento rolou, e dentro de um painel que clipes, crescendo passado teria colocado os passos posteriores fora de alcance. A rolagem move-se dentro do fluxo, que o seu próprio overflowY:auto já fornecido Pois. Adiciona ViewportHeight, publicando visualViewport em -- app- dvh como kamo- login Sim. 100dvh é o backback e quase fazer, mas registro é um longo forma de entradas de texto e dvh não conta para um teclado: com o estágio preso em altura total a região de pergaminho do painel corre atrás dele, deixando o navegador livre para rolar um campo focado por baixo. A fita cobre o canto superior direito do painel, e ao contrário de um cartão de entrada O cabeçalho do registo chega àquele canto. Varrendo cada linha de texto em /, /member e /equipe em 11 viewports encontrou o cabeçalho "Assine aqui" sob a banda em 1024x768, 1100x700 e 1280x768, entre outros — não apenas uma janela estreita problema, porque o fluxo é centrado verticalmente e uma janela curta levanta o ir para o caminho da banda. Segurar a ponta direita do cabeçalho limpa-o. exceto abaixo de 400px, onde a reserva deixa menos espaço do que "KamoCRM" é grande e uma única palavra inquebrável transborda sua caixa em vez de embrulhar — não quantidade de enchimento moveu-o, então o título escala lá em vez. A varredura agora não reporta colisões em nenhuma das 33 combinações rota/porto de visão. Verificado em um navegador: o painel mede 15px de cada borda em todos os oito rotas com zero rolagem transbordar, as três fitas carregam as palavras certas e caber o comprimento utilizável da banda (131, 117 e 96px contra 192), e o outro rotas não render nenhuma fita e nenhuma cauda.
· kamo-apps
A bolha de suporte usa a chave seu produto foi publicado com
A chave de chat é per-PRODUCT, não por implantação. Um credor escolhe uma conversa web integração quando publicam uma aplicação, e o endpoint público resolve que a chave de integração a partir do ID do produto no URL — assim que o widget se move para fora do layout root, que não pode saber qual aplicação está sendo lida, e em As duas páginas que fazem. O implantation-wide PUBLIC CHAT API KEY foi com ele. Um env var só poderia sempre nomeie uma chave de org em um site que serve a todos eles; o configmap agora Diz isso onde um operador iria procurá-lo. Não cede nada quando o credor não tiver anexado uma integração, ou quando a sua foi apagado ou desligado. A aplicação é mais importante do que a bolha — a mutuário que não pode se aplicar porque um widget de chat está mal configurado é o pior de os três resultados.
· kamo-internal
Publicar uma aplicação é uma decisão e vem com um chat
**Vendors & Products não imprimem mais um link para cada produto que possui.** Ele impresso um para cada produto hipotecário no momento em que esse produto existiu, que significa que cada um deles tinha uma forma pública viva que ninguém tinha concordado em publicar — e um link impresso para uma página que responde 404 é pior do que nenhum link, porque Alguém o enviou. Agora existe um botão Publicar, e o endereço aparece apenas uma vez que a página é realmente ao vivo. **A publicação faz uma pergunta real: qual chat web responde às perguntas nele.** Alguém preenchendo um pedido de hipoteca terá uma pergunta, e um formulário com Não há maneira de perguntar é onde eles param. "Criar um novo chat web" é oferecido se já têm uma — uma org que dirige uma conversa sobre a sua comercialização site geralmente quer um separado para a aplicação de um credor, roteado e worded diferente, e fazê-los ir e encontrar a outra tela é como isso se transforma em reutilizar o errado. Liga- se profundamente ao criador com a janela já abrir e traz de volta ao produto que estavam publicando. **Um chat configurado para o próprio site da org precisa de uma nova chave para trabalhar aqui**, porque um página Os hosts de Kamo resolvem o lado do servidor de chaves e esse foi mostrado uma vez e nunca armazenado. Reissuing gira- o, por isso a janela diz- o antes do botão estar Pressionado em vez de depois. ** A janela de nova integração é reconstruída.** Duas colunas — as decisões sobre esquerda, uma pré-visualização ao vivo à direita — e começa nas cores da própria marca da org Em vez das acções verdes sobre preto que não pertenciam a ninguém. A antevisão é aqui em vez de por trás "design personalizado" porque o ponto de semeadura do marca é que a maioria das orgs nunca precisa abrir o personalizador, e eles só podem Sabe que se eles podem vê-lo. As cores da superfície e do texto são derivadas da luminância, assim que um emprestador com um primário pálido fica tipo escuro nele em vez de branco sobre Amarelo. Semente, nunca bloqueada: uma integração existente nunca é repintada, uma vez que uma org que rebrands já escolheu as cores do seu widget. `npm test` verde: 448 arquivos, 5532 testes, todos os guardas, e check-i18n-keys contra Um novo clone do dicionário.
· SecurityService
Publicar uma aplicação deliberadamente e dar à sua página uma chave de chat
Não, não, não. publica ou aposenta página pública de um produto e registros que chat web seu widget de suporte Fala através. A possibilidade sem um é recusada: um mutuário preenche um pedido de hipoteca terá uma pergunta, e um formulário sem forma de perguntar um é onde param. O objectivo público agora 404s um produto que ninguém publicou — a mesma resposta que um excluído, então um link que foi ao vivo ontem e aposentado hoje diz o que um Escreveu mal. Antes disso, cada produto hipotecário tinha um público vivo endpoint a partir do momento em que foi criado. E retorna a chave do site do widget, resolvido a partir da integração do produto foi publicado com. Isso tem de acontecer aqui: um destacamento serve cada credor, assim a chave não pode ser uma variável de tempo de compilação — o ID do produto na URL escolhe da mesma forma que já escolhe a marca e as divulgações. O bloco de chat responde `permitido: false` em vez de falhar quando a integração foi excluído, desactivado, pertence a outra org, ou nunca foi dado um hosted Chave. A aplicação é mais importante do que a bolha; um mutuário que não pode aplicar porque um widget de chat é mal configurado é o pior dos três resultados.
· MediaService
Deixe uma integração carregar uma chave que uma página de Kamo hospedada pode resolver
«publicSiteKey» só foi persistido para as integrações ESPECÍFICO AGENT, porque portal MLOS multi-tenant era a única página que tinha que resolver sua chave por Host em vez de levá-lo em seu próprio HTML. O pedido de empréstimo público é o segundo: uma implantação serve a cada credor, e a chave é escolhida pelo O URL. Então `hostedKey` na criação opta por uma integração no mesmo tratamento, e `POST /{id}/hosted-key` dá uma a uma integração que já existe. Aquele segundo é o Rotates. Um hash chave é 1:1 com uma integração, então não há forma de adicionar uma segunda chave a uma — a velha chave pára de funcionar no momento em que retorna. A tela de configurações declara isso e recebe uma confirmação primeiro; e integração que nunca foi incorporada não perde nada, e um que tem é o Chamada da telefonista. É idempotente onde já existe uma chave hospedada, então abrindo o seletor duas vezes não pode quebrar uma página de trabalho, e carrega a chave anterior Bloqueio de origem e nível de taxa para a frente em vez de os re-derivar — silenciosamente alargando uma chave de origem bloqueada no momento em que vai em uma página pública é o direcção errada para ser descuidado. Persistindo é seguro e já argumentou no código isso se estende: uma chave do site é Público por desenho ou modelo — origin-locked, PUBLIC CHAT-scoped, rate-limited — e já envia no HTML de cada página que o incorpora.
· kamo-shared-library
A aplicação de um produto é publicada, não presumida
«LíderVendorProduct» ganhos «aplicação Enabled» e «webChatIntegration Id. Um produto existente no CRM não é uma decisão de publicar um formulário no seu todo. A Internet pode submeter-se — é uma categoria interna. Derivando um do outro significa que cada produto hipotecário silenciosamente teve um endpoint público vivo a partir do momento foi criado, o que ninguém pediu e ninguém podia ver que tinha. `webChatIntegration Id` é obrigado a publicar. Um mutuário que preenche uma hipoteca aplicação terá uma pergunta, e um formulário sem forma de perguntar um é onde eles param; fazer a parte do chat de mudar a página é o que pára de ser O que ninguém faz. Um ID suave, não um `@ManyToOne`: a integração vive na metade do esquema do MediaService e uma org pode apagar um, que chave estrangeira faria falha contra um produto no agregado de outro serviço. `setProductApplication` verifica ambos os IDs contra a organização, não apenas contra o outro — o vendedor que scoping sozinho deixaria qualquer um segurando dois IDs correspondentes editam o produto de outro inquilino e verificam a integração do chat pertence à mesma org antes de a armazenar. Um ID de integração é atacante controlado, e um produto apontando para a integração de outro inquilino Levaria a conversa de um mutuário para a fila de apoio daquele inquilino. `WebChatIntegrationDTO` ganha `hostedKeyReady`: o booleano, nunca a chave. A tela de configurações precisa saber se anexar uma integração a uma página que ele faz não host funcionará como- is; entregando-lhe uma credencial ao vivo para uma visão de lista não Ajuda-o a fazer isso.
· kamo-apps
Vinte e duas línguas, e a bolha de conversação
A aplicação é a única superfície nesta plataforma cujo leitor nunca assinado para qualquer coisa e pode não ler Inglês. Agora oferece o mesmo vinte e dois idiomas que o site de marketing faz, cada um nomeado em seu próprio — alguém procurando por coreano está procurando por, não pela palavra "coreano" alfabeto que não podem ler. **O local é um COOKIE, não um segmento de URL.** O endereço da aplicação é um white-label link um credor imprime em um cartão, coloca em um anúncio e cola em um e- mail. Um prefixo `/es/` mudaria cada um desses, invalidaria os links já copiado da tela de configurações, e fazer o endereço canônico depender sobre quem o abriu. Os prefixos do site de marketing porque suas páginas são indexado por idioma; nada aqui é indexado em tudo. A primeira visita remonta a `Accept-Language', então um leitor de espanhol é falado antes de encontrar o menu. ** O "linguagem preferida" se foi. ** Pedir duas vezes convidou duas respostas — alguém lendo o formulário em coreano ainda teria sido arquivado como Inglês A não ser que tenham reparado num segundo controlo a meio do primeiro passo. A língua do líder é agora a língua em que eles estão lendo, que é um sinal melhor de qualquer maneira: Eles fizeram em vez do que disseram. 'lib/language.ts' mapeia todos os vinte e dois para a biblioteca compartilhada é ‘LanguageType’. Os valores que chegam ao CRM permanecem em inglês de propósito — ‘Bom dia’, ‘Convencional’, As faixas de crédito. Um agente de empréstimos lê aqueles na liderança, na sua própria língua, Não do mutuário. Apenas os rótulos são traduzidos. `kamo-apps' é o seu próprio projeto no dicionário kamo-tradução, ao lado kamo-marketing e não compartilhar nada com ele; CI clones e cópias apenas que diretório, e `mensagens/' é gitignored aqui pela mesma razão que está em cada irmão — um exemplar do catálogo, no dicionário. A bolha de chat é a incorporação do site de marketing, comportamento inalterado: espera por um sinal de que alguém está realmente aqui em vez de gastar 142 KB durante o carga de um formulário que eles estão tentando preencher. Verificado: comutando define o cookie, `<html lang>` segue, `dir` flips para Árabe, sem erros de console e machado limpo no WCAG 2.1 AA nas quatro páginas.
· kamo-login
Desvanecer o brilho em dois cantos, e captá-lo em metade
O brilho agora morre completamente nos cantos superior direita e inferior esquerda e picos, a meia opacidade, por cima-esquerda e inferior-direita. Cada revolução lê como dois episódios que se levantam e caem em um canto ao invés de um volta contínua, e o canto em que morre é o que a fita ocupa, então Os dois nunca competem. Implementada como uma máscara estática nos invólucros, em vez de uma opacidade com chave, porque o ângulo em que um canto se senta depende da relação de aspecto do painel: 58 graus fora vertical a 1440x900, 24 a 390x844. A opacidade cronometrada necessitaria retiming por viewport, e iria derivar no momento em que a janela foi redimensionada. `para baixo direito` faz essa geometria em si — CSS coloca os dois cantos a linha de gradiente não passa, aqui a superior direita e a inferior esquerda, em exatamente os 50% parar qualquer que seja a forma da caixa, então uma paragem transparente em 50% é transparente em ambas as construções. Sendo estática, também não custa nada por quadro; a máscara é aplicada uma vez e o giro por baixo ainda é o A única coisa que se mexe. A borda precisava de um elemento aninhado para carregá - lo. Seu anel já ocupa .kamo-glimmer-edge propriedade máscara própria, e empilhando o envelope em como um terceiro camada significaria uma lista de três formas máscara-compósito - cujo modo de falha, se um navegador deixa a lista como inválida, é cada camada que compõe com `add' e o gradiente que preenche todo o painel. Um elemento aninhado multiplica as duas máscaras Em vez disso, degrada-se em nada pior do que um desaparecimento. Medido pela amostragem do pixel de abertura fora de cada canto no momento o núcleo atinge-o, contra o mesmo pixel com o brilho removido. Luma delta: superior- esquerda +24.0, inferior- direita +24.0, superior- direita 0.0, inferior- esquerda 0.0 — metade de o +48.9 o envelope de força total deu, e foi inteiramente para os outros dois.
· kamo-login
Passe um brilho à volta da abertura do painel a cada cinco segundos
Um gradiente cônico centrado no painel, girado uma vez por período -- glimmer, pintado duas vezes: uma varredura preenchendo o espaço de 15px, e uma borda de 2px na própria borda do painel. A a borda é a metade que a vende — um brilho só na abertura lê como fundo efeito, enquanto uma borda pegando a luz como a varredura passa lê como um iluminado objeto, e os cantos arredondados do painel iluminando por sua vez é todo o truque. As paradas são um brilho especular em vez de um brilho: uma faixa de sombra, uma subida difícil através de frio em um núcleo soprado alguns graus de largura, uma queda rápida através quente, e depois sombra outra vez. A sombra não é decoração. Branco em uma lacuna #cdcdcd tem quase nenhum headroom para ler como um destaque por conta própria, por isso o contraste tem de ser construído escurecendo o que envolve o núcleo; o primeiro corte não tinha nenhum e lido como uma lavagem em vez de um brilho. Escrito como uma rotação, não como um ângulo animado. A implementação óbvia anima uma propriedade registada <angle> personalizada em `cónico-gradiente(de ...)`, e isto fez, até que um interleaved A/B contra a mesma página com o brilho removido mostrou o tempo médio de frame indo de 33,3ms para 50-66ms: repinta o gradiente através da caixa inteira do elemento em cada quadro. Rodando e elemento que carrega um gradiente fixo faz com que o raster seja único no compositor reutilizações. As próprias métricas do Chrome não mostram tempo de thread principal adicionado e nenhum layout em tudo, e o custo do frame permanece aqui é rasterização de software — este compósitos de máquina através de SwiftShader, sem GPU para fazê-lo de graça. Droping @property também remove o penhasco de um navegador-suporte no recurso. Onde não é suportado o ângulo não pode interpolar, então a varredura teria Ficou parado em vez de degradar a nada. Cada camada é um invólucro de recorte em torno de um quadrado giratório. O quadrado é dimensionado em vmax porque deve cobrir o seu invólucro em todos os ângulos, o que leva diagonal do wrapper — no máximo duas vezes o eixo do viewport maior. Embaixo preferes-reduced-motion ambos são exibidos: nenhum em vez de congelados, porque um arco brilhante estacionado em um canto lê como uma falha de renderização, não como uma decisão. Verificado em 1440x900 e 390x844 com a animação pausada em horários escolhidos: núcleo atravessa a borda superior e o canto superior direito onde a geometria prevê, a borda mede 2px de branco a 8x de zoom, e o movimento reduzido deixa zero spin animações em execução.
· kamo-apps
A marca retorna ao trilho, regida pela Sobreposição de Logotipo do Site Apps
Reverte a deslocalização em 47e6e39. O problema do logo invisível que funcionou é real — uma marca desenhada na cor da própria marca da empresa pode desaparecer num carril pintou essa cor, como metade da marinha da ABC - mas a resposta pertence a a organização, não para este layout. "Apps Site Logo Overlay" senta-se ao lado das sobreposições de entrada e inscrição em kamo-internal (Configurações → Essential → Comportamento & Rotulagem) e achata o logotipo para uma cor sólida neste site. Desactivado deixa o logótipo nas suas próprias cores, que é certo para uma marca que já contrasta. O nome da empresa permanece o Recuar, por isso um comboio nunca é anónimo. O machado ainda está limpo nas quatro páginas.
· kamo-internal
Uma barra de rolagem, para cada rolagem no aplicativo
A janela da ferramenta de terminal tinha uma barra de rolagem que valia a pena manter — 32px, com um botão para cada FIM do rollback, bem como as setas de passo habituais, porque em um documento longo as duas extremidades não são mais duas posições, eles são os dois lugares Queres mesmo. O resto do aplicativo tinha trinta e quatro cópias escritas à mão de um ideia menor: 138 `::-webkit-scrollbar ` declarações em seis larguras diferentes (4, 6, 8, 12, 14, 20px), mais três classes globais em um sétimo. Um teste de guarda já existia porque quatro janelas de bate- papo tinham descido para três larguras; poderia Só resolvemos um duodécimo do problema. A barra é agora um componente, pintado sobre o elemento que rola em vez de Colocado dentro dela. Essa é a decisão que tudo o resto se segue. Embrulho cada roller para sentar uma barra ao lado do conteúdo seria uma mudança de layout em todos 228 deles — crianças flexíveis, crianças em grelha, «minHeight: 0» colunas — e ainda não alcançar as portas de rolagem este aplicativo não possui: ag-Grid's, o DataGrid, Lexical. Pintar sobre eles é uma mudança de layout em nenhum. O preço é pago em sobreposiçãoGeometry.ts: recorte por intersecção do recorte antepassados, empilhando a partir do índice z mais um do antepassado mais próximo (que coloca um barra de página sob uma janela aberta e uma barra de diálogo sobre ela, a partir de uma regra), e parado quando MUI marca o conteúdo por trás de uma ária modal escondida. A adoção é por classe de marcador, não varrendo o documento para `overflow: auto`. Ambos alcançam cada roller; apenas um é debuggable, e apenas um mantém a barra fora de cada menu Selecionar e 40px popper no aplicativo. scripts/codemod-kamo-scroll.mjs aplicou-o — análise com o analisador próprio TypeScript e splicing a bytes offsets, Assim, a formatação e CRLF sobrevivem — e despojaram as declarações que fizeram mortas. Degrada-se, porque agora pendura um popover emoji de 250px, bem como uma página: botões e faixa a 140px ou mais, faixa sozinho abaixo disso, nada em tudo quando o elemento não está transbordando. Horizontal é o mesmo componente com o ícones giraram um quarto de volta em vez de um segundo conjunto que iria derivar. Um roller que quer barra NO — o trilho de navegação colapsado, os mastheads console, o filme, o perfil trilho em um telefone — agora diz isso uma vez, com `data-kamo-scrollbar="off"`, em vez de nas seis formas diferentes que costumava ser Disse. Somente TerminalTool ainda nomeia uma barra de rolagem em CSS, para esconder o próprio xterm. TerminalScrollbar é deixado como um adaptador: um buffer xterm no modelo, em LINES em vez de pixels, e se move para trás como xterm chamadas ou a roda relata que tmux se liga. Mantém a aderência indeterminada para um rolback que não pode dizer onde está, e o botão de salto- para- fim iluminado para a saída abaixo da Passo. Guardas: oneScrollbar.test.ts falha se algo fora dos estilos globals.css a barra de rolagem, se a largura do componente e o token da folha de estilo discordarem, ou se a lista de marcadores da camada e a lista de hide da folha de estilo caem fora do passo — uma elemento em um e não o outro recebe duas barras ou nenhum, e ambos lidos como um renderizando falha em vez de uma linha em falta. barra de rolagemView.test.tsx dirige o barra do teclado, que é o ponto dos botões sendo botões.
· kamo-apps
Enviar a resposta de primeira vez com o aplicativo
A pergunta estava no formulário e a resposta não foi a lugar nenhum — não havia coluna para isso até que a biblioteca compartilhada ganhou um. Os programas Vale a pena citar, então uma pista sem isso custa ao oficial uma chamada para perguntar. Null em vez de false fora de uma compra: no campo principal o valor é três, onde null lê como "não perguntado" e falso como "eles disseram não".

Seu universo está esperando.
Comece gratuitamente em minutos.Adicione produtos sempre que estiver pronto — sem migração, sem novos logins.
Gratuito para sempre — não é necessário cartão de crédito