Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
b48d359
Add list editor components (flat, sortable, nested)
Apr 24, 2026
1114162
Align list-editor variants and polish edit/drag visuals
Apr 24, 2026
cc882b0
Simplify nested list-editor drag feedback
Apr 24, 2026
c46238c
Instruction-based nested drop indicator + reparent
Apr 24, 2026
b7c525f
Fix false "moved" flags + keep source row visible during drag
Apr 24, 2026
4b3bb9d
Align drop line with drag handle column + disable dragged subtree
Apr 24, 2026
4a90d92
Auto-expand make-child target after drop
Apr 24, 2026
c2a3f71
Pivot nested drop UX to pointer-X-for-depth outliner model
Apr 24, 2026
67c2b7a
Polish nested drop UX and rework moved tracking
Apr 24, 2026
6c993eb
Move reorder toolbar into header + nested actions polish
Apr 24, 2026
1688c89
Test coverage for list editors + fix reorder-mode header visibility
Apr 24, 2026
c67101f
Extract shared list-editor primitives (composables, components, styles)
Apr 24, 2026
068955c
Flatten list-editor styles to a shared .a-le-* class namespace
Apr 24, 2026
7ee5716
Move ANestedRow into internal/ and drop A prefix on internal components
Apr 24, 2026
a5bd02e
List-editor Phase 7: keyboard nav, reorder-menu dialogs, unsaved guard
Apr 27, 2026
7a0ff24
List-editor: per-item validation rail (F5)
Apr 27, 2026
32c1b4d
List-editor: closure polish + actions.update slot prop + d.ts cleanup
Apr 27, 2026
ad831bc
List-editor: shared reorder mode (embedded prop) + nested unsaved-key…
Apr 27, 2026
fb949e4
List-editor: rail-color tests + embedded add-button polish + playgrou…
Apr 28, 2026
3bc466c
List-editor: outer reorder toolbar aggregates embedded children's pen…
Apr 28, 2026
d3f47a4
List-editor: post-audit perf + refactor + API polish
Apr 28, 2026
525a876
List-editor: add 50 unit tests for new composables
Apr 28, 2026
bdd014f
update deps
Apr 28, 2026
a13dc7e
Dep bumps + lint cleanup across list editors
May 4, 2026
34c520b
Merge branch 'feat/list-editors' of github.com:anzusystems/common-adm…
May 4, 2026
bbe3ffb
update deps + lint fixes
May 5, 2026
50c4e26
Merge branch 'beta' of github.com:anzusystems/common-admin into feat/…
May 5, 2026
4aed729
List-editor: view-body slot for consumer-rendered view mode
May 5, 2026
b7bfb0f
ImageWidgetMultiple: adopt ASortableListEditor via view-body slot
May 5, 2026
22ba229
Merge remote-tracking branch 'origin/feat/list-editors' into feat/lis…
May 5, 2026
1c056e9
List-editor: format card-grid playground + test to match new lint style
May 5, 2026
cc0e19b
Tests: pre-optimize VRadio, VRadioGroup, VBadge to fix CI flake
May 5, 2026
12dee7f
bump up version
May 5, 2026
5e1ce5a
Merge remote-tracking branch 'origin/beta' into feat/list-editors
May 12, 2026
37f43fd
update deps
May 12, 2026
0e1d4e3
bump up version
May 12, 2026
4cb57a0
fix list-editor delete flow, dirty baseline, readonly inline, i18n label
May 13, 2026
a6127ec
update deps + bump version
May 13, 2026
815498b
fix useDirtyBaseline auto-rebaseline + bump version
May 14, 2026
f094e22
update deps
May 14, 2026
3eb4744
trim verbose comments + bump version
May 14, 2026
a94f0d7
fix lint: trim 2 over-120 comment lines
May 14, 2026
fcbf5a5
wip
May 15, 2026
300a68f
wip
May 15, 2026
183021e
wip
May 15, 2026
8752d7c
wip
May 16, 2026
ebada59
wip
May 18, 2026
75c158a
fix list-editor empty-header rail and addFirst label
May 18, 2026
6793990
wip
May 19, 2026
acfb322
add named sections to the unsaved-changes guard
May 20, 2026
f0bf973
wip
May 20, 2026
c5f2fc2
wip
May 22, 2026
784926e
wip
May 22, 2026
d107196
add disableUnsaved prop to list editors
May 23, 2026
8261a88
require explicit compactField/slot for list-editor row compact text
May 23, 2026
a877305
ASortableListEditor: show up/down move arrows in chip mode on touch d…
May 23, 2026
29a735c
ASortableListEditor: gate dragEnabled on canInteract
May 23, 2026
d44face
AListEditor: defaultExpanded prop + simplify empty state
May 23, 2026
00190fa
wip
May 23, 2026
4fb6d47
wip
May 23, 2026
7b1bb2f
wip
May 24, 2026
74fffbe
wip
May 24, 2026
d4a50ed
wip
May 24, 2026
eaf9050
fix(useCachedItem): keep reactivity alive on prop changes
May 25, 2026
dfc685d
wip
May 29, 2026
d470ed0
wip
May 29, 2026
2220810
wip
Jun 1, 2026
901c3c0
wip
Jun 1, 2026
c9c122e
wip
Jun 5, 2026
de3e563
wip
Jun 6, 2026
dcbc6ff
wip
Jun 10, 2026
3bd6521
wip
Jun 10, 2026
ef506c2
wip
Jun 11, 2026
2fc5a35
feat(labs): list editor extraction APIs — vuelidate sentinel, shared …
Jun 11, 2026
b34f8b3
feat(labs): sortByPosition util — shared non-mutating position orderi…
Jun 11, 2026
76c543f
fix(test): Array.from instead of NodeList spread — build test tsconfi…
Jun 11, 2026
91ee287
fix(labs): managed add/delete marks model write as non-fill — first i…
Jun 11, 2026
8c67281
fix(build): lint:tsc:test uses vue-tsc so .vue imports resolve
Jun 13, 2026
d0d424e
feat(labs): collapse inline editing on save + close add-after menu on…
Jun 13, 2026
794bd1b
feat: createCachedChip factory for cached-entity chips
Jun 13, 2026
05ae248
docs(labs): note manage-delete @deleted cleanup requirement on useNes…
Jun 13, 2026
ab710fb
test(labs): type createCachedChip stub props
Jun 13, 2026
f0b14e6
wip
Jun 13, 2026
6606637
wip
Jun 16, 2026
ec4b498
wip
Jun 17, 2026
30f0b12
wip
Jun 17, 2026
7991226
fix(labs): QA 85050 batch5 — list-editor dirty/validation/nested fixes
Jun 18, 2026
d914c4c
feat(labs): v2 list-editor controller/handle redesign
Jun 21, 2026
7dc4c4d
chore(deps): bump minor dependencies
Jun 21, 2026
c04043b
chore: bump dev version timestamp
Jun 21, 2026
1d8b90d
wip
Jun 24, 2026
28e3ac1
wip
Jun 24, 2026
0ddc2b0
fix(labs): catch failed remote resolves in form/filter autocompletes
Jun 24, 2026
4db04b4
wip
Jun 24, 2026
f487b0b
fix(labs): dirty-gate invalid rail, reorder-badge clear, embedded val…
Jun 25, 2026
54ae303
wip
Jun 25, 2026
257c6cd
test(labs): regression tests for QA 85050 list-editor bugs (U-03/04/0…
Jun 26, 2026
ccd24e8
wip
Jun 26, 2026
43449b1
wip
Jun 26, 2026
1b7cd89
wip
Jun 26, 2026
d26d90c
wip
Jul 1, 2026
b3b4a57
fix(labs): QA 85050 list-editor batch (nested tint, stable keys, inte…
Jul 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pnpm-debug.log*
lerna-debug.log*

node_modules
todo
dist
dist-ssr
*.local
Expand All @@ -28,7 +29,4 @@ dist-ssr

.playwright-cli
.vitest-attachments
todo

# vitest-browser snapshot output — regenerated on every run, never check in.
__screenshots__/
todo
2 changes: 2 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ enableGlobalCache: false
enableScripts: true

nodeLinker: node-modules

npmMinimalAgeGate: 0
80 changes: 41 additions & 39 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@anzusystems/common-admin",
"packageManager": "yarn@4.14.1",
"packageManager": "yarn@4.17.0",
"files": [
"dist",
"src/eslint"
Expand All @@ -20,7 +20,7 @@
"./eslint": "./src/eslint/plugin.mjs",
"./*": "./*"
},
"version": "1.47.0-beta.362",
"version": "1.47.0-beta.dev-1782072599",
"license": "Apache-2.0",
"repository": {
"type": "git",
Expand All @@ -42,7 +42,7 @@
"lint": "[ \"$*\" = \"--fix\" ] && yarn lint:fix || yarn ci",
"lint:fix": "run-s --print-name lint:tsc format lint:oxlint:fix lint:eslint:fix lint:stylelint:fix",
"lint:tsc": "NODE_OPTIONS=--max-old-space-size=4096 vue-tsc --build",
"lint:tsc:test": "NODE_OPTIONS=--max-old-space-size=4096 tsc --build tsconfig.test.json",
"lint:tsc:test": "NODE_OPTIONS=--max-old-space-size=4096 vue-tsc --build tsconfig.test.json",
"lint:eslint": "eslint",
"lint:eslint:fix": "eslint --fix",
"lint:oxlint": "oxlint .",
Expand All @@ -57,65 +57,67 @@
},
"devDependencies": {
"@anzusystems/common-admin": "workspace:*",
"@intlify/unplugin-vue-i18n": "^11.1.2",
"@intlify/unplugin-vue-i18n": "^11.2.4",
"@kyvg/vue3-notification": "^3.4.2",
"@mdi/font": "^7.4.47",
"@sentry/vue": "^10.50.0",
"@shikijs/vitepress-twoslash": "^4.0.2",
"@microsoft/api-extractor": "^7.58.9",
"@sentry/vue": "^10.62.0",
"@shikijs/vitepress-twoslash": "^4.3.0",
"@stylistic/eslint-plugin": "^5.10.0",
"@tsconfig/node22": "^22.0.5",
"@types/node": "^24.12.2",
"@types/node": "^24.13.2",
"@types/rusha": "^0.8.3",
"@types/sortablejs": "^1.15.9",
"@types/webfontloader": "^1.6.38",
"@vitejs/plugin-vue": "^6.0.6",
"@vitest/browser": "^4.1.5",
"@vitest/browser-playwright": "^4.1.5",
"@vitest/ui": "^4.1.5",
"@vue/eslint-config-typescript": "^14.7.0",
"@vue/language-server": "3.2.7",
"@vue/test-utils": "^2.4.9",
"@vitejs/plugin-vue": "^6.0.7",
"@vitest/browser": "^4.1.9",
"@vitest/browser-playwright": "^4.1.9",
"@vitest/ui": "^4.1.9",
"@vue/compiler-dom": "3.5.39",
"@vue/eslint-config-typescript": "^14.9.0",
"@vue/language-server": "3.3.6",
"@vue/test-utils": "^2.4.11",
"@vue/tsconfig": "0.9.1",
"@vuelidate/core": "^2.0.3",
"@vuelidate/validators": "^2.0.4",
"@vueuse/core": "^14.2.1",
"@vueuse/integrations": "^14.2.1",
"axios": "1.15.2",
"@vueuse/core": "14.2.1",
"@vueuse/integrations": "14.2.1",
"axios": "1.18.1",
"cropperjs": "^1.6.2",
"dayjs": "1.11.20",
"eslint": "^10.2.1",
"eslint-plugin-oxlint": "1.62.0",
"eslint-plugin-vue": "10.9.0",
"dayjs": "1.11.21",
"eslint": "^10.6.0",
"eslint-plugin-oxlint": "1.72.0",
"eslint-plugin-vue": "10.9.2",
"eslint-plugin-vuetify": "^2.7.2",
"npm-run-all2": "^8.0.4",
"oxfmt": "^0.47.0",
"oxlint": "1.62.0",
"npm-run-all2": "^9.0.2",
"oxfmt": "^0.57.0",
"oxlint": "1.72.0",
"pinia": "3.0.4",
"playwright": "^1.59.1",
"postcss": "^8.5.12",
"playwright": "^1.61.1",
"postcss": "^8.5.16",
"postcss-html": "^1.8.1",
"postcss-prefix-selector": "^2.1.1",
"rusha": "^0.8.14",
"sass": "1.99.0",
"sass": "1.101.0",
"socket.io-client": "4.8.3",
"sortablejs": "^1.15.7",
"stylelint": "17.9.1",
"stylelint": "17.14.0",
"stylelint-config-recommended-vue": "^1.6.1",
"stylelint-config-standard-scss": "^17.0.0",
"typescript": "5.9.3",
"unplugin": "3.0.0",
"uuid": "^14.0.0",
"vite": "7.3.2",
"vite-plugin-dts": "4.5.4",
"unplugin": "3.3.0",
"unplugin-dts": "^1.0.3",
"uuid": "^14.0.1",
"vite": "7.3.6",
"vite-plugin-vuetify": "^2.1.3",
"vitepress": "1.6.4",
"vitest": "^4.1.5",
"vue": "3.5.33",
"vue-eslint-parser": "^10.4.0",
"vue-i18n": "11.4.0",
"vue-router": "5.0.6",
"vue-tsc": "3.2.7",
"vuetify": "4.0.6",
"vitest": "^4.1.9",
"vue": "3.5.39",
"vue-eslint-parser": "^10.4.1",
"vue-i18n": "11.4.6",
"vue-router": "5.1.0",
"vue-tsc": "3.3.6",
"vuetify": "4.1.2",
"webfontloader": "^1.6.28"
},
"peerDependencies": {
Expand Down
66 changes: 66 additions & 0 deletions src/components/createCachedChip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { type Component, defineComponent, h, type PropType } from 'vue'
import ACachedChip from '@/components/ACachedChip.vue'
import type { DocId, IntegerId } from '@/types/common'

export type CachedChipId = null | undefined | IntegerId | DocId

export interface CreateCachedChipOptions {
/**
* Composable returning the per-id cache getter — invoked inside the chip's
* setup so the backing cache store resolves in component scope. The `id`
* param is `any` to match `ACachedChip` and accept both numeric- and
* doc-id getters regardless of their exact parameter type.
*/
useGetCachedFn: () => (id: any) => unknown
/** Named route the chip links to (e.g. `'/(cms)/desks/[id]'`). */
route: string
/** Dot-path into the cached entity for the chip label (e.g. `'name'`). */
displayTextPath: string
/** Static props baked onto every instance (e.g. a fixed `textOnly`). */
chipProps?: Record<string, unknown>
/** Component name for devtools / warnings. */
name?: string
}

/**
* Builds a cached-entity chip from a domain's cache composable + route, so each
* per-domain `CachedXChip.vue` collapses to a single factory call instead of a
* full SFC re-binding `ACachedChip`. Caller-passed attributes (`size`, `color`,
* `disable-click`, …) and slots fall through to `ACachedChip`.
*
* Use in an SFC's plain `<script lang="ts">` (not `setup`):
* ```ts
* export default createCachedChip({
* useGetCachedFn: () => useCachedDesks().getCachedDesk,
* route: '/(cms)/desks/[id]',
* displayTextPath: 'name',
* })
* ```
*/
export function createCachedChip(options: CreateCachedChipOptions): Component {
return defineComponent({
name: options.name ?? 'CachedChip',
inheritAttrs: false,
// Vue skips type validation for null/undefined on non-required props, so a
// null id (the common "empty" case) won't warn despite the typed prop.
props: {
id: { type: [Number, String] as PropType<CachedChipId>, default: null },
},
setup(props, { attrs, slots }) {
const getCachedFn = options.useGetCachedFn()
return () =>
h(
ACachedChip,
{
id: props.id,
getCachedFn,
route: options.route,
displayTextPath: options.displayTextPath,
...options.chipProps,
...attrs,
},
slots,
)
},
})
}
Loading
Loading