Localisation updates from https://translatewiki.net.
[mediawiki.git] / resources / src / mediawiki.special.block / components / NamespacesField.vue
blob3885869f670f8d52c84f4494df9d79b32b73a935
1 <template>
2         <cdx-field>
3                 <template #label>
4                         {{ $i18n( 'ipb-namespaces-label' ).text() }}
5                 </template>
6                 <cdx-multiselect-lookup
7                         v-model:input-chips="chips"
8                         v-model:selected="selection"
9                         class="mw-block-namespaces"
10                         :menu-items="menuItems"
11                         :menu-config="menuConfig"
12                         :aria-label="$i18n( 'ipb-namespaces-label' ).text()"
13                         :placeholder="$i18n( 'block-namespaces-placeholder' ).text()"
14                         @input="onInput"
15                         @update:input-chips="onUpdateChips"
16                 ></cdx-multiselect-lookup>
17         </cdx-field>
18 </template>
20 <script>
21 const { defineComponent, ref } = require( 'vue' );
22 const { storeToRefs } = require( 'pinia' );
23 const { CdxField, ChipInputItem, CdxMultiselectLookup } = require( '@wikimedia/codex' );
24 const useBlockStore = require( '../stores/block.js' );
26 /**
27  * Namespaces field component for use by Special:Block.
28  *
29  * @todo Abstract for general use in MediaWiki (T375220)
30  */
31 module.exports = exports = defineComponent( {
32         name: 'NamespacesField',
33         components: {
34                 CdxField,
35                 CdxMultiselectLookup
36         },
37         setup() {
38                 const { namespaces } = storeToRefs( useBlockStore() );
39                 const selection = ref( namespaces.value );
40                 const mwNamespaces = mw.config.get( 'wgFormattedNamespaces' );
41                 mwNamespaces[ '0' ] = mw.msg( 'blanknamespace' );
42                 const initialMenuItems = Object.keys( mwNamespaces )
43                         // Exclude virtual namespaces
44                         .filter( ( id ) => Number( id ) >= 0 )
45                         .map( ( id ) => ( {
46                                 value: Number( id ),
47                                 label: mwNamespaces[ id ]
48                         } ) );
49                 const chips = ref(
50                         namespaces.value.map( ( nsId ) => ( { value: nsId, label: mwNamespaces[ nsId ] } ) )
51                 );
52                 const menuItems = ref( initialMenuItems );
53                 const menuConfig = { visibleItemLimit: 10 };
55                 /**
56                  * On input, filter the menu items.
57                  *
58                  * @param {string} value
59                  */
60                 function onInput( value ) {
61                         if ( value ) {
62                                 // eslint-disable-next-line arrow-body-style
63                                 menuItems.value = initialMenuItems.filter( ( item ) => {
64                                         return item.label.toLowerCase().indexOf( value.toLowerCase() ) !== -1;
65                                 } );
66                         } else {
67                                 menuItems.value = initialMenuItems;
68                         }
69                 }
71                 /**
72                  * Update the store with the new chip values.
73                  *
74                  * @param {ChipInputItem[]} newChips
75                  */
76                 function onUpdateChips( newChips ) {
77                         namespaces.value = newChips.map( ( chip ) => chip.value );
78                 }
80                 return {
81                         chips,
82                         selection,
83                         menuItems,
84                         menuConfig,
85                         onInput,
86                         onUpdateChips
87                 };
88         }
89 } );
90 </script>