広告に関する修正(配信中の絞り込み、Create時にMiAdを返すように) (#11913)

* ad/createにて作成したMiAdを返すように

別なツールからアップデート等をする際に必要

* ad/list取得に現在掲載中のオプションを作成

* スイッチで配信中のみを絞れるように

* update CHANGELOG

* エラー修正

* Update packages/frontend/src/pages/admin/ads.vue

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
This commit is contained in:
nenohi 2023-09-29 12:27:05 +09:00 committed by GitHub
parent b9da1415a5
commit 9c448055a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 10 deletions

View file

@ -24,9 +24,11 @@
### Client ### Client
- Enhance: モデレーションログ機能の強化 - Enhance: モデレーションログ機能の強化
- Enhance: Plugin:register_post_form_actionを用いてCWを取得・変更できるように - Enhance: Plugin:register_post_form_actionを用いてCWを取得・変更できるように
- Feat:admin/ad/listにて掲載中の広告が絞り込めるように
### Server ### Server
- Enhance: MasterプロセスのPIDを書き出せるように - Enhance: MasterプロセスのPIDを書き出せるように
- Feat:admin/ad/createにてレスポンス200、設定した広告情報を返すように
## 2023.9.1 ## 2023.9.1

View file

@ -41,7 +41,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private idService: IdService, private idService: IdService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
await this.adsRepository.insert({ const ad = await this.adsRepository.insert({
id: this.idService.genId(), id: this.idService.genId(),
createdAt: new Date(), createdAt: new Date(),
expiresAt: new Date(ps.expiresAt), expiresAt: new Date(ps.expiresAt),
@ -53,7 +53,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
ratio: ps.ratio, ratio: ps.ratio,
place: ps.place, place: ps.place,
memo: ps.memo, memo: ps.memo,
}); }).then(r => this.adsRepository.findOneByOrFail({ id: r.identifiers[0].id }));
return ad;
}); });
} }
} }

View file

@ -22,6 +22,7 @@ export const paramDef = {
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
sinceId: { type: 'string', format: 'misskey:id' }, sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' },
publishing: { type: 'boolean', default: false },
}, },
required: [], required: [],
} as const; } as const;
@ -36,6 +37,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const query = this.queryService.makePaginationQuery(this.adsRepository.createQueryBuilder('ad'), ps.sinceId, ps.untilId); const query = this.queryService.makePaginationQuery(this.adsRepository.createQueryBuilder('ad'), ps.sinceId, ps.untilId);
if (ps.publishing) {
query.andWhere('ad.expiresAt > :now', { now: new Date() }).andWhere('ad.startsAt <= :now', { now: new Date() });
}
const ads = await query.limit(ps.limit).getMany(); const ads = await query.limit(ps.limit).getMany();
return ads; return ads;

View file

