Jelajahi Sumber

initial work to add code details

Daniel Sheffield 4 bulan lalu
induk
melakukan
38b1217c3f

+ 8 - 10
util-sqlpage/code/Index.sql

@@ -1,14 +1,12 @@
-SELECT 'dynamic' AS component, sqlpage.run_sql('sqlpage/Style.sql') AS properties;
+SET :content = sqlpage.variables('post');
 
-SET json = sqlpage.variables('post');
+SET :has_post_params = (SELECT 1 FROM json_each($content) LIMIT 1);
 
-SET inner = CASE (SELECT 1 FROM json_each($json) LIMIT 1)
+SET :inner = CASE :has_post_params
   WHEN 1 THEN 'code/save.sql'
-  ELSE 'code/recent.sql'
+  ELSE CASE COALESCE($hash, '')
+    WHEN '' THEN 'code/recent.sql'
+    ELSE 'code/form-fuel.sql'
+  END
 END;
---  ELSE CASE COALESCE($hash,'') = ''
---    WHEN TRUE THEN 'sqlpage/Link.sql'
---    ELSE 'sqlpage/link.sql'
---  END
---END;
-SELECT 'dynamic' AS component, sqlpage.run_sql($inner) AS properties;
+SELECT 'dynamic' AS component, sqlpage.run_sql(:inner) AS properties;

+ 0 - 1
util-sqlpage/code/entry.sql

@@ -5,5 +5,4 @@ SET tabler_color = 'azure';
 --SET image = '/static/upload/upload-favicon_square.svg';
 --SET favicon = $image;
 --SET manifest = '/static/upload/manifest.json';
-SELECT 'dynamic' AS component, sqlpage.run_sql('sqlpage/theme.sql') AS properties;
 SELECT 'dynamic' AS component, sqlpage.run_sql($inner) AS properties;

+ 59 - 0
util-sqlpage/code/form-fuel.sql

