Files
rogee 321c61aaae Vendor Chatwoot Vue 3 frontend into frontend/
Copy the Chatwoot (v4.14.0) frontend runnable subset into frontend/ for
customization:
- app/javascript/ (Vue SPA: dashboard, widget, sdk, portal, superadmin)
- app/views/ (ERB templates for vite-plugin-ruby entrypoint resolution)
- app/helpers/, app/assets/ (Rails view helpers, static assets)
- enterprise/ (Enterprise edition frontend overlay)
- config/vite.json, vite.config.ts, bin/vite (Vite-Rails toolchain)
- package.json, pnpm-lock.yaml, tailwind/postcss/eslint configs
- Gemfile, Gemfile.lock (vite_rails gem for bin/vite binstub)

Excluded Rails backend: controllers, models, services, jobs, mailers,
policies, db, lib, spec, public, node_modules.

Update references to the new frontend location:
- .gitignore: exclude frontend build artifacts (node_modules, tmp, packs),
  keep frontend/bin/ and frontend/vendor/ via negation
- backend/scripts/parity_frontend_smoke.sh: CHATWOOT_DIR default
  reference/chatwoot -> ../frontend
- backend/scripts/parity_frontend_browser_smoke.mjs: same default update
- AGENTS.md: add frontend section with Rails/Vite coupling notes
- README: architecture tree includes frontend/
2026-07-07 14:56:01 +08:00

99 lines
2.3 KiB
JavaScript

/* global axios */
import PortalsAPI from './portals';
import { getArticleSearchURL } from 'dashboard/helper/URLHelper.js';
class ArticlesAPI extends PortalsAPI {
constructor() {
super('articles', { accountScoped: true });
}
getArticles({
pageNumber,
portalSlug,
locale,
status,
authorId,
categorySlug,
sort,
}) {
const url = getArticleSearchURL({
pageNumber,
portalSlug,
locale,
status,
authorId,
categorySlug,
sort,
host: this.url,
});
return axios.get(url);
}
searchArticles({ portalSlug, query }) {
const url = getArticleSearchURL({
portalSlug,
query,
host: this.url,
});
return axios.get(url);
}
getArticle({ id, portalSlug }) {
return axios.get(`${this.url}/${portalSlug}/articles/${id}`);
}
updateArticle({ portalSlug, articleId, articleObj }) {
return axios.patch(
`${this.url}/${portalSlug}/articles/${articleId}`,
articleObj
);
}
createArticle({ portalSlug, articleObj }) {
const { content, title, authorId, categoryId, locale } = articleObj;
return axios.post(`${this.url}/${portalSlug}/articles`, {
content,
title,
author_id: authorId,
category_id: categoryId,
locale,
});
}
deleteArticle({ articleId, portalSlug }) {
return axios.delete(`${this.url}/${portalSlug}/articles/${articleId}`);
}
reorderArticles({ portalSlug, reorderedGroup, categorySlug }) {
return axios.post(`${this.url}/${portalSlug}/articles/reorder`, {
positions_hash: reorderedGroup,
category_slug: categorySlug,
});
}
bulkTranslate({ portalSlug, articleIds, locale, categoryId, force = false }) {
return axios.post(
`${this.url}/${portalSlug}/articles/bulk_actions/translate`,
{ ids: articleIds, locale, category_id: categoryId, force }
);
}
bulkUpdateStatus({ portalSlug, articleIds, status }) {
return axios.patch(
`${this.url}/${portalSlug}/articles/bulk_actions/update_status`,
{ ids: articleIds, status }
);
}
bulkDelete({ portalSlug, articleIds }) {
return axios.delete(
`${this.url}/${portalSlug}/articles/bulk_actions/delete_articles`,
{ data: { ids: articleIds } }
);
}
}
export default new ArticlesAPI();