Ir para o conteúdo
KAMOUniverse

Changelog

O que há de novo.

Cada melhoria para a plataforma, como ele envia.

  1. · kamo-internal

    Apague a cascata, adicione ações em massa de ramificações, explique a regra

    O destaque em cascata agora viaja a cadeia em vez de piscar cada afetado Remem imediatamente. ActivadoOs antepassados já chegam mais próximos, por isso o índice É o distância percorrida acima da árvore e cada fila demora 90ms atrás da última – ver como move o filho para o pai para o avô é o que ensina a regra, que o flash simultâneo lê como uma falha. Ainda instantâneo sob o movimento preferido. Conceda tudo / Remova tudo em um branch, mostrado apenas quando eles mudariam algo. Roteado através da aplicaçãoToggle por direito em vez de escrever as configurações diretamente: a A acção global não deve tornar-se uma segunda aplicação das regras em cascata que deriva do único em direitosHierarchy.ts. A pílula concedida/total está agora sempre em uma linha pai em vez de apenas quando colapso — é a leitura mais rápida do que uma filial realmente concede. Também renderiza hierarquiaHeading/hierarchyBody, que o commit anterior adicionou o dicionário e então nunca usado. Mostrado apenas acima de um grupo que realmente tem ninho; um banner que aparece em toda parte é um povo aprender a pular. direitosTreeForest.test.ts fixa a regra de ancoragem a árvore e os tipos de ramos compartilhamento do editor: um direito cujo pai é filtrado para fora do grupo atual para o ancestral presente mais próximo, ou torna-se uma raiz. O outro caminho faz um permissão concebível desaparecer do editor sem nada para indicá-lo — e ele é acessível na prática, porque EDIT QUOTE TERMS é declarado CRM enquanto o seu O GERENTE-pai QUOTES é POS.

  2. · kamo-internal

    Mostrar e impor a hierarquia de permissões em todos os cinco editores

    Cinco editores concederam 199 direitos como cinco listas planas de caixas de seleção, e nenhum dos eles mostraram que um direito pode ser um pré-requisito para outro. Conceder um filho sem seu pai parecia exatamente como conceder uma permissão de trabalho — que é como a guia Legal & Compliance precisava de dois direitos e nenhum editor poderia dizer isso. Direitos Árvore torna a árvore: indentação com um conector espinha, colapsável branches, uma pílula concedida/total por branch, pesquisa que mantém os antepassados de uma combinação visível, e uma cascata que é animada porque a animação é o que ensina regra — habilitar um filho a iluminar o que depende, desactivando um genitor Subtree, ambos com um nome de brinde de desfazer exatamente o que se moveu. Honras prefere movimento reduzido. Também deixa de mentir sobre três estados que os editores jamais poderiam expressar: direitos bloqueado pelo modelo de segurança da org, linhas legadas concedidas-mas-inertes cujo pai é Negados, e os 58 direitos que são concedidos, a não ser portão nada em qualquer lugar. Um administrador não foi possível indicar previamente uma permissão real de um placeholder. As regras em cascata vivem em app/lib/rightsHierarchy.ts, espelhados a partir de Java's Tipo de Papel Direito. Uma cópia de uma regra de segurança é um passivo, então o teste de paridade lê a fonte Java e falha em qualquer divergência em vez de uma convenção confiável. O editor de modelos de ramos obtém a ordenação e a indentação, mas mantém a sua controle próprio e não auto-cascade: esses são valores FORCE, absolutos e aplicado depois de cada nível, assim em cascata eles iria silenciosamente reescrever um Ativar. A relação pai ainda é aplicada lá no momento da resolução. Concepção + auditoria reprodutível: docs/superpoderes/specs/

  3. · SecurityService

    Normalizar o membro sobrepõe- se à hierarquia

    Os direitos directos dos membros passam agora pela hierarquia dos direitos. normalizeLevel antes deles Persistem: uma criança concedida puxa seus antepassados até CONCEDIDO ao membro nível, um pai negado empurra NUKE para baixo de sua subárvore lá. O lado do servidor em vez de confiar no editor, porque este endpoint é alcançável directamente. Um nível armazenado com uma criança, mas não seu pai é precisamente o que o As tiras de fechamento do resolvedor mais tarde — o membro continuaria perdendo um direito A UI mostrou-se como garantida, sem nada para explicar. Coletado em um mapa primeiro para que a hierarquia vê todo o nível de uma vez; normalizar a entrada por entrada dependerá da ordem que o cliente enviou.

  4. · InitializerService

    Os antepassados do 'backfill' não podem remover o acesso

    MemberRightsAppliedService agora nega qualquer direito cuja cadeia pai não é Concedida. Cada linha escrita antes da hierarquia existir não sabe nada sobre Antepassados, portanto, um papel de MANAGEM SUBSCRIPTION PANS sem ACCESS COMMERCE — totalmente normal até agora — perderia-o no próximo novo cálculo. Através de 13 organizações vivas que são uma interrupção, não uma migração. Aumenta todos os quatro níveis (funções de org, departamentos, títulos de trabalho, substituições de membros) para o invariante os caminhos de escrita agora mantêm, usando a mesma regra: O descendente puxa os seus antepassados para a vitória. Passo 2 é o que realmente impede a interrupção — transforma um antepassado explicitamente DENIED para concedido, porque linhas que existem sobreviver passo 1 intocado e fechamento iria, em seguida, revogar cada Descendente abaixo deles. Modelos de segurança não são deliberadamente tocados: um FORCE NUKE em um pai é um administrador que desliga uma subárvore de propósito, e o encerramento honra Essa é a característica. Passo 3 é um GATE, não uma linha de log: ele verifica novamente o invariante e falha na execução se qualquer nível ainda detém um descendente concedido sob um antepassado não concedido. A migração que relatou sucesso com uma violação deixada para trás iria entregar o problema para o resolvedor, onde ele aparece como um membro permissão sem nada para explicar.

  5. · kamo-shared-library

    Hierarquia pai/filho para todos os 199 direitos

    RoleRightType declarou um campo 'pai' e um getParent() público por anos. Todas as constantes passaram nulas e nada lhe chamou. Isto termina que andaimes: 135 crianças, 34 raízes, 30 independentes, profundidade máxima 3, derivadas de uma auditoria de todos os 199 direitos acima de 15.081 ficheiros-fonte nos 40 acordos de recompra. DOIS pontos de execução, e a divisão é o projeto: normalizeLevel () é AUTOR. Torna ONE nível auto-consistente — um concedido A criança puxa seus antepassados para cima nesse nível, um pai negado empurra NUKE para baixo A sua subárvore ali. Aplicado no papel, departamento e caminhos de escrita de título de trabalho. Porque cada nível permanece coerente, um título de emprego que concede a uma criança também concede o pai lá, e a cachoeira existente já permite o mais específico O nível venceu um departamento que negou. Nenhuma regra de precedência entre níveis foi adicionado e a cachoeira é intocada. applyClosure() é RESOLUÇÃO, anexada após aplicarTemplateRules. É um rede de segurança para as duas únicas coisas que a autoria não pode alcançar: um modelo de segurança FORCE NUKE em um pai (absoluto, aplicado por último, então sem isso um forçado-off pai deixa seus filhos concedidos) e linhas escritas antes de qualquer um destes. Dois pares permanecem deliberadamente FLAT porque a separação dos deveres depende disso: HOMOLOGAÇÃO TIMECARD AJUSTAMENTOS / FINALIZAÇÃO PAY PERIODS, e APROVAÇÃO ORG PAYOUTS como um irmão de MANAGEM ORG FINANCES em vez de seu filho — aninhando este último Obrigaria cada aprovador de pagamento a ser também um emitente. Desenho: kamo-internal ****************************

  6. · kamo-internal

    Repintar o lembrete na cor do org, abrir as suas opções no local

    O cartão é a cor primária da organização agora, com cada marca desenhada in -- on-primary em vez de um branco literal - uma org de rótulo branco que escolhe um pálido primário pode redefinir que um token e mover a carta inteira. Batatas fritas, carris e as bordas são coloridas da mesma forma para que permaneçam legíveis de qualquer forma. A ação primária é uma pílula invertida, combinando o idioma a assinatura legal herói já usa para um botão em uma faixa colorida. A espinha do sotaque per-kind se foi; o ícone já carrega o tipo, e um segunda cor em um cartão colorido apenas lamacentou-o. Overdue é a exceção, e inverte em vez de ficar vermelho: vermelho numa cor org arbitrária é ilegível. Seu Snooze e Mais menus foram MUI Menus, que portal para o documento e trazer Um pergaminho com eles. Essa fechadura afunda: escondida E compensa estofamento-direita em document.body, e estofamento do corpo move cada posição fixa elemento na página — por isso o baralho, que é fixado no fundo/direita 20, saltou lateralmente no momento em que alguém chegou para Snooze, e o menu cobriu o cartão Pertencia a ela. Ambos são um painel em linha agora, expandindo dentro do cartão com o Ativado à esquerda. Não há portal, nem cadeado, nada para cobrir.

  7. · kamo-internal

    Página de configuração legal e conformidade com o texto legal padrão

    Uma nova aba sobre /settings/features/hrs segurando Texto Legal Padrão, vinculada a partir do menu de configurações e a plataforma de configurações. Criar um pacote ligado O cumprimento legal começa agora, e esse campo é três fileiras mais alto. Certo. A página de configurações HRS como um todo agora REFUSAS PARA RENDER sem MANAGEM HRS SETTINGS em vez de apenas redirecionar: o redirecionamento é um efeito, então não pode correr até depois de uma renderização, e cada aba estava pintando — e disparando seu cargas de montagem-tempo — para um membro que não detém o direito. A nova página adicionalmente precisa de GESTÃO LEGAL AND COMPLIANCE, mantido idêntico em três lugares (página, link de menu, placa de lançamento) e preso por um teste, porque um link oferecido para alguém a página não irá renderizar a aba para abrir Configuração do Provedor em vez disso: O SettingsView resolve um ?tab= desconhecido para indexar 0 em vez de erros. O diálogo semeia o padrão somente enquanto o autor não digitou — a busca resolve-se depois de já poderem estar a escrever. SeedDefault Attestation é um puro helper para que a regra seja testável, e seja aplicada FORA do atualizador de estado: Reagir os actualizadores de dupla-invocações em desenvolvimento, que deixaram o instantâneo semeado O segundo chamamento recusa a sua própria mudança. Um EDIT nunca re-semeia. O pacote contém a sua própria formulação e sobrepõe-a seria reescrever o que o público de uma versão publicada é solicitado a concordar.

  8. · kamo-internal

    Texto rico no pegajoso e nas antevisões, e um modo que você pode alternar

    Uma nota agora diz se é texto rico ou texto simples, e tanto o editor e o pegajoso flutuante pode mudá-lo. A nota flutuante em modo rico incorpora o mesmo editor /notes usa, então tem todas as ferramentas que a página completa tem — vestida com a cor da nota através de um novo 'tone' opcional no KbArticleEditor. O adereço é aditivo: ausente, o editor olha exatamente como fez, assim que o conhecimento A base está intocada. A barra de ferramentas quebra e rola em vez de empurrar o área de escrita de uma estreita pegajosa. Mudando de rich -> simples pergunta primeiro, e diz claramente que a formatação é eliminado e não pode ser recuperado enquanto o texto é mantido. Não é. oculto — modo simples não tem onde colocá-lo — assim a conversão também instantâneos uma versão, deixando a formatação antiga recuperável do histórico. Simples -> rico apenas liga as ferramentas e não precisa de aviso. Antecedentes nas cartas de parede e os chips de plataforma de lançamento agora mostram o real conteúdo em vez de uma linha achatada. Eles fazem através de um autônomo lexicalToHtml em vez de uma instância Lexical montada: uma parede é dezenas de cartas, e cada uma de outra forma arrastaria todo o tempo de execução do editor para Apresentar um parágrafo. Essa saída é injetada, e o conteúdo da nota é membro-autor e muitas vezes colado em, por isso é a parte sensível à segurança e foi escrito teste-primeiro — fuga, uma lista de allowlist esquema que recusa javascript: e dados: (incluindo tab- e caso- visado), dentro do href, e as notas do legado cru-HTML mostradas como texto em vez de renderizados. Enquanto uma pesquisa está executando as cartas manter a visualização simples realçada: marcar o hit importa mais no meio da pesquisa, e ele não pode destacar renderizado HTML sem re-parsing o que foi apenas serializado. Além disso: as notas flutuantes carregam o fundo configurável da org marca d'água, a mesma que as páginas de conteúdo usam, honrando as org's bgSetting Watermark incluindo NENHUMA. Tamanho como uma parte da nota para ele mantém em qualquer tamanho, e um pouco mais forte do que as páginas usam porque um pegajoso fica em papel saturado em vez de quase branco.

  9. · KBService

    Carregue o modo rich-text / plain-text de uma nota através da API

    Criar honras no modo solicitado e o padrão para rich, correspondendo ao editor uma nota é criada em. A atualização é nula como qualquer outra campo nesse endpoint, então um chamador enviando apenas { isRichText } não em branco a nota. O DTO lê através de isRichTextOrDefault(), então uma linha que de alguma forma Escapou do enchimento é relatado como rico. Errando para manter formatação é a direção segura: o oposto apresentaria um formatado nota como simples e convidar o membro para achatá-lo.

  10. · InitializerService

    Adicionar a coluna is rich text, predefinida e recheada ao rich

    Se uma nota é editada como texto rico ou texto simples não pode ser lido de volta fora do seu conteúdo: uma nota rica que ninguém formatou ainda é byte-for-byte Um simples. Sem uma coluna, o editor perde a barra de ferramentas sempre que o A nota está reaberta. Padrão TRUE, que também permite ao YugabyteDB adicionar a coluna a um tabela que já tem linhas. VERDADEIRO especificamente porque cada nota escrita antes de existir a coluna foi de autoria do editor rico — era o só havia editor — então o preenchimento para FALSE mostraria formatado notas como simples e oferecer para achatá-los. @Order(0) pela razão usual: o momento em que a compartilhamento de lib mapeia a coluna, cada corredor que carrega uma nota SELECTS ele, então uma migração tardia nunca é Atingido. Navios com guarda deriva este pacote usa — reflete a coluna nome da entidade em vez de restaurá-la, e foi verificado quebrando O nome e vê-lo falhar. Aplicado contra Yugabyte: coluna presente como true padrão booleano, tudo linhas existentes recheadas de forma verdadeira, sem NULLs.

  11. · kamo-shared-library

    Uma nota registra se é texto rico ou texto simples

    O modo não pode ser derivado do conteúdo. Uma nota rica que o membro tem não formatado ainda serializa byte-for-byte de forma idêntica a um simples - ambos são um documento lexical de parágrafos unstyled — assim sem em algum lugar para mantê-lo, o editor perde sua barra de ferramentas cada vez que a nota é reaberta. O padrão é rich, e a coluna está cheia de volta para TRUE, porque cada nota que antecede a bandeira foi de autoria do editor rico; foi o único Uma que havia. Reforço para FALSE apresentaria notas formatadas como simples E convida o membro a aplainá-los. Nulable de propósito, com isRichTextOrDefault () lendo uma bandeira não definida como rico: uma linha que de alguma forma escapa ao preenchimento deve errar para manter formatação, não para descartá-la.

  12. · kamo-internal

    Uma página para as notificações e os controles sobre elas

    A página de notificações usava um cabeçalho próprio — uma sobrancelha, um título e três botões de comprimidos dentro de um cartão bordado — enquanto cada página vizinha (a conta navegador, cada tela de configurações) é introduzido pelo herói de gradiente de marca com um seta traseira e uma barra de tabulação debaixo dela. Leu como em outro lugar no produto. Ele agora carrega o mesmo cabeçalho, com a contagem não lida como sua legenda e os dois ações que operam na lista como botões brancos do herói. Sob ela, duas abas: Notificações e Configurações. As configurações são as que costumava ser uma aba no próprio perfil do membro em /settings/member/{id}?tab= notificações, que colocam os controlos sobre notificações num ecrã diferente das próprias notificações — um assunto em dois locais, nenhum dos quais mencionou o outro. Um membro que abre o sino porque não vai parar é agora já na página que pode pará-lo. `?tab=` é compartilhado através NOTIFICAÇÃO TABS, então a barra e as superfícies que se ligam profundamente a ela não podem deriva para um valor que não seleciona nada. Ambas as superfícies que estão ligadas ao antigo local (acção de Definições do deck de torradas, O próprio botão Configurações da página, agora uma aba) vá para NOTIFICATION SETTINGS HREF. An o marcador antigo do URL do membro ainda resolve — SettingsView retorna ao primeira aba para `?tab=` não reconhece. A cópia de dicas rápidas que pendurada na aba antiga (settings.notifications.help.*) é não transitado: a gaveta de ajuda é uma conta do SettingsView e esta página tem nenhum. As chaves são deixadas no dicionário em vez de esfregadas.

  13. · DocsService

    GET/PATTH o texto legal padrão da org

    /api/docs/legal/settings, atrás do mesmo funil guarded() que todos os outros mapeamento neste controlador. A leitura NUNCA cria uma linha: resolve para LegalDefaults quando o org tem nenhum. Isso mantém a semente do editor de pacotes livre de efeitos colaterais e é o que cobre organizações criadas após a semente KamoInitializer correr — a linha é materializado no primeiro salvo, onde uma escrita pertence. O conjunto certo é deliberadamente mais amplo do que os terminais de pacotes. Este parâmetro de avaliação é alcançado a partir da guia de configurações Legal & Compliance (MANAGE HRS SETTINGS) e do editor de pacotes (MANAGE LEGAL AND COMPLIANCE); tanto sozinho 403s um ecrã num campo que possui. Seguro para ampliar porque é uma string de nível org de placa de caldeira — sem lista, sem atribuição, sem provas — e um ensaio de regressão pinos que o alargamento não atinge lista/criar/audiência-preview. Semântica PATCH: um campo ausente não é tocado, uma cadeia vazia é uma cadeia deliberada Afastem-se. Publicar já recusa um atestado em branco, então um padrão limpo apenas faz o autor escrever o seu próprio.

  14. · InitializerService

    Semeia cada organização um texto legal padrão

    Uma linha hr legal settings por org, única em org id, carregando **************************** Inserto-only, nunca uma atualização. Uma org que editou o seu próprio texto possui-o; uma redistribuição silenciosamente reescrever a sentença seu povo é solicitado a legalmente Concordo em ser o pior comportamento possível para esta cadeia. Isso também faz O corredor idempotente. Orgs criados após esta execução são cobertos pelo fallback lido DocsService Em vez de or ganizar, por isso, um futuro caminho de provisionamento que se esqueceu chamada não pode enviar uma org cujo texto legal padrão é em branco. Ambas as instruções voltam a tentar 40001: um lançamento de um CommandLineRunner aborta o todo inicializa e salta cada corredor ordenado após ele.

  15. · kamo-shared-library

    Texto legal padrão de nível de org

    LegalSettings é uma linha por organização que carrega a redação de uma nova lei O pacote começa com. É um DEFAULT, nunca uma referência viva: criar um o pacote copia o texto, e a publicação congela essa cópia em uma versão, então editá- lo aqui não pode alterar um pacote existente ou alguém já Concordo. LegalDefaults detém a redação da plataforma em UM lugar. O KamoInitializer seed, a leitura do DocsService back e o campo de configurações todos se ligam a ele — três literais iriam derivar e orgs cada lado da migração seria então discordar sobre o que é o padrão.

  16. · kamo-internal

    A história torna-se uma página, e o sino toca

    O sino abriu um popover, que é a forma certa para "o que acabou de acontecer" e a errada para "o que disse aquele lembrete na terça-feira". Um painel pendurado em um a barra de ferramentas não pode ser paged, não pode ser filtrada sem aglomeração, e fecha quando você clique em qualquer coisa — para que um membro possa ver algumas notificações recentes não lidas e Nada mais. Na prática, tudo o que já havia lido tinha desaparecido. Isso é um pobre propriedade para o registro do que a aplicação disse a alguém. /notificações é esse registro. Lê-se como uma cronologia em vez de uma lista, porque as notificações são eventos e a pergunta que um membro traz é quase sempre "quando": uma coluna de dias com as notificações penduradas, cada ponto na cor de seu próprio tipo, assim um mês de história lê como bandas antes de um único A palavra é lida. As linhas não lidas carregam o chão e as lidas carregam apenas o ponto, que é a diferença a ser examinada. A grade de filtro estreita o que o a coluna não a reordena — lida, não lida ou ambas, e por espécie com uma contagem contra cada um. O agrupamento do dia é consciente do calendário e não das horas decorridos: à meia hora À meia-noite, ontem aconteceu algo de há quatro horas, e "há 4h" não é O que uma pessoa à procura vai procurar. Qualquer coisa que o servidor não possa datar é mantido e agrupado separadamente, onde não pode reivindicar um dia a que não pode pertencer. O sino agora é um link, marcado como as outras duas marcas de atenção no bar assim Os três leram da mesma forma. O que difere é o movimento, e deliberadamente: excelente documento e um relógio em execução são estados, e eles pulsam um anel que Diz "ainda é verdade". Uma notificação não lida é um evento, e o que um sino faz quando Um evento acontece é anel. Então ele balança — golpeado uma vez e assentado, amplitudes metade 12° → 9° → 6° → 3° → 1.5°, girando para a coroa porque um sino pendura — e depois descansa quatro segundos. Um sino que nunca parou seria um alarme, e o conde ao lado já diz que a coisa persiste.

  17. · EmailService

    Um histórico filtrado e paged

    O centro poderia responder a uma pergunta: as centenas mais recentes, não lidas ou não, sem forma de pedir o que já tinha sido lido. Então, qualquer coisa que um membro tenha visto foi, na prática, ido — que é uma propriedade pobre para o registro do que o A candidatura contou a alguém. GET /api/notifications/browse páginas, relata o total, conta cada tipo para um filtrar trilho, e assume um status de tudo, não lido ou lido. A lista existente permanece Como era: enche o convés ao vivo, que quer os mais novos poucos e nada mais. Construído a partir de predicados em vez de uma consulta por combinação de filtros, e deliberadamente não de (:kind IS NULL OR ...) — um parâmetro nulo não tipificado é o que fez cada calendário procurar 500, e um predicado omitido não pode fazer isso.

  18. · kamo-shared-library

    Deixe o histórico ser consultado pela especificação

    O histórico da testa filtra por tipo e se uma notificação foi ler, e aqueles combinam livremente — que como JPQL é uma consulta por combinação, ou uma consulta cheia de (:kind IS NULL OR n.kind =:kind). O segundo é o que fez cada procura de calendário responder 500: um parâmetro nulo chega untyped e PostgreSQL recusa a declaração definitiva. A Especificação omite o predicado em vez de passar um nulo, então a falha não pode voltar aqui.

  19. · kamo-internal

    Reconstruir /notas como uma parede de papel com um editor de painel dividido

    A página foi a última tela ainda em Tailwind cru azul-600 / cinza-50 enquanto tudo ao seu redor se moveu para o sistema de casa, e cada um de seus ~100 `escuro:` variantes era código morto — globals.css pinos `color-scheme: luz`. Ele também ignorou `--acent-conhecimento`, o símbolo de sotaque reservado para exatamente Este módulo. Reconstruído em torno da metáfora que os dados já carregam: a paleta é post-it por construção, por isso notas render como papel — alturas de alvenaria, a inclinação determinística per-id que se endireita sobre pairar, uma cabeça de alfinete sobre preso notas no tom profundo do bilhete. Uma nota não colorida recebe papel simples em vez de resolver o fallback de limão do StickyColor (), que de outra forma pintar toda a parede amarela e gastar a paleta antes do membro escolhido Qualquer coisa. As bandas seguem o tipo ativo em vez de serem fixas, então um separador somente custa espaço quando diz algo verdadeiro: recência sob um tipo de data, iniciais sob um tipo de título, open-frequence sob um tipo de view-count. Adiciona também: uma paleta de comandos (□K), uma grade de filtro colapsável com cor swatches e estatísticas de parede, multi-selecionados com ações de mudança de faixa e massa, nav do teclado (/ □ K N P F X setas), realce da pesquisa, carregamento do esqueleto na própria forma da parede, e separar estados vazios vs sem resultados. O editor agora abre ao lado da parede em um divisor arrastável em vez de substituindo a página, e é chaveado por note id assim que a mudança de notas redefini-la. Filtragem, triagem, bandagem, balanceamento de alvenaria e geometria de papel app/lib/noteWall.ts atrás de 48 testes unitários. Conteúdo baseado no DOM do NoteCard O analisador desapareceu — usou o documento. createElement, então uma nota cuja contentPlain foi anulado ao salvar renderizado sem visualização em todo o lado do servidor. Remove NOTE SORT OPTIONS, que enviou etiquetas de classificação em inglês de código rígido em todos os 22 locais.

  20. · kamo-internal

    Pin e desabotoar uma nota do seu pegajoso flutuante

    O pegajoso pode recolorir, renomear, minimizar, maximizar e fechar uma nota, mas não piná-lo — então fiação significava voltar para / notas para a única coisa o O bilhete já está à tua frente. Pinning é uma propriedade da nota em vez do pegajoso, por isso o comuta escreve diretamente até a nota e volta através do cache compartilhado. Isto é... o que o faz pousar em todos os lugares ao mesmo tempo: a lista /notes, e as notas presas banda na plataforma de lançamento casa (onde fica escondido até que o pegajoso é fechado, como antes). Otimista, e coloca o pino de volta se a escrita falhar. Reutiliza components.notes.card.pin / .unpin e o mesmo ícone do editor Um pino significa uma coisa nas três superfícies. Nada de novos laços.

  21. · kamo-internal

    Uma janela de horas silenciosas, que rege ambos os canais de notificação

    Eram dois. O par perto do topo da página silenciou os cartões no aplicativo; o par na parte inferior silenciou os e-mails de mensagem perdida. Nada no ecrã disse eram coisas diferentes, assim que um membro fixando horas quietas teve que notar o o segundo conjunto existiu e estabeleceu-o também — e a suposição razoável, que o Eles já tinham preenchido coberto a noite, estava errado. A janela no topo é agora a única, e escreve ambas. Eles são armazenados por diferentes serviços – horas de funcionamento nas preferências de notificação do membro, horas de e-mail no ui-preference MediaService lê — assim o controle escreve duas vezes, que é exatamente o encanamento que um membro nunca deveria ter que saber. As duas lojas são reconciliadas uma vez, em carga, porque um membro pode chegar com um janela de um lado e não o outro. O que estiver definido ganha: uma janela de e- mail é adotado quando o lado in-app não tem nenhum, então nada configurado é jogado longe, e caso contrário a janela in-app é empurrada para fora de modo que o único controle sobre O ecrã está a dizer a verdade sobre ambos os canais. A preferência de e-mail pertence ao painel agora e não à sua própria seção. Dois componentes debouncing escreve para a mesma chave armazenada iria correr e poderia persistir meia forma, e MediaService lê um campo ausente como padrão o O membro nunca escolheu.

  22. · kamo-internal

    Dois significados de 100% — uma largura de leitura, e todo o painel

    A percentagem foi reiniciada para uma linha de base: a página cresceu para o painel mas capificou em 920px, que em um monitor largo deixa a folha flutuando em muito Mesa vazia. Esse boné é deliberado — uma página de carta estendida através de um A tela de 34 polegadas é um documento pior, não um maior, porque o olho Não se pode seguir uma linha tão longa — mas nem sempre é o que o membro quer. Lendo letras finas ou trabalhando numa forma densa, eles querem o espaço que têm. Então agora há dois, e um botão na cápsula escolhe que: página a largura legível, tampado em 920. O que o painel abre. largura preenche o painel, menos um 24px calha para que a sombra da folha não é cortado contra a borda ea página lê como estabelecido em vez que cultivada. Eles são um MODE, não mais duas paradas na escada de zoom, porque eles são intenções diferentes em vez de ampliações diferentes. Ampliação multiplica qualquer que seja a linha de base está ativa, então a leitura permanece honesta sobre o que é um múltiplo de, e + / − ainda trabalho de qualquer um deles. Alternando o PAIS inicial nele — o zoom retorna a 100%. "Fit to width" que esquerda um zoom de 250% aplicado no topo não caberia em nada, e o membro pediu uma largura, não um multiplicador de um. A opção é um botão com 'aria-pressed', e seus nomes de dicas O QUE IMPRESSO FAZ mais do que o que está atualmente em: "Fit to Width" na página modo, "Reset view" em modo largura. Ambas as chaves já existiam e são não vazio em todos os 22 locais. MaxPageWidthFor cobre as bordas em testes: uma queda de medição do painel NaN voltar para a tampa legível em vez de alcançar PdfPages como MaxPageWidth e renderizando nada, e um painel colapsado nunca retorna uma largura muito pequena para Lê. Um teste prende o fato de que em um painel mais estreito do que a tampa os dois modos convergem para dentro da calha — isso é correto em vez de um bug para Desenho em redor.

  23. · kamo-internal

    Atualizar o relógio NavTop no momento em que o editor salvar

    Vazio do soco um membro é atualmente cronometrado sob já deixa-os OFF servidor-side: RosterService.clockState lê o mais recente soco ao vivo e salta linhas vazias, por isso nenhum relógio-out é escrito e nenhum é necessário. Um SHIFT OUT aqui seria pior do que inútil — o SHIFT IN com o qual seria emparelhado foi apenas anulado, por isso ele pousa como um órfão e levanta a exceção faltando-punch o editor existe para limpar. O que estava realmente errado era o indicador. Ele pesquisa em um 60s andar sem sinal do editor, por isso depois de apagar a entrada eles foram marcados em baixo o membro viu o cromo continuar dizendo que eles estavam no relógio. O editor agora anuncia uma gravação que escreveu algo e o controle re-ler. Despedido de `finalmente' e fechado sobre o que LANDED em vez de sobre o sucesso: uma poupança que parou a meio caminho ainda mudou o registro, e esse é o caso em que um O distintivo é difícil de reparar. O evento carrega o membro editadoId porque o relógio NavTop é auto- encoberto (fetchMyClockState não toma nenhum ID de membro) enquanto este mesmo editor é usado pelo HR contra outros membros em /hr/attenance. Deve AtualizarClock Para comparações como STRINGS e recusa um número, pela razão parseClockState já dá: ids são valores únicos rowid() passados MAX SAFE INTEGER e dois membros podem arredondar para o mesmo número. Não corrige o navegador do outro membro quando o HR edita seu cartão — que precisa O cartão de ponto.

  24. · kamo-internal

    Amplia o documento e agarra- o para o mover

    Uma cápsula flutuante na parte inferior direita do painel do documento: −, a actual percentagem, +. A REALIZAÇÃO É O REset — um botão de reset separado seria um terceiro controle para algo que o membro só quer uma vez que eles já podem ver que eles não são 100%, e onde eles olham para verificar é o número. Está. um botão real com uma etiqueta, então os leitores de teclado e tela alcançam. 100% significa FIT-TO-PANE, não tamanho real. 'zoom' multiplica a largura de ajuste escala PdfPages já calcula, e a vista em que o membro começou é o que Quer dizer quando eles pressionam "100%". Os passos são multiplicativos (x1.25), não ±0,25: um passo fixo é um quarto da página a 100% e um décimo sexto dela A 400%, por isso, voltar de longe levaria uma dúzia de prensas. A matemática está em app/lib/pdfZoom.ts com testes, incluindo que + então − retorna exatamente onde você estava e que uma NaN cai de volta para caber em vez de alcançando PdfPages como `escala = naturalScale * NaN`, que renderiza zero páginas e se parece precisamente com o documento que não carrega. Drag TO PAN, em qualquer lugar que não é algo que você opera. useDragToPan escreve rollLeft/scrollTop em vez de transformar o conteúdo, então herda gratuitamente os limites, barras de rolagem e o comportamento das rodas do contentor — e o eixo horizontal simplesmente não faz nada até que a página seja maior do que o painel, sem qualquer condição para o dizer. Recusa-se a começar input, textarea, select, button, a[href], label, [role=radiogroup] and the descanso: estas são as caixas de assinatura, campos de texto e grupos de caixa de seleção InteractiveField renderiza e os botões da cápsula de zoom. O ponteiro é capturado no caminho para baixo para um arrastar que deixa o painel continua a rastrear e ainda termina limpo. Só para ratos. Toque já panes nativamente com momentum e borracha-banda que nenhum manipulador aqui pode reproduzir, e sequestrá-lo faria o documento pior nos dispositivos onde arrastar é o gesto natural. Uma correção de layout vem com isto: PdfPages centros páginas com «itens de alinhamento: centro», e um item flex maior do que o seu recipiente transborda IGUALDADE em ambos os lados — a metade esquerda da qual nenhuma posição de rolagem pode Alcançar. Ampliar a largura do painel teria colocado a margem esquerda de cada página permanentemente fora de alcance. A embalagem de página agora cresce para o mais largo página («largura: conteúdo de ajuste», piso em «min-largura: 100%») A folha fica dentro da área de rolagem.

  25. · kamo-internal

    Notas afixadas na plataforma de lançamento, rotação de cores e um envio adequado

    Três coisas. Notas pinadas chegam à plataforma de lançamento. Cada nota fixada em /notas recebe uma chip lá em sua própria cor pegajosa, com uma visualização curta; clicando em um pega-o na sobreposição, e um controle de canto abre-o na totalidade editor em vez disso para as coisas que um pegajoso não pode fazer. Uma nota que é ATUALMENTE FLOAING é deixado de fora — já está na tela do membro, e listando ele ofereceria a mesma nota duas vezes, a mesma regra que faz o seu cartão /notes vai inert. Fechando o pegajoso coloca o chip de volta. A banda renderiza apenas quando a opção notas sobreviveu ao próprio portão do navegador, então não decide nada sobre acesso por si só, e prefere a sobreposição cópia em cache de uma nota para que um chip nunca mostre um título ou cor de antes Foi apanhado. Novas notas giram através da paleta. Cada um abre na cor depois a nota mais recentemente CRIADA do membro, embrulhando no final, então uma parede Nunca é um bloco de amarelo idêntico. Tirado das notas eles mesmos em vez de um contador armazenado, então ele fica em todos os dispositivos e sessões sem nada extra para persistir; um não definido ou não reconhecido a cor anterior reinicia a rotação em vez de adivinhar. Fechar uma nota agora amassa-a. Uma batida de antecipação, e depois se enruga, gira e cai, deixando uma folha de pedaços de papel na sua própria cor sobre o espaço que deixou. Os restos são renderizados pela camada, não o nota: uma criança herda a transformada de saída da nota e encolheria com ele em vez de estourar para fora, então a nota dá sobre a sua última Retângulo e cor na saída. Uma nota maximizada rompe através do viewport inteiro em vez do tamanho que ele iria restaurar para baixo; um minimizado Não se rompe de todo, sem espaço no ecrã para rebentar; e prefere-reduzido-moção começa um desbotamento simples sem restos. A dispersão é uma hash determinista, não Math.random, que iria re-roll cada renderização e Mexer os restos no meio do voo.

  26. · kamo-internal

    Configurações de notificação através da largura, com um modelo funcional

    Era uma coluna de 760px de linhas de switch, que lê como um formulário para preencher em vez do que algo para sintonizar — e em uma tela larga deixou dois terços da página vazia enquanto a lista de tipos de notificação correu para fora do fundo. A verdadeira pergunta da página não é "o que são as minhas configurações", mas "o quão difícil é isso a aplicação permitiu interromper-me", então agora abre-se respondendo isso em um frase reunida a partir dos valores vivos — no aplicativo, com um som, no seu desktop, fora de suas horas tranquilas — e dá a largura para as quatro decisões Que canais, onde pousam, quando ficam quietos, e o que há Vale a pena ser informado. A peça central é um palco: o próprio viewport do aplicativo em miniatura, pintado no as fichas escuras do baralho de notificação enquanto a página à sua volta permanece clara, porque que é o contraste exato que uma notificação real faz quando chega sobre um ecrã de trabalho. O canto é escolhido clicando no canto, eo cartão molas ao invés de corte, então o controle e suas consequências são uma gesto. Quatro quadrantes batem um dropdown aqui: a escolha é espacial, e o palavras "inferior direito" são um mapa pior de uma tela do que uma imagem de uma. Além disso, mostre-me levanta uma notificação real no baralho real no membro próprio som, canto e tempo de demissão. Uma página de configuração para notificações deve ser capaz de mostrar-lhe uma notificação, e uma zombaria seria uma imagem de um — assim PreviewToast coloca uma carta descartável através do baralho real, escrevendo nada, publicar nada e nunca chegar ao centro. Os tipos tornaram-se azulejos onde a telha inteira é o interruptor, em vez de linhas com um alternância 34px na extrema direita, e a seção de e-mail adotou o próprio painel linhas para que ele lê como parte da página em vez de uma carta que vagueou dentro. Não perturbe agora aparece uma vez. Foi no resumo tira e novamente no cartão silencioso — o mesmo interruptor duas vezes em uma tela. Vive com o resumo, que é a coisa que muda; o cartão silencioso é deixado para o tipo agendado.

  27. · kamo-internal

    Notificações se tornam uma aba no próprio perfil do membro

    Eles eram uma página própria em /settings/notifications, o que colocou uma preferência sobre uma pessoa em outro lugar que não a página sobre essa pessoa — e deixou o e-mail missage switches encalhados na aba perfil, então as duas metades de "como é que me dizem as coisas" vivia em ecrãs diferentes. Ambos estão aqui agora, em * ******************* directamente após o meu perfil. Os interruptores de e-mail mantêm o seu comportamento exactamente — a mesma tecla de preferência, a mesma me-scoped rota, mesmo debounce e keepalive flush - e são retraídas com o seção própria do painel de notificação e linha primitivas para que eles leiam como parte dele em vez de como um cartão que entrou. Eles permanecem uma seção distinta, e dizem: que o canal o alcança quando o aplicativo é fechado, é escrito por um serviço diferente, e mantém suas próprias horas tranquilas. Dobrando os dois conjuntos de horas em um controle mudaria silenciosamente o que um deles governa. A aba é auto-somente, porque cada preferência por trás dela é lida e escrita através de rotas me-scoped — no perfil de outra pessoa estes controles editariam O próprio visualizador enquanto aparece para editar o seu. Obtém o endereço da conta em vez de tirá- lo da aba perfil: as abas de configurações montam uma a uma tempo, então um valor retirado de um irmão estaria faltando exatamente quando um membro abriu esta página primeiro, que a partir de um link Configurações de uma notificação é sempre. A rota antiga foi-se, juntamente com o seu tópico ajuste-menu, e as três superfícies que ligado a ele agora construir o caminho através de um ajudante — um caminho montado à mão em três lugares está uma rota que eventualmente discorda de si mesma.

  28. · kamo-internal

    Assinar um pacote em /settings/sign, numa rota própria

    A assinatura estava em linha na aba de perfil do membro, então o documento sentou-se em a aba de configurações tira E a sub-tab de conformidade tira E essa aba ajuda painel — três bandas de cromo não relacionado sobre o instrumento o membro é sendo pedido para ler, e dois cabeçalhos. Agora é... A página herda NavTop e NavPri como qualquer outra tela e a banda herói do assistente é a única Cabeçalho. Terminar ou sair retorna para ******************* Veio do balde onde o pacote estava. A lista navega com `push`, não `substituir`: é uma mudança para uma diferente screen, então o navegador Back tem que voltar para a lista. O allowlist teve que se mexer com ele. «RESTRICted ROUTE PREFIXES» prefixo emparelhado e nega por padrão, e é o que um membro O emprego está encerrado. Sem «/settings/sign», a ex-funcionário poderia abrir sua lista de pacotes e ser repelido para trás a ele por membros restritosGuarda no momento em que eles clicaram em um — um redireccionar o ciclo na superfície exacta em que existe a camada para manter a acessibilidade, uma vez que o reconhecimento de conformidade é uma das duas coisas que protege. `restritedRoutes.test.ts` agora pinos que, incluindo que o jogo não é um '/settings/sinal' não é '/settings/sinal'. Não há portão na página em si, deliberadamente. Um membro que executa o seu próprio o acordo de emprego não tem direito ao RH e nunca terá — o pacote foi Emitido a eles — e cada endpoint por trás dele é auto-escoberto em DocsService (Administração legal, não legalPackageAccess), então a sessão decide de quem é a missão e o UID de outra pessoa responde 404. Um /settings/sign sem atribuição retorna à lista em vez de relatando um erro: não há nada na página sem um e nenhuma maneira para O membro para o fornecer lá. Um UID mal formado mostra o erro, porque Saltar esconderia uma ligação má que alguém está prestes a enviar outra vez.

  29. · kamo-internal

    Recordar o tamanho e a posição de cada nota flutuante por dispositivo

    Reabrindo uma nota separada agora a coloca de volta exatamente onde ficou, em O tamanho que ficou, naquele ecrã. A colocação é por DEVICE, deliberadamente. Que notas estão flutuando é um propriedade do membro e fica do lado servidor em ui-preferences, assim que segue-os em toda parte; onde uma nota SITS é uma propriedade da tela em dianteiro deles, e um layout que se adequa a um desktop de 27" está errado em um Computador portátil. Assim, colocações vivem em localStorage, escopo por membro porque um navegador é um dispositivo, mas pode ser mais de uma pessoa. As colocações sobrevivem ao pegajoso de propósito — fechar uma nota mantém geometria, que é o ponto todo — assim a loja é tampada por membro e despejas menos recentemente colocado primeiro, e uma nota que é suprimida (ou 404s na restauração) dá sua fenda para cima imediatamente. Duas coisas que isto tinha de acertar: - logout faz um localStorage.clear(), que teria caído A disposição em cada saída. Agora captura e restaura esta chave Da mesma forma que já faz para o esconderijo de ligação profunda. IDs de nota e Apenas coordenadas, nunca conteúdo. - a hidratação aguarda a identificação do membro em vez de correr na montagem. As colocações são vigiadas por membros, por isso, restabelecer antes de sabermos quem é iria ignorar silenciosamente o layout deste dispositivo e voltar para o geometria do dispositivo cruzado. Precedência na restauração é a colocação deste dispositivo, ou seja lá o que for. Preferência do dispositivo cruzado última transportada - assim que um dispositivo novo ainda abre para um layout são em vez de uma cascata — e de qualquer forma é re-clamped para o viewport atual.

  30. · kamo-internal

    A liderança de um retorno é lida, não lembrada — e uma chamada pode ser reaberta

    Duas coisas, tanto sobre um evento de calendário ser um lugar pobre para manter uma cópia de O registo de outra pessoa. O diálogo de eventos agora lê o lead do CRM. O nome, o número a tocar, o e- mail, o melhor momento para chamar — tudo obtido quando a janela se abre, com a tecla O ID de retorno do evento já armazena. O que ele não faz é mostrar uma cópia congelado no momento em que a chamada foi reservada, que é o que a descrição costumava carregar e o que teria dito silenciosamente um membro para ligar para um número que ninguém tinha respondeu em semanas. A descrição é agora a própria nota do membro e nada outra coisa, que não pode ficar velha porque nunca foi uma cópia de nada. E uma chamada pendente pode ser aberta da página principal. Clicar em um reabre o mesmo evento de calendário na mesma janela, de modo que o local onde um membro vai olhar para um Chamada prometida é o lugar onde eles podem movê-la. A poupança passa pelo Serviço de Segurança em vez da API do calendário, porque o registro de callback e o evento são dois vistas de uma promessa e apenas o serviço que possui ambos podem movê-los juntos — a alternativa é uma página principal e um calendário que não A chamada é, e um lembrete de que fogos contra o que o membro não está lendo. A linha em si é o controle; os botões de resolução ao lado param o clique, então Ninguém marca uma chamada contatada enquanto pretende lê-la.

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