Buildings and levels for the floor map, and make every identifier searchable
This commit is contained in:
@@ -21,13 +21,35 @@ from shopdb.api import require_permission, apply_import_timestamps
|
||||
knowledgebase_bp = Blueprint('knowledgebase', __name__)
|
||||
|
||||
|
||||
def _visible_articles():
|
||||
"""Active articles whose topic is not a retired application.
|
||||
|
||||
An article about a decommissioned application is not something anyone should
|
||||
find by browsing or searching: it describes a thing that is no longer in
|
||||
service, and presenting it alongside live documentation reads as though it
|
||||
were current.
|
||||
|
||||
An article with NO topic still shows. Not every article is about an
|
||||
application, and a null topic is not a retired one.
|
||||
|
||||
Expressed as a subquery rather than a join because the topic sort below joins
|
||||
Application itself, and two joins onto the same table in one query collide.
|
||||
"""
|
||||
retired = db.session.query(Application.appid).filter(
|
||||
Application.isactive.is_(False))
|
||||
return KnowledgeBase.query.filter(
|
||||
KnowledgeBase.isactive.is_(True),
|
||||
db.or_(KnowledgeBase.appid.is_(None),
|
||||
KnowledgeBase.appid.notin_(retired)))
|
||||
|
||||
|
||||
@knowledgebase_bp.route('', methods=['GET'])
|
||||
@jwt_required(optional=True)
|
||||
def list_articles():
|
||||
"""List all knowledge base articles."""
|
||||
page, per_page = get_pagination_params(request)
|
||||
|
||||
query = KnowledgeBase.query.filter_by(isactive=True)
|
||||
query = _visible_articles()
|
||||
|
||||
# Search: title, keywords, and the topic (its Application's name). The topic
|
||||
# is matched via an appid subquery instead of a join so it does not collide
|
||||
@@ -35,8 +57,13 @@ def list_articles():
|
||||
# clause and still match on title/keywords.
|
||||
if search := request.args.get('search'):
|
||||
like = f'%{search}%'
|
||||
# Active applications only. A retired application is not a topic anyone
|
||||
# should be offered: matching its name surfaced its articles and printed
|
||||
# the retired app as their subject, which reads as though it were still
|
||||
# in service.
|
||||
topic_appids = db.session.query(Application.appid).filter(
|
||||
Application.appname.ilike(like))
|
||||
Application.appname.ilike(like),
|
||||
Application.isactive.is_(True))
|
||||
query = query.filter(
|
||||
db.or_(
|
||||
KnowledgeBase.shortdescription.ilike(like),
|
||||
@@ -100,11 +127,11 @@ def list_articles():
|
||||
@jwt_required(optional=True)
|
||||
def get_stats():
|
||||
"""Get knowledge base statistics."""
|
||||
total_clicks = db.session.query(
|
||||
db.func.coalesce(db.func.sum(KnowledgeBase.clicks), 0)
|
||||
).filter(KnowledgeBase.isactive == True).scalar()
|
||||
|
||||
total_articles = KnowledgeBase.query.filter_by(isactive=True).count()
|
||||
# Counted over the same set the list shows. A total that includes articles
|
||||
# nobody can see is a total nobody can reconcile.
|
||||
visible = _visible_articles()
|
||||
total_clicks = sum(article.clicks or 0 for article in visible)
|
||||
total_articles = visible.count()
|
||||
|
||||
return success_response({
|
||||
'totalclicks': int(total_clicks),
|
||||
|
||||
Reference in New Issue
Block a user