このコミットが含まれているのは:
@@ -340,7 +340,7 @@ class CountsCondition
|
|||||||
return @definition.alias_source(root) if root.start_with?('aliases_')
|
return @definition.alias_source(root) if root.start_with?('aliases_')
|
||||||
return [nil, @definition.name_expression(root)]
|
return [nil, @definition.name_expression(root)]
|
||||||
end
|
end
|
||||||
return [nil, "(#{ @population.latest_sql })"] if root == 'latest'
|
return [nil, "(#{ @population.current_latest_sql })"] if root == 'latest'
|
||||||
if root == 'user' && parts.any?
|
if root == 'user' && parts.any?
|
||||||
expression = parts.first == 'id' ? 'v.created_by_user_id' :
|
expression = parts.first == 'id' ? 'v.created_by_user_id' :
|
||||||
'(SELECT actor.name FROM users actor WHERE actor.id = v.created_by_user_id)'
|
'(SELECT actor.name FROM users actor WHERE actor.id = v.created_by_user_id)'
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class CountsDefaults
|
|||||||
details = details.transform_values do |value|
|
details = details.transform_values do |value|
|
||||||
value.split(' ').flat_map do |token|
|
value.split(' ').flat_map do |token|
|
||||||
if resource == 'tags' && ['name', 'parents.name'].include?(token)
|
if resource == 'tags' && ['name', 'parents.name'].include?(token)
|
||||||
token == 'name' ? name : ["parents.#{ name }", "parents.#{ aliases }"]
|
token == 'name' ? name : "parents.#{ name }"
|
||||||
elsif resource == 'tags' && token == 'aliases'
|
elsif resource == 'tags' && token == 'aliases'
|
||||||
aliases
|
aliases
|
||||||
elsif resource == 'tags' && token.start_with?('aliases.')
|
elsif resource == 'tags' && token.start_with?('aliases.')
|
||||||
|
|||||||
@@ -41,8 +41,7 @@ class CountsPopulation
|
|||||||
raise ArgumentError
|
raise ArgumentError
|
||||||
end
|
end
|
||||||
|
|
||||||
def latest_sql(row = 'v', cutoff = nil)
|
def latest_at_sql(row, cutoff)
|
||||||
cutoff ||= history ? at : timestamp(params['at']) || at
|
|
||||||
keys = definition.keys.map { "newer.#{ _1 } = #{ row }.#{ _1 }" }.join(' AND ')
|
keys = definition.keys.map { "newer.#{ _1 } = #{ row }.#{ _1 }" }.join(' AND ')
|
||||||
bound = definition.model.connection.quote(cutoff)
|
bound = definition.model.connection.quote(cutoff)
|
||||||
<<~SQL.squish
|
<<~SQL.squish
|
||||||
@@ -52,6 +51,14 @@ class CountsPopulation
|
|||||||
SQL
|
SQL
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def current_latest_sql(row = 'v')
|
||||||
|
keys = definition.keys.map { "newer.#{ _1 } = #{ row }.#{ _1 }" }.join(' AND ')
|
||||||
|
<<~SQL.squish
|
||||||
|
NOT EXISTS (SELECT 1 FROM #{ definition.table } newer
|
||||||
|
WHERE #{ keys } AND newer.version_no > #{ row }.version_no)
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
def changed_sql(key)
|
def changed_sql(key)
|
||||||
column = definition.column(key)
|
column = definition.column(key)
|
||||||
"(previous.id IS NOT NULL AND NOT (v.#{ column } <=> previous.#{ column }))"
|
"(previous.id IS NOT NULL AND NOT (v.#{ column } <=> previous.#{ column }))"
|
||||||
@@ -125,7 +132,7 @@ class CountsPopulation
|
|||||||
raise ArgumentError if point > at
|
raise ArgumentError if point > at
|
||||||
|
|
||||||
@scope = @scope.where("v.#{ definition.time_column } <= ?", point)
|
@scope = @scope.where("v.#{ definition.time_column } <= ?", point)
|
||||||
.where(Arel.sql(latest_sql('v', point))).where.not('v.event_type' => 'discard')
|
.where(Arel.sql(latest_at_sql('v', point))).where.not('v.event_type' => 'discard')
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
first = timestamp(params['from'])
|
first = timestamp(params['from'])
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# Common entrypoint for six version resources; legacy endpoints keep their contracts.
|
# Common entrypoint for six version resources; legacy endpoints keep their contracts.
|
||||||
class CountsTableQuery
|
class CountsTableQuery
|
||||||
|
SQL_HINTS = ['MAX_EXECUTION_TIME(10000)',
|
||||||
|
"SET_VAR(optimizer_switch='semijoin=off')"].freeze
|
||||||
MAX_COLUMNS = 100
|
MAX_COLUMNS = 100
|
||||||
class TooManyColumns < ArgumentError; end
|
class TooManyColumns < ArgumentError; end
|
||||||
|
|
||||||
@@ -127,7 +129,7 @@ class CountsTableQuery
|
|||||||
numbered AS (SELECT row_groups.*,
|
numbered AS (SELECT row_groups.*,
|
||||||
ROW_NUMBER() OVER (ORDER BY #{ order_rows.join(', ') }) AS position FROM row_groups),
|
ROW_NUMBER() OVER (ORDER BY #{ order_rows.join(', ') }) AS position FROM row_groups),
|
||||||
group_totals AS (SELECT COUNT(*) AS group_count FROM row_groups)
|
group_totals AS (SELECT COUNT(*) AS group_count FROM row_groups)
|
||||||
SELECT /*+ MAX_EXECUTION_TIME(10000) */ cells.*,
|
SELECT /*+ #{ SQL_HINTS.join(' ') } */ cells.*,
|
||||||
page_rows.position AS counts_position, group_totals.group_count AS counts_group_count
|
page_rows.position AS counts_position, group_totals.group_count AS counts_group_count
|
||||||
FROM group_totals LEFT JOIN numbered page_rows
|
FROM group_totals LEFT JOIN numbered page_rows
|
||||||
ON page_rows.position > #{ (page - 1) * limit }
|
ON page_rows.position > #{ (page - 1) * limit }
|
||||||
@@ -175,7 +177,7 @@ class CountsTableQuery
|
|||||||
|
|
||||||
def details
|
def details
|
||||||
query = population.scope.select(Arel.sql(
|
query = population.scope.select(Arel.sql(
|
||||||
"(#{ population.latest_sql }) AS counts_latest"))
|
"(#{ population.current_latest_sql }) AS counts_latest"))
|
||||||
order = sort_sql { detail_expression(_1) }
|
order = sort_sql { detail_expression(_1) }
|
||||||
query = query.order(Arel.sql((order + ['v.id ASC']).join(', ')))
|
query = query.order(Arel.sql((order + ['v.id ASC']).join(', ')))
|
||||||
.limit(limit).offset((page - 1) * limit)
|
.limit(limit).offset((page - 1) * limit)
|
||||||
@@ -253,11 +255,11 @@ class CountsTableQuery
|
|||||||
|
|
||||||
if HistoryAccess.admin? || mode == 'summary'
|
if HistoryAccess.admin? || mode == 'summary'
|
||||||
total = population.scope.except(:select)
|
total = population.scope.except(:select)
|
||||||
.optimizer_hints('MAX_EXECUTION_TIME(10000)').count
|
.optimizer_hints(*SQL_HINTS).count
|
||||||
return @record_counts = { total:, visible: total, denied: 0 }
|
return @record_counts = { total:, visible: total, denied: 0 }
|
||||||
end
|
end
|
||||||
total, denied = unrestricted_population.scope.except(:select)
|
total, denied = unrestricted_population.scope.except(:select)
|
||||||
.optimizer_hints('MAX_EXECUTION_TIME(10000)').pick(Arel.sql('COUNT(*)'),
|
.optimizer_hints(*SQL_HINTS).pick(Arel.sql('COUNT(*)'),
|
||||||
Arel.sql("COALESCE(SUM(CASE WHEN #{ HistoryAccess.sql(@definition.model, 'v') } " +
|
Arel.sql("COALESCE(SUM(CASE WHEN #{ HistoryAccess.sql(@definition.model, 'v') } " +
|
||||||
'THEN 0 ELSE 1 END), 0)'))
|
'THEN 0 ELSE 1 END), 0)'))
|
||||||
# Related/previous-version predicates may differ under public authority.
|
# Related/previous-version predicates may differ under public authority.
|
||||||
@@ -267,7 +269,7 @@ class CountsTableQuery
|
|||||||
total.to_i - denied.to_i
|
total.to_i - denied.to_i
|
||||||
else
|
else
|
||||||
population.scope.except(:select)
|
population.scope.except(:select)
|
||||||
.optimizer_hints('MAX_EXECUTION_TIME(10000)').count
|
.optimizer_hints(*SQL_HINTS).count
|
||||||
end
|
end
|
||||||
@record_counts = { total: total.to_i, denied: denied.to_i, visible: }
|
@record_counts = { total: total.to_i, denied: denied.to_i, visible: }
|
||||||
end
|
end
|
||||||
@@ -309,7 +311,7 @@ class CountsTableQuery
|
|||||||
prefix = "WITH cells AS (#{ sql })"
|
prefix = "WITH cells AS (#{ sql })"
|
||||||
@connection.select_value(<<~SQL).to_i
|
@connection.select_value(<<~SQL).to_i
|
||||||
#{ prefix }
|
#{ prefix }
|
||||||
SELECT /*+ MAX_EXECUTION_TIME(10000) */ COUNT(*) FROM (
|
SELECT /*+ #{ SQL_HINTS.join(' ') } */ COUNT(*) FROM (
|
||||||
SELECT #{ keys.join(', ') } FROM cells GROUP BY #{ keys.join(', ') }
|
SELECT #{ keys.join(', ') } FROM cells GROUP BY #{ keys.join(', ') }
|
||||||
) output_groups
|
) output_groups
|
||||||
SQL
|
SQL
|
||||||
@@ -335,7 +337,7 @@ class CountsTableQuery
|
|||||||
end
|
end
|
||||||
values = @connection.select_rows(<<~SQL)
|
values = @connection.select_rows(<<~SQL)
|
||||||
#{ prefix }
|
#{ prefix }
|
||||||
SELECT /*+ MAX_EXECUTION_TIME(10000) */ DISTINCT #{ keys.join(', ') } FROM cells
|
SELECT /*+ #{ SQL_HINTS.join(' ') } */ DISTINCT #{ keys.join(', ') } FROM cells
|
||||||
ORDER BY #{ order } LIMIT #{ MAX_COLUMNS + 1 }
|
ORDER BY #{ order } LIMIT #{ MAX_COLUMNS + 1 }
|
||||||
SQL
|
SQL
|
||||||
raise TooManyColumns if values.length > MAX_COLUMNS
|
raise TooManyColumns if values.length > MAX_COLUMNS
|
||||||
@@ -395,7 +397,7 @@ class CountsTableQuery
|
|||||||
end
|
end
|
||||||
|
|
||||||
def detail_expression(key)
|
def detail_expression(key)
|
||||||
return "(#{ population.latest_sql })" if key == 'latest'
|
return "(#{ population.current_latest_sql })" if key == 'latest'
|
||||||
return @definition.name_expression(key) if @definition.resource == 'tags' &&
|
return @definition.name_expression(key) if @definition.resource == 'tags' &&
|
||||||
@definition.name_column(key)
|
@definition.name_column(key)
|
||||||
aliases = { 'tags' => 'tags_json', 'parents' => @definition.resource == 'posts' ?
|
aliases = { 'tags' => 'tags_json', 'parents' => @definition.resource == 'posts' ?
|
||||||
|
|||||||
@@ -91,6 +91,34 @@ RSpec.describe 'Counts table API', type: :request do
|
|||||||
expect(versions(query(predicate.merge('conditions.0.value' => 'true')))).to eq([3])
|
expect(versions(query(predicate.merge('conditions.0.value' => 'true')))).to eq([3])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'distinguishes the snapshot cutoff from the current latest flag and condition' do
|
||||||
|
past = { definition: 'latest', at: '2024-01-31T16:00:00Z' }
|
||||||
|
result = query(past)
|
||||||
|
expect(versions(result)).to eq([2])
|
||||||
|
expect(result['versions'].first['latest']).to be(false)
|
||||||
|
predicate = { conditions: '', 'conditions.0.field' => 'latest',
|
||||||
|
'conditions.0.operator' => 'eq', 'conditions.0.value' => 'false' }
|
||||||
|
expect(versions(query(past.merge(predicate)))).to eq([2])
|
||||||
|
expect(versions(query(past.merge(predicate).merge('conditions.0.value' => 'true'))))
|
||||||
|
.to eq([])
|
||||||
|
unchanged = query(definition: 'latest', at: '2024-02-01T00:00:00Z')
|
||||||
|
expect(versions(unchanged)).to eq([3])
|
||||||
|
expect(unchanged['versions'].first['latest']).to be(true)
|
||||||
|
expect(versions(query(sort: 'latest:desc resource_id:asc version_no:asc'))).to eq([3, 1, 2])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'checks the current latest flag beyond the execution timestamp' do
|
||||||
|
PostVersion.create!(post: record, version_no: 4, event_type: 'update',
|
||||||
|
url: record.url, title: 'after execution', tags: '', tags_json: [],
|
||||||
|
parent_post_ids: '', created_at: Time.utc(2025, 2, 1))
|
||||||
|
result = query
|
||||||
|
expect(versions(result)).to eq([1, 2, 3])
|
||||||
|
expect(result['versions'].map { _1['latest'] }).to eq([false, false, false])
|
||||||
|
snapshot = query(definition: 'latest')
|
||||||
|
expect(versions(snapshot)).to eq([3])
|
||||||
|
expect(snapshot['versions'].first['latest']).to be(false)
|
||||||
|
end
|
||||||
|
|
||||||
it 'keeps ANY, ALL and NONE distinct without multiplying parent records' do
|
it 'keeps ANY, ALL and NONE distinct without multiplying parent records' do
|
||||||
values = { conditions: '', 'conditions.0.field' => 'tags',
|
values = { conditions: '', 'conditions.0.field' => 'tags',
|
||||||
'conditions.0.values' => '1', condition_values: '',
|
'conditions.0.values' => '1', condition_values: '',
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ bundle exec rspec spec/requests/counts_table_spec.rb spec/requests/counts_downlo
|
|||||||
frontend ディレクトリで提案する対象(未実行):
|
frontend ディレクトリで提案する対象(未実行):
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm run test:run -- src/lib/counts.test.ts src/lib/api.test.ts src/pages/CountsResourcePage.test.tsx src/pages/help/HelpChangesPage.test.tsx src/components/counts/CountsControls.test.tsx src/components/counts/CountsSummaryResults.test.tsx src/components/counts/CountsExportProgress.test.tsx
|
npm run test:run -- src/lib/counts.test.ts src/lib/api.test.ts src/pages/counts/CountsResourcePage.test.tsx src/pages/help/HelpChangesPage.test.tsx src/components/counts/CountsControls.test.tsx src/components/counts/CountsSummaryResults.test.tsx src/components/counts/CountsExportProgress.test.tsx
|
||||||
```
|
```
|
||||||
|
|
||||||
SSR は frontend/server.ssr.test.mjs が dist/server/entry-server.js を読み込む。
|
SSR は frontend/server.ssr.test.mjs が dist/server/entry-server.js を読み込む。
|
||||||
@@ -104,7 +104,7 @@ SQL の速度改善・索引追加は別 Issue とし、今回 migration は追
|
|||||||
- frontend/src/components/counts/CountsSummaryResults.tsx:行番号コードの撤去、私的セルの
|
- frontend/src/components/counts/CountsSummaryResults.tsx:行番号コードの撤去、私的セルの
|
||||||
ドリルダウン抑止、公開列のソート維持。
|
ドリルダウン抑止、公開列のソート維持。
|
||||||
- frontend/src/components/counts/CountsSortHeader.tsx:禁止座標のソート抑止と伏字の理由表示。
|
- frontend/src/components/counts/CountsSortHeader.tsx:禁止座標のソート抑止と伏字の理由表示。
|
||||||
- frontend/src/pages/CountsResourcePage.tsx:専用エラーと、初回失敗後にも再実行できる状態。
|
- frontend/src/pages/counts/CountsResourcePage.tsx:専用エラーと、初回失敗後にも再実行できる状態。
|
||||||
- frontend/src/locales/ja/counts.json:承認されたエラー文言。
|
- frontend/src/locales/ja/counts.json:承認されたエラー文言。
|
||||||
- frontend/src/locales/ain-Kana/counts.json:同じキーと未翻訳・日本語 fallback の管理。
|
- frontend/src/locales/ain-Kana/counts.json:同じキーと未翻訳・日本語 fallback の管理。
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ SQL の速度改善・索引追加は別 Issue とし、今回 migration は追
|
|||||||
再描画、開始受付失敗、通信断、独立期限、取消の競合・再試行、unmount、iframe 失敗。
|
再描画、開始受付失敗、通信断、独立期限、取消の競合・再試行、unmount、iframe 失敗。
|
||||||
- frontend/src/components/counts/CountsSummaryResults.test.tsx(新規):伏字・理由・コピー・旧行番号。
|
- frontend/src/components/counts/CountsSummaryResults.test.tsx(新規):伏字・理由・コピー・旧行番号。
|
||||||
- frontend/src/components/counts/CountsControls.test.tsx:summary 行番号廃止と表示件数選択。
|
- frontend/src/components/counts/CountsControls.test.tsx:summary 行番号廃止と表示件数選択。
|
||||||
- frontend/src/pages/CountsResourcePage.test.tsx:初期エラーからの再実行、サイト名付き title。
|
- frontend/src/pages/counts/CountsResourcePage.test.tsx:初期エラーからの再実行、サイト名付き title。
|
||||||
- frontend/src/lib/api.test.ts:共有 CSRF 待機中の中断、iframe の解放・重複失敗通知。
|
- frontend/src/lib/api.test.ts:共有 CSRF 待機中の中断、iframe の解放・重複失敗通知。
|
||||||
- frontend/src/lib/counts.test.ts:理由別エラーと任意のサーバー文字列を表示しないこと。
|
- frontend/src/lib/counts.test.ts:理由別エラーと任意のサーバー文字列を表示しないこと。
|
||||||
- frontend/src/test/setup.ts:時刻が進む非同期 RAF と Canvas のテスト専用 fallback。
|
- frontend/src/test/setup.ts:時刻が進む非同期 RAF と Canvas のテスト専用 fallback。
|
||||||
|
|||||||
+1
-1
@@ -81,7 +81,7 @@ const MaterialListPage = lazyPage (() => import ('@/pages/materials/MaterialList
|
|||||||
const MaterialNewPage = lazyPage (() => import ('@/pages/materials/MaterialNewPage'))
|
const MaterialNewPage = lazyPage (() => import ('@/pages/materials/MaterialNewPage'))
|
||||||
const MaterialSyncSuppressionsPage = lazyPage (
|
const MaterialSyncSuppressionsPage = lazyPage (
|
||||||
() => import ('@/pages/materials/MaterialSyncSuppressionsPage'))
|
() => import ('@/pages/materials/MaterialSyncSuppressionsPage'))
|
||||||
const CountsResourcePage = lazyPage (() => import ('@/pages/CountsResourcePage'))
|
const CountsResourcePage = lazyPage (() => import ('@/pages/counts/CountsResourcePage'))
|
||||||
const MorePage = lazyPage (() => import ('@/pages/MorePage'))
|
const MorePage = lazyPage (() => import ('@/pages/MorePage'))
|
||||||
const GekanatorUnavailablePage = lazyPage (() => import ('@/pages/GekanatorUnavailablePage'))
|
const GekanatorUnavailablePage = lazyPage (() => import ('@/pages/GekanatorUnavailablePage'))
|
||||||
const NicoTagListPage = lazyPage (() => import ('@/pages/tags/NicoTagListPage'))
|
const NicoTagListPage = lazyPage (() => import ('@/pages/tags/NicoTagListPage'))
|
||||||
|
|||||||
@@ -120,7 +120,8 @@ export const menuOutline = (
|
|||||||
{ ...message ('entertainment'), visible: false, subMenu: [
|
{ ...message ('entertainment'), visible: false, subMenu: [
|
||||||
{ ...message ('theatre'), to: '/theatres/1' },
|
{ ...message ('theatre'), to: '/theatres/1' },
|
||||||
{ ...message ('gekanator'), to: '/gekanator' }] },
|
{ ...message ('gekanator'), to: '/gekanator' }] },
|
||||||
{ ...message ('counts'), visible: false, subMenu: [
|
{ ...message ('counts'),
|
||||||
|
name: `${ message ('counts').name } (β)`, visible: false, subMenu: [
|
||||||
{ ...message ('posts'), to: '/counts/posts' },
|
{ ...message ('posts'), to: '/counts/posts' },
|
||||||
{ ...message ('tags'), to: '/counts/tags' },
|
{ ...message ('tags'), to: '/counts/tags' },
|
||||||
{ ...message ('externalTags'), to: '/counts/nico-tags' }] },
|
{ ...message ('externalTags'), to: '/counts/nico-tags' }] },
|
||||||
|
|||||||
@@ -49,8 +49,9 @@ const CountsAxes = ({ params, update }: {
|
|||||||
commit (next)
|
commit (next)
|
||||||
}
|
}
|
||||||
return <SortableList groups={groups} name={name} onChange={commit}
|
return <SortableList groups={groups} name={name} onChange={commit}
|
||||||
renderGroup={(id, content, over) => <fieldset className="mb-2 min-w-0">
|
renderGroup={(id, content, over) => <fieldset className="mx-2 mb-2 min-w-0">
|
||||||
<legend>{label (id === 'available' ? 'axisItems' : id)}</legend>
|
<legend className="mb-1 font-semibold">
|
||||||
|
{label (id === 'available' ? 'axisItems' : id)}</legend>
|
||||||
<div className={cn ('rounded border px-1 dark:border-slate-700',
|
<div className={cn ('rounded border px-1 dark:border-slate-700',
|
||||||
over && 'ring-1 ring-blue-500 dark:ring-blue-400')}>{content}</div>
|
over && 'ring-1 ring-blue-500 dark:ring-blue-400')}>{content}</div>
|
||||||
</fieldset>} renderItem={(id, group) => {
|
</fieldset>} renderItem={(id, group) => {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
.ainu-ui-word
|
.ainu-ui-word
|
||||||
{
|
{
|
||||||
display: inline-block;
|
display: inline;
|
||||||
white-space: nowrap !important;
|
white-space: nowrap !important;
|
||||||
word-break: keep-all !important;
|
word-break: keep-all !important;
|
||||||
overflow-wrap: normal !important;
|
overflow-wrap: normal !important;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"_untranslated": ["languageNames.en"],
|
|
||||||
"languageNames": {
|
"languageNames": {
|
||||||
"ja": "シサㇺ イタㇰ",
|
"ja": "シサㇺ イタㇰ",
|
||||||
"ain": "ヤウンモシルン アイヌ イタㇰ"
|
"ain": "ヤウンモシルン アイヌ イタㇰ",
|
||||||
|
"en": "イングリㇱ イタㇰ"
|
||||||
},
|
},
|
||||||
"loadingLabel": "$t(common:loading)",
|
"loadingLabel": "$t(common:loading)",
|
||||||
"countLabel": "チピㇱキㇷ゚",
|
"countLabel": "チピㇱキㇷ゚",
|
||||||
|
|||||||
@@ -1,28 +1,311 @@
|
|||||||
{
|
{
|
||||||
"_untranslated": [
|
"titles": {
|
||||||
"*",
|
"posts": "ミンタㇻ ウコピㇱキ",
|
||||||
"outputRows",
|
"tags": "シロシ ウコピㇱキ",
|
||||||
"maskedReason",
|
"nico_tags": "ソイタ シロシ ウコピㇱキ",
|
||||||
"downloadErrors",
|
"tag_descriptions": "シロシ オルㇱペ ウコピㇱキ ネワ オルㇱペ",
|
||||||
"axisLimit",
|
"tag_groups": "シロシ ウコ イソネカ ウコピㇱキ ネワ オルㇱペ",
|
||||||
"privateCondition",
|
"materials": "チカㇻペ ウコピㇱキ ネワ オルㇱペ"
|
||||||
"errors"
|
|
||||||
],
|
|
||||||
"outputRows": "行数:{{value}} 件",
|
|
||||||
"maskedReason": "閲覧権限のない履歴に由来するため、この項目の値は表示できません。集計件数には含まれます。",
|
|
||||||
"downloadErrors": {
|
|
||||||
"unavailable": "ダウンロードの認可が失われたか、ファイルの有効期限が切れています。",
|
|
||||||
"failed": "ダウンロード応答を開始できませんでした。",
|
|
||||||
"timeout": "ダウンロード応答の開始確認がタイムアウトしました。"
|
|
||||||
},
|
},
|
||||||
"axisLimit": "集計軸は最大{{max}}個です。行・列の項目を減らしてください。",
|
"target": "ウコピㇱキ イアヌ",
|
||||||
"privateCondition": "非公開情報を保護するため、この抽出条件では集計できません。",
|
"localeName": "レ({{language}})",
|
||||||
|
"localeNameWithScript": "レ({{language}}・{{script}})",
|
||||||
|
"localeAliases": "モㇱマ レ({{language}})",
|
||||||
|
"localeAliasesWithScript": "モㇱマ レ({{language}}・{{script}})",
|
||||||
|
"run": "ウコピㇱキ キ",
|
||||||
|
"columnLimit": {
|
||||||
|
"title": "コラム チピㇱキㇷ゚ イヨッタ ポロ ネ",
|
||||||
|
"message": "ウコピㇱキ テーブル コラム {{max}} パㇰノ アエイワンケ エアㇱカイ。コラム イヌㇺケ シンナ カㇻ ネ ヤ、イフナラ クニ ペ ポンノ カㇻ ヤン。"
|
||||||
|
},
|
||||||
|
"conditions": "ウコピㇱキ イアヌ",
|
||||||
|
"output": "アサンケ クニ オルㇱペ",
|
||||||
|
"filters": "イフナラ イアヌ",
|
||||||
|
"mode": "アヌカレ",
|
||||||
|
"exportProgress": {
|
||||||
|
"title": "エクスポート",
|
||||||
|
"format": "イソネカ:{{format}}",
|
||||||
|
"starting": "アオハシ コㇿ アン",
|
||||||
|
"queued": "アテレ コㇿ アン",
|
||||||
|
"running": "アカㇻ コㇿ アン",
|
||||||
|
"aggregating": "ウコピㇱキ コㇿ アン",
|
||||||
|
"writing": "アサンケ コㇿ アン",
|
||||||
|
"cancelling": "ソモ キ クス イカㇻ コㇿ アン",
|
||||||
|
"cancelled": "ソモ キ オケレ",
|
||||||
|
"ready": "チヌイェㇷ゚ アカㇻ オケレ・ダウンロード アオハシ(アウカオ オケレ ヤ ソモ アエラマン)",
|
||||||
|
"failed": "ハイタ",
|
||||||
|
"processed": "{{count}} ペ アカㇻ オケレ",
|
||||||
|
"measured": "{{processed}} / {{total}} ペ({{percent}}%)"
|
||||||
|
},
|
||||||
|
"displaySettings": "アヌカレ イアヌ",
|
||||||
|
"summary": "ウコピㇱキ",
|
||||||
|
"details": "オルㇱペ",
|
||||||
|
"axis": "ウコピㇱキ アㇰシㇱ",
|
||||||
|
"axes": {
|
||||||
|
"month": "チュㇷ゚ ネ ウシンナ(UTC)",
|
||||||
|
"user": "$t(history:actor)",
|
||||||
|
"tags": "シロシ ネ ウシンナ"
|
||||||
|
},
|
||||||
|
"metric": "フㇱコアンペ レコード チピㇱキㇷ゚",
|
||||||
|
"total": "フㇱコアンペ レコード チピㇱキㇷ゚:{{count}}",
|
||||||
|
"csv": "CSV",
|
||||||
|
"csvScope": "タネ アヌカレ ソㇱ ネワ アヌㇺケ コラム CSV ウン アサンケ",
|
||||||
|
"empty": "ネ フㇱコアンペ イサㇺ。",
|
||||||
|
"columns": {
|
||||||
|
"changedAt": "イカㇻ ト ヘㇺ トキ",
|
||||||
|
"version": "ウェㇽソン",
|
||||||
|
"name": "レ",
|
||||||
|
"resourceId": "Id.",
|
||||||
|
"postTitle": "レ",
|
||||||
|
"postURL": "URL",
|
||||||
|
"tags": "シロシ",
|
||||||
|
"deprecated": "エイワンケ ソモ エアㇱカイ シㇼキ",
|
||||||
|
"latest": "イヨッタ アシㇼ シロシ",
|
||||||
|
"thumbnailURL": "ポン ノカ モト URL",
|
||||||
|
"originalFrom": "ホㇱキ アオ ト ヘㇺ トキ(オㇿ ワノ)",
|
||||||
|
"originalBefore": "ホㇱキ アオ ト ヘㇺ トキ(エトコ ウン)",
|
||||||
|
"language": "イタㇰ",
|
||||||
|
"kind": "ウㇱケ オㇿ・ソイタ",
|
||||||
|
"sections": "シロシ アオ トキ ウシ",
|
||||||
|
"names": "イタㇰ ネ ウシンナ レ",
|
||||||
|
"thumbnailDisplay": "$t(shared:labels.thumbnail)"
|
||||||
|
},
|
||||||
|
"fields": {
|
||||||
|
"from": "アオハシ(エコㇿ マシン トキ・オㇿ ワノ)",
|
||||||
|
"before": "オケレ(エコㇿ マシン トキ・エトコ ウン)",
|
||||||
|
"post": "ミンタㇻ Id.",
|
||||||
|
"tag": "シロシ レ ネ ヤ Id.",
|
||||||
|
"actor": "イカㇻ クㇽ Id.",
|
||||||
|
"limit": "アヌカレ ペ チピㇱキㇷ゚"
|
||||||
|
},
|
||||||
|
"latestOnly": "イヨッタ アシㇼ ペ パテㇰ",
|
||||||
|
"truthValues": {
|
||||||
|
"true": "アニ",
|
||||||
|
"false": "ソモ"
|
||||||
|
},
|
||||||
|
"boolean": {
|
||||||
|
"true": "ルウェ ウン",
|
||||||
|
"false": "ソモ ネ"
|
||||||
|
},
|
||||||
|
"kinds": {
|
||||||
|
"internal": "ウㇱケ オㇿ シロシ",
|
||||||
|
"external": "ソイタ シロシ"
|
||||||
|
},
|
||||||
|
"nested": {
|
||||||
|
"toggle": "テーブル オㇿ テーブル アㇱマカ・アセㇱケ",
|
||||||
|
"selection": "サパ ペ OFF ネ ヤッカ ポン ペ イヌㇺケ アウカオ コㇿ アン。",
|
||||||
|
"noColumns": "アサンケ クニ オルㇱペ ソモ アヌㇺケ。",
|
||||||
|
"asJSON": "オㇱケ テーブル JSON アニ アヌカレ"
|
||||||
|
},
|
||||||
|
"sort": {
|
||||||
|
"action": "クリッㇰ コㇿ シネ ソート。Ctrl ネ ヤ タンネ アオサンケ コㇿ キー アオ・シンナ・アウㇱカ。NULL イヨㇱノ。",
|
||||||
|
"structured": "サパ テーブル オㇿ ポロンノ アン ペ アピㇱキ ワ、アウカオ ノカ イタㇰ シㇼ ネ アウコシㇼキ。Ctrl ネ ヤ タンネ アオサンケ コㇿ ポロンノ キー ソート エアㇱカイ。ポン テーブル ソート サパ テーブル ウン エラㇺシㇰ ソモ キ。",
|
||||||
|
"label": "{{column}}:{{direction}}、ホㇱキ ネ イキㇼ {{priority}}",
|
||||||
|
"none": "ソート イサㇺ",
|
||||||
|
"ascending": "ポン ペ ホㇱキ",
|
||||||
|
"descending": "ポロ ペ ホㇱキ",
|
||||||
|
"unsortedLabel": "{{column}}:ソート イサㇺ",
|
||||||
|
"singleLabel": "{{column}}:{{direction}}"
|
||||||
|
},
|
||||||
|
"notRegistered": "レ ソモ アヌイェ",
|
||||||
|
"selection": {
|
||||||
|
"table": "ウコピㇱキ ネワ オルㇱペ テーブル",
|
||||||
|
"textMode": "イタㇰ イヌㇺケ コㇿ アン",
|
||||||
|
"hint": "クリッㇰ コㇿ セル アヌㇺケ、ドラッグ ネ ヤ Shift+クリッㇰ コㇿ ウシ アヌㇺケ。タッチ ネ セル タンネ アオサンケ ワ ドラッグ。Ctrl+C/Cmd+C コㇿ コピー。アㇻㇺプヤラ ケイ コㇿ オマン、Shift+アㇻㇺプヤラ ケイ コㇿ ウシ ポロ カㇻ、Escape コㇿ アウㇱカ。",
|
||||||
|
"copy": "コピー",
|
||||||
|
"copyHeaders": "サパ レ コㇿ コピー",
|
||||||
|
"row": "イキㇼ アヌㇺケ",
|
||||||
|
"column": "コラム アヌㇺケ",
|
||||||
|
"all": "オピッタ アヌㇺケ"
|
||||||
|
},
|
||||||
|
"resize": {
|
||||||
|
"column": "{{column}} コラム サクマ シンナ。イキㇻ ドラッグ、タッチ ネ タンネ アオサンケ ワ ドラッグ。アㇻㇺプヤラ ケイ アニ カ シンナ エアㇱカイ。"
|
||||||
|
},
|
||||||
|
"latestValue": "イヨッタ アシㇼ",
|
||||||
|
"sections": {
|
||||||
|
"range": "{{begin}}~{{end}}",
|
||||||
|
"separator": "、"
|
||||||
|
},
|
||||||
|
"reorder": "{{column}}:アサンケ クニ オルㇱペ イキㇼ シンナ",
|
||||||
|
"state": {
|
||||||
|
"list": "シロシ ネ ウシンナ ミンタㇻ チピㇱキㇷ゚ イキㇼ",
|
||||||
|
"trend": "シロシ ネ ウシンナ ミンタㇻ チピㇱキㇷ゚ シンナ シㇼキ",
|
||||||
|
"details": "ネ トキ コㇿ オルㇱペ",
|
||||||
|
"history": "フㇱコアンペ ウコピㇱキ",
|
||||||
|
"historyDetails": "フㇱコアンペ オルㇱペ",
|
||||||
|
"at": "ウコピㇱキ トキ",
|
||||||
|
"boundary": "ウコピㇱキ トキ(UTC)",
|
||||||
|
"period": "トキ(UTC)",
|
||||||
|
"grain": "トキ イソネカ(UTC)",
|
||||||
|
"grains": {
|
||||||
|
"day": "ト ネ ウシンナ",
|
||||||
|
"month": "チュㇷ゚ ネ ウシンナ",
|
||||||
|
"year": "パ ネ ウシンナ"
|
||||||
|
},
|
||||||
|
"postCount": "ミンタㇻ チピㇱキㇷ゚",
|
||||||
|
"totals": {
|
||||||
|
"posts": "ミンタㇻ チピㇱキㇷ゚ オピッタ",
|
||||||
|
"tags": "ウㇱケ オㇿ シロシ チピㇱキㇷ゚ オピッタ",
|
||||||
|
"assignments": "シロシ アオ ペ チピㇱキㇷ゚ オピッタ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"measure": "アピㇱキ ペ",
|
||||||
|
"export": "エクスポート",
|
||||||
|
"exportFormat": "エクスポート イソネカ",
|
||||||
|
"exportFormats": {
|
||||||
|
"json": "JSON",
|
||||||
|
"csv": "CSV"
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"posts": "ミンタㇻ",
|
||||||
|
"tags": "シロシ",
|
||||||
|
"nico_tags": "ソイタ シロシ",
|
||||||
|
"tag_descriptions": "シロシ オルㇱペ",
|
||||||
|
"tag_groups": "シロシ ウコ イソネカ",
|
||||||
|
"materials": "チカㇻペ"
|
||||||
|
},
|
||||||
|
"latest": "イヨッタ アシㇼ",
|
||||||
|
"history": "フㇱコアンペ",
|
||||||
|
"referenceAt": "アㇱパ ト ヘㇺ トキ",
|
||||||
|
"referenceHelp": "エヌㇺケ トキ タ イヨッタ アシㇼ アン ペ アウコピㇱキ ワ アヌカレ。ソモ エヌイェ コㇿ タネ イヨッタ アシㇼ ペ アエイワンケ。",
|
||||||
|
"from": "アオハシ",
|
||||||
|
"through": "オケレ",
|
||||||
|
"axisItems": "オルㇱペ イキㇼ",
|
||||||
|
"rows": "イキㇼ",
|
||||||
|
"cols": "コラム",
|
||||||
|
"axisPlace": "{{field}} {{target}} ウン アオ",
|
||||||
|
"field": "オルㇱペ",
|
||||||
|
"operator": "オペレーター",
|
||||||
|
"add": "アオ",
|
||||||
|
"remove": "アウㇱカ",
|
||||||
|
"value": "アヌイェ ペ",
|
||||||
|
"blank": "エンプティ",
|
||||||
|
"additionalConditions": "モㇱマ イアヌ",
|
||||||
|
"changedField": "シンナ アカㇻ オルㇱペ",
|
||||||
|
"eventType": "シンナ イソネカ",
|
||||||
|
"count": "チピㇱキㇷ゚",
|
||||||
|
"outputTotal": "チピㇱキㇷ゚:{{value}} ペ",
|
||||||
|
"excludedRecords": "(アヌカㇻ エアイカㇷ゚ レコード {{count}} ペ アサンケ ソモ キ)",
|
||||||
|
"recordTotal": "アヌカㇻ エアㇱカイ ペ チピㇱキㇷ゚:{{count}}",
|
||||||
|
"grain": "トキ イソネカ",
|
||||||
|
"grains": {
|
||||||
|
"year": "パ",
|
||||||
|
"quarter": "パ 4 イキㇼ オㇿ シネ ペ",
|
||||||
|
"month": "チュㇷ゚",
|
||||||
|
"week": "シネ ウィーㇰ",
|
||||||
|
"day": "ト",
|
||||||
|
"hour": "トキ"
|
||||||
|
},
|
||||||
|
"operatorSymbols": {
|
||||||
|
"in": "IN",
|
||||||
|
"not_in": "NOT IN",
|
||||||
|
"any": "ANY",
|
||||||
|
"all": "ALL",
|
||||||
|
"none": "NONE",
|
||||||
|
"eq": "=",
|
||||||
|
"ne": "≠",
|
||||||
|
"gt": ">",
|
||||||
|
"lt": "<",
|
||||||
|
"ge": "≥",
|
||||||
|
"le": "≤",
|
||||||
|
"like": "LIKE",
|
||||||
|
"range": "~"
|
||||||
|
},
|
||||||
|
"operators": {
|
||||||
|
"in": "IN",
|
||||||
|
"not_in": "NOT IN",
|
||||||
|
"any": "アヌㇺケ ペ オㇿ シネ ペ カ アン",
|
||||||
|
"all": "アヌㇺケ ペ オピッタ アン",
|
||||||
|
"none": "アヌㇺケ ペ シネ ペ カ イサㇺ",
|
||||||
|
"eq": "ウコシノㇳ",
|
||||||
|
"ne": "ウコシノㇳ ソモ キ",
|
||||||
|
"gt": "イヨッタ ポロ",
|
||||||
|
"lt": "ポン ワ アン",
|
||||||
|
"ge": "ポロ ネ ヤ ウコシノㇳ",
|
||||||
|
"le": "ポン ネ ヤ ウコシノㇳ",
|
||||||
|
"like": "パターン",
|
||||||
|
"range": "ウシ"
|
||||||
|
},
|
||||||
|
"pattern": {
|
||||||
|
"input": "ソㇱ アヌカレ イソネカ",
|
||||||
|
"single": "シネ ペ エヌイェ",
|
||||||
|
"multiple": "ポロンノ エヌイェ",
|
||||||
|
"list": "ポロンノ アヌㇺケ イキㇼ",
|
||||||
|
"pattern": "データ パターン",
|
||||||
|
"link": "データ ウコテㇷ゚",
|
||||||
|
"columns": "アヌカレ コラム",
|
||||||
|
"value": "アエイワンケ ペ",
|
||||||
|
"selection": "イヌㇺケ"
|
||||||
|
},
|
||||||
|
"events": {
|
||||||
|
"create": "アシㇼ アカㇻ",
|
||||||
|
"update": "シンナ アカㇻ",
|
||||||
|
"discard": "アウㇱカ",
|
||||||
|
"restore": "アホシピレ"
|
||||||
|
},
|
||||||
|
"attributes": {
|
||||||
|
"sourceLanguage": "イタㇰ シンナ カㇻ モト イタㇰ",
|
||||||
|
"source_language_code": "イタㇰ シンナ カㇻ モト イタㇰ",
|
||||||
|
"source_version_no": "モト ウェㇽソン チピㇱキㇷ゚",
|
||||||
|
"event_type": "シンナ イソネカ",
|
||||||
|
"body": "ヌイェㇷ゚",
|
||||||
|
"linked_tags": "ウコテㇷ゚ シロシ",
|
||||||
|
"description": "オルㇱペ",
|
||||||
|
"members": "ウコオマレ ペ",
|
||||||
|
"placements": "イアヌ ウシ",
|
||||||
|
"parent_id": "オナ チカㇻペ",
|
||||||
|
"tag_id": "シロシ",
|
||||||
|
"tag_name": "シロシ レ",
|
||||||
|
"tag_category": "シロシ イソネカ",
|
||||||
|
"discarded_at": "アウㇱカ ト ヘㇺ トキ",
|
||||||
|
"updated_at": "フㇱコアンペ イキㇼ アシㇼ アカㇻ ト ヘㇺ トキ",
|
||||||
|
"updated_by_user_id": "フㇱコアンペ イキㇼ アシㇼ カㇻ クㇽ",
|
||||||
|
"export_paths_json": "アサンケ パㇱ",
|
||||||
|
"file_blob_id": "チヌイェㇷ゚ Id.",
|
||||||
|
"file_filename": "チヌイェㇷ゚ レ",
|
||||||
|
"file_content_type": "チヌイェㇷ゚ イソネカ",
|
||||||
|
"file_byte_size": "チヌイェㇷ゚ サイズ",
|
||||||
|
"file_checksum": "チェックサム",
|
||||||
|
"file_sha256": "SHA-256",
|
||||||
|
"source_kind": "モト イソネカ",
|
||||||
|
"source_uri": "モト URI",
|
||||||
|
"source_path": "モト パㇱ",
|
||||||
|
"source_file_id": "モト チヌイェㇷ゚ Id.",
|
||||||
|
"normalized_source_key": "モト イアヌ キー",
|
||||||
|
"parent_post_ids": "サパ ミンタㇻ",
|
||||||
|
"parent_tag_ids": "サパ シロシ",
|
||||||
|
"video_ms": "チモイェノカ トキ",
|
||||||
|
"original_created_from": "ホㇱキ アカㇻ ト ヘㇺ トキ(オㇿ ワノ)",
|
||||||
|
"original_created_before": "ホㇱキ アカㇻ ト ヘㇺ トキ(エトコ ウン)",
|
||||||
|
"deprecated_at": "エイワンケ ソモ エアㇱカイ アカㇻ ト",
|
||||||
|
"section_name": "イキㇻ レ",
|
||||||
|
"children": "ポン ペ",
|
||||||
|
"profile": "アサンケ イアヌ",
|
||||||
|
"path": "アサンケ パㇱ"
|
||||||
|
},
|
||||||
|
"rowNumberHeading": "No.",
|
||||||
|
"subtotal": "ポン ウコピㇱキ",
|
||||||
|
"singleTotal": "ウコピㇱキ オピッタ",
|
||||||
|
"grandTotal": "オピッタ ウコピㇱキ",
|
||||||
|
"rowNumbers": "イキㇼ チピㇱキㇷ゚",
|
||||||
|
"periodSeparator": "〜",
|
||||||
|
"bot": "$t(history:bot)",
|
||||||
|
"actorWithId": "{{name}} (#{{id}})",
|
||||||
|
"axisWithGrain": "{{field}}({{grain}})",
|
||||||
|
"outputRows": "イキㇼ チピㇱキㇷ゚:{{value}} ペ",
|
||||||
|
"maskedReason": "エヌカㇻ エアイカㇷ゚ フㇱコアンペ オㇿ ワ アウㇰ ペ クス、タン オルㇱペ アヌカレ エアイカㇷ゚。ウコピㇱキ チピㇱキㇷ゚ オㇿ アン。",
|
||||||
|
"downloadErrors": {
|
||||||
|
"unavailable": "ダウンロード エアㇱカイ イレンカ イサㇺ ネ ヤ、チヌイェㇷ゚ エイワンケ エアㇱカイ トキ オケレ。",
|
||||||
|
"failed": "ダウンロード ホㇱキ アオハシ カ エアイカㇷ゚。",
|
||||||
|
"timeout": "ダウンロード アオハシ アエヌカㇻ トキ オケレ。"
|
||||||
|
},
|
||||||
|
"axisLimit": "ウコピㇱキ アㇰシㇱ {{max}} パㇰノ ネ。イキㇼ ネワ コラム オルㇱペ ポンノ カㇻ ヤン。",
|
||||||
|
"privateCondition": "ソモ アヌカレ オルㇱペ アシッケウ クス、タン イフナラ イアヌ アニ ウコピㇱキ エアイカㇷ゚。",
|
||||||
"errors": {
|
"errors": {
|
||||||
"queryTimeout": "集計処理が時間制限を超えました。抽出条件や集計軸を減らして再実行してください。",
|
"queryTimeout": "ウコピㇱキ イカㇻ トキ オケレ。イフナラ イアヌ ネ ヤ ウコピㇱキ アㇰシㇱ ポンノ カㇻ ワ スイ キ ヤン。",
|
||||||
"workerUnavailable": "エクスポートワーカーが稼働していません。",
|
"workerUnavailable": "エクスポート ワーカー イカㇻ ソモ キ。",
|
||||||
"stopped": "エクスポート処理が停止しました。再実行してください。",
|
"stopped": "エクスポート イカㇻ オケレ ソモ キ。スイ キ ヤン。",
|
||||||
"input": "入力条件が正しくありません。",
|
"input": "エヌイェㇷ゚ シㇼキ ピㇼカ ソモ ネ。",
|
||||||
"permission": "この操作を実行する権限がありません。",
|
"permission": "タン イカㇻ キ クス イレンカ エコㇿ ソモ キ。",
|
||||||
"authentication": "認証状態を確認して再実行してください。"
|
"authentication": "エアヌカㇻ シㇼキ エヌカㇻ ワ スイ キ ヤン。"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,5 @@
|
|||||||
{
|
{
|
||||||
"_untranslated": [
|
"exportPath": "アサンケ パㇱ",
|
||||||
"exportPath",
|
|
||||||
"restoreScope",
|
|
||||||
"nameChanges.title",
|
|
||||||
"nameChanges.script",
|
|
||||||
"nameChanges.automatic",
|
|
||||||
"nameChanges.certified",
|
|
||||||
"nameChanges.otherLanguages",
|
|
||||||
"nameChanges.changed",
|
|
||||||
"nameChanges.currentReference",
|
|
||||||
"nameChanges.noNameRecord",
|
|
||||||
"nameChanges.uncertified"
|
|
||||||
],
|
|
||||||
"exportPath": "export_path",
|
|
||||||
"postTitle": "$t(tags:history)",
|
"postTitle": "$t(tags:history)",
|
||||||
"tagTitle": "シロシ イヌイェㇷ゚ フㇱコアンペ",
|
"tagTitle": "シロシ イヌイェㇷ゚ フㇱコアンペ",
|
||||||
"materialTitle": "チカㇻペ フㇱコアンペ",
|
"materialTitle": "チカㇻペ フㇱコアンペ",
|
||||||
@@ -32,17 +19,17 @@
|
|||||||
"confirmTitle": "アホシピレ エヌカㇻ",
|
"confirmTitle": "アホシピレ エヌカㇻ",
|
||||||
"confirmPost": "「{{name}}」 ウェㇽソン {{version}} ウン アホシピレ ヤ?\nピㇼカ ヤ?",
|
"confirmPost": "「{{name}}」 ウェㇽソン {{version}} ウン アホシピレ ヤ?\nピㇼカ ヤ?",
|
||||||
"confirmTag": "シロシ「{{name}}」 ウェㇽソン {{version}} ウン アホシピレ ヤ?\nピㇼカ ヤ?",
|
"confirmTag": "シロシ「{{name}}」 ウェㇽソン {{version}} ウン アホシピレ ヤ?\nピㇼカ ヤ?",
|
||||||
"restoreScope": "名称・別名は現在表示中の言語だけを差し戻します。全言語の名称は復元しません。",
|
"restoreScope": "レ ネワ モㇱマ レ タネ アヌカレ イタㇰ パテㇰ アホシピレ。イタㇰ オピッタ コㇿ レ アホシピレ ソモ キ。",
|
||||||
"nameChanges": {
|
"nameChanges": {
|
||||||
"currentReference": "現行名・参考",
|
"currentReference": "タネ レ・アエヌカㇻ クニ ペ",
|
||||||
"noNameRecord": "この版には名称記録なし",
|
"noNameRecord": "タン ウェㇽソン タ レ アヌイェ ペ イサㇺ",
|
||||||
"otherLanguages": "他言語情報",
|
"otherLanguages": "モㇱマ イタㇰ オルㇱペ",
|
||||||
"changed": "(異動あり)",
|
"changed": "(シンナ アカㇻ)",
|
||||||
"uncertified": "(未公証)",
|
"uncertified": "(ナ ソモ アヌカㇻ オケレ)",
|
||||||
"title": "言語別の変更",
|
"title": "イタㇰ ネ ウシンナ シンナ アカㇻ ペ",
|
||||||
"script": "文字体系",
|
"script": "ヌイェ イソネカ",
|
||||||
"automatic": "自動生成",
|
"automatic": "ヤイウㇰ アカㇻ",
|
||||||
"certified": "公証済み"
|
"certified": "(アヌカㇻ オケレ)"
|
||||||
},
|
},
|
||||||
"revert": "アホシピレ",
|
"revert": "アホシピレ",
|
||||||
"restored": "アホシピレ オケレ!",
|
"restored": "アホシピレ オケレ!",
|
||||||
|
|||||||
@@ -24,5 +24,7 @@
|
|||||||
"settings": "イアヌ",
|
"settings": "イアヌ",
|
||||||
"legal": "イレンカ",
|
"legal": "イレンカ",
|
||||||
"terms": "エイワンケ イレンカ",
|
"terms": "エイワンケ イレンカ",
|
||||||
"more": "モㇱマ アン ペ »"
|
"more": "モㇱマ アン ペ »",
|
||||||
|
"counts": "ウコピㇱキ",
|
||||||
|
"externalTags": "ソイタ シロシ"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
{
|
{
|
||||||
"head": { "description": "$t(posts:list.tagline)" },
|
"head": {
|
||||||
|
"description": "$t(posts:list.tagline)"
|
||||||
|
},
|
||||||
"dialogue": {
|
"dialogue": {
|
||||||
"confirm": "エヌカㇻ ワ ピㇼカ",
|
"confirm": "エヌカㇻ ワ ピㇼカ",
|
||||||
"close": "$t(settings:actions.close)"
|
"close": "$t(settings:actions.close)"
|
||||||
@@ -56,7 +58,8 @@
|
|||||||
"latest": "(イヨッタ アシㇼ)",
|
"latest": "(イヨッタ アシㇼ)",
|
||||||
"diff": "ウシンナイペ",
|
"diff": "ウシンナイペ",
|
||||||
"restore": "ホㇱピ",
|
"restore": "ホㇱピ",
|
||||||
"show": "ヌカㇻ"
|
"show": "ヌカㇻ",
|
||||||
|
"count": "チピㇱキㇷ゚"
|
||||||
},
|
},
|
||||||
"messages": {
|
"messages": {
|
||||||
"loading": "アウㇰ コㇿ アン…",
|
"loading": "アウㇰ コㇿ アン…",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"languageNames": {
|
"languageNames": {
|
||||||
"ja": "日本語",
|
"ja": "日本語",
|
||||||
"ain": "北海道アイヌ語",
|
"ain": "北海道アイヌ語",
|
||||||
"en": "英語"
|
"en": "イングランド語"
|
||||||
},
|
},
|
||||||
"loadingLabel": "Loading",
|
"loadingLabel": "Loading",
|
||||||
"countLabel": "件数",
|
"countLabel": "件数",
|
||||||
|
|||||||
@@ -70,11 +70,11 @@
|
|||||||
"thumbnailDisplay": "$t(shared:labels.thumbnail)"
|
"thumbnailDisplay": "$t(shared:labels.thumbnail)"
|
||||||
},
|
},
|
||||||
"fields": {
|
"fields": {
|
||||||
"from": "開始(端末の時刻帯・以上)",
|
"from": "開始(以上)",
|
||||||
"before": "終了(端末の時刻帯・未満)",
|
"before": "終了(未満)",
|
||||||
"post": "投稿 ID",
|
"post": "投稿 Id.",
|
||||||
"tag": "タグ名または ID",
|
"tag": "タグ名または Id.",
|
||||||
"actor": "操作者 ID",
|
"actor": "操作者 Id.",
|
||||||
"limit": "表示件数"
|
"limit": "表示件数"
|
||||||
},
|
},
|
||||||
"latestOnly": "最新のみ",
|
"latestOnly": "最新のみ",
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
import CountsResourcePage from '@/pages/CountsResourcePage'
|
|
||||||
|
|
||||||
|
|
||||||
const CountsPage = () => <CountsResourcePage resource="posts"/>
|
|
||||||
|
|
||||||
export default CountsPage
|
|
||||||
+1
-1
@@ -6,7 +6,7 @@ import { HelmetProvider } from 'react-helmet-async'
|
|||||||
import { createMemoryRouter, RouterProvider, useLocation } from 'react-router-dom'
|
import { createMemoryRouter, RouterProvider, useLocation } from 'react-router-dom'
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||||
|
|
||||||
import CountsResourcePage from '@/pages/CountsResourcePage'
|
import CountsResourcePage from '@/pages/counts/CountsResourcePage'
|
||||||
import DialogueProvider from '@/components/dialogues/DialogueProvider'
|
import DialogueProvider from '@/components/dialogues/DialogueProvider'
|
||||||
import { countsKeys } from '@/lib/queryKeys'
|
import { countsKeys } from '@/lib/queryKeys'
|
||||||
import SortableColumns from '@/components/common/SortableColumns'
|
import SortableColumns from '@/components/common/SortableColumns'
|
||||||
+25
-16
@@ -222,7 +222,8 @@ const CountsResourceContent = (
|
|||||||
}
|
}
|
||||||
catch (failure)
|
catch (failure)
|
||||||
{
|
{
|
||||||
if (pendingRun.current !== pending) return
|
if (pendingRun.current !== pending)
|
||||||
|
return
|
||||||
pendingRun.current = null
|
pendingRun.current = null
|
||||||
setRunning (false)
|
setRunning (false)
|
||||||
setRunFailure (failure)
|
setRunFailure (failure)
|
||||||
@@ -252,7 +253,8 @@ const CountsResourceContent = (
|
|||||||
if (key === 'measures' || key.startsWith ('measures.')) next.delete (key)
|
if (key === 'measures' || key.startsWith ('measures.')) next.delete (key)
|
||||||
for (const [key, value] of Object.entries (extra)) next.set (key, value)
|
for (const [key, value] of Object.entries (extra)) next.set (key, value)
|
||||||
}
|
}
|
||||||
if (key === 'sort') next.delete ('page')
|
if (key === 'sort')
|
||||||
|
next.delete ('page')
|
||||||
setParams (next)
|
setParams (next)
|
||||||
}
|
}
|
||||||
const download = async (format: 'csv' | 'json') => {
|
const download = async (format: 'csv' | 'json') => {
|
||||||
@@ -321,8 +323,11 @@ const CountsResourceContent = (
|
|||||||
aria-expanded={expanded.has (target)} aria-controls={`counts-definition-${target}`}
|
aria-expanded={expanded.has (target)} aria-controls={`counts-definition-${target}`}
|
||||||
onClick={() => setExpanded (previous => {
|
onClick={() => setExpanded (previous => {
|
||||||
const next = new Set (previous)
|
const next = new Set (previous)
|
||||||
if (next.has (target)) next.delete (target)
|
if (next.has (target))
|
||||||
else next.add (target)
|
next.delete (target)
|
||||||
|
else
|
||||||
|
next.add (target)
|
||||||
|
|
||||||
return next
|
return next
|
||||||
})}>
|
})}>
|
||||||
<span aria-hidden className="inline-block" style={{
|
<span aria-hidden className="inline-block" style={{
|
||||||
@@ -331,18 +336,22 @@ const CountsResourceContent = (
|
|||||||
{label (`resources.${target}`)}
|
{label (`resources.${target}`)}
|
||||||
</button>
|
</button>
|
||||||
<AnimatedCollapse open={expanded.has (target)} id={`counts-definition-${target}`}>
|
<AnimatedCollapse open={expanded.has (target)} id={`counts-definition-${target}`}>
|
||||||
<ul className="ml-3">
|
<ul className="ml-3">
|
||||||
{(['latest', 'history'] as const).map (definition => {
|
{(['latest', 'history'] as const).map (definition => {
|
||||||
const next = countsDefinitionParams (definition, params)
|
const next = countsDefinitionParams (definition, params)
|
||||||
const active = target === resource
|
const active = target === resource
|
||||||
&& params.get ('definition') === definition
|
&& params.get ('definition') === definition
|
||||||
return <li key={definition}><PrefetchLink
|
return (
|
||||||
to={`/counts/${target}?${next}`}
|
<li key={definition}>
|
||||||
aria-current={active ? 'page' : undefined}
|
<PrefetchLink
|
||||||
className={cn ('block py-1', active && 'font-bold underline')}>
|
to={`/counts/${target}?${next}`}
|
||||||
{label (definition)}</PrefetchLink></li>
|
aria-current={active ? 'page' : undefined}
|
||||||
})}
|
className={cn ('block py-1', active && 'font-bold underline')}>
|
||||||
</ul>
|
{label (definition)}
|
||||||
|
</PrefetchLink>
|
||||||
|
</li>)
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
</AnimatedCollapse>
|
</AnimatedCollapse>
|
||||||
</li>)}
|
</li>)}
|
||||||
</ul>
|
</ul>
|
||||||
新しいイシューから参照
ユーザーをブロックする