Page MenuHomePhabricator

Group Vue files by feature
Closed, ResolvedPublicFeature

Description

Feature summary (what you would like to be able to do and where):

We have moved to Composition api in Vue: https://phabricator.wikimedia.org/T399845.
Now this allows us to group vue files computed, actions, lifecycle hooks by feature.

Use case(s):

resources/ext.wikilambda.app/components/widgets/publish/PublishDialog.vue would benefit most from Composition-API feature grouping.

An example:

setup( props, { emit } ) {
	// --- Imports & store setup ---
	const store = useMainStore();
	const i18n = inject( 'i18n' );
	const router = useRouter();

	// --- Submission state & validation ---
	const submissionState = {
		isSubmitting: ref( false ),
		showValidationErrors: ref( false ),
		validationMessage: computed( () => store.getValidationMessage )
	};
	function triggerValidation() {
		submissionState.showValidationErrors.value = true;
		store.validateZObject();
	}

	// --- Parser coordination ---
	const parserState = {
		isParserRunning: ref( false ),
		waitForParsers: async () => {
			parserState.isParserRunning.value = true;
			await store.waitForRunningParsers();
			parserState.isParserRunning.value = false;
		}
	};

	// --- Warning / error handling ---
	const warnings = {
		hasWarnings: computed( () => store.hasPublishWarnings ),
		warningMessage: computed( () => store.getPublishWarningMessage ),
		clear: () => store.clearPublishWarnings()
	};

	// --- Dialog controls & emits ---
	const dialogControls = {
		isOpen: computed( () => props.open ),
		close: () => emit( 'update:open', false ),
		confirm: async () => {
			await parserState.waitForParsers();
			triggerValidation();
			if ( !warnings.hasWarnings.value ) {
				submissionState.isSubmitting.value = true;
				await store.publish();
				submissionState.isSubmitting.value = false;
				dialogControls.close();
			}
		}
	};

	// --- Watches / lifecycle grouped by feature ---
	watch( () => props.open, ( open ) => {
		if ( !open ) {
			warnings.clear();
			submissionState.showValidationErrors.value = false;
		}
	} );

	onMounted( () => {
		// log that dialog opened, etc.
	} );

	return {
		...submissionState,
		...parserState,
		...warnings,
		...dialogControls
	};
}

Benefits (why should this be implemented?):

It’s a large dialog component that currently mixes several concerns—submission flow, validation state, parser status, warnings, and UI control flags—all interleaved within one huge setup block. Grouping related refs, computeds, watchers, and methods into labeled sections (e.g., “Submission state,” “Warnings,” “Parser coordination,” “Dialog controls”) would:

  1. Improve readability: Contributors can skim to the section that owns a given behavior instead of chasing variables throughout the file.
  2. Clarify dependencies: Grouping highlights which refs/services belong together, making it easier to see shared state and side effects for a feature.
  3. Ease future refactors: Encapsulated feature groups can be lifted into dedicated composables or extracted out when they grow further, reducing merge conflicts.
  4. Reduce accidental coupling: Isolating logic discourages reusing refs across unrelated features, lowering the risk of regressions.

Given the size and complexity of PublishDialog.vue, organizing it by feature would have the highest payoff compared with smaller components.

Details

Related Changes in Gerrit:

Event Timeline

DSmit-WMF changed the task status from Open to In Progress.Dec 16 2025, 1:29 PM
DSmit-WMF claimed this task.

Change #1218798 had a related patch set uploaded (by Daphne Smit; author: Daphne Smit):

[mediawiki/extensions/WikiLambda@master] Group Vue files by feature

https://gerrit.wikimedia.org/r/1218798

Change #1218798 merged by jenkins-bot:

[mediawiki/extensions/WikiLambda@master] Group Vue files by feature

https://gerrit.wikimedia.org/r/1218798