Orzu Ionut 2 years ago
parent
commit
76aff69866
  1. 43
      README.md
  2. 8
      app/Http/Controllers/SearchAndDisplaceController.php
  3. 4
      app/Http/Controllers/SearcherController.php
  4. 3
      app/SearchDisplace/Searchers/Duckling.php
  5. 2
      app/SearchDisplace/Searchers/Searcher.php
  6. 2
      app/SearchDisplace/Searchers/SearcherCreator.php
  7. 4
      app/SearchDisplace/Searchers/SearcherFactory.php
  8. 4
      app/SearchDisplace/Searchers/SearchersStorage.php
  9. 239
      composer-env.nix
  10. 13
      default.nix
  11. 588
      node-env.nix
  12. 17
      node.nix
  13. 16872
      package-lock.json
  14. 2
      package.json
  15. 1028
      php-packages.nix
  16. 626
      public/css/app.css
  17. 281
      registry.nix
  18. 2
      resources/js/app.ts
  19. 3
      resources/js/components/ProcessFile/ProcessFile.scss
  20. 18
      resources/js/components/ProcessFile/ProcessFile.ts
  21. 21
      resources/js/components/ProcessFile/ProcessFile.vue
  22. 95
      resources/js/components/Regex/Create.vue
  23. 91
      resources/js/components/Searchers/Create.vue
  24. 6
      resources/js/components/Searchers/DefineSearcher.vue
  25. 6
      resources/js/components/Searchers/Index.vue
  26. 1
      resources/js/interfaces/Searcher.ts
  27. 7
      resources/sass/components/regex/create/_index.sass
  28. 2
      resources/sass/components/searchers/_create.sass

43
README.md

@ -1,4 +1,11 @@
# Search and Displace Core
# Search and Displace Core
---
**NOTE**
The installation steps below were tested on an Ubuntu machine and should be adapted for each specific environment.
---
## Install
- Create the `.env` file by copying the contents from the `.env.example` file.
@ -7,8 +14,8 @@
- Install the 'sqlite' driver for your PHP version if it is not already installed.
- For the 'QUEUE_CONNECTION' variable in `.env` you can use either `sync` or `redis` (recommended). If you choose to use `redis`
then you need to make sure that it is installed on your machine.
- For the 'QUEUE_CONNECTION' variable in `.env` you can use either `sync` or `redis` (recommended). If you choose to use `redis`
then you need to make sure that it is installed on your machine.
`apt update`
@ -16,16 +23,20 @@ then you need to make sure that it is installed on your machine.
- Install the `Search and Displace Ingest` app, found here https://git.law/newroco/searchanddisplace-ingest
- Get the URL of the `Search and Displace Ingest` app and add it to the `SD_INGEST_URL` variable in `.env`
- Add in `.env` the `WEBHOOK_CLIENT_SECRET` value which needs to be the same value as the `WEBHOOK_CORE_SECRET` in
- Add in `.env` the `WEBHOOK_CLIENT_SECRET` value which needs to be the same value as the `WEBHOOK_CORE_SECRET` in
the `Search and Displace Ingest` app `.env` file
- Add in `.env` the `SD_DUCKLING_URL` value which by default is `http://0.0.0.0:8000/parse`. You can find
details about installing Facebook Duckling in a section below.
- Add in `.env` the `SD_DUCKLING_URL` value which by default is `http://0.0.0.0:8000/parse`. You can find
details about installing Facebook Duckling in a section below.
- Install composer
- Install composer
- Install composer dependencies
`composer install`
- Generate the app key by running the following command:
`php artisan key:generate`
- Install NodeJS and npm
- Install npm dependencies
@ -41,14 +52,14 @@ details about installing Facebook Duckling in a section below.
- Migrate DB tables
- `php artisan migrate`
`php artisan migrate`
### Facebook Duckling
### Facebook Duckling
- `$ apt-get install libpcre3-dev`
- `$ cd ..`
- `$ cd ..`
- `$ git clone https://github.com/facebook/duckling.git && cd duckling`
- `$ curl -sSL https://get.haskellstack.org/ | sh`
- `$ stack build && stack exec duckling-example-exe`
- `$ curl -sSL https://get.haskellstack.org/ | sh`
- `$ stack build && stack exec duckling-example-exe`
- `$ stack test`
### Converting documents from MD to ODT
@ -88,17 +99,17 @@ have 4 digits, a dash, 3 digits, a dash, and finally 3 digits; 1234-123-123 is a
## Compounded searcher
A compounded searcher contains one or more searchers, which can be either basic or comopounded.
The searchers can be listed in two ways: in rows and in columns. Each column in a row
The searchers can be listed in two ways: in rows and in columns. Each column in a row
extends the searching criteria and each row filters the results of the previous row.
Let's take as an example the following searcher: the first row has 2 searchers, in the first column
Let's take as an example the following searcher: the first row has 2 searchers, in the first column
we have the 'Email' native basic searcher and in the second column we have a custom basic searcher
which searches for text strings that have a leading '#' character. The second rows has only one column
and that column has a custom basic searcher which searches for text strings which contain the '@' character.
After we execute the Search&Displace the first row of the searcher will be applied on the initial document content
and will find all email addresses and all text strings which have a leading '#' character, so the operation applies
and will find all email addresses and all text strings which have a leading '#' character, so the operation applies
the searchers in the first row independently, each column extending the searching criteria.
Then the second row will be applied on the results of the first row, so on the email addresses and the text strings
Then the second row will be applied on the results of the first row, so on the email addresses and the text strings
which have a leading '#' character, basically each row filters the results of the previous row.
# Demo Version

8
app/Http/Controllers/SearchAndDisplaceController.php

