mirror of
https://github.com/flarum/core.git
synced 2025-08-16 13:24:11 +02:00
Compare commits
35 Commits
v1.3.1
...
sm/3504-fi
Author | SHA1 | Date | |
---|---|---|---|
|
1caff3e6fc | ||
|
e21a1e09fd | ||
|
03178bb460 | ||
|
5753edac79 | ||
|
2e3d6dfa2c | ||
|
7cd28710bc | ||
|
bc1d6f9e91 | ||
|
bf4c543692 | ||
|
709c5566bb | ||
|
9a62c32c28 | ||
|
bbf90e42ff | ||
|
0859bb13a5 | ||
|
62be3e01be | ||
|
613523c9b4 | ||
|
3e56bd3dc6 | ||
|
293e8ab8b6 | ||
|
824fb2feff | ||
|
4923253fbf | ||
|
36c296d787 | ||
|
9fc2e5e2c0 | ||
|
cb47a9c92e | ||
|
5dedec12f9 | ||
|
5e81592e18 | ||
|
74bcab866c | ||
|
1d949a3170 | ||
|
79e0f44324 | ||
|
976a03c9e5 | ||
|
49ab6630d4 | ||
|
27fb011bf5 | ||
|
6466427061 | ||
|
818035f385 | ||
|
4748f31d93 | ||
|
e049e9d7ae | ||
|
776f9bf132 | ||
|
f882ff9bb5 |
112
.github/workflows/REUSABLE_backend.yml
vendored
Normal file
112
.github/workflows/REUSABLE_backend.yml
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
name: Flarum Backend Jobs
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
enable_backend_testing:
|
||||
description: "Enable Backend Testing?"
|
||||
type: boolean
|
||||
default: true
|
||||
required: false
|
||||
|
||||
backend_directory:
|
||||
description: The directory of the project where backend code is located. This should contain a `composer.json` file, and is generally the root directory of the repo.
|
||||
type: string
|
||||
required: false
|
||||
default: '.'
|
||||
|
||||
php_versions:
|
||||
description: Versions of PHP to test with. Should be array of strings encoded as JSON array
|
||||
type: string
|
||||
required: false
|
||||
default: '["7.4", "8.0", "8.1"]'
|
||||
db_versions:
|
||||
description: Versions of databases to test with. Should be array of strings encoded as JSON array
|
||||
type: string
|
||||
required: false
|
||||
default: '["mysql:5.7", "mariadb"]'
|
||||
|
||||
php_ini_values:
|
||||
description: PHP ini values
|
||||
type: string
|
||||
required: false
|
||||
default: error_reporting=E_ALL
|
||||
|
||||
env:
|
||||
COMPOSER_ROOT_VERSION: dev-main
|
||||
FLARUM_TEST_TMP_DIR_LOCAL: tests/integration/tmp
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php: ${{ fromJSON(inputs.php_versions) }}
|
||||
service: ${{ fromJSON(inputs.db_versions) }}
|
||||
prefix: ['', flarum_]
|
||||
|
||||
include:
|
||||
- service: 'mysql:5.7'
|
||||
db: MySQL
|
||||
- service: mariadb
|
||||
db: MariaDB
|
||||
- prefix: flarum_
|
||||
prefixStr: (prefix)
|
||||
|
||||
exclude:
|
||||
- php: 8.0
|
||||
service: 'mysql:5.7'
|
||||
prefix: flarum_
|
||||
- php: 8.0
|
||||
service: mariadb
|
||||
prefix: flarum_
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: ${{ matrix.service }}
|
||||
ports:
|
||||
- 13306:3306
|
||||
|
||||
name: 'PHP ${{ matrix.php }} / ${{ matrix.db }} ${{ matrix.prefixStr }}'
|
||||
|
||||
if: inputs.enable_backend_testing
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
coverage: xdebug
|
||||
extensions: curl, dom, gd, json, mbstring, openssl, pdo_mysql, tokenizer, zip
|
||||
tools: phpunit, composer:v2
|
||||
ini-values: ${{ inputs.php_ini_values }}
|
||||
|
||||
# The authentication alter is necessary because newer mysql versions use the `caching_sha2_password` driver,
|
||||
# which isn't supported prior to PHP7.4
|
||||
# When we drop support for PHP7.3, we should remove this from the setup.
|
||||
- name: Create MySQL Database
|
||||
run: |
|
||||
sudo systemctl start mysql
|
||||
mysql -uroot -proot -e 'CREATE DATABASE flarum_test;' --port 13306
|
||||
mysql -uroot -proot -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root';" --port 13306
|
||||
|
||||
- name: Install Composer dependencies
|
||||
run: composer install
|
||||
working-directory: ${{ inputs.backend_directory }}
|
||||
|
||||
- name: Setup Composer tests
|
||||
run: composer test:setup
|
||||
working-directory: ${{ inputs.backend_directory }}
|
||||
env:
|
||||
DB_PORT: 13306
|
||||
DB_PASSWORD: root
|
||||
DB_PREFIX: ${{ matrix.prefix }}
|
||||
|
||||
- name: Run Composer tests
|
||||
run: composer test
|
||||
working-directory: ${{ inputs.backend_directory }}
|
||||
env:
|
||||
COMPOSER_PROCESS_TIMEOUT: 600
|
220
.github/workflows/REUSABLE_frontend.yml
vendored
Normal file
220
.github/workflows/REUSABLE_frontend.yml
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
name: Flarum Frontend Jobs
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
enable_bundlewatch:
|
||||
description: "Enable Bundlewatch?"
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
enable_prettier:
|
||||
description: "Enable Prettier?"
|
||||
type: boolean
|
||||
default: true
|
||||
required: false
|
||||
enable_typescript:
|
||||
description: "Enable TypeScript?"
|
||||
type: boolean
|
||||
default: true
|
||||
required: false
|
||||
|
||||
backend_directory:
|
||||
description: The directory of the project where backend code is located. This should contain a `composer.json` file, and is generally the root directory of the repo.
|
||||
type: string
|
||||
required: false
|
||||
default: '.'
|
||||
frontend_directory:
|
||||
description: The directory of the project where frontend code is located. This should contain a `package.json` file.
|
||||
type: string
|
||||
required: false
|
||||
default: './js'
|
||||
main_git_branch:
|
||||
description: The main git branch to use for the workflow.
|
||||
type: string
|
||||
required: false
|
||||
default: main
|
||||
node_version:
|
||||
description: The node version to use for the workflow.
|
||||
type: number
|
||||
required: false
|
||||
default: 16
|
||||
|
||||
js_package_manager:
|
||||
description: "Enable TypeScript?"
|
||||
type: string
|
||||
default: yarn
|
||||
required: false
|
||||
cache_dependency_path:
|
||||
description: "The path to the cache dependency file."
|
||||
type: string
|
||||
required: false
|
||||
|
||||
secrets:
|
||||
bundlewatch_github_token:
|
||||
description: The GitHub token to use for Bundlewatch.
|
||||
required: false
|
||||
|
||||
env:
|
||||
COMPOSER_ROOT_VERSION: dev-main
|
||||
ci_script: ${{ inputs.js_package_manager == 'yarn' && 'yarn install --immutable' || 'npm ci' }}
|
||||
cache_dependency_path: ${{ inputs.cache_dependency_path || format(inputs.js_package_manager == 'yarn' && '{0}/yarn.lock' || '{0}/package-lock.json', inputs.frontend_directory) }}
|
||||
|
||||
jobs:
|
||||
bundlewatch:
|
||||
name: Bundlewatch
|
||||
runs-on: ubuntu-latest
|
||||
if: inputs.enable_bundlewatch
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ inputs.node_version }}
|
||||
cache: ${{ inputs.js_package_manager }}
|
||||
cache-dependency-path: ${{ env.cache_dependency_path }}
|
||||
|
||||
- name: Build production assets
|
||||
uses: flarum/action-build@2
|
||||
with:
|
||||
github_token: ${{ secrets.github_token }}
|
||||
build_script: build
|
||||
package_manager: ${{ inputs.js_package_manager }}
|
||||
js_path: ${{ inputs.frontend_directory }}
|
||||
do_not_commit: true
|
||||
|
||||
- name: Check bundle size change
|
||||
run: node_modules/.bin/bundlewatch --config .bundlewatch.config.json
|
||||
working-directory: ${{ inputs.frontend_directory }}
|
||||
env:
|
||||
BUNDLEWATCH_GITHUB_TOKEN: ${{ secrets.bundlewatch_github_token }}
|
||||
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
prettier:
|
||||
name: Prettier
|
||||
runs-on: ubuntu-latest
|
||||
if: inputs.enable_prettier
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ inputs.node_version }}
|
||||
cache: ${{ inputs.js_package_manager }}
|
||||
cache-dependency-path: ${{ env.cache_dependency_path }}
|
||||
|
||||
- name: Install JS dependencies
|
||||
run: ${{ env.ci_script }}
|
||||
working-directory: ${{ inputs.frontend_directory }}
|
||||
|
||||
- name: Check JS formatting
|
||||
run: ${{ inputs.js_package_manager }} run format-check
|
||||
working-directory: ${{ inputs.frontend_directory }}
|
||||
|
||||
typecheck:
|
||||
name: Typecheck
|
||||
runs-on: ubuntu-latest
|
||||
if: inputs.enable_typescript
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ inputs.node_version }}
|
||||
cache: ${{ inputs.js_package_manager }}
|
||||
cache-dependency-path: ${{ env.cache_dependency_path }}
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.0'
|
||||
extensions: curl, dom, gd, json, mbstring, openssl, pdo_mysql, tokenizer, zip
|
||||
tools: composer:v2
|
||||
|
||||
# Needed since tsconfig draws typings from vendor folder.
|
||||
- name: Install Composer dependencies
|
||||
run: composer install
|
||||
working-directory: ${{ inputs.backend_directory }}
|
||||
|
||||
- name: Install JS dependencies
|
||||
run: ${{ env.ci_script }}
|
||||
working-directory: ${{ inputs.frontend_directory }}
|
||||
|
||||
- name: Typecheck
|
||||
run: ${{ inputs.js_package_manager }} run check-typings
|
||||
working-directory: ${{ inputs.frontend_directory }}
|
||||
|
||||
type-coverage:
|
||||
name: Type Coverage
|
||||
runs-on: ubuntu-latest
|
||||
if: inputs.enable_typescript
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ inputs.node_version }}
|
||||
cache: ${{ inputs.js_package_manager }}
|
||||
cache-dependency-path: ${{ env.cache_dependency_path }}
|
||||
|
||||
- name: Install JS dependencies
|
||||
run: ${{ env.ci_script }}
|
||||
working-directory: ${{ inputs.frontend_directory }}
|
||||
|
||||
- name: Check type coverage
|
||||
run: ${{ inputs.js_package_manager }} run check-typings-coverage
|
||||
working-directory: ${{ inputs.frontend_directory }}
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
if: "always() && !contains(needs.*.result, 'failed') && !contains(needs.*.result, 'cancelled')"
|
||||
needs: [bundlewatch, prettier, typecheck, type-coverage]
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ inputs.node_version }}
|
||||
cache: ${{ inputs.js_package_manager }}
|
||||
cache-dependency-path: ${{ env.cache_dependency_path }}
|
||||
|
||||
# Our action will install npm/yarn, cd into `${{ inputs.frontend_directory }}`, build dist JS and typings,
|
||||
# then commit and upload any changes iff we are on the main branch and have just pushed.
|
||||
- name: Build production JS
|
||||
if: inputs.enable_typescript
|
||||
uses: flarum/action-build@2
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
build_script: build
|
||||
package_manager: ${{ inputs.js_package_manager }}
|
||||
typings_script: build-typings
|
||||
js_path: ${{ inputs.frontend_directory }}
|
||||
do_not_commit: ${{ github.ref != format('refs/heads/{0}', inputs.main_git_branch) || github.event_name != 'push' }}
|
||||
|
||||
# Our action will install npm/yarn, cd into `${{ inputs.frontend_directory }}`, build dist JS and typings,
|
||||
# then commit and upload any changes iff we are on the main branch and have just pushed.
|
||||
- name: Build production JS
|
||||
if: "! inputs.enable_typescript"
|
||||
uses: flarum/action-build@2
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
build_script: build
|
||||
package_manager: ${{ inputs.js_package_manager }}
|
||||
js_path: ${{ inputs.frontend_directory }}
|
||||
do_not_commit: ${{ github.ref != format('refs/heads/{0}', inputs.main_git_branch) || github.event_name != 'push' }}
|
6
.github/workflows/flarum-akismet-backend.yml
vendored
6
.github/workflows/flarum-akismet-backend.yml
vendored
@@ -2,13 +2,9 @@ name: Akismet PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: true
|
||||
|
||||
|
@@ -2,13 +2,9 @@ name: Akismet JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: true
|
||||
@@ -17,6 +13,7 @@ jobs:
|
||||
frontend_directory: ./extensions/akismet/js
|
||||
backend_directory: ./extensions/akismet
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
|
||||
secrets:
|
||||
|
@@ -2,13 +2,9 @@ name: Approval PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: false
|
||||
|
||||
|
@@ -2,13 +2,9 @@ name: Approval JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: true
|
||||
@@ -17,6 +13,7 @@ jobs:
|
||||
frontend_directory: ./extensions/approval/js
|
||||
backend_directory: ./extensions/approval
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
|
||||
secrets:
|
||||
|
6
.github/workflows/flarum-core-backend.yml
vendored
6
.github/workflows/flarum-core-backend.yml
vendored
@@ -2,13 +2,9 @@ name: Core PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: true
|
||||
|
||||
|
7
.github/workflows/flarum-core-frontend.yml
vendored
7
.github/workflows/flarum-core-frontend.yml
vendored
@@ -2,13 +2,9 @@ name: Core JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: true
|
||||
enable_prettier: true
|
||||
@@ -17,6 +13,7 @@ jobs:
|
||||
frontend_directory: ./framework/core/js
|
||||
backend_directory: ./framework/core
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
|
||||
secrets:
|
||||
|
6
.github/workflows/flarum-embed-backend.yml
vendored
6
.github/workflows/flarum-embed-backend.yml
vendored
@@ -2,13 +2,9 @@ name: Embed PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: false
|
||||
|
||||
|
7
.github/workflows/flarum-embed-frontend.yml
vendored
7
.github/workflows/flarum-embed-frontend.yml
vendored
@@ -2,13 +2,9 @@ name: Embed JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: true
|
||||
@@ -17,6 +13,7 @@ jobs:
|
||||
frontend_directory: ./extensions/embed/js
|
||||
backend_directory: ./extensions/embed
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
|
||||
secrets:
|
||||
|
6
.github/workflows/flarum-emoji-backend.yml
vendored
6
.github/workflows/flarum-emoji-backend.yml
vendored
@@ -2,13 +2,9 @@ name: Emoji PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: false
|
||||
|
||||
|
7
.github/workflows/flarum-emoji-frontend.yml
vendored
7
.github/workflows/flarum-emoji-frontend.yml
vendored
@@ -2,13 +2,9 @@ name: Emoji JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: true
|
||||
@@ -17,6 +13,7 @@ jobs:
|
||||
frontend_directory: ./extensions/emoji/js
|
||||
backend_directory: ./extensions/emoji
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
|
||||
secrets:
|
||||
|
6
.github/workflows/flarum-flags-backend.yml
vendored
6
.github/workflows/flarum-flags-backend.yml
vendored
@@ -2,13 +2,9 @@ name: Flags PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: true
|
||||
|
||||
|
7
.github/workflows/flarum-flags-frontend.yml
vendored
7
.github/workflows/flarum-flags-frontend.yml
vendored
@@ -2,13 +2,9 @@ name: Flags JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: true
|
||||
@@ -17,6 +13,7 @@ jobs:
|
||||
frontend_directory: ./extensions/flags/js
|
||||
backend_directory: ./extensions/flags
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
|
||||
secrets:
|
||||
|
6
.github/workflows/flarum-likes-backend.yml
vendored
6
.github/workflows/flarum-likes-backend.yml
vendored
@@ -2,13 +2,9 @@ name: Likes PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: false
|
||||
|
||||
|
7
.github/workflows/flarum-likes-frontend.yml
vendored
7
.github/workflows/flarum-likes-frontend.yml
vendored
@@ -2,13 +2,9 @@ name: Likes JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: true
|
||||
@@ -17,6 +13,7 @@ jobs:
|
||||
frontend_directory: ./extensions/likes/js
|
||||
backend_directory: ./extensions/likes
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
|
||||
secrets:
|
||||
|
6
.github/workflows/flarum-lock-backend.yml
vendored
6
.github/workflows/flarum-lock-backend.yml
vendored
@@ -2,13 +2,9 @@ name: Lock PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: false
|
||||
|
||||
|
7
.github/workflows/flarum-lock-frontend.yml
vendored
7
.github/workflows/flarum-lock-frontend.yml
vendored
@@ -2,13 +2,9 @@ name: Lock JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: true
|
||||
@@ -17,6 +13,7 @@ jobs:
|
||||
frontend_directory: ./extensions/lock/js
|
||||
backend_directory: ./extensions/lock
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
|
||||
secrets:
|
||||
|
@@ -2,13 +2,9 @@ name: Markdown PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: false
|
||||
|
||||
|
@@ -2,13 +2,9 @@ name: Markdown JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: true
|
||||
@@ -17,6 +13,7 @@ jobs:
|
||||
frontend_directory: ./extensions/markdown/js
|
||||
backend_directory: ./extensions/markdown
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
|
||||
secrets:
|
||||
|
@@ -2,13 +2,9 @@ name: Mentions PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: true
|
||||
|
||||
|
@@ -2,13 +2,9 @@ name: Mentions JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: true
|
||||
@@ -17,6 +13,7 @@ jobs:
|
||||
frontend_directory: ./extensions/mentions/js
|
||||
backend_directory: ./extensions/mentions
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
|
||||
secrets:
|
||||
|
@@ -2,13 +2,9 @@ name: Nicknames PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: true
|
||||
|
||||
|
@@ -2,13 +2,9 @@ name: Nicknames JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: true
|
||||
@@ -17,6 +13,7 @@ jobs:
|
||||
frontend_directory: ./extensions/nicknames/js
|
||||
backend_directory: ./extensions/nicknames
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
|
||||
secrets:
|
||||
|
@@ -2,13 +2,9 @@ name: Package Manager PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: true
|
||||
|
||||
|
@@ -2,13 +2,9 @@ name: Package Manager JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: true
|
||||
@@ -17,6 +13,7 @@ jobs:
|
||||
frontend_directory: ./extensions/package-manager/js
|
||||
backend_directory: ./extensions/package-manager
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
|
||||
secrets:
|
||||
|
6
.github/workflows/flarum-pusher-backend.yml
vendored
6
.github/workflows/flarum-pusher-backend.yml
vendored
@@ -2,13 +2,9 @@ name: Pusher PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: false
|
||||
|
||||
|
7
.github/workflows/flarum-pusher-frontend.yml
vendored
7
.github/workflows/flarum-pusher-frontend.yml
vendored
@@ -2,13 +2,9 @@ name: Pusher JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: true
|
||||
@@ -17,6 +13,7 @@ jobs:
|
||||
frontend_directory: ./extensions/pusher/js
|
||||
backend_directory: ./extensions/pusher
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
|
||||
secrets:
|
||||
|
@@ -2,13 +2,9 @@ name: Statistics PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: true
|
||||
|
||||
|
@@ -2,13 +2,9 @@ name: Statistics JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: true
|
||||
@@ -17,6 +13,7 @@ jobs:
|
||||
frontend_directory: ./extensions/statistics/js
|
||||
backend_directory: ./extensions/statistics
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
|
||||
secrets:
|
||||
|
8
.github/workflows/flarum-sticky-backend.yml
vendored
8
.github/workflows/flarum-sticky-backend.yml
vendored
@@ -2,14 +2,10 @@ name: Sticky PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: false
|
||||
enable_backend_testing: true
|
||||
|
||||
backend_directory: ./extensions/sticky
|
||||
|
7
.github/workflows/flarum-sticky-frontend.yml
vendored
7
.github/workflows/flarum-sticky-frontend.yml
vendored
@@ -2,13 +2,9 @@ name: Sticky JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: true
|
||||
@@ -17,6 +13,7 @@ jobs:
|
||||
frontend_directory: ./extensions/sticky/js
|
||||
backend_directory: ./extensions/sticky
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
|
||||
secrets:
|
||||
|
@@ -2,13 +2,9 @@ name: Subscriptions PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: false
|
||||
|
||||
|
@@ -2,13 +2,9 @@ name: Subscriptions JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: true
|
||||
@@ -17,6 +13,7 @@ jobs:
|
||||
frontend_directory: ./extensions/subscriptions/js
|
||||
backend_directory: ./extensions/subscriptions
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
|
||||
secrets:
|
||||
|
6
.github/workflows/flarum-suspend-backend.yml
vendored
6
.github/workflows/flarum-suspend-backend.yml
vendored
@@ -2,13 +2,9 @@ name: Suspend PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: false
|
||||
|
||||
|
@@ -2,13 +2,9 @@ name: Suspend JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: true
|
||||
@@ -17,6 +13,7 @@ jobs:
|
||||
frontend_directory: ./extensions/suspend/js
|
||||
backend_directory: ./extensions/suspend
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
|
||||
secrets:
|
||||
|
6
.github/workflows/flarum-tags-backend.yml
vendored
6
.github/workflows/flarum-tags-backend.yml
vendored
@@ -2,13 +2,9 @@ name: Tags PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_backend.yml
|
||||
with:
|
||||
enable_backend_testing: true
|
||||
|
||||
|
9
.github/workflows/flarum-tags-frontend.yml
vendored
9
.github/workflows/flarum-tags-frontend.yml
vendored
@@ -2,21 +2,18 @@ name: Tags JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
uses: ./.github/workflows/REUSABLE_frontend.yml
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: false
|
||||
enable_prettier: true
|
||||
enable_typescript: true
|
||||
|
||||
frontend_directory: ./extensions/tags/js
|
||||
backend_directory: ./extensions/tags
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
secrets:
|
||||
bundlewatch_github_token: ${{ secrets.BUNDLEWATCH_GITHUB_TOKEN }}
|
||||
|
@@ -86,7 +86,6 @@
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": ">=7.3",
|
||||
"axy/sourcemap": "^0.1.4",
|
||||
"components/font-awesome": "^5.14.0",
|
||||
"composer/composer": "^2.0",
|
||||
"dflydev/fig-cookies": "^3.0.0",
|
||||
@@ -127,6 +126,8 @@
|
||||
"psr/http-server-middleware": "^1.0",
|
||||
"pusher/pusher-php-server": "^2.2",
|
||||
"s9e/text-formatter": "^2.3.6",
|
||||
"sycho/json-api": "^0.5.0",
|
||||
"sycho/sourcemap": "^2.0.0",
|
||||
"symfony/config": "^5.2.2",
|
||||
"symfony/console": "^5.2.2",
|
||||
"symfony/event-dispatcher": "^5.2.2",
|
||||
@@ -134,7 +135,6 @@
|
||||
"symfony/polyfill-intl-messageformatter": "^1.22.0",
|
||||
"symfony/translation": "^5.1.5",
|
||||
"symfony/yaml": "^5.2.2",
|
||||
"tobscure/json-api": "^0.3.0",
|
||||
"wikimedia/less.php": "^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
8862
extensions/emoji/js/package-lock.json
generated
8862
extensions/emoji/js/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2
extensions/mentions/js/dist/forum.js
generated
vendored
2
extensions/mentions/js/dist/forum.js
generated
vendored
File diff suppressed because one or more lines are too long
2
extensions/mentions/js/dist/forum.js.map
generated
vendored
2
extensions/mentions/js/dist/forum.js.map
generated
vendored
File diff suppressed because one or more lines are too long
@@ -23,6 +23,6 @@ export default class PostMentionedNotification extends Notification {
|
||||
}
|
||||
|
||||
excerpt() {
|
||||
return truncate(this.attrs.notification.subject().contentPlain(), 200);
|
||||
return truncate(this.attrs.notification.subject().contentPlain() || '', 200);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Schema\Builder;
|
||||
|
||||
return [
|
||||
'up' => function (Builder $schema) {
|
||||
$schema->table('post_mentions_post', function (Blueprint $table) {
|
||||
$table->timestamp('created_at')->nullable();
|
||||
});
|
||||
|
||||
// do this manually because dbal doesn't recognize timestamp columns
|
||||
$connection = $schema->getConnection();
|
||||
$prefix = $connection->getTablePrefix();
|
||||
$connection->statement("ALTER TABLE `${prefix}post_mentions_post` MODIFY created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP");
|
||||
},
|
||||
|
||||
'down' => function (Builder $schema) {
|
||||
$schema->table('post_mentions_post', function (Blueprint $table) {
|
||||
$table->dropColumn('created_at');
|
||||
});
|
||||
}
|
||||
];
|
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Schema\Builder;
|
||||
|
||||
return [
|
||||
'up' => function (Builder $schema) {
|
||||
$schema->table('post_mentions_user', function (Blueprint $table) {
|
||||
$table->timestamp('created_at')->nullable();
|
||||
});
|
||||
|
||||
// do this manually because dbal doesn't recognize timestamp columns
|
||||
$connection = $schema->getConnection();
|
||||
$prefix = $connection->getTablePrefix();
|
||||
$connection->statement("ALTER TABLE `${prefix}post_mentions_user` MODIFY created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP");
|
||||
},
|
||||
|
||||
'down' => function (Builder $schema) {
|
||||
$schema->table('post_mentions_user', function (Blueprint $table) {
|
||||
$table->dropColumn('created_at');
|
||||
});
|
||||
}
|
||||
];
|
@@ -14,7 +14,7 @@ use Flarum\Testing\integration\RetrievesAuthorizedUsers;
|
||||
use Flarum\Testing\integration\TestCase;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class ListTest extends TestCase
|
||||
class ListPostsTest extends TestCase
|
||||
{
|
||||
use RetrievesAuthorizedUsers;
|
||||
|
||||
@@ -85,4 +85,26 @@ class ListTest extends TestCase
|
||||
$ids = Arr::pluck($data, 'id');
|
||||
$this->assertEqualsCanonicalizing(['4'], $ids, 'IDs do not match');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function mentioned_filter_works_with_sort()
|
||||
{
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api/posts')
|
||||
->withQueryParams([
|
||||
'filter' => ['mentioned' => 1],
|
||||
'sort' => '-createdAt'
|
||||
])
|
||||
);
|
||||
|
||||
$data = json_decode($response->getBody()->getContents(), true)['data'];
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
|
||||
// Order-independent comparison
|
||||
$ids = Arr::pluck($data, 'id');
|
||||
$this->assertEqualsCanonicalizing(['2', '3'], $ids, 'IDs do not match');
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -51,7 +51,7 @@
|
||||
"prettier": true,
|
||||
"typescript": false,
|
||||
"bundlewatch": false,
|
||||
"backendTesting": false,
|
||||
"backendTesting": true,
|
||||
"editorConfig": true,
|
||||
"styleci": true
|
||||
}
|
||||
@@ -64,5 +64,28 @@
|
||||
}
|
||||
],
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
"prefer-stable": true,
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Flarum\\Sticky\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": [
|
||||
"@test:unit",
|
||||
"@test:integration"
|
||||
],
|
||||
"test:unit": "phpunit -c tests/phpunit.unit.xml",
|
||||
"test:integration": "phpunit -c tests/phpunit.integration.xml",
|
||||
"test:setup": "@php tests/integration/setup.php"
|
||||
},
|
||||
"scripts-descriptions": {
|
||||
"test": "Runs all tests.",
|
||||
"test:unit": "Runs all unit tests.",
|
||||
"test:integration": "Runs all integration tests.",
|
||||
"test:setup": "Sets up a database for use with integration tests. Execute this only once."
|
||||
},
|
||||
"require-dev": {
|
||||
"flarum/testing": "^1.0.0"
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -60,7 +60,6 @@ class PinStickiedDiscussionsToTop
|
||||
$query->orderByRaw('is_sticky and not exists ('.$read->toSql().') and last_posted_at > ? desc')
|
||||
->addBinding(array_merge($read->getBindings(), [$filterState->getActor()->read_time ?: 0]), 'union');
|
||||
|
||||
$query->unionOrders = array_merge($query->unionOrders, $query->orders);
|
||||
$query->unionLimit = $query->limit;
|
||||
$query->unionOffset = $query->offset;
|
||||
|
||||
|
0
extensions/sticky/tests/fixtures/.gitkeep
vendored
Normal file
0
extensions/sticky/tests/fixtures/.gitkeep
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Sticky\tests\integration\api;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
|
||||
use Flarum\Testing\integration\TestCase;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class ListDiscussionsTest extends TestCase
|
||||
{
|
||||
use RetrievesAuthorizedUsers;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->extension('flarum-sticky');
|
||||
|
||||
$this->prepareDatabase([
|
||||
'users' => [
|
||||
['id' => 1, 'username' => 'Muralf', 'email' => 'muralf@machine.local', 'is_email_confirmed' => 1],
|
||||
$this->normalUser()
|
||||
],
|
||||
'discussions' => [
|
||||
['id' => 1, 'title' => __CLASS__, 'created_at' => Carbon::now(), 'last_posted_at' => Carbon::now(), 'user_id' => 1, 'first_post_id' => 1, 'comment_count' => 1, 'is_sticky' => true],
|
||||
['id' => 2, 'title' => __CLASS__, 'created_at' => Carbon::now()->addMinute(), 'last_posted_at' => Carbon::now(), 'user_id' => 1, 'first_post_id' => 1, 'comment_count' => 1, 'is_sticky' => false],
|
||||
['id' => 3, 'title' => __CLASS__, 'created_at' => Carbon::now()->addMinutes(2), 'last_posted_at' => Carbon::now(), 'user_id' => 1, 'first_post_id' => 1, 'comment_count' => 1, 'is_sticky' => true],
|
||||
['id' => 4, 'title' => __CLASS__, 'created_at' => Carbon::now()->addMinutes(3), 'last_posted_at' => Carbon::now(), 'user_id' => 1, 'first_post_id' => 1, 'comment_count' => 1, 'is_sticky' => false],
|
||||
],
|
||||
'discussion_user' => [
|
||||
['discussion_id' => 1, 'user_id' => 1, 'last_read_post_number' => 1],
|
||||
['discussion_id' => 3, 'user_id' => 1, 'last_read_post_number' => 1],
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function list_discussions_shows_sticky_first_as_guest()
|
||||
{
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api/discussions')
|
||||
);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertEqualsCanonicalizing([1, 3, 2, 4], Arr::pluck($data['data'], 'id'));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function list_discussions_shows_sticky_unread_first_as_user()
|
||||
{
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api/discussions', [
|
||||
'authenticatedAs' => 2
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertEqualsCanonicalizing([1, 3, 2, 4], Arr::pluck($data['data'], 'id'));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function list_discussions_shows_normal_order_when_all_read_as_user()
|
||||
{
|
||||
$response = $this->send(
|
||||
$this->request('GET', '/api/discussions', [
|
||||
'authenticatedAs' => 1
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$this->assertEqualsCanonicalizing([1, 2, 3, 4], Arr::pluck($data['data'], 'id'));
|
||||
}
|
||||
}
|
16
extensions/sticky/tests/integration/setup.php
Normal file
16
extensions/sticky/tests/integration/setup.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Flarum\Testing\integration\Setup\SetupScript;
|
||||
|
||||
require __DIR__.'/../../vendor/autoload.php';
|
||||
|
||||
$setup = new SetupScript();
|
||||
|
||||
$setup->run();
|
25
extensions/sticky/tests/phpunit.integration.xml
Normal file
25
extensions/sticky/tests/phpunit.integration.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
|
||||
backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="true"
|
||||
stopOnFailure="false"
|
||||
>
|
||||
<coverage processUncoveredFiles="true">
|
||||
<include>
|
||||
<directory suffix=".php">../src/</directory>
|
||||
</include>
|
||||
</coverage>
|
||||
<testsuites>
|
||||
<testsuite name="Flarum Integration Tests">
|
||||
<directory suffix="Test.php">./integration</directory>
|
||||
<exclude>./integration/tmp</exclude>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
27
extensions/sticky/tests/phpunit.unit.xml
Normal file
27
extensions/sticky/tests/phpunit.unit.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
|
||||
backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
>
|
||||
<coverage processUncoveredFiles="true">
|
||||
<include>
|
||||
<directory suffix=".php">../src/</directory>
|
||||
</include>
|
||||
</coverage>
|
||||
<testsuites>
|
||||
<testsuite name="Flarum Unit Tests">
|
||||
<directory suffix="Test.php">./unit</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<listeners>
|
||||
<listener class="\Mockery\Adapter\Phpunit\TestListener" />
|
||||
</listeners>
|
||||
</phpunit>
|
0
extensions/sticky/tests/unit/.gitkeep
Normal file
0
extensions/sticky/tests/unit/.gitkeep
Normal file
File diff suppressed because it is too large
Load Diff
2
extensions/suspend/js/dist/forum.js
generated
vendored
2
extensions/suspend/js/dist/forum.js
generated
vendored
File diff suppressed because one or more lines are too long
2
extensions/suspend/js/dist/forum.js.map
generated
vendored
2
extensions/suspend/js/dist/forum.js.map
generated
vendored
File diff suppressed because one or more lines are too long
@@ -7,11 +7,12 @@ export default function () {
|
||||
if (app.session.user) {
|
||||
const message = app.session.user.suspendMessage();
|
||||
const until = app.session.user.suspendedUntil();
|
||||
const isSuspended = message && until && new Date() < until;
|
||||
const alreadyDisplayed = localStorage.getItem(localStorageKey()) === until?.getTime().toString();
|
||||
|
||||
if (message && !alreadyDisplayed) {
|
||||
if (isSuspended && !alreadyDisplayed) {
|
||||
app.modal.show(SuspensionInfoModal, { message, until });
|
||||
} else if (!until && localStorage.getItem(localStorageKey())) {
|
||||
} else if (localStorage.getItem(localStorageKey())) {
|
||||
localStorage.removeItem(localStorageKey());
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
4
extensions/tags/js/dist-typings/@types/shims.d.ts
generated
vendored
4
extensions/tags/js/dist-typings/@types/shims.d.ts
generated
vendored
@@ -1,5 +1,5 @@
|
||||
import type Tag from "../common/models/Tag";
|
||||
import type TagListState from "../forum/states/TagListState";
|
||||
import type Tag from '../common/models/Tag';
|
||||
import type TagListState from '../forum/states/TagListState';
|
||||
|
||||
declare module 'flarum/forum/routes' {
|
||||
export interface ForumRoutes {
|
||||
|
2
extensions/tags/js/dist-typings/common/utils/sortTags.d.ts
generated
vendored
2
extensions/tags/js/dist-typings/common/utils/sortTags.d.ts
generated
vendored
@@ -1,2 +1,2 @@
|
||||
import Tag from "../models/Tag";
|
||||
import Tag from '../models/Tag';
|
||||
export default function sortTags(tags: Tag[]): Tag[];
|
||||
|
2
extensions/tags/js/dist-typings/forum/states/TagListState.d.ts
generated
vendored
2
extensions/tags/js/dist-typings/forum/states/TagListState.d.ts
generated
vendored
@@ -1,4 +1,4 @@
|
||||
import type Tag from "../../common/models/Tag";
|
||||
import type Tag from '../../common/models/Tag';
|
||||
export default class TagListState {
|
||||
loadedIncludes: Set<unknown>;
|
||||
load(includes?: string[]): Promise<Tag[]>;
|
||||
|
2
extensions/tags/js/dist/admin.js
generated
vendored
2
extensions/tags/js/dist/admin.js
generated
vendored
File diff suppressed because one or more lines are too long
2
extensions/tags/js/dist/admin.js.map
generated
vendored
2
extensions/tags/js/dist/admin.js.map
generated
vendored
File diff suppressed because one or more lines are too long
2
extensions/tags/js/dist/forum.js
generated
vendored
2
extensions/tags/js/dist/forum.js
generated
vendored
File diff suppressed because one or more lines are too long
2
extensions/tags/js/dist/forum.js.map
generated
vendored
2
extensions/tags/js/dist/forum.js.map
generated
vendored
File diff suppressed because one or more lines are too long
@@ -2,6 +2,7 @@
|
||||
"private": true,
|
||||
"name": "@flarum/tags",
|
||||
"version": "0.0.0",
|
||||
"prettier": "@flarum/prettier-config",
|
||||
"dependencies": {
|
||||
"sortablejs": "^1.14.0"
|
||||
},
|
||||
@@ -13,14 +14,17 @@
|
||||
"build-typings": "yarn run clean-typings && ([ -e src/@types ] && cp -r src/@types dist-typings/@types || true) && tsc && yarn run post-build-typings",
|
||||
"post-build-typings": "find dist-typings -type f -name '*.d.ts' -print0 | xargs -0 sed -i 's,../src/@types,@types,g'",
|
||||
"check-typings": "tsc --noEmit --emitDeclarationOnly false",
|
||||
"check-typings-coverage": "typescript-coverage-report"
|
||||
"check-typings-coverage": "typescript-coverage-report",
|
||||
"format": "prettier --write src",
|
||||
"format-check": "prettier --check src"
|
||||
},
|
||||
"devDependencies": {
|
||||
"flarum-webpack-config": "^2.0.0",
|
||||
"webpack": "^5.65.0",
|
||||
"webpack-cli": "^4.9.1",
|
||||
"flarum-tsconfig": "^1.0.2",
|
||||
"flarum-webpack-config": "^2.0.0",
|
||||
"prettier": "^2.7.1",
|
||||
"typescript": "^4.5.4",
|
||||
"typescript-coverage-report": "^0.6.1"
|
||||
"typescript-coverage-report": "^0.6.1",
|
||||
"webpack": "^5.65.0",
|
||||
"webpack-cli": "^4.9.1"
|
||||
}
|
||||
}
|
||||
|
4
extensions/tags/js/src/@types/shims.d.ts
vendored
4
extensions/tags/js/src/@types/shims.d.ts
vendored
@@ -1,5 +1,5 @@
|
||||
import type Tag from "../common/models/Tag";
|
||||
import type TagListState from "../forum/states/TagListState";
|
||||
import type Tag from '../common/models/Tag';
|
||||
import type TagListState from '../forum/states/TagListState';
|
||||
|
||||
declare module 'flarum/forum/routes' {
|
||||
export interface ForumRoutes {
|
||||
|
@@ -2,26 +2,30 @@ import { extend } from 'flarum/common/extend';
|
||||
import PermissionGrid from 'flarum/admin/components/PermissionGrid';
|
||||
import SettingDropdown from 'flarum/admin/components/SettingDropdown';
|
||||
|
||||
export default function() {
|
||||
extend(PermissionGrid.prototype, 'startItems', items => {
|
||||
items.add('allowTagChange', {
|
||||
icon: 'fas fa-tag',
|
||||
label: app.translator.trans('flarum-tags.admin.permissions.allow_edit_tags_label'),
|
||||
setting: () => {
|
||||
const minutes = parseInt(app.data.settings.allow_tag_change, 10);
|
||||
export default function () {
|
||||
extend(PermissionGrid.prototype, 'startItems', (items) => {
|
||||
items.add(
|
||||
'allowTagChange',
|
||||
{
|
||||
icon: 'fas fa-tag',
|
||||
label: app.translator.trans('flarum-tags.admin.permissions.allow_edit_tags_label'),
|
||||
setting: () => {
|
||||
const minutes = parseInt(app.data.settings.allow_tag_change, 10);
|
||||
|
||||
return SettingDropdown.component({
|
||||
defaultLabel: minutes
|
||||
? app.translator.trans('core.admin.permissions_controls.allow_some_minutes_button', {count: minutes})
|
||||
: app.translator.trans('core.admin.permissions_controls.allow_indefinitely_button'),
|
||||
key: 'allow_tag_change',
|
||||
options: [
|
||||
{value: '-1', label: app.translator.trans('core.admin.permissions_controls.allow_indefinitely_button')},
|
||||
{value: '10', label: app.translator.trans('core.admin.permissions_controls.allow_ten_minutes_button')},
|
||||
{value: 'reply', label: app.translator.trans('core.admin.permissions_controls.allow_until_reply_button')}
|
||||
]
|
||||
});
|
||||
}
|
||||
}, 90);
|
||||
return SettingDropdown.component({
|
||||
defaultLabel: minutes
|
||||
? app.translator.trans('core.admin.permissions_controls.allow_some_minutes_button', { count: minutes })
|
||||
: app.translator.trans('core.admin.permissions_controls.allow_indefinitely_button'),
|
||||
key: 'allow_tag_change',
|
||||
options: [
|
||||
{ value: '-1', label: app.translator.trans('core.admin.permissions_controls.allow_indefinitely_button') },
|
||||
{ value: '10', label: app.translator.trans('core.admin.permissions_controls.allow_ten_minutes_button') },
|
||||
{ value: 'reply', label: app.translator.trans('core.admin.permissions_controls.allow_until_reply_button') },
|
||||
],
|
||||
});
|
||||
},
|
||||
},
|
||||
90
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@@ -1,14 +1,22 @@
|
||||
export default function () {
|
||||
app.extensionData
|
||||
.for('flarum-tags')
|
||||
.registerPermission({
|
||||
icon: 'fas fa-tag',
|
||||
label: app.translator.trans('flarum-tags.admin.permissions.tag_discussions_label'),
|
||||
permission: 'discussion.tag',
|
||||
}, 'moderate', 95)
|
||||
.registerPermission({
|
||||
icon: 'fas fa-tags',
|
||||
label: app.translator.trans('flarum-tags.admin.permissions.bypass_tag_counts_label'),
|
||||
permission: 'bypassTagCounts',
|
||||
}, 'start', 89);
|
||||
.registerPermission(
|
||||
{
|
||||
icon: 'fas fa-tag',
|
||||
label: app.translator.trans('flarum-tags.admin.permissions.tag_discussions_label'),
|
||||
permission: 'discussion.tag',
|
||||
},
|
||||
'moderate',
|
||||
95
|
||||
)
|
||||
.registerPermission(
|
||||
{
|
||||
icon: 'fas fa-tags',
|
||||
label: app.translator.trans('flarum-tags.admin.permissions.bypass_tag_counts_label'),
|
||||
permission: 'bypassTagCounts',
|
||||
},
|
||||
'start',
|
||||
89
|
||||
);
|
||||
}
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import { extend } from 'flarum/common/extend';
|
||||
import BasicsPage from 'flarum/admin/components/BasicsPage';
|
||||
|
||||
export default function() {
|
||||
extend(BasicsPage.prototype, 'homePageItems', items => {
|
||||
export default function () {
|
||||
extend(BasicsPage.prototype, 'homePageItems', (items) => {
|
||||
items.add('tags', {
|
||||
path: '/tags',
|
||||
label: app.translator.trans('flarum-tags.admin.basics.tags_label')
|
||||
label: app.translator.trans('flarum-tags.admin.basics.tags_label'),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@@ -11,10 +11,10 @@ import tagIcon from '../common/helpers/tagIcon';
|
||||
import sortTags from '../common/utils/sortTags';
|
||||
import Tag from '../common/models/Tag';
|
||||
|
||||
export default function() {
|
||||
export default function () {
|
||||
extend(PermissionGrid.prototype, 'oninit', function () {
|
||||
this.loading = true;
|
||||
})
|
||||
});
|
||||
|
||||
extend(PermissionGrid.prototype, 'oncreate', function () {
|
||||
app.store.find<Tag[]>('tags', {}).then(() => {
|
||||
@@ -30,7 +30,7 @@ export default function() {
|
||||
}
|
||||
|
||||
return original(vnode);
|
||||
})
|
||||
});
|
||||
|
||||
override(app, 'getRequiredPermissions', (original, permission) => {
|
||||
const tagPrefix = permission.match(/^tag\d+\./);
|
||||
@@ -40,45 +40,60 @@ export default function() {
|
||||
|
||||
const required = original(globalPermission);
|
||||
|
||||
return required.map(required => tagPrefix[0] + required);
|
||||
return required.map((required) => tagPrefix[0] + required);
|
||||
}
|
||||
|
||||
return original(permission);
|
||||
});
|
||||
|
||||
extend(PermissionGrid.prototype, 'scopeItems', items => {
|
||||
extend(PermissionGrid.prototype, 'scopeItems', (items) => {
|
||||
sortTags(app.store.all('tags'))
|
||||
.filter(tag => tag.isRestricted())
|
||||
.forEach(tag => items.add('tag' + tag.id(), {
|
||||
label: tagLabel(tag),
|
||||
onremove: () => tag.save({isRestricted: false}),
|
||||
render: item => {
|
||||
if ('setting' in item) return '';
|
||||
.filter((tag) => tag.isRestricted())
|
||||
.forEach((tag) =>
|
||||
items.add('tag' + tag.id(), {
|
||||
label: tagLabel(tag),
|
||||
onremove: () => tag.save({ isRestricted: false }),
|
||||
render: (item) => {
|
||||
if ('setting' in item) return '';
|
||||
|
||||
if (item.permission === 'viewForum'
|
||||
|| item.permission === 'startDiscussion'
|
||||
|| (item.permission && item.permission.indexOf('discussion.') === 0 && item.tagScoped !== false)
|
||||
|| item.tagScoped) {
|
||||
return PermissionDropdown.component({
|
||||
permission: 'tag' + tag.id() + '.' + item.permission,
|
||||
allowGuest: item.allowGuest
|
||||
});
|
||||
}
|
||||
if (
|
||||
item.permission === 'viewForum' ||
|
||||
item.permission === 'startDiscussion' ||
|
||||
(item.permission && item.permission.indexOf('discussion.') === 0 && item.tagScoped !== false) ||
|
||||
item.tagScoped
|
||||
) {
|
||||
return PermissionDropdown.component({
|
||||
permission: 'tag' + tag.id() + '.' + item.permission,
|
||||
allowGuest: item.allowGuest,
|
||||
});
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}));
|
||||
return '';
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
extend(PermissionGrid.prototype, 'scopeControlItems', items => {
|
||||
const tags = sortTags(app.store.all<Tag>('tags').filter(tag => !tag.isRestricted()));
|
||||
extend(PermissionGrid.prototype, 'scopeControlItems', (items) => {
|
||||
const tags = sortTags(app.store.all<Tag>('tags').filter((tag) => !tag.isRestricted()));
|
||||
|
||||
if (tags.length) {
|
||||
items.add('tag', <Dropdown className='Dropdown--restrictByTag' buttonClassName='Button Button--text' label={app.translator.trans('flarum-tags.admin.permissions.restrict_by_tag_heading')} icon='fas fa-plus' caretIcon={null}>
|
||||
{tags.map(tag => <Button icon={true} onclick={() => tag.save({ isRestricted: true })}>
|
||||
{[tagIcon(tag, { className: 'Button-icon' }), ' ', tag.name()]}
|
||||
</Button>)}
|
||||
</Dropdown>);
|
||||
items.add(
|
||||
'tag',
|
||||
<Dropdown
|
||||
className="Dropdown--restrictByTag"
|
||||
buttonClassName="Button Button--text"
|
||||
label={app.translator.trans('flarum-tags.admin.permissions.restrict_by_tag_heading')}
|
||||
icon="fas fa-plus"
|
||||
caretIcon={null}
|
||||
>
|
||||
{tags.map((tag) => (
|
||||
<Button icon={true} onclick={() => tag.save({ isRestricted: true })}>
|
||||
{[tagIcon(tag, { className: 'Button-icon' }), ' ', tag.name()]}
|
||||
</Button>
|
||||
))}
|
||||
</Dropdown>
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -59,9 +59,7 @@ export default class EditTagModal extends Modal<EditTagModalAttrs> {
|
||||
content() {
|
||||
return (
|
||||
<div className="Modal-body">
|
||||
<div className="Form">
|
||||
{this.fields().toArray()}
|
||||
</div>
|
||||
<div className="Form">{this.fields().toArray()}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -69,59 +67,97 @@ export default class EditTagModal extends Modal<EditTagModalAttrs> {
|
||||
fields() {
|
||||
const items = new ItemList();
|
||||
|
||||
items.add('name', <div className="Form-group">
|
||||
<label>{app.translator.trans('flarum-tags.admin.edit_tag.name_label')}</label>
|
||||
<input className="FormControl" placeholder={app.translator.trans('flarum-tags.admin.edit_tag.name_placeholder')} value={this.name()} oninput={(e: InputEvent) => {
|
||||
const target = e.target as HTMLInputElement;
|
||||
this.name(target.value);
|
||||
this.slug(slug(target.value));
|
||||
}} />
|
||||
</div>, 50);
|
||||
items.add(
|
||||
'name',
|
||||
<div className="Form-group">
|
||||
<label>{app.translator.trans('flarum-tags.admin.edit_tag.name_label')}</label>
|
||||
<input
|
||||
className="FormControl"
|
||||
placeholder={app.translator.trans('flarum-tags.admin.edit_tag.name_placeholder')}
|
||||
value={this.name()}
|
||||
oninput={(e: InputEvent) => {
|
||||
const target = e.target as HTMLInputElement;
|
||||
this.name(target.value);
|
||||
this.slug(slug(target.value));
|
||||
}}
|
||||
/>
|
||||
</div>,
|
||||
50
|
||||
);
|
||||
|
||||
items.add('slug', <div className="Form-group">
|
||||
<label>{app.translator.trans('flarum-tags.admin.edit_tag.slug_label')}</label>
|
||||
<input className="FormControl" bidi={this.slug} />
|
||||
</div>, 40);
|
||||
items.add(
|
||||
'slug',
|
||||
<div className="Form-group">
|
||||
<label>{app.translator.trans('flarum-tags.admin.edit_tag.slug_label')}</label>
|
||||
<input className="FormControl" bidi={this.slug} />
|
||||
</div>,
|
||||
40
|
||||
);
|
||||
|
||||
items.add('description', <div className="Form-group">
|
||||
<label>{app.translator.trans('flarum-tags.admin.edit_tag.description_label')}</label>
|
||||
<textarea className="FormControl" bidi={this.description} />
|
||||
</div>, 30);
|
||||
items.add(
|
||||
'description',
|
||||
<div className="Form-group">
|
||||
<label>{app.translator.trans('flarum-tags.admin.edit_tag.description_label')}</label>
|
||||
<textarea className="FormControl" bidi={this.description} />
|
||||
</div>,
|
||||
30
|
||||
);
|
||||
|
||||
items.add('color', <div className="Form-group">
|
||||
<label>{app.translator.trans('flarum-tags.admin.edit_tag.color_label')}</label>
|
||||
<ColorPreviewInput className="FormControl" placeholder="#aaaaaa" bidi={this.color} />
|
||||
</div>, 20);
|
||||
items.add(
|
||||
'color',
|
||||
<div className="Form-group">
|
||||
<label>{app.translator.trans('flarum-tags.admin.edit_tag.color_label')}</label>
|
||||
<ColorPreviewInput className="FormControl" placeholder="#aaaaaa" bidi={this.color} />
|
||||
</div>,
|
||||
20
|
||||
);
|
||||
|
||||
items.add('icon', <div className="Form-group">
|
||||
<label>{app.translator.trans('flarum-tags.admin.edit_tag.icon_label')}</label>
|
||||
<div className="helpText">
|
||||
{app.translator.trans('flarum-tags.admin.edit_tag.icon_text', { a: <a href="https://fontawesome.com/icons?m=free" tabindex="-1" /> })}
|
||||
</div>
|
||||
<input className="FormControl" placeholder="fas fa-bolt" bidi={this.icon} />
|
||||
</div>, 10);
|
||||
items.add(
|
||||
'icon',
|
||||
<div className="Form-group">
|
||||
<label>{app.translator.trans('flarum-tags.admin.edit_tag.icon_label')}</label>
|
||||
<div className="helpText">
|
||||
{app.translator.trans('flarum-tags.admin.edit_tag.icon_text', { a: <a href="https://fontawesome.com/icons?m=free" tabindex="-1" /> })}
|
||||
</div>
|
||||
<input className="FormControl" placeholder="fas fa-bolt" bidi={this.icon} />
|
||||
</div>,
|
||||
10
|
||||
);
|
||||
|
||||
items.add('hidden', <div className="Form-group">
|
||||
<div>
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" bidi={this.isHidden} />
|
||||
{app.translator.trans('flarum-tags.admin.edit_tag.hide_label')}
|
||||
</label>
|
||||
</div>
|
||||
</div>, 10);
|
||||
items.add(
|
||||
'hidden',
|
||||
<div className="Form-group">
|
||||
<div>
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" bidi={this.isHidden} />
|
||||
{app.translator.trans('flarum-tags.admin.edit_tag.hide_label')}
|
||||
</label>
|
||||
</div>
|
||||
</div>,
|
||||
10
|
||||
);
|
||||
|
||||
items.add('submit', <div className="Form-group">
|
||||
{Button.component({
|
||||
type: 'submit',
|
||||
className: 'Button Button--primary EditTagModal-save',
|
||||
loading: this.loading,
|
||||
}, app.translator.trans('flarum-tags.admin.edit_tag.submit_button'))}
|
||||
{this.tag.exists ? (
|
||||
<button type="button" className="Button EditTagModal-delete" onclick={this.delete.bind(this)}>
|
||||
{app.translator.trans('flarum-tags.admin.edit_tag.delete_tag_button')}
|
||||
</button>
|
||||
) : ''}
|
||||
</div>, -10);
|
||||
items.add(
|
||||
'submit',
|
||||
<div className="Form-group">
|
||||
{Button.component(
|
||||
{
|
||||
type: 'submit',
|
||||
className: 'Button Button--primary EditTagModal-save',
|
||||
loading: this.loading,
|
||||
},
|
||||
app.translator.trans('flarum-tags.admin.edit_tag.submit_button')
|
||||
)}
|
||||
{this.tag.exists ? (
|
||||
<button type="button" className="Button EditTagModal-delete" onclick={this.delete.bind(this)}>
|
||||
{app.translator.trans('flarum-tags.admin.edit_tag.delete_tag_button')}
|
||||
</button>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</div>,
|
||||
-10
|
||||
);
|
||||
|
||||
return items;
|
||||
}
|
||||
@@ -147,20 +183,22 @@ export default class EditTagModal extends Modal<EditTagModalAttrs> {
|
||||
// This is done for better error visibility on smaller screen heights.
|
||||
this.tag.save(this.submitData()).then(
|
||||
() => this.hide(),
|
||||
() => this.loading = false
|
||||
() => (this.loading = false)
|
||||
);
|
||||
}
|
||||
|
||||
delete() {
|
||||
if (confirm(extractText(app.translator.trans('flarum-tags.admin.edit_tag.delete_tag_confirmation')))) {
|
||||
const children = app.store.all<Tag>('tags').filter(tag => tag.parent() === this.tag);
|
||||
const children = app.store.all<Tag>('tags').filter((tag) => tag.parent() === this.tag);
|
||||
|
||||
this.tag.delete().then(() => {
|
||||
children.forEach(tag => tag.pushData({
|
||||
attributes: { isChild: false },
|
||||
// @deprecated. Temporary hack for type safety, remove before v1.3.
|
||||
relationships: { parent: null as any as [] }
|
||||
}));
|
||||
children.forEach((tag) =>
|
||||
tag.pushData({
|
||||
attributes: { isChild: false },
|
||||
// @deprecated. Temporary hack for type safety, remove before v1.3.
|
||||
relationships: { parent: null as any as [] },
|
||||
})
|
||||
);
|
||||
m.redraw();
|
||||
});
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import sortable from 'sortablejs';
|
||||
|
||||
import app from 'flarum/admin/app';
|
||||
import ExtensionPage from 'flarum/admin/components/ExtensionPage';
|
||||
import Button from 'flarum/common/components/Button';
|
||||
import LoadingIndicator from 'flarum/common/components/LoadingIndicator';
|
||||
@@ -18,16 +19,18 @@ function tagItem(tag) {
|
||||
{Button.component({
|
||||
className: 'Button Button--link',
|
||||
icon: 'fas fa-pencil-alt',
|
||||
onclick: () => app.modal.show(EditTagModal, { model: tag })
|
||||
onclick: () => app.modal.show(EditTagModal, { model: tag }),
|
||||
})}
|
||||
</div>
|
||||
{!tag.isChild() && tag.position() !== null ? (
|
||||
<ol className="TagListItem-children TagList">
|
||||
{sortTags(app.store.all('tags'))
|
||||
.filter(child => child.parent() === tag)
|
||||
.filter((child) => child.parent() === tag)
|
||||
.map(tagItem)}
|
||||
</ol>
|
||||
) : ''}
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
}
|
||||
@@ -62,81 +65,78 @@ export default class TagsPage extends ExtensionPage {
|
||||
const minSecondaryTags = this.setting('flarum-tags.min_secondary_tags', 0);
|
||||
const maxSecondaryTags = this.setting('flarum-tags.max_secondary_tags', 0);
|
||||
|
||||
const tags = sortTags(app.store.all('tags').filter(tag => !tag.parent()));
|
||||
|
||||
const tags = sortTags(app.store.all('tags').filter((tag) => !tag.parent()));
|
||||
|
||||
return (
|
||||
<div className="TagsContent">
|
||||
<div className="TagsContent-list">
|
||||
<div className="container" key={this.forcedRefreshKey} oncreate={this.onListOnCreate.bind(this)}><div className="SettingsGroups">
|
||||
<div className="TagGroup">
|
||||
<label>{app.translator.trans('flarum-tags.admin.tags.primary_heading')}</label>
|
||||
<ol className="TagList TagList--primary">
|
||||
{tags
|
||||
.filter(tag => tag.position() !== null && !tag.isChild())
|
||||
.map(tagItem)}
|
||||
</ol>
|
||||
{Button.component(
|
||||
{
|
||||
className: 'Button TagList-button',
|
||||
icon: 'fas fa-plus',
|
||||
onclick: () => app.modal.show(EditTagModal, { primary: true }),
|
||||
},
|
||||
app.translator.trans('flarum-tags.admin.tags.create_primary_tag_button')
|
||||
)}
|
||||
</div>
|
||||
<div className="container" key={this.forcedRefreshKey} oncreate={this.onListOnCreate.bind(this)}>
|
||||
<div className="SettingsGroups">
|
||||
<div className="TagGroup">
|
||||
<label>{app.translator.trans('flarum-tags.admin.tags.primary_heading')}</label>
|
||||
<ol className="TagList TagList--primary">{tags.filter((tag) => tag.position() !== null && !tag.isChild()).map(tagItem)}</ol>
|
||||
{Button.component(
|
||||
{
|
||||
className: 'Button TagList-button',
|
||||
icon: 'fas fa-plus',
|
||||
onclick: () => app.modal.show(EditTagModal, { primary: true }),
|
||||
},
|
||||
app.translator.trans('flarum-tags.admin.tags.create_primary_tag_button')
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="TagGroup TagGroup--secondary">
|
||||
<label>{app.translator.trans('flarum-tags.admin.tags.secondary_heading')}</label>
|
||||
<ul className="TagList">
|
||||
{tags
|
||||
.filter(tag => tag.position() === null)
|
||||
.sort((a, b) => a.name().localeCompare(b.name()))
|
||||
.map(tagItem)}
|
||||
</ul>
|
||||
{Button.component(
|
||||
{
|
||||
className: 'Button TagList-button',
|
||||
icon: 'fas fa-plus',
|
||||
onclick: () => app.modal.show(EditTagModal, { primary: false }),
|
||||
},
|
||||
app.translator.trans('flarum-tags.admin.tags.create_secondary_tag_button')
|
||||
)}
|
||||
</div>
|
||||
<div className="Form">
|
||||
<label>{app.translator.trans('flarum-tags.admin.tags.settings_heading')}</label>
|
||||
<div className="Form-group">
|
||||
<label>{app.translator.trans('flarum-tags.admin.tag_settings.required_primary_heading')}</label>
|
||||
<div className="helpText">{app.translator.trans('flarum-tags.admin.tag_settings.required_primary_text')}</div>
|
||||
<div className="TagSettings-rangeInput">
|
||||
<input
|
||||
className="FormControl"
|
||||
type="number"
|
||||
min="0"
|
||||
value={minPrimaryTags()}
|
||||
oninput={withAttr('value', this.setMinTags.bind(this, minPrimaryTags, maxPrimaryTags))}
|
||||
/>
|
||||
{app.translator.trans('flarum-tags.admin.tag_settings.range_separator_text')}
|
||||
<input className="FormControl" type="number" min={minPrimaryTags()} bidi={maxPrimaryTags} />
|
||||
</div>
|
||||
<div className="TagGroup TagGroup--secondary">
|
||||
<label>{app.translator.trans('flarum-tags.admin.tags.secondary_heading')}</label>
|
||||
<ul className="TagList">
|
||||
{tags
|
||||
.filter((tag) => tag.position() === null)
|
||||
.sort((a, b) => a.name().localeCompare(b.name()))
|
||||
.map(tagItem)}
|
||||
</ul>
|
||||
{Button.component(
|
||||
{
|
||||
className: 'Button TagList-button',
|
||||
icon: 'fas fa-plus',
|
||||
onclick: () => app.modal.show(EditTagModal, { primary: false }),
|
||||
},
|
||||
app.translator.trans('flarum-tags.admin.tags.create_secondary_tag_button')
|
||||
)}
|
||||
</div>
|
||||
<div className="Form-group">
|
||||
<label>{app.translator.trans('flarum-tags.admin.tag_settings.required_secondary_heading')}</label>
|
||||
<div className="helpText">{app.translator.trans('flarum-tags.admin.tag_settings.required_secondary_text')}</div>
|
||||
<div className="TagSettings-rangeInput">
|
||||
<input
|
||||
className="FormControl"
|
||||
type="number"
|
||||
min="0"
|
||||
value={minSecondaryTags()}
|
||||
oninput={withAttr('value', this.setMinTags.bind(this, minSecondaryTags, maxSecondaryTags))}
|
||||
/>
|
||||
{app.translator.trans('flarum-tags.admin.tag_settings.range_separator_text')}
|
||||
<input className="FormControl" type="number" min={minSecondaryTags()} bidi={maxSecondaryTags} />
|
||||
<div className="Form">
|
||||
<label>{app.translator.trans('flarum-tags.admin.tags.settings_heading')}</label>
|
||||
<div className="Form-group">
|
||||
<label>{app.translator.trans('flarum-tags.admin.tag_settings.required_primary_heading')}</label>
|
||||
<div className="helpText">{app.translator.trans('flarum-tags.admin.tag_settings.required_primary_text')}</div>
|
||||
<div className="TagSettings-rangeInput">
|
||||
<input
|
||||
className="FormControl"
|
||||
type="number"
|
||||
min="0"
|
||||
value={minPrimaryTags()}
|
||||
oninput={withAttr('value', this.setMinTags.bind(this, minPrimaryTags, maxPrimaryTags))}
|
||||
/>
|
||||
{app.translator.trans('flarum-tags.admin.tag_settings.range_separator_text')}
|
||||
<input className="FormControl" type="number" min={minPrimaryTags()} bidi={maxPrimaryTags} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="Form-group">
|
||||
<label>{app.translator.trans('flarum-tags.admin.tag_settings.required_secondary_heading')}</label>
|
||||
<div className="helpText">{app.translator.trans('flarum-tags.admin.tag_settings.required_secondary_text')}</div>
|
||||
<div className="TagSettings-rangeInput">
|
||||
<input
|
||||
className="FormControl"
|
||||
type="number"
|
||||
min="0"
|
||||
value={minSecondaryTags()}
|
||||
oninput={withAttr('value', this.setMinTags.bind(this, minSecondaryTags, maxSecondaryTags))}
|
||||
/>
|
||||
{app.translator.trans('flarum-tags.admin.tag_settings.range_separator_text')}
|
||||
<input className="FormControl" type="number" min={minSecondaryTags()} bidi={maxSecondaryTags} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="Form-group">{this.submitButton()}</div>
|
||||
</div>
|
||||
<div className="Form-group">{this.submitButton()}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="TagsContent-footer">
|
||||
<p>{app.translator.trans('flarum-tags.admin.tags.about_tags_text')}</p>
|
||||
</div>
|
||||
@@ -147,19 +147,21 @@ export default class TagsPage extends ExtensionPage {
|
||||
}
|
||||
|
||||
onListOnCreate(vnode) {
|
||||
this.$('.TagList').get().map(e => {
|
||||
sortable.create(e, {
|
||||
group: 'tags',
|
||||
delay: 50,
|
||||
delayOnTouchOnly: true,
|
||||
touchStartThreshold: 5,
|
||||
animation: 150,
|
||||
swapThreshold: 0.65,
|
||||
dragClass: 'sortable-dragging',
|
||||
ghostClass: 'sortable-placeholder',
|
||||
onSort: (e) => this.onSortUpdate(e)
|
||||
})
|
||||
});
|
||||
this.$('.TagList')
|
||||
.get()
|
||||
.map((e) => {
|
||||
sortable.create(e, {
|
||||
group: 'tags',
|
||||
delay: 50,
|
||||
delayOnTouchOnly: true,
|
||||
touchStartThreshold: 5,
|
||||
animation: 150,
|
||||
swapThreshold: 0.65,
|
||||
dragClass: 'sortable-dragging',
|
||||
ghostClass: 'sortable-placeholder',
|
||||
onSort: (e) => this.onSortUpdate(e),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
setMinTags(minTags, maxTags, value) {
|
||||
@@ -175,9 +177,9 @@ export default class TagsPage extends ExtensionPage {
|
||||
app.store.getById('tags', e.item.getAttribute('data-id')).pushData({
|
||||
attributes: {
|
||||
position: null,
|
||||
isChild: false
|
||||
isChild: false,
|
||||
},
|
||||
relationships: { parent: null }
|
||||
relationships: { parent: null },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -187,12 +189,15 @@ export default class TagsPage extends ExtensionPage {
|
||||
.map(function () {
|
||||
return {
|
||||
id: $(this).data('id'),
|
||||
children: $(this).find('li')
|
||||
children: $(this)
|
||||
.find('li')
|
||||
.map(function () {
|
||||
return $(this).data('id');
|
||||
}).get()
|
||||
})
|
||||
.get(),
|
||||
};
|
||||
}).get();
|
||||
})
|
||||
.get();
|
||||
|
||||
// Now that we have an accurate representation of the order which the
|
||||
// primary tags are in, we will update the tag attributes in our local
|
||||
@@ -202,18 +207,18 @@ export default class TagsPage extends ExtensionPage {
|
||||
parent.pushData({
|
||||
attributes: {
|
||||
position: i,
|
||||
isChild: false
|
||||
isChild: false,
|
||||
},
|
||||
relationships: { parent: null }
|
||||
relationships: { parent: null },
|
||||
});
|
||||
|
||||
tag.children.forEach((child, j) => {
|
||||
app.store.getById('tags', child).pushData({
|
||||
attributes: {
|
||||
position: j,
|
||||
isChild: true
|
||||
isChild: true,
|
||||
},
|
||||
relationships: { parent }
|
||||
relationships: { parent },
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -221,7 +226,7 @@ export default class TagsPage extends ExtensionPage {
|
||||
app.request({
|
||||
url: app.forum.attribute('apiUrl') + '/tags/order',
|
||||
method: 'POST',
|
||||
body: { order }
|
||||
body: { order },
|
||||
});
|
||||
|
||||
this.forcedRefreshKey++;
|
||||
|
@@ -6,7 +6,7 @@ import addTagsHomePageOption from './addTagsHomePageOption';
|
||||
import addTagChangePermission from './addTagChangePermission';
|
||||
import TagsPage from './components/TagsPage';
|
||||
|
||||
app.initializers.add('flarum-tags', app => {
|
||||
app.initializers.add('flarum-tags', (app) => {
|
||||
app.store.models.tags = Tag;
|
||||
|
||||
app.extensionData.for('flarum-tags').registerPage(TagsPage);
|
||||
@@ -17,7 +17,6 @@ app.initializers.add('flarum-tags', app => {
|
||||
addTagChangePermission();
|
||||
});
|
||||
|
||||
|
||||
// Expose compat API
|
||||
import tagsCompat from './compat';
|
||||
import { compat } from '@flarum/core/admin';
|
||||
|
@@ -9,5 +9,5 @@ export default {
|
||||
'tags/models/Tag': Tag,
|
||||
'tags/helpers/tagsLabel': tagsLabel,
|
||||
'tags/helpers/tagIcon': tagIcon,
|
||||
'tags/helpers/tagLabel': tagLabel
|
||||
'tags/helpers/tagLabel': tagLabel,
|
||||
};
|
||||
|
@@ -4,11 +4,7 @@ export default function tagIcon(tag, attrs = {}, settings = {}) {
|
||||
const hasIcon = tag && tag.icon();
|
||||
const { useColor = true } = settings;
|
||||
|
||||
attrs.className = classList([
|
||||
attrs.className,
|
||||
'icon',
|
||||
hasIcon ? tag.icon() : 'TagIcon'
|
||||
]);
|
||||
attrs.className = classList([attrs.className, 'icon', hasIcon ? tag.icon() : 'TagIcon']);
|
||||
|
||||
if (tag && useColor) {
|
||||
attrs.style = attrs.style || {};
|
||||
@@ -21,5 +17,5 @@ export default function tagIcon(tag, attrs = {}, settings = {}) {
|
||||
attrs.className += ' untagged';
|
||||
}
|
||||
|
||||
return hasIcon ? <i {...attrs}/> : <span {...attrs}/>;
|
||||
return hasIcon ? <i {...attrs} /> : <span {...attrs} />;
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ export default function tagLabel(tag, attrs = {}) {
|
||||
|
||||
if (link) {
|
||||
attrs.title = tag.description() || '';
|
||||
attrs.href = app.route('tag', {tags: tag.slug()});
|
||||
attrs.href = app.route('tag', { tags: tag.slug() });
|
||||
}
|
||||
|
||||
if (tag.isChild()) {
|
||||
@@ -28,11 +28,11 @@ export default function tagLabel(tag, attrs = {}) {
|
||||
attrs.className += ' untagged';
|
||||
}
|
||||
|
||||
return (
|
||||
m((link ? Link : 'span'), attrs,
|
||||
<span className="TagLabel-text">
|
||||
{tag && tag.icon() && tagIcon(tag, {}, {useColor: false})} {tagText}
|
||||
</span>
|
||||
)
|
||||
return m(
|
||||
link ? Link : 'span',
|
||||
attrs,
|
||||
<span className="TagLabel-text">
|
||||
{tag && tag.icon() && tagIcon(tag, {}, { useColor: false })} {tagText}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
@@ -9,9 +9,9 @@ export default function tagsLabel(tags, attrs = {}) {
|
||||
attrs.className = 'TagsLabel ' + (attrs.className || '');
|
||||
|
||||
if (tags) {
|
||||
sortTags(tags).forEach(tag => {
|
||||
sortTags(tags).forEach((tag) => {
|
||||
if (tag || tags.length === 1) {
|
||||
children.push(tagLabel(tag, {link}));
|
||||
children.push(tagLabel(tag, { link }));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import Tag from "../models/Tag";
|
||||
import Tag from '../models/Tag';
|
||||
|
||||
export default function sortTags(tags: Tag[]) {
|
||||
return tags.slice(0).sort((a, b) => {
|
||||
@@ -7,8 +7,7 @@ export default function sortTags(tags: Tag[]) {
|
||||
|
||||
// If they're both secondary tags, sort them by their discussions count,
|
||||
// descending.
|
||||
if (aPos === null && bPos === null)
|
||||
return b.discussionCount() - a.discussionCount();
|
||||
if (aPos === null && bPos === null) return b.discussionCount() - a.discussionCount();
|
||||
|
||||
// If just one is a secondary tag, then the primary tag should
|
||||
// come first.
|
||||
@@ -23,20 +22,14 @@ export default function sortTags(tags: Tag[]) {
|
||||
// If they both have the same parent, then their positions are local,
|
||||
// so we can compare them directly.
|
||||
if (aParent === bParent) return aPos - bPos;
|
||||
|
||||
// If they are both child tags, then we will compare the positions of their
|
||||
// parents.
|
||||
else if (aParent && bParent)
|
||||
return aParent.position()! - bParent.position()!;
|
||||
|
||||
else if (aParent && bParent) return aParent.position()! - bParent.position()!;
|
||||
// If we are comparing a child tag with its parent, then we let the parent
|
||||
// come first. If we are comparing an unrelated parent/child, then we
|
||||
// compare both of the parents.
|
||||
else if (aParent)
|
||||
return aParent === b ? 1 : aParent.position()! - bPos;
|
||||
|
||||
else if (bParent)
|
||||
return bParent === a ? -1 : aPos - bParent.position()!;
|
||||
else if (aParent) return aParent === b ? 1 : aParent.position()! - bPos;
|
||||
else if (bParent) return bParent === a ? -1 : aPos - bParent.position()!;
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
@@ -15,15 +15,14 @@ export default function () {
|
||||
if (tag) {
|
||||
const parent = tag.parent();
|
||||
const tags = parent ? [parent, tag] : [tag];
|
||||
promise.then(composer => composer.fields.tags = tags);
|
||||
promise.then((composer) => (composer.fields.tags = tags));
|
||||
} else {
|
||||
app.composer.fields.tags = [];
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
extend(DiscussionComposer.prototype, 'oninit', function () {
|
||||
app.tagList.load(['parent']).then(() => m.redraw())
|
||||
app.tagList.load(['parent']).then(() => m.redraw());
|
||||
});
|
||||
|
||||
// Add tag-selection abilities to the discussion composer.
|
||||
@@ -34,10 +33,10 @@ export default function () {
|
||||
|
||||
app.modal.show(TagDiscussionModal, {
|
||||
selectedTags: (this.composer.fields.tags || []).slice(0),
|
||||
onsubmit: tags => {
|
||||
onsubmit: (tags) => {
|
||||
this.composer.fields.tags = tags;
|
||||
this.$('textarea').focus();
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -47,32 +46,43 @@ export default function () {
|
||||
const tags = this.composer.fields.tags || [];
|
||||
const selectableTags = getSelectableTags();
|
||||
|
||||
items.add('tags', (
|
||||
items.add(
|
||||
'tags',
|
||||
<a className={classList(['DiscussionComposer-changeTags', !selectableTags.length && 'disabled'])} onclick={this.chooseTags.bind(this)}>
|
||||
{tags.length
|
||||
? tagsLabel(tags)
|
||||
: <span className="TagLabel untagged">{app.translator.trans('flarum-tags.forum.composer_discussion.choose_tags_link')}</span>}
|
||||
</a>
|
||||
), 10);
|
||||
{tags.length ? (
|
||||
tagsLabel(tags)
|
||||
) : (
|
||||
<span className="TagLabel untagged">{app.translator.trans('flarum-tags.forum.composer_discussion.choose_tags_link')}</span>
|
||||
)}
|
||||
</a>,
|
||||
10
|
||||
);
|
||||
});
|
||||
|
||||
override(DiscussionComposer.prototype, 'onsubmit', function (original) {
|
||||
const chosenTags = this.composer.fields.tags || [];
|
||||
const chosenPrimaryTags = chosenTags.filter(tag => tag.position() !== null && !tag.isChild());
|
||||
const chosenSecondaryTags = chosenTags.filter(tag => tag.position() === null);
|
||||
const chosenPrimaryTags = chosenTags.filter((tag) => tag.position() !== null && !tag.isChild());
|
||||
const chosenSecondaryTags = chosenTags.filter((tag) => tag.position() === null);
|
||||
const selectableTags = getSelectableTags();
|
||||
|
||||
if ((!chosenTags.length
|
||||
|| (chosenPrimaryTags.length < app.forum.attribute('minPrimaryTags'))
|
||||
|| (chosenSecondaryTags.length < app.forum.attribute('minSecondaryTags'))
|
||||
) && selectableTags.length) {
|
||||
const minPrimaryTags = parseInt(app.forum.attribute('minPrimaryTags'));
|
||||
const minSecondaryTags = parseInt(app.forum.attribute('minSecondaryTags'));
|
||||
const maxPrimaryTags = parseInt(app.forum.attribute('maxPrimaryTags'));
|
||||
const maxSecondaryTags = parseInt(app.forum.attribute('maxSecondaryTags'));
|
||||
|
||||
if (
|
||||
((!chosenTags.length && maxPrimaryTags !== 0 && maxSecondaryTags !== 0) ||
|
||||
chosenPrimaryTags.length < minPrimaryTags ||
|
||||
chosenSecondaryTags.length < minSecondaryTags) &&
|
||||
selectableTags.length
|
||||
) {
|
||||
app.modal.show(TagDiscussionModal, {
|
||||
selectedTags: chosenTags,
|
||||
onsubmit: tags => {
|
||||
this.composer.fields.tags = tags;
|
||||
original();
|
||||
}
|
||||
});
|
||||
selectedTags: chosenTags,
|
||||
onsubmit: (tags) => {
|
||||
this.composer.fields.tags = tags;
|
||||
original();
|
||||
},
|
||||
});
|
||||
} else {
|
||||
original();
|
||||
}
|
||||
|
@@ -4,13 +4,16 @@ import Button from 'flarum/common/components/Button';
|
||||
|
||||
import TagDiscussionModal from './components/TagDiscussionModal';
|
||||
|
||||
export default function() {
|
||||
export default function () {
|
||||
// Add a control allowing the discussion to be moved to another category.
|
||||
extend(DiscussionControls, 'moderationControls', function(items, discussion) {
|
||||
extend(DiscussionControls, 'moderationControls', function (items, discussion) {
|
||||
if (discussion.canTag()) {
|
||||
items.add('tags', <Button icon="fas fa-tag" onclick={() => app.modal.show(TagDiscussionModal, { discussion })}>
|
||||
{app.translator.trans('flarum-tags.forum.discussion_controls.edit_tags_button')}
|
||||
</Button>);
|
||||
items.add(
|
||||
'tags',
|
||||
<Button icon="fas fa-tag" onclick={() => app.modal.show(TagDiscussionModal, { discussion })}>
|
||||
{app.translator.trans('flarum-tags.forum.discussion_controls.edit_tags_button')}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -10,10 +10,10 @@ import TagHero from './components/TagHero';
|
||||
import Tag from '../common/models/Tag';
|
||||
import { ComponentAttrs } from 'flarum/common/Component';
|
||||
|
||||
const findTag = (slug: string) => app.store.all<Tag>('tags').find(tag => tag.slug().localeCompare(slug, undefined, { sensitivity: 'base' }) === 0);
|
||||
const findTag = (slug: string) => app.store.all<Tag>('tags').find((tag) => tag.slug().localeCompare(slug, undefined, { sensitivity: 'base' }) === 0);
|
||||
|
||||
export default function() {
|
||||
IndexPage.prototype.currentTag = function() {
|
||||
export default function () {
|
||||
IndexPage.prototype.currentTag = function () {
|
||||
if (this.currentActiveTag) {
|
||||
return this.currentActiveTag;
|
||||
}
|
||||
@@ -25,7 +25,7 @@ export default function() {
|
||||
tag = findTag(slug);
|
||||
}
|
||||
|
||||
if (slug && !tag || (tag && !tag.isChild() && !tag.children())) {
|
||||
if ((slug && !tag) || (tag && !tag.isChild() && !tag.children())) {
|
||||
if (this.currentTagLoading) {
|
||||
return;
|
||||
}
|
||||
@@ -36,13 +36,16 @@ export default function() {
|
||||
// a child tag page, then either:
|
||||
// - We loaded in that child tag (and its siblings) in the API document
|
||||
// - We first navigated to the current tag's parent, which would have loaded in the current tag's siblings.
|
||||
app.store.find('tags', slug, { include: 'children,children.parent,parent,state'}).then(() => {
|
||||
this.currentActiveTag = findTag(slug);
|
||||
app.store
|
||||
.find('tags', slug, { include: 'children,children.parent,parent,state' })
|
||||
.then(() => {
|
||||
this.currentActiveTag = findTag(slug);
|
||||
|
||||
m.redraw();
|
||||
}).finally(() => {
|
||||
this.currentTagLoading = false;
|
||||
});
|
||||
m.redraw();
|
||||
})
|
||||
.finally(() => {
|
||||
this.currentTagLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
if (tag) {
|
||||
@@ -54,7 +57,7 @@ export default function() {
|
||||
};
|
||||
|
||||
// If currently viewing a tag, insert a tag hero at the top of the view.
|
||||
override(IndexPage.prototype, 'hero', function(original) {
|
||||
override(IndexPage.prototype, 'hero', function (original) {
|
||||
const tag = this.currentTag();
|
||||
|
||||
if (tag) return <TagHero model={tag} />;
|
||||
@@ -62,13 +65,13 @@ export default function() {
|
||||
return original();
|
||||
});
|
||||
|
||||
extend(IndexPage.prototype, 'view', function(vdom: Mithril.Vnode<ComponentAttrs, {}>) {
|
||||
extend(IndexPage.prototype, 'view', function (vdom: Mithril.Vnode<ComponentAttrs, {}>) {
|
||||
const tag = this.currentTag();
|
||||
|
||||
if (tag) vdom.attrs.className += ' IndexPage--tag'+tag.id();
|
||||
if (tag) vdom.attrs.className += ' IndexPage--tag' + tag.id();
|
||||
});
|
||||
|
||||
extend(IndexPage.prototype, 'setTitle', function() {
|
||||
extend(IndexPage.prototype, 'setTitle', function () {
|
||||
const tag = this.currentTag();
|
||||
|
||||
if (tag) {
|
||||
@@ -78,7 +81,7 @@ export default function() {
|
||||
|
||||
// If currently viewing a tag, restyle the 'new discussion' button to use
|
||||
// the tag's color, and disable if the user isn't allowed to edit.
|
||||
extend(IndexPage.prototype, 'sidebarItems', function(items) {
|
||||
extend(IndexPage.prototype, 'sidebarItems', function (items) {
|
||||
const tag = this.currentTag();
|
||||
|
||||
if (tag) {
|
||||
@@ -92,18 +95,20 @@ export default function() {
|
||||
}
|
||||
|
||||
newDiscussion.attrs.disabled = !canStartDiscussion;
|
||||
newDiscussion.children = app.translator.trans(canStartDiscussion ? 'core.forum.index.start_discussion_button' : 'core.forum.index.cannot_start_discussion_button');
|
||||
newDiscussion.children = app.translator.trans(
|
||||
canStartDiscussion ? 'core.forum.index.start_discussion_button' : 'core.forum.index.cannot_start_discussion_button'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Add a parameter for the global search state to pass on to the
|
||||
// DiscussionListState that will let us filter discussions by tag.
|
||||
extend(GlobalSearchState.prototype, 'params', function(params) {
|
||||
extend(GlobalSearchState.prototype, 'params', function (params) {
|
||||
params.tags = m.route.param('tags');
|
||||
});
|
||||
|
||||
// Translate that parameter into a gambit appended to the search query.
|
||||
extend(DiscussionListState.prototype, 'requestParams', function(this: DiscussionListState, params) {
|
||||
extend(DiscussionListState.prototype, 'requestParams', function (this: DiscussionListState, params) {
|
||||
if (typeof params.include === 'string') {
|
||||
params.include = [params.include];
|
||||
} else {
|
||||
@@ -118,7 +123,7 @@ export default function() {
|
||||
if (q) {
|
||||
filter.q = `${q} tag:${this.params.tags}`;
|
||||
}
|
||||
params.filter = filter
|
||||
params.filter = filter;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -5,9 +5,9 @@ import DiscussionHero from 'flarum/forum/components/DiscussionHero';
|
||||
import tagsLabel from '../common/helpers/tagsLabel';
|
||||
import sortTags from '../common/utils/sortTags';
|
||||
|
||||
export default function() {
|
||||
export default function () {
|
||||
// Add tag labels to each discussion in the discussion list.
|
||||
extend(DiscussionListItem.prototype, 'infoItems', function(items) {
|
||||
extend(DiscussionListItem.prototype, 'infoItems', function (items) {
|
||||
const tags = this.attrs.discussion.tags();
|
||||
|
||||
if (tags && tags.length) {
|
||||
@@ -16,7 +16,7 @@ export default function() {
|
||||
});
|
||||
|
||||
// Restyle a discussion's hero to use its first tag's color.
|
||||
extend(DiscussionHero.prototype, 'view', function(view) {
|
||||
extend(DiscussionHero.prototype, 'view', function (view) {
|
||||
const tags = sortTags(this.attrs.discussion.tags());
|
||||
|
||||
if (tags && tags.length) {
|
||||
@@ -30,11 +30,11 @@ export default function() {
|
||||
|
||||
// Add a list of a discussion's tags to the discussion hero, displayed
|
||||
// before the title. Put the title on its own line.
|
||||
extend(DiscussionHero.prototype, 'items', function(items) {
|
||||
extend(DiscussionHero.prototype, 'items', function (items) {
|
||||
const tags = this.attrs.discussion.tags();
|
||||
|
||||
if (tags && tags.length) {
|
||||
items.add('tags', tagsLabel(tags, {link: true}), 5);
|
||||
items.add('tags', tagsLabel(tags, { link: true }), 5);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -7,14 +7,17 @@ import TagLinkButton from './components/TagLinkButton';
|
||||
import TagsPage from './components/TagsPage';
|
||||
import sortTags from '../common/utils/sortTags';
|
||||
|
||||
export default function() {
|
||||
export default function () {
|
||||
// Add a link to the tags page, as well as a list of all the tags,
|
||||
// to the index page's sidebar.
|
||||
extend(IndexPage.prototype, 'navItems', function (items) {
|
||||
items.add('tags', <LinkButton icon="fas fa-th-large" href={app.route('tags')}>
|
||||
{app.translator.trans('flarum-tags.forum.index.tags_link')}
|
||||
</LinkButton>
|
||||
, -10);
|
||||
items.add(
|
||||
'tags',
|
||||
<LinkButton icon="fas fa-th-large" href={app.route('tags')}>
|
||||
{app.translator.trans('flarum-tags.forum.index.tags_link')}
|
||||
</LinkButton>,
|
||||
-10
|
||||
);
|
||||
|
||||
if (app.current.matches(TagsPage)) return;
|
||||
|
||||
@@ -24,7 +27,7 @@ export default function() {
|
||||
const tags = app.store.all('tags');
|
||||
const currentTag = this.currentTag();
|
||||
|
||||
const addTag = tag => {
|
||||
const addTag = (tag) => {
|
||||
let active = currentTag === tag;
|
||||
|
||||
if (!active && currentTag) {
|
||||
@@ -36,23 +39,21 @@ export default function() {
|
||||
// use its children to populate the dropdown. The problem here is that `view`
|
||||
// on TagLinkButton is only called AFTER SelectDropdown, so no children are available
|
||||
// for SelectDropdown to use at the time.
|
||||
items.add('tag' + tag.id(), TagLinkButton.component({model: tag, params, active}, tag?.name()), -14);
|
||||
items.add('tag' + tag.id(), TagLinkButton.component({ model: tag, params, active }, tag?.name()), -14);
|
||||
};
|
||||
|
||||
sortTags(tags)
|
||||
.filter(tag => tag.position() !== null && (!tag.isChild() || (currentTag && (tag.parent() === currentTag || tag.parent() === currentTag.parent()))))
|
||||
.filter(
|
||||
(tag) => tag.position() !== null && (!tag.isChild() || (currentTag && (tag.parent() === currentTag || tag.parent() === currentTag.parent())))
|
||||
)
|
||||
.forEach(addTag);
|
||||
|
||||
const more = tags
|
||||
.filter(tag => tag.position() === null)
|
||||
.sort((a, b) => b.discussionCount() - a.discussionCount());
|
||||
const more = tags.filter((tag) => tag.position() === null).sort((a, b) => b.discussionCount() - a.discussionCount());
|
||||
|
||||
more.splice(0, 3).forEach(addTag);
|
||||
|
||||
if (more.length) {
|
||||
items.add('moreTags', <LinkButton href={app.route('tags')}>
|
||||
{app.translator.trans('flarum-tags.forum.index.more_link')}
|
||||
</LinkButton>, -16)
|
||||
items.add('moreTags', <LinkButton href={app.route('tags')}>{app.translator.trans('flarum-tags.forum.index.more_link')}</LinkButton>, -16);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -9,9 +9,7 @@ export default class DiscussionTaggedPost extends EventPost {
|
||||
const newTags = attrs.post.content()[1];
|
||||
|
||||
function diffTags(tags1, tags2) {
|
||||
return tags1
|
||||
.filter(tag => tags2.indexOf(tag) === -1)
|
||||
.map(id => app.store.getById('tags', id));
|
||||
return tags1.filter((tag) => tags2.indexOf(tag) === -1).map((id) => app.store.getById('tags', id));
|
||||
}
|
||||
|
||||
attrs.tagsAdded = diffTags(newTags, oldTags);
|
||||
@@ -39,15 +37,15 @@ export default class DiscussionTaggedPost extends EventPost {
|
||||
|
||||
if (this.attrs.tagsAdded.length) {
|
||||
data.tagsAdded = app.translator.trans('flarum-tags.forum.post_stream.tags_text', {
|
||||
tags: tagsLabel(this.attrs.tagsAdded, {link: true}),
|
||||
count: this.attrs.tagsAdded.length
|
||||
tags: tagsLabel(this.attrs.tagsAdded, { link: true }),
|
||||
count: this.attrs.tagsAdded.length,
|
||||
});
|
||||
}
|
||||
|
||||
if (this.attrs.tagsRemoved.length) {
|
||||
data.tagsRemoved = app.translator.trans('flarum-tags.forum.post_stream.tags_text', {
|
||||
tags: tagsLabel(this.attrs.tagsRemoved, {link: true}),
|
||||
count: this.attrs.tagsRemoved.length
|
||||
tags: tagsLabel(this.attrs.tagsRemoved, { link: true }),
|
||||
count: this.attrs.tagsRemoved.length,
|
||||
});
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user