@ -5,11 +5,16 @@ SPDX-License-Identifier: AGPL-3.0-only
<template> <template>
<MkStickyContainer> <MkStickyContainer>
<template #header><XHeader :actions="headerActions" :tabs="headerTabs"/></template> <template #header>
<XHeader :actions="headerActions" :tabs="headerTabs" />
</template>
<MkSpacer :contentMax="900"> <MkSpacer :contentMax="900">
<MkSwitch :modelValue="publishing" @update:modelValue="onChangePublishing">
{{ i18n.ts.publishing }}
</MkSwitch>
<div> <div>
<div v-for="ad in ads" class="_panel _gaps_m" :class="$style.ad"> <div v-for="ad in ads" class="_panel _gaps_m" :class="$style.ad">
<MkAd v-if="ad.url" :specify="ad"/> <MkAd v-if="ad.url" :specify="ad" />
<MkInput v-model="ad.url" type="url"> <MkInput v-model="ad.url" type="url">
<template #label>URL</template> <template #label>URL</template>
</MkInput> </MkInput>
@ -46,7 +51,8 @@ SPDX-License-Identifier: AGPL-3.0-only
<span> <span>
{{ i18n.ts._ad.timezoneinfo }} {{ i18n.ts._ad.timezoneinfo }}
<div v-for="(day, index) in daysOfWeek" :key="index"> <div v-for="(day, index) in daysOfWeek" :key="index">
<input :id="`ad${ad.id}-${index}`" type="checkbox" :checked="(ad.dayOfWeek & (1 << index)) !== 0" @change="toggleDayOfWeek(ad, index)"> <input :id="`ad${ad.id}-${index}`" type="checkbox" :checked="(ad.dayOfWeek & (1 << index)) !== 0"
@change="toggleDayOfWeek(ad, index)">
<label :for="`ad${ad.id}-${index}`">{{ day }}</label> <label :for="`ad${ad.id}-${index}`">{{ day }}</label>
</div> </div>
</span> </span>
@ -55,8 +61,10 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #label>{{ i18n.ts.memo }}</template> <template #label>{{ i18n.ts.memo }}</template>
</MkTextarea> </MkTextarea>
<div class="buttons"> <div class="buttons">
<MkButton class="button" inline primary style="margin-right: 12px;" @click="save(ad)"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton> <MkButton class="button" inline primary style="margin-right: 12px;" @click="save(ad)"><i
<MkButton class="button" inline danger @click="remove(ad)"><i class="ti ti-trash"></i> {{ i18n.ts.remove }}</MkButton> class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
<MkButton class="button" inline danger @click="remove(ad)"><i class="ti ti-trash"></i> {{ i18n.ts.remove }}
</MkButton>
</div> </div>
</div> </div>
<MkButton class="button" @click="more()"> <MkButton class="button" @click="more()">
@ -75,6 +83,7 @@ import MkInput from '@/components/MkInput.vue';
import MkTextarea from '@/components/MkTextarea.vue'; import MkTextarea from '@/components/MkTextarea.vue';
import MkRadios from '@/components/MkRadios.vue'; import MkRadios from '@/components/MkRadios.vue';
import MkFolder from '@/components/MkFolder.vue'; import MkFolder from '@/components/MkFolder.vue';
import MkSwitch from '@/components/MkSwitch.vue';
import FormSplit from '@/components/form/split.vue'; import FormSplit from '@/components/form/split.vue';
import * as os from '@/os.js'; import * as os from '@/os.js';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
@ -86,8 +95,9 @@ let ads: any[] = $ref([]);
const localTime = new Date(); const localTime = new Date();
const localTimeDiff = localTime.getTimezoneOffset() * 60 * 1000; const localTimeDiff = localTime.getTimezoneOffset() * 60 * 1000;
const daysOfWeek: string[] = [i18n.ts._weekday.sunday, i18n.ts._weekday.monday, i18n.ts._weekday.tuesday, i18n.ts._weekday.wednesday, i18n.ts._weekday.thursday, i18n.ts._weekday.friday, i18n.ts._weekday.saturday]; const daysOfWeek: string[] = [i18n.ts._weekday.sunday, i18n.ts._weekday.monday, i18n.ts._weekday.tuesday, i18n.ts._weekday.wednesday, i18n.ts._weekday.thursday, i18n.ts._weekday.friday, i18n.ts._weekday.saturday];
let publishing = false;
os.api('admin/ad/list').then(adsResponse => { os.api('admin/ad/list', { publishing: publishing }).then(adsResponse => {
ads = adsResponse.map(r => { ads = adsResponse.map(r => {
const exdate = new Date(r.expiresAt); const exdate = new Date(r.expiresAt);
const stdate = new Date(r.startsAt); const stdate = new Date(r.startsAt);
@ -101,6 +111,10 @@ os.api('admin/ad/list').then(adsResponse => {
}); });
}); });
const onChangePublishing = (v) => {
publishing = v;
refresh();
};
// (index) // (index)
function toggleDayOfWeek(ad, index) { function toggleDayOfWeek(ad, index) {
ad.dayOfWeek ^= 1 << index; ad.dayOfWeek ^= 1 << index;
@ -131,6 +145,8 @@ function remove(ad) {
if (ad.id == null) return; if (ad.id == null) return;
os.apiWithDialog('admin/ad/delete', { os.apiWithDialog('admin/ad/delete', {
id: ad.id, id: ad.id,
}).then(() => {
refresh();
}); });
}); });
} }
@ -172,7 +188,7 @@ function save(ad) {
} }
} }
function more() { function more() {
os.api('admin/ad/list', { untilId: ads.reduce((acc, ad) => ad.id != null ? ad : acc).id }).then(adsResponse => { os.api('admin/ad/list', { untilId: ads.reduce((acc, ad) => ad.id != null ? ad : acc).id, publishing: publishing }).then(adsResponse => {
ads = ads.concat(adsResponse.map(r => { ads = ads.concat(adsResponse.map(r => {
const exdate = new Date(r.expiresAt); const exdate = new Date(r.expiresAt);
const stdate = new Date(r.startsAt); const stdate = new Date(r.startsAt);
@ -188,7 +204,7 @@ function more() {
} }
function refresh() { function refresh() {
os.api('admin/ad/list').then(adsResponse => { os.api('admin/ad/list', { publishing: publishing }).then(adsResponse => {
ads = adsResponse.map(r => { ads = adsResponse.map(r => {
const exdate = new Date(r.expiresAt); const exdate = new Date(r.expiresAt);
const stdate = new Date(r.startsAt); const stdate = new Date(r.startsAt);