@ -14,9 +14,9 @@ class SearchAndDisplaceController extends Controller
try {
$result = $handler->getAfterIngest($id);
if ($result['status'] !== 'processing') {
$handler->destroy($id);
}
// if ($result['status'] !== 'processing') {
// $handler->destroy($id);
// }
return response()->json($result, 200);
} catch (\Exception $exception) {
@ -40,7 +40,7 @@ class SearchAndDisplaceController extends Controller
$searchOnly = request()->input('searchOnly') ?? false;
$searchAndDisplace = new SearchAndDisplace(
request()->input('content'),
stripslashes(request()->input('content')),
[
'searchers' => request()->input('searchers'),
],

4
app/Http/Controllers/SearcherController.php

@ -37,6 +37,7 @@ class SearcherController extends Controller
{
request()->validate([
'name' => 'required',
'description' => 'required',
'tag' => 'nullable',
'rows' => 'required|array',
'rows.*' => 'array',
@ -45,6 +46,7 @@ class SearcherController extends Controller
try {
$factory = new SearcherFactory(
request()->get('name'),
request()->get('description'),
request()->get('rows'),
request()->get('tag')
);
@ -112,6 +114,7 @@ class SearcherController extends Controller
{
request()->validate([
'name' => 'required',
'description' => 'required',
'tag' => 'nullable',
'rows' => 'required|array',
'rows.*' => 'array',
@ -120,6 +123,7 @@ class SearcherController extends Controller
try {
$factory = new SearcherFactory(
request()->get('name'),
request()->get('description'),
request()->get('rows'),
request()->get('tag')
);

3
app/SearchDisplace/Searchers/Duckling.php

@ -10,7 +10,8 @@ class Duckling
public function __construct()
{
$this->url = env('SD_DUCKLING_URL');
// $this->url = env('SD_DUCKLING_URL');
$this->url = 'host.docker.internal:5000/parse';
}
public function execute($content, $dimensions)

2
app/SearchDisplace/Searchers/Searcher.php

@ -53,7 +53,7 @@ class Searcher
return [
'start' => $item['start'],
'end' => $item['end'] - 1,
'content' => $item['body'],
'content' => filter_var($item['body'], FILTER_SANITIZE_URL),
];
}, $result);
}

2
app/SearchDisplace/Searchers/SearcherCreator.php

@ -62,8 +62,8 @@ abstract class SearcherCreator
$contents = [
'id' => $id,
'name' => $this->name,
'tag' => $this->tag,
'description' => $this->description,
'tag' => $this->tag,
'rows' => $this->rows,
];

4
app/SearchDisplace/Searchers/SearcherFactory.php

@ -4,9 +4,9 @@ namespace App\SearchDisplace\Searchers;
class SearcherFactory extends SearcherCreator
{
public function __construct($name, $rows, $tag = '')
public function __construct($name, $description, $rows, $tag = '')
{
parent::__construct($name, $tag, '');
parent::__construct($name, $tag, $description);
$this->rows = $rows;
}

4
app/SearchDisplace/Searchers/SearchersStorage.php

@ -28,9 +28,13 @@ class SearchersStorage
continue;
}
$contents = json_decode($this->storage->get($file), true);
$description = $contents['description'];
$searchers[$fileName] = [
'id' => $fileName,
'name' => $result[1],
'description' => $description,
'tag' => '',
'param' => SearchersCollection::PARAM_REQUIRED,
];

239
composer-env.nix

@ -0,0 +1,239 @@
# This file originates from composer2nix
{ stdenv, lib, writeTextFile, fetchurl, php, unzip, phpPackages }:
let
inherit (phpPackages) composer;
buildZipPackage = { name, src }:
stdenv.mkDerivation {
inherit name src;
buildInputs = [ unzip ];
buildCommand = ''
unzip $src
baseDir=$(find . -type d -mindepth 1 -maxdepth 1)
cd $baseDir
mkdir -p $out
mv * $out
'';
};
buildPackage =
{ name
, src
, packages ? {}
, devPackages ? {}
, buildInputs ? []
, symlinkDependencies ? false
, executable ? false
, removeComposerArtifacts ? false
, postInstall ? ""
, noDev ? false
, composerExtraArgs ? ""
, unpackPhase ? "true"
, buildPhase ? "true"
, ...}@args:
let
reconstructInstalled = writeTextFile {
name = "reconstructinstalled.php";
executable = true;
text = ''
#! ${php}/bin/php
<?php
if(file_exists($argv[1]))
{
$composerLockStr = file_get_contents($argv[1]);
if($composerLockStr === false)
{
fwrite(STDERR, "Cannot open composer.lock contents\n");
exit(1);
}
else
{
$config = json_decode($composerLockStr, true);
if(array_key_exists("packages", $config))
$allPackages = $config["packages"];
else
$allPackages = array();
${lib.optionalString (!noDev) ''
if(array_key_exists("packages-dev", $config))
$allPackages = array_merge($allPackages, $config["packages-dev"]);
''}
$packagesStr = json_encode($allPackages, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
print($packagesStr);
}
}
else
print("[]");
?>
'';
};
constructBin = writeTextFile {
name = "constructbin.php";
executable = true;
text = ''
#! ${php}/bin/php
<?php
$composerJSONStr = file_get_contents($argv[1]);
if($composerJSONStr === false)
{
fwrite(STDERR, "Cannot open composer.json contents\n");
exit(1);
}
else
{
$config = json_decode($composerJSONStr, true);
if(array_key_exists("bin-dir", $config))
$binDir = $config["bin-dir"];
else
$binDir = "bin";
if(array_key_exists("bin", $config))
{
if(!file_exists("vendor/".$binDir))
mkdir("vendor/".$binDir);
foreach($config["bin"] as $bin)
symlink("../../".$bin, "vendor/".$binDir."/".basename($bin));
}
}
?>
'';
};
bundleDependencies = dependencies:
lib.concatMapStrings (dependencyName:
let
dependency = dependencies.${dependencyName};
in
''
${if dependency.targetDir == "" then ''
vendorDir="$(dirname ${dependencyName})"
mkdir -p "$vendorDir"
${if symlinkDependencies then
''ln -s "${dependency.src}" "$vendorDir/$(basename "${dependencyName}")"''
else
''cp -av "${dependency.src}" "$vendorDir/$(basename "${dependencyName}")"''
}
'' else ''
namespaceDir="${dependencyName}/$(dirname "${dependency.targetDir}")"
mkdir -p "$namespaceDir"
${if symlinkDependencies then
''ln -s "${dependency.src}" "$namespaceDir/$(basename "${dependency.targetDir}")"''
else
''cp -av "${dependency.src}" "$namespaceDir/$(basename "${dependency.targetDir}")"''
}
''}
'') (builtins.attrNames dependencies);
extraArgs = removeAttrs args [ "name" "packages" "devPackages" "buildInputs" ];
in
stdenv.mkDerivation ({
name = "composer-${name}";
buildInputs = [ php composer ] ++ buildInputs;
inherit unpackPhase buildPhase;
installPhase = ''
${if executable then ''
mkdir -p $out/share/php
cp -av $src $out/share/php/$name
chmod -R u+w $out/share/php/$name
cd $out/share/php/$name
'' else ''
cp -av $src $out
chmod -R u+w $out
cd $out
''}
# Remove unwanted files
rm -f *.nix
export HOME=$TMPDIR
# Remove the provided vendor folder if it exists
rm -Rf vendor
# If there is no composer.lock file, compose a dummy file.
# Otherwise, composer attempts to download the package.json file from
# the registry which we do not want.
if [ ! -f composer.lock ]
then
cat > composer.lock <<EOF
{
"packages": []
}
EOF
fi
# Reconstruct the installed.json file from the lock file
mkdir -p vendor/composer
${php}/bin/php ${reconstructInstalled} composer.lock > vendor/composer/installed.json
# Copy or symlink the provided dependencies
cd vendor
${bundleDependencies packages}
${lib.optionalString (!noDev) (bundleDependencies devPackages)}
cd ..
# Reconstruct autoload scripts
# We use the optimize feature because Nix packages cannot change after they have been built
# Using the dynamic loader for a Nix package is useless since there is nothing to dynamically reload.
composer dump-autoload --optimize ${lib.optionalString noDev "--no-dev"} ${composerExtraArgs}
# Run the install step as a validation to confirm that everything works out as expected
composer install --optimize-autoloader ${lib.optionalString noDev "--no-dev"} ${composerExtraArgs}
${lib.optionalString executable ''
# Reconstruct the bin/ folder if we deploy an executable project
${php}/bin/php ${constructBin} composer.json
ln -s $(pwd)/vendor/bin $out/bin
''}
${lib.optionalString (!symlinkDependencies) ''
# Patch the shebangs if possible
if [ -d $(pwd)/vendor/bin ]
then
# Look for all executables in bin/
for i in $(pwd)/vendor/bin/*
do
# Look for their location
realFile=$(readlink -f "$i")
# Restore write permissions
chmod u+wx "$(dirname "$realFile")"
chmod u+w "$realFile"
# Patch shebang
sed -e "s|#!/usr/bin/php|#!${php}/bin/php|" \
-e "s|#!/usr/bin/env php|#!${php}/bin/php|" \
"$realFile" > tmp
mv tmp "$realFile"
chmod u+x "$realFile"
done
fi
''}
if [ "$removeComposerArtifacts" = "1" ]
then
# Remove composer stuff
rm -f composer.json composer.lock
fi
# Execute post install hook
runHook postInstall
'';
} // extraArgs);
in
{
composer = lib.makeOverridable composer;
buildZipPackage = lib.makeOverridable buildZipPackage;
buildPackage = lib.makeOverridable buildPackage;
}

13
default.nix

@ -0,0 +1,13 @@
{pkgs ? import <nixpkgs> {
inherit system;
}, system ? builtins.currentSystem, noDev ? false}:
let
composerEnv = import ./composer-env.nix {
inherit (pkgs) stdenv lib writeTextFile fetchurl php unzip phpPackages;
};
in
import ./php-packages.nix {
inherit composerEnv noDev;
inherit (pkgs) fetchurl fetchgit fetchhg fetchsvn;
}

588
node-env.nix

@ -0,0 +1,588 @@
# This file originates from node2nix
{lib, stdenv, nodejs, python2, pkgs, libtool, runCommand, writeTextFile, writeShellScript}:
let
# Workaround to cope with utillinux in Nixpkgs 20.09 and util-linux in Nixpkgs master
utillinux = if pkgs ? utillinux then pkgs.utillinux else pkgs.util-linux;
python = if nodejs ? python then nodejs.python else python2;
# Create a tar wrapper that filters all the 'Ignoring unknown extended header keyword' noise
tarWrapper = runCommand "tarWrapper" {} ''
mkdir -p $out/bin
cat > $out/bin/tar <<EOF
#! ${stdenv.shell} -e
$(type -p tar) "\$@" --warning=no-unknown-keyword --delay-directory-restore
EOF
chmod +x $out/bin/tar
'';
# Function that generates a TGZ file from a NPM project
buildNodeSourceDist =
{ name, version, src, ... }:
stdenv.mkDerivation {
name = "node-tarball-${name}-${version}";
inherit src;
buildInputs = [ nodejs ];
buildPhase = ''
export HOME=$TMPDIR
tgzFile=$(npm pack | tail -n 1) # Hooks to the pack command will add output (https://docs.npmjs.com/misc/scripts)
'';
installPhase = ''
mkdir -p $out/tarballs
mv $tgzFile $out/tarballs
mkdir -p $out/nix-support
echo "file source-dist $out/tarballs/$tgzFile" >> $out/nix-support/hydra-build-products
'';
};
# Common shell logic
installPackage = writeShellScript "install-package" ''
installPackage() {
local packageName=$1 src=$2
local strippedName
local DIR=$PWD
cd $TMPDIR
unpackFile $src
# Make the base dir in which the target dependency resides first
mkdir -p "$(dirname "$DIR/$packageName")"
if [ -f "$src" ]
then
# Figure out what directory has been unpacked
packageDir="$(find . -maxdepth 1 -type d | tail -1)"
# Restore write permissions to make building work
find "$packageDir" -type d -exec chmod u+x {} \;
chmod -R u+w "$packageDir"
# Move the extracted tarball into the output folder
mv "$packageDir" "$DIR/$packageName"
elif [ -d "$src" ]
then
# Get a stripped name (without hash) of the source directory.
# On old nixpkgs it's already set internally.
if [ -z "$strippedName" ]
then
strippedName="$(stripHash $src)"
fi
# Restore write permissions to make building work
chmod -R u+w "$strippedName"
# Move the extracted directory into the output folder
mv "$strippedName" "$DIR/$packageName"
fi
# Change to the package directory to install dependencies
cd "$DIR/$packageName"
}
'';
# Bundle the dependencies of the package
#
# Only include dependencies if they don't exist. They may also be bundled in the package.
includeDependencies = {dependencies}:
lib.optionalString (dependencies != []) (
''
mkdir -p node_modules
cd node_modules
''
+ (lib.concatMapStrings (dependency:
''
if [ ! -e "${dependency.name}" ]; then
${composePackage dependency}
fi
''
) dependencies)
+ ''
cd ..
''
);
# Recursively composes the dependencies of a package
composePackage = { name, packageName, src, dependencies ? [], ... }@args:
builtins.addErrorContext "while evaluating node package '${packageName}'" ''
installPackage "${packageName}" "${src}"
${includeDependencies { inherit dependencies; }}
cd ..
${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
'';
pinpointDependencies = {dependencies, production}:
let
pinpointDependenciesFromPackageJSON = writeTextFile {
name = "pinpointDependencies.js";
text = ''
var fs = require('fs');
var path = require('path');
function resolveDependencyVersion(location, name) {
if(location == process.env['NIX_STORE']) {
return null;
} else {
var dependencyPackageJSON = path.join(location, "node_modules", name, "package.json");
if(fs.existsSync(dependencyPackageJSON)) {
var dependencyPackageObj = JSON.parse(fs.readFileSync(dependencyPackageJSON));
if(dependencyPackageObj.name == name) {
return dependencyPackageObj.version;
}
} else {
return resolveDependencyVersion(path.resolve(location, ".."), name);
}
}
}
function replaceDependencies(dependencies) {
if(typeof dependencies == "object" && dependencies !== null) {
for(var dependency in dependencies) {
var resolvedVersion = resolveDependencyVersion(process.cwd(), dependency);
if(resolvedVersion === null) {
process.stderr.write("WARNING: cannot pinpoint dependency: "+dependency+", context: "+process.cwd()+"\n");
} else {
dependencies[dependency] = resolvedVersion;
}
}
}
}
/* Read the package.json configuration */
var packageObj = JSON.parse(fs.readFileSync('./package.json'));
/* Pinpoint all dependencies */
replaceDependencies(packageObj.dependencies);
if(process.argv[2] == "development") {
replaceDependencies(packageObj.devDependencies);
}
replaceDependencies(packageObj.optionalDependencies);
/* Write the fixed package.json file */
fs.writeFileSync("package.json", JSON.stringify(packageObj, null, 2));
'';
};
in
''
node ${pinpointDependenciesFromPackageJSON} ${if production then "production" else "development"}
${lib.optionalString (dependencies != [])
''
if [ -d node_modules ]
then
cd node_modules
${lib.concatMapStrings (dependency: pinpointDependenciesOfPackage dependency) dependencies}
cd ..
fi
''}
'';
# Recursively traverses all dependencies of a package and pinpoints all
# dependencies in the package.json file to the versions that are actually
# being used.
pinpointDependenciesOfPackage = { packageName, dependencies ? [], production ? true, ... }@args:
''
if [ -d "${packageName}" ]
then
cd "${packageName}"
${pinpointDependencies { inherit dependencies production; }}
cd ..
${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
fi
'';
# Extract the Node.js source code which is used to compile packages with
# native bindings
nodeSources = runCommand "node-sources" {} ''
tar --no-same-owner --no-same-permissions -xf ${nodejs.src}
mv node-* $out
'';
# Script that adds _integrity fields to all package.json files to prevent NPM from consulting the cache (that is empty)
addIntegrityFieldsScript = writeTextFile {
name = "addintegrityfields.js";
text = ''
var fs = require('fs');
var path = require('path');
function augmentDependencies(baseDir, dependencies) {
for(var dependencyName in dependencies) {
var dependency = dependencies[dependencyName];
// Open package.json and augment metadata fields
var packageJSONDir = path.join(baseDir, "node_modules", dependencyName);
var packageJSONPath = path.join(packageJSONDir, "package.json");
if(fs.existsSync(packageJSONPath)) { // Only augment packages that exist. Sometimes we may have production installs in which development dependencies can be ignored
console.log("Adding metadata fields to: "+packageJSONPath);
var packageObj = JSON.parse(fs.readFileSync(packageJSONPath));
if(dependency.integrity) {
packageObj["_integrity"] = dependency.integrity;
} else {
packageObj["_integrity"] = "sha1-000000000000000000000000000="; // When no _integrity string has been provided (e.g. by Git dependencies), add a dummy one. It does not seem to harm and it bypasses downloads.
}
if(dependency.resolved) {
packageObj["_resolved"] = dependency.resolved; // Adopt the resolved property if one has been provided
} else {
packageObj["_resolved"] = dependency.version; // Set the resolved version to the version identifier. This prevents NPM from cloning Git repositories.
}
if(dependency.from !== undefined) { // Adopt from property if one has been provided
packageObj["_from"] = dependency.from;
}
fs.writeFileSync(packageJSONPath, JSON.stringify(packageObj, null, 2));
}
// Augment transitive dependencies
if(dependency.dependencies !== undefined) {
augmentDependencies(packageJSONDir, dependency.dependencies);
}
}
}
if(fs.existsSync("./package-lock.json")) {
var packageLock = JSON.parse(fs.readFileSync("./package-lock.json"));
if(![1, 2].includes(packageLock.lockfileVersion)) {
process.stderr.write("Sorry, I only understand lock file versions 1 and 2!\n");
process.exit(1);
}
if(packageLock.dependencies !== undefined) {
augmentDependencies(".", packageLock.dependencies);
}
}
'';
};
# Reconstructs a package-lock file from the node_modules/ folder structure and package.json files with dummy sha1 hashes
reconstructPackageLock = writeTextFile {
name = "addintegrityfields.js";
text = ''
var fs = require('fs');
var path = require('path');
var packageObj = JSON.parse(fs.readFileSync("package.json"));
var lockObj = {
name: packageObj.name,
version: packageObj.version,
lockfileVersion: 1,
requires: true,
dependencies: {}
};
function augmentPackageJSON(filePath, dependencies) {
var packageJSON = path.join(filePath, "package.json");
if(fs.existsSync(packageJSON)) {
var packageObj = JSON.parse(fs.readFileSync(packageJSON));
dependencies[packageObj.name] = {
version: packageObj.version,
integrity: "sha1-000000000000000000000000000=",
dependencies: {}
};
processDependencies(path.join(filePath, "node_modules"), dependencies[packageObj.name].dependencies);
}
}
function processDependencies(dir, dependencies) {
if(fs.existsSync(dir)) {
var files = fs.readdirSync(dir);
files.forEach(function(entry) {
var filePath = path.join(dir, entry);
var stats = fs.statSync(filePath);
if(stats.isDirectory()) {
if(entry.substr(0, 1) == "@") {
// When we encounter a namespace folder, augment all packages belonging to the scope
var pkgFiles = fs.readdirSync(filePath);
pkgFiles.forEach(function(entry) {
if(stats.isDirectory()) {
var pkgFilePath = path.join(filePath, entry);
augmentPackageJSON(pkgFilePath, dependencies);
}
});
} else {
augmentPackageJSON(filePath, dependencies);
}
}
});
}
}
processDependencies("node_modules", lockObj.dependencies);
fs.writeFileSync("package-lock.json", JSON.stringify(lockObj, null, 2));
'';
};
prepareAndInvokeNPM = {packageName, bypassCache, reconstructLock, npmFlags, production}:
let
forceOfflineFlag = if bypassCache then "--offline" else "--registry http://www.example.com";
in
''
# Pinpoint the versions of all dependencies to the ones that are actually being used
echo "pinpointing versions of dependencies..."
source $pinpointDependenciesScriptPath
# Patch the shebangs of the bundled modules to prevent them from
# calling executables outside the Nix store as much as possible
patchShebangs .
# Deploy the Node.js package by running npm install. Since the
# dependencies have been provided already by ourselves, it should not
# attempt to install them again, which is good, because we want to make
# it Nix's responsibility. If it needs to install any dependencies
# anyway (e.g. because the dependency parameters are
# incomplete/incorrect), it fails.
#
# The other responsibilities of NPM are kept -- version checks, build
# steps, postprocessing etc.
export HOME=$TMPDIR
cd "${packageName}"
runHook preRebuild
${lib.optionalString bypassCache ''
${lib.optionalString reconstructLock ''
if [ -f package-lock.json ]
then
echo "WARNING: Reconstruct lock option enabled, but a lock file already exists!"
echo "This will most likely result in version mismatches! We will remove the lock file and regenerate it!"
rm package-lock.json
else
echo "No package-lock.json file found, reconstructing..."
fi
node ${reconstructPackageLock}
''}
node ${addIntegrityFieldsScript}
''}
npm ${forceOfflineFlag} --nodedir=${nodeSources} ${npmFlags} ${lib.optionalString production "--production"} rebuild
if [ "''${dontNpmInstall-}" != "1" ]
then
# NPM tries to download packages even when they already exist if npm-shrinkwrap is used.
rm -f npm-shrinkwrap.json
npm ${forceOfflineFlag} --nodedir=${nodeSources} ${npmFlags} ${lib.optionalString production "--production"} install
fi
'';
# Builds and composes an NPM package including all its dependencies
buildNodePackage =
{ name
, packageName
, version
, dependencies ? []
, buildInputs ? []
, production ? true
, npmFlags ? ""
, dontNpmInstall ? false
, bypassCache ? false
, reconstructLock ? false
, preRebuild ? ""
, dontStrip ? true
, unpackPhase ? "true"
, buildPhase ? "true"
, meta ? {}
, ... }@args:
let
extraArgs = removeAttrs args [ "name" "dependencies" "buildInputs" "dontStrip" "dontNpmInstall" "preRebuild" "unpackPhase" "buildPhase" "meta" ];
in
stdenv.mkDerivation ({
name = "${name}-${version}";
buildInputs = [ tarWrapper python nodejs ]
++ lib.optional (stdenv.isLinux) utillinux
++ lib.optional (stdenv.isDarwin) libtool
++ buildInputs;
inherit nodejs;
inherit dontStrip; # Stripping may fail a build for some package deployments
inherit dontNpmInstall preRebuild unpackPhase buildPhase;
compositionScript = composePackage args;
pinpointDependenciesScript = pinpointDependenciesOfPackage args;
passAsFile = [ "compositionScript" "pinpointDependenciesScript" ];
installPhase = ''
source ${installPackage}
# Create and enter a root node_modules/ folder
mkdir -p $out/lib/node_modules
cd $out/lib/node_modules
# Compose the package and all its dependencies
source $compositionScriptPath
${prepareAndInvokeNPM { inherit packageName bypassCache reconstructLock npmFlags production; }}
# Create symlink to the deployed executable folder, if applicable
if [ -d "$out/lib/node_modules/.bin" ]
then
ln -s $out/lib/node_modules/.bin $out/bin
fi
# Create symlinks to the deployed manual page folders, if applicable
if [ -d "$out/lib/node_modules/${packageName}/man" ]
then
mkdir -p $out/share
for dir in "$out/lib/node_modules/${packageName}/man/"*
do
mkdir -p $out/share/man/$(basename "$dir")
for page in "$dir"/*
do
ln -s $page $out/share/man/$(basename "$dir")
done
done
fi
# Run post install hook, if provided
runHook postInstall
'';
meta = {
# default to Node.js' platforms
platforms = nodejs.meta.platforms;
} // meta;
} // extraArgs);
# Builds a node environment (a node_modules folder and a set of binaries)
buildNodeDependencies =
{ name
, packageName
, version
, src
, dependencies ? []
, buildInputs ? []
, production ? true
, npmFlags ? ""
, dontNpmInstall ? false
, bypassCache ? false
, reconstructLock ? false
, dontStrip ? true
, unpackPhase ? "true"
, buildPhase ? "true"
, ... }@args:
let
extraArgs = removeAttrs args [ "name" "dependencies" "buildInputs" ];
in
stdenv.mkDerivation ({
name = "node-dependencies-${name}-${version}";
buildInputs = [ tarWrapper python nodejs ]
++ lib.optional (stdenv.isLinux) utillinux
++ lib.optional (stdenv.isDarwin) libtool
++ buildInputs;
inherit dontStrip; # Stripping may fail a build for some package deployments
inherit dontNpmInstall unpackPhase buildPhase;
includeScript = includeDependencies { inherit dependencies; };
pinpointDependenciesScript = pinpointDependenciesOfPackage args;
passAsFile = [ "includeScript" "pinpointDependenciesScript" ];
installPhase = ''
source ${installPackage}
mkdir -p $out/${packageName}
cd $out/${packageName}
source $includeScriptPath
# Create fake package.json to make the npm commands work properly
cp ${src}/package.json .
chmod 644 package.json
${lib.optionalString bypassCache ''
if [ -f ${src}/package-lock.json ]
then
cp ${src}/package-lock.json .
fi
''}
# Go to the parent folder to make sure that all packages are pinpointed
cd ..
${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
${prepareAndInvokeNPM { inherit packageName bypassCache reconstructLock npmFlags production; }}
# Expose the executables that were installed
cd ..
${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
mv ${packageName} lib
ln -s $out/lib/node_modules/.bin $out/bin
'';
} // extraArgs);
# Builds a development shell
buildNodeShell =
{ name
, packageName
, version
, src
, dependencies ? []
, buildInputs ? []
, production ? true
, npmFlags ? ""
, dontNpmInstall ? false
, bypassCache ? false
, reconstructLock ? false
, dontStrip ? true
, unpackPhase ? "true"
, buildPhase ? "true"
, ... }@args:
let
nodeDependencies = buildNodeDependencies args;
in
stdenv.mkDerivation {
name = "node-shell-${name}-${version}";
buildInputs = [ python nodejs ] ++ lib.optional (stdenv.isLinux) utillinux ++ buildInputs;
buildCommand = ''
mkdir -p $out/bin
cat > $out/bin/shell <<EOF
#! ${stdenv.shell} -e
$shellHook
exec ${stdenv.shell}
EOF
chmod +x $out/bin/shell
'';
# Provide the dependencies in a development shell through the NODE_PATH environment variable
inherit nodeDependencies;
shellHook = lib.optionalString (dependencies != []) ''
export NODE_PATH=${nodeDependencies}/lib/node_modules
export PATH="${nodeDependencies}/bin:$PATH"
'';
};
in
{
buildNodeSourceDist = lib.makeOverridable buildNodeSourceDist;
buildNodePackage = lib.makeOverridable buildNodePackage;
buildNodeDependencies = lib.makeOverridable buildNodeDependencies;
buildNodeShell = lib.makeOverridable buildNodeShell;
}

17
node.nix

@ -0,0 +1,17 @@
# This file has been generated by node2nix 1.9.0. Do not edit!
{pkgs ? import <nixpkgs> {
inherit system;
}, system ? builtins.currentSystem, nodejs ? pkgs."nodejs-12_x"}:
let
nodeEnv = import ./node-env.nix {
inherit (pkgs) stdenv lib python2 runCommand writeTextFile writeShellScript;
inherit pkgs nodejs;
libtool = if pkgs.stdenv.isDarwin then pkgs.darwin.cctools else null;
};
in
import ./registry.nix {
inherit (pkgs) fetchurl nix-gitignore stdenv lib fetchgit;
inherit nodeEnv;
}

16872
package-lock.json
File diff suppressed because it is too large
View File

2
package.json

@ -1,4 +1,6 @@
{
"name": "search-and-displace-core",
"version": "1",
"private": true,
"scripts": {
"dev": "npm run development",

1028
php-packages.nix
File diff suppressed because it is too large
View File

626
public/css/app.css
File diff suppressed because it is too large
View File

281
registry.nix

@ -0,0 +1,281 @@
# This file has been generated by node2nix 1.9.0. Do not edit!
{nodeEnv, fetchurl, fetchgit, nix-gitignore, stdenv, lib, globalBuildInputs ? []}:
let
sources = {
"@types/json5-0.0.29" = {
name = "_at_types_slash_json5";
packageName = "@types/json5";
version = "0.0.29";
src = fetchurl {
url = "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz";
sha1 = "ee28707ae94e11d2b827bcbe5270bcea7f3e71ee";
};
};
"@types/marked-2.0.5" = {
name = "_at_types_slash_marked";
packageName = "@types/marked";
version = "2.0.5";
src = fetchurl {
url = "https://registry.npmjs.org/@types/marked/-/marked-2.0.5.tgz";
sha512 = "shRZ7XnYFD/8n8zSjKvFdto1QNSf4tONZIlNEZGrJe8GsOE8DL/hG1Hbl8gZlfLnjS7+f5tZGIaTgfpyW38h4w==";
};
};
"ansi-styles-4.3.0" = {
name = "ansi-styles";
packageName = "ansi-styles";
version = "4.3.0";
src = fetchurl {
url = "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz";
sha512 = "zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==";
};
};
"chalk-4.1.2" = {
name = "chalk";
packageName = "chalk";
version = "4.1.2";
src = fetchurl {
url = "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz";
sha512 = "oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==";
};
};
"color-convert-2.0.1" = {
name = "color-convert";
packageName = "color-convert";
version = "2.0.1";
src = fetchurl {
url = "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz";
sha512 = "RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==";
};
};
"color-name-1.1.4" = {
name = "color-name";
packageName = "color-name";
version = "1.1.4";
src = fetchurl {
url = "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz";
sha512 = "dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==";
};
};
"enhanced-resolve-5.8.3" = {
name = "enhanced-resolve";
packageName = "enhanced-resolve";
version = "5.8.3";
src = fetchurl {
url = "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz";
sha512 = "EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==";
};
};
"graceful-fs-4.2.8" = {
name = "graceful-fs";
packageName = "graceful-fs";
version = "4.2.8";
src = fetchurl {
url = "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz";
sha512 = "qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==";
};
};
"has-flag-4.0.0" = {
name = "has-flag";
packageName = "has-flag";
version = "4.0.0";
src = fetchurl {
url = "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz";
sha512 = "EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==";
};
};
"json5-1.0.1" = {
name = "json5";
packageName = "json5";
version = "1.0.1";
src = fetchurl {
url = "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz";
sha512 = "aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==";
};
};
"marked-2.1.3" = {
name = "marked";
packageName = "marked";
version = "2.1.3";
src = fetchurl {
url = "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz";
sha512 = "/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==";
};
};
"minimist-1.2.5" = {
name = "minimist";
packageName = "minimist";
version = "1.2.5";
src = fetchurl {
url = "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz";
sha512 = "FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==";
};
};
"mitt-2.1.0" = {
name = "mitt";
packageName = "mitt";
version = "2.1.0";
src = fetchurl {
url = "https://registry.npmjs.org/mitt/-/mitt-2.1.0.tgz";
sha512 = "ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==";
};
};
"primeflex-2.0.0" = {
name = "primeflex";
packageName = "primeflex";
version = "2.0.0";
src = fetchurl {
url = "https://registry.npmjs.org/primeflex/-/primeflex-2.0.0.tgz";
sha512 = "t6AG3iRI1rh04uI+9nC4JSlbKfA8PnpRDFtjyqi3rDSLRgdfOuhIiunJbjVQ4alnnCfuQAAbVyde1AKN9QxT/w==";
};
};
"primeicons-4.1.0" = {
name = "primeicons";
packageName = "primeicons";
version = "4.1.0";
src = fetchurl {
url = "https://registry.npmjs.org/primeicons/-/primeicons-4.1.0.tgz";
sha512 = "uEv2pSPk1zQCfaB2VgnUfnUxxlGryYi+5rbdxmZBBt5v9S/pscIQYS5YDLxsQZ7D9jn5c76+Tx5wX/2J1nK6sA==";
};
};
"primevue-2.8.0" = {
name = "primevue";
packageName = "primevue";
version = "2.8.0";
src = fetchurl {
url = "https://registry.npmjs.org/primevue/-/primevue-2.8.0.tgz";
sha512 = "Ky7AtQmXkxnqvcdQPjnh+vRbF0Q4PUL7P9HDiWAbjc4y8fgfvZ6USQgorJkbpccg1fLYA3iGwUmIqd65wJkljA==";
};
};
"strip-bom-3.0.0" = {
name = "strip-bom";
packageName = "strip-bom";
version = "3.0.0";
src = fetchurl {
url = "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz";
sha1 = "2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3";
};
};
"supports-color-7.2.0" = {
name = "supports-color";
packageName = "supports-color";
version = "7.2.0";
src = fetchurl {
url = "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz";
sha512 = "qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==";
};
};
"tapable-2.2.1" = {
name = "tapable";
packageName = "tapable";
version = "2.2.1";
src = fetchurl {
url = "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz";
sha512 = "GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==";
};
};
"tsconfig-paths-3.12.0" = {
name = "tsconfig-paths";
packageName = "tsconfig-paths";
version = "3.12.0";
src = fetchurl {
url = "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz";
sha512 = "e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==";
};
};
"tsconfig-paths-webpack-plugin-3.5.2" = {
name = "tsconfig-paths-webpack-plugin";
packageName = "tsconfig-paths-webpack-plugin";
version = "3.5.2";
src = fetchurl {
url = "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-3.5.2.tgz";
sha512 = "EhnfjHbzm5IYI9YPNVIxx1moxMI4bpHD2e0zTXeDNQcwjjRaGepP7IhTHJkyDBG0CAOoxRfe7jCG630Ou+C6Pw==";
};
};
"vue-2.6.14" = {
name = "vue";
packageName = "vue";
version = "2.6.14";
src = fetchurl {
url = "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz";
sha512 = "x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==";
};
};
"vue-class-component-7.2.6" = {
name = "vue-class-component";
packageName = "vue-class-component";
version = "7.2.6";
src = fetchurl {
url = "https://registry.npmjs.org/vue-class-component/-/vue-class-component-7.2.6.tgz";
sha512 = "+eaQXVrAm/LldalI272PpDe3+i4mPis0ORiMYxF6Ae4hyuCh15W8Idet7wPUEs4N4YptgFHGys4UrgNQOMyO6w==";
};
};
"vue-property-decorator-8.5.1" = {
name = "vue-property-decorator";
packageName = "vue-property-decorator";
version = "8.5.1";
src = fetchurl {
url = "https://registry.npmjs.org/vue-property-decorator/-/vue-property-decorator-8.5.1.tgz";
sha512 = "O6OUN2OMsYTGPvgFtXeBU3jPnX5ffQ9V4I1WfxFQ6dqz6cOUbR3Usou7kgFpfiXDvV7dJQSFcJ5yUPgOtPPm1Q==";
};
};
};
args = {
name = "search-and-displace-core";
packageName = "search-and-displace-core";
version = "1";
src = ./.;
dependencies = [
sources."@types/json5-0.0.29"
sources."@types/marked-2.0.5"
sources."ansi-styles-4.3.0"
sources."chalk-4.1.2"
sources."color-convert-2.0.1"
sources."color-name-1.1.4"
sources."enhanced-resolve-5.8.3"
sources."graceful-fs-4.2.8"
sources."has-flag-4.0.0"
sources."json5-1.0.1"
sources."marked-2.1.3"
sources."minimist-1.2.5"
sources."mitt-2.1.0"
sources."primeflex-2.0.0"
sources."primeicons-4.1.0"
sources."primevue-2.8.0"
sources."strip-bom-3.0.0"
sources."supports-color-7.2.0"
sources."tapable-2.2.1"
sources."tsconfig-paths-3.12.0"
sources."tsconfig-paths-webpack-plugin-3.5.2"
sources."vue-2.6.14"
sources."vue-class-component-7.2.6"
sources."vue-property-decorator-8.5.1"
];
buildInputs = globalBuildInputs;
meta = {
};
production = true;
bypassCache = true;
reconstructLock = true;
};
in
{
args = args;
sources = sources;
tarball = nodeEnv.buildNodeSourceDist args;
package = nodeEnv.buildNodePackage args;
shell = nodeEnv.buildNodeShell args;
nodeDependencies = nodeEnv.buildNodeDependencies (lib.overrideExisting args {
src = stdenv.mkDerivation {
name = args.name + "-package-json";
src = nix-gitignore.gitignoreSourcePure [
"*"
"!package.json"
"!package-lock.json"
] args.src;
dontBuild = true;
installPhase = "mkdir -p $out; cp -r ./* $out;";
};
});
}

2
resources/js/app.ts

@ -36,6 +36,7 @@ import ScrollPanel from 'primevue/scrollpanel';
import ConfirmationService from 'primevue/confirmationservice';
import ConfirmDialog from 'primevue/confirmdialog';
import Tooltip from 'primevue/tooltip';
import Textarea from 'primevue/textarea';
// Own components
import AppHeader from './components/layout/Header.vue';
@ -83,6 +84,7 @@ Vue.component('Message', Message);
Vue.component('Timeline', Timeline);
Vue.component('ScrollPanel', ScrollPanel);
Vue.component('ConfirmDialog', ConfirmDialog);
Vue.component('Textarea', Textarea);
Vue.directive('tooltip', Tooltip);

3
resources/js/components/ProcessFile/ProcessFile.scss

@ -14,6 +14,7 @@
}
.p-sidebar-content {
overflow: visible !important;
.p-toolbar {
margin-top: 32px;
}
@ -34,7 +35,7 @@ button.add-searchers {
.p-button.sidebar-toggle-button {
position: absolute;
left: calc(-16px - 2.357rem);
left: calc(-16px - 1.357rem);
top: 50px;
border-radius: 3px 0 0 3px;
}

18
resources/js/components/ProcessFile/ProcessFile.ts

@ -17,7 +17,7 @@ export default class ProcessFile extends Vue {
/**
* Props
*/
// The data for the file we are processing
// The data for the file we are processing
@Prop({default: {id: -1, file: '', path: ''}})
public readonly file!: FileData;
@ -60,7 +60,7 @@ export default class ProcessFile extends Vue {
// private searchersData: Array<{ id: string; name: string; type: string; }> = [];
// The list of filters applied to the selected searchers
private searchersFilters: any = [];
private searchersFilters: any = {};
// The list of selected filters/searchers
private selectedSearchers: any = {};
@ -563,6 +563,20 @@ export default class ProcessFile extends Vue {
this.showDefineSearcher = false;
}
/**
* Watch the filters for any changes. When the search value is empty, remove it
* This is needed due to a bug in PrimeVue where the pagination doesn't work when there is a active filter
*
* @param newValue
* @param oldValue
*/
@Watch('searchersFilters', { deep: true })
private onFiltersChanged(newValue: any, oldValue: object): void {
if (newValue.global === '') {
this.searchersFilters = {};
}
}
/**
* Watch the `showDiffHighlight` property for changes
*

21
resources/js/components/ProcessFile/ProcessFile.vue

@ -181,10 +181,27 @@
:rows="10"
paginatorTemplate="CurrentPageReport FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdown"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords}"
:rowsPerPageOptions="[10,20,50]">
:rowsPerPageOptions="[10,20,50]"
:filters="searchersFilters">
<Column selectionMode="multiple" headerStyle="width: 3em"></Column>
<Column field="name" header="Name" sortable></Column>
<Column
field="name"
header="Name"
sortable>
<template #body="slotProps">
{{slotProps.data.name}}
</template>
<template #filter>
<InputText type="text" v-model="searchersFilters['global']" class="p-column-filter" placeholder="Search by name por description"/>
</template>
</Column>
<Column
field="description"
header="Description"
sortable
class="filter-description">
</Column>
</DataTable>
<template #footer>

95
resources/js/components/Regex/Create.vue

@ -1,58 +1,57 @@
<template>
<div id="regex-create">
<div class="regex-header">
<h1 v-if=" ! regex"> New regex searcher </h1>
<div class="p-d-flex p-jc-center">
<div class="p-formgroup-inline">
<div class="p-field" v-if=" ! regex">
<span class="p-float-label">
<InputText v-model="name"
<Card>
<template #title v-if=" ! regex">
New regex searcher
</template>
<template #content>
<div class="p-fluid p-formgrid p-grid">
<div class="p-field p-col-12 p-md-6">
<label for="name">Enter searcher name</label>
<InputText v-model="name"
type="text"
name="name"
id="name">
</InputText>
</div>
<div class="p-field p-col-12 p-md-6">
<label for="tag">Enter searcher tag (optional)</label>
<InputText v-model="tag"
type="text"
name="name"
id="name">
</InputText>
<label for="name">Enter searcher name</label>
</span>
name="tag"
id="tag">
</InputText>
</div>
<div class="p-field">
<span class="p-float-label">
<InputText v-model="tag"
type="text"
name="tag"
id="tag">
</InputText>
<label for="tag">Enter searcher tag (optional)</label>
</span>
</div>
</template>
<template #footer>
<Button @click="onSave"
:disabled="( ! name && ! regex) || ! pattern"
class="p-button-raised">
Save
</Button>
</template>
</Card>
<Card>
<template #content>
<div class="regex-box">
<div class="main">
<pattern-box v-model="pattern"></pattern-box>
<text-box :pattern="pattern"
:flags="flags">
</text-box>
<flags v-model="flags"></flags>
</div>
<Button @click="onSave"
:disabled="( ! name && ! regex) || ! pattern"
class="p-button-raised">
Save
</Button>
<aside>
<side-bar></side-bar>
</aside>
</div>
</div>
</div>
<div class="regex-box">
<div class="main">
<pattern-box v-model="pattern"></pattern-box>
<text-box :pattern="pattern"
:flags="flags">
</text-box>
<flags v-model="flags"></flags>
</div>
<aside>
<side-bar></side-bar>
</aside>
</div>
</template>
</Card>
</div>
</template>

91
resources/js/components/Searchers/Create.vue

@ -1,39 +1,57 @@
<template>
<div id="searchers-create" :class="{'is-defining': isDefining,}">
<div>
<h1> {{ searcher.id ? 'Edit' : 'New' }} searcher </h1>
<InputText v-model="name"
type="text"
placeholder="Enter searcher name"
class="input">
</InputText>
<Button @click="onSave" :disabled=" ! name || rows.length === 0">
Save
</Button>
</div>
<div>
<h3>Default tag (optional)</h3>
<InputText v-model="tag"
type="text"
placeholder="Enter the default tag"
class="input">
</InputText>
</div>
<div v-if="standalone">
<p>
A searcher may contain multiple compounded searchers on multiple rows and columns.
</p>
<p>
Each searcher in a row is extending the searching criteria on the content resulted from the
previous row searchers.
</p>
</div>
<!-- <h1> {{ searcher.id ? 'Edit' : 'New' }} searcher </h1> -->
<Card>
<template #title>
{{ searcher.id ? 'Edit' : 'New' }} searcher
</template>
<template #content>
<div class="p-fluid p-formgrid p-grid">
<div class="p-field p-col-12 p-md-6">
<label for="searcher-">Searcher name</label>
<InputText v-model="name"
type="text"
placeholder="Enter searcher name"
class="input"
id="searcher-name"
name="searcher-name">
</InputText>
</div>
<div class="p-field p-col-12 p-md-6">
<label for="lastname">Default tag</label>
<InputText v-model="tag"
type="text"
placeholder="Enter the default tag"
class="input"
id="searcher-default-tag"
name="searcher-default-tag">
</InputText>
</div>
<div class="p-field p-col-12">
<label for="address">Description</label>
<Textarea
v-model="description"
rows="5"
placeholder="Enter searcher description"
id="searcher-description"
name="searcher-description"
/>
</div>
</div>
<Message severity="info" v-if="standalone">
<p>A searcher may contain multiple compounded searchers on multiple rows and columns.</p>
<p>Each searcher in a row is extending the searching criteria on the content resulted from the
previous row searchers.</p>
</Message>
</template>
<template #footer>
<Button @click="onSave" :disabled=" ! name || rows.length === 0">
Save
</Button>
</template>
</Card>
<div v-for="(row, rowIndex) in rows"
:key="`row-${rowIndex}`"
@ -77,6 +95,7 @@ import {Component, Prop, Vue} from "vue-property-decorator";
export default class Create extends Vue {
private id: String = '';
private name: String = '';
private description: String = '';
private tag: String = '';
private rows: Array<Array<any>> = [];
@ -85,6 +104,7 @@ import {Component, Prop, Vue} from "vue-property-decorator";
return {
id: '',
name: '',
description: '',
tag: '',
rows: [],
};
@ -126,6 +146,7 @@ import {Component, Prop, Vue} from "vue-property-decorator";
const updatedSearcher = Object.assign(this.searcher, {
name: this.name,
description: this.description,
tag: this.tag,
rows: this.rows,
});
@ -153,6 +174,7 @@ import {Component, Prop, Vue} from "vue-property-decorator";
async update() {
const { data } = await (window as any).axios.put(`/searchers/${this.id}`, {
name: this.name,
description: this.description,
tag: this.tag,
rows: this.rows,
});
@ -163,6 +185,7 @@ import {Component, Prop, Vue} from "vue-property-decorator";
async create() {
const { data } = await (window as any).axios.post('/searchers', {
name: this.name,
description: this.description,
tag: this.tag,
rows: this.rows,
});
@ -208,11 +231,13 @@ import {Component, Prop, Vue} from "vue-property-decorator";
this.id = this.searcher.id;
this.rows = this.searcher.rows;
this.name = this.searcher.name;
this.description = this.searcher.description;
this.tag = this.searcher.tag;
}
if (this.isDefining && this.definedSearcher) {
this.name = this.definedSearcher;
this.description = '';
this.rows.push([
{

6
resources/js/components/Searchers/DefineSearcher.vue

@ -3,9 +3,9 @@
:visible.sync="showDialog"
:maximizable="true"
:modal="true"
:block-scroll="true"
:style="{width: '95vw', height: '95vh',}"
:contentStyle="{overflow: 'visible'}"
:block-scroll="false"
:style="{'position': 'absolute'}"
:contentStyle="{height: '100%'}"
:baseZIndex="2014"
id="define-searcher"
ref="define-searcher">

6
resources/js/components/Searchers/Index.vue

@ -21,11 +21,7 @@
<Column v-if="allowSelect" selectionMode="single" headerStyle="width: 3em"></Column>
<Column header="Name" sortable>
<template #body="slotProps">
{{ slotProps.data.name }}
</template>
</Column>
<Column header="Name" field="name" sortable></Column>
<Column header="Actions" headerStyle="text-align: right">
<template #body="slotProps">
<div class="action-buttons" style="text-align: right">

1
resources/js/interfaces/Searcher.ts

@ -1,6 +1,7 @@
export interface Searcher {
id: string;
name: string,
description: string,
param: string,
type: string;
}

7
resources/sass/components/regex/create/_index.sass

@ -4,6 +4,13 @@
@import 'references'
#regex-create
text-align: left
margin: 10px
.p-card
margin-top: 10px
margin-bottom: 10px
.regex-header
margin-bottom: 5rem

2
resources/sass/components/searchers/_create.sass

@ -1,3 +1,5 @@
#searchers-create.is-defining
max-height: 100%
overflow-y: auto
margin: 10px
text-align: left
Loading…
Cancel
Save