Aller au contenu

MediaWiki:Gadget-BatchDelete.js

De Wiki Undertale FR

Note : après avoir publié vos modifications, il se peut que vous deviez forcer le rechargement complet du cache de votre navigateur pour voir les changements.

  • Firefox / Safari : maintenez la touche Maj (Shift) en cliquant sur le bouton Actualiser ou appuyez sur Ctrl + F5 ou Ctrl + R (⌘ + R sur un Mac).
  • Google Chrome : appuyez sur Ctrl + Maj + R (⌘ + Shift + R sur un Mac).
  •  Edge : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl + F5.
/* TODO: MediaWiki 1.45 allows loading .vue files in Gadgets (T340460) */
const {createMwApp, ref} = mw.loader.require('vue');
const {
    CdxButton,
    CdxDialog,
    CdxField,
    CdxLookup,
    CdxTextArea,
    CdxTextInput
} = mw.loader.require('@wikimedia/codex');

const api = new mw.Api();
const dialogOpen = ref(false);
const reason = ref('');
const logList = ref('');
const pageList = ref('');
const selectedCategory = ref(null);
const menuItems = ref([]);
const inProgress = ref(false);

function log(message) {
    logList.value = `${logList.value.trim()}\n${message}`.trim();
}

function deleteOnce() {
    if (!inProgress.value) {
        return;
    }
    const pages = pageList.value
        .trim()
        .split('\n')
        .map(p => p.trim())
        .filter(Boolean);
    if (!pages.length) {
        log('Finished deleting pages!');
        inProgress.value = false;
        return;
    }
    const title = pages.shift();
    pageList.value = pages.join('\n');
    api.postWithToken('csrf', {
        action: 'delete',
        title,
        reason: reason.value,
        tags: ['batchdelete'],
        bot: true
    }).done(deleteOnce).fail(code => {
        log(`Error deleting ${title}: ${code}.`);
        deleteOnce();
    });
}

function startBatchDelete() {
    inProgress.value = true;
    deleteOnce();
}

function pauseBatchDelete() {
    inProgress.value = false;
}

function closeDialog() {
    pauseBatchDelete();
    dialogOpen.value = false;
}

function categorySelected(cmtitle, cmcontinue) {
    selectedCategory.value = null;
    api.get({
        action: 'query',
        list: 'categorymembers',
        cmtitle,
        cmcontinue,
        cmlimit: 'max'
    }).then(data => {
        pageList.value = `${pageList.value.trim()}\n${
            data.query.categorymembers
                .map(c => c.title)
                .join('\n')
        }`.trim();
    });
}

function onCategoryInput(search) {
    if (!search) {
        return;
    }
    api.get({
        action: 'opensearch',
        namespace: 14,
        search,
        warningsaserror: true
    }).then(([, names, descriptions]) => {
        menuItems.value = names.map((name, index) => ({
            label: name.replace(/^[^:]+:/, ''),
            value: name,
            description: descriptions[index]
        }));
    });
}

const app = createMwApp({
    name: 'batch-delete',
    components: {
        CdxButton,
        CdxDialog,
        CdxField,
        CdxLookup,
        CdxTextArea,
        CdxTextInput
    },
    template: `
    <cdx-dialog
        v-model:open="dialogOpen"
        title="Suppression groupée"
        :use-close-button="true"
    >
        <form>
            <cdx-field>
                <cdx-text-input v-model="reason" />
                <template #label>Raison de la suppression</template>
            </cdx-field>
            <cdx-field>
                <cdx-lookup
                    v-model:selected="selectedCategory"
                    :menu-items="menuItems"
                    @update:selected="categorySelected"
                    @input="onCategoryInput"
                />
                <template #label>Ajouter une catégorie</template>
                <template #description>Entrer le nom d'une catégorie pour ajouter tout son contenu à la liste des pages à supprimer</template>
            </cdx-field>
            <cdx-field>
                <cdx-text-area v-model="pageList" :disabled="inProgress" rows="10" />
                <template #label>Liste des pages à supprimer</template>
                <template #description>Chaque nom de page doit se trouver sur une ligne différente.</template>
            </cdx-field>
            <cdx-field>
                <cdx-text-area v-model="logList" :disabled="true" rows="10" />
                <template #label>Journal</template>
                <template #description>Les erreurs qui se produisent seront consignées ici.</template>
            </cdx-field>
        </form>
        <template #footer>
            <cdx-button @click="closeDialog">Fermer</cdx-button>
            <cdx-button :disabled="!inProgress" @click="pauseBatchDelete">Pause</cdx-button>
            <cdx-button :disabled="inProgress" @click="startBatchDelete">Démarrer</cdx-button>
        </template>
    </cdx-dialog>
    `,
    setup() {
        return {
            dialogOpen,
            reason,
            pageList,
            logList,
            selectedCategory,
            menuItems,
            inProgress,
            startBatchDelete,
            closeDialog,
            pauseBatchDelete,
            categorySelected,
            onCategoryInput
        };
    }
});
const root = document.createElement('div');
document.body.appendChild(root);
app.mount(root);
mw.util.addPortletLink(
    'p-tb',
    '#',
    'Suppression groupée',
    't-batch-delete',
    'Supprimer plusieurs pages à la fois.'
).addEventListener('click', event => {
    event.preventDefault();
    dialogOpen.value = true;
});