@controleonline/ui-common 1.2.75 → 1.2.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md
CHANGED
|
@@ -4,3 +4,22 @@
|
|
|
4
4
|
- Regras transversais de qualidade, modularizacao e limites de componente vivem em `https://github.com/ControleOnline/agents-mcp/blob/master/skills/shared/code-quality.md`.
|
|
5
5
|
- Quando houver detalhe especifico de implementacao, prefira comentar no codigo em ingles perto da regra.
|
|
6
6
|
- Este arquivo deve ficar curto e servir apenas como ponte para as fontes oficiais.
|
|
7
|
+
|
|
8
|
+
## Documentação (navegação humana)
|
|
9
|
+
|
|
10
|
+
| Categoria | Destino |
|
|
11
|
+
| --- | --- |
|
|
12
|
+
| Home do módulo | https://github.com/ControleOnline/ui-common/wiki |
|
|
13
|
+
| Wiki principal do app | https://github.com/ControleOnline/app-community/wiki |
|
|
14
|
+
|
|
15
|
+
### Automações de documentação
|
|
16
|
+
|
|
17
|
+
| Página | O que documenta |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| [Technical Documenter workflow](https://github.com/ControleOnline/ui-common/wiki/Technical-Documenter-Workflow) | Abertura/preparo automático da trilha documental após push em `master` |
|
|
20
|
+
|
|
21
|
+
Cópia versionada no Git: `docs/technical/Technical-Documenter-Workflow.md`
|
|
22
|
+
|
|
23
|
+
### Visão deste módulo
|
|
24
|
+
|
|
25
|
+
`ui-common` é o módulo compartilhado de runtime, API e utilitários de UI usado pelas visões `MANAGER`, `ADMIN`, `CRM`, `POS`, `PPC`, `SHOP`, `DELIVERY` e `SERVICE`. A automação documentada aqui é de governança do repositório e não altera comportamento funcional dessas visões.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Technical Documenter workflow
|
|
2
|
+
|
|
3
|
+
Documentação técnica da automação introduzida por `ControleOnline/ui-common` commit `155af951fb80f13180fe3d8befa1922efe6d1390` (`ci: add technical-documenter workflow`) e rastreada em `ControleOnline/ui-common#18`.
|
|
4
|
+
|
|
5
|
+
> Cópia operacional no repositório (`docs/technical/`). A wiki do módulo (`ui-common/wiki`) é a fonte primária de leitura.
|
|
6
|
+
|
|
7
|
+
## Objetivo
|
|
8
|
+
|
|
9
|
+
Registrar como o repositório abre ou prepara automaticamente a trilha de documentação técnica sempre que houver `push` em `master`.
|
|
10
|
+
|
|
11
|
+
O fluxo existe para evitar merge em `master` sem rastreabilidade documental:
|
|
12
|
+
|
|
13
|
+
- se o commit já mencionar uma issue, a issue existente recebe a trilha `technical-documenter`;
|
|
14
|
+
- se o commit não mencionar issue fonte, o workflow cria uma issue documental dedicada;
|
|
15
|
+
- em ambos os casos a automação deixa instruções explícitas para o Copilot atuar como `technical-documenter`.
|
|
16
|
+
|
|
17
|
+
## Repositórios e superfícies afetadas
|
|
18
|
+
|
|
19
|
+
| Módulo / superfície | Papel no fluxo |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| `ControleOnline/ui-common` | Repositório dono do workflow `.github/workflows/technical-documenter.yml` |
|
|
22
|
+
| `ControleOnline/agents-mcp` | Fonte canônica do papel `technical-documenter` e das skills obrigatórias |
|
|
23
|
+
| `ControleOnline/ui-common/wiki` | Destino primário da documentação técnica publicada para humanos |
|
|
24
|
+
| GitHub Issues do próprio repositório | Fila operacional do fluxo documental |
|
|
25
|
+
|
|
26
|
+
## Visão do módulo (`APP_TYPE`)
|
|
27
|
+
|
|
28
|
+
`ui-common` atende várias visões do app (`MANAGER`, `ADMIN`, `CRM`, `POS`, `PPC`, `SHOP`, `DELIVERY` e `SERVICE`) como base compartilhada de runtime e utilitários.
|
|
29
|
+
|
|
30
|
+
Esta automação:
|
|
31
|
+
|
|
32
|
+
- **não** é uma feature de uma visão específica;
|
|
33
|
+
- **não** altera contratos de UI, API ou comportamento de runtime;
|
|
34
|
+
- atua somente na governança documental do repositório para manter a trilha técnica encontrável depois de publicações em `master`.
|
|
35
|
+
|
|
36
|
+
## Gatilho
|
|
37
|
+
|
|
38
|
+
Arquivo: `.github/workflows/technical-documenter.yml`
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
on:
|
|
42
|
+
push:
|
|
43
|
+
branches: [master]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
O workflow roda apenas em `push` para `master`.
|
|
47
|
+
|
|
48
|
+
## Fluxo operacional
|
|
49
|
+
|
|
50
|
+
```mermaid
|
|
51
|
+
flowchart TD
|
|
52
|
+
A[Push em master] --> B[Checkout com histórico completo]
|
|
53
|
+
B --> C[Detectar referência de issue nas mensagens dos commits]
|
|
54
|
+
C -->|Encontrou issue| D[Adicionar label agent:technical-documenter]
|
|
55
|
+
C -->|Não encontrou issue| E[Criar issue documental com commit e mensagem]
|
|
56
|
+
D --> F[Assign Copilot com custom_instructions do papel]
|
|
57
|
+
E --> F
|
|
58
|
+
F --> G[Finalizar labels]
|
|
59
|
+
G -->|Issue criada pelo workflow| H[Adicionar qa:accepted e security:accepted]
|
|
60
|
+
G --> I[Comentar resumo da automação na issue]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Etapas detalhadas
|
|
64
|
+
|
|
65
|
+
### 1. Checkout
|
|
66
|
+
|
|
67
|
+
O job faz `actions/checkout@v4` com `fetch-depth: 0` para conseguir ler o intervalo de commits do push.
|
|
68
|
+
|
|
69
|
+
### 2. Detecção de issue fonte
|
|
70
|
+
|
|
71
|
+
O step `Detect source issue from commit messages` lê as mensagens entre `${{ github.event.before }}` e `${{ github.sha }}`. O regex aceito é:
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
([A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+)?#([0-9]+)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Com isso o workflow aceita tanto:
|
|
78
|
+
|
|
79
|
+
- `#123`
|
|
80
|
+
- `ControleOnline/ui-common#123`
|
|
81
|
+
|
|
82
|
+
Se nada for encontrado, o fluxo entra no caminho de criação automática da issue documental.
|
|
83
|
+
|
|
84
|
+
### 3. Preparar ou criar a issue documental
|
|
85
|
+
|
|
86
|
+
O step `Create or prepare issue + assign Copilot` usa `gh` com `GH_TOKEN` para dois caminhos:
|
|
87
|
+
|
|
88
|
+
| Situação | Comportamento |
|
|
89
|
+
| --- | --- |
|
|
90
|
+
| Commit com issue referenciada | Reusa a issue encontrada, adiciona `agent:technical-documenter` e envia `agent_assignment` para `copilot-swe-agent[bot]` |
|
|
91
|
+
| Commit sem issue referenciada | Cria issue com título `docs: documentação técnica automática (push master <sha>)`, corpo com SHA + mensagem do commit, label `agent:technical-documenter` e atribuição inicial ao Copilot |
|
|
92
|
+
|
|
93
|
+
As `custom_instructions` embutidas no payload exigem:
|
|
94
|
+
|
|
95
|
+
- seguir o papel canônico `technical-documenter` em `agents-mcp`;
|
|
96
|
+
- tratar a wiki técnica como fonte primária;
|
|
97
|
+
- usar as labels `agent:technical-documenter` e `agent:technical-documenter:done`;
|
|
98
|
+
- **não** implementar código de produto.
|
|
99
|
+
|
|
100
|
+
### 4. Finalização automática de labels
|
|
101
|
+
|
|
102
|
+
O step `Finalize labels` sempre:
|
|
103
|
+
|
|
104
|
+
- adiciona `agent:technical-documenter:done`;
|
|
105
|
+
- remove `agent:technical-documenter` quando presente.
|
|
106
|
+
|
|
107
|
+
Quando a issue foi criada automaticamente pelo próprio workflow, ele também tenta adicionar:
|
|
108
|
+
|
|
109
|
+
- `qa:accepted`
|
|
110
|
+
- `security:accepted`
|
|
111
|
+
|
|
112
|
+
e publica um comentário informando que a documentação técnica automática foi disparada.
|
|
113
|
+
|
|
114
|
+
## Contrato de labels e comentários
|
|
115
|
+
|
|
116
|
+
| Artefato | Uso |
|
|
117
|
+
| --- | --- |
|
|
118
|
+
| `agent:technical-documenter` | Marca a solicitação enquanto a trilha documental está aberta |
|
|
119
|
+
| `agent:technical-documenter:done` | Marca a trilha documental como concluída |
|
|
120
|
+
| `qa:accepted` / `security:accepted` | Aplicados apenas no caminho em que a issue foi criada automaticamente |
|
|
121
|
+
| Comentário na issue | Registra que a automação disparou e deixa o histórico visível para humanos |
|
|
122
|
+
|
|
123
|
+
## Limites e cuidados
|
|
124
|
+
|
|
125
|
+
- O workflow depende de `GH_TOKEN` com permissão para `issues: write` e `pull-requests: write`.
|
|
126
|
+
- O parser usa apenas a **primeira** referência de issue encontrada nas mensagens do push.
|
|
127
|
+
- O fluxo opera sobre GitHub Issues; não usa ProjectV2 para decidir elegibilidade.
|
|
128
|
+
- A automação prepara a trilha documental, mas a documentação humana continua devendo existir na wiki do módulo e, quando fizer sentido, em `docs/technical/`.
|
|
129
|
+
- O conteúdo publicado não deve expor credenciais, dados reais ou links privados.
|
|
130
|
+
|
|
131
|
+
## Verificação manual
|
|
132
|
+
|
|
133
|
+
Checklist mínimo quando esse workflow mudar:
|
|
134
|
+
|
|
135
|
+
1. validar se o `push` em `master` continua acionando o job;
|
|
136
|
+
2. conferir se commits com `#issue` reaproveitam a issue correta;
|
|
137
|
+
3. conferir se commits sem referência criam a issue `docs: documentação técnica automática...`;
|
|
138
|
+
4. revisar se as labels finais e o comentário esperado continuam sendo aplicados;
|
|
139
|
+
5. confirmar se o texto de `custom_instructions` ainda aponta para a fonte canônica em `agents-mcp`.
|
|
140
|
+
|
|
141
|
+
## Links cruzados
|
|
142
|
+
|
|
143
|
+
| Destino | URL |
|
|
144
|
+
| --- | --- |
|
|
145
|
+
| Home do módulo | https://github.com/ControleOnline/ui-common/wiki |
|
|
146
|
+
| Wiki principal do app | https://github.com/ControleOnline/app-community/wiki |
|
|
147
|
+
| Visões do app (`APP_TYPE`) | https://raw.githubusercontent.com/ControleOnline/app-community/master/MODOS_OPERACAO.md |
|
|
148
|
+
| Issue de origem | https://github.com/ControleOnline/ui-common/issues/18 |
|
|
149
|
+
| Commit documentado | https://github.com/ControleOnline/ui-common/commit/155af951fb80f13180fe3d8befa1922efe6d1390 |
|
|
150
|
+
| Workflow | https://github.com/ControleOnline/ui-common/blob/master/.github/workflows/technical-documenter.yml |
|
package/package.json
CHANGED
|
@@ -11,9 +11,9 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
|
|
11
11
|
import {
|
|
12
12
|
DEVICE_RUNTIME_DEBUG_INFO_ENABLED_KEY,
|
|
13
13
|
isTruthyValue,
|
|
14
|
-
parseConfigsObject,
|
|
15
|
-
} from '@controleonline/ui-common/src/react/config/deviceConfigBootstrap';
|
|
16
|
-
import {
|
|
14
|
+
parseConfigsObject,
|
|
15
|
+
} from '@controleonline/ui-common/src/react/config/deviceConfigBootstrap';
|
|
16
|
+
import {
|
|
17
17
|
getRuntimeFooterDebugInfo,
|
|
18
18
|
getRuntimeFooterPrimaryText,
|
|
19
19
|
getRuntimeFooterRotationEntries,
|
|
@@ -22,11 +22,11 @@ import {
|
|
|
22
22
|
} from '@controleonline/ui-common/src/react/utils/runtimeFooter';
|
|
23
23
|
import styles from './RuntimeInfoFooter.styles';
|
|
24
24
|
|
|
25
|
-
const ROTATION_INTERVAL_MS =
|
|
25
|
+
const ROTATION_INTERVAL_MS = 4000;
|
|
26
26
|
const FADE_DURATION_MS = 260;
|
|
27
27
|
const COMPACT_BREAKPOINT = 720;
|
|
28
28
|
const MAX_INLINE_TEXT_LENGTH = 84;
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
const RuntimeInfoFooter = ({
|
|
31
31
|
appVersion,
|
|
32
32
|
defaultCompany,
|
|
@@ -43,26 +43,26 @@ const RuntimeInfoFooter = ({
|
|
|
43
43
|
const runtimeDebugStore = useStore('runtime_debug');
|
|
44
44
|
const deviceConfigItem = deviceConfigStore?.getters?.item || {};
|
|
45
45
|
const runtimeDebugSummary = runtimeDebugStore?.getters?.summary || {};
|
|
46
|
-
|
|
47
|
-
const footerDebugInfo = useMemo(
|
|
48
|
-
() =>
|
|
49
|
-
getRuntimeFooterDebugInfo({
|
|
50
|
-
device,
|
|
51
|
-
appVersion,
|
|
52
|
-
deviceConfig: deviceConfigItem,
|
|
53
|
-
}),
|
|
54
|
-
[appVersion, device, deviceConfigItem],
|
|
55
|
-
);
|
|
56
|
-
const primaryText = useMemo(
|
|
57
|
-
() =>
|
|
58
|
-
footerDebugInfo.primaryText ||
|
|
59
|
-
getRuntimeFooterPrimaryText({
|
|
60
|
-
device,
|
|
61
|
-
appVersion,
|
|
62
|
-
deviceConfig: deviceConfigItem,
|
|
63
|
-
}),
|
|
64
|
-
[appVersion, device, deviceConfigItem, footerDebugInfo.primaryText],
|
|
65
|
-
);
|
|
46
|
+
|
|
47
|
+
const footerDebugInfo = useMemo(
|
|
48
|
+
() =>
|
|
49
|
+
getRuntimeFooterDebugInfo({
|
|
50
|
+
device,
|
|
51
|
+
appVersion,
|
|
52
|
+
deviceConfig: deviceConfigItem,
|
|
53
|
+
}),
|
|
54
|
+
[appVersion, device, deviceConfigItem],
|
|
55
|
+
);
|
|
56
|
+
const primaryText = useMemo(
|
|
57
|
+
() =>
|
|
58
|
+
footerDebugInfo.primaryText ||
|
|
59
|
+
getRuntimeFooterPrimaryText({
|
|
60
|
+
device,
|
|
61
|
+
appVersion,
|
|
62
|
+
deviceConfig: deviceConfigItem,
|
|
63
|
+
}),
|
|
64
|
+
[appVersion, device, deviceConfigItem, footerDebugInfo.primaryText],
|
|
65
|
+
);
|
|
66
66
|
const companyFooterText = useMemo(
|
|
67
67
|
() => getRuntimeFooterText(defaultCompany),
|
|
68
68
|
[defaultCompany?.configs],
|
|
@@ -71,18 +71,18 @@ const RuntimeInfoFooter = ({
|
|
|
71
71
|
() => getRuntimeFooterTextLines(companyFooterText),
|
|
72
72
|
[companyFooterText],
|
|
73
73
|
);
|
|
74
|
-
const deviceConfigs = useMemo(
|
|
75
|
-
() => parseConfigsObject(deviceConfigItem?.configs),
|
|
76
|
-
[deviceConfigItem?.configs],
|
|
77
|
-
);
|
|
78
|
-
const showDebugInfo = useMemo(
|
|
79
|
-
() =>
|
|
80
|
-
isTruthyValue(
|
|
81
|
-
deviceConfigs?.[DEVICE_RUNTIME_DEBUG_INFO_ENABLED_KEY],
|
|
82
|
-
),
|
|
83
|
-
[deviceConfigs],
|
|
84
|
-
);
|
|
85
|
-
|
|
74
|
+
const deviceConfigs = useMemo(
|
|
75
|
+
() => parseConfigsObject(deviceConfigItem?.configs),
|
|
76
|
+
[deviceConfigItem?.configs],
|
|
77
|
+
);
|
|
78
|
+
const showDebugInfo = useMemo(
|
|
79
|
+
() =>
|
|
80
|
+
isTruthyValue(
|
|
81
|
+
deviceConfigs?.[DEVICE_RUNTIME_DEBUG_INFO_ENABLED_KEY],
|
|
82
|
+
),
|
|
83
|
+
[deviceConfigs],
|
|
84
|
+
);
|
|
85
|
+
|
|
86
86
|
const rotationEntries = useMemo(
|
|
87
87
|
() =>
|
|
88
88
|
getRuntimeFooterRotationEntries({
|
|
@@ -95,43 +95,39 @@ const RuntimeInfoFooter = ({
|
|
|
95
95
|
() => [primaryText, ...footerTextLines].filter(Boolean).join(' • '),
|
|
96
96
|
[footerTextLines, primaryText],
|
|
97
97
|
);
|
|
98
|
+
// Always rotate when there is more than one entry (e.g. 1 footer line + primaryText).
|
|
99
|
+
// Do not fall back to concatenated inlineText in that case.
|
|
98
100
|
const shouldRotate =
|
|
99
|
-
!showDebugInfo &&
|
|
100
|
-
|
|
101
|
-
(
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const
|
|
112
|
-
const
|
|
113
|
-
if (
|
|
114
|
-
return
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return 0;
|
|
132
|
-
}),
|
|
133
|
-
[runtimeDebugSummary?.entries],
|
|
134
|
-
);
|
|
101
|
+
!showDebugInfo && rotationEntries.length > 1;
|
|
102
|
+
const footerEntries = useMemo(
|
|
103
|
+
() =>
|
|
104
|
+
Object.values(runtimeDebugSummary?.entries || {})
|
|
105
|
+
.filter(entry => entry && Array.isArray(entry.lines) && entry.lines.length > 0)
|
|
106
|
+
.sort((left, right) => {
|
|
107
|
+
const leftOrder = Number(left?.order || 100);
|
|
108
|
+
const rightOrder = Number(right?.order || 100);
|
|
109
|
+
if (leftOrder !== rightOrder) {
|
|
110
|
+
return leftOrder - rightOrder;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const leftTime = Date.parse(left?.updatedAt || '');
|
|
114
|
+
const rightTime = Date.parse(right?.updatedAt || '');
|
|
115
|
+
if (Number.isFinite(leftTime) && Number.isFinite(rightTime)) {
|
|
116
|
+
return rightTime - leftTime;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (Number.isFinite(rightTime)) {
|
|
120
|
+
return 1;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (Number.isFinite(leftTime)) {
|
|
124
|
+
return -1;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return 0;
|
|
128
|
+
}),
|
|
129
|
+
[runtimeDebugSummary?.entries],
|
|
130
|
+
);
|
|
135
131
|
const socketEntry = useMemo(
|
|
136
132
|
() => footerEntries.find(entry => entry?.key === 'socket') || null,
|
|
137
133
|
[footerEntries],
|
|
@@ -170,7 +166,7 @@ const RuntimeInfoFooter = ({
|
|
|
170
166
|
[allStores],
|
|
171
167
|
);
|
|
172
168
|
const bottomInset = Math.max(Number(insets.bottom) || 0, 16);
|
|
173
|
-
|
|
169
|
+
|
|
174
170
|
useEffect(() => {
|
|
175
171
|
if (!shouldRotate || rotationEntries.length <= 1) {
|
|
176
172
|
setActiveIndex(0);
|
|
@@ -302,5 +298,5 @@ const RuntimeInfoFooter = ({
|
|
|
302
298
|
</View>
|
|
303
299
|
);
|
|
304
300
|
};
|
|
305
|
-
|
|
306
|
-
export default RuntimeInfoFooter;
|
|
301
|
+
|
|
302
|
+
export default RuntimeInfoFooter;
|