User:Asked42/QuickCat.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
// <nowiki>
if (typeof createCategories === 'undefined') {
var createCategories = {};
}
createCategories.api = new mw.Api();
mw.loader.using('@wikimedia/codex').then(function(require) {
const Vue = require('vue');
const Codex = require('@wikimedia/codex');
const mountPoint = document.body.appendChild(document.createElement('div'));
Vue.createMwApp({
data: function() {
return {
year: '',
categoryType: 'date',
previewContent: '',
selectedCategories: [],
showMessage: false,
messageType: '',
messageContent: '',
showProgress: false,
showConfirmDialog: false,
showSuccessDialog: false,
monthOptions: [
{ value: 1, label: 'জানুয়ারি' },
{ value: 2, label: 'ফেব্রুয়ারি' },
{ value: 3, label: 'মার্চ' },
{ value: 4, label: 'এপ্রিল' },
{ value: 5, label: 'মে' },
{ value: 6, label: 'জুন' },
{ value: 7, label: 'জুলাই' },
{ value: 8, label: 'আগস্ট' },
{ value: 9, label: 'সেপ্টেম্বর' },
{ value: 10, label: 'অক্টোবর' },
{ value: 11, label: 'নভেম্বর' },
{ value: 12, label: 'ডিসেম্বর' }
],
categoryTypeOptions: [
{ label: 'তারিখ বিষয়শ্রেণী', value: 'date' },
{ label: 'মাস বিষয়শ্রেণী', value: 'month' }
],
expanded: false,
chips: [],
selectedValue: [],
createdPages: 0,
updatedPages: 0,
totalTime: 0
};
},
computed: {
isFormValid: function() {
return this.year && this.selectedValue.length > 0;
},
activeDescendant: function() {
const highlightedItem = this.$refs.menu && this.$refs.menu.getHighlightedMenuItem();
return highlightedItem ? highlightedItem.id : undefined;
},
menuId: function() {
return 'month-menu';
}
},
methods: {
showConfirmationDialog: function() {
if (this.isFormValid) {
this.showConfirmDialog = true;
} else {
this.showWarningMessage('অনুগ্রহ করে বছর এবং অন্তত একটি মাস নির্বাচন করুন।');
}
},
generatePreview: function() {
this.resetMessageState();
if (this.isFormValid) {
this.showProgress = true;
let previewPromises;
if (this.categoryType === 'date') {
this.previewContent = '{{Wn/bn/তারিখশ্রেণী}}';
previewPromises = this.getPreviewDateCategories(this.year, this.selectedValue);
} else {
this.previewContent = '{{Wn/bn/মাসশ্রেণী}}';
previewPromises = this.getPreviewMonthCategories(this.year, this.selectedValue);
}
Promise.all(previewPromises)
.then((previewItems) => {
this.selectedCategories = previewItems.flat().map(item => ({
...item,
selected: true
}));
this.showProgress = false;
})
.catch((error) => {
console.error('Error generating preview:', error);
this.showProgress = false;
this.showErrorMessage('প্রাকদর্শন তৈরি করার সময় একটি ত্রুটি ঘটেছে৷');
});
} else {
this.showWarningMessage('অনুগ্রহ করে বছর এবং অন্তত একটি মাস নির্বাচন করুন।');
}
},
createCategories: function() {
this.resetMessageState();
this.showConfirmDialog = false;
this.showProgress = true;
const selectedCategories = this.selectedCategories.filter(category => category.selected);
if (selectedCategories.length === 0) {
this.showWarningMessage('অনুগ্রহ করে অন্তত একটি বিষয়শ্রেণী নির্বাচন করুন।');
this.showProgress = false;
return;
}
this.createdPages = 0;
this.updatedPages = 0;
const startTime = Date.now();
// Sort categories to ensure they are created serially
selectedCategories.sort((a, b) => {
const aMatch = a.title.match(/(\d+)/);
const bMatch = b.title.match(/(\d+)/);
return (aMatch && bMatch) ? parseInt(aMatch[1]) - parseInt(bMatch[1]) : 0;
});
const createCategoriesSequentially = (categories, index = 0) => {
if (index >= categories.length) {
this.totalTime = (Date.now() - startTime) / 1000;
this.showProgress = false;
this.showSuccessDialog = true;
this.showSuccessMessage('বিষয়শ্রেণীগুলো সফলভাবে তৈরি/হালনাগাদ করা হয়েছে।');
return;
}
const category = categories[index];
this.checkAndUpdateCategory(category.title, this.previewContent)
.then((result) => {
if (result === 'create') this.createdPages++;
if (result === 'update') this.updatedPages++;
createCategoriesSequentially(categories, index + 1);
})
.catch((error) => {
console.error('Error creating/updating category:', error);
this.showProgress = false;
this.showErrorMessage('বিষয়শ্রেণী তৈরি/হালনাগাদ করার সময় একটি ত্রুটি ঘটেছে৷');
});
};
createCategoriesSequentially(selectedCategories);
},
resetForm: function() {
this.year = '';
this.selectedValue = [];
this.chips = [];
this.categoryType = 'date';
this.previewContent = '';
this.selectedCategories = [];
this.resetMessageState();
},
resetMessageState: function() {
this.showMessage = false;
this.messageType = '';
this.messageContent = '';
},
showWarningMessage: function(message) {
this.messageType = 'warning';
this.messageContent = message;
this.showMessage = true;
},
showErrorMessage: function(message) {
this.messageType = 'error';
this.messageContent = message;
this.showMessage = true;
},
showSuccessMessage: function(message) {
this.messageType = 'success';
this.messageContent = message;
this.showMessage = true;
},
handleMessageDismiss: function() {
this.showMessage = false;
},
handleSuccessDialogClose: function() {
this.showSuccessDialog = false;
this.resetForm();
},
handleConfirmDialogCancel: function() {
this.showConfirmDialog = false;
},
getPreviewDateCategories: function(year, months) {
return months.map(month => {
const daysInMonth = new Date(year, month, 0).getDate();
return Array.from({length: daysInMonth}, (_, i) => ({
title: `Category:Wn/bn/${this.convertToBengaliNumber(i + 1)} ${this.getBengaliMonthName(month)} ${this.convertToBengaliNumber(year)}`
}));
});
},
getPreviewMonthCategories: function(year, months) {
return months.map(month => [{
title: `Category:Wn/bn/${this.getBengaliMonthName(month)} ${this.convertToBengaliNumber(year)}`
}]);
},
checkAndUpdateCategory: function(title, content) {
return createCategories.api.get({
action: 'query',
format: 'json',
prop: 'revisions',
titles: title,
formatversion: '2',
rvprop: 'content',
rvslots: '*'
}).then(data => {
const page = data.query.pages[0];
const action = page.missing !== undefined ? 'create' : 'update';
return this.createOrUpdateCategory(title, content, action);
});
},
createOrUpdateCategory: function(title, content, actionType) {
const summary = actionType === 'create'
? '[[User:Asked42/উইকিসংবাদ স্ক্রিপ্ট#QuickCat|QuickCat]] ব্যবহার করে নতুন বিষয়শ্রেণী পৃষ্ঠা তৈরি করা'
: '[[User:Asked42/উইকিসংবাদ স্ক্রিপ্ট#QuickCat|QuickCat]] ব্যবহার করে বিষয়শ্রেণী পৃষ্ঠা হালনাগাদ করা';
return createCategories.api.postWithToken('csrf', {
action: 'edit',
title: title,
text: content,
summary: summary
}).then(() => actionType);
},
convertToBengaliNumber: function(num) {
return num.toString().replace(/\d/g, d => "০১২৩৪৫৬৭৮৯"[d]);
},
getBengaliMonthName: function(month) {
const monthNames = [
"জানুয়ারি", "ফেব্রুয়ারি", "মার্চ", "এপ্রিল", "মে", "জুন",
"জুলাই", "আগস্ট", "সেপ্টেম্বর", "অক্টোবর", "নভেম্বর", "ডিসেম্বর"
];
return monthNames[month - 1];
},
handleChipChange: function(newChips) {
this.selectedValue = newChips.map((chip) => chip.value);
},
handleSelection: function(newSelected) {
this.chips = newSelected.map((value) => {
const selectedMonth = this.monthOptions.find(m => m.value === value);
return { value, label: selectedMonth.label };
});
},
onKeydown: function(e) {
if (e.key === ' ') {
return;
}
if (this.$refs.menu) {
this.$refs.menu.delegateKeyNavigation(e);
}
},
onClick: function() {
this.expanded = true;
}
},
template: `
<div style="max-width: 500px; margin: 20px auto; padding: 20px; border: 1px solid #ccc; border-radius: 8px;">
<cdx-label input-id="cc_year">
বছর
</cdx-label>
<cdx-text-input id="cc_year" v-model="year" placeholder="বছর লিখুন" style="margin-bottom: 15px;" />
<cdx-label input-id="cc_months">
মাস বাছাই করুন
</cdx-label>
<div class="cdx-docs-multiselect-menu" style="margin-bottom: 15px; position: relative;">
<cdx-chip-input
ref="chipInput"
v-model:input-chips="chips"
class="cdx-docs-multiselect-menu__input"
role="combobox"
:aria-expanded="expanded"
:aria-controls="menuId"
:aria-activedescendant="activeDescendant"
remove-button-label="Remove"
@click="onClick"
@blur="expanded = false"
@keydown="onKeydown"
@update:input-chips="handleChipChange"
></cdx-chip-input>
<cdx-menu
:id="menuId"
ref="menu"
v-model:selected="selectedValue"
v-model:expanded="expanded"
:menu-items="monthOptions"
@update:selected="handleSelection"
style="position: absolute; width: 100%; z-index: 1;"
></cdx-menu>
</div>
<cdx-label input-id="cc_type">
বিষয়শ্রেণীর ধরণ
</cdx-label>
<cdx-select id="cc_type" v-model:selected="categoryType" :menu-items="categoryTypeOptions" default-label="বিষয়শ্রেণীর ধরণ নির্বাচন করুন" style="margin-bottom: 15px;" />
<div style="display: flex; justify-content: space-between;">
<cdx-button @click="generatePreview" action="progressive" weight="primary" style="margin-bottom: 15px; margin-right: 5px;">
প্রাকদর্শন
</cdx-button>
<cdx-button @click="resetForm" action="normal" style="margin-bottom: 15px;">
নতুন করে শুরু করুন
</cdx-button>
</div>
<div v-if="selectedCategories.length > 0">
<cdx-label input-id="cc_preview">
নির্বাচিত বিষয়শ্রেণী পাতাগুলোতে যা যোগ করা হবে:
</cdx-label>
<cdx-textarea id="cc_preview" v-model="previewContent" aria-label="বিষয়শ্রেণী বিষয়বস্তু" rows="4" style="margin-bottom: 15px;" />
<cdx-label>নির্বাচিত বিষয়শ্রেণী</cdx-label>
<div style="max-height: 200px; overflow-y: auto; border: 1px solid #ccc; padding: 10px; margin-bottom: 15px;">
<cdx-checkbox v-for="category in selectedCategories" :key="category.title" v-model="category.selected" :input-id="category.title">
{{ category.title }}
</cdx-checkbox>
</div>
<cdx-button @click="showConfirmationDialog" action="progressive" weight="primary" style="margin-bottom: 15px;">
বিষয়শ্রেণী তৈরি করুন
</cdx-button>
</div>
<cdx-progress-bar v-if="showProgress" inline />
</div>
<cdx-dialog v-if="showConfirmDialog" :open="showConfirmDialog" @close="handleConfirmDialogCancel" title="নিশ্চিতকরণ">
<template #default>
<p>আপনি কি নিশ্চিত যে আপনি নির্বাচিত বিষয়শ্রেণীগুলি তৈরি/হালনাগাদ করতে চান?</p>
</template>
<template #footer>
<cdx-button action="progressive" weight="primary" @click="createCategories" style="margin-right: 10px;">
হ্যাঁ, নিশ্চিত
</cdx-button>
<cdx-button action="normal" @click="handleConfirmDialogCancel">
বাতিল
</cdx-button>
</template>
</cdx-dialog>
<cdx-dialog v-if="showSuccessDialog" :open="showSuccessDialog" @close="handleSuccessDialogClose" title="সফল অপারেশন">
<template #default>
<p>বিষয়শ্রেণীগুলো সফলভাবে তৈরি/হালনাগাদ করা হয়েছে।</p>
<p>মোট তৈরি করা পৃষ্ঠা: {{ createdPages }}</p>
<p>মোট হালনাগাদ করা পৃষ্ঠা: {{ updatedPages }}</p>
<p>মোট সময় লেগেছে: {{ totalTime.toFixed(2) }} সেকেন্ড</p>
</template>
<template #footer>
<cdx-button action="progressive" weight="primary" @click="handleSuccessDialogClose">
ঠিক আছে
</cdx-button>
</template>
</cdx-dialog>
<div v-if="showMessage" style="position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); width: 60%; z-index: 999;">
<cdx-message
:type="messageType"
:fade-in="true"
:auto-dismiss="messageType === 'success'"
:display-time="3000"
dismiss-button-label="Close"
@dismissed="handleMessageDismiss"
>
{{ messageContent }}
</cdx-message>
</div>
`
})
.component('cdx-text-input', Codex.CdxTextInput)
.component('cdx-textarea', Codex.CdxTextArea)
.component('cdx-select', Codex.CdxSelect)
.component('cdx-checkbox', Codex.CdxCheckbox)
.component('cdx-button', Codex.CdxButton)
.component('cdx-progress-bar', Codex.CdxProgressBar)
.component('cdx-message', Codex.CdxMessage)
.component('cdx-dialog', Codex.CdxDialog)
.component('cdx-label', Codex.CdxLabel)
.component('cdx-chip-input', Codex.CdxChipInput)
.component('cdx-menu', Codex.CdxMenu)
.mount('#category-create-form');
});
// </nowiki>