@@ -0,0 +1,59 @@
+--TODO: show barcode at top
+--SELECT 'dynamic' AS component, sqlpage.run_sql('sqlpage/QR.sql') AS properties;
+SET filter_options = (
+  SELECT json_agg(json_build_object('name', k, 'options', o))
+  FROM (
+    SELECT o.k, json_agg(
+      json_build_object('label', v, 'value', v, 'selected', c == 1)
+      ORDER BY v)
+    FROM (
+      SELECT 'store' AS k, DISTINCT store AS v, count(DISTINCT store) AS c FROM code_detail
+      UNION
+      SELECT 'value' AS k, DISTINCT value AS v, count(DISTINCT value) AS c FROM code_detail 
+    ) AS o
+    WHERE v IS NOT NULL
+    GROUP BY o.k
+  ) q(k, o)
+);
+SET :expiry = (SELECT expiry FROM code_detail WHERE hash = $hash);
+SET :value = (SELECT value FROM code_detail WHERE hash = $hash);
+SET :store = (SELECT store FROM code_detail WHERE hash = $hash);
+SET :used = (SELECT used FROM code_detail WHERE hash = $hash);
+
+SELECT 'form' AS component
+, '/code.sql' AS action
+, 'Update' AS validate
+, $tabler_color AS validate_color
+, 'post' AS method
+;
+SELECT j.name
+--, fo.j#>>'{options}' AS label
+, j.label
+, COALESCE(c.type, j.type) AS type
+, j.dropdown AS dropdown
+, j.multiple
+, COALESCE(c.width, j.width) AS width
+, o.j#>'{options}' AS options
+, COALESCE(j.value, v.value) AS value
+, CASE j.type
+    WHEN 'checkbox' THEN v.value::bool
+    ELSE NULL
+  END AS checked
+, j.formaction
+FROM json_populate_recordset(null::sqlpage_filter_type, sqlpage.read_file_as_text('code/json/filters.json')::json) j
+LEFT JOIN json_populate_recordset(null::sqlpage_filter_type, $filter_config::json) c
+USING (name)
+LEFT JOIN json_array_elements($filter_options::json) o(j)
+ON (o.j#>>'{name}') = j.name
+LEFT JOIN json_each_text(sqlpage.variables()::json) v(key, value)
+ON v.key = j.name
+;
+INSERT INTO code_detal(hash, type, value, expiry, used)
+VALUES ($hash, $type, $value, $expiry, $used)
+ON CONFLICT DO
+UPDATE SET
+  type = excluded.type,
+  value = excluded.value,
+  expiry = excluded.expiry,
+  used = excluded.used
+;

+ 21 - 0
util-sqlpage/code/json/filters.json

@@ -0,0 +1,21 @@
+[
+    { "name": "type", "label": "",
+      "type": "hidden", "value": "Fuel"
+    },
+    { "name": "used", "label": "Use",
+      "type": "checkbox", "value": "true",
+      "width": 1
+    },
+    { "name": "expiry", "label": "Expiry",
+      "type": "date",
+      "width": 3
+    },
+    { "name": "store", "label": "Store",
+      "type": "select", "dropdown": true,
+      "width": 3
+    },
+    { "name": "value", "label": "Value", "prefix": "$",
+      "type": "select", "dropdown": true,
+      "width": 3
+    }
+]

+ 10 - 0
util-sqlpage/code/new.sql

@@ -0,0 +1,10 @@
+INSERT INTO code(hash, content, svg, created)
+VALUES ($hash, $content, $qr, CURRENT_TIMESTAMP)
+ON CONFLICT DO
+UPDATE SET
+  content = excluded.content,
+  created = excluded.created,
+  svg = excluded.svg
+WHERE excluded.created > code.created;
+SELECT 'text' AS component;
+SELECT $hash AS contents;

+ 68 - 1
util-sqlpage/code/recent.sql

@@ -1,2 +1,69 @@
+SELECT 'dynamic' AS component, sqlpage.run_sql('sqlpage/theme.sql') AS properties;
+SELECT 'dynamic' AS component, sqlpage.run_sql('sqlpage/Style.sql') AS properties;
+SET filter_config = '[
+  {"name": "type", "type": "select"},
+  {"name": "expired", "label": "Show Expired",
+   "type": "checkbox", "value": "true"
+  },
+  {"name": "used", "label": "Show Used"}
+]';
+SET filter_options = (
+  SELECT json_agg(json_build_object('name', k, 'options', o))
+  FROM (
+    SELECT o.k, json_agg(
+      json_build_object('label', v, 'value', v, 'selected', c == 1)
+      ORDER BY v)
+    FROM (
+      SELECT 'store' AS k, DISTINCT store AS v, count(DISTINCT store) AS c FROM code_detail
+      UNION
+      SELECT 'type' AS k, DISTINCT type AS v, count(DISTINCT type) AS c FROM code_detail 
+    ) AS o
+    WHERE v IS NOT NULL
+    GROUP BY o.k
+  ) q(k, o)
+);
+SELECT 'form' AS component
+, '/code.sql' AS action
+, 'Update' AS validate
+, $tabler_color AS validate_color
+, 'get' AS method
+;
+SELECT j.name
+--, fo.j#>>'{options}' AS label
+, j.label
+, COALESCE(c.type, j.type) AS type
+, j.dropdown AS dropdown
+, j.multiple
+, COALESCE(c.width, j.width) AS width
+, o.j#>'{options}' AS options
+, COALESCE(j.value, v.value) AS value
+, CASE j.type
+    WHEN 'checkbox' THEN v.value::bool
+    ELSE NULL
+  END AS checked
+, j.formaction
+FROM json_populate_recordset(null::sqlpage_filter_type, sqlpage.read_file_as_text('code/json/filters.json')::json) j
+LEFT JOIN json_populate_recordset(null::sqlpage_filter_type, $filter_config::json) c
+USING (name)
+LEFT JOIN json_array_elements($filter_options::json) o(j)
+ON (o.j#>>'{name}') = j.name
+LEFT JOIN json_each_text(sqlpage.variables()::json) v(key, value)
+ON v.key = j.name
+;
 SELECT 'table' AS component;
-SELECT hash, content, created FROM code;
+SELECT hash, content, created
+FROM code c
+LEFT JOIN code_detail cd
+ON c.hash = cd.hash
+WHERE (
+    cd.expiry IS NULL OR COALESCE($expired, 'false') == 'true' OR cd.expiry::date < datetime(CURRENT_TIMESTAMP, 'localtime')::date
+) AND (
+    cd.used IS NULL OR COALESCE($used, 'false') == 'true' OR NOT cd.used
+) AND (
+    cd.type IS NULL OR CASE COALESCE($type, '')
+      WHEN '' THEN TRUE
+      ELSE COALESCE($type, '') = cd.type
+    END
+)
+ORDER BY expiry, type, hash NULLS FIRST
+;

+ 12 - 18
util-sqlpage/code/save.sql

@@ -1,32 +1,26 @@
-SET request = json_object(
+SET :request = json_object(
     'method', 'POST',
     'url', 'https://shandan.one/hash',
     'headers', json_object(),
     'body', json_object(
-        'data', $json,
+        'data', $content,
         'person', $tool
     )
 );
-SET hash = sqlpage.fetch($request);
-SET fallback = 'https://shandan.one/upload/' || sqlpage.url_encode($hash);
-SET request = json_object(
+SET :hash = sqlpage.fetch($request);
+SET :fallback = 'https://shandan.one/upload/' || sqlpage.url_encode($hash);
+SET :request = json_object(
     'method', 'POST',
     'url', 'https://shandan.one/qr',
     'headers', json_object(),
     'body', json_object(
-        'data', $json,
+        'data', $content,
         'fallback', $fallback
     )
 );
-SET qr = sqlpage.fetch($request);
-INSERT INTO code(hash, content, svg, created)
-VALUES ($hash, $json, $qr, CURRENT_TIMESTAMP)
-ON CONFLICT DO
-UPDATE SET
-  content = excluded.content,
-  created = excluded.created,
-  svg = excluded.svg
-WHERE excluded.created > code.created;
-SELECT 'text' AS component;
-SELECT $json AS contents;
---SELECT 'dynamic' AS component, sqlpage.run_sql('sqlpage/link.sql') AS properties;
+SET :qr = sqlpage.fetch($request);
+SET :inner = CASE $action
+  WHEN 'Update' THEN 'code/update.sql'
+  ELSE 'code/new.sql'
+END;
+SELECT 'dynamic' AS component, sqlpage.run_sql(:inner) AS properties;

+ 8 - 0
util-sqlpage/sqlpage/migrations/007_code_detail.sql

@@ -0,0 +1,8 @@
+DROP TABLE IF EXISTS code_detail;
+CREATE TABLE IF NOT EXISTS code_detail(
+  hash text PRIMARY KEY,
+  type text,
+  value numeric,
+  expiry timestamp,
+  used bool
+);