@ethisyscore/eslint-plugin-coreconnect 1.90.0 → 1.92.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ethisyscore/eslint-plugin-coreconnect",
3
- "version": "1.90.0",
3
+ "version": "1.92.0",
4
4
  "description": "ESLint rules enforcing EthisysCore plugin frontend conventions. Published so a new rule reaches every plugin on a version bump, rather than being copied into each scaffold and drifting.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/index.js CHANGED
@@ -5,6 +5,7 @@ import noLocalCompletenessBanner from "./rules/no-local-completeness-banner.js";
5
5
  import noLocalDataGrid from "./rules/no-local-data-grid.js";
6
6
  import noLocalDateInput from "./rules/no-local-date-input.js";
7
7
  import noLocalEmptyState from "./rules/no-local-empty-state.js";
8
+ import noLocalInProgressBanner from "./rules/no-local-in-progress-banner.js";
8
9
  import noLocalMappingEditor from "./rules/no-local-mapping-editor.js";
9
10
  import noLocalSearchInput from "./rules/no-local-search-input.js";
10
11
  import noParamInNavPath from "./rules/no-param-in-nav-path.js";
@@ -17,6 +18,7 @@ const rules = {
17
18
  "no-local-data-grid": noLocalDataGrid,
18
19
  "no-local-date-input": noLocalDateInput,
19
20
  "no-local-empty-state": noLocalEmptyState,
21
+ "no-local-in-progress-banner": noLocalInProgressBanner,
20
22
  "no-local-mapping-editor": noLocalMappingEditor,
21
23
  "no-local-search-input": noLocalSearchInput,
22
24
  "no-param-in-nav-path": noParamInNavPath,
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Disallow a plugin declaring its own in-progress / background-job banner.
3
+ *
4
+ * The backstop to a promotion, and the sibling of `no-local-empty-state` - deliberately, because
5
+ * the two components are one decision. A surface with no in-progress state does not stay silent: it
6
+ * renders its EMPTY state instead, which claims the operation finished and produced nothing. That
7
+ * defect shipped twice in one week on a single page (engineering-skills UX-113).
8
+ *
9
+ * Three hand-written copies existed at promotion time - the tech repo-import indicator, the
10
+ * self-healing fix-run banner, and the monolith's own OperationGlobalBanner - with a byte-identical
11
+ * `height: 6, borderRadius: 3` progress bar, and that same pair repeated in ten more places. A rule
12
+ * describing the correct markup did not stop the second occurrence; one implementation can.
13
+ *
14
+ * Fires on a DECLARATION, never a use, so importing `InProgressBanner` from
15
+ * `@ethisyscore/plugin-ui/components/shared` and rendering it is what the rule wants - including
16
+ * wrapping it in a plugin-specific component that feeds it that plugin's own progress data, which
17
+ * the shared helper exempts by recognising the canonical binding.
18
+ *
19
+ * @type {import("eslint").Rule.RuleModule}
20
+ */
21
+ import { createNoLocalComponentRule } from "./componentDeclarations.js";
22
+
23
+ export default createNoLocalComponentRule({
24
+ // The names this banner keeps being rewritten under. `Indicator` is included because the tech
25
+ // copy was called `TechImportIndicator`, and a suffix match is what catches the plugin-prefixed
26
+ // spellings; the shared helper's hook guard keeps `useImportIndicator` out of it.
27
+ pattern: /(InProgressBanner|ImportIndicator|ProgressBanner|ProgressIndicator|OperationBanner|BusyBanner)$/,
28
+ canonical: { source: "@ethisyscore/plugin-ui/components/shared", name: "InProgressBanner" },
29
+ messageId: "noLocalInProgressBanner",
30
+ description:
31
+ "Disallow a locally-declared in-progress banner - import InProgressBanner from @ethisyscore/plugin-ui/components/shared",
32
+ message:
33
+ "'{{name}}' looks like a local in-progress banner. Import { InProgressBanner } from '@ethisyscore/plugin-ui/components/shared' instead, so a background job looks the same wherever it appears. It takes title, children, value (omit for an indeterminate bar), action and sx.",
34
